Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5a27056

Browse files
committed
Fix regexp_matches() handling of zero-length matches.
We'd find the same match twice if it was of zero length and not immediatelyadjacent to the previous match. replace_text_regexp() got similar casesright, so adjust this search logic to match that. Note that even thoughthe regexp_split_to_xxx() functions share this code, they did not displayequivalent misbehavior, because the second match would be considereddegenerate and ignored.Jeevan Chalke, with some cosmetic changes by me.
1 parent6c1fec9 commit5a27056

File tree

4 files changed

+75
-8
lines changed

4 files changed

+75
-8
lines changed

‎src/backend/utils/adt/regexp.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -938,14 +938,13 @@ setup_regexp_matches(text *orig_str, text *pattern, text *flags,
938938
break;
939939

940940
/*
941-
* Advance search position. Normally we startjust after the end of
942-
* the previous match, butalways advance at least one character (the
943-
*special case can occur if the pattern matches zero characters just
944-
*after the prior match or at the end of the string).
941+
* Advance search position. Normally we startthe next search at the
942+
*end ofthe previous match; butif the match was of zero length, we
943+
*have to advance by one character, or we'd just find the same match
944+
*again.
945945
*/
946-
if (start_search<pmatch[0].rm_eo)
947-
start_search=pmatch[0].rm_eo;
948-
else
946+
start_search=prev_match_end;
947+
if (pmatch[0].rm_so==pmatch[0].rm_eo)
949948
start_search++;
950949
if (start_search>wide_len)
951950
break;

‎src/backend/utils/adt/varlena.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2833,7 +2833,10 @@ replace_text_regexp(text *src_text, void *regexp,
28332833
break;
28342834

28352835
/*
2836-
* Search from next character when the matching text is zero width.
2836+
* Advance search position. Normally we start the next search at the
2837+
* end of the previous match; but if the match was of zero length, we
2838+
* have to advance by one character, or we'd just find the same match
2839+
* again.
28372840
*/
28382841
search_start=data_pos;
28392842
if (pmatch[0].rm_so==pmatch[0].rm_eo)

‎src/test/regress/expected/strings.out

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,64 @@ SELECT regexp_matches('foobarbequebaz', $re$barbeque$re$);
440440
{barbeque}
441441
(1 row)
442442

443+
-- start/end-of-line matches are of zero length
444+
SELECT regexp_matches('foo' || chr(10) || 'bar' || chr(10) || 'bequq' || chr(10) || 'baz', '^', 'mg');
445+
regexp_matches
446+
----------------
447+
{""}
448+
{""}
449+
{""}
450+
{""}
451+
(4 rows)
452+
453+
SELECT regexp_matches('foo' || chr(10) || 'bar' || chr(10) || 'bequq' || chr(10) || 'baz', '$', 'mg');
454+
regexp_matches
455+
----------------
456+
{""}
457+
{""}
458+
{""}
459+
{""}
460+
(4 rows)
461+
462+
SELECT regexp_matches('1' || chr(10) || '2' || chr(10) || '3' || chr(10) || '4' || chr(10), '^.?', 'mg');
463+
regexp_matches
464+
----------------
465+
{1}
466+
{2}
467+
{3}
468+
{4}
469+
{""}
470+
(5 rows)
471+
472+
SELECT regexp_matches(chr(10) || '1' || chr(10) || '2' || chr(10) || '3' || chr(10) || '4' || chr(10), '.?$', 'mg');
473+
regexp_matches
474+
----------------
475+
{""}
476+
{1}
477+
{""}
478+
{2}
479+
{""}
480+
{3}
481+
{""}
482+
{4}
483+
{""}
484+
{""}
485+
(10 rows)
486+
487+
SELECT regexp_matches(chr(10) || '1' || chr(10) || '2' || chr(10) || '3' || chr(10) || '4', '.?$', 'mg');
488+
regexp_matches
489+
----------------
490+
{""}
491+
{1}
492+
{""}
493+
{2}
494+
{""}
495+
{3}
496+
{""}
497+
{4}
498+
{""}
499+
(9 rows)
500+
443501
-- give me errors
444502
SELECT regexp_matches('foobarbequebaz', $re$(bar)(beque)$re$, 'gz');
445503
ERROR: invalid regexp option: "z"

‎src/test/regress/sql/strings.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ SELECT regexp_matches('foobarbequebaz', $re$(bar)(.+)?(beque)$re$);
158158
-- no capture groups
159159
SELECT regexp_matches('foobarbequebaz', $re$barbeque$re$);
160160

161+
-- start/end-of-line matches are of zero length
162+
SELECT regexp_matches('foo'|| chr(10)||'bar'|| chr(10)||'bequq'|| chr(10)||'baz','^','mg');
163+
SELECT regexp_matches('foo'|| chr(10)||'bar'|| chr(10)||'bequq'|| chr(10)||'baz','$','mg');
164+
SELECT regexp_matches('1'|| chr(10)||'2'|| chr(10)||'3'|| chr(10)||'4'|| chr(10),'^.?','mg');
165+
SELECT regexp_matches(chr(10)||'1'|| chr(10)||'2'|| chr(10)||'3'|| chr(10)||'4'|| chr(10),'.?$','mg');
166+
SELECT regexp_matches(chr(10)||'1'|| chr(10)||'2'|| chr(10)||'3'|| chr(10)||'4','.?$','mg');
167+
161168
-- give me errors
162169
SELECT regexp_matches('foobarbequebaz', $re$(bar)(beque)$re$,'gz');
163170
SELECT regexp_matches('foobarbequebaz', $re$(barbeque$re$);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp