]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Address more review comments on commit 2d819a08a1.
authorJeff Davis <jdavis@postgresql.org>
Mon, 18 Mar 2024 18:56:45 +0000 (11:56 -0700)
committerJeff Davis <jdavis@postgresql.org>
Mon, 18 Mar 2024 18:58:13 +0000 (11:58 -0700)
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/4135cf11-206d-40ed-96c0-9363c1232379@eisentraut.org

doc/src/sgml/ref/create_database.sgml
src/backend/commands/collationcmds.c
src/backend/utils/adt/pg_locale.c
src/bin/initdb/initdb.c
src/bin/initdb/t/001_initdb.pl
src/include/catalog/catversion.h
src/include/utils/pg_locale.h
src/test/icu/t/010_database.pl

index 6c1fd95602da2ea402ca288f28dd0f652e0eb18b..a839a8568cb06b73d35dd696fd9dadba9411b8c9 100644 (file)
@@ -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>
index 9059f8b3efda33f11a120691115d5ede86b88fa6..63ef9a08411b0b4bb3e56caea0194e455158a137 100644 (file)
@@ -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)
                {
index 364716bcec8692db16908f1987c971d58ec7c962..f793f50b98444297ade6ebd19f99f7b0ecbfa69f 100644 (file)
@@ -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)
                {
@@ -2501,6 +2495,26 @@ pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
        return result;
 }
 
+/*
+ * 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.
index 8d53ef4a1fc8923de24d83d5bcdf7ef53187b314..c2daff1717976de950c9ce60ce2ceef43d367269 100644 (file)
@@ -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"
index e719f70dae285ebb33bb8c3f2d30527da88c31d3..3478f58b02a10a94bf6c5d73691c1e829755417e 100644 (file)
@@ -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(
index 43a9a707094093a1753c534481f971149ba0f961..6fb22007ed007624b3e5af5df19128f3ee390132 100644 (file)
@@ -57,6 +57,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     202403172
+#define CATALOG_VERSION_NO     202403181
 
 #endif
index 3d949d5112390436a04698e6f1d5bdb156e3bb77..205aa200672f6833ed0fb6e7c9115d0fce5122bd 100644 (file)
@@ -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);
index 5f8ef16803423262a4a17868dab147046e2ae9c9..88d91cca39d4729b9d8178cb93b107c9f69294c0 100644 (file)
@@ -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(