aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2020-03-13 11:28:11 +0100
committerPeter Eisentraut <peter@eisentraut.org>2020-03-13 11:57:20 +0100
commitc9ef507e82ebb2bffc50e531edd6fb4593dd5146 (patch)
treef5a6dc1f711ebe4950595984507b59532bdf15f6 /src/backend/commands/tablecmds.c
parent630590d6ff632b95418eff9e98482d9a93b60ee3 (diff)
downloadpostgresql-c9ef507e82ebb2bffc50e531edd6fb4593dd5146.tar.gz
postgresql-c9ef507e82ebb2bffc50e531edd6fb4593dd5146.zip
Preserve replica identity index across ALTER TABLE rewrite
If an index was explicitly set as replica identity index, this setting was lost when a table was rewritten by ALTER TABLE. Because this setting is part of pg_index but actually controlled by ALTER TABLE (not part of CREATE INDEX, say), we have to do some extra work to restore it. Based-on-patch-by: Quan Zongliang <quanzongliang@gmail.com> Reviewed-by: Euler Taveira <euler.taveira@2ndquadrant.com> Discussion: https://www.postgresql.org/message-id/flat/c70fcab2-4866-0d9f-1d01-e75e189db342@gmail.com
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d07476d8ddf..74eb7ac8d76 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -174,6 +174,7 @@ typedef struct AlteredTableInfo
List *changedConstraintDefs; /* string definitions of same */
List *changedIndexOids; /* OIDs of indexes to rebuild */
List *changedIndexDefs; /* string definitions of same */
+ char *replicaIdentityIndex; /* index to reset as REPLICA IDENTITY */
} AlteredTableInfo;
/* Struct describing one new constraint to check in Phase 3 scan */
@@ -11139,6 +11140,22 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
}
/*
+ * Subroutine for ATExecAlterColumnType: remember that a replica identity
+ * needs to be reset.
+ */
+static void
+RememberReplicaIdentityForRebuilding(Oid indoid, AlteredTableInfo *tab)
+{
+ if (!get_index_isreplident(indoid))
+ return;
+
+ if (tab->replicaIdentityIndex)
+ elog(ERROR, "relation %u has multiple indexes marked as replica identity", tab->relid);
+
+ tab->replicaIdentityIndex = get_rel_name(indoid);
+}
+
+/*
* Subroutine for ATExecAlterColumnType: remember that a constraint needs
* to be rebuilt (which we might already know).
*/
@@ -11156,11 +11173,16 @@ RememberConstraintForRebuilding(Oid conoid, AlteredTableInfo *tab)
{
/* OK, capture the constraint's existing definition string */
char *defstring = pg_get_constraintdef_command(conoid);
+ Oid indoid;
tab->changedConstraintOids = lappend_oid(tab->changedConstraintOids,
conoid);
tab->changedConstraintDefs = lappend(tab->changedConstraintDefs,
defstring);
+
+ indoid = get_constraint_index(conoid);
+ if (OidIsValid(indoid))
+ RememberReplicaIdentityForRebuilding(indoid, tab);
}
}
@@ -11203,6 +11225,8 @@ RememberIndexForRebuilding(Oid indoid, AlteredTableInfo *tab)
indoid);
tab->changedIndexDefs = lappend(tab->changedIndexDefs,
defstring);
+
+ RememberReplicaIdentityForRebuilding(indoid, tab);
}
}
}
@@ -11312,6 +11336,24 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
}
/*
+ * Queue up command to restore replica identity index marking
+ */
+ if (tab->replicaIdentityIndex)
+ {
+ AlterTableCmd *cmd = makeNode(AlterTableCmd);
+ ReplicaIdentityStmt *subcmd = makeNode(ReplicaIdentityStmt);
+
+ subcmd->identity_type = REPLICA_IDENTITY_INDEX;
+ subcmd->name = tab->replicaIdentityIndex;
+ cmd->subtype = AT_ReplicaIdentity;
+ cmd->def = (Node *) subcmd;
+
+ /* do it after indexes and constraints */
+ tab->subcmds[AT_PASS_OLD_CONSTR] =
+ lappend(tab->subcmds[AT_PASS_OLD_CONSTR], cmd);
+ }
+
+ /*
* It should be okay to use DROP_RESTRICT here, since nothing else should
* be depending on these objects.
*/