summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorPeter Eisentraut2022-03-17 10:11:21 +0000
committerPeter Eisentraut2022-03-17 10:13:16 +0000
commitf2553d43060edb210b36c63187d52a632448e1d2 (patch)
tree7c75fca6ad45c4c25f8b2c6d3d51fa871d2c72d8 /src/test
parentf6f0db4d62400ff88f523dcc4d7e25f9506bc0d8 (diff)
Add option to use ICU as global locale provider
This adds the option to use ICU as the default locale provider for either the whole cluster or a database. New options for initdb, createdb, and CREATE DATABASE are used to select this. Since some (legacy) code still uses the libc locale facilities directly, we still need to set the libc global locale settings even if ICU is otherwise selected. So pg_database now has three locale-related fields: the existing datcollate and datctype, which are always set, and a new daticulocale, which is only set if ICU is selected. A similar change is made in pg_collation for consistency, but in that case, only the libc-related fields or the ICU-related field is set, never both. Reviewed-by: Julien Rouhaud <rjuju123@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/5e756dd6-0e91-d778-96fd-b1bcb06c161a%402ndquadrant.com
Diffstat (limited to 'src/test')
-rw-r--r--src/test/Makefile6
-rw-r--r--src/test/icu/.gitignore2
-rw-r--r--src/test/icu/Makefile25
-rw-r--r--src/test/icu/README27
-rw-r--r--src/test/icu/t/010_database.pl58
-rw-r--r--src/test/regress/expected/collate.icu.utf8.out10
-rw-r--r--src/test/regress/sql/collate.icu.utf8.sql8
7 files changed, 124 insertions, 12 deletions
diff --git a/src/test/Makefile b/src/test/Makefile
index 46275915ff3..69ef074d75e 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -14,6 +14,10 @@ include $(top_builddir)/src/Makefile.global
SUBDIRS = perl regress isolation modules authentication recovery subscription
+ifeq ($(with_icu),yes)
+SUBDIRS += icu
+endif
+
# Test suites that are not safe by default but can be run if selected
# by the user via the whitespace-separated list in variable
# PG_TEST_EXTRA:
@@ -37,7 +41,7 @@ endif
# clean" etc to recurse into them. (We must filter out those that we
# have conditionally included into SUBDIRS above, else there will be
# make confusion.)
-ALWAYS_SUBDIRS = $(filter-out $(SUBDIRS),examples kerberos ldap ssl)
+ALWAYS_SUBDIRS = $(filter-out $(SUBDIRS),examples kerberos icu ldap ssl)
# We want to recurse to all subdirs for all standard targets, except that
# installcheck and install should not recurse into the subdirectory "modules".
diff --git a/src/test/icu/.gitignore b/src/test/icu/.gitignore
new file mode 100644
index 00000000000..871e943d50e
--- /dev/null
+++ b/src/test/icu/.gitignore
@@ -0,0 +1,2 @@
+# Generated by test suite
+/tmp_check/
diff --git a/src/test/icu/Makefile b/src/test/icu/Makefile
new file mode 100644
index 00000000000..e30f5e95244
--- /dev/null
+++ b/src/test/icu/Makefile
@@ -0,0 +1,25 @@
+#-------------------------------------------------------------------------
+#
+# Makefile for src/test/icu
+#
+# Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+# Portions Copyright (c) 1994, Regents of the University of California
+#
+# src/test/icu/Makefile
+#
+#-------------------------------------------------------------------------
+
+subdir = src/test/icu
+top_builddir = ../../..
+include $(top_builddir)/src/Makefile.global
+
+export with_icu
+
+check:
+ $(prove_check)
+
+installcheck:
+ $(prove_installcheck)
+
+clean distclean maintainer-clean:
+ rm -rf tmp_check
diff --git a/src/test/icu/README b/src/test/icu/README
new file mode 100644
index 00000000000..cfc9353dffe
--- /dev/null
+++ b/src/test/icu/README
@@ -0,0 +1,27 @@
+src/test/icu/README
+
+Regression tests for ICU functionality
+======================================
+
+This directory contains a test suite for ICU functionality.
+
+Running the tests
+=================
+
+NOTE: You must have given the --enable-tap-tests argument to configure.
+Also, to use "make installcheck", you must have built and installed
+contrib/hstore in addition to the core code.
+
+Run
+ make check
+or
+ make installcheck
+You can use "make installcheck" if you previously did "make install".
+In that case, the code in the installation tree is tested. With
+"make check", a temporary installation tree is built from the current
+sources and then tested.
+
+Either way, this test initializes, starts, and stops several test Postgres
+clusters.
+
+See src/test/perl/README for more info about running these tests.
diff --git a/src/test/icu/t/010_database.pl b/src/test/icu/t/010_database.pl
new file mode 100644
index 00000000000..4cc8907b421
--- /dev/null
+++ b/src/test/icu/t/010_database.pl
@@ -0,0 +1,58 @@
+# Copyright (c) 2022, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+use PostgreSQL::Test::Cluster;
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+if ($ENV{with_icu} ne 'yes')
+{
+ plan skip_all => 'ICU not supported by this build';
+}
+
+my $node1 = PostgreSQL::Test::Cluster->new('node1');
+$node1->init;
+$node1->start;
+
+$node1->safe_psql('postgres',
+ q{CREATE DATABASE dbicu LOCALE_PROVIDER icu LOCALE 'C' ICU_LOCALE 'en-u-kf-upper' TEMPLATE template0});
+
+$node1->safe_psql('dbicu',
+q{
+CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper');
+CREATE TABLE icu (def text, en text COLLATE "en-x-icu", upfirst text COLLATE upperfirst);
+INSERT INTO icu VALUES ('a', 'a', 'a'), ('b', 'b', 'b'), ('A', 'A', 'A'), ('B', 'B', 'B');
+});
+
+is($node1->safe_psql('dbicu', q{SELECT def FROM icu ORDER BY def}),
+ qq(A
+a
+B
+b),
+ 'sort by database default locale');
+
+is($node1->safe_psql('dbicu', q{SELECT def FROM icu ORDER BY def COLLATE "en-x-icu"}),
+ qq(a
+A
+b
+B),
+ 'sort by explicit collation standard');
+
+is($node1->safe_psql('dbicu', q{SELECT def FROM icu ORDER BY en COLLATE upperfirst}),
+ qq(A
+a
+B
+b),
+ 'sort by explicit collation upper first');
+
+
+# Test error cases in CREATE DATABASE involving locale-related options
+
+my ($ret, $stdout, $stderr) = $node1->psql('postgres',
+ q{CREATE DATABASE dbicu LOCALE_PROVIDER icu TEMPLATE template0});
+isnt($ret, 0, "ICU locale must be specified for ICU provider: exit code not 0");
+like($stderr, qr/ERROR: ICU locale must be specified/, "ICU locale must be specified for ICU provider: error message");
+
+
+done_testing();
diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out
index 9699ca16cfc..d4c8c6de38e 100644
--- a/src/test/regress/expected/collate.icu.utf8.out
+++ b/src/test/regress/expected/collate.icu.utf8.out
@@ -1029,14 +1029,12 @@ CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
ERROR: collation "test0" already exists
do $$
BEGIN
- EXECUTE 'CREATE COLLATION test1 (provider = icu, lc_collate = ' ||
- quote_literal(current_setting('lc_collate')) ||
- ', lc_ctype = ' ||
- quote_literal(current_setting('lc_ctype')) || ');';
+ EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' ||
+ quote_literal(current_setting('lc_collate')) || ');';
END
$$;
-CREATE COLLATION test3 (provider = icu, lc_collate = 'en_US.utf8'); -- fail, need lc_ctype
-ERROR: parameter "lc_ctype" must be specified
+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'); /* never fails with ICU */ DROP COLLATION testx;
CREATE COLLATION test4 FROM nonsense;
ERROR: collation "nonsense" for encoding "UTF8" does not exist
diff --git a/src/test/regress/sql/collate.icu.utf8.sql b/src/test/regress/sql/collate.icu.utf8.sql
index 242a7ce6b7c..b0ddc7db44b 100644
--- a/src/test/regress/sql/collate.icu.utf8.sql
+++ b/src/test/regress/sql/collate.icu.utf8.sql
@@ -366,13 +366,11 @@ $$;
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
do $$
BEGIN
- EXECUTE 'CREATE COLLATION test1 (provider = icu, lc_collate = ' ||
- quote_literal(current_setting('lc_collate')) ||
- ', lc_ctype = ' ||
- quote_literal(current_setting('lc_ctype')) || ');';
+ EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' ||
+ quote_literal(current_setting('lc_collate')) || ');';
END
$$;
-CREATE COLLATION test3 (provider = icu, lc_collate = 'en_US.utf8'); -- fail, need lc_ctype
+CREATE COLLATION test3 (provider = icu, lc_collate = 'en_US.utf8'); -- fail, needs "locale"
CREATE COLLATION testx (provider = icu, locale = 'nonsense'); /* never fails with ICU */ DROP COLLATION testx;
CREATE COLLATION test4 FROM nonsense;