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
This commit is contained in:
Jeff Davis 2024-09-04 12:30:14 -07:00
parent 83eb481d52
commit 06421b0843
8 changed files with 35 additions and 73 deletions

View File

@ -427,7 +427,7 @@ spg_text_inner_consistent(PG_FUNCTION_ARGS)
{ {
spgInnerConsistentIn *in = (spgInnerConsistentIn *) PG_GETARG_POINTER(0); spgInnerConsistentIn *in = (spgInnerConsistentIn *) PG_GETARG_POINTER(0);
spgInnerConsistentOut *out = (spgInnerConsistentOut *) PG_GETARG_POINTER(1); 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 *reconstructedValue;
text *reconstrText; text *reconstrText;
int maxReconstrLen; int maxReconstrLen;

View File

@ -377,13 +377,9 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
if (!OidIsValid(newoid)) if (!OidIsValid(newoid))
return InvalidObjectAddress; return InvalidObjectAddress;
/* /* Check that the locales can be loaded. */
* Check that the locales can be loaded. NB: pg_newlocale_from_collation
* is only supposed to be called on non-C-equivalent locales.
*/
CommandCounterIncrement(); 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); ObjectAddressSet(address, CollationRelationId, newoid);

View File

@ -433,7 +433,7 @@ match_pattern_prefix(Node *leftop,
* collation. * collation.
*/ */
if (collation_aware && if (collation_aware &&
!lc_collate_is_c(indexcollation)) !pg_newlocale_from_collation(indexcollation)->collate_is_c)
return NIL; return NIL;
/* /*
@ -1603,7 +1603,7 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc, Oid collation)
else else
workstr = TextDatumGetCString(str_const->constvalue); workstr = TextDatumGetCString(str_const->constvalue);
len = strlen(workstr); 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; cmpstr = str_const->constvalue;
else else
{ {

View File

@ -1266,33 +1266,6 @@ lookup_collation_cache(Oid collation)
return cache_entry; 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 * Detect whether collation's LC_CTYPE property is C
*/ */
@ -1571,12 +1544,12 @@ pg_newlocale_from_collation(Oid collid)
{ {
collation_cache_entry *cache_entry; collation_cache_entry *cache_entry;
/* Callers must pass a valid OID */
Assert(OidIsValid(collid));
if (collid == DEFAULT_COLLATION_OID) if (collid == DEFAULT_COLLATION_OID)
return &default_locale; return &default_locale;
if (!OidIsValid(collid))
elog(ERROR, "cache lookup failed for collation %u", collid);
if (last_collation_cache_oid == collid) if (last_collation_cache_oid == collid)
return last_collation_cache_locale; return last_collation_cache_locale;

View File

@ -4646,6 +4646,7 @@ static char *
convert_string_datum(Datum value, Oid typid, Oid collid, bool *failure) convert_string_datum(Datum value, Oid typid, Oid collid, bool *failure)
{ {
char *val; char *val;
pg_locale_t mylocale;
switch (typid) switch (typid)
{ {
@ -4671,9 +4672,10 @@ convert_string_datum(Datum value, Oid typid, Oid collid, bool *failure)
return NULL; 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; char *xfrmstr;
size_t xfrmlen; size_t xfrmlen;
size_t xfrmlen2 PG_USED_FOR_ASSERTS_ONLY; size_t xfrmlen2 PG_USED_FOR_ASSERTS_ONLY;

View File

@ -748,20 +748,16 @@ bpchareq(PG_FUNCTION_ARGS)
len2; len2;
bool result; bool result;
Oid collid = PG_GET_COLLATION(); Oid collid = PG_GET_COLLATION();
bool locale_is_c = false; pg_locale_t mylocale;
pg_locale_t mylocale = 0;
check_collation_set(collid); check_collation_set(collid);
len1 = bcTruelen(arg1); len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2); len2 = bcTruelen(arg2);
if (lc_collate_is_c(collid)) mylocale = pg_newlocale_from_collation(collid);
locale_is_c = true;
else
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 * Since we only care about equality or not-equality, we can avoid all
@ -793,20 +789,16 @@ bpcharne(PG_FUNCTION_ARGS)
len2; len2;
bool result; bool result;
Oid collid = PG_GET_COLLATION(); Oid collid = PG_GET_COLLATION();
bool locale_is_c = false; pg_locale_t mylocale;
pg_locale_t mylocale = 0;
check_collation_set(collid); check_collation_set(collid);
len1 = bcTruelen(arg1); len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2); len2 = bcTruelen(arg2);
if (lc_collate_is_c(collid)) mylocale = pg_newlocale_from_collation(collid);
locale_is_c = true;
else
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 * Since we only care about equality or not-equality, we can avoid all

View File

@ -1538,10 +1538,13 @@ int
varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid) varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
{ {
int result; int result;
pg_locale_t mylocale;
check_collation_set(collid); 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)); result = memcmp(arg1, arg2, Min(len1, len2));
if ((result == 0) && (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 else
{ {
pg_locale_t mylocale;
mylocale = pg_newlocale_from_collation(collid);
/* /*
* memcmp() can't tell us which of two unequal strings sorts first, * 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 * 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 abbreviate = ssup->abbreviate;
bool collate_c = false; bool collate_c = false;
VarStringSortSupport *sss; VarStringSortSupport *sss;
pg_locale_t locale = 0; pg_locale_t locale;
check_collation_set(collid); check_collation_set(collid);
locale = pg_newlocale_from_collation(collid);
/* /*
* If possible, set ssup->comparator to a function which can be used to * 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 * 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 * varstrfastcmp_c, bpcharfastcmp_c, or namefastcmp_c, all of which use
* memcmp() rather than strcoll(). * memcmp() rather than strcoll().
*/ */
if (lc_collate_is_c(collid)) if (locale->collate_is_c)
{ {
if (typid == BPCHAROID) if (typid == BPCHAROID)
ssup->comparator = bpcharfastcmp_c; ssup->comparator = bpcharfastcmp_c;
@ -1893,13 +1894,6 @@ varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
} }
else 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. * We use varlenafastcmp_locale except for type NAME.
*/ */
@ -1950,7 +1944,10 @@ varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
sss->last_len2 = -1; sss->last_len2 = -1;
/* Initialize */ /* Initialize */
sss->last_returned = 0; 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, * 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 opcintype = PG_GETARG_OID(0); */
Oid collid = PG_GET_COLLATION(); Oid collid = PG_GET_COLLATION();
pg_locale_t locale;
check_collation_set(collid); 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 || collid == DEFAULT_COLLATION_OID ||
get_collation_isdeterministic(collid)) pg_locale_deterministic(locale))
PG_RETURN_BOOL(true); PG_RETURN_BOOL(true);
else else
PG_RETURN_BOOL(false); PG_RETURN_BOOL(false);

View File

@ -54,7 +54,6 @@ extern PGDLLIMPORT bool database_ctype_is_c;
extern bool check_locale(int category, const char *locale, char **canonname); extern bool check_locale(int category, const char *locale, char **canonname);
extern char *pg_perm_setlocale(int category, const char *locale); 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); extern bool lc_ctype_is_c(Oid collation);
/* /*