aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/pg_locale.c
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2021-05-07 20:17:42 +1200
committerThomas Munro <tmunro@postgresql.org>2021-05-07 21:10:11 +1200
commitec48314708262d8ea6cdcb83f803fc83dd89e721 (patch)
treef5b7c82ea571ce78aaa355095dd588dce07349ff /src/backend/utils/adt/pg_locale.c
parenta288d94c91e345ebeb10ac30f247270c8c8e380a (diff)
downloadpostgresql-ec48314708262d8ea6cdcb83f803fc83dd89e721.tar.gz
postgresql-ec48314708262d8ea6cdcb83f803fc83dd89e721.zip
Revert per-index collation version tracking feature.
Design problems were discovered in the handling of composite types and record types that would cause some relevant versions not to be recorded. Misgivings were also expressed about the use of the pg_depend catalog for this purpose. We're out of time for this release so we'll revert and try again. Commits reverted: 1bf946bd: Doc: Document known problem with Windows collation versions. cf002008: Remove no-longer-relevant test case. ef387bed: Fix bogus collation-version-recording logic. 0fb0a050: Hide internal error for pg_collation_actual_version(<bad OID>). ff942057: Suppress "warning: variable 'collcollate' set but not used". d50e3b1f: Fix assertion in collation version lookup. f24b1569: Rethink extraction of collation dependencies. 257836a7: Track collation versions for indexes. cd6f479e: Add pg_depend.refobjversion. 7d1297df: Remove pg_collation.collversion. Discussion: https://postgr.es/m/CA%2BhUKGLhj5t1fcjqAu8iD9B3ixJtsTNqyCCD4V0aTO9kAKAjjA%40mail.gmail.com
Diffstat (limited to 'src/backend/utils/adt/pg_locale.c')
-rw-r--r--src/backend/utils/adt/pg_locale.c89
1 files changed, 39 insertions, 50 deletions
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index aa4874163f8..eab089f252f 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -57,9 +57,7 @@
#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"
@@ -127,9 +125,6 @@ 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
*
@@ -1488,10 +1483,12 @@ pg_newlocale_from_collation(Oid collid)
/* We haven't computed this yet in this session, so do it */
HeapTuple tp;
Form_pg_collation collform;
- const char *collcollate pg_attribute_unused();
+ const char *collcollate;
const char *collctype pg_attribute_unused();
struct pg_locale_struct result;
pg_locale_t resultp;
+ Datum collversion;
+ bool isnull;
tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
if (!HeapTupleIsValid(tp))
@@ -1593,6 +1590,41 @@ pg_newlocale_from_collation(Oid collid)
#endif /* not USE_ICU */
}
+ collversion = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collversion,
+ &isnull);
+ if (!isnull)
+ {
+ char *actual_versionstr;
+ char *collversionstr;
+
+ actual_versionstr = get_collation_actual_version(collform->collprovider, collcollate);
+ if (!actual_versionstr)
+ {
+ /*
+ * This could happen when specifying a version in CREATE
+ * COLLATION for a libc locale, or manually creating a mess in
+ * the catalogs.
+ */
+ ereport(ERROR,
+ (errmsg("collation \"%s\" has no actual version, but a version was specified",
+ NameStr(collform->collname))));
+ }
+ collversionstr = TextDatumGetCString(collversion);
+
+ if (strcmp(actual_versionstr, collversionstr) != 0)
+ ereport(WARNING,
+ (errmsg("collation \"%s\" has version mismatch",
+ NameStr(collform->collname)),
+ errdetail("The collation in the database was created using version %s, "
+ "but the operating system provides version %s.",
+ collversionstr, actual_versionstr),
+ errhint("Rebuild all objects affected by this collation and run "
+ "ALTER COLLATION %s REFRESH VERSION, "
+ "or build PostgreSQL with the right library version.",
+ quote_qualified_identifier(get_namespace_name(collform->collnamespace),
+ NameStr(collform->collname)))));
+ }
+
ReleaseSysCache(tp);
/* We'll keep the pg_locale_t structures in TopMemoryContext */
@@ -1609,7 +1641,7 @@ pg_newlocale_from_collation(Oid collid)
* Get provider-specific collation version string for the given collation from
* the operating system/library.
*/
-static char *
+char *
get_collation_actual_version(char collprovider, const char *collcollate)
{
char *collversion = NULL;
@@ -1697,49 +1729,6 @@ 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, or the collation is
- * unversioned (for example "C"). Unknown OIDs result in NULL if missing_ok is
- * true.
- */
-char *
-get_collation_version_for_oid(Oid oid, bool missing_ok)
-{
- HeapTuple tp;
- char *version;
-
- 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))
- {
- if (missing_ok)
- return NULL;
- 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
/*