@@ -128,9 +128,6 @@ static bool CurrentLCTimeValid = false;
128
128
typedef struct
129
129
{
130
130
Oid collid ; /* hash key: pg_collation OID */
131
- bool collate_is_c ; /* is collation's LC_COLLATE C? */
132
- bool ctype_is_c ; /* is collation's LC_CTYPE C? */
133
- bool flags_valid ; /* true if above flags are valid */
134
131
pg_locale_t locale ; /* locale_t struct, or 0 if not valid */
135
132
136
133
/* needed for simplehash */
@@ -1225,29 +1222,13 @@ IsoLocaleName(const char *winlocname)
1225
1222
/*
1226
1223
* Cache mechanism for collation information.
1227
1224
*
1228
- * We cache two flags: whether the collation's LC_COLLATE or LC_CTYPE is C
1229
- * (or POSIX), so we can optimize a few code paths in various places.
1230
- * For the built-in C and POSIX collations, we can know that without even
1231
- * doing a cache lookup, but we want to support aliases for C/POSIX too.
1232
- * For the "default" collation, there are separate static cache variables,
1233
- * since consulting the pg_collation catalog doesn't tell us what we need.
1234
- *
1235
- * Also, if a pg_locale_t has been requested for a collation, we cache that
1236
- * for the life of a backend.
1237
- *
1238
- * Note that some code relies on the flags not reporting false negatives
1239
- * (that is, saying it's not C when it is). For example, char2wchar()
1240
- * could fail if the locale is C, so str_tolower() shouldn't call it
1241
- * in that case.
1242
- *
1243
1225
* Note that we currently lack any way to flush the cache. Since we don't
1244
1226
* support ALTER COLLATION, this is OK. The worst case is that someone
1245
1227
* drops a collation, and a useless cache entry hangs around in existing
1246
1228
* backends.
1247
1229
*/
1248
-
1249
1230
static collation_cache_entry *
1250
- lookup_collation_cache (Oid collation , bool set_flags )
1231
+ lookup_collation_cache (Oid collation )
1251
1232
{
1252
1233
collation_cache_entry * cache_entry ;
1253
1234
bool found ;
@@ -1271,59 +1252,9 @@ lookup_collation_cache(Oid collation, bool set_flags)
1271
1252
* Make sure cache entry is marked invalid, in case we fail before
1272
1253
* setting things.
1273
1254
*/
1274
- cache_entry -> flags_valid = false;
1275
1255
cache_entry -> locale = 0 ;
1276
1256
}
1277
1257
1278
- if (set_flags && !cache_entry -> flags_valid )
1279
- {
1280
- /* Attempt to set the flags */
1281
- HeapTuple tp ;
1282
- Form_pg_collation collform ;
1283
-
1284
- tp = SearchSysCache1 (COLLOID , ObjectIdGetDatum (collation ));
1285
- if (!HeapTupleIsValid (tp ))
1286
- elog (ERROR , "cache lookup failed for collation %u" , collation );
1287
- collform = (Form_pg_collation ) GETSTRUCT (tp );
1288
-
1289
- if (collform -> collprovider == COLLPROVIDER_BUILTIN )
1290
- {
1291
- Datum datum ;
1292
- const char * colllocale ;
1293
-
1294
- datum = SysCacheGetAttrNotNull (COLLOID , tp , Anum_pg_collation_colllocale );
1295
- colllocale = TextDatumGetCString (datum );
1296
-
1297
- cache_entry -> collate_is_c = true;
1298
- cache_entry -> ctype_is_c = (strcmp (colllocale , "C" ) == 0 );
1299
- }
1300
- else if (collform -> collprovider == COLLPROVIDER_LIBC )
1301
- {
1302
- Datum datum ;
1303
- const char * collcollate ;
1304
- const char * collctype ;
1305
-
1306
- datum = SysCacheGetAttrNotNull (COLLOID , tp , Anum_pg_collation_collcollate );
1307
- collcollate = TextDatumGetCString (datum );
1308
- datum = SysCacheGetAttrNotNull (COLLOID , tp , Anum_pg_collation_collctype );
1309
- collctype = TextDatumGetCString (datum );
1310
-
1311
- cache_entry -> collate_is_c = ((strcmp (collcollate , "C" ) == 0 ) ||
1312
- (strcmp (collcollate , "POSIX" ) == 0 ));
1313
- cache_entry -> ctype_is_c = ((strcmp (collctype , "C" ) == 0 ) ||
1314
- (strcmp (collctype , "POSIX" ) == 0 ));
1315
- }
1316
- else
1317
- {
1318
- cache_entry -> collate_is_c = false;
1319
- cache_entry -> ctype_is_c = false;
1320
- }
1321
-
1322
- cache_entry -> flags_valid = true;
1323
-
1324
- ReleaseSysCache (tp );
1325
- }
1326
-
1327
1258
return cache_entry ;
1328
1259
}
1329
1260
@@ -1341,47 +1272,6 @@ lc_collate_is_c(Oid collation)
1341
1272
if (!OidIsValid (collation ))
1342
1273
return false;
1343
1274
1344
- /*
1345
- * If we're asked about the default collation, we have to inquire of the C
1346
- * library. Cache the result so we only have to compute it once.
1347
- */
1348
- if (collation == DEFAULT_COLLATION_OID )
1349
- {
1350
- static int result = -1 ;
1351
- const char * localeptr ;
1352
-
1353
- if (result >= 0 )
1354
- return (bool ) result ;
1355
-
1356
- if (default_locale .provider == COLLPROVIDER_BUILTIN )
1357
- {
1358
- result = true;
1359
- return (bool ) result ;
1360
- }
1361
- else if (default_locale .provider == COLLPROVIDER_ICU )
1362
- {
1363
- result = false;
1364
- return (bool ) result ;
1365
- }
1366
- else if (default_locale .provider == COLLPROVIDER_LIBC )
1367
- {
1368
- localeptr = setlocale (LC_CTYPE , NULL );
1369
- if (!localeptr )
1370
- elog (ERROR , "invalid LC_CTYPE setting" );
1371
- }
1372
- else
1373
- elog (ERROR , "unexpected collation provider '%c'" ,
1374
- default_locale .provider );
1375
-
1376
- if (strcmp (localeptr , "C" ) == 0 )
1377
- result = true;
1378
- else if (strcmp (localeptr , "POSIX" ) == 0 )
1379
- result = true;
1380
- else
1381
- result = false;
1382
- return (bool ) result ;
1383
- }
1384
-
1385
1275
/*
1386
1276
* If we're asked about the built-in C/POSIX collations, we know that.
1387
1277
*/
@@ -1392,7 +1282,7 @@ lc_collate_is_c(Oid collation)
1392
1282
/*
1393
1283
* Otherwise, we have to consult pg_collation, but we cache that.
1394
1284
*/
1395
- return ( lookup_collation_cache ( collation , true) )-> collate_is_c ;
1285
+ return pg_newlocale_from_collation ( collation )-> collate_is_c ;
1396
1286
}
1397
1287
1398
1288
/*
@@ -1408,46 +1298,6 @@ lc_ctype_is_c(Oid collation)
1408
1298
if (!OidIsValid (collation ))
1409
1299
return false;
1410
1300
1411
- /*
1412
- * If we're asked about the default collation, we have to inquire of the C
1413
- * library. Cache the result so we only have to compute it once.
1414
- */
1415
- if (collation == DEFAULT_COLLATION_OID )
1416
- {
1417
- static int result = -1 ;
1418
- const char * localeptr ;
1419
-
1420
- if (result >= 0 )
1421
- return (bool ) result ;
1422
-
1423
- if (default_locale .provider == COLLPROVIDER_BUILTIN )
1424
- {
1425
- localeptr = default_locale .info .builtin .locale ;
1426
- }
1427
- else if (default_locale .provider == COLLPROVIDER_ICU )
1428
- {
1429
- result = false;
1430
- return (bool ) result ;
1431
- }
1432
- else if (default_locale .provider == COLLPROVIDER_LIBC )
1433
- {
1434
- localeptr = setlocale (LC_CTYPE , NULL );
1435
- if (!localeptr )
1436
- elog (ERROR , "invalid LC_CTYPE setting" );
1437
- }
1438
- else
1439
- elog (ERROR , "unexpected collation provider '%c'" ,
1440
- default_locale .provider );
1441
-
1442
- if (strcmp (localeptr , "C" ) == 0 )
1443
- result = true;
1444
- else if (strcmp (localeptr , "POSIX" ) == 0 )
1445
- result = true;
1446
- else
1447
- result = false;
1448
- return (bool ) result ;
1449
- }
1450
-
1451
1301
/*
1452
1302
* If we're asked about the built-in C/POSIX collations, we know that.
1453
1303
*/
@@ -1458,7 +1308,7 @@ lc_ctype_is_c(Oid collation)
1458
1308
/*
1459
1309
* Otherwise, we have to consult pg_collation, but we cache that.
1460
1310
*/
1461
- return ( lookup_collation_cache ( collation , true) )-> ctype_is_c ;
1311
+ return pg_newlocale_from_collation ( collation )-> ctype_is_c ;
1462
1312
}
1463
1313
1464
1314
/* simple subroutine for reporting errors from newlocale() */
@@ -1647,6 +1497,9 @@ init_database_collation(void)
1647
1497
1648
1498
builtin_validate_locale (dbform -> encoding , datlocale );
1649
1499
1500
+ default_locale .collate_is_c = true;
1501
+ default_locale .ctype_is_c = (strcmp (datlocale , "C" ) == 0 );
1502
+
1650
1503
default_locale .info .builtin .locale = MemoryContextStrdup (
1651
1504
TopMemoryContext , datlocale );
1652
1505
}
@@ -1658,6 +1511,9 @@ init_database_collation(void)
1658
1511
datum = SysCacheGetAttrNotNull (DATABASEOID , tup , Anum_pg_database_datlocale );
1659
1512
datlocale = TextDatumGetCString (datum );
1660
1513
1514
+ default_locale .collate_is_c = false;
1515
+ default_locale .ctype_is_c = false;
1516
+
1661
1517
datum = SysCacheGetAttr (DATABASEOID , tup , Anum_pg_database_daticurules , & isnull );
1662
1518
if (!isnull )
1663
1519
icurules = TextDatumGetCString (datum );
@@ -1678,6 +1534,11 @@ init_database_collation(void)
1678
1534
datum = SysCacheGetAttrNotNull (DATABASEOID , tup , Anum_pg_database_datctype );
1679
1535
datctype = TextDatumGetCString (datum );
1680
1536
1537
+ default_locale .collate_is_c = (strcmp (datcollate , "C" ) == 0 ) ||
1538
+ (strcmp (datcollate , "POSIX" ) == 0 );
1539
+ default_locale .ctype_is_c = (strcmp (datctype , "C" ) == 0 ) ||
1540
+ (strcmp (datctype , "POSIX" ) == 0 );
1541
+
1681
1542
make_libc_collator (datcollate , datctype , & default_locale );
1682
1543
}
1683
1544
@@ -1712,7 +1573,7 @@ pg_newlocale_from_collation(Oid collid)
1712
1573
if (collid == DEFAULT_COLLATION_OID )
1713
1574
return & default_locale ;
1714
1575
1715
- cache_entry = lookup_collation_cache (collid , false );
1576
+ cache_entry = lookup_collation_cache (collid );
1716
1577
1717
1578
if (cache_entry -> locale == 0 )
1718
1579
{
@@ -1741,6 +1602,9 @@ pg_newlocale_from_collation(Oid collid)
1741
1602
datum = SysCacheGetAttrNotNull (COLLOID , tp , Anum_pg_collation_colllocale );
1742
1603
locstr = TextDatumGetCString (datum );
1743
1604
1605
+ result .collate_is_c = true;
1606
+ result .ctype_is_c = (strcmp (locstr , "C" ) == 0 );
1607
+
1744
1608
builtin_validate_locale (GetDatabaseEncoding (), locstr );
1745
1609
1746
1610
result .info .builtin .locale = MemoryContextStrdup (TopMemoryContext ,
@@ -1756,6 +1620,11 @@ pg_newlocale_from_collation(Oid collid)
1756
1620
datum = SysCacheGetAttrNotNull (COLLOID , tp , Anum_pg_collation_collctype );
1757
1621
collctype = TextDatumGetCString (datum );
1758
1622
1623
+ result .collate_is_c = (strcmp (collcollate , "C" ) == 0 ) ||
1624
+ (strcmp (collcollate , "POSIX" ) == 0 );
1625
+ result .ctype_is_c = (strcmp (collctype , "C" ) == 0 ) ||
1626
+ (strcmp (collctype , "POSIX" ) == 0 );
1627
+
1759
1628
make_libc_collator (collcollate , collctype , & result );
1760
1629
}
1761
1630
else if (collform -> collprovider == COLLPROVIDER_ICU )
@@ -1766,6 +1635,9 @@ pg_newlocale_from_collation(Oid collid)
1766
1635
datum = SysCacheGetAttrNotNull (COLLOID , tp , Anum_pg_collation_colllocale );
1767
1636
iculocstr = TextDatumGetCString (datum );
1768
1637
1638
+ result .collate_is_c = false;
1639
+ result .ctype_is_c = false;
1640
+
1769
1641
datum = SysCacheGetAttr (COLLOID , tp , Anum_pg_collation_collicurules , & isnull );
1770
1642
if (!isnull )
1771
1643
icurules = TextDatumGetCString (datum );
0 commit comments