diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 3ca23c8ef5..7fa054f56a 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -13416,6 +13416,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) List *childrels; TupleConstr *attachRel_constr; List *partConstraint, + *partConstraintOrig, *existConstraint; SysScanDesc scan; ScanKeyData skey; @@ -13581,6 +13582,15 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) partConstraint = list_make1(make_ands_explicit(partConstraint)); /* + * Adjust the generated constraint to match this partition's attribute + * numbers. Save the original to be used later if we decide to proceed + * with the validation scan after all. + */ + partConstraintOrig = copyObject(partConstraint); + partConstraint = map_partition_varattnos(partConstraint, 1, attachRel, + rel); + + /* * Check if we can do away with having to scan the table being attached to * validate the partition constraint, by *proving* that the existing * constraints of the table *imply* the partition predicate. We include @@ -13715,7 +13725,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) tab = ATGetQueueEntry(wqueue, part_rel); /* Adjust constraint to match this partition */ - constr = linitial(partConstraint); + constr = linitial(partConstraintOrig); tab->partition_constraint = (Expr *) map_partition_varattnos((List *) constr, 1, part_rel, rel); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 13d6a4b747..ec67b4cc73 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -3347,6 +3347,16 @@ ALTER TABLE part_5 DROP CONSTRAINT check_a; ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IN (5)), ALTER a SET NOT NULL; ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5); INFO: partition constraint for table "part_5" is implied by existing constraints +-- scan will be skipped, even though partition column attribute numbers differ +-- from the parent (provided the appropriate check constraint is present) +CREATE TABLE part_6 ( + c int, + LIKE list_parted2, + CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 6) +); +ALTER TABLE part_6 DROP c; +ALTER TABLE list_parted2 ATTACH PARTITION part_6 FOR VALUES IN (6); +INFO: partition constraint for table "part_6" is implied by existing constraints -- check that the table being attached is not already a partition ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2); ERROR: "part_2" is already a partition diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index 5dd1402ea6..5779ad1161 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -2178,6 +2178,16 @@ ALTER TABLE part_5 DROP CONSTRAINT check_a; ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IN (5)), ALTER a SET NOT NULL; ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5); +-- scan will be skipped, even though partition column attribute numbers differ +-- from the parent (provided the appropriate check constraint is present) +CREATE TABLE part_6 ( + c int, + LIKE list_parted2, + CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 6) +); +ALTER TABLE part_6 DROP c; +ALTER TABLE list_parted2 ATTACH PARTITION part_6 FOR VALUES IN (6); + -- check that the table being attached is not already a partition ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2);