From 905e44152a1d49b90cb8d800dcaaba7981288ae2 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 18 Mar 2026 08:54:35 +0100 Subject: [PATCH] Allow setting the collation strength in ICU tailoring rules There was a bug that if you created an ICU collation with tailoring rules, any strength specification inside the rules was ignored. This was because we called ucol_openRules() with UCOL_DEFAULT_STRENGTH for the strength argument, which overrides the strength. This was because of faulty guidance in the ICU documentation, which has since been fixed. The correct invocation is to use UCOL_DEFAULT for the strength argument. This fixes bug #18771 and bug #19425. Author: Daniel Verite Reported-by: Ruben Ruiz Reported-by: dorian.752@live.fr Reported-by: Todd Lang Discussion: https://www.postgresql.org/message-id/flat/YT2PPF959236618377A072745A280E278F4BE1DA@YT2PPF959236618.CANPRD01.PROD.OUTLOOK.COM Discussion: https://www.postgresql.org/message-id/flat/18771-98bb23e455b0f367@postgresql.org Discussion: https://www.postgresql.org/message-id/flat/19425-58915e19dacd4f40%40postgresql.org --- src/backend/utils/adt/pg_locale_icu.c | 2 +- src/test/regress/expected/collate.icu.utf8.out | 8 ++++++++ src/test/regress/sql/collate.icu.utf8.sql | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/adt/pg_locale_icu.c b/src/backend/utils/adt/pg_locale_icu.c index 352b4c3885f..5ad05fcd016 100644 --- a/src/backend/utils/adt/pg_locale_icu.c +++ b/src/backend/utils/adt/pg_locale_icu.c @@ -587,7 +587,7 @@ make_icu_collator(const char *iculocstr, const char *icurules) status = U_ZERO_ERROR; collator_all_rules = ucol_openRules(all_rules, u_strlen(all_rules), - UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, + UCOL_DEFAULT, UCOL_DEFAULT, NULL, &status); if (U_FAILURE(status)) { diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out index 1325e123877..d170e7da066 100644 --- a/src/test/regress/expected/collate.icu.utf8.out +++ b/src/test/regress/expected/collate.icu.utf8.out @@ -1297,6 +1297,14 @@ DROP TABLE test7; CREATE COLLATION testcoll_rulesx (provider = icu, locale = '', rules = '!!wrong!!'); NOTICE: using standard form "und" for ICU locale "" ERROR: could not open collator for locale "und" with rules "!!wrong!!": U_INVALID_FORMAT_ERROR +-- strength specified in the rules +CREATE COLLATION strength_in_rule (provider = icu, locale = 'und', deterministic = false, rules = '[strength 1]'); +SELECT 'a' = 'à' COLLATE strength_in_rule; -- true because of the rule + ?column? +---------- + t +(1 row) + -- nondeterministic collations CREATE COLLATION ctest_det (provider = icu, locale = '', deterministic = true); NOTICE: using standard form "und" for ICU locale "" diff --git a/src/test/regress/sql/collate.icu.utf8.sql b/src/test/regress/sql/collate.icu.utf8.sql index b6c54503d21..8f0f973f5fa 100644 --- a/src/test/regress/sql/collate.icu.utf8.sql +++ b/src/test/regress/sql/collate.icu.utf8.sql @@ -513,6 +513,10 @@ DROP TABLE test7; CREATE COLLATION testcoll_rulesx (provider = icu, locale = '', rules = '!!wrong!!'); +-- strength specified in the rules +CREATE COLLATION strength_in_rule (provider = icu, locale = 'und', deterministic = false, rules = '[strength 1]'); +SELECT 'a' = 'à' COLLATE strength_in_rule; -- true because of the rule + -- nondeterministic collations