Skip to content

Commit f413941

Browse files
committed
Fix t_isspace(), etc., when datlocprovider=i and datctype=C.
Check whether the datctype is C to determine whether t_isspace() and related functions use isspace() or iswspace(). Previously, t_isspace() checked whether the database default collation was C; which is incorrect when the default collation uses the ICU provider. Discussion: https://postgr.es/m/79e4354d9eccfdb00483146a6b9f6295202e7890.camel@j-davis.com Reviewed-by: Peter Eisentraut Backpatch-through: 15
1 parent 064709f commit f413941

File tree

8 files changed

+16
-42
lines changed

8 files changed

+16
-42
lines changed

contrib/unaccent/expected/unaccent.out

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,3 @@
1-
-- unaccent is broken if the default collation is provided by ICU and
2-
-- LC_CTYPE=C
3-
SELECT current_setting('lc_ctype') = 'C' AND
4-
(SELECT datlocprovider='i' FROM pg_database
5-
WHERE datname=current_database())
6-
AS skip_test \gset
7-
\if :skip_test
8-
\quit
9-
\endif
101
CREATE EXTENSION unaccent;
112
-- must have a UTF8 database
123
SELECT getdatabaseencoding();

contrib/unaccent/expected/unaccent_1.out

Lines changed: 0 additions & 8 deletions
This file was deleted.

contrib/unaccent/sql/unaccent.sql

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,3 @@
1-
2-
-- unaccent is broken if the default collation is provided by ICU and
3-
-- LC_CTYPE=C
4-
SELECT current_setting('lc_ctype') = 'C' AND
5-
(SELECT datlocprovider='i' FROM pg_database
6-
WHERE datname=current_database())
7-
AS skip_test \gset
8-
\if :skip_test
9-
\quit
10-
\endif
11-
121
CREATE EXTENSION unaccent;
132

143
-- must have a UTF8 database

src/backend/tsearch/ts_locale.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,9 @@ t_isdigit(const char *ptr)
3838
{
3939
int clen = pg_mblen(ptr);
4040
wchar_t character[WC_BUF_LEN];
41-
Oid collation = DEFAULT_COLLATION_OID; /* TODO */
4241
pg_locale_t mylocale = 0; /* TODO */
4342

44-
if (clen == 1 || lc_ctype_is_c(collation))
43+
if (clen == 1 || database_ctype_is_c)
4544
return isdigit(TOUCHAR(ptr));
4645

4746
char2wchar(character, WC_BUF_LEN, ptr, clen, mylocale);
@@ -54,10 +53,9 @@ t_isspace(const char *ptr)
5453
{
5554
int clen = pg_mblen(ptr);
5655
wchar_t character[WC_BUF_LEN];
57-
Oid collation = DEFAULT_COLLATION_OID; /* TODO */
5856
pg_locale_t mylocale = 0; /* TODO */
5957

60-
if (clen == 1 || lc_ctype_is_c(collation))
58+
if (clen == 1 || database_ctype_is_c)
6159
return isspace(TOUCHAR(ptr));
6260

6361
char2wchar(character, WC_BUF_LEN, ptr, clen, mylocale);
@@ -70,10 +68,9 @@ t_isalpha(const char *ptr)
7068
{
7169
int clen = pg_mblen(ptr);
7270
wchar_t character[WC_BUF_LEN];
73-
Oid collation = DEFAULT_COLLATION_OID; /* TODO */
7471
pg_locale_t mylocale = 0; /* TODO */
7572

76-
if (clen == 1 || lc_ctype_is_c(collation))
73+
if (clen == 1 || database_ctype_is_c)
7774
return isalpha(TOUCHAR(ptr));
7875

7976
char2wchar(character, WC_BUF_LEN, ptr, clen, mylocale);
@@ -86,10 +83,9 @@ t_isalnum(const char *ptr)
8683
{
8784
int clen = pg_mblen(ptr);
8885
wchar_t character[WC_BUF_LEN];
89-
Oid collation = DEFAULT_COLLATION_OID; /* TODO */
9086
pg_locale_t mylocale = 0; /* TODO */
9187

92-
if (clen == 1 || lc_ctype_is_c(collation))
88+
if (clen == 1 || database_ctype_is_c)
9389
return isalnum(TOUCHAR(ptr));
9490

9591
char2wchar(character, WC_BUF_LEN, ptr, clen, mylocale);
@@ -102,10 +98,9 @@ t_isprint(const char *ptr)
10298
{
10399
int clen = pg_mblen(ptr);
104100
wchar_t character[WC_BUF_LEN];
105-
Oid collation = DEFAULT_COLLATION_OID; /* TODO */
106101
pg_locale_t mylocale = 0; /* TODO */
107102

108-
if (clen == 1 || lc_ctype_is_c(collation))
103+
if (clen == 1 || database_ctype_is_c)
109104
return isprint(TOUCHAR(ptr));
110105

111106
char2wchar(character, WC_BUF_LEN, ptr, clen, mylocale);
@@ -273,7 +268,6 @@ char *
273268
lowerstr_with_len(const char *str, int len)
274269
{
275270
char *out;
276-
Oid collation = DEFAULT_COLLATION_OID; /* TODO */
277271
pg_locale_t mylocale = 0; /* TODO */
278272

279273
if (len == 0)
@@ -285,7 +279,7 @@ lowerstr_with_len(const char *str, int len)
285279
* Also, for a C locale there is no need to process as multibyte. From
286280
* backend/utils/adt/oracle_compat.c Teodor
287281
*/
288-
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c(collation))
282+
if (pg_database_encoding_max_length() > 1 && !database_ctype_is_c)
289283
{
290284
wchar_t *wstr,
291285
*wptr;

src/backend/tsearch/wparser_def.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,10 @@ TParserInit(char *str, int len)
297297
*/
298298
if (prs->charmaxlen > 1)
299299
{
300-
Oid collation = DEFAULT_COLLATION_OID; /* TODO */
301300
pg_locale_t mylocale = 0; /* TODO */
302301

303302
prs->usewide = true;
304-
if (lc_ctype_is_c(collation))
303+
if (database_ctype_is_c)
305304
{
306305
/*
307306
* char2wchar doesn't work for C-locale and sizeof(pg_wchar) could

src/backend/utils/adt/pg_locale.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ char *localized_full_days[7 + 1];
107107
char *localized_abbrev_months[12 + 1];
108108
char *localized_full_months[12 + 1];
109109

110+
/* is the databases's LC_CTYPE the C locale? */
111+
bool database_ctype_is_c = false;
112+
110113
/* indicates whether locale information cache is valid */
111114
static bool CurrentLocaleConvValid = false;
112115
static bool CurrentLCTimeValid = false;

src/backend/utils/init/postinit.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,10 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
419419
" which is not recognized by setlocale().", ctype),
420420
errhint("Recreate the database with another locale or install the missing locale.")));
421421

422+
if (strcmp(ctype, "C") == 0 ||
423+
strcmp(ctype, "POSIX") == 0)
424+
database_ctype_is_c = true;
425+
422426
if (dbform->datlocprovider == COLLPROVIDER_ICU)
423427
{
424428
char *icurules;

src/include/utils/pg_locale.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ extern PGDLLIMPORT char *localized_full_days[];
4747
extern PGDLLIMPORT char *localized_abbrev_months[];
4848
extern PGDLLIMPORT char *localized_full_months[];
4949

50+
/* is the databases's LC_CTYPE the C locale? */
51+
extern PGDLLIMPORT bool database_ctype_is_c;
5052

5153
extern bool check_locale(int category, const char *locale, char **canonname);
5254
extern char *pg_perm_setlocale(int category, const char *locale);

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