Be more careful with error paths in pg_set_regex_collation().

Set global variables after error paths so that they don't end up in an
inconsistent state.

The inconsistent state doesn't lead to an actual problem, because
after an error, pg_set_regex_collation() will be called again before
the globals are accessed.

Change extracted from patch by Andreas Karlsson, though not discussed
explicitly.

Discussion: https://postgr.es/m/60929555-4709-40a7-b136-bcb44cff5a3c@proxel.se
This commit is contained in:
Jeff Davis 2024-09-05 12:10:08 -07:00
parent fadff3fc94
commit 7829f85a62

View File

@ -231,6 +231,9 @@ static const unsigned char pg_char_properties[128] = {
void void
pg_set_regex_collation(Oid collation) pg_set_regex_collation(Oid collation)
{ {
pg_locale_t locale = 0;
PG_Locale_Strategy strategy;
if (!OidIsValid(collation)) if (!OidIsValid(collation))
{ {
/* /*
@ -246,40 +249,41 @@ pg_set_regex_collation(Oid collation)
if (lc_ctype_is_c(collation)) if (lc_ctype_is_c(collation))
{ {
/* C/POSIX collations use this path regardless of database encoding */ /* C/POSIX collations use this path regardless of database encoding */
pg_regex_strategy = PG_REGEX_STRATEGY_C; strategy = PG_REGEX_STRATEGY_C;
pg_regex_locale = 0; collation = C_COLLATION_OID;
pg_regex_collation = C_COLLATION_OID;
} }
else else
{ {
pg_regex_locale = pg_newlocale_from_collation(collation); locale = pg_newlocale_from_collation(collation);
if (!pg_locale_deterministic(pg_regex_locale)) if (!pg_locale_deterministic(locale))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("nondeterministic collations are not supported for regular expressions"))); errmsg("nondeterministic collations are not supported for regular expressions")));
if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN) if (locale->provider == COLLPROVIDER_BUILTIN)
{ {
Assert(GetDatabaseEncoding() == PG_UTF8); Assert(GetDatabaseEncoding() == PG_UTF8);
pg_regex_strategy = PG_REGEX_STRATEGY_BUILTIN; strategy = PG_REGEX_STRATEGY_BUILTIN;
} }
#ifdef USE_ICU #ifdef USE_ICU
else if (pg_regex_locale->provider == COLLPROVIDER_ICU) else if (locale->provider == COLLPROVIDER_ICU)
{ {
pg_regex_strategy = PG_REGEX_STRATEGY_ICU; strategy = PG_REGEX_STRATEGY_ICU;
} }
#endif #endif
else else
{ {
if (GetDatabaseEncoding() == PG_UTF8) if (GetDatabaseEncoding() == PG_UTF8)
pg_regex_strategy = PG_REGEX_STRATEGY_LIBC_WIDE; strategy = PG_REGEX_STRATEGY_LIBC_WIDE;
else else
pg_regex_strategy = PG_REGEX_STRATEGY_LIBC_1BYTE; strategy = PG_REGEX_STRATEGY_LIBC_1BYTE;
} }
pg_regex_collation = collation;
} }
pg_regex_strategy = strategy;
pg_regex_locale = locale;
pg_regex_collation = collation;
} }
static int static int