Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3aa2373

Browse files
committed
Refactor the code to create a pg_locale_t into new function.
Reviewed-by: Andreas KarlssonDiscussion:https://postgr.es/m/59da7ee4-5e1a-4727-b464-a603c6ed84cd@proxel.se
1 parent924e039 commit3aa2373

File tree

1 file changed

+139
-157
lines changed

1 file changed

+139
-157
lines changed

‎src/backend/utils/adt/pg_locale.c

Lines changed: 139 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,42 +1215,135 @@ IsoLocaleName(const char *winlocname)
12151215

12161216

12171217
/*
1218-
* Cache mechanism for collation information.
1219-
*
1220-
* Note that we currently lack any way to flush the cache. Since we don't
1221-
* support ALTER COLLATION, this is OK. The worst case is that someone
1222-
* drops a collation, and a useless cache entry hangs around in existing
1223-
* backends.
1218+
* Create a new pg_locale_t struct for the given collation oid.
12241219
*/
1225-
staticcollation_cache_entry*
1226-
lookup_collation_cache(Oidcollation)
1220+
staticpg_locale_t
1221+
create_pg_locale(Oidcollid,MemoryContextcontext)
12271222
{
1228-
collation_cache_entry*cache_entry;
1229-
boolfound;
1223+
HeapTupletp;
1224+
Form_pg_collationcollform;
1225+
pg_locale_tresult;
1226+
Datumdatum;
1227+
boolisnull;
12301228

1231-
Assert(OidIsValid(collation));
1232-
Assert(collation!=DEFAULT_COLLATION_OID);
1229+
result=MemoryContextAllocZero(context,sizeof(structpg_locale_struct));
12331230

1234-
if (CollationCache==NULL)
1231+
tp=SearchSysCache1(COLLOID,ObjectIdGetDatum(collid));
1232+
if (!HeapTupleIsValid(tp))
1233+
elog(ERROR,"cache lookup failed for collation %u",collid);
1234+
collform= (Form_pg_collation)GETSTRUCT(tp);
1235+
1236+
result->provider=collform->collprovider;
1237+
result->deterministic=collform->collisdeterministic;
1238+
1239+
if (collform->collprovider==COLLPROVIDER_BUILTIN)
12351240
{
1236-
CollationCacheContext=AllocSetContextCreate(TopMemoryContext,
1237-
"collation cache",
1238-
ALLOCSET_DEFAULT_SIZES);
1239-
CollationCache=collation_cache_create(CollationCacheContext,
1240-
16,NULL);
1241+
constchar*locstr;
1242+
1243+
datum=SysCacheGetAttrNotNull(COLLOID,tp,Anum_pg_collation_colllocale);
1244+
locstr=TextDatumGetCString(datum);
1245+
1246+
result->collate_is_c= true;
1247+
result->ctype_is_c= (strcmp(locstr,"C")==0);
1248+
1249+
builtin_validate_locale(GetDatabaseEncoding(),locstr);
1250+
1251+
result->info.builtin.locale=MemoryContextStrdup(context,
1252+
locstr);
12411253
}
1254+
elseif (collform->collprovider==COLLPROVIDER_ICU)
1255+
{
1256+
#ifdefUSE_ICU
1257+
constchar*iculocstr;
1258+
constchar*icurules;
12421259

1243-
cache_entry=collation_cache_insert(CollationCache,collation,&found);
1244-
if (!found)
1260+
datum=SysCacheGetAttrNotNull(COLLOID,tp,Anum_pg_collation_colllocale);
1261+
iculocstr=TextDatumGetCString(datum);
1262+
1263+
result->collate_is_c= false;
1264+
result->ctype_is_c= false;
1265+
1266+
datum=SysCacheGetAttr(COLLOID,tp,Anum_pg_collation_collicurules,&isnull);
1267+
if (!isnull)
1268+
icurules=TextDatumGetCString(datum);
1269+
else
1270+
icurules=NULL;
1271+
1272+
result->info.icu.locale=MemoryContextStrdup(context,iculocstr);
1273+
result->info.icu.ucol=make_icu_collator(iculocstr,icurules);
1274+
#else
1275+
/* could get here if a collation was created by a build with ICU */
1276+
ereport(ERROR,
1277+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1278+
errmsg("ICU is not supported in this build")));
1279+
#endif
1280+
}
1281+
elseif (collform->collprovider==COLLPROVIDER_LIBC)
12451282
{
1246-
/*
1247-
* Make sure cache entry is marked invalid, in case we fail before
1248-
* setting things.
1249-
*/
1250-
cache_entry->locale=0;
1283+
constchar*collcollate;
1284+
constchar*collctype;
1285+
1286+
datum=SysCacheGetAttrNotNull(COLLOID,tp,Anum_pg_collation_collcollate);
1287+
collcollate=TextDatumGetCString(datum);
1288+
datum=SysCacheGetAttrNotNull(COLLOID,tp,Anum_pg_collation_collctype);
1289+
collctype=TextDatumGetCString(datum);
1290+
1291+
result->collate_is_c= (strcmp(collcollate,"C")==0)||
1292+
(strcmp(collcollate,"POSIX")==0);
1293+
result->ctype_is_c= (strcmp(collctype,"C")==0)||
1294+
(strcmp(collctype,"POSIX")==0);
1295+
1296+
result->info.lt=make_libc_collator(collcollate,collctype);
1297+
}
1298+
else
1299+
/* shouldn't happen */
1300+
PGLOCALE_SUPPORT_ERROR(collform->collprovider);
1301+
1302+
datum=SysCacheGetAttr(COLLOID,tp,Anum_pg_collation_collversion,
1303+
&isnull);
1304+
if (!isnull)
1305+
{
1306+
char*actual_versionstr;
1307+
char*collversionstr;
1308+
1309+
collversionstr=TextDatumGetCString(datum);
1310+
1311+
if (collform->collprovider==COLLPROVIDER_LIBC)
1312+
datum=SysCacheGetAttrNotNull(COLLOID,tp,Anum_pg_collation_collcollate);
1313+
else
1314+
datum=SysCacheGetAttrNotNull(COLLOID,tp,Anum_pg_collation_colllocale);
1315+
1316+
actual_versionstr=get_collation_actual_version(collform->collprovider,
1317+
TextDatumGetCString(datum));
1318+
if (!actual_versionstr)
1319+
{
1320+
/*
1321+
* This could happen when specifying a version in CREATE COLLATION
1322+
* but the provider does not support versioning, or manually
1323+
* creating a mess in the catalogs.
1324+
*/
1325+
ereport(ERROR,
1326+
(errmsg("collation \"%s\" has no actual version, but a version was recorded",
1327+
NameStr(collform->collname))));
1328+
}
1329+
1330+
if (strcmp(actual_versionstr,collversionstr)!=0)
1331+
ereport(WARNING,
1332+
(errmsg("collation \"%s\" has version mismatch",
1333+
NameStr(collform->collname)),
1334+
errdetail("The collation in the database was created using version %s, "
1335+
"but the operating system provides version %s.",
1336+
collversionstr,actual_versionstr),
1337+
errhint("Rebuild all objects affected by this collation and run "
1338+
"ALTER COLLATION %s REFRESH VERSION, "
1339+
"or build PostgreSQL with the right library version.",
1340+
quote_qualified_identifier(get_namespace_name(collform->collnamespace),
1341+
NameStr(collform->collname)))));
12511342
}
12521343

1253-
returncache_entry;
1344+
ReleaseSysCache(tp);
1345+
1346+
returnresult;
12541347
}
12551348

12561349
/*
@@ -1358,6 +1451,7 @@ pg_locale_t
13581451
pg_newlocale_from_collation(Oidcollid)
13591452
{
13601453
collation_cache_entry*cache_entry;
1454+
boolfound;
13611455

13621456
if (collid==DEFAULT_COLLATION_OID)
13631457
return&default_locale;
@@ -1368,140 +1462,28 @@ pg_newlocale_from_collation(Oid collid)
13681462
if (last_collation_cache_oid==collid)
13691463
returnlast_collation_cache_locale;
13701464

1371-
cache_entry=lookup_collation_cache(collid);
1372-
1373-
if (cache_entry->locale==0)
1465+
if (CollationCache==NULL)
13741466
{
1375-
/* We haven't computed this yet in this session, so do it */
1376-
HeapTupletp;
1377-
Form_pg_collationcollform;
1378-
structpg_locale_structresult;
1379-
pg_locale_tresultp;
1380-
Datumdatum;
1381-
boolisnull;
1382-
1383-
tp=SearchSysCache1(COLLOID,ObjectIdGetDatum(collid));
1384-
if (!HeapTupleIsValid(tp))
1385-
elog(ERROR,"cache lookup failed for collation %u",collid);
1386-
collform= (Form_pg_collation)GETSTRUCT(tp);
1387-
1388-
/* We'll fill in the result struct locally before allocating memory */
1389-
memset(&result,0,sizeof(result));
1390-
result.provider=collform->collprovider;
1391-
result.deterministic=collform->collisdeterministic;
1392-
1393-
if (collform->collprovider==COLLPROVIDER_BUILTIN)
1394-
{
1395-
constchar*locstr;
1396-
1397-
datum=SysCacheGetAttrNotNull(COLLOID,tp,Anum_pg_collation_colllocale);
1398-
locstr=TextDatumGetCString(datum);
1399-
1400-
result.collate_is_c= true;
1401-
result.ctype_is_c= (strcmp(locstr,"C")==0);
1402-
1403-
builtin_validate_locale(GetDatabaseEncoding(),locstr);
1404-
1405-
result.info.builtin.locale=MemoryContextStrdup(TopMemoryContext,
1406-
locstr);
1407-
}
1408-
elseif (collform->collprovider==COLLPROVIDER_ICU)
1409-
{
1410-
#ifdefUSE_ICU
1411-
constchar*iculocstr;
1412-
constchar*icurules;
1413-
1414-
datum=SysCacheGetAttrNotNull(COLLOID,tp,Anum_pg_collation_colllocale);
1415-
iculocstr=TextDatumGetCString(datum);
1416-
1417-
result.collate_is_c= false;
1418-
result.ctype_is_c= false;
1419-
1420-
datum=SysCacheGetAttr(COLLOID,tp,Anum_pg_collation_collicurules,&isnull);
1421-
if (!isnull)
1422-
icurules=TextDatumGetCString(datum);
1423-
else
1424-
icurules=NULL;
1425-
1426-
result.info.icu.locale=MemoryContextStrdup(TopMemoryContext,iculocstr);
1427-
result.info.icu.ucol=make_icu_collator(iculocstr,icurules);
1428-
#else
1429-
/* could get here if a collation was created by a build with ICU */
1430-
ereport(ERROR,
1431-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1432-
errmsg("ICU is not supported in this build")));
1433-
#endif
1434-
}
1435-
elseif (collform->collprovider==COLLPROVIDER_LIBC)
1436-
{
1437-
constchar*collcollate;
1438-
constchar*collctype;
1439-
1440-
datum=SysCacheGetAttrNotNull(COLLOID,tp,Anum_pg_collation_collcollate);
1441-
collcollate=TextDatumGetCString(datum);
1442-
datum=SysCacheGetAttrNotNull(COLLOID,tp,Anum_pg_collation_collctype);
1443-
collctype=TextDatumGetCString(datum);
1444-
1445-
result.collate_is_c= (strcmp(collcollate,"C")==0)||
1446-
(strcmp(collcollate,"POSIX")==0);
1447-
result.ctype_is_c= (strcmp(collctype,"C")==0)||
1448-
(strcmp(collctype,"POSIX")==0);
1449-
1450-
result.info.lt=make_libc_collator(collcollate,collctype);
1451-
}
1452-
else
1453-
/* shouldn't happen */
1454-
PGLOCALE_SUPPORT_ERROR(collform->collprovider);
1455-
1456-
datum=SysCacheGetAttr(COLLOID,tp,Anum_pg_collation_collversion,
1457-
&isnull);
1458-
if (!isnull)
1459-
{
1460-
char*actual_versionstr;
1461-
char*collversionstr;
1462-
1463-
collversionstr=TextDatumGetCString(datum);
1464-
1465-
if (collform->collprovider==COLLPROVIDER_LIBC)
1466-
datum=SysCacheGetAttrNotNull(COLLOID,tp,Anum_pg_collation_collcollate);
1467-
else
1468-
datum=SysCacheGetAttrNotNull(COLLOID,tp,Anum_pg_collation_colllocale);
1469-
1470-
actual_versionstr=get_collation_actual_version(collform->collprovider,
1471-
TextDatumGetCString(datum));
1472-
if (!actual_versionstr)
1473-
{
1474-
/*
1475-
* This could happen when specifying a version in CREATE
1476-
* COLLATION but the provider does not support versioning, or
1477-
* manually creating a mess in the catalogs.
1478-
*/
1479-
ereport(ERROR,
1480-
(errmsg("collation \"%s\" has no actual version, but a version was recorded",
1481-
NameStr(collform->collname))));
1482-
}
1483-
1484-
if (strcmp(actual_versionstr,collversionstr)!=0)
1485-
ereport(WARNING,
1486-
(errmsg("collation \"%s\" has version mismatch",
1487-
NameStr(collform->collname)),
1488-
errdetail("The collation in the database was created using version %s, "
1489-
"but the operating system provides version %s.",
1490-
collversionstr,actual_versionstr),
1491-
errhint("Rebuild all objects affected by this collation and run "
1492-
"ALTER COLLATION %s REFRESH VERSION, "
1493-
"or build PostgreSQL with the right library version.",
1494-
quote_qualified_identifier(get_namespace_name(collform->collnamespace),
1495-
NameStr(collform->collname)))));
1496-
}
1497-
1498-
ReleaseSysCache(tp);
1467+
CollationCacheContext=AllocSetContextCreate(TopMemoryContext,
1468+
"collation cache",
1469+
ALLOCSET_DEFAULT_SIZES);
1470+
CollationCache=collation_cache_create(CollationCacheContext,
1471+
16,NULL);
1472+
}
14991473

1500-
/* We'll keep the pg_locale_t structures in TopMemoryContext */
1501-
resultp=MemoryContextAlloc(TopMemoryContext,sizeof(*resultp));
1502-
*resultp=result;
1474+
cache_entry=collation_cache_insert(CollationCache,collid,&found);
1475+
if (!found)
1476+
{
1477+
/*
1478+
* Make sure cache entry is marked invalid, in case we fail before
1479+
* setting things.
1480+
*/
1481+
cache_entry->locale=0;
1482+
}
15031483

1504-
cache_entry->locale=resultp;
1484+
if (cache_entry->locale==0)
1485+
{
1486+
cache_entry->locale=create_pg_locale(collid,CollationCacheContext);
15051487
}
15061488

15071489
last_collation_cache_oid=collid;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp