summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Davis2024-03-18 18:56:45 +0000
committerJeff Davis2024-03-18 18:58:13 +0000
commit846311051e8fdca4c9db83b2b09425759a8b102d (patch)
treea6b47781bb156109b4048c773b7ad30be9d9a96b
parent66ab9371a23320cf608e68e8e5d2811992941bea (diff)
Address more review comments on commit 2d819a08a1.
Based on comments from Peter Eisentraut. * Document CREATE DATABASE ... BUILTIN_LOCALE. * Determine required encoding based on locale name for CREATE COLLATION. Use -1 for "C" (requires catversion bump). * initdb output fixups. * Make ctype_is_c a constant true for now. * Fixups to ICU 010_create_database.pl test. Discussion: https://postgr.es/m/[email protected]
-rw-r--r--doc/src/sgml/ref/create_database.sgml18
-rw-r--r--src/backend/commands/collationcmds.c2
-rw-r--r--src/backend/utils/adt/pg_locale.c28
-rw-r--r--src/bin/initdb/initdb.c7
-rw-r--r--src/bin/initdb/t/001_initdb.pl2
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/utils/pg_locale.h1
-rw-r--r--src/test/icu/t/010_database.pl12
8 files changed, 58 insertions, 14 deletions
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
index 6c1fd95602d..a839a8568cb 100644
--- a/doc/src/sgml/ref/create_database.sgml
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -29,6 +29,7 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
[ LOCALE [=] <replaceable class="parameter">locale</replaceable> ]
[ LC_COLLATE [=] <replaceable class="parameter">lc_collate</replaceable> ]
[ LC_CTYPE [=] <replaceable class="parameter">lc_ctype</replaceable> ]
+ [ BUILTIN_LOCALE [=] <replaceable class="parameter">builtin_locale</replaceable> ]
[ ICU_LOCALE [=] <replaceable class="parameter">icu_locale</replaceable> ]
[ ICU_RULES [=] <replaceable class="parameter">icu_rules</replaceable> ]
[ LOCALE_PROVIDER [=] <replaceable class="parameter">locale_provider</replaceable> ]
@@ -216,6 +217,23 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
</listitem>
</varlistentry>
+ <varlistentry id="create-database-builtin-locale">
+ <term><replaceable class="parameter">builtin_locale</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the builtin provider locale for the database default
+ collation order and character classification, overriding the setting
+ <xref linkend="create-database-locale"/>. The <link
+ linkend="create-database-locale-provider">locale provider</link> must
+ be <literal>builtin</literal>. The default is the setting of <xref
+ linkend="create-database-locale"/> if specified; otherwise the same
+ setting as the template database. Currently, the only available
+ locale for the <literal>builtin</literal> provider is
+ <literal>C</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="create-database-icu-locale">
<term><replaceable class="parameter">icu_locale</replaceable></term>
<listitem>
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 9059f8b3efd..63ef9a08411 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -318,7 +318,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
if (collprovider == COLLPROVIDER_BUILTIN)
{
- collencoding = GetDatabaseEncoding();
+ collencoding = builtin_locale_encoding(colllocale);
}
else if (collprovider == COLLPROVIDER_ICU)
{
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 364716bcec8..f793f50b984 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1270,14 +1270,8 @@ lookup_collation_cache(Oid collation, bool set_flags)
if (collform->collprovider == COLLPROVIDER_BUILTIN)
{
- Datum datum;
- const char *colllocale;
-
- datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
- colllocale = TextDatumGetCString(datum);
-
cache_entry->collate_is_c = true;
- cache_entry->ctype_is_c = (strcmp(colllocale, "C") == 0);
+ cache_entry->ctype_is_c = true;
}
else if (collform->collprovider == COLLPROVIDER_LIBC)
{
@@ -2502,6 +2496,26 @@ pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
}
/*
+ * Return required encoding ID for the given locale, or -1 if any encoding is
+ * valid for the locale.
+ *
+ * The only supported locale for the builtin provider is "C", and it's
+ * available for any encoding.
+ */
+int
+builtin_locale_encoding(const char *locale)
+{
+ if (strcmp(locale, "C") == 0)
+ return -1;
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("invalid locale name \"%s\" for builtin provider",
+ locale)));
+}
+
+
+/*
* Validate the locale and encoding combination, and return the canonical form
* of the locale name.
*
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 8d53ef4a1fc..c2daff17179 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -2455,7 +2455,8 @@ usage(const char *progname)
" set default locale in the respective category for\n"
" new databases (default taken from environment)\n"));
printf(_(" --no-locale equivalent to --locale=C\n"));
- printf(_(" --builtin-locale=LOCALE set builtin locale name for new databases\n"));
+ printf(_(" --builtin-locale=LOCALE\n"
+ " set builtin locale name for new databases\n"));
printf(_(" --locale-provider={builtin|libc|icu}\n"
" set default locale provider for new databases\n"));
printf(_(" --pwfile=FILE read password for the new superuser from file\n"));
@@ -2618,9 +2619,9 @@ setup_locale_encoding(void)
else
{
printf(_("The database cluster will be initialized with this locale configuration:\n"));
- printf(_(" default collation provider: %s\n"), collprovider_name(locale_provider));
+ printf(_(" locale provider: %s\n"), collprovider_name(locale_provider));
if (locale_provider != COLLPROVIDER_LIBC)
- printf(_(" default collation locale: %s\n"), datlocale);
+ printf(_(" default collation: %s\n"), datlocale);
printf(_(" LC_COLLATE: %s\n"
" LC_CTYPE: %s\n"
" LC_MESSAGES: %s\n"
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index e719f70dae2..3478f58b02a 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -138,7 +138,7 @@ if ($ENV{with_icu} eq 'yes')
'--lc-monetary=C', '--lc-time=C',
"$tempdir/data4"
],
- qr/^\s+default collation locale:\s+und\n/ms,
+ qr/^\s+default collation:\s+und\n/ms,
'options --locale-provider=icu --locale=und --lc-*=C');
command_fails_like(
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 43a9a707094..6fb22007ed0 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -57,6 +57,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202403172
+#define CATALOG_VERSION_NO 202403181
#endif
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 3d949d51123..205aa200672 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -117,6 +117,7 @@ extern size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize,
extern size_t pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
size_t srclen, pg_locale_t locale);
+extern int builtin_locale_encoding(const char *loc_str);
extern const char *builtin_validate_locale(int encoding, const char *loc_str);
extern void icu_validate_locale(const char *loc_str);
extern char *icu_language_tag(const char *loc_str, int elevel);
diff --git a/src/test/icu/t/010_database.pl b/src/test/icu/t/010_database.pl
index 5f8ef168034..88d91cca39d 100644
--- a/src/test/icu/t/010_database.pl
+++ b/src/test/icu/t/010_database.pl
@@ -62,8 +62,18 @@ is( $node1->psql(
0,
"C locale works for ICU");
+# Test that LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE
+# are specified
+is( $node1->psql(
+ 'postgres',
+ q{CREATE DATABASE dbicu2 LOCALE_PROVIDER icu LOCALE '@colStrength=primary'
+ LC_COLLATE='C' LC_CTYPE='C' TEMPLATE template0 ENCODING UTF8}
+ ),
+ 0,
+ "LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE are specified");
+
my ($ret, $stdout, $stderr) = $node1->psql('postgres',
- q{CREATE DATABASE dbicu LOCALE_PROVIDER builtin LOCALE 'C' TEMPLATE dbicu}
+ q{CREATE DATABASE dbicu3 LOCALE_PROVIDER builtin LOCALE 'C' TEMPLATE dbicu}
);
isnt($ret, 0, "locale provider must match template: exit code not 0");
like(