diff --git a/src/backend/regex/regexec.c b/src/backend/regex/regexec.c index 3748a9c171..78ebdee39e 100644 --- a/src/backend/regex/regexec.c +++ b/src/backend/regex/regexec.c @@ -487,19 +487,21 @@ cfindloop(struct vars * v, *coldp = cold; return er; } - if ((shorter) ? end == estop : end == begin) - { - /* no point in trying again */ - *coldp = cold; - return REG_NOMATCH; - } - /* go around and try again */ + /* try next shorter/longer match with same begin point */ if (shorter) + { + if (end == estop) + break; /* NOTE BREAK OUT */ estart = end + 1; + } else + { + if (end == begin) + break; /* NOTE BREAK OUT */ estop = end - 1; - } - } + } + } /* end loop over endpoint positions */ + } /* end loop over beginning positions */ } while (close < v->stop); *coldp = cold; diff --git a/src/test/regress/expected/regex.out b/src/test/regress/expected/regex.out index 757f2a4028..df39ef937d 100644 --- a/src/test/regress/expected/regex.out +++ b/src/test/regress/expected/regex.out @@ -173,3 +173,18 @@ select 'a' ~ '((((((a+|)+|)+|)+|)+|)+|)'; t (1 row) +-- Test backref in combination with non-greedy quantifier +-- https://core.tcl.tk/tcl/tktview/6585b21ca8fa6f3678d442b97241fdd43dba2ec0 +select 'Programmer' ~ '(\w).*?\1' as t; + t +--- + t +(1 row) + +select regexp_matches('Programmer', '(\w)(.*?\1)', 'g'); + regexp_matches +---------------- + {r,ogr} + {m,m} +(2 rows) + diff --git a/src/test/regress/sql/regex.sql b/src/test/regress/sql/regex.sql index 1426562119..e5f690263b 100644 --- a/src/test/regress/sql/regex.sql +++ b/src/test/regress/sql/regex.sql @@ -41,3 +41,8 @@ select 'a' ~ '($|^)*'; -- Test for infinite loop in fixempties() (Tcl bugs 3604074, 3606683) select 'a' ~ '((((((a)*)*)*)*)*)*'; select 'a' ~ '((((((a+|)+|)+|)+|)+|)+|)'; + +-- Test backref in combination with non-greedy quantifier +-- https://core.tcl.tk/tcl/tktview/6585b21ca8fa6f3678d442b97241fdd43dba2ec0 +select 'Programmer' ~ '(\w).*?\1' as t; +select regexp_matches('Programmer', '(\w)(.*?\1)', 'g');