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

-9
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

-8
This file was deleted.

contrib/unaccent/sql/unaccent.sql

-11
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

+6-12
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

+1-2
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

+3
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

+4
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

+2
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)