From d115de9d89164e87269d73d4f0f1368f06ebdd5e Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Tue, 4 Nov 2025 16:28:07 -0800 Subject: [PATCH] Special case C_COLLATION_OID in pg_newlocale_from_collation(). Allow pg_newlocale_from_collation(C_COLLATION_OID) to work even if there's no catalog access, which some extensions expect. Not known to be a bug without extensions involved, but backport to 18. Also corrects an issue in master with dummy_c_locale (introduced in commit 5a38104b36) where deterministic was not set. That wasn't a bug, but could have been if that structure was used more widely. Reported-by: Alexander Kukushkin Reviewed-by: Alexander Kukushkin Discussion: https://postgr.es/m/CAFh8B=nj966ECv5vi_u3RYij12v0j-7NPZCXLYzNwOQp9AcPWQ@mail.gmail.com Backpatch-through: 18 --- src/backend/regex/regc_pg_locale.c | 36 +++++------------------------- src/backend/utils/adt/pg_locale.c | 13 +++++++++++ 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c index e0c892db713..4698f110a0c 100644 --- a/src/backend/regex/regc_pg_locale.c +++ b/src/backend/regex/regc_pg_locale.c @@ -23,11 +23,6 @@ static pg_locale_t pg_regex_locale; -static struct pg_locale_struct dummy_c_locale = { - .collate_is_c = true, - .ctype_is_c = true, -}; - /* * pg_set_regex_collation: set collation for these functions to obey @@ -53,33 +48,12 @@ pg_set_regex_collation(Oid collation) errhint("Use the COLLATE clause to set the collation explicitly."))); } - if (collation == C_COLLATION_OID) - { - /* - * Some callers expect regexes to work for C_COLLATION_OID before - * catalog access is available, so we can't call - * pg_newlocale_from_collation(). - */ - locale = &dummy_c_locale; - } - else - { - locale = pg_newlocale_from_collation(collation); - - if (!locale->deterministic) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("nondeterministic collations are not supported for regular expressions"))); + locale = pg_newlocale_from_collation(collation); - if (locale->ctype_is_c) - { - /* - * C/POSIX collations use this path regardless of database - * encoding - */ - locale = &dummy_c_locale; - } - } + if (!locale->deterministic) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("nondeterministic collations are not supported for regular expressions"))); pg_regex_locale = locale; } diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 67299c55ed8..b14c7837938 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -106,6 +106,12 @@ static pg_locale_t default_locale = NULL; static bool CurrentLocaleConvValid = false; static bool CurrentLCTimeValid = false; +static struct pg_locale_struct c_locale = { + .deterministic = true, + .collate_is_c = true, + .ctype_is_c = true, +}; + /* Cache for collation-related knowledge */ typedef struct @@ -1185,6 +1191,13 @@ pg_newlocale_from_collation(Oid collid) if (collid == DEFAULT_COLLATION_OID) return default_locale; + /* + * Some callers expect C_COLLATION_OID to succeed even without catalog + * access. + */ + if (collid == C_COLLATION_OID) + return &c_locale; + if (!OidIsValid(collid)) elog(ERROR, "cache lookup failed for collation %u", collid); -- 2.47.3