hi. while reviewing disallow generated column as partition key in [1], I found out this bug.
demo: drop table if exists t4; CREATE TABLE t4(f1 int, f2 bigint) PARTITION BY list ((t4)); create table t4_1 partition of t4 for values in ((1,2)); alter table t4 alter column f2 set data type text using f2; insert into t4 select 1, '2'; ERROR: invalid memory alloc request size 18446744073709551615 turns out the fix seems pretty simple, mainly on has_partition_attrs. has_partition_attrs is used to Checks if any of the 'attnums' is a partition key attribute for rel. if partition keys have column references, then has_partition_attrs should return true. [1]: https://postgr.es/m/CACJufxF=wdgthxsaqr9thyusfx_1_t9e6n8te3b8eqxcvov...@mail.gmail.com
From 7a4c9bc1cb65c3aedc92a4bf31352ba19f1135b9 Mon Sep 17 00:00:00 2001 From: jian he <jian.universal...@gmail.com> Date: Tue, 22 Apr 2025 19:37:24 +0800 Subject: [PATCH v1 1/1] fix wholerow as partition key reference. If the partition key contains wholerow reference, individual columns cannot be altered. discussion: https://postgr.es/m/ --- src/backend/catalog/partition.c | 12 ++++++++++++ src/test/regress/expected/alter_table.out | 14 ++++++++++++++ src/test/regress/sql/alter_table.sql | 7 +++++++ 3 files changed, 33 insertions(+) diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c index 93d72157a46..e0ae3d2abe1 100644 --- a/src/backend/catalog/partition.c +++ b/src/backend/catalog/partition.c @@ -290,6 +290,18 @@ has_partition_attrs(Relation rel, Bitmapset *attnums, bool *used_in_expr) /* Find all attributes referenced */ pull_varattnos(expr, 1, &expr_attrs); + + /* + * If this is a wholerow reference, then assume unconditionally that + * 'attnums' is included as part of the partition key attributes. + */ + if (bms_is_member(0 - FirstLowInvalidHeapAttributeNumber, expr_attrs)) + { + if (used_in_expr) + *used_in_expr = true; + return true; + } + partexprs_item = lnext(partexprs, partexprs_item); if (bms_overlap(attnums, expr_attrs)) diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 476266e3f4b..fef20e5ae7c 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -3984,6 +3984,20 @@ LINE 1: ALTER TABLE partitioned ALTER COLUMN b TYPE char(5); ALTER TABLE partitioned SET (fillfactor=100); ERROR: cannot specify storage parameters for a partitioned table HINT: Specify storage parameters for its leaf partitions instead. +-- partition expression is whole row +CREATE TABLE partitioned1(a int, b int) PARTITION BY list((partitioned1)); +ALTER TABLE partitioned1 DROP COLUMN a; --error +ERROR: cannot drop column "a" because it is part of the partition key of relation "partitioned1" +ALTER TABLE partitioned1 DROP COLUMN b; --error +ERROR: cannot drop column "b" because it is part of the partition key of relation "partitioned1" +ALTER TABLE partitioned1 ALTER COLUMN a TYPE text; --error +ERROR: cannot alter column "a" because it is part of the partition key of relation "partitioned1" +LINE 1: ALTER TABLE partitioned1 ALTER COLUMN a TYPE text; + ^ +ALTER TABLE partitioned1 ALTER COLUMN b TYPE text; --error +ERROR: cannot alter column "b" because it is part of the partition key of relation "partitioned1" +LINE 1: ALTER TABLE partitioned1 ALTER COLUMN b TYPE text; + ^ -- partitioned table cannot participate in regular inheritance CREATE TABLE nonpartitioned ( a int, diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index 5ce9d1e429f..f5745f448ae 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -2390,6 +2390,13 @@ ALTER TABLE partitioned ALTER COLUMN b TYPE char(5); -- specifying storage parameters for partitioned tables is not supported ALTER TABLE partitioned SET (fillfactor=100); +-- partition expression is whole row +CREATE TABLE partitioned1(a int, b int) PARTITION BY list((partitioned1)); +ALTER TABLE partitioned1 DROP COLUMN a; --error +ALTER TABLE partitioned1 DROP COLUMN b; --error +ALTER TABLE partitioned1 ALTER COLUMN a TYPE text; --error +ALTER TABLE partitioned1 ALTER COLUMN b TYPE text; --error + -- partitioned table cannot participate in regular inheritance CREATE TABLE nonpartitioned ( a int, -- 2.34.1