diff options
Diffstat (limited to 'src/backend/regex')
-rw-r--r-- | src/backend/regex/regc_nfa.c | 71 | ||||
-rw-r--r-- | src/backend/regex/regcomp.c | 6 |
2 files changed, 77 insertions, 0 deletions
diff --git a/src/backend/regex/regc_nfa.c b/src/backend/regex/regc_nfa.c index a10a346e8f8..77b860cb0fd 100644 --- a/src/backend/regex/regc_nfa.c +++ b/src/backend/regex/regc_nfa.c @@ -1383,6 +1383,77 @@ duptraverse(struct nfa *nfa, } /* + * removeconstraints - remove any constraints in an NFA + * + * Constraint arcs are replaced by empty arcs, essentially treating all + * constraints as automatically satisfied. + */ +static void +removeconstraints(struct nfa *nfa, + struct state *start, /* process subNFA starting here */ + struct state *stop) /* and stopping here */ +{ + if (start == stop) + return; + + stop->tmp = stop; + removetraverse(nfa, start); + /* done, except for clearing out the tmp pointers */ + + stop->tmp = NULL; + cleartraverse(nfa, start); +} + +/* + * removetraverse - recursive heart of removeconstraints + */ +static void +removetraverse(struct nfa *nfa, + struct state *s) +{ + struct arc *a; + struct arc *oa; + + /* Since this is recursive, it could be driven to stack overflow */ + if (STACK_TOO_DEEP(nfa->v->re)) + { + NERR(REG_ETOOBIG); + return; + } + + if (s->tmp != NULL) + return; /* already done */ + + s->tmp = s; + for (a = s->outs; a != NULL && !NISERR(); a = oa) + { + removetraverse(nfa, a->to); + if (NISERR()) + break; + oa = a->outchain; + switch (a->type) + { + case PLAIN: + case EMPTY: + /* nothing to do */ + break; + case AHEAD: + case BEHIND: + case '^': + case '$': + case LACON: + /* replace it */ + newarc(nfa, EMPTY, 0, s, a->to); + freearc(nfa, a); + break; + default: + NERR(REG_ASSERT); + break; + } + } +} + +/* * cleartraverse - recursive cleanup for algorithms that leave tmp ptrs set */ static void diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c index 1f7fa513b26..3c7627a955e 100644 --- a/src/backend/regex/regcomp.c +++ b/src/backend/regex/regcomp.c @@ -150,6 +150,8 @@ static void delsub(struct nfa *, struct state *, struct state *); static void deltraverse(struct nfa *, struct state *, struct state *); static void dupnfa(struct nfa *, struct state *, struct state *, struct state *, struct state *); static void duptraverse(struct nfa *, struct state *, struct state *); +static void removeconstraints(struct nfa *, struct state *, struct state *); +static void removetraverse(struct nfa *, struct state *); static void cleartraverse(struct nfa *, struct state *); static struct state *single_color_transition(struct state *, struct state *); static void specialcolors(struct nfa *); @@ -1182,6 +1184,10 @@ parseqatom(struct vars *v, dupnfa(v->nfa, v->subs[subno]->begin, v->subs[subno]->end, atom->begin, atom->end); NOERR(); + + /* The backref node's NFA should not enforce any constraints */ + removeconstraints(v->nfa, atom->begin, atom->end); + NOERR(); } /* |