From 55ed3defc966cf718fe1e8c0efe964580bb23351 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Wed, 26 Jun 2019 18:38:51 -0400 Subject: Fix partitioned index creation with foreign partitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/backend/commands/indexcmds.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/backend/commands/indexcmds.c') diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index a3cbeff9500..cdbb56f1a4a 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -1085,6 +1085,26 @@ DefineIndex(Oid relationId, int maplen; childrel = table_open(childRelid, lockmode); + + /* + * Don't try to create indexes on foreign tables, though. + * Skip those if a regular index, or fail if trying to create + * a constraint index. + */ + if (childrel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) + { + if (stmt->unique || stmt->primary) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot create unique index on partitioned table \"%s\"", + RelationGetRelationName(rel)), + errdetail("Table \"%s\" contains partitions that are foreign tables.", + RelationGetRelationName(rel)))); + + table_close(childrel, lockmode); + continue; + } + childidxs = RelationGetIndexList(childrel); attmap = convert_tuples_by_name_map(RelationGetDescr(childrel), -- cgit v1.2.3