aboutsummaryrefslogtreecommitdiff
path: root/src/backend/regex/regexec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/regex/regexec.c')
-rw-r--r--src/backend/regex/regexec.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/backend/regex/regexec.c b/src/backend/regex/regexec.c
index cf959899489..8d7777f8c62 100644
--- a/src/backend/regex/regexec.c
+++ b/src/backend/regex/regexec.c
@@ -77,6 +77,9 @@ struct dfa
chr *lastpost; /* location of last cache-flushed success */
chr *lastnopr; /* location of last cache-flushed NOPROGRESS */
struct sset *search; /* replacement-search-pointer memory */
+ int backno; /* if DFA for a backref, subno it refers to */
+ short backmin; /* min repetitions for backref */
+ short backmax; /* max repetitions for backref */
bool ismalloced; /* should this struct dfa be freed? */
bool arraysmalloced; /* should its subsidiary arrays be freed? */
};
@@ -154,6 +157,7 @@ static int creviterdissect(struct vars *, struct subre *, chr *, chr *);
static chr *longest(struct vars *, struct dfa *, chr *, chr *, int *);
static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *, chr **, int *);
static int matchuntil(struct vars *, struct dfa *, chr *, struct sset **, chr **);
+static chr *dfa_backref(struct vars *, struct dfa *, chr *, chr *, chr *, bool);
static chr *lastcold(struct vars *, struct dfa *);
static struct dfa *newdfa(struct vars *, struct cnfa *, struct colormap *, struct smalldfa *);
static void freedfa(struct dfa *);
@@ -342,13 +346,23 @@ static struct dfa *
getsubdfa(struct vars *v,
struct subre *t)
{
- if (v->subdfas[t->id] == NULL)
+ struct dfa *d = v->subdfas[t->id];
+
+ if (d == NULL)
{
- v->subdfas[t->id] = newdfa(v, &t->cnfa, &v->g->cmap, DOMALLOC);
+ d = newdfa(v, &t->cnfa, &v->g->cmap, DOMALLOC);
if (ISERR())
return NULL;
+ /* set up additional info if this is a backref node */
+ if (t->op == 'b')
+ {
+ d->backno = t->backno;
+ d->backmin = t->min;
+ d->backmax = t->max;
+ }
+ v->subdfas[t->id] = d;
}
- return v->subdfas[t->id];
+ return d;
}
/*
@@ -369,6 +383,7 @@ getladfa(struct vars *v,
v->ladfas[n] = newdfa(v, &sub->cnfa, &v->g->cmap, DOMALLOC);
if (ISERR())
return NULL;
+ /* a LACON can't contain a backref, so nothing else to do */
}
return v->ladfas[n];
}
@@ -927,6 +942,9 @@ crevcondissect(struct vars *v,
/*
* cbrdissect - dissect match for backref node
+ *
+ * The backref match might already have been verified by dfa_backref(),
+ * but we don't know that for sure so must check it here.
*/
static int /* regexec return code */
cbrdissect(struct vars *v,