aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/cache')
-rw-r--r--src/backend/utils/cache/relcache.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 8e08ca1c680..7234cb3da69 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -4789,19 +4789,41 @@ RelationGetIndexList(Relation relation)
result = lappend_oid(result, index->indexrelid);
/*
- * Invalid, 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, non-immediate or predicate indexes aren't interesting
+ * for either oid indexes or replication identity indexes, so don't
+ * check them.
*/
- if (!index->indisvalid || !index->indisunique ||
+ if (!index->indisunique ||
!index->indimmediate ||
!heap_attisnull(htup, Anum_pg_index_indpred, NULL))
continue;
- /* remember primary key index if any */
- if (index->indisprimary)
+ /*
+ * Remember primary key index, if any. We do this only if the index
+ * is valid; but if the table is partitioned, then we do it even if
+ * it's invalid.
+ *
+ * The reason for returning invalid primary keys for foreign tables is
+ * because of pg_dump of NOT NULL constraints, and the fact that PKs
+ * remain marked invalid until the partitions' PKs are attached to it.
+ * If we make rd_pkindex invalid, then the attnotnull flag is reset
+ * after the PK is created, which causes the ALTER INDEX ATTACH
+ * PARTITION to fail with 'column ... is not marked NOT NULL'. With
+ * this, dropconstraint_internal() will believe that the columns must
+ * not have attnotnull reset, so the PKs-on-partitions can be attached
+ * correctly, until finally the PK-on-parent is marked valid.
+ *
+ * Also, this doesn't harm anything, because rd_pkindex is not a
+ * "real" index anyway, but a RELKIND_PARTITIONED_INDEX.
+ */
+ if (index->indisprimary &&
+ (index->indisvalid ||
+ relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE))
pkeyIndex = index->indexrelid;
+ if (!index->indisvalid)
+ continue;
+
/* remember explicitly chosen replica index */
if (index->indisreplident)
candidateIndex = index->indexrelid;