1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-03 09:13:20 +03:00

Let regexp_replace() make use of REG_NOSUB when feasible.

If the replacement string doesn't contain \1...\9, then we don't
need sub-match locations, so we can use the REG_NOSUB optimization
here too.  There's already a pre-scan of the replacement string
to look for backslashes, so extend that to check for digits, and
refactor to allow that to happen before we compile the regexp.

While at it, try to speed up the pre-scan by using memchr() instead
of a handwritten loop.  It's likely that this is lost in the noise
compared to the regexp processing proper, but maybe not.  In any
case, this coding is shorter.

Also, add some test cases to improve the poor coverage of
appendStringInfoRegexpSubstr().

Discussion: https://postgr.es/m/3534632.1628536485@sss.pgh.pa.us
This commit is contained in:
Tom Lane
2021-08-09 20:53:25 -04:00
parent e12694523e
commit 18bac60ede
5 changed files with 90 additions and 65 deletions

View File

@@ -630,11 +630,10 @@ textregexreplace_noopt(PG_FUNCTION_ARGS)
text *s = PG_GETARG_TEXT_PP(0);
text *p = PG_GETARG_TEXT_PP(1);
text *r = PG_GETARG_TEXT_PP(2);
regex_t *re;
re = RE_compile_and_cache(p, REG_ADVANCED, PG_GET_COLLATION());
PG_RETURN_TEXT_P(replace_text_regexp(s, (void *) re, r, 0, 1));
PG_RETURN_TEXT_P(replace_text_regexp(s, p, r,
REG_ADVANCED, PG_GET_COLLATION(),
0, 1));
}
/*
@@ -648,7 +647,6 @@ textregexreplace(PG_FUNCTION_ARGS)
text *p = PG_GETARG_TEXT_PP(1);
text *r = PG_GETARG_TEXT_PP(2);
text *opt = PG_GETARG_TEXT_PP(3);
regex_t *re;
pg_re_flags flags;
/*
@@ -672,10 +670,9 @@ textregexreplace(PG_FUNCTION_ARGS)
parse_re_flags(&flags, opt);
re = RE_compile_and_cache(p, flags.cflags, PG_GET_COLLATION());
PG_RETURN_TEXT_P(replace_text_regexp(s, (void *) re, r, 0,
flags.glob ? 0 : 1));
PG_RETURN_TEXT_P(replace_text_regexp(s, p, r,
flags.cflags, PG_GET_COLLATION(),
0, flags.glob ? 0 : 1));
}
/*
@@ -694,7 +691,6 @@ textregexreplace_extended(PG_FUNCTION_ARGS)
int n = 1;
text *flags = PG_GETARG_TEXT_PP_IF_EXISTS(5);
pg_re_flags re_flags;
regex_t *re;
/* Collect optional parameters */
if (PG_NARGS() > 3)
@@ -723,11 +719,10 @@ textregexreplace_extended(PG_FUNCTION_ARGS)
if (PG_NARGS() <= 4)
n = re_flags.glob ? 0 : 1;
/* Compile the regular expression */
re = RE_compile_and_cache(p, re_flags.cflags, PG_GET_COLLATION());
/* Do the replacement(s) */
PG_RETURN_TEXT_P(replace_text_regexp(s, (void *) re, r, start - 1, n));
PG_RETURN_TEXT_P(replace_text_regexp(s, p, r,
re_flags.cflags, PG_GET_COLLATION(),
start - 1, n));
}
/* This is separate to keep the opr_sanity regression test from complaining */