Re: ICU locale validation / canonicalization
Jeff Davis <pgsql@j-davis.com>
Attachments
- v1-0001-For-ICU-collations-canonicalize-locale-names-to-l.patch (text/x-patch) patch v1-0001
On Thu, 2023-02-09 at 14:09 -0800, Jeff Davis wrote: > It feels like BCP 47 is the right catalog representation. We are > already using it for the import of initial collations, and it's a > standard, and there seems to be good support in ICU. Patch attached. We should have been canonicalizing all along -- either with uloc_toLanguageTag(), as this patch does, or at least with uloc_canonicalize() -- before passing to ucol_open(). ucol_open() is documented[1] to work on either language tags or ICU format locale IDs. Anything else is invalid and ends up going through some fallback logic, probably after being mis-parsed. For instance, in ICU 72, "fr_CA.UTF-8" is not a valid ICU format locale ID or a valid language tag, and is resolved by ucol_open() to the actual locale "root"; but if you canonicalize it first (to the ICU format locale ID "fr_CA" or the language tag "fr-CA"), it correctly resolves to the actual locale "fr_CA". The correct thing to do is canonicalize first and then pass to ucol_open(). But because we didn't canonicalize in the past, there could be raw locale strings stored in the catalog that resolve to the wrong actual collator, and there could be indexes depending on the wrong collator, so we have to be careful during pg_upgrade. Say someone created two ICU collations, one with locale "en_US.UTF-8" and one with locale "fr_CA.UTF-8" in PG15. When they upgrade to PG16, this patch will check the language tag "en-US" and see that it resolves to the same locale as "en_US.UTF-8", and change to the language tag during upgrade (so "en-US" will be in the new catalog). But when it checks the language tag "fr-CA", it will notice that it resolves to a different locale than "fr_CA.UTF-8", and keep the latter string even though it's wrong, because some indexes might be dependent on that wrong collator. [1] https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/ucol_8h.html#a3b0bf34733dc208040e4157b0fe5fcd6 -- Jeff Davis PostgreSQL Contributor Team - AWS
Commits
-
Add missing source file to nls.mk
- b8c3f6df85e7 16.0 cited
-
Fix MSVC warning introduced in ea1db8ae70.
- 36320cbc164a 16.0 landed
-
Canonicalize ICU locale names to language tags.
- ea1db8ae70e5 16.0 landed
-
Validate ICU locales.
- 1671f990dd66 16.0 landed
-
initdb: emit message when using default ICU locale.
- c1f1c1f87fd6 16.0 landed
-
initdb: replace check_icu_locale() with default_icu_locale().
- f8ca22295e99 16.0 landed
-
Fix error inconsistency in older ICU versions.
- 8b3eb0c584be 16.0 landed
-
Avoid potential UCollator leak for older ICU versions.
- a03b3b6b4a72 16.0 landed
-
pg_locale.c: change ereport() to elog().
- 9a242899158c 16.0 landed
-
Handle the "und" locale in ICU versions 54 and older.
- 3b50275b1295 16.0 landed
-
Wrap ICU ucol_open().
- a326aac8f171 16.0 landed
-
Support language tags in older ICU versions (53 and earlier).
- 869650fa86ad 16.0 landed
-
Improve support for UNICODE collation on older ICU
- d72900bdedc6 16.0 cited
-
Use ICU by default at initdb time.
- 27b62377b47f 16.0 cited