summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier2020-03-03 04:55:41 +0000
committerMichael Paquier2020-03-03 04:55:41 +0000
commit0b48f1335dddb7141160e392cccac98edfb3fa85 (patch)
treeceed64af27f821185ee2bd3ece37ec627546eb8d
parent54a4f52a9258198243c53fceaf8da70546ebd652 (diff)
Fix assertion failure with ALTER TABLE ATTACH PARTITION and indexes
Using ALTER TABLE ATTACH PARTITION causes an assertion failure when attempting to work on a partitioned index, because partitioned indexes cannot have partition bounds. The grammar of ALTER TABLE ATTACH PARTITION requires partition bounds, but not ALTER INDEX, so mixing ALTER TABLE with partitioned indexes is confusing. Hence, on HEAD, prevent ALTER TABLE to attach a partition if the relation involved is a partitioned index. On back-branches, as applications may rely on the existing behavior, just remove the culprit assertion. Reported-by: Alexander Lakhin Author: Amit Langote, Michael Paquier Discussion: https://postgr.es/m/[email protected] Backpatch-through: 11
-rw-r--r--src/backend/parser/parse_utilcmd.c12
-rw-r--r--src/test/regress/expected/indexing.out17
-rw-r--r--src/test/regress/sql/indexing.sql10
3 files changed, 37 insertions, 2 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index ee2d2b54a1..973eab6ae2 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -3698,8 +3698,16 @@ transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd)
cmd->bound);
break;
case RELKIND_PARTITIONED_INDEX:
- /* nothing to check */
- Assert(cmd->bound == NULL);
+
+ /*
+ * A partitioned index cannot have a partition bound set. ALTER
+ * INDEX prevents that with its grammar, but not ALTER TABLE.
+ */
+ if (cmd->bound != NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("\"%s\" is not a partitioned table",
+ RelationGetRelationName(parentRel))));
break;
case RELKIND_RELATION:
/* the table must be partitioned */
diff --git a/src/test/regress/expected/indexing.out b/src/test/regress/expected/indexing.out
index ec1d4eaef4..f78865ef81 100644
--- a/src/test/regress/expected/indexing.out
+++ b/src/test/regress/expected/indexing.out
@@ -121,6 +121,23 @@ Partition of: idxparti2
No partition constraint
btree, for table "public.idxpart1"
+-- Forbid ALTER TABLE when attaching or detaching an index to a partition.
+create index idxpart_c on only idxpart (c);
+create index idxpart1_c on idxpart1 (c);
+alter table idxpart_c attach partition idxpart1_c for values from (10) to (20);
+ERROR: "idxpart_c" is not a partitioned table
+alter index idxpart_c attach partition idxpart1_c;
+select relname, relpartbound from pg_class
+ where relname in ('idxpart_c', 'idxpart1_c')
+ order by relname;
+ relname | relpartbound
+------------+--------------
+ idxpart1_c |
+ idxpart_c |
+(2 rows)
+
+alter table idxpart_c detach partition idxpart1_c;
+ERROR: "idxpart_c" is not a table
drop table idxpart;
-- If a partition already has an index, don't create a duplicative one
create table idxpart (a int, b int) partition by range (a, b);
diff --git a/src/test/regress/sql/indexing.sql b/src/test/regress/sql/indexing.sql
index f6a3767918..35d159f41b 100644
--- a/src/test/regress/sql/indexing.sql
+++ b/src/test/regress/sql/indexing.sql
@@ -63,6 +63,16 @@ alter table idxpart attach partition idxpart1 for values from (0) to (10);
\d idxpart1
\d+ idxpart1_a_idx
\d+ idxpart1_b_c_idx
+
+-- Forbid ALTER TABLE when attaching or detaching an index to a partition.
+create index idxpart_c on only idxpart (c);
+create index idxpart1_c on idxpart1 (c);
+alter table idxpart_c attach partition idxpart1_c for values from (10) to (20);
+alter index idxpart_c attach partition idxpart1_c;
+select relname, relpartbound from pg_class
+ where relname in ('idxpart_c', 'idxpart1_c')
+ order by relname;
+alter table idxpart_c detach partition idxpart1_c;
drop table idxpart;
-- If a partition already has an index, don't create a duplicative one