aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache/relcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/cache/relcache.c')
-rw-r--r--src/backend/utils/cache/relcache.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 4d339ee7950..7ad6a35a50e 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -4761,6 +4761,7 @@ RelationGetIndexList(Relation relation)
char replident = relation->rd_rel->relreplident;
Oid pkeyIndex = InvalidOid;
Oid candidateIndex = InvalidOid;
+ bool pkdeferrable = false;
MemoryContext oldcxt;
/* Quick exit if we already computed the list. */
@@ -4802,12 +4803,12 @@ RelationGetIndexList(Relation relation)
result = lappend_oid(result, index->indexrelid);
/*
- * Non-unique, non-immediate or predicate indexes aren't interesting
- * for either oid indexes or replication identity indexes, so don't
- * check them.
+ * Non-unique or predicate indexes aren't interesting for either oid
+ * indexes or replication identity indexes, so don't check them.
+ * Deferred ones are not useful for replication identity either; but
+ * we do include them if they are PKs.
*/
if (!index->indisunique ||
- !index->indimmediate ||
!heap_attisnull(htup, Anum_pg_index_indpred, NULL))
continue;
@@ -4832,7 +4833,13 @@ RelationGetIndexList(Relation relation)
if (index->indisprimary &&
(index->indisvalid ||
relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE))
+ {
pkeyIndex = index->indexrelid;
+ pkdeferrable = !index->indimmediate;
+ }
+
+ if (!index->indimmediate)
+ continue;
if (!index->indisvalid)
continue;
@@ -4854,7 +4861,8 @@ RelationGetIndexList(Relation relation)
oldlist = relation->rd_indexlist;
relation->rd_indexlist = list_copy(result);
relation->rd_pkindex = pkeyIndex;
- if (replident == REPLICA_IDENTITY_DEFAULT && OidIsValid(pkeyIndex))
+ relation->rd_ispkdeferrable = pkdeferrable;
+ if (replident == REPLICA_IDENTITY_DEFAULT && OidIsValid(pkeyIndex) && !pkdeferrable)
relation->rd_replidindex = pkeyIndex;
else if (replident == REPLICA_IDENTITY_INDEX && OidIsValid(candidateIndex))
relation->rd_replidindex = candidateIndex;
@@ -4957,7 +4965,8 @@ RelationGetStatExtList(Relation relation)
/*
* RelationGetPrimaryKeyIndex -- get OID of the relation's primary key index
*
- * Returns InvalidOid if there is no such index.
+ * Returns InvalidOid if there is no such index, or if the primary key is
+ * DEFERRABLE.
*/
Oid
RelationGetPrimaryKeyIndex(Relation relation)
@@ -4972,7 +4981,7 @@ RelationGetPrimaryKeyIndex(Relation relation)
Assert(relation->rd_indexvalid);
}
- return relation->rd_pkindex;
+ return relation->rd_ispkdeferrable ? InvalidOid : relation->rd_pkindex;
}
/*
@@ -5190,6 +5199,7 @@ RelationGetIndexPredicate(Relation relation)
* INDEX_ATTR_BITMAP_KEY Columns in non-partial unique indexes not
* in expressions (i.e., usable for FKs)
* INDEX_ATTR_BITMAP_PRIMARY_KEY Columns in the table's primary key
+ * (beware: even if PK is deferrable!)
* INDEX_ATTR_BITMAP_IDENTITY_KEY Columns in the table's replica identity
* index (empty if FULL)
* INDEX_ATTR_BITMAP_HOT_BLOCKING Columns that block updates from being HOT
@@ -5198,6 +5208,9 @@ RelationGetIndexPredicate(Relation relation)
* Attribute numbers are offset by FirstLowInvalidHeapAttributeNumber so that
* we can include system attributes (e.g., OID) in the bitmap representation.
*
+ * Deferred indexes are considered for the primary key, but not for replica
+ * identity.
+ *
* Caller had better hold at least RowExclusiveLock on the target relation
* to ensure it is safe (deadlock-free) for us to take locks on the relation's
* indexes. Note that since the introduction of CREATE INDEX CONCURRENTLY,