Fix failure when creating cloned indexes for a partition
authorMichael Paquier <michael@paquier.xyz>
Sat, 2 Nov 2019 05:16:04 +0000 (14:16 +0900)
committerMichael Paquier <michael@paquier.xyz>
Sat, 2 Nov 2019 05:16:04 +0000 (14:16 +0900)
When using CREATE TABLE for a new partition, the partitioned indexes of
the parent are created automatically in a fashion similar to LIKE
INDEXES.  The new partition and its parent use a mapping for attribute
numbers for this operation, and while the mapping was correctly built,
its length was defined as the number of attributes of the newly-created
child, and not the parent.  If the parent includes dropped columns, this
could cause failures.

This is wrong since 8b08f7d which has introduced the concept of
partitioned indexes, so backpatch down to 11.

Reported-by: Wyatt Alt
Author: Michael Paquier
Reviewed-by: Amit Langote
Discussion: https://postgr.es/m/CAGem3qCcRmhbs4jYMkenYNfP2kEusDXvTfw-q+eOhM0zTceG-g@mail.gmail.com
Backpatch-through: 11

src/backend/commands/tablecmds.c
src/test/regress/expected/create_table.out
src/test/regress/sql/create_table.sql

index 8d25d147729ae73b1e493aaf05a79c9e47c126a7..5597be6e3d9ee343ac7c0e6e457b0a4bd86ec70a 100644 (file)
@@ -1091,7 +1091,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
                                                RelationGetDescr(parent));
            idxstmt =
                generateClonedIndexStmt(NULL, idxRel,
-                                       attmap, RelationGetDescr(rel)->natts,
+                                       attmap, RelationGetDescr(parent)->natts,
                                        &constraintOid);
            DefineIndex(RelationGetRelid(rel),
                        idxstmt,
index ce2484fd4e44053df2dfff6327cec74516700c9a..f63016871cad5365292086204e079f72a6de6c5f 100644 (file)
@@ -1168,3 +1168,52 @@ insert into defcheck_def values (0, 0);
 create table defcheck_0 partition of defcheck for values in (0);
 ERROR:  updated partition constraint for default partition "defcheck_def" would be violated by some row
 drop table defcheck;
+-- tests of column drop with partition tables and indexes using
+-- predicates and expressions.
+create table part_column_drop (
+  useless_1 int,
+  id int,
+  useless_2 int,
+  d int,
+  b int,
+  useless_3 int
+) partition by range (id);
+alter table part_column_drop drop column useless_1;
+alter table part_column_drop drop column useless_2;
+alter table part_column_drop drop column useless_3;
+create index part_column_drop_b_pred on part_column_drop(b) where b = 1;
+create index part_column_drop_b_expr on part_column_drop((b = 1));
+create index part_column_drop_d_pred on part_column_drop(d) where d = 2;
+create index part_column_drop_d_expr on part_column_drop((d = 2));
+create table part_column_drop_1_10 partition of
+  part_column_drop for values from (1) to (10);
+\d part_column_drop
+    Partitioned table "public.part_column_drop"
+ Column |  Type   | Collation | Nullable | Default 
+--------+---------+-----------+----------+---------
+ id     | integer |           |          | 
+ d      | integer |           |          | 
+ b      | integer |           |          | 
+Partition key: RANGE (id)
+Indexes:
+    "part_column_drop_b_expr" btree ((b = 1))
+    "part_column_drop_b_pred" btree (b) WHERE b = 1
+    "part_column_drop_d_expr" btree ((d = 2))
+    "part_column_drop_d_pred" btree (d) WHERE d = 2
+Number of partitions: 1 (Use \d+ to list them.)
+
+\d part_column_drop_1_10
+       Table "public.part_column_drop_1_10"
+ Column |  Type   | Collation | Nullable | Default 
+--------+---------+-----------+----------+---------
+ id     | integer |           |          | 
+ d      | integer |           |          | 
+ b      | integer |           |          | 
+Partition of: part_column_drop FOR VALUES FROM (1) TO (10)
+Indexes:
+    "part_column_drop_1_10_b_idx" btree (b) WHERE b = 1
+    "part_column_drop_1_10_d_idx" btree (d) WHERE d = 2
+    "part_column_drop_1_10_expr_idx" btree ((b = 1))
+    "part_column_drop_1_10_expr_idx1" btree ((d = 2))
+
+drop table part_column_drop;
index 144eeb480dd5ce95356e6176817e81ea78e429d3..e835b65ac44ee131a20ecba54677548dd1eb3413 100644 (file)
@@ -903,3 +903,26 @@ create table defcheck_1 partition of defcheck for values in (1, null);
 insert into defcheck_def values (0, 0);
 create table defcheck_0 partition of defcheck for values in (0);
 drop table defcheck;
+
+-- tests of column drop with partition tables and indexes using
+-- predicates and expressions.
+create table part_column_drop (
+  useless_1 int,
+  id int,
+  useless_2 int,
+  d int,
+  b int,
+  useless_3 int
+) partition by range (id);
+alter table part_column_drop drop column useless_1;
+alter table part_column_drop drop column useless_2;
+alter table part_column_drop drop column useless_3;
+create index part_column_drop_b_pred on part_column_drop(b) where b = 1;
+create index part_column_drop_b_expr on part_column_drop((b = 1));
+create index part_column_drop_d_pred on part_column_drop(d) where d = 2;
+create index part_column_drop_d_expr on part_column_drop((d = 2));
+create table part_column_drop_1_10 partition of
+  part_column_drop for values from (1) to (10);
+\d part_column_drop
+\d part_column_drop_1_10
+drop table part_column_drop;