Special case C_COLLATION_OID in pg_newlocale_from_collation().
authorJeff Davis <jdavis@postgresql.org>
Wed, 5 Nov 2025 00:27:31 +0000 (16:27 -0800)
committerJeff Davis <jdavis@postgresql.org>
Wed, 5 Nov 2025 00:49:00 +0000 (16:49 -0800)
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 <cyberdemn@gmail.com>
Reviewed-by: Alexander Kukushkin <cyberdemn@gmail.com>
Discussion: https://postgr.es/m/CAFh8B=nj966ECv5vi_u3RYij12v0j-7NPZCXLYzNwOQp9AcPWQ@mail.gmail.com
Backpatch-through: 18

src/backend/utils/adt/pg_locale.c

index f5e31c433a0de1b5c585c258d68adc6d7c4ad47b..fc5b842de291933f31461bb3a8a8258f7b820fcd 100644 (file)
@@ -134,6 +134,13 @@ static pg_locale_t default_locale = NULL;
 static bool CurrentLocaleConvValid = false;
 static bool CurrentLCTimeValid = false;
 
+static struct pg_locale_struct c_locale = {
+   .provider = COLLPROVIDER_LIBC,
+   .deterministic = true,
+   .collate_is_c = true,
+   .ctype_is_c = true,
+};
+
 /* Cache for collation-related knowledge */
 
 typedef struct
@@ -1194,6 +1201,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);