aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/collationcmds.c16
-rw-r--r--src/backend/commands/tablecmds.c31
2 files changed, 32 insertions, 15 deletions
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 5ad8886e60a..7b31272734d 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -270,23 +270,9 @@ Datum
pg_collation_actual_version(PG_FUNCTION_ARGS)
{
Oid collid = PG_GETARG_OID(0);
- HeapTuple tp;
- char *collcollate;
- char collprovider;
char *version;
- tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
- if (!HeapTupleIsValid(tp))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("collation with OID %u does not exist", collid)));
-
- collcollate = pstrdup(NameStr(((Form_pg_collation) GETSTRUCT(tp))->collcollate));
- collprovider = ((Form_pg_collation) GETSTRUCT(tp))->collprovider;
-
- ReleaseSysCache(tp);
-
- version = get_collation_actual_version(collprovider, collcollate);
+ version = get_collation_version_for_oid(collid);
if (version)
PG_RETURN_TEXT_P(cstring_to_text(version));
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index df13b72974f..1b105ba1c42 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -93,6 +93,7 @@
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/partcache.h"
+#include "utils/pg_locale.h"
#include "utils/relcache.h"
#include "utils/ruleutils.h"
#include "utils/snapmgr.h"
@@ -559,6 +560,7 @@ static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx,
Relation partitionTbl);
static List *GetParentedForeignKeyRefs(Relation partition);
static void ATDetachCheckNoForeignKeyRefs(Relation partition);
+static void ATExecAlterCollationRefreshVersion(Relation rel, List *coll);
/* ----------------------------------------------------------------
@@ -3986,6 +3988,10 @@ AlterTableGetLockLevel(List *cmds)
cmd_lockmode = AccessShareLock;
break;
+ case AT_AlterCollationRefreshVersion:
+ cmd_lockmode = AccessExclusiveLock;
+ break;
+
default: /* oops */
elog(ERROR, "unrecognized alter table type: %d",
(int) cmd->subtype);
@@ -4160,6 +4166,12 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
/* This command never recurses */
pass = AT_PASS_MISC;
break;
+ case AT_AlterCollationRefreshVersion: /* ALTER COLLATION ... REFRESH
+ * VERSION */
+ ATSimplePermissions(rel, ATT_INDEX);
+ /* This command never recurses */
+ pass = AT_PASS_MISC;
+ break;
case AT_SetStorage: /* ALTER COLUMN SET STORAGE */
ATSimplePermissions(rel, ATT_TABLE | ATT_MATVIEW | ATT_FOREIGN_TABLE);
ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context);
@@ -4738,6 +4750,11 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
ATExecDetachPartition(rel, ((PartitionCmd *) cmd->def)->name);
break;
+ case AT_AlterCollationRefreshVersion:
+ /* ATPrepCmd ensured it must be an index */
+ Assert(rel->rd_rel->relkind == RELKIND_INDEX);
+ ATExecAlterCollationRefreshVersion(rel, cmd->object);
+ break;
default: /* oops */
elog(ERROR, "unrecognized alter table type: %d",
(int) cmd->subtype);
@@ -17582,3 +17599,17 @@ ATDetachCheckNoForeignKeyRefs(Relation partition)
table_close(rel, NoLock);
}
}
+
+/*
+ * ALTER INDEX ... ALTER COLLATION ... REFRESH VERSION
+ *
+ * Update refobjversion to the current collation version by force. This clears
+ * warnings about version mismatches without the need to run REINDEX,
+ * potentially hiding corruption due to ordering changes.
+ */
+static void
+ATExecAlterCollationRefreshVersion(Relation rel, List *coll)
+{
+ index_update_collation_versions(rel->rd_id, get_collation_oid(coll, false));
+ CacheInvalidateRelcache(rel);
+}