Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)