Re: Another regexp performance improvement: skip useless paren-captures
Mark Dilger <mark.dilger@enterprisedb.com>
From: Mark Dilger <mark.dilger@enterprisedb.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Andrew Dunstan <andrew@dunslane.net>,
PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>,
Joel Jacobson <joel@compiler.org>
Date: 2021-08-08T18:22:24Z
Lists: pgsql-hackers
> On Aug 8, 2021, at 10:04 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>
> I've also rebased over the bug fixes from the other thread,
> and added a couple more test cases.
>
> regards, tom lane
Hmm. This changes the behavior when applied against master (c1132aae336c41cf9d316222e525d8d593c2b5d2):
select regexp_split_to_array('uuuzkodphfbfbfb', '((.))(\1\2)', 'ntw');
regexp_split_to_array
-----------------------
- {"",zkodphfbfbfb}
+ {uuuzkodphfbfbfb}
(1 row)
The string starts with three "u" characters. The first of them is doubly-matched, meaning \1 and \2 refer to the first "u" character. The (\1\2) that follows matches the next two "u" characters. When the extra "useless" capture group is skipped, apparently this doesn't work anymore. I haven't looked at your patch, so I'm not sure why, but I'm guessing that \2 doesn't refer to anything.
That analysis is consistent with the next change:
select regexp_split_to_array('snfwbvxeesnzqabixqbixqiumpgxdemmxvnsemjxgqoqknrqessmcqmfslfspskqpqxe', '((((?:.))))\3');
- regexp_split_to_array
----------------------------------------------------------------------
- {snfwbvx,snzqabixqbixqiumpgxde,xvnsemjxgqoqknrqe,mcqmfslfspskqpqxe}
+ regexp_split_to_array
+------------------------------------------------------------------------
+ {snfwbvxeesnzqabixqbixqiumpgxdemmxvnsemjxgqoqknrqessmcqmfslfspskqpqxe}
(1 row)
The pattern matches any double character. I would expect it to match the "ee", the "mm" and the "ss" in the text. With the patched code, it matches nothing.
—
Mark Dilger
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Commits
-
Fix regexp misbehavior with capturing parens inside "{0}".
- 92620e82f6a1 12.9 landed
- 7e75fe390b68 9.6.24 landed
- 3ebd32e70c09 11.14 landed
- 244dd79923a1 14.0 landed
- 071146184a59 13.5 landed
- 062c4c791937 10.19 landed
- 65dc30ced64c 15.0 landed
-
Let regexp_replace() make use of REG_NOSUB when feasible.
- 18bac60ede44 15.0 landed
-
Fix bogus assertion in BootstrapModeMain().
- e12694523e7e 15.0 cited
-
Avoid determining regexp subexpression matches, when possible.
- 0e6aa8747d43 15.0 landed
-
Check the size in COPY_POINTER_FIELD
- c1132aae336c 15.0 cited
-
Make regexp engine's backref-related compilation state more bulletproof.
- cb76fbd7ec87 15.0 cited