aboutsummaryrefslogtreecommitdiff
path: root/src/backend/regex/regcomp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/regex/regcomp.c')
-rw-r--r--src/backend/regex/regcomp.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c
index 72b0d76af68..44a472fa69e 100644
--- a/src/backend/regex/regcomp.c
+++ b/src/backend/regex/regcomp.c
@@ -568,21 +568,26 @@ makesearch(struct vars * v,
* splitting each such state into progress and no-progress states.
*/
- /* first, make a list of the states */
+ /* first, make a list of the states reachable from pre and elsewhere */
slist = NULL;
for (a = pre->outs; a != NULL; a = a->outchain)
{
s = a->to;
for (b = s->ins; b != NULL; b = b->inchain)
+ {
if (b->from != pre)
break;
+ }
+
+ /*
+ * We want to mark states as being in the list already by having non
+ * NULL tmp fields, but we can't just store the old slist value in tmp
+ * because that doesn't work for the first such state. Instead, the
+ * first list entry gets its own address in tmp.
+ */
if (b != NULL && s->tmp == NULL)
{
- /*
- * Must be split if not already in the list (fixes bugs 505048,
- * 230589, 840258, 504785).
- */
- s->tmp = slist;
+ s->tmp = (slist != NULL) ? slist : s;
slist = s;
}
}
@@ -601,7 +606,7 @@ makesearch(struct vars * v,
freearc(nfa, a);
}
}
- s2 = s->tmp;
+ s2 = (s->tmp != s) ? s->tmp : NULL;
s->tmp = NULL; /* clean up while we're at it */
}
}