summaryrefslogtreecommitdiff
path: root/contrib/pg_trgm/trgm_regexp.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/pg_trgm/trgm_regexp.c')
-rw-r--r--contrib/pg_trgm/trgm_regexp.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/contrib/pg_trgm/trgm_regexp.c b/contrib/pg_trgm/trgm_regexp.c
index 64816dd3703..1887a39161f 100644
--- a/contrib/pg_trgm/trgm_regexp.c
+++ b/contrib/pg_trgm/trgm_regexp.c
@@ -907,6 +907,7 @@ transformGraph(TrgmNFA *trgmNFA)
HASHCTL hashCtl;
TrgmStateKey initkey;
TrgmState *initstate;
+ ListCell *lc;
/* Initialize this stage's workspace in trgmNFA struct */
trgmNFA->queue = NIL;
@@ -937,12 +938,13 @@ transformGraph(TrgmNFA *trgmNFA)
/*
* Recursively build the expanded graph by processing queue of states
* (breadth-first search). getState already put initstate in the queue.
+ * Note that getState will append new states to the queue within the loop,
+ * too; this works as long as we don't do repeat fetches using the "lc"
+ * pointer.
*/
- while (trgmNFA->queue != NIL)
+ foreach(lc, trgmNFA->queue)
{
- TrgmState *state = (TrgmState *) linitial(trgmNFA->queue);
-
- trgmNFA->queue = list_delete_first(trgmNFA->queue);
+ TrgmState *state = (TrgmState *) lfirst(lc);
/*
* If we overflowed then just mark state as final. Otherwise do
@@ -966,22 +968,29 @@ transformGraph(TrgmNFA *trgmNFA)
static void
processState(TrgmNFA *trgmNFA, TrgmState *state)
{
+ ListCell *lc;
+
/* keysQueue should be NIL already, but make sure */
trgmNFA->keysQueue = NIL;
/*
* Add state's own key, and then process all keys added to keysQueue until
- * queue is empty. But we can quit if the state gets marked final.
+ * queue is finished. But we can quit if the state gets marked final.
*/
addKey(trgmNFA, state, &state->stateKey);
- while (trgmNFA->keysQueue != NIL && !(state->flags & TSTATE_FIN))
+ foreach(lc, trgmNFA->keysQueue)
{
- TrgmStateKey *key = (TrgmStateKey *) linitial(trgmNFA->keysQueue);
+ TrgmStateKey *key = (TrgmStateKey *) lfirst(lc);
- trgmNFA->keysQueue = list_delete_first(trgmNFA->keysQueue);
+ if (state->flags & TSTATE_FIN)
+ break;
addKey(trgmNFA, state, key);
}
+ /* Release keysQueue to clean up for next cycle */
+ list_free(trgmNFA->keysQueue);
+ trgmNFA->keysQueue = NIL;
+
/*
* Add outgoing arcs only if state isn't final (we have no interest in
* outgoing arcs if we already match)