Remove support for null pg_locale_t most places.

Previously, passing NULL for pg_locale_t meant "use the libc provider
and the server environment". Now that the database collation is
represented as a proper pg_locale_t (not dependent on setlocale()),
remove special cases for NULL.

Leave wchar2char() and char2wchar() unchanged for now, because the
callers don't always have a libc-based pg_locale_t available.

Discussion: https://postgr.es/m/cfd9eb85-c52a-4ec9-a90e-a5e4de56e57d@eisentraut.org
Reviewed-by: Peter Eisentraut, Andreas Karlsson
This commit is contained in:
Jeff Davis 2024-08-05 18:15:57 -07:00
parent f80b09bac8
commit e9931bfb75
7 changed files with 73 additions and 255 deletions

View File

@ -268,7 +268,7 @@ hashtext(PG_FUNCTION_ARGS)
{ {
text *key = PG_GETARG_TEXT_PP(0); text *key = PG_GETARG_TEXT_PP(0);
Oid collid = PG_GET_COLLATION(); Oid collid = PG_GET_COLLATION();
pg_locale_t mylocale = 0; pg_locale_t mylocale;
Datum result; Datum result;
if (!collid) if (!collid)
@ -277,8 +277,7 @@ hashtext(PG_FUNCTION_ARGS)
errmsg("could not determine which collation to use for string hashing"), errmsg("could not determine which collation to use for string hashing"),
errhint("Use the COLLATE clause to set the collation explicitly."))); errhint("Use the COLLATE clause to set the collation explicitly.")));
if (!lc_collate_is_c(collid)) mylocale = pg_newlocale_from_collation(collid);
mylocale = pg_newlocale_from_collation(collid);
if (pg_locale_deterministic(mylocale)) if (pg_locale_deterministic(mylocale))
{ {
@ -324,7 +323,7 @@ hashtextextended(PG_FUNCTION_ARGS)
{ {
text *key = PG_GETARG_TEXT_PP(0); text *key = PG_GETARG_TEXT_PP(0);
Oid collid = PG_GET_COLLATION(); Oid collid = PG_GET_COLLATION();
pg_locale_t mylocale = 0; pg_locale_t mylocale;
Datum result; Datum result;
if (!collid) if (!collid)
@ -333,8 +332,7 @@ hashtextextended(PG_FUNCTION_ARGS)
errmsg("could not determine which collation to use for string hashing"), errmsg("could not determine which collation to use for string hashing"),
errhint("Use the COLLATE clause to set the collation explicitly."))); errhint("Use the COLLATE clause to set the collation explicitly.")));
if (!lc_collate_is_c(collid)) mylocale = pg_newlocale_from_collation(collid);
mylocale = pg_newlocale_from_collation(collid);
if (pg_locale_deterministic(mylocale)) if (pg_locale_deterministic(mylocale))
{ {

View File

@ -67,8 +67,6 @@ typedef enum
{ {
PG_REGEX_LOCALE_C, /* C locale (encoding independent) */ PG_REGEX_LOCALE_C, /* C locale (encoding independent) */
PG_REGEX_BUILTIN, /* built-in Unicode semantics */ PG_REGEX_BUILTIN, /* built-in Unicode semantics */
PG_REGEX_LOCALE_WIDE, /* Use <wctype.h> functions */
PG_REGEX_LOCALE_1BYTE, /* Use <ctype.h> functions */
PG_REGEX_LOCALE_WIDE_L, /* Use locale_t <wctype.h> functions */ PG_REGEX_LOCALE_WIDE_L, /* Use locale_t <wctype.h> functions */
PG_REGEX_LOCALE_1BYTE_L, /* Use locale_t <ctype.h> functions */ PG_REGEX_LOCALE_1BYTE_L, /* Use locale_t <ctype.h> functions */
PG_REGEX_LOCALE_ICU, /* Use ICU uchar.h functions */ PG_REGEX_LOCALE_ICU, /* Use ICU uchar.h functions */
@ -261,13 +259,13 @@ pg_set_regex_collation(Oid collation)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("nondeterministic collations are not supported for regular expressions"))); errmsg("nondeterministic collations are not supported for regular expressions")));
if (pg_regex_locale && pg_regex_locale->provider == COLLPROVIDER_BUILTIN) if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
{ {
Assert(GetDatabaseEncoding() == PG_UTF8); Assert(GetDatabaseEncoding() == PG_UTF8);
pg_regex_strategy = PG_REGEX_BUILTIN; pg_regex_strategy = PG_REGEX_BUILTIN;
} }
#ifdef USE_ICU #ifdef USE_ICU
else if (pg_regex_locale && pg_regex_locale->provider == COLLPROVIDER_ICU) else if (pg_regex_locale->provider == COLLPROVIDER_ICU)
{ {
pg_regex_strategy = PG_REGEX_LOCALE_ICU; pg_regex_strategy = PG_REGEX_LOCALE_ICU;
} }
@ -275,19 +273,9 @@ pg_set_regex_collation(Oid collation)
else else
{ {
if (GetDatabaseEncoding() == PG_UTF8) if (GetDatabaseEncoding() == PG_UTF8)
{ pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
if (pg_regex_locale)
pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE;
}
else else
{ pg_regex_strategy = PG_REGEX_LOCALE_1BYTE_L;
if (pg_regex_locale)
pg_regex_strategy = PG_REGEX_LOCALE_1BYTE_L;
else
pg_regex_strategy = PG_REGEX_LOCALE_1BYTE;
}
} }
pg_regex_collation = collation; pg_regex_collation = collation;
@ -304,13 +292,6 @@ pg_wc_isdigit(pg_wchar c)
(pg_char_properties[c] & PG_ISDIGIT)); (pg_char_properties[c] & PG_ISDIGIT));
case PG_REGEX_BUILTIN: case PG_REGEX_BUILTIN:
return pg_u_isdigit(c, true); return pg_u_isdigit(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
/* FALL THRU */
case PG_REGEX_LOCALE_1BYTE:
return (c <= (pg_wchar) UCHAR_MAX &&
isdigit((unsigned char) c));
case PG_REGEX_LOCALE_WIDE_L: case PG_REGEX_LOCALE_WIDE_L:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF) if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit_l((wint_t) c, pg_regex_locale->info.lt); return iswdigit_l((wint_t) c, pg_regex_locale->info.lt);
@ -338,13 +319,6 @@ pg_wc_isalpha(pg_wchar c)
(pg_char_properties[c] & PG_ISALPHA)); (pg_char_properties[c] & PG_ISALPHA));
case PG_REGEX_BUILTIN: case PG_REGEX_BUILTIN:
return pg_u_isalpha(c); return pg_u_isalpha(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalpha((wint_t) c);
/* FALL THRU */
case PG_REGEX_LOCALE_1BYTE:
return (c <= (pg_wchar) UCHAR_MAX &&
isalpha((unsigned char) c));
case PG_REGEX_LOCALE_WIDE_L: case PG_REGEX_LOCALE_WIDE_L:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF) if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalpha_l((wint_t) c, pg_regex_locale->info.lt); return iswalpha_l((wint_t) c, pg_regex_locale->info.lt);
@ -372,13 +346,6 @@ pg_wc_isalnum(pg_wchar c)
(pg_char_properties[c] & PG_ISALNUM)); (pg_char_properties[c] & PG_ISALNUM));
case PG_REGEX_BUILTIN: case PG_REGEX_BUILTIN:
return pg_u_isalnum(c, true); return pg_u_isalnum(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
/* FALL THRU */
case PG_REGEX_LOCALE_1BYTE:
return (c <= (pg_wchar) UCHAR_MAX &&
isalnum((unsigned char) c));
case PG_REGEX_LOCALE_WIDE_L: case PG_REGEX_LOCALE_WIDE_L:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF) if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum_l((wint_t) c, pg_regex_locale->info.lt); return iswalnum_l((wint_t) c, pg_regex_locale->info.lt);
@ -415,13 +382,6 @@ pg_wc_isupper(pg_wchar c)
(pg_char_properties[c] & PG_ISUPPER)); (pg_char_properties[c] & PG_ISUPPER));
case PG_REGEX_BUILTIN: case PG_REGEX_BUILTIN:
return pg_u_isupper(c); return pg_u_isupper(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswupper((wint_t) c);
/* FALL THRU */
case PG_REGEX_LOCALE_1BYTE:
return (c <= (pg_wchar) UCHAR_MAX &&
isupper((unsigned char) c));
case PG_REGEX_LOCALE_WIDE_L: case PG_REGEX_LOCALE_WIDE_L:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF) if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswupper_l((wint_t) c, pg_regex_locale->info.lt); return iswupper_l((wint_t) c, pg_regex_locale->info.lt);
@ -449,13 +409,6 @@ pg_wc_islower(pg_wchar c)
(pg_char_properties[c] & PG_ISLOWER)); (pg_char_properties[c] & PG_ISLOWER));
case PG_REGEX_BUILTIN: case PG_REGEX_BUILTIN:
return pg_u_islower(c); return pg_u_islower(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswlower((wint_t) c);
/* FALL THRU */
case PG_REGEX_LOCALE_1BYTE:
return (c <= (pg_wchar) UCHAR_MAX &&
islower((unsigned char) c));
case PG_REGEX_LOCALE_WIDE_L: case PG_REGEX_LOCALE_WIDE_L:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF) if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswlower_l((wint_t) c, pg_regex_locale->info.lt); return iswlower_l((wint_t) c, pg_regex_locale->info.lt);
@ -483,13 +436,6 @@ pg_wc_isgraph(pg_wchar c)
(pg_char_properties[c] & PG_ISGRAPH)); (pg_char_properties[c] & PG_ISGRAPH));
case PG_REGEX_BUILTIN: case PG_REGEX_BUILTIN:
return pg_u_isgraph(c); return pg_u_isgraph(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswgraph((wint_t) c);
/* FALL THRU */
case PG_REGEX_LOCALE_1BYTE:
return (c <= (pg_wchar) UCHAR_MAX &&
isgraph((unsigned char) c));
case PG_REGEX_LOCALE_WIDE_L: case PG_REGEX_LOCALE_WIDE_L:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF) if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswgraph_l((wint_t) c, pg_regex_locale->info.lt); return iswgraph_l((wint_t) c, pg_regex_locale->info.lt);
@ -517,13 +463,6 @@ pg_wc_isprint(pg_wchar c)
(pg_char_properties[c] & PG_ISPRINT)); (pg_char_properties[c] & PG_ISPRINT));
case PG_REGEX_BUILTIN: case PG_REGEX_BUILTIN:
return pg_u_isprint(c); return pg_u_isprint(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswprint((wint_t) c);
/* FALL THRU */
case PG_REGEX_LOCALE_1BYTE:
return (c <= (pg_wchar) UCHAR_MAX &&
isprint((unsigned char) c));
case PG_REGEX_LOCALE_WIDE_L: case PG_REGEX_LOCALE_WIDE_L:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF) if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswprint_l((wint_t) c, pg_regex_locale->info.lt); return iswprint_l((wint_t) c, pg_regex_locale->info.lt);
@ -551,13 +490,6 @@ pg_wc_ispunct(pg_wchar c)
(pg_char_properties[c] & PG_ISPUNCT)); (pg_char_properties[c] & PG_ISPUNCT));
case PG_REGEX_BUILTIN: case PG_REGEX_BUILTIN:
return pg_u_ispunct(c, true); return pg_u_ispunct(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
/* FALL THRU */
case PG_REGEX_LOCALE_1BYTE:
return (c <= (pg_wchar) UCHAR_MAX &&
ispunct((unsigned char) c));
case PG_REGEX_LOCALE_WIDE_L: case PG_REGEX_LOCALE_WIDE_L:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF) if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct_l((wint_t) c, pg_regex_locale->info.lt); return iswpunct_l((wint_t) c, pg_regex_locale->info.lt);
@ -585,13 +517,6 @@ pg_wc_isspace(pg_wchar c)
(pg_char_properties[c] & PG_ISSPACE)); (pg_char_properties[c] & PG_ISSPACE));
case PG_REGEX_BUILTIN: case PG_REGEX_BUILTIN:
return pg_u_isspace(c); return pg_u_isspace(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswspace((wint_t) c);
/* FALL THRU */
case PG_REGEX_LOCALE_1BYTE:
return (c <= (pg_wchar) UCHAR_MAX &&
isspace((unsigned char) c));
case PG_REGEX_LOCALE_WIDE_L: case PG_REGEX_LOCALE_WIDE_L:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF) if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswspace_l((wint_t) c, pg_regex_locale->info.lt); return iswspace_l((wint_t) c, pg_regex_locale->info.lt);
@ -620,20 +545,6 @@ pg_wc_toupper(pg_wchar c)
return c; return c;
case PG_REGEX_BUILTIN: case PG_REGEX_BUILTIN:
return unicode_uppercase_simple(c); return unicode_uppercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
return pg_ascii_toupper((unsigned char) c);
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return towupper((wint_t) c);
/* FALL THRU */
case PG_REGEX_LOCALE_1BYTE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
return pg_ascii_toupper((unsigned char) c);
if (c <= (pg_wchar) UCHAR_MAX)
return toupper((unsigned char) c);
return c;
case PG_REGEX_LOCALE_WIDE_L: case PG_REGEX_LOCALE_WIDE_L:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF) if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return towupper_l((wint_t) c, pg_regex_locale->info.lt); return towupper_l((wint_t) c, pg_regex_locale->info.lt);
@ -662,20 +573,6 @@ pg_wc_tolower(pg_wchar c)
return c; return c;
case PG_REGEX_BUILTIN: case PG_REGEX_BUILTIN:
return unicode_lowercase_simple(c); return unicode_lowercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
return pg_ascii_tolower((unsigned char) c);
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return towlower((wint_t) c);
/* FALL THRU */
case PG_REGEX_LOCALE_1BYTE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
return pg_ascii_tolower((unsigned char) c);
if (c <= (pg_wchar) UCHAR_MAX)
return tolower((unsigned char) c);
return c;
case PG_REGEX_LOCALE_WIDE_L: case PG_REGEX_LOCALE_WIDE_L:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF) if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return towlower_l((wint_t) c, pg_regex_locale->info.lt); return towlower_l((wint_t) c, pg_regex_locale->info.lt);
@ -829,11 +726,9 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
case PG_REGEX_BUILTIN: case PG_REGEX_BUILTIN:
max_chr = (pg_wchar) MAX_SIMPLE_CHR; max_chr = (pg_wchar) MAX_SIMPLE_CHR;
break; break;
case PG_REGEX_LOCALE_WIDE:
case PG_REGEX_LOCALE_WIDE_L: case PG_REGEX_LOCALE_WIDE_L:
max_chr = (pg_wchar) MAX_SIMPLE_CHR; max_chr = (pg_wchar) MAX_SIMPLE_CHR;
break; break;
case PG_REGEX_LOCALE_1BYTE:
case PG_REGEX_LOCALE_1BYTE_L: case PG_REGEX_LOCALE_1BYTE_L:
#if MAX_SIMPLE_CHR >= UCHAR_MAX #if MAX_SIMPLE_CHR >= UCHAR_MAX
max_chr = (pg_wchar) UCHAR_MAX; max_chr = (pg_wchar) UCHAR_MAX;

View File

@ -1665,7 +1665,7 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
mylocale = pg_newlocale_from_collation(collid); mylocale = pg_newlocale_from_collation(collid);
#ifdef USE_ICU #ifdef USE_ICU
if (mylocale && mylocale->provider == COLLPROVIDER_ICU) if (mylocale->provider == COLLPROVIDER_ICU)
{ {
int32_t len_uchar; int32_t len_uchar;
int32_t len_conv; int32_t len_conv;
@ -1681,7 +1681,7 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
} }
else else
#endif #endif
if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN) if (mylocale->provider == COLLPROVIDER_BUILTIN)
{ {
const char *src = buff; const char *src = buff;
size_t srclen = nbytes; size_t srclen = nbytes;
@ -1710,7 +1710,7 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
} }
else else
{ {
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC); Assert(mylocale->provider == COLLPROVIDER_LIBC);
if (pg_database_encoding_max_length() > 1) if (pg_database_encoding_max_length() > 1)
{ {
@ -1730,12 +1730,7 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale); char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale);
for (curr_char = 0; workspace[curr_char] != 0; curr_char++) for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
{ workspace[curr_char] = towlower_l(workspace[curr_char], mylocale->info.lt);
if (mylocale)
workspace[curr_char] = towlower_l(workspace[curr_char], mylocale->info.lt);
else
workspace[curr_char] = towlower(workspace[curr_char]);
}
/* /*
* Make result large enough; case change might change number * Make result large enough; case change might change number
@ -1761,12 +1756,7 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
* collations you get exactly what the collation says. * collations you get exactly what the collation says.
*/ */
for (p = result; *p; p++) for (p = result; *p; p++)
{ *p = tolower_l((unsigned char) *p, mylocale->info.lt);
if (mylocale)
*p = tolower_l((unsigned char) *p, mylocale->info.lt);
else
*p = pg_tolower((unsigned char) *p);
}
} }
} }
} }
@ -1813,7 +1803,7 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
mylocale = pg_newlocale_from_collation(collid); mylocale = pg_newlocale_from_collation(collid);
#ifdef USE_ICU #ifdef USE_ICU
if (mylocale && mylocale->provider == COLLPROVIDER_ICU) if (mylocale->provider == COLLPROVIDER_ICU)
{ {
int32_t len_uchar, int32_t len_uchar,
len_conv; len_conv;
@ -1829,7 +1819,7 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
} }
else else
#endif #endif
if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN) if (mylocale->provider == COLLPROVIDER_BUILTIN)
{ {
const char *src = buff; const char *src = buff;
size_t srclen = nbytes; size_t srclen = nbytes;
@ -1858,7 +1848,7 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
} }
else else
{ {
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC); Assert(mylocale->provider == COLLPROVIDER_LIBC);
if (pg_database_encoding_max_length() > 1) if (pg_database_encoding_max_length() > 1)
{ {
@ -1878,12 +1868,7 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale); char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale);
for (curr_char = 0; workspace[curr_char] != 0; curr_char++) for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
{ workspace[curr_char] = towupper_l(workspace[curr_char], mylocale->info.lt);
if (mylocale)
workspace[curr_char] = towupper_l(workspace[curr_char], mylocale->info.lt);
else
workspace[curr_char] = towupper(workspace[curr_char]);
}
/* /*
* Make result large enough; case change might change number * Make result large enough; case change might change number
@ -1909,12 +1894,7 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
* collations you get exactly what the collation says. * collations you get exactly what the collation says.
*/ */
for (p = result; *p; p++) for (p = result; *p; p++)
{ *p = toupper_l((unsigned char) *p, mylocale->info.lt);
if (mylocale)
*p = toupper_l((unsigned char) *p, mylocale->info.lt);
else
*p = pg_toupper((unsigned char) *p);
}
} }
} }
} }
@ -2003,7 +1983,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
mylocale = pg_newlocale_from_collation(collid); mylocale = pg_newlocale_from_collation(collid);
#ifdef USE_ICU #ifdef USE_ICU
if (mylocale && mylocale->provider == COLLPROVIDER_ICU) if (mylocale->provider == COLLPROVIDER_ICU)
{ {
int32_t len_uchar, int32_t len_uchar,
len_conv; len_conv;
@ -2019,7 +1999,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
} }
else else
#endif #endif
if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN) if (mylocale->provider == COLLPROVIDER_BUILTIN)
{ {
const char *src = buff; const char *src = buff;
size_t srclen = nbytes; size_t srclen = nbytes;
@ -2060,7 +2040,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
} }
else else
{ {
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC); Assert(mylocale->provider == COLLPROVIDER_LIBC);
if (pg_database_encoding_max_length() > 1) if (pg_database_encoding_max_length() > 1)
{ {
@ -2081,22 +2061,11 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
for (curr_char = 0; workspace[curr_char] != 0; curr_char++) for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
{ {
if (mylocale) if (wasalnum)
{ workspace[curr_char] = towlower_l(workspace[curr_char], mylocale->info.lt);
if (wasalnum)
workspace[curr_char] = towlower_l(workspace[curr_char], mylocale->info.lt);
else
workspace[curr_char] = towupper_l(workspace[curr_char], mylocale->info.lt);
wasalnum = iswalnum_l(workspace[curr_char], mylocale->info.lt);
}
else else
{ workspace[curr_char] = towupper_l(workspace[curr_char], mylocale->info.lt);
if (wasalnum) wasalnum = iswalnum_l(workspace[curr_char], mylocale->info.lt);
workspace[curr_char] = towlower(workspace[curr_char]);
else
workspace[curr_char] = towupper(workspace[curr_char]);
wasalnum = iswalnum(workspace[curr_char]);
}
} }
/* /*
@ -2124,22 +2093,11 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
*/ */
for (p = result; *p; p++) for (p = result; *p; p++)
{ {
if (mylocale) if (wasalnum)
{ *p = tolower_l((unsigned char) *p, mylocale->info.lt);
if (wasalnum)
*p = tolower_l((unsigned char) *p, mylocale->info.lt);
else
*p = toupper_l((unsigned char) *p, mylocale->info.lt);
wasalnum = isalnum_l((unsigned char) *p, mylocale->info.lt);
}
else else
{ *p = toupper_l((unsigned char) *p, mylocale->info.lt);
if (wasalnum) wasalnum = isalnum_l((unsigned char) *p, mylocale->info.lt);
*p = pg_tolower((unsigned char) *p);
else
*p = pg_toupper((unsigned char) *p);
wasalnum = isalnum((unsigned char) *p);
}
} }
} }
} }

View File

@ -174,8 +174,7 @@ Generic_Text_IC_like(text *str, text *pat, Oid collation)
*p; *p;
int slen, int slen,
plen; plen;
pg_locale_t locale = 0; pg_locale_t locale;
bool locale_is_c = false;
if (!OidIsValid(collation)) if (!OidIsValid(collation))
{ {
@ -189,10 +188,7 @@ Generic_Text_IC_like(text *str, text *pat, Oid collation)
errhint("Use the COLLATE clause to set the collation explicitly."))); errhint("Use the COLLATE clause to set the collation explicitly.")));
} }
if (lc_ctype_is_c(collation)) locale = pg_newlocale_from_collation(collation);
locale_is_c = true;
else
locale = pg_newlocale_from_collation(collation);
if (!pg_locale_deterministic(locale)) if (!pg_locale_deterministic(locale))
ereport(ERROR, ereport(ERROR,
@ -228,7 +224,7 @@ Generic_Text_IC_like(text *str, text *pat, Oid collation)
plen = VARSIZE_ANY_EXHDR(pat); plen = VARSIZE_ANY_EXHDR(pat);
s = VARDATA_ANY(str); s = VARDATA_ANY(str);
slen = VARSIZE_ANY_EXHDR(str); slen = VARSIZE_ANY_EXHDR(str);
return SB_IMatchText(s, slen, p, plen, locale, locale_is_c); return SB_IMatchText(s, slen, p, plen, locale, locale->ctype_is_c);
} }
} }

View File

@ -1464,11 +1464,7 @@ make_icu_collator(const char *iculocstr,
bool bool
pg_locale_deterministic(pg_locale_t locale) pg_locale_deterministic(pg_locale_t locale)
{ {
/* default locale must always be deterministic */ return locale->deterministic;
if (locale == NULL)
return true;
else
return locale->deterministic;
} }
/* /*
@ -1812,7 +1808,7 @@ get_collation_actual_version(char collprovider, const char *collcollate)
* pg_strncoll_libc_win32_utf8 * pg_strncoll_libc_win32_utf8
* *
* Win32 does not have UTF-8. Convert UTF8 arguments to wide characters and * Win32 does not have UTF-8. Convert UTF8 arguments to wide characters and
* invoke wcscoll() or wcscoll_l(). * invoke wcscoll_l().
*/ */
#ifdef WIN32 #ifdef WIN32
static int static int
@ -1828,7 +1824,7 @@ pg_strncoll_libc_win32_utf8(const char *arg1, size_t len1, const char *arg2,
int r; int r;
int result; int result;
Assert(!locale || locale->provider == COLLPROVIDER_LIBC); Assert(locale->provider == COLLPROVIDER_LIBC);
Assert(GetDatabaseEncoding() == PG_UTF8); Assert(GetDatabaseEncoding() == PG_UTF8);
#ifndef WIN32 #ifndef WIN32
Assert(false); Assert(false);
@ -1868,10 +1864,7 @@ pg_strncoll_libc_win32_utf8(const char *arg1, size_t len1, const char *arg2,
((LPWSTR) a2p)[r] = 0; ((LPWSTR) a2p)[r] = 0;
errno = 0; errno = 0;
if (locale) result = wcscoll_l((LPWSTR) a1p, (LPWSTR) a2p, locale->info.lt);
result = wcscoll_l((LPWSTR) a1p, (LPWSTR) a2p, locale->info.lt);
else
result = wcscoll((LPWSTR) a1p, (LPWSTR) a2p);
if (result == 2147483647) /* _NLSCMPERROR; missing from mingw headers */ if (result == 2147483647) /* _NLSCMPERROR; missing from mingw headers */
ereport(ERROR, ereport(ERROR,
(errmsg("could not compare Unicode strings: %m"))); (errmsg("could not compare Unicode strings: %m")));
@ -1886,9 +1879,9 @@ pg_strncoll_libc_win32_utf8(const char *arg1, size_t len1, const char *arg2,
/* /*
* pg_strcoll_libc * pg_strcoll_libc
* *
* Call strcoll(), strcoll_l(), wcscoll(), or wcscoll_l() as appropriate for * Call strcoll_l() or wcscoll_l() as appropriate for the given locale,
* the given locale, platform, and database encoding. If the locale is NULL, * platform, and database encoding. If the locale is NULL, use the database
* use the database collation. * collation.
* *
* Arguments must be encoded in the database encoding and nul-terminated. * Arguments must be encoded in the database encoding and nul-terminated.
*/ */
@ -1897,7 +1890,7 @@ pg_strcoll_libc(const char *arg1, const char *arg2, pg_locale_t locale)
{ {
int result; int result;
Assert(!locale || locale->provider == COLLPROVIDER_LIBC); Assert(locale->provider == COLLPROVIDER_LIBC);
#ifdef WIN32 #ifdef WIN32
if (GetDatabaseEncoding() == PG_UTF8) if (GetDatabaseEncoding() == PG_UTF8)
{ {
@ -1908,10 +1901,7 @@ pg_strcoll_libc(const char *arg1, const char *arg2, pg_locale_t locale)
} }
else else
#endif /* WIN32 */ #endif /* WIN32 */
if (locale)
result = strcoll_l(arg1, arg2, locale->info.lt); result = strcoll_l(arg1, arg2, locale->info.lt);
else
result = strcoll(arg1, arg2);
return result; return result;
} }
@ -1933,7 +1923,7 @@ pg_strncoll_libc(const char *arg1, size_t len1, const char *arg2, size_t len2,
char *arg2n; char *arg2n;
int result; int result;
Assert(!locale || locale->provider == COLLPROVIDER_LIBC); Assert(locale->provider == COLLPROVIDER_LIBC);
#ifdef WIN32 #ifdef WIN32
/* check for this case before doing the work for nul-termination */ /* check for this case before doing the work for nul-termination */
@ -2064,9 +2054,9 @@ pg_strncoll_icu(const char *arg1, int32_t len1, const char *arg2, int32_t len2,
/* /*
* pg_strcoll * pg_strcoll
* *
* Call ucol_strcollUTF8(), ucol_strcoll(), strcoll(), strcoll_l(), wcscoll(), * Call ucol_strcollUTF8(), ucol_strcoll(), strcoll_l() or wcscoll_l() as
* or wcscoll_l() as appropriate for the given locale, platform, and database * appropriate for the given locale, platform, and database encoding. If the
* encoding. If the locale is not specified, use the database collation. * locale is not specified, use the database collation.
* *
* Arguments must be encoded in the database encoding and nul-terminated. * Arguments must be encoded in the database encoding and nul-terminated.
* *
@ -2079,7 +2069,7 @@ pg_strcoll(const char *arg1, const char *arg2, pg_locale_t locale)
{ {
int result; int result;
if (!locale || locale->provider == COLLPROVIDER_LIBC) if (locale->provider == COLLPROVIDER_LIBC)
result = pg_strcoll_libc(arg1, arg2, locale); result = pg_strcoll_libc(arg1, arg2, locale);
#ifdef USE_ICU #ifdef USE_ICU
else if (locale->provider == COLLPROVIDER_ICU) else if (locale->provider == COLLPROVIDER_ICU)
@ -2095,9 +2085,9 @@ pg_strcoll(const char *arg1, const char *arg2, pg_locale_t locale)
/* /*
* pg_strncoll * pg_strncoll
* *
* Call ucol_strcollUTF8(), ucol_strcoll(), strcoll(), strcoll_l(), wcscoll(), * Call ucol_strcollUTF8(), ucol_strcoll(), strcoll_l() or wcscoll_l() as
* or wcscoll_l() as appropriate for the given locale, platform, and database * appropriate for the given locale, platform, and database encoding. If the
* encoding. If the locale is not specified, use the database collation. * locale is not specified, use the database collation.
* *
* Arguments must be encoded in the database encoding. * Arguments must be encoded in the database encoding.
* *
@ -2115,7 +2105,7 @@ pg_strncoll(const char *arg1, size_t len1, const char *arg2, size_t len2,
{ {
int result; int result;
if (!locale || locale->provider == COLLPROVIDER_LIBC) if (locale->provider == COLLPROVIDER_LIBC)
result = pg_strncoll_libc(arg1, len1, arg2, len2, locale); result = pg_strncoll_libc(arg1, len1, arg2, len2, locale);
#ifdef USE_ICU #ifdef USE_ICU
else if (locale->provider == COLLPROVIDER_ICU) else if (locale->provider == COLLPROVIDER_ICU)
@ -2133,13 +2123,10 @@ static size_t
pg_strxfrm_libc(char *dest, const char *src, size_t destsize, pg_strxfrm_libc(char *dest, const char *src, size_t destsize,
pg_locale_t locale) pg_locale_t locale)
{ {
Assert(!locale || locale->provider == COLLPROVIDER_LIBC); Assert(locale->provider == COLLPROVIDER_LIBC);
#ifdef TRUST_STRXFRM #ifdef TRUST_STRXFRM
if (locale) return strxfrm_l(dest, src, destsize, locale->info.lt);
return strxfrm_l(dest, src, destsize, locale->info.lt);
else
return strxfrm(dest, src, destsize);
#else #else
/* shouldn't happen */ /* shouldn't happen */
PGLOCALE_SUPPORT_ERROR(locale->provider); PGLOCALE_SUPPORT_ERROR(locale->provider);
@ -2156,7 +2143,7 @@ pg_strnxfrm_libc(char *dest, const char *src, size_t srclen, size_t destsize,
size_t bufsize = srclen + 1; size_t bufsize = srclen + 1;
size_t result; size_t result;
Assert(!locale || locale->provider == COLLPROVIDER_LIBC); Assert(locale->provider == COLLPROVIDER_LIBC);
if (bufsize > TEXTBUFLEN) if (bufsize > TEXTBUFLEN)
buf = palloc(bufsize); buf = palloc(bufsize);
@ -2328,7 +2315,7 @@ pg_strnxfrm_prefix_icu(char *dest, const char *src, int32_t srclen,
bool bool
pg_strxfrm_enabled(pg_locale_t locale) pg_strxfrm_enabled(pg_locale_t locale)
{ {
if (!locale || locale->provider == COLLPROVIDER_LIBC) if (locale->provider == COLLPROVIDER_LIBC)
#ifdef TRUST_STRXFRM #ifdef TRUST_STRXFRM
return true; return true;
#else #else
@ -2362,7 +2349,7 @@ pg_strxfrm(char *dest, const char *src, size_t destsize, pg_locale_t locale)
{ {
size_t result = 0; /* keep compiler quiet */ size_t result = 0; /* keep compiler quiet */
if (!locale || locale->provider == COLLPROVIDER_LIBC) if (locale->provider == COLLPROVIDER_LIBC)
result = pg_strxfrm_libc(dest, src, destsize, locale); result = pg_strxfrm_libc(dest, src, destsize, locale);
#ifdef USE_ICU #ifdef USE_ICU
else if (locale->provider == COLLPROVIDER_ICU) else if (locale->provider == COLLPROVIDER_ICU)
@ -2399,7 +2386,7 @@ pg_strnxfrm(char *dest, size_t destsize, const char *src, size_t srclen,
{ {
size_t result = 0; /* keep compiler quiet */ size_t result = 0; /* keep compiler quiet */
if (!locale || locale->provider == COLLPROVIDER_LIBC) if (locale->provider == COLLPROVIDER_LIBC)
result = pg_strnxfrm_libc(dest, src, srclen, destsize, locale); result = pg_strnxfrm_libc(dest, src, srclen, destsize, locale);
#ifdef USE_ICU #ifdef USE_ICU
else if (locale->provider == COLLPROVIDER_ICU) else if (locale->provider == COLLPROVIDER_ICU)
@ -2419,7 +2406,7 @@ pg_strnxfrm(char *dest, size_t destsize, const char *src, size_t srclen,
bool bool
pg_strxfrm_prefix_enabled(pg_locale_t locale) pg_strxfrm_prefix_enabled(pg_locale_t locale)
{ {
if (!locale || locale->provider == COLLPROVIDER_LIBC) if (locale->provider == COLLPROVIDER_LIBC)
return false; return false;
else if (locale->provider == COLLPROVIDER_ICU) else if (locale->provider == COLLPROVIDER_ICU)
return true; return true;
@ -2449,13 +2436,11 @@ pg_strxfrm_prefix(char *dest, const char *src, size_t destsize,
{ {
size_t result = 0; /* keep compiler quiet */ size_t result = 0; /* keep compiler quiet */
if (!locale)
PGLOCALE_SUPPORT_ERROR(COLLPROVIDER_LIBC);
#ifdef USE_ICU #ifdef USE_ICU
else if (locale->provider == COLLPROVIDER_ICU) if (locale->provider == COLLPROVIDER_ICU)
result = pg_strnxfrm_prefix_icu(dest, src, -1, destsize, locale); result = pg_strnxfrm_prefix_icu(dest, src, -1, destsize, locale);
#endif
else else
#endif
PGLOCALE_SUPPORT_ERROR(locale->provider); PGLOCALE_SUPPORT_ERROR(locale->provider);
return result; return result;
@ -2484,13 +2469,11 @@ pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
{ {
size_t result = 0; /* keep compiler quiet */ size_t result = 0; /* keep compiler quiet */
if (!locale)
PGLOCALE_SUPPORT_ERROR(COLLPROVIDER_LIBC);
#ifdef USE_ICU #ifdef USE_ICU
else if (locale->provider == COLLPROVIDER_ICU) if (locale->provider == COLLPROVIDER_ICU)
result = pg_strnxfrm_prefix_icu(dest, src, -1, destsize, locale); result = pg_strnxfrm_prefix_icu(dest, src, -1, destsize, locale);
#endif
else else
#endif
PGLOCALE_SUPPORT_ERROR(locale->provider); PGLOCALE_SUPPORT_ERROR(locale->provider);
return result; return result;

View File

@ -999,7 +999,7 @@ hashbpchar(PG_FUNCTION_ARGS)
Oid collid = PG_GET_COLLATION(); Oid collid = PG_GET_COLLATION();
char *keydata; char *keydata;
int keylen; int keylen;
pg_locale_t mylocale = 0; pg_locale_t mylocale;
Datum result; Datum result;
if (!collid) if (!collid)
@ -1011,8 +1011,7 @@ hashbpchar(PG_FUNCTION_ARGS)
keydata = VARDATA_ANY(key); keydata = VARDATA_ANY(key);
keylen = bcTruelen(key); keylen = bcTruelen(key);
if (!lc_collate_is_c(collid)) mylocale = pg_newlocale_from_collation(collid);
mylocale = pg_newlocale_from_collation(collid);
if (pg_locale_deterministic(mylocale)) if (pg_locale_deterministic(mylocale))
{ {
@ -1056,7 +1055,7 @@ hashbpcharextended(PG_FUNCTION_ARGS)
Oid collid = PG_GET_COLLATION(); Oid collid = PG_GET_COLLATION();
char *keydata; char *keydata;
int keylen; int keylen;
pg_locale_t mylocale = 0; pg_locale_t mylocale;
Datum result; Datum result;
if (!collid) if (!collid)
@ -1068,8 +1067,7 @@ hashbpcharextended(PG_FUNCTION_ARGS)
keydata = VARDATA_ANY(key); keydata = VARDATA_ANY(key);
keylen = bcTruelen(key); keylen = bcTruelen(key);
if (!lc_collate_is_c(collid)) mylocale = pg_newlocale_from_collation(collid);
mylocale = pg_newlocale_from_collation(collid);
if (pg_locale_deterministic(mylocale)) if (pg_locale_deterministic(mylocale))
{ {

View File

@ -1217,12 +1217,11 @@ text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
{ {
int len1 = VARSIZE_ANY_EXHDR(t1); int len1 = VARSIZE_ANY_EXHDR(t1);
int len2 = VARSIZE_ANY_EXHDR(t2); int len2 = VARSIZE_ANY_EXHDR(t2);
pg_locale_t mylocale = 0; pg_locale_t mylocale;
check_collation_set(collid); check_collation_set(collid);
if (!lc_collate_is_c(collid)) mylocale = pg_newlocale_from_collation(collid);
mylocale = pg_newlocale_from_collation(collid);
if (!pg_locale_deterministic(mylocale)) if (!pg_locale_deterministic(mylocale))
ereport(ERROR, ereport(ERROR,
@ -1619,18 +1618,14 @@ Datum
texteq(PG_FUNCTION_ARGS) texteq(PG_FUNCTION_ARGS)
{ {
Oid collid = PG_GET_COLLATION(); Oid collid = PG_GET_COLLATION();
bool locale_is_c = false;
pg_locale_t mylocale = 0; pg_locale_t mylocale = 0;
bool result; bool result;
check_collation_set(collid); check_collation_set(collid);
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 (pg_locale_deterministic(mylocale))
{ {
Datum arg1 = PG_GETARG_DATUM(0); Datum arg1 = PG_GETARG_DATUM(0);
Datum arg2 = PG_GETARG_DATUM(1); Datum arg2 = PG_GETARG_DATUM(1);
@ -1678,18 +1673,14 @@ Datum
textne(PG_FUNCTION_ARGS) textne(PG_FUNCTION_ARGS)
{ {
Oid collid = PG_GET_COLLATION(); Oid collid = PG_GET_COLLATION();
bool locale_is_c = false; pg_locale_t mylocale;
pg_locale_t mylocale = 0;
bool result; bool result;
check_collation_set(collid); check_collation_set(collid);
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 (pg_locale_deterministic(mylocale))
{ {
Datum arg1 = PG_GETARG_DATUM(0); Datum arg1 = PG_GETARG_DATUM(0);
Datum arg2 = PG_GETARG_DATUM(1); Datum arg2 = PG_GETARG_DATUM(1);
@ -1793,15 +1784,14 @@ text_starts_with(PG_FUNCTION_ARGS)
Datum arg1 = PG_GETARG_DATUM(0); Datum arg1 = PG_GETARG_DATUM(0);
Datum arg2 = PG_GETARG_DATUM(1); Datum arg2 = PG_GETARG_DATUM(1);
Oid collid = PG_GET_COLLATION(); Oid collid = PG_GET_COLLATION();
pg_locale_t mylocale = 0; pg_locale_t mylocale;
bool result; bool result;
Size len1, Size len1,
len2; len2;
check_collation_set(collid); check_collation_set(collid);
if (!lc_collate_is_c(collid)) mylocale = pg_newlocale_from_collation(collid);
mylocale = pg_newlocale_from_collation(collid);
if (!pg_locale_deterministic(mylocale)) if (!pg_locale_deterministic(mylocale))
ereport(ERROR, ereport(ERROR,