Hello,
I have run into an issue where specifying the rules argument for "CREATE
COLLATION" changes the collation strength to tertiary, even if it is explicitly
set in the rules string. I discovered that this is because ucol_openRules is
called passing strength UCOL_DEFAULT_STRENGTH, which overwrites whatever is in
the rules string with UCOL_TERTIARY.
This fix changes this call to pass UCOL_DEFAULT instead. This way,
UCOL_TERTIARY is still specified by default, but the strength explicitly set on
the rules string is not overwritten. This is important because there is
currently no way to create a collation with custom tailoring rules with strengh
other than tertiary.
What happens currently:
CREATE COLLATION my_col (provider = icu, locale = 'und', rules = '',
deterministic = false); -- strengh: tertiary
CREATE COLLATION my_col (provider = icu, locale = 'und', rules = '[strength
2]', deterministic = false); -- strength: tertiary
CREATE COLLATION my_col (provider = icu, locale = 'und', rules = '[strength
1]', deterministic = false); -- strength: tertiary
What happens after the patch:
CREATE COLLATION my_col (provider = icu, locale = 'und', rules = '',
deterministic = false); -- strengh: tertiary
CREATE COLLATION my_col (provider = icu, locale = 'und', rules = '[strength
2]', deterministic = false); -- strength: secondary
CREATE COLLATION my_col (provider = icu, locale = 'und', rules = '[strength
1]', deterministic = false); -- strength: primary
As this only affects cases where the strength is explicitly set but was
previously ignores, I do not think it is a breaking change.
I have successfully compiled and tested PostgreSQL after this change, and it
behaves as documented above.
Thank you in advance,
Luis
From fa37c67416fcf472c01cf59c8bb12c7dba2ab284 Mon Sep 17 00:00:00 2001
From: lfpraca <[email protected]>
Date: Mon, 27 Oct 2025 14:27:27 -0300
Subject: [PATCH] Fix ICU strength not being honored in collation rules
---
src/backend/utils/adt/pg_locale_icu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/backend/utils/adt/pg_locale_icu.c b/src/backend/utils/adt/pg_locale_icu.c
index 05bad20..08a461a 100644
--- a/src/backend/utils/adt/pg_locale_icu.c
+++ b/src/backend/utils/adt/pg_locale_icu.c
@@ -466,7 +466,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))
{
--
2.49.1