Revert "ICU: do not convert locale 'C' to 'en-US-u-va-posix'."
authorJeff Davis <[email protected]>
Tue, 9 May 2023 03:50:51 +0000 (20:50 -0700)
committerJeff Davis <[email protected]>
Tue, 9 May 2023 03:50:51 +0000 (20:50 -0700)
This reverts commit f7faa9976cc0504c027a20ed66ceca9018041dd4.

Discussion: https://postgr.es/m/483826.1683582475@sss.pgh.pa.us

src/backend/utils/adt/pg_locale.c
src/bin/initdb/initdb.c
src/test/regress/expected/collate.icu.utf8.out
src/test/regress/sql/collate.icu.utf8.sql

index 51b4221a39c4e12aab2255427dafdc94c97fee62..f0b6567da127e0686171e0b99f0801df03da672d 100644 (file)
@@ -2782,10 +2782,26 @@ icu_language_tag(const char *loc_str, int elevel)
 {
 #ifdef USE_ICU
        UErrorCode       status;
+       char             lang[ULOC_LANG_CAPACITY];
        char            *langtag;
        size_t           buflen = 32;   /* arbitrary starting buffer size */
        const bool       strict = true;
 
+       status = U_ZERO_ERROR;
+       uloc_getLanguage(loc_str, lang, ULOC_LANG_CAPACITY, &status);
+       if (U_FAILURE(status))
+       {
+               if (elevel > 0)
+                       ereport(elevel,
+                                       (errmsg("could not get language from locale \"%s\": %s",
+                                                       loc_str, u_errorName(status))));
+               return NULL;
+       }
+
+       /* C/POSIX locales aren't handled by uloc_getLanguageTag() */
+       if (strcmp(lang, "c") == 0 || strcmp(lang, "posix") == 0)
+               return pstrdup("en-US-u-va-posix");
+
        /*
         * A BCP47 language tag doesn't have a clearly-defined upper limit
         * (cf. RFC5646 section 4.4). Additionally, in older ICU versions,
@@ -2873,7 +2889,8 @@ icu_validate_locale(const char *loc_str)
 
        /* check for special language name */
        if (strcmp(lang, "") == 0 ||
-               strcmp(lang, "root") == 0 || strcmp(lang, "und") == 0)
+               strcmp(lang, "root") == 0 || strcmp(lang, "und") == 0 ||
+               strcmp(lang, "c") == 0 || strcmp(lang, "posix") == 0)
                found = true;
 
        /* search for matching language within ICU */
index 40868344581980eb0a97b2de38ff38d052ab15cf..2c208ead019b52ee456ec516c7344898c8e7a452 100644 (file)
@@ -2238,10 +2238,24 @@ icu_language_tag(const char *loc_str)
 {
 #ifdef USE_ICU
        UErrorCode       status;
+       char             lang[ULOC_LANG_CAPACITY];
        char            *langtag;
        size_t           buflen = 32;   /* arbitrary starting buffer size */
        const bool       strict = true;
 
+       status = U_ZERO_ERROR;
+       uloc_getLanguage(loc_str, lang, ULOC_LANG_CAPACITY, &status);
+       if (U_FAILURE(status))
+       {
+               pg_fatal("could not get language from locale \"%s\": %s",
+                                loc_str, u_errorName(status));
+               return NULL;
+       }
+
+       /* C/POSIX locales aren't handled by uloc_getLanguageTag() */
+       if (strcmp(lang, "c") == 0 || strcmp(lang, "posix") == 0)
+               return pstrdup("en-US-u-va-posix");
+
        /*
         * A BCP47 language tag doesn't have a clearly-defined upper limit
         * (cf. RFC5646 section 4.4). Additionally, in older ICU versions,
@@ -2313,7 +2327,8 @@ icu_validate_locale(const char *loc_str)
 
        /* check for special language name */
        if (strcmp(lang, "") == 0 ||
-               strcmp(lang, "root") == 0 || strcmp(lang, "und") == 0)
+               strcmp(lang, "root") == 0 || strcmp(lang, "und") == 0 ||
+               strcmp(lang, "c") == 0 || strcmp(lang, "posix") == 0)
                found = true;
 
        /* search for matching language within ICU */
index c8fcbeb450455cc7c85753872f7cc9f4990bccd8..b5a221b030052381aa76083767f33ba17d320c56 100644 (file)
@@ -1020,7 +1020,6 @@ CREATE ROLE regress_test_role;
 CREATE SCHEMA test_schema;
 -- We need to do this this way to cope with varying names for encodings:
 SET client_min_messages TO WARNING;
-SET icu_validation_level = disabled;
 do $$
 BEGIN
   EXECUTE 'CREATE COLLATION test0 (provider = icu, locale = ' ||
@@ -1035,24 +1034,17 @@ BEGIN
           quote_literal(current_setting('lc_collate')) || ');';
 END
 $$;
-RESET icu_validation_level;
 RESET client_min_messages;
 CREATE COLLATION test3 (provider = icu, lc_collate = 'en_US.utf8'); -- fail, needs "locale"
 ERROR:  parameter "locale" must be specified
 CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere'); -- fails
 ERROR:  ICU locale "nonsense-nowhere" has unknown language "nonsense"
 HINT:  To disable ICU locale validation, set parameter icu_validation_level to DISABLED.
-CREATE COLLATION testx (provider = icu, locale = 'C'); -- fails
-ERROR:  could not convert locale name "C" to language tag: U_ILLEGAL_ARGUMENT_ERROR
 CREATE COLLATION testx (provider = icu, locale = '@colStrength=primary;nonsense=yes'); -- fails
 ERROR:  could not convert locale name "@colStrength=primary;nonsense=yes" to language tag: U_ILLEGAL_ARGUMENT_ERROR
 SET icu_validation_level = WARNING;
 CREATE COLLATION testx (provider = icu, locale = '@colStrength=primary;nonsense=yes'); DROP COLLATION testx;
 WARNING:  could not convert locale name "@colStrength=primary;nonsense=yes" to language tag: U_ILLEGAL_ARGUMENT_ERROR
-CREATE COLLATION testx (provider = icu, locale = 'C'); DROP COLLATION testx;
-WARNING:  could not convert locale name "C" to language tag: U_ILLEGAL_ARGUMENT_ERROR
-WARNING:  ICU locale "C" has unknown language "c"
-HINT:  To disable ICU locale validation, set parameter icu_validation_level to DISABLED.
 CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere'); DROP COLLATION testx;
 WARNING:  ICU locale "nonsense-nowhere" has unknown language "nonsense"
 HINT:  To disable ICU locale validation, set parameter icu_validation_level to DISABLED.
index 46df58d092b913a814bf906ad841284cb1e74e74..85e26951b626323adf575372dcedf77f886a7702 100644 (file)
@@ -358,7 +358,6 @@ CREATE SCHEMA test_schema;
 
 -- We need to do this this way to cope with varying names for encodings:
 SET client_min_messages TO WARNING;
-SET icu_validation_level = disabled;
 
 do $$
 BEGIN
@@ -374,16 +373,13 @@ BEGIN
 END
 $$;
 
-RESET icu_validation_level;
 RESET client_min_messages;
 
 CREATE COLLATION test3 (provider = icu, lc_collate = 'en_US.utf8'); -- fail, needs "locale"
 CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere'); -- fails
-CREATE COLLATION testx (provider = icu, locale = 'C'); -- fails
 CREATE COLLATION testx (provider = icu, locale = '@colStrength=primary;nonsense=yes'); -- fails
 SET icu_validation_level = WARNING;
 CREATE COLLATION testx (provider = icu, locale = '@colStrength=primary;nonsense=yes'); DROP COLLATION testx;
-CREATE COLLATION testx (provider = icu, locale = 'C'); DROP COLLATION testx;
 CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere'); DROP COLLATION testx;
 RESET icu_validation_level;