summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorAlvaro Herrera2019-06-26 22:38:51 +0000
committerAlvaro Herrera2019-06-26 22:38:51 +0000
commit55ed3defc966cf718fe1e8c0efe964580bb23351 (patch)
treeddc9c211ea304679726c72019f92494450779c04 /src/test
parent65e6d42140c8d9918638b9f73528288ab980af82 (diff)
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/test')
-rw-r--r--src/test/regress/expected/foreign_data.out56
-rw-r--r--src/test/regress/sql/foreign_data.sql42
2 files changed, 95 insertions, 3 deletions
diff --git a/src/test/regress/expected/foreign_data.out b/src/test/regress/expected/foreign_data.out
index c81e4bda807..b9e25820bc0 100644
--- a/src/test/regress/expected/foreign_data.out
+++ b/src/test/regress/expected/foreign_data.out
@@ -748,10 +748,62 @@ ERROR: foreign-data wrapper "dummy" has no handler
CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a);
CREATE FOREIGN TABLE ft_part1
PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0;
-CREATE INDEX ON lt1 (a); -- ERROR
-ERROR: cannot create index on partitioned table "lt1"
+CREATE INDEX ON lt1 (a); -- skips partition
+CREATE UNIQUE INDEX ON lt1 (a); -- ERROR
+ERROR: cannot create unique index on partitioned table "lt1"
DETAIL: Table "lt1" contains partitions that are foreign tables.
+ALTER TABLE lt1 ADD PRIMARY KEY (a); -- ERROR
+ERROR: cannot create unique index on partitioned table "lt1"
+DETAIL: Table "lt1" contains partitions that are foreign tables.
+DROP TABLE lt1;
+CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a);
+CREATE INDEX ON lt1 (a);
+CREATE FOREIGN TABLE ft_part1
+ PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0;
+CREATE FOREIGN TABLE ft_part2 (a INT) SERVER s0;
+ALTER TABLE lt1 ATTACH PARTITION ft_part2 FOR VALUES FROM (1000) TO (2000);
+DROP FOREIGN TABLE ft_part1, ft_part2;
+CREATE UNIQUE INDEX ON lt1 (a);
+ALTER TABLE lt1 ADD PRIMARY KEY (a);
+CREATE FOREIGN TABLE ft_part1
+ PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0; -- ERROR
+ERROR: cannot create foreign partition of partitioned table "lt1"
+DETAIL: Table "lt1" contains indexes that are unique.
+CREATE FOREIGN TABLE ft_part2 (a INT NOT NULL) SERVER s0;
+ALTER TABLE lt1 ATTACH PARTITION ft_part2
+ FOR VALUES FROM (1000) TO (2000); -- ERROR
+ERROR: cannot attach foreign table "ft_part2" as partition of partitioned table "lt1"
+DETAIL: Table "lt1" contains unique indexes.
+DROP TABLE lt1;
+DROP FOREIGN TABLE ft_part2;
+CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a);
+CREATE INDEX ON lt1 (a);
+CREATE TABLE lt1_part1
+ PARTITION OF lt1 FOR VALUES FROM (0) TO (1000)
+ PARTITION BY RANGE (a);
+CREATE FOREIGN TABLE ft_part_1_1
+ PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0;
+CREATE FOREIGN TABLE ft_part_1_2 (a INT) SERVER s0;
+ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200);
+CREATE UNIQUE INDEX ON lt1 (a);
+ERROR: cannot create unique index on partitioned table "lt1"
+DETAIL: Table "lt1" contains partitions that are foreign tables.
+ALTER TABLE lt1 ADD PRIMARY KEY (a);
+ERROR: cannot create unique index on partitioned table "lt1_part1"
+DETAIL: Table "lt1_part1" contains partitions that are foreign tables.
+DROP FOREIGN TABLE ft_part_1_1, ft_part_1_2;
+CREATE UNIQUE INDEX ON lt1 (a);
+ALTER TABLE lt1 ADD PRIMARY KEY (a);
+CREATE FOREIGN TABLE ft_part_1_1
+ PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0;
+ERROR: cannot create foreign partition of partitioned table "lt1_part1"
+DETAIL: Table "lt1_part1" contains indexes that are unique.
+CREATE FOREIGN TABLE ft_part_1_2 (a INT NOT NULL) SERVER s0;
+ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200);
+ERROR: cannot attach foreign table "ft_part_1_2" as partition of partitioned table "lt1_part1"
+DETAIL: Table "lt1_part1" contains unique indexes.
DROP TABLE lt1;
+DROP FOREIGN TABLE ft_part_1_2;
-- ALTER FOREIGN TABLE
COMMENT ON FOREIGN TABLE ft1 IS 'foreign table';
COMMENT ON FOREIGN TABLE ft1 IS NULL;
diff --git a/src/test/regress/sql/foreign_data.sql b/src/test/regress/sql/foreign_data.sql
index c646ed91526..73f9f621d8f 100644
--- a/src/test/regress/sql/foreign_data.sql
+++ b/src/test/regress/sql/foreign_data.sql
@@ -318,9 +318,49 @@ EXPLAIN SELECT * FROM ft1; -- ERROR
CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a);
CREATE FOREIGN TABLE ft_part1
PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0;
-CREATE INDEX ON lt1 (a); -- ERROR
+CREATE INDEX ON lt1 (a); -- skips partition
+CREATE UNIQUE INDEX ON lt1 (a); -- ERROR
+ALTER TABLE lt1 ADD PRIMARY KEY (a); -- ERROR
DROP TABLE lt1;
+CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a);
+CREATE INDEX ON lt1 (a);
+CREATE FOREIGN TABLE ft_part1
+ PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0;
+CREATE FOREIGN TABLE ft_part2 (a INT) SERVER s0;
+ALTER TABLE lt1 ATTACH PARTITION ft_part2 FOR VALUES FROM (1000) TO (2000);
+DROP FOREIGN TABLE ft_part1, ft_part2;
+CREATE UNIQUE INDEX ON lt1 (a);
+ALTER TABLE lt1 ADD PRIMARY KEY (a);
+CREATE FOREIGN TABLE ft_part1
+ PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0; -- ERROR
+CREATE FOREIGN TABLE ft_part2 (a INT NOT NULL) SERVER s0;
+ALTER TABLE lt1 ATTACH PARTITION ft_part2
+ FOR VALUES FROM (1000) TO (2000); -- ERROR
+DROP TABLE lt1;
+DROP FOREIGN TABLE ft_part2;
+
+CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a);
+CREATE INDEX ON lt1 (a);
+CREATE TABLE lt1_part1
+ PARTITION OF lt1 FOR VALUES FROM (0) TO (1000)
+ PARTITION BY RANGE (a);
+CREATE FOREIGN TABLE ft_part_1_1
+ PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0;
+CREATE FOREIGN TABLE ft_part_1_2 (a INT) SERVER s0;
+ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200);
+CREATE UNIQUE INDEX ON lt1 (a);
+ALTER TABLE lt1 ADD PRIMARY KEY (a);
+DROP FOREIGN TABLE ft_part_1_1, ft_part_1_2;
+CREATE UNIQUE INDEX ON lt1 (a);
+ALTER TABLE lt1 ADD PRIMARY KEY (a);
+CREATE FOREIGN TABLE ft_part_1_1
+ PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0;
+CREATE FOREIGN TABLE ft_part_1_2 (a INT NOT NULL) SERVER s0;
+ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200);
+DROP TABLE lt1;
+DROP FOREIGN TABLE ft_part_1_2;
+
-- ALTER FOREIGN TABLE
COMMENT ON FOREIGN TABLE ft1 IS 'foreign table';
COMMENT ON FOREIGN TABLE ft1 IS NULL;