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

  1. Fix regexp misbehavior with capturing parens inside "{0}".

  2. Let regexp_replace() make use of REG_NOSUB when feasible.

  3. Fix bogus assertion in BootstrapModeMain().

  4. Avoid determining regexp subexpression matches, when possible.

  5. Check the size in COPY_POINTER_FIELD

  6. Make regexp engine's backref-related compilation state more bulletproof.