aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2019-06-26 18:38:51 -0400
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2019-06-26 18:38:51 -0400
commit55ed3defc966cf718fe1e8c0efe964580bb23351 (patch)
treeddc9c211ea304679726c72019f92494450779c04 /src/backend/commands/tablecmds.c
parent65e6d42140c8d9918638b9f73528288ab980af82 (diff)
downloadpostgresql-55ed3defc966cf718fe1e8c0efe964580bb23351.tar.gz
postgresql-55ed3defc966cf718fe1e8c0efe964580bb23351.zip
Fix partitioned index creation with foreign partitions
When a partitioned tables contains foreign tables as partitions, it is not possible to implement unique or primary key indexes -- but when regular indexes are created, there is no reason to do anything other than ignoring such partitions. We were raising errors upon encountering the foreign partitions, which is unfriendly and doesn't protect against any actual problems. Relax this restriction so that index creation is allowed on partitioned tables containing foreign partitions, becoming a no-op on them. (We may later want to redefine this so that the FDW is told to create the indexes on the foreign side.) This applies to CREATE INDEX, as well as ALTER TABLE / ATTACH PARTITION and CREATE TABLE / PARTITION OF. Backpatch to 11, where indexes on partitioned tables were introduced. Discussion: https://postgr.es/m/15724-d5a58fa9472eef4f@postgresql.org Author: Álvaro Herrera Reviewed-by: Amit Langote
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index ba59fc708a9..7dcd634a1ae 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -1069,6 +1069,22 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
IndexStmt *idxstmt;
Oid constraintOid;
+ if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ {
+ if (idxRel->rd_index->indisunique)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot create foreign partition of partitioned table \"%s\"",
+ RelationGetRelationName(parent)),
+ errdetail("Table \"%s\" contains indexes that are unique.",
+ RelationGetRelationName(parent))));
+ else
+ {
+ index_close(idxRel, AccessShareLock);
+ continue;
+ }
+ }
+
attmap = convert_tuples_by_name_map(RelationGetDescr(rel),
RelationGetDescr(parent),
gettext_noop("could not convert row type"));
@@ -15723,6 +15739,34 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel)
}
/*
+ * If we're attaching a foreign table, we must fail if any of the indexes
+ * is a constraint index; otherwise, there's nothing to do here. Do this
+ * before starting work, to avoid wasting the effort of building a few
+ * non-unique indexes before coming across a unique one.
+ */
+ if (attachrel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ {
+ foreach(cell, idxes)
+ {
+ Oid idx = lfirst_oid(cell);
+ Relation idxRel = index_open(idx, AccessShareLock);
+
+ if (idxRel->rd_index->indisunique ||
+ idxRel->rd_index->indisprimary)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"",
+ RelationGetRelationName(attachrel),
+ RelationGetRelationName(rel)),
+ errdetail("Table \"%s\" contains unique indexes.",
+ RelationGetRelationName(rel))));
+ index_close(idxRel, AccessShareLock);
+ }
+
+ goto out;
+ }
+
+ /*
* For each index on the partitioned table, find a matching one in the
* partition-to-be; if one is not found, create one.
*/
@@ -15824,6 +15868,7 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel)
index_close(idxRel, AccessShareLock);
}
+out:
/* Clean up. */
for (i = 0; i < list_length(attachRelIdxs); i++)
index_close(attachrelIdxRels[i], AccessShareLock);