mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
Track collation versions for indexes.
Record the current version of dependent collations in pg_depend when creating or rebuilding an index. When accessing the index later, warn that the index may be corrupted if the current version doesn't match. Thanks to Douglas Doole, Peter Eisentraut, Christoph Berg, Laurenz Albe, Michael Paquier, Robert Haas, Tom Lane and others for very helpful discussion. Author: Thomas Munro <thomas.munro@gmail.com> Author: Julien Rouhaud <rjuju123@gmail.com> Reviewed-by: Peter Eisentraut <peter.eisentraut@2ndquadrant.com> (earlier versions) Discussion: https://postgr.es/m/CAEepm%3D0uEQCpfq_%2BLYFBdArCe4Ot98t1aR4eYiYTe%3DyavQygiQ%40mail.gmail.com
This commit is contained in:
@ -57,7 +57,9 @@
|
||||
#include "access/htup_details.h"
|
||||
#include "catalog/pg_collation.h"
|
||||
#include "catalog/pg_control.h"
|
||||
#include "catalog/pg_database.h"
|
||||
#include "mb/pg_wchar.h"
|
||||
#include "miscadmin.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/formatting.h"
|
||||
#include "utils/hsearch.h"
|
||||
@ -139,6 +141,9 @@ static char *IsoLocaleName(const char *); /* MSVC specific */
|
||||
static void icu_set_collation_attributes(UCollator *collator, const char *loc);
|
||||
#endif
|
||||
|
||||
static char *get_collation_actual_version(char collprovider,
|
||||
const char *collcollate);
|
||||
|
||||
/*
|
||||
* pg_perm_setlocale
|
||||
*
|
||||
@ -1630,7 +1635,7 @@ pg_newlocale_from_collation(Oid collid)
|
||||
* Get provider-specific collation version string for the given collation from
|
||||
* the operating system/library.
|
||||
*/
|
||||
char *
|
||||
static char *
|
||||
get_collation_actual_version(char collprovider, const char *collcollate)
|
||||
{
|
||||
char *collversion = NULL;
|
||||
@ -1712,6 +1717,45 @@ get_collation_actual_version(char collprovider, const char *collcollate)
|
||||
return collversion;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get provider-specific collation version string for a given collation OID.
|
||||
* Return NULL if the provider doesn't support versions.
|
||||
*/
|
||||
char *
|
||||
get_collation_version_for_oid(Oid oid)
|
||||
{
|
||||
HeapTuple tp;
|
||||
char *version = NULL;
|
||||
|
||||
Assert(oid != C_COLLATION_OID && oid != POSIX_COLLATION_OID);
|
||||
|
||||
if (oid == DEFAULT_COLLATION_OID)
|
||||
{
|
||||
Form_pg_database dbform;
|
||||
|
||||
tp = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
|
||||
if (!HeapTupleIsValid(tp))
|
||||
elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
|
||||
dbform = (Form_pg_database) GETSTRUCT(tp);
|
||||
version = get_collation_actual_version(COLLPROVIDER_LIBC,
|
||||
NameStr(dbform->datcollate));
|
||||
}
|
||||
else
|
||||
{
|
||||
Form_pg_collation collform;
|
||||
|
||||
tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(oid));
|
||||
if (!HeapTupleIsValid(tp))
|
||||
elog(ERROR, "cache lookup failed for collation %u", oid);
|
||||
collform = (Form_pg_collation) GETSTRUCT(tp);
|
||||
version = get_collation_actual_version(collform->collprovider,
|
||||
NameStr(collform->collcollate));
|
||||
}
|
||||
|
||||
ReleaseSysCache(tp);
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
#ifdef USE_ICU
|
||||
/*
|
||||
|
Reference in New Issue
Block a user