Skip to content

Commit 51edc4c

Browse files
committed
Remove lc_ctype_is_c().
Instead always fetch the locale and look at the ctype_is_c field. hba.c relies on regexes working for the C locale without needing catalog access, which worked before due to a special case for C_COLLATION_OID in lc_ctype_is_c(). Move the special case to pg_set_regex_collation() now that lc_ctype_is_c() is gone. Author: Andreas Karlsson Discussion: https://postgr.es/m/60929555-4709-40a7-b136-bcb44cff5a3c@proxel.se
1 parent 129a2f6 commit 51edc4c

File tree

7 files changed

+39
-61
lines changed

7 files changed

+39
-61
lines changed

src/backend/regex/regc_pg_locale.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,13 @@ pg_set_regex_collation(Oid collation)
246246
errhint("Use the COLLATE clause to set the collation explicitly.")));
247247
}
248248

249-
if (lc_ctype_is_c(collation))
249+
if (collation == C_COLLATION_OID)
250250
{
251-
/* C/POSIX collations use this path regardless of database encoding */
251+
/*
252+
* Some callers expect regexes to work for C_COLLATION_OID before
253+
* catalog access is available, so we can't call
254+
* pg_newlocale_from_collation().
255+
*/
252256
strategy = PG_REGEX_STRATEGY_C;
253257
collation = C_COLLATION_OID;
254258
}
@@ -261,7 +265,17 @@ pg_set_regex_collation(Oid collation)
261265
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
262266
errmsg("nondeterministic collations are not supported for regular expressions")));
263267

264-
if (locale->provider == COLLPROVIDER_BUILTIN)
268+
if (locale->ctype_is_c)
269+
{
270+
/*
271+
* C/POSIX collations use this path regardless of database
272+
* encoding
273+
*/
274+
strategy = PG_REGEX_STRATEGY_C;
275+
locale = 0;
276+
collation = C_COLLATION_OID;
277+
}
278+
else if (locale->provider == COLLPROVIDER_BUILTIN)
265279
{
266280
Assert(GetDatabaseEncoding() == PG_UTF8);
267281
strategy = PG_REGEX_STRATEGY_BUILTIN;
@@ -274,6 +288,7 @@ pg_set_regex_collation(Oid collation)
274288
#endif
275289
else
276290
{
291+
Assert(locale->provider == COLLPROVIDER_LIBC);
277292
if (GetDatabaseEncoding() == PG_UTF8)
278293
strategy = PG_REGEX_STRATEGY_LIBC_WIDE;
279294
else

src/backend/utils/adt/formatting.c

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,6 +1636,7 @@ char *
16361636
str_tolower(const char *buff, size_t nbytes, Oid collid)
16371637
{
16381638
char *result;
1639+
pg_locale_t mylocale;
16391640

16401641
if (!buff)
16411642
return NULL;
@@ -1653,17 +1654,15 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
16531654
errhint("Use the COLLATE clause to set the collation explicitly.")));
16541655
}
16551656

1657+
mylocale = pg_newlocale_from_collation(collid);
1658+
16561659
/* C/POSIX collations use this path regardless of database encoding */
1657-
if (lc_ctype_is_c(collid))
1660+
if (mylocale->ctype_is_c)
16581661
{
16591662
result = asc_tolower(buff, nbytes);
16601663
}
16611664
else
16621665
{
1663-
pg_locale_t mylocale;
1664-
1665-
mylocale = pg_newlocale_from_collation(collid);
1666-
16671666
#ifdef USE_ICU
16681667
if (mylocale->provider == COLLPROVIDER_ICU)
16691668
{
@@ -1774,6 +1773,7 @@ char *
17741773
str_toupper(const char *buff, size_t nbytes, Oid collid)
17751774
{
17761775
char *result;
1776+
pg_locale_t mylocale;
17771777

17781778
if (!buff)
17791779
return NULL;
@@ -1791,17 +1791,15 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
17911791
errhint("Use the COLLATE clause to set the collation explicitly.")));
17921792
}
17931793

1794+
mylocale = pg_newlocale_from_collation(collid);
1795+
17941796
/* C/POSIX collations use this path regardless of database encoding */
1795-
if (lc_ctype_is_c(collid))
1797+
if (mylocale->ctype_is_c)
17961798
{
17971799
result = asc_toupper(buff, nbytes);
17981800
}
17991801
else
18001802
{
1801-
pg_locale_t mylocale;
1802-
1803-
mylocale = pg_newlocale_from_collation(collid);
1804-
18051803
#ifdef USE_ICU
18061804
if (mylocale->provider == COLLPROVIDER_ICU)
18071805
{
@@ -1954,6 +1952,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
19541952
{
19551953
char *result;
19561954
int wasalnum = false;
1955+
pg_locale_t mylocale;
19571956

19581957
if (!buff)
19591958
return NULL;
@@ -1971,17 +1970,15 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
19711970
errhint("Use the COLLATE clause to set the collation explicitly.")));
19721971
}
19731972

1973+
mylocale = pg_newlocale_from_collation(collid);
1974+
19741975
/* C/POSIX collations use this path regardless of database encoding */
1975-
if (lc_ctype_is_c(collid))
1976+
if (mylocale->ctype_is_c)
19761977
{
19771978
result = asc_initcap(buff, nbytes);
19781979
}
19791980
else
19801981
{
1981-
pg_locale_t mylocale;
1982-
1983-
mylocale = pg_newlocale_from_collation(collid);
1984-
19851982
#ifdef USE_ICU
19861983
if (mylocale->provider == COLLPROVIDER_ICU)
19871984
{

src/backend/utils/adt/like.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ SB_lower_char(unsigned char c, pg_locale_t locale, bool locale_is_c)
147147
static inline int
148148
GenericMatchText(const char *s, int slen, const char *p, int plen, Oid collation)
149149
{
150-
if (collation && !lc_ctype_is_c(collation))
150+
if (collation)
151151
{
152152
pg_locale_t locale = pg_newlocale_from_collation(collation);
153153

src/backend/utils/adt/like_support.c

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ static Selectivity regex_selectivity(const char *patt, int pattlen,
100100
bool case_insensitive,
101101
int fixed_prefix_len);
102102
static int pattern_char_isalpha(char c, bool is_multibyte,
103-
pg_locale_t locale, bool locale_is_c);
103+
pg_locale_t locale);
104104
static Const *make_greater_string(const Const *str_const, FmgrInfo *ltproc,
105105
Oid collation);
106106
static Datum string_to_datum(const char *str, Oid datatype);
@@ -1000,7 +1000,6 @@ like_fixed_prefix(Const *patt_const, bool case_insensitive, Oid collation,
10001000
match_pos;
10011001
bool is_multibyte = (pg_database_encoding_max_length() > 1);
10021002
pg_locale_t locale = 0;
1003-
bool locale_is_c = false;
10041003

10051004
/* the right-hand const is type text or bytea */
10061005
Assert(typeid == BYTEAOID || typeid == TEXTOID);
@@ -1024,11 +1023,7 @@ like_fixed_prefix(Const *patt_const, bool case_insensitive, Oid collation,
10241023
errhint("Use the COLLATE clause to set the collation explicitly.")));
10251024
}
10261025

1027-
/* If case-insensitive, we need locale info */
1028-
if (lc_ctype_is_c(collation))
1029-
locale_is_c = true;
1030-
else
1031-
locale = pg_newlocale_from_collation(collation);
1026+
locale = pg_newlocale_from_collation(collation);
10321027
}
10331028

10341029
if (typeid != BYTEAOID)
@@ -1065,7 +1060,7 @@ like_fixed_prefix(Const *patt_const, bool case_insensitive, Oid collation,
10651060

10661061
/* Stop if case-varying character (it's sort of a wildcard) */
10671062
if (case_insensitive &&
1068-
pattern_char_isalpha(patt[pos], is_multibyte, locale, locale_is_c))
1063+
pattern_char_isalpha(patt[pos], is_multibyte, locale))
10691064
break;
10701065

10711066
match[match_pos++] = patt[pos];
@@ -1499,16 +1494,16 @@ regex_selectivity(const char *patt, int pattlen, bool case_insensitive,
14991494
*/
15001495
static int
15011496
pattern_char_isalpha(char c, bool is_multibyte,
1502-
pg_locale_t locale, bool locale_is_c)
1497+
pg_locale_t locale)
15031498
{
1504-
if (locale_is_c)
1499+
if (locale->ctype_is_c)
15051500
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
15061501
else if (is_multibyte && IS_HIGHBIT_SET(c))
15071502
return true;
1508-
else if (locale && locale->provider == COLLPROVIDER_ICU)
1503+
else if (locale->provider == COLLPROVIDER_ICU)
15091504
return IS_HIGHBIT_SET(c) ||
15101505
(c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
1511-
else if (locale && locale->provider == COLLPROVIDER_LIBC)
1506+
else if (locale->provider == COLLPROVIDER_LIBC)
15121507
return isalpha_l((unsigned char) c, locale->info.lt);
15131508
else
15141509
return isalpha((unsigned char) c);

src/backend/utils/adt/pg_locale.c

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,32 +1266,6 @@ lookup_collation_cache(Oid collation)
12661266
return cache_entry;
12671267
}
12681268

1269-
/*
1270-
* Detect whether collation's LC_CTYPE property is C
1271-
*/
1272-
bool
1273-
lc_ctype_is_c(Oid collation)
1274-
{
1275-
/*
1276-
* If we're asked about "collation 0", return false, so that the code will
1277-
* go into the non-C path and report that the collation is bogus.
1278-
*/
1279-
if (!OidIsValid(collation))
1280-
return false;
1281-
1282-
/*
1283-
* If we're asked about the built-in C/POSIX collations, we know that.
1284-
*/
1285-
if (collation == C_COLLATION_OID ||
1286-
collation == POSIX_COLLATION_OID)
1287-
return true;
1288-
1289-
/*
1290-
* Otherwise, we have to consult pg_collation, but we cache that.
1291-
*/
1292-
return pg_newlocale_from_collation(collation)->ctype_is_c;
1293-
}
1294-
12951269
/* simple subroutine for reporting errors from newlocale() */
12961270
static void
12971271
report_newlocale_failure(const char *localename)

src/include/catalog/pg_collation.dat

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
descr => 'standard C collation',
2020
collname => 'C', collprovider => 'c', collencoding => '-1',
2121
collcollate => 'C', collctype => 'C' },
22-
{ oid => '951', oid_symbol => 'POSIX_COLLATION_OID',
23-
descr => 'standard POSIX collation',
22+
{ oid => '951', descr => 'standard POSIX collation',
2423
collname => 'POSIX', collprovider => 'c', collencoding => '-1',
2524
collcollate => 'POSIX', collctype => 'POSIX' },
2625
{ oid => '962', descr => 'sorts by Unicode code point, C character semantics',

src/include/utils/pg_locale.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ extern PGDLLIMPORT bool database_ctype_is_c;
5454
extern bool check_locale(int category, const char *locale, char **canonname);
5555
extern char *pg_perm_setlocale(int category, const char *locale);
5656

57-
extern bool lc_ctype_is_c(Oid collation);
58-
5957
/*
6058
* Return the POSIX lconv struct (contains number/money formatting
6159
* information) with locale information for all categories.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy