diff options
Diffstat (limited to 'contrib/pg_trgm/trgm_regexp.c')
-rw-r--r-- | contrib/pg_trgm/trgm_regexp.c | 25 |
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) |