89
89
90
90
#define MAX_L10N_DATA 80
91
91
92
+ /* pg_locale_builtin.c */
93
+ extern pg_locale_t create_pg_locale_builtin (Oid collid , MemoryContext context );
94
+
92
95
/* pg_locale_icu.c */
93
96
#ifdef USE_ICU
94
97
extern UCollator * pg_ucol_open (const char * loc_str );
95
- extern UCollator * make_icu_collator (const char * iculocstr ,
96
- const char * icurules );
97
98
extern int strncoll_icu (const char * arg1 , ssize_t len1 ,
98
99
const char * arg2 , ssize_t len2 ,
99
100
pg_locale_t locale );
@@ -104,10 +105,10 @@ extern size_t strnxfrm_prefix_icu(char *dest, size_t destsize,
104
105
const char * src , ssize_t srclen ,
105
106
pg_locale_t locale );
106
107
#endif
108
+ extern pg_locale_t create_pg_locale_icu (Oid collid , MemoryContext context );
107
109
108
110
/* 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 );
111
112
extern int strncoll_libc (const char * arg1 , ssize_t len1 ,
112
113
const char * arg2 , ssize_t len2 ,
113
114
pg_locale_t locale );
@@ -138,7 +139,7 @@ char *localized_full_months[12 + 1];
138
139
/* is the databases's LC_CTYPE the C locale? */
139
140
bool database_ctype_is_c = false;
140
141
141
- static struct pg_locale_struct default_locale ;
142
+ static pg_locale_t default_locale = NULL ;
142
143
143
144
/* indicates whether locale information cache is valid */
144
145
static bool CurrentLocaleConvValid = false;
@@ -1194,7 +1195,6 @@ IsoLocaleName(const char *winlocname)
1194
1195
1195
1196
#endif /* WIN32 && LC_MESSAGES */
1196
1197
1197
-
1198
1198
/*
1199
1199
* Create a new pg_locale_t struct for the given collation oid.
1200
1200
*/
@@ -1207,80 +1207,23 @@ create_pg_locale(Oid collid, MemoryContext context)
1207
1207
Datum datum ;
1208
1208
bool isnull ;
1209
1209
1210
- result = MemoryContextAllocZero (context , sizeof (struct pg_locale_struct ));
1211
-
1212
1210
tp = SearchSysCache1 (COLLOID , ObjectIdGetDatum (collid ));
1213
1211
if (!HeapTupleIsValid (tp ))
1214
1212
elog (ERROR , "cache lookup failed for collation %u" , collid );
1215
1213
collform = (Form_pg_collation ) GETSTRUCT (tp );
1216
1214
1217
- result -> provider = collform -> collprovider ;
1218
- result -> deterministic = collform -> collisdeterministic ;
1219
- result -> is_default = false;
1220
-
1221
1215
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 );
1236
1217
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 );
1263
1219
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 );
1280
1221
else
1281
1222
/* shouldn't happen */
1282
1223
PGLOCALE_SUPPORT_ERROR (collform -> collprovider );
1283
1224
1225
+ result -> is_default = false;
1226
+
1284
1227
datum = SysCacheGetAttr (COLLOID , tp , Anum_pg_collation_collversion ,
1285
1228
& isnull );
1286
1229
if (!isnull )
@@ -1336,7 +1279,9 @@ init_database_collation(void)
1336
1279
{
1337
1280
HeapTuple tup ;
1338
1281
Form_pg_database dbform ;
1339
- Datum datum ;
1282
+ pg_locale_t result ;
1283
+
1284
+ Assert (default_locale == NULL );
1340
1285
1341
1286
/* Fetch our pg_database row normally, via syscache */
1342
1287
tup = SearchSysCache1 (DATABASEOID , ObjectIdGetDatum (MyDatabaseId ));
@@ -1345,81 +1290,22 @@ init_database_collation(void)
1345
1290
dbform = (Form_pg_database ) GETSTRUCT (tup );
1346
1291
1347
1292
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 );
1362
1295
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 );
1390
1298
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 );
1407
1301
else
1408
1302
/* shouldn't happen */
1409
1303
PGLOCALE_SUPPORT_ERROR (dbform -> datlocprovider );
1410
1304
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;
1422
1306
ReleaseSysCache (tup );
1307
+
1308
+ default_locale = result ;
1423
1309
}
1424
1310
1425
1311
/*
@@ -1437,7 +1323,7 @@ pg_newlocale_from_collation(Oid collid)
1437
1323
bool found ;
1438
1324
1439
1325
if (collid == DEFAULT_COLLATION_OID )
1440
- return & default_locale ;
1326
+ return default_locale ;
1441
1327
1442
1328
if (!OidIsValid (collid ))
1443
1329
elog (ERROR , "cache lookup failed for collation %u" , collid );
0 commit comments