aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2019-03-19 09:37:46 +0100
committerPeter Eisentraut <peter@eisentraut.org>2019-03-19 09:37:46 +0100
commit1f050c08f91d866c560344d4510404ecd2763cbf (patch)
tree9bbb83d3fd129bd8854a39969f92e8e957e9dafc
parent53680c116ce8c501e4081332d32ba0e93aa1aaa2 (diff)
downloadpostgresql-1f050c08f91d866c560344d4510404ecd2763cbf.tar.gz
postgresql-1f050c08f91d866c560344d4510404ecd2763cbf.zip
Fix bug in support for collation attributes on older ICU versions
Unrecognized attribute names are supposed to be ignored. But the code would error out on an unrecognized attribute value even if it did not recognize the attribute name. So unrecognized attributes wouldn't really be ignored unless the value happened to be one that matched a recognized value. This would break some important cases where the attribute would be processed by ucol_open() directly. Fix that and add a test case. The restructured code should also avoid compiler warnings about initializing a UColAttribute value to -1, because the type might be an unsigned enum. (reported by Andres Freund)
-rw-r--r--src/backend/utils/adt/pg_locale.c10
-rw-r--r--src/test/regress/expected/collate.icu.utf8.out10
-rw-r--r--src/test/regress/sql/collate.icu.utf8.sql7
3 files changed, 23 insertions, 4 deletions
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index ec14bad4e34..7fe10e284aa 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1623,8 +1623,8 @@ icu_set_collation_attributes(UCollator *collator, const char *loc)
{
char *name;
char *value;
- UColAttribute uattr = -1;
- UColAttributeValue uvalue = -1;
+ UColAttribute uattr;
+ UColAttributeValue uvalue;
UErrorCode status;
status = U_ZERO_ERROR;
@@ -1650,7 +1650,9 @@ icu_set_collation_attributes(UCollator *collator, const char *loc)
uattr = UCOL_NORMALIZATION_MODE;
else if (strcmp(name, "colnumeric") == 0)
uattr = UCOL_NUMERIC_COLLATION;
- /* ignore if unknown */
+ else
+ /* ignore if unknown */
+ continue;
if (strcmp(value, "primary") == 0)
uvalue = UCOL_PRIMARY;
@@ -1677,7 +1679,7 @@ icu_set_collation_attributes(UCollator *collator, const char *loc)
else
status = U_ILLEGAL_ARGUMENT_ERROR;
- if (uattr != -1 && uvalue != -1)
+ if (status == U_ZERO_ERROR)
ucol_setAttribute(collator, uattr, uvalue, &status);
/*
diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out
index 4b94921cf88..b66193d1be2 100644
--- a/src/test/regress/expected/collate.icu.utf8.out
+++ b/src/test/regress/expected/collate.icu.utf8.out
@@ -1101,6 +1101,7 @@ select textrange_en_us('A','Z') @> 'b'::text;
drop type textrange_c;
drop type textrange_en_us;
-- test ICU collation customization
+-- test the attributes handled by icu_set_collation_attributes()
CREATE COLLATION testcoll_ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseLevel=yes');
SELECT 'aaá' > 'AAA' COLLATE "und-x-icu", 'aaá' < 'AAA' COLLATE testcoll_ignore_accents;
?column? | ?column?
@@ -1139,6 +1140,15 @@ SELECT 'A-21' > 'A-123' COLLATE "und-x-icu", 'A-21' < 'A-123' COLLATE testcoll_n
CREATE COLLATION testcoll_error1 (provider = icu, locale = '@colNumeric=lower');
ERROR: could not open collator for locale "@colNumeric=lower": U_ILLEGAL_ARGUMENT_ERROR
+-- test that attributes not handled by icu_set_collation_attributes()
+-- (handled by ucol_open() directly) also work
+CREATE COLLATION testcoll_de_phonebook (provider = icu, locale = 'de@collation=phonebook');
+SELECT 'Goldmann' < 'Götz' COLLATE "de-x-icu", 'Goldmann' > 'Götz' COLLATE testcoll_de_phonebook;
+ ?column? | ?column?
+----------+----------
+ t | t
+(1 row)
+
-- cleanup
SET client_min_messages TO warning;
DROP SCHEMA collate_tests CASCADE;
diff --git a/src/test/regress/sql/collate.icu.utf8.sql b/src/test/regress/sql/collate.icu.utf8.sql
index 73fb1232a7d..68c2d696593 100644
--- a/src/test/regress/sql/collate.icu.utf8.sql
+++ b/src/test/regress/sql/collate.icu.utf8.sql
@@ -427,6 +427,8 @@ drop type textrange_en_us;
-- test ICU collation customization
+-- test the attributes handled by icu_set_collation_attributes()
+
CREATE COLLATION testcoll_ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseLevel=yes');
SELECT 'aaá' > 'AAA' COLLATE "und-x-icu", 'aaá' < 'AAA' COLLATE testcoll_ignore_accents;
@@ -445,6 +447,11 @@ SELECT 'A-21' > 'A-123' COLLATE "und-x-icu", 'A-21' < 'A-123' COLLATE testcoll_n
CREATE COLLATION testcoll_error1 (provider = icu, locale = '@colNumeric=lower');
+-- test that attributes not handled by icu_set_collation_attributes()
+-- (handled by ucol_open() directly) also work
+CREATE COLLATION testcoll_de_phonebook (provider = icu, locale = 'de@collation=phonebook');
+SELECT 'Goldmann' < 'Götz' COLLATE "de-x-icu", 'Goldmann' > 'Götz' COLLATE testcoll_de_phonebook;
+
-- cleanup
SET client_min_messages TO warning;