diff options
-rw-r--r-- | src/backend/regex/regcomp.c | 5 | ||||
-rw-r--r-- | src/test/regress/expected/regex.out | 49 | ||||
-rw-r--r-- | src/test/regress/sql/regex.sql | 10 |
3 files changed, 63 insertions, 1 deletions
diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c index 7ae9673a7d5..f72c41692bb 100644 --- a/src/backend/regex/regcomp.c +++ b/src/backend/regex/regcomp.c @@ -1147,7 +1147,10 @@ parseqatom(struct vars * v, /* rest of branch can be strung starting from atom->end */ s2 = atom->end; } - else if (m == 1 && n == 1) + else if (m == 1 && n == 1 && + (qprefer == 0 || + (atom->flags & (LONGER | SHORTER | MIXED)) == 0 || + qprefer == (atom->flags & (LONGER | SHORTER | MIXED)))) { /* no/vacuous quantifier: done */ EMPTYARC(s, atom->begin); /* empty prefix */ diff --git a/src/test/regress/expected/regex.out b/src/test/regress/expected/regex.out index 2b4f2ec2522..e5a4777f1bb 100644 --- a/src/test/regress/expected/regex.out +++ b/src/test/regress/expected/regex.out @@ -295,6 +295,55 @@ select regexp_matches('foo/bar/baz', {foo,bar,baz} (1 row) +-- Test that greediness can be overridden by outer quantifier +select regexp_matches('llmmmfff', '^(l*)(.*)(f*)$'); + regexp_matches +---------------- + {ll,mmmfff,""} +(1 row) + +select regexp_matches('llmmmfff', '^(l*){1,1}(.*)(f*)$'); + regexp_matches +---------------- + {ll,mmmfff,""} +(1 row) + +select regexp_matches('llmmmfff', '^(l*){1,1}?(.*)(f*)$'); + regexp_matches +------------------ + {"",llmmmfff,""} +(1 row) + +select regexp_matches('llmmmfff', '^(l*){1,1}?(.*){1,1}?(f*)$'); + regexp_matches +---------------- + {"",llmmm,fff} +(1 row) + +select regexp_matches('llmmmfff', '^(l*?)(.*)(f*)$'); + regexp_matches +------------------ + {"",llmmmfff,""} +(1 row) + +select regexp_matches('llmmmfff', '^(l*?){1,1}(.*)(f*)$'); + regexp_matches +---------------- + {ll,mmmfff,""} +(1 row) + +select regexp_matches('llmmmfff', '^(l*?){1,1}?(.*)(f*)$'); + regexp_matches +------------------ + {"",llmmmfff,""} +(1 row) + +select regexp_matches('llmmmfff', '^(l*?){1,1}?(.*){1,1}?(f*)$'); + regexp_matches +---------------- + {"",llmmm,fff} +(1 row) + -- Test for infinite loop in cfindloop with zero-length possible match -- but no actual match (can only happen in the presence of backrefs) select 'a' ~ '$()|^\1'; diff --git a/src/test/regress/sql/regex.sql b/src/test/regress/sql/regex.sql index 635f068eae9..9c2e9c54ad8 100644 --- a/src/test/regress/sql/regex.sql +++ b/src/test/regress/sql/regex.sql @@ -76,6 +76,16 @@ select regexp_matches('Programmer', '(\w)(.*?\1)', 'g'); select regexp_matches('foo/bar/baz', '^([^/]+?)(?:/([^/]+?))(?:/([^/]+?))?$', ''); +-- Test that greediness can be overridden by outer quantifier +select regexp_matches('llmmmfff', '^(l*)(.*)(f*)$'); +select regexp_matches('llmmmfff', '^(l*){1,1}(.*)(f*)$'); +select regexp_matches('llmmmfff', '^(l*){1,1}?(.*)(f*)$'); +select regexp_matches('llmmmfff', '^(l*){1,1}?(.*){1,1}?(f*)$'); +select regexp_matches('llmmmfff', '^(l*?)(.*)(f*)$'); +select regexp_matches('llmmmfff', '^(l*?){1,1}(.*)(f*)$'); +select regexp_matches('llmmmfff', '^(l*?){1,1}?(.*)(f*)$'); +select regexp_matches('llmmmfff', '^(l*?){1,1}?(.*){1,1}?(f*)$'); + -- Test for infinite loop in cfindloop with zero-length possible match -- but no actual match (can only happen in the presence of backrefs) select 'a' ~ '$()|^\1'; |