Skip to content

Commit 1ba0782

Browse files
committed
Perform provider-specific initialization in new functions.
Reviewed-by: Andreas Karlsson Discussion: https://postgr.es/m/4548a168-62cd-457b-8d06-9ba7b985c477@proxel.se
1 parent 8817e8d commit 1ba0782

File tree

6 files changed

+259
-146
lines changed

6 files changed

+259
-146
lines changed

src/backend/utils/adt/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ OBJS = \
7979
orderedsetaggs.o \
8080
partitionfuncs.o \
8181
pg_locale.o \
82+
pg_locale_builtin.o \
8283
pg_locale_icu.o \
8384
pg_locale_libc.o \
8485
pg_lsn.o \

src/backend/utils/adt/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ backend_sources += files(
6666
'orderedsetaggs.c',
6767
'partitionfuncs.c',
6868
'pg_locale.c',
69+
'pg_locale_builtin.c',
6970
'pg_locale_icu.c',
7071
'pg_locale_libc.c',
7172
'pg_lsn.c',

src/backend/utils/adt/pg_locale.c

Lines changed: 24 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,12 @@
8989

9090
#define MAX_L10N_DATA 80
9191

92+
/* pg_locale_builtin.c */
93+
extern pg_locale_t create_pg_locale_builtin(Oid collid, MemoryContext context);
94+
9295
/* pg_locale_icu.c */
9396
#ifdef USE_ICU
9497
extern UCollator *pg_ucol_open(const char *loc_str);
95-
extern UCollator *make_icu_collator(const char *iculocstr,
96-
const char *icurules);
9798
extern int strncoll_icu(const char *arg1, ssize_t len1,
9899
const char *arg2, ssize_t len2,
99100
pg_locale_t locale);
@@ -104,10 +105,10 @@ extern size_t strnxfrm_prefix_icu(char *dest, size_t destsize,
104105
const char *src, ssize_t srclen,
105106
pg_locale_t locale);
106107
#endif
108+
extern pg_locale_t create_pg_locale_icu(Oid collid, MemoryContext context);
107109

108110
/* pg_locale_libc.c */
109-
extern locale_t make_libc_collator(const char *collate,
110-
const char *ctype);
111+
extern pg_locale_t create_pg_locale_libc(Oid collid, MemoryContext context);
111112
extern int strncoll_libc(const char *arg1, ssize_t len1,
112113
const char *arg2, ssize_t len2,
113114
pg_locale_t locale);
@@ -138,7 +139,7 @@ char *localized_full_months[12 + 1];
138139
/* is the databases's LC_CTYPE the C locale? */
139140
bool database_ctype_is_c = false;
140141

141-
static struct pg_locale_struct default_locale;
142+
static pg_locale_t default_locale = NULL;
142143

143144
/* indicates whether locale information cache is valid */
144145
static bool CurrentLocaleConvValid = false;
@@ -1194,7 +1195,6 @@ IsoLocaleName(const char *winlocname)
11941195

11951196
#endif /* WIN32 && LC_MESSAGES */
11961197

1197-
11981198
/*
11991199
* Create a new pg_locale_t struct for the given collation oid.
12001200
*/
@@ -1207,80 +1207,23 @@ create_pg_locale(Oid collid, MemoryContext context)
12071207
Datum datum;
12081208
bool isnull;
12091209

1210-
result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct));
1211-
12121210
tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
12131211
if (!HeapTupleIsValid(tp))
12141212
elog(ERROR, "cache lookup failed for collation %u", collid);
12151213
collform = (Form_pg_collation) GETSTRUCT(tp);
12161214

1217-
result->provider = collform->collprovider;
1218-
result->deterministic = collform->collisdeterministic;
1219-
result->is_default = false;
1220-
12211215
if (collform->collprovider == COLLPROVIDER_BUILTIN)
1222-
{
1223-
const char *locstr;
1224-
1225-
datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
1226-
locstr = TextDatumGetCString(datum);
1227-
1228-
result->collate_is_c = true;
1229-
result->ctype_is_c = (strcmp(locstr, "C") == 0);
1230-
1231-
builtin_validate_locale(GetDatabaseEncoding(), locstr);
1232-
1233-
result->info.builtin.locale = MemoryContextStrdup(context,
1234-
locstr);
1235-
}
1216+
result = create_pg_locale_builtin(collid, context);
12361217
else if (collform->collprovider == COLLPROVIDER_ICU)
1237-
{
1238-
#ifdef USE_ICU
1239-
const char *iculocstr;
1240-
const char *icurules;
1241-
1242-
datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
1243-
iculocstr = TextDatumGetCString(datum);
1244-
1245-
result->collate_is_c = false;
1246-
result->ctype_is_c = false;
1247-
1248-
datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collicurules, &isnull);
1249-
if (!isnull)
1250-
icurules = TextDatumGetCString(datum);
1251-
else
1252-
icurules = NULL;
1253-
1254-
result->info.icu.locale = MemoryContextStrdup(context, iculocstr);
1255-
result->info.icu.ucol = make_icu_collator(iculocstr, icurules);
1256-
#else
1257-
/* could get here if a collation was created by a build with ICU */
1258-
ereport(ERROR,
1259-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1260-
errmsg("ICU is not supported in this build")));
1261-
#endif
1262-
}
1218+
result = create_pg_locale_icu(collid, context);
12631219
else if (collform->collprovider == COLLPROVIDER_LIBC)
1264-
{
1265-
const char *collcollate;
1266-
const char *collctype;
1267-
1268-
datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate);
1269-
collcollate = TextDatumGetCString(datum);
1270-
datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collctype);
1271-
collctype = TextDatumGetCString(datum);
1272-
1273-
result->collate_is_c = (strcmp(collcollate, "C") == 0) ||
1274-
(strcmp(collcollate, "POSIX") == 0);
1275-
result->ctype_is_c = (strcmp(collctype, "C") == 0) ||
1276-
(strcmp(collctype, "POSIX") == 0);
1277-
1278-
result->info.lt = make_libc_collator(collcollate, collctype);
1279-
}
1220+
result = create_pg_locale_libc(collid, context);
12801221
else
12811222
/* shouldn't happen */
12821223
PGLOCALE_SUPPORT_ERROR(collform->collprovider);
12831224

1225+
result->is_default = false;
1226+
12841227
datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collversion,
12851228
&isnull);
12861229
if (!isnull)
@@ -1336,7 +1279,9 @@ init_database_collation(void)
13361279
{
13371280
HeapTuple tup;
13381281
Form_pg_database dbform;
1339-
Datum datum;
1282+
pg_locale_t result;
1283+
1284+
Assert(default_locale == NULL);
13401285

13411286
/* Fetch our pg_database row normally, via syscache */
13421287
tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
@@ -1345,81 +1290,22 @@ init_database_collation(void)
13451290
dbform = (Form_pg_database) GETSTRUCT(tup);
13461291

13471292
if (dbform->datlocprovider == COLLPROVIDER_BUILTIN)
1348-
{
1349-
char *datlocale;
1350-
1351-
datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
1352-
datlocale = TextDatumGetCString(datum);
1353-
1354-
builtin_validate_locale(dbform->encoding, datlocale);
1355-
1356-
default_locale.collate_is_c = true;
1357-
default_locale.ctype_is_c = (strcmp(datlocale, "C") == 0);
1358-
1359-
default_locale.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
1360-
datlocale);
1361-
}
1293+
result = create_pg_locale_builtin(DEFAULT_COLLATION_OID,
1294+
TopMemoryContext);
13621295
else if (dbform->datlocprovider == COLLPROVIDER_ICU)
1363-
{
1364-
#ifdef USE_ICU
1365-
char *datlocale;
1366-
char *icurules;
1367-
bool isnull;
1368-
1369-
datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
1370-
datlocale = TextDatumGetCString(datum);
1371-
1372-
default_locale.collate_is_c = false;
1373-
default_locale.ctype_is_c = false;
1374-
1375-
datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_daticurules, &isnull);
1376-
if (!isnull)
1377-
icurules = TextDatumGetCString(datum);
1378-
else
1379-
icurules = NULL;
1380-
1381-
default_locale.info.icu.locale = MemoryContextStrdup(TopMemoryContext, datlocale);
1382-
default_locale.info.icu.ucol = make_icu_collator(datlocale, icurules);
1383-
#else
1384-
/* could get here if a collation was created by a build with ICU */
1385-
ereport(ERROR,
1386-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1387-
errmsg("ICU is not supported in this build")));
1388-
#endif
1389-
}
1296+
result = create_pg_locale_icu(DEFAULT_COLLATION_OID,
1297+
TopMemoryContext);
13901298
else if (dbform->datlocprovider == COLLPROVIDER_LIBC)
1391-
{
1392-
const char *datcollate;
1393-
const char *datctype;
1394-
1395-
datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datcollate);
1396-
datcollate = TextDatumGetCString(datum);
1397-
datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datctype);
1398-
datctype = TextDatumGetCString(datum);
1399-
1400-
default_locale.collate_is_c = (strcmp(datcollate, "C") == 0) ||
1401-
(strcmp(datcollate, "POSIX") == 0);
1402-
default_locale.ctype_is_c = (strcmp(datctype, "C") == 0) ||
1403-
(strcmp(datctype, "POSIX") == 0);
1404-
1405-
default_locale.info.lt = make_libc_collator(datcollate, datctype);
1406-
}
1299+
result = create_pg_locale_libc(DEFAULT_COLLATION_OID,
1300+
TopMemoryContext);
14071301
else
14081302
/* shouldn't happen */
14091303
PGLOCALE_SUPPORT_ERROR(dbform->datlocprovider);
14101304

1411-
1412-
default_locale.provider = dbform->datlocprovider;
1413-
default_locale.is_default = true;
1414-
1415-
/*
1416-
* Default locale is currently always deterministic. Nondeterministic
1417-
* locales currently don't support pattern matching, which would break a
1418-
* lot of things if applied globally.
1419-
*/
1420-
default_locale.deterministic = true;
1421-
1305+
result->is_default = true;
14221306
ReleaseSysCache(tup);
1307+
1308+
default_locale = result;
14231309
}
14241310

14251311
/*
@@ -1437,7 +1323,7 @@ pg_newlocale_from_collation(Oid collid)
14371323
bool found;
14381324

14391325
if (collid == DEFAULT_COLLATION_OID)
1440-
return &default_locale;
1326+
return default_locale;
14411327

14421328
if (!OidIsValid(collid))
14431329
elog(ERROR, "cache lookup failed for collation %u", collid);
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*-----------------------------------------------------------------------
2+
*
3+
* PostgreSQL locale utilities for builtin provider
4+
*
5+
* Portions Copyright (c) 2002-2024, PostgreSQL Global Development Group
6+
*
7+
* src/backend/utils/adt/pg_locale_builtin.c
8+
*
9+
*-----------------------------------------------------------------------
10+
*/
11+
12+
#include "postgres.h"
13+
14+
#include "catalog/pg_database.h"
15+
#include "catalog/pg_collation.h"
16+
#include "mb/pg_wchar.h"
17+
#include "miscadmin.h"
18+
#include "utils/builtins.h"
19+
#include "utils/memutils.h"
20+
#include "utils/pg_locale.h"
21+
#include "utils/syscache.h"
22+
23+
extern pg_locale_t create_pg_locale_builtin(Oid collid,
24+
MemoryContext context);
25+
26+
pg_locale_t
27+
create_pg_locale_builtin(Oid collid, MemoryContext context)
28+
{
29+
const char *locstr;
30+
pg_locale_t result;
31+
32+
if (collid == DEFAULT_COLLATION_OID)
33+
{
34+
HeapTuple tp;
35+
Datum datum;
36+
37+
tp = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
38+
if (!HeapTupleIsValid(tp))
39+
elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
40+
datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
41+
Anum_pg_database_datlocale);
42+
locstr = TextDatumGetCString(datum);
43+
ReleaseSysCache(tp);
44+
}
45+
else
46+
{
47+
HeapTuple tp;
48+
Datum datum;
49+
50+
tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
51+
if (!HeapTupleIsValid(tp))
52+
elog(ERROR, "cache lookup failed for collation %u", collid);
53+
datum = SysCacheGetAttrNotNull(COLLOID, tp,
54+
Anum_pg_collation_colllocale);
55+
locstr = TextDatumGetCString(datum);
56+
ReleaseSysCache(tp);
57+
}
58+
59+
builtin_validate_locale(GetDatabaseEncoding(), locstr);
60+
61+
result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct));
62+
63+
result->info.builtin.locale = MemoryContextStrdup(context, locstr);
64+
result->provider = COLLPROVIDER_BUILTIN;
65+
result->deterministic = true;
66+
result->collate_is_c = true;
67+
result->ctype_is_c = (strcmp(locstr, "C") == 0);
68+
69+
return result;
70+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy