diff options
author | Jeff Davis <jdavis@postgresql.org> | 2023-03-09 10:52:41 -0800 |
---|---|---|
committer | Jeff Davis <jdavis@postgresql.org> | 2023-03-09 10:52:41 -0800 |
commit | 27b62377b47f9e7bf58613608bc718c86ea91e91 (patch) | |
tree | 80ada6d59fac3df61ff41801d5fd3c1faf469470 /src | |
parent | a7e584a7d68a9a2bcc7efaf442262771f9044248 (diff) | |
download | postgresql-27b62377b47f9e7bf58613608bc718c86ea91e91.tar.gz postgresql-27b62377b47f9e7bf58613608bc718c86ea91e91.zip |
Use ICU by default at initdb time.
If the ICU locale is not specified, initialize the default collator
and retrieve the locale name from that.
Discussion: https://postgr.es/m/510d284759f6e943ce15096167760b2edcb2e700.camel@j-davis.com
Reviewed-by: Peter Eisentraut
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/initdb/Makefile | 4 | ||||
-rw-r--r-- | src/bin/initdb/initdb.c | 54 | ||||
-rw-r--r-- | src/bin/initdb/t/001_initdb.pl | 7 | ||||
-rw-r--r-- | src/bin/pg_dump/t/002_pg_dump.pl | 2 | ||||
-rw-r--r-- | src/bin/scripts/t/020_createdb.pl | 2 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/Makefile | 3 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/connect/test5.pgc | 2 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/expected/connect-test5.c | 2 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/expected/connect-test5.stderr | 2 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/meson.build | 1 | ||||
-rw-r--r-- | src/test/icu/t/010_database.pl | 2 |
11 files changed, 61 insertions, 20 deletions
diff --git a/src/bin/initdb/Makefile b/src/bin/initdb/Makefile index eab89c55013..d69bd89572a 100644 --- a/src/bin/initdb/Makefile +++ b/src/bin/initdb/Makefile @@ -16,7 +16,7 @@ subdir = src/bin/initdb top_builddir = ../../.. include $(top_builddir)/src/Makefile.global -override CPPFLAGS := -I$(libpq_srcdir) -I$(top_srcdir)/src/timezone $(CPPFLAGS) +override CPPFLAGS := -I$(libpq_srcdir) -I$(top_srcdir)/src/timezone $(ICU_CFLAGS) $(CPPFLAGS) # Note: it's important that we link to encnames.o from libpgcommon, not # from libpq, else we have risks of version skew if we run with a libpq @@ -24,7 +24,7 @@ override CPPFLAGS := -I$(libpq_srcdir) -I$(top_srcdir)/src/timezone $(CPPFLAGS) # should ensure that that happens. # # We need libpq only because fe_utils does. -LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport) +LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport) $(ICU_LIBS) # use system timezone data? ifneq (,$(with_system_tzdata)) diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 5e3c6a27c48..bf88cd24396 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -53,6 +53,9 @@ #include <netdb.h> #include <sys/socket.h> #include <sys/stat.h> +#ifdef USE_ICU +#include <unicode/ucol.h> +#endif #include <unistd.h> #include <signal.h> #include <time.h> @@ -133,7 +136,11 @@ static char *lc_monetary = NULL; static char *lc_numeric = NULL; static char *lc_time = NULL; static char *lc_messages = NULL; +#ifdef USE_ICU +static char locale_provider = COLLPROVIDER_ICU; +#else static char locale_provider = COLLPROVIDER_LIBC; +#endif static char *icu_locale = NULL; static char *icu_rules = NULL; static const char *default_text_search_config = NULL; @@ -2029,6 +2036,50 @@ check_icu_locale_encoding(int user_enc) } /* + * Check that ICU accepts the locale name; or if not specified, retrieve the + * default ICU locale. + */ +static void +check_icu_locale(void) +{ +#ifdef USE_ICU + UCollator *collator; + UErrorCode status; + + status = U_ZERO_ERROR; + collator = ucol_open(icu_locale, &status); + if (U_FAILURE(status)) + { + if (icu_locale) + pg_fatal("could not open collator for locale \"%s\": %s", + icu_locale, u_errorName(status)); + else + pg_fatal("could not open collator for default locale: %s", + u_errorName(status)); + } + + /* if not specified, get locale from default collator */ + if (icu_locale == NULL) + { + const char *default_locale; + + status = U_ZERO_ERROR; + default_locale = ucol_getLocaleByType(collator, ULOC_VALID_LOCALE, + &status); + if (U_FAILURE(status)) + { + ucol_close(collator); + pg_fatal("could not determine default ICU locale"); + } + + icu_locale = pg_strdup(default_locale); + } + + ucol_close(collator); +#endif +} + +/* * set up the locale variables * * assumes we have called setlocale(LC_ALL, "") -- see set_pglocale_pgservice @@ -2081,8 +2132,7 @@ setlocales(void) if (locale_provider == COLLPROVIDER_ICU) { - if (!icu_locale) - pg_fatal("ICU locale must be specified"); + check_icu_locale(); /* * In supported builds, the ICU locale ID will be checked by the diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl index 772769acabf..e5d214e09c4 100644 --- a/src/bin/initdb/t/001_initdb.pl +++ b/src/bin/initdb/t/001_initdb.pl @@ -97,11 +97,6 @@ SKIP: if ($ENV{with_icu} eq 'yes') { - command_fails_like( - [ 'initdb', '--no-sync', '--locale-provider=icu', "$tempdir/data2" ], - qr/initdb: error: ICU locale must be specified/, - 'locale provider ICU requires --icu-locale'); - command_ok( [ 'initdb', '--no-sync', @@ -116,7 +111,7 @@ if ($ENV{with_icu} eq 'yes') '--locale-provider=icu', '--icu-locale=@colNumeric=lower', "$tempdir/dataX" ], - qr/FATAL: could not open collator for locale/, + qr/error: could not open collator for locale/, 'fails for invalid ICU locale'); command_fails_like( diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl index 187e4b8d07d..9c354213ceb 100644 --- a/src/bin/pg_dump/t/002_pg_dump.pl +++ b/src/bin/pg_dump/t/002_pg_dump.pl @@ -1758,7 +1758,7 @@ my %tests = ( create_sql => "CREATE DATABASE dump_test2 LOCALE = 'C' TEMPLATE = template0;", regexp => qr/^ - \QCREATE DATABASE dump_test2 \E.*\QLOCALE = 'C';\E + \QCREATE DATABASE dump_test2 \E.*\QLOCALE = 'C'\E /xm, like => { pg_dumpall_dbprivs => 1, }, }, diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl index 3ad4fbb00c8..8ec58cdd648 100644 --- a/src/bin/scripts/t/020_createdb.pl +++ b/src/bin/scripts/t/020_createdb.pl @@ -13,7 +13,7 @@ program_version_ok('createdb'); program_options_handling_ok('createdb'); my $node = PostgreSQL::Test::Cluster->new('main'); -$node->init; +$node->init(extra => ['--locale-provider=libc']); $node->start; $node->issues_sql_like( diff --git a/src/interfaces/ecpg/test/Makefile b/src/interfaces/ecpg/test/Makefile index d7a7d1d1ca5..cf841a3a5b2 100644 --- a/src/interfaces/ecpg/test/Makefile +++ b/src/interfaces/ecpg/test/Makefile @@ -14,9 +14,6 @@ override CPPFLAGS := \ '-DSHELLPROG="$(SHELL)"' \ $(CPPFLAGS) -# default encoding for regression tests -ENCODING = SQL_ASCII - ifneq ($(build_os),mingw32) abs_builddir := $(shell pwd) else diff --git a/src/interfaces/ecpg/test/connect/test5.pgc b/src/interfaces/ecpg/test/connect/test5.pgc index de291600899..d5125536777 100644 --- a/src/interfaces/ecpg/test/connect/test5.pgc +++ b/src/interfaces/ecpg/test/connect/test5.pgc @@ -55,7 +55,7 @@ exec sql end declare section; exec sql connect to 'unix:postgresql://localhost/ecpg2_regression' as main user :user USING "connectpw"; exec sql disconnect main; - exec sql connect to unix:postgresql://localhost/ecpg2_regression?connect_timeout=180&client_encoding=latin1 as main user regress_ecpg_user1/connectpw; + exec sql connect to unix:postgresql://localhost/ecpg2_regression?connect_timeout=180&client_encoding=sql_ascii as main user regress_ecpg_user1/connectpw; exec sql disconnect main; exec sql connect to "unix:postgresql://200.46.204.71/ecpg2_regression" as main user regress_ecpg_user1/connectpw; diff --git a/src/interfaces/ecpg/test/expected/connect-test5.c b/src/interfaces/ecpg/test/expected/connect-test5.c index c1124c627ff..ec1514ed9ab 100644 --- a/src/interfaces/ecpg/test/expected/connect-test5.c +++ b/src/interfaces/ecpg/test/expected/connect-test5.c @@ -117,7 +117,7 @@ main(void) #line 56 "test5.pgc" - { ECPGconnect(__LINE__, 0, "unix:postgresql://localhost/ecpg2_regression?connect_timeout=180 & client_encoding=latin1" , "regress_ecpg_user1" , "connectpw" , "main", 0); } + { ECPGconnect(__LINE__, 0, "unix:postgresql://localhost/ecpg2_regression?connect_timeout=180 & client_encoding=sql_ascii" , "regress_ecpg_user1" , "connectpw" , "main", 0); } #line 58 "test5.pgc" { ECPGdisconnect(__LINE__, "main");} diff --git a/src/interfaces/ecpg/test/expected/connect-test5.stderr b/src/interfaces/ecpg/test/expected/connect-test5.stderr index 01a6a0a13b2..51cc18916a1 100644 --- a/src/interfaces/ecpg/test/expected/connect-test5.stderr +++ b/src/interfaces/ecpg/test/expected/connect-test5.stderr @@ -50,7 +50,7 @@ [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_finish: connection main closed [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ECPGconnect: opening database ecpg2_regression on <DEFAULT> port <DEFAULT> with options connect_timeout=180 & client_encoding=latin1 for user regress_ecpg_user1 +[NO_PID]: ECPGconnect: opening database ecpg2_regression on <DEFAULT> port <DEFAULT> with options connect_timeout=180 & client_encoding=sql_ascii for user regress_ecpg_user1 [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_finish: connection main closed [NO_PID]: sqlca: code: 0, state: 00000 diff --git a/src/interfaces/ecpg/test/meson.build b/src/interfaces/ecpg/test/meson.build index d0be73ccf98..04c6819a799 100644 --- a/src/interfaces/ecpg/test/meson.build +++ b/src/interfaces/ecpg/test/meson.build @@ -69,7 +69,6 @@ ecpg_test_files = files( ecpg_regress_args = [ '--dbname=ecpg1_regression,ecpg2_regression', '--create-role=regress_ecpg_user1,regress_ecpg_user2', - '--encoding=SQL_ASCII', ] tests += { diff --git a/src/test/icu/t/010_database.pl b/src/test/icu/t/010_database.pl index 80ab1c7789c..45d77c319a3 100644 --- a/src/test/icu/t/010_database.pl +++ b/src/test/icu/t/010_database.pl @@ -12,7 +12,7 @@ if ($ENV{with_icu} ne 'yes') } my $node1 = PostgreSQL::Test::Cluster->new('node1'); -$node1->init; +$node1->init(extra => ['--locale-provider=libc']); $node1->start; $node1->safe_psql('postgres', |