Refactor: make default_locale internal to pg_locale.c.
authorJeff Davis <jdavis@postgresql.org>
Sun, 28 Jul 2024 20:07:25 +0000 (13:07 -0700)
committerJeff Davis <jdavis@postgresql.org>
Sun, 28 Jul 2024 20:07:25 +0000 (13:07 -0700)
Discussion: https://postgr.es/m/2228884bb1f1a02614b39f71a90c94d2cc8a3a2f.camel@j-davis.com
Reviewed-by: Peter Eisentraut, Andreas Karlsson
src/backend/utils/adt/pg_locale.c
src/backend/utils/init/postinit.c
src/include/utils/pg_locale.h

index f386945ee0c487fcbdff225964612eb9722e4784..c1b7ecced4810802e523cf7057488b249a8a02cc 100644 (file)
@@ -56,6 +56,7 @@
 
 #include "access/htup_details.h"
 #include "catalog/pg_collation.h"
+#include "catalog/pg_database.h"
 #include "common/hashfn.h"
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
@@ -116,6 +117,8 @@ char       *localized_full_months[12 + 1];
 /* is the databases's LC_CTYPE the C locale? */
 bool       database_ctype_is_c = false;
 
+static struct pg_locale_struct default_locale;
+
 /* indicates whether locale information cache is valid */
 static bool CurrentLocaleConvValid = false;
 static bool CurrentLCTimeValid = false;
@@ -1458,8 +1461,6 @@ lc_ctype_is_c(Oid collation)
    return (lookup_collation_cache(collation, true))->ctype_is_c;
 }
 
-struct pg_locale_struct default_locale;
-
 void
 make_icu_collator(const char *iculocstr,
                  const char *icurules,
@@ -1554,7 +1555,69 @@ pg_locale_deterministic(pg_locale_t locale)
 }
 
 /*
- * Create a locale_t from a collation OID.  Results are cached for the
+ * Initialize default_locale with database locale settings.
+ */
+void
+init_database_collation(void)
+{
+   HeapTuple   tup;
+   Form_pg_database dbform;
+   Datum       datum;
+   bool        isnull;
+
+   /* Fetch our pg_database row normally, via syscache */
+   tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
+   if (!HeapTupleIsValid(tup))
+       elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
+   dbform = (Form_pg_database) GETSTRUCT(tup);
+
+   if (dbform->datlocprovider == COLLPROVIDER_BUILTIN)
+   {
+       char       *datlocale;
+
+       datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
+       datlocale = TextDatumGetCString(datum);
+
+       builtin_validate_locale(dbform->encoding, datlocale);
+
+       default_locale.info.builtin.locale = MemoryContextStrdup(
+                                                                TopMemoryContext, datlocale);
+   }
+   else if (dbform->datlocprovider == COLLPROVIDER_ICU)
+   {
+       char       *datlocale;
+       char       *icurules;
+
+       datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
+       datlocale = TextDatumGetCString(datum);
+
+       datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_daticurules, &isnull);
+       if (!isnull)
+           icurules = TextDatumGetCString(datum);
+       else
+           icurules = NULL;
+
+       make_icu_collator(datlocale, icurules, &default_locale);
+   }
+   else
+   {
+       Assert(dbform->datlocprovider == COLLPROVIDER_LIBC);
+   }
+
+   default_locale.provider = dbform->datlocprovider;
+
+   /*
+    * Default locale is currently always deterministic.  Nondeterministic
+    * locales currently don't support pattern matching, which would break a
+    * lot of things if applied globally.
+    */
+   default_locale.deterministic = true;
+
+   ReleaseSysCache(tup);
+}
+
+/*
+ * Create a pg_locale_t from a collation OID.  Results are cached for the
  * lifetime of the backend.  Thus, do not free the result with freelocale().
  *
  * As a special optimization, the default/database collation returns 0.
index 25867c8bd5b960c28e9089641b356834b25318a9..fe703e4f19fd53e6618db851d941f2e188f9eb85 100644 (file)
@@ -318,7 +318,6 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
    bool        isnull;
    char       *collate;
    char       *ctype;
-   char       *datlocale;
 
    /* Fetch our pg_database row normally, via syscache */
    tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
@@ -423,42 +422,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
        strcmp(ctype, "POSIX") == 0)
        database_ctype_is_c = true;
 
-   if (dbform->datlocprovider == COLLPROVIDER_BUILTIN)
-   {
-       datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
-       datlocale = TextDatumGetCString(datum);
-
-       builtin_validate_locale(dbform->encoding, datlocale);
-
-       default_locale.info.builtin.locale = MemoryContextStrdup(
-                                                                TopMemoryContext, datlocale);
-   }
-   else if (dbform->datlocprovider == COLLPROVIDER_ICU)
-   {
-       char       *icurules;
-
-       datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
-       datlocale = TextDatumGetCString(datum);
-
-       datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_daticurules, &isnull);
-       if (!isnull)
-           icurules = TextDatumGetCString(datum);
-       else
-           icurules = NULL;
-
-       make_icu_collator(datlocale, icurules, &default_locale);
-   }
-   else
-       datlocale = NULL;
-
-   default_locale.provider = dbform->datlocprovider;
-
-   /*
-    * Default locale is currently always deterministic.  Nondeterministic
-    * locales currently don't support pattern matching, which would break a
-    * lot of things if applied globally.
-    */
-   default_locale.deterministic = true;
+   init_database_collation();
 
    /*
     * Check collation version.  See similar code in
@@ -478,7 +442,10 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
        if (dbform->datlocprovider == COLLPROVIDER_LIBC)
            locale = collate;
        else
-           locale = datlocale;
+       {
+           datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
+           locale = TextDatumGetCString(datum);
+       }
 
        actual_versionstr = get_collation_actual_version(dbform->datlocprovider, locale);
        if (!actual_versionstr)
index 040968d6ff295766449b94ab8ccb74ebb7ce591d..3e14a261b1636d69d899d05c9f2c2f9d17090a78 100644 (file)
@@ -93,13 +93,12 @@ struct pg_locale_struct
 
 typedef struct pg_locale_struct *pg_locale_t;
 
-extern PGDLLIMPORT struct pg_locale_struct default_locale;
-
 extern void make_icu_collator(const char *iculocstr,
                              const char *icurules,
                              struct pg_locale_struct *resultp);
 
 extern bool pg_locale_deterministic(pg_locale_t locale);
+extern void init_database_collation(void);
 extern pg_locale_t pg_newlocale_from_collation(Oid collid);
 
 extern char *get_collation_actual_version(char collprovider, const char *collcollate);