On Thu, 2025-09-25 at 11:31 +0200, Alexander Kukushkin wrote:
> Hi Jeff,
>
> On Thu, 25 Sept 2025 at 11:08, Jeff Davis <[email protected]> wrote:
> > Committed v2-0001.
> >
>
>
> 06421b084364 commit broke possibility to
> call GetSharedSecurityLabel() from ClientAuthentication_hook.
> Now GetSharedSecurityLabel() calls fail with the error "cannot read
> pg_class without having selected a database".
...
> pg_shseclabel.provider data type is TEXT with collation C.
> When doing btree lookup by (objoid, classoid, provider) we need to
> take into account collation.
> varstr_cmp() was used to make an exception for C collation, and now
> it has to do a cache lookup for pg_collation to determine that this
> is a C collation.
> However, caches are not yet initialized at the moment
> when ClientAuthentication_hook is executed, and they can't be,
> because database access is not yet allowed.
>
> Or, in other words, this commit made shared pg_catalog relations
> depend on non shared relations.
Thank you, patch attached, intended for backport to 18.
Are you aware of any way to encounter this bug without using an
extension?
Regards,
Jeff Davis
From b6dd158d4a2a5a070634e56142c4b1ad8b9b1859 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Thu, 23 Oct 2025 19:24:14 -0700
Subject: [PATCH v1] Special case C_COLLATION_OID in
pg_newlocale_from_collation().
Discussion: https://postgr.es/m/CAFh8B=nj966ecv5vi_u3ryij12v0j-7npzcxlyznwoqp9ac...@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.43.0