aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c64
1 files changed, 22 insertions, 42 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 7c697a285bd..1293545947e 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -15773,7 +15773,10 @@ ATExecDropOf(Relation rel, LOCKMODE lockmode)
* relation_mark_replica_identity: Update a table's replica identity
*
* Iff ri_type = REPLICA_IDENTITY_INDEX, indexOid must be the Oid of a suitable
- * index. Otherwise, it should be InvalidOid.
+ * index. Otherwise, it must be InvalidOid.
+ *
+ * Caller had better hold an exclusive lock on the relation, as the results
+ * of running two of these concurrently wouldn't be pretty.
*/
static void
relation_mark_replica_identity(Relation rel, char ri_type, Oid indexOid,
@@ -15785,7 +15788,6 @@ relation_mark_replica_identity(Relation rel, char ri_type, Oid indexOid,
HeapTuple pg_index_tuple;
Form_pg_class pg_class_form;
Form_pg_index pg_index_form;
-
ListCell *index;
/*
@@ -15807,29 +15809,7 @@ relation_mark_replica_identity(Relation rel, char ri_type, Oid indexOid,
heap_freetuple(pg_class_tuple);
/*
- * Check whether the correct index is marked indisreplident; if so, we're
- * done.
- */
- if (OidIsValid(indexOid))
- {
- Assert(ri_type == REPLICA_IDENTITY_INDEX);
-
- pg_index_tuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexOid));
- if (!HeapTupleIsValid(pg_index_tuple))
- elog(ERROR, "cache lookup failed for index %u", indexOid);
- pg_index_form = (Form_pg_index) GETSTRUCT(pg_index_tuple);
-
- if (pg_index_form->indisreplident)
- {
- ReleaseSysCache(pg_index_tuple);
- return;
- }
- ReleaseSysCache(pg_index_tuple);
- }
-
- /*
- * Clear the indisreplident flag from any index that had it previously,
- * and set it for any index that should have it now.
+ * Update the per-index indisreplident flags correctly.
*/
pg_index = table_open(IndexRelationId, RowExclusiveLock);
foreach(index, RelationGetIndexList(rel))
@@ -15843,19 +15823,23 @@ relation_mark_replica_identity(Relation rel, char ri_type, Oid indexOid,
elog(ERROR, "cache lookup failed for index %u", thisIndexOid);
pg_index_form = (Form_pg_index) GETSTRUCT(pg_index_tuple);
- /*
- * Unset the bit if set. We know it's wrong because we checked this
- * earlier.
- */
- if (pg_index_form->indisreplident)
+ if (thisIndexOid == indexOid)
{
- dirty = true;
- pg_index_form->indisreplident = false;
+ /* Set the bit if not already set. */
+ if (!pg_index_form->indisreplident)
+ {
+ dirty = true;
+ pg_index_form->indisreplident = true;
+ }
}
- else if (thisIndexOid == indexOid)
+ else
{
- dirty = true;
- pg_index_form->indisreplident = true;
+ /* Unset the bit if set. */
+ if (pg_index_form->indisreplident)
+ {
+ dirty = true;
+ pg_index_form->indisreplident = false;
+ }
}
if (dirty)
@@ -15867,7 +15851,9 @@ relation_mark_replica_identity(Relation rel, char ri_type, Oid indexOid,
/*
* Invalidate the relcache for the table, so that after we commit
* all sessions will refresh the table's replica identity index
- * before attempting any UPDATE or DELETE on the table.
+ * before attempting any UPDATE or DELETE on the table. (If we
+ * changed the table's pg_class row above, then a relcache inval
+ * is already queued due to that; but we might not have.)
*/
CacheInvalidateRelcache(rel);
}
@@ -15952,12 +15938,6 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot use partial index \"%s\" as replica identity",
RelationGetRelationName(indexRel))));
- /* And neither are invalid indexes. */
- if (!indexRel->rd_index->indisvalid)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot use invalid index \"%s\" as replica identity",
- RelationGetRelationName(indexRel))));
/* Check index for nullable columns. */
for (key = 0; key < IndexRelationGetNumberOfKeyAttributes(indexRel); key++)