aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/regex/regcomp.c24
-rw-r--r--src/test/regress/expected/regex.out19
-rw-r--r--src/test/regress/sql/regex.sql5
3 files changed, 42 insertions, 6 deletions
diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c
index 8cd7d56b226..b6459e4bafa 100644
--- a/src/backend/regex/regcomp.c
+++ b/src/backend/regex/regcomp.c
@@ -959,7 +959,7 @@ parseqatom(struct vars *v,
if (cap)
{
v->subs[subno] = atom;
- t = subre(v, '(', atom->flags | CAP, lp, rp);
+ t = subre(v, '(', atom->flags | CAP, s, s2);
NOERR();
t->subno = subno;
t->left = atom;
@@ -1042,11 +1042,23 @@ parseqatom(struct vars *v,
/* annoying special case: {0} or {0,0} cancels everything */
if (m == 0 && n == 0)
{
- if (atom != NULL)
- freesubre(v, atom);
- if (atomtype == '(')
- v->subs[subno] = NULL;
- delsub(v->nfa, lp, rp);
+ /*
+ * If we had capturing subexpression(s) within the atom, we don't want
+ * to destroy them, because it's legal (if useless) to back-ref them
+ * later. Hence, just unlink the atom from lp/rp and then ignore it.
+ */
+ if (atom != NULL && (atom->flags & CAP))
+ {
+ delsub(v->nfa, lp, atom->begin);
+ delsub(v->nfa, atom->end, rp);
+ }
+ else
+ {
+ /* Otherwise, we can clean up any subre infrastructure we made */
+ if (atom != NULL)
+ freesubre(v, atom);
+ delsub(v->nfa, lp, rp);
+ }
EMPTYARC(lp, rp);
return;
}
diff --git a/src/test/regress/expected/regex.out b/src/test/regress/expected/regex.out
index 8f4626f41da..09afccc98cf 100644
--- a/src/test/regress/expected/regex.out
+++ b/src/test/regress/expected/regex.out
@@ -567,6 +567,25 @@ select 'a' ~ '()+\1';
t
(1 row)
+-- Test incorrect removal of capture groups within {0}
+select 'xxx' ~ '(.){0}(\1)' as f;
+ f
+---
+ f
+(1 row)
+
+select 'xxx' ~ '((.)){0}(\2)' as f;
+ f
+---
+ f
+(1 row)
+
+select 'xyz' ~ '((.)){0}(\2){0}' as t;
+ t
+---
+ t
+(1 row)
+
-- Test ancient oversight in when to apply zaptreesubs
select 'abcdef' ~ '^(.)\1|\1.' as f;
f
diff --git a/src/test/regress/sql/regex.sql b/src/test/regress/sql/regex.sql
index 762b3ae69b2..758de44d2f4 100644
--- a/src/test/regress/sql/regex.sql
+++ b/src/test/regress/sql/regex.sql
@@ -135,6 +135,11 @@ select 'a' ~ '.. ()|\1';
select 'a' ~ '()*\1';
select 'a' ~ '()+\1';
+-- Test incorrect removal of capture groups within {0}
+select 'xxx' ~ '(.){0}(\1)' as f;
+select 'xxx' ~ '((.)){0}(\2)' as f;
+select 'xyz' ~ '((.)){0}(\2){0}' as t;
+
-- Test ancient oversight in when to apply zaptreesubs
select 'abcdef' ~ '^(.)\1|\1.' as f;
select 'abadef' ~ '^((.)\2|..)\2' as f;