From 06421b08436414b42cd169501005f15adee986f1 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Wed, 4 Sep 2024 12:30:14 -0700 Subject: [PATCH] Remove lc_collate_is_c(). Instead just look up the collation and check collate_is_c field. Author: Andreas Karlsson Discussion: https://postgr.es/m/60929555-4709-40a7-b136-bcb44cff5a3c@proxel.se --- src/backend/access/spgist/spgtextproc.c | 2 +- src/backend/commands/collationcmds.c | 8 ++---- src/backend/utils/adt/like_support.c | 4 +-- src/backend/utils/adt/pg_locale.c | 33 +++--------------------- src/backend/utils/adt/selfuncs.c | 6 +++-- src/backend/utils/adt/varchar.c | 20 +++++---------- src/backend/utils/adt/varlena.c | 34 ++++++++++++------------- src/include/utils/pg_locale.h | 1 - 8 files changed, 35 insertions(+), 73 deletions(-) diff --git a/src/backend/access/spgist/spgtextproc.c b/src/backend/access/spgist/spgtextproc.c index 3f08d330b6..d5237a68b5 100644 --- a/src/backend/access/spgist/spgtextproc.c +++ b/src/backend/access/spgist/spgtextproc.c @@ -427,7 +427,7 @@ spg_text_inner_consistent(PG_FUNCTION_ARGS) { spgInnerConsistentIn *in = (spgInnerConsistentIn *) PG_GETARG_POINTER(0); spgInnerConsistentOut *out = (spgInnerConsistentOut *) PG_GETARG_POINTER(1); - bool collate_is_c = lc_collate_is_c(PG_GET_COLLATION()); + bool collate_is_c = pg_newlocale_from_collation(PG_GET_COLLATION())->collate_is_c; text *reconstructedValue; text *reconstrText; int maxReconstrLen; diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c index 63ef9a0841..53b6a479aa 100644 --- a/src/backend/commands/collationcmds.c +++ b/src/backend/commands/collationcmds.c @@ -377,13 +377,9 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e if (!OidIsValid(newoid)) return InvalidObjectAddress; - /* - * Check that the locales can be loaded. NB: pg_newlocale_from_collation - * is only supposed to be called on non-C-equivalent locales. - */ + /* Check that the locales can be loaded. */ CommandCounterIncrement(); - if (!lc_collate_is_c(newoid) || !lc_ctype_is_c(newoid)) - (void) pg_newlocale_from_collation(newoid); + (void) pg_newlocale_from_collation(newoid); ObjectAddressSet(address, CollationRelationId, newoid); diff --git a/src/backend/utils/adt/like_support.c b/src/backend/utils/adt/like_support.c index 2635050861..fb9291441d 100644 --- a/src/backend/utils/adt/like_support.c +++ b/src/backend/utils/adt/like_support.c @@ -433,7 +433,7 @@ match_pattern_prefix(Node *leftop, * collation. */ if (collation_aware && - !lc_collate_is_c(indexcollation)) + !pg_newlocale_from_collation(indexcollation)->collate_is_c) return NIL; /* @@ -1603,7 +1603,7 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc, Oid collation) else workstr = TextDatumGetCString(str_const->constvalue); len = strlen(workstr); - if (lc_collate_is_c(collation) || len == 0) + if (len == 0 || pg_newlocale_from_collation(collation)->collate_is_c) cmpstr = str_const->constvalue; else { diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index d82e816230..cb9f1b4f78 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -1266,33 +1266,6 @@ lookup_collation_cache(Oid collation) return cache_entry; } - -/* - * Detect whether collation's LC_COLLATE property is C - */ -bool -lc_collate_is_c(Oid collation) -{ - /* - * If we're asked about "collation 0", return false, so that the code will - * go into the non-C path and report that the collation is bogus. - */ - if (!OidIsValid(collation)) - return false; - - /* - * If we're asked about the built-in C/POSIX collations, we know that. - */ - if (collation == C_COLLATION_OID || - collation == POSIX_COLLATION_OID) - return true; - - /* - * Otherwise, we have to consult pg_collation, but we cache that. - */ - return pg_newlocale_from_collation(collation)->collate_is_c; -} - /* * Detect whether collation's LC_CTYPE property is C */ @@ -1571,12 +1544,12 @@ pg_newlocale_from_collation(Oid collid) { collation_cache_entry *cache_entry; - /* Callers must pass a valid OID */ - Assert(OidIsValid(collid)); - if (collid == DEFAULT_COLLATION_OID) return &default_locale; + if (!OidIsValid(collid)) + elog(ERROR, "cache lookup failed for collation %u", collid); + if (last_collation_cache_oid == collid) return last_collation_cache_locale; diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index bf42393bec..03d7fb5f48 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -4646,6 +4646,7 @@ static char * convert_string_datum(Datum value, Oid typid, Oid collid, bool *failure) { char *val; + pg_locale_t mylocale; switch (typid) { @@ -4671,9 +4672,10 @@ convert_string_datum(Datum value, Oid typid, Oid collid, bool *failure) return NULL; } - if (!lc_collate_is_c(collid)) + mylocale = pg_newlocale_from_collation(collid); + + if (!mylocale->collate_is_c) { - pg_locale_t mylocale = pg_newlocale_from_collation(collid); char *xfrmstr; size_t xfrmlen; size_t xfrmlen2 PG_USED_FOR_ASSERTS_ONLY; diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c index 0c219dcc77..d2d1c5709d 100644 --- a/src/backend/utils/adt/varchar.c +++ b/src/backend/utils/adt/varchar.c @@ -748,20 +748,16 @@ bpchareq(PG_FUNCTION_ARGS) len2; bool result; Oid collid = PG_GET_COLLATION(); - bool locale_is_c = false; - pg_locale_t mylocale = 0; + pg_locale_t mylocale; check_collation_set(collid); len1 = bcTruelen(arg1); len2 = bcTruelen(arg2); - if (lc_collate_is_c(collid)) - locale_is_c = true; - else - mylocale = pg_newlocale_from_collation(collid); + mylocale = pg_newlocale_from_collation(collid); - if (locale_is_c || pg_locale_deterministic(mylocale)) + if (mylocale->collate_is_c || pg_locale_deterministic(mylocale)) { /* * Since we only care about equality or not-equality, we can avoid all @@ -793,20 +789,16 @@ bpcharne(PG_FUNCTION_ARGS) len2; bool result; Oid collid = PG_GET_COLLATION(); - bool locale_is_c = false; - pg_locale_t mylocale = 0; + pg_locale_t mylocale; check_collation_set(collid); len1 = bcTruelen(arg1); len2 = bcTruelen(arg2); - if (lc_collate_is_c(collid)) - locale_is_c = true; - else - mylocale = pg_newlocale_from_collation(collid); + mylocale = pg_newlocale_from_collation(collid); - if (locale_is_c || pg_locale_deterministic(mylocale)) + if (mylocale->collate_is_c || pg_locale_deterministic(mylocale)) { /* * Since we only care about equality or not-equality, we can avoid all diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index 7c6391a276..1862943888 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -1538,10 +1538,13 @@ int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid) { int result; + pg_locale_t mylocale; check_collation_set(collid); - if (lc_collate_is_c(collid)) + mylocale = pg_newlocale_from_collation(collid); + + if (mylocale->collate_is_c) { result = memcmp(arg1, arg2, Min(len1, len2)); if ((result == 0) && (len1 != len2)) @@ -1549,10 +1552,6 @@ varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid) } else { - pg_locale_t mylocale; - - mylocale = pg_newlocale_from_collation(collid); - /* * memcmp() can't tell us which of two unequal strings sorts first, * but it's a cheap way to tell if they're equal. Testing shows that @@ -1859,10 +1858,12 @@ varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid) bool abbreviate = ssup->abbreviate; bool collate_c = false; VarStringSortSupport *sss; - pg_locale_t locale = 0; + pg_locale_t locale; check_collation_set(collid); + locale = pg_newlocale_from_collation(collid); + /* * If possible, set ssup->comparator to a function which can be used to * directly compare two datums. If we can do this, we'll avoid the @@ -1876,7 +1877,7 @@ varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid) * varstrfastcmp_c, bpcharfastcmp_c, or namefastcmp_c, all of which use * memcmp() rather than strcoll(). */ - if (lc_collate_is_c(collid)) + if (locale->collate_is_c) { if (typid == BPCHAROID) ssup->comparator = bpcharfastcmp_c; @@ -1893,13 +1894,6 @@ varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid) } else { - /* - * We need a collation-sensitive comparison. To make things faster, - * we'll figure out the collation based on the locale id and cache the - * result. - */ - locale = pg_newlocale_from_collation(collid); - /* * We use varlenafastcmp_locale except for type NAME. */ @@ -1950,7 +1944,10 @@ varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid) sss->last_len2 = -1; /* Initialize */ sss->last_returned = 0; - sss->locale = locale; + if (collate_c) + sss->locale = NULL; + else + sss->locale = locale; /* * To avoid somehow confusing a strxfrm() blob and an original string, @@ -2536,12 +2533,15 @@ btvarstrequalimage(PG_FUNCTION_ARGS) { /* Oid opcintype = PG_GETARG_OID(0); */ Oid collid = PG_GET_COLLATION(); + pg_locale_t locale; check_collation_set(collid); - if (lc_collate_is_c(collid) || + locale = pg_newlocale_from_collation(collid); + + if (locale->collate_is_c || collid == DEFAULT_COLLATION_OID || - get_collation_isdeterministic(collid)) + pg_locale_deterministic(locale)) PG_RETURN_BOOL(true); else PG_RETURN_BOOL(false); diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h index f41d33975b..8ec24437f4 100644 --- a/src/include/utils/pg_locale.h +++ b/src/include/utils/pg_locale.h @@ -54,7 +54,6 @@ extern PGDLLIMPORT bool database_ctype_is_c; extern bool check_locale(int category, const char *locale, char **canonname); extern char *pg_perm_setlocale(int category, const char *locale); -extern bool lc_collate_is_c(Oid collation); extern bool lc_ctype_is_c(Oid collation); /*