mirror of
https://github.com/postgres/postgres.git
synced 2025-06-29 10:41:53 +03:00
Back-patch fix for extraction of fixed prefixes from regular expressions.
Back-patch of commits628cbb50ba
andc6aae3042b
. This has been broken since 7.3, so back-patch to all supported branches.
This commit is contained in:
@ -1147,3 +1147,68 @@ build_regexp_split_result(regexp_matches_ctx *splitctx)
|
||||
Int32GetDatum(startpos + 1));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* regexp_fixed_prefix - extract fixed prefix, if any, for a regexp
|
||||
*
|
||||
* The result is NULL if there is no fixed prefix, else a palloc'd string.
|
||||
* If it is an exact match, not just a prefix, *exact is returned as TRUE.
|
||||
*/
|
||||
char *
|
||||
regexp_fixed_prefix(text *text_re, bool case_insensitive,
|
||||
bool *exact)
|
||||
{
|
||||
char *result;
|
||||
regex_t *re;
|
||||
int cflags;
|
||||
int re_result;
|
||||
pg_wchar *str;
|
||||
size_t slen;
|
||||
size_t maxlen;
|
||||
char errMsg[100];
|
||||
|
||||
*exact = false; /* default result */
|
||||
|
||||
/* Compile RE */
|
||||
cflags = REG_ADVANCED;
|
||||
if (case_insensitive)
|
||||
cflags |= REG_ICASE;
|
||||
|
||||
re = RE_compile_and_cache(text_re, cflags);
|
||||
|
||||
/* Examine it to see if there's a fixed prefix */
|
||||
re_result = pg_regprefix(re, &str, &slen);
|
||||
|
||||
switch (re_result)
|
||||
{
|
||||
case REG_NOMATCH:
|
||||
return NULL;
|
||||
|
||||
case REG_PREFIX:
|
||||
/* continue with wchar conversion */
|
||||
break;
|
||||
|
||||
case REG_EXACT:
|
||||
*exact = true;
|
||||
/* continue with wchar conversion */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* re failed??? */
|
||||
pg_regerror(re_result, re, errMsg, sizeof(errMsg));
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
|
||||
errmsg("regular expression failed: %s", errMsg)));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Convert pg_wchar result back to database encoding */
|
||||
maxlen = pg_database_encoding_max_length() * slen + 1;
|
||||
result = (char *) palloc(maxlen);
|
||||
slen = pg_wchar2mb_with_len(str, result, slen);
|
||||
Assert(slen < maxlen);
|
||||
|
||||
free(str);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
Reference in New Issue
Block a user