From: Masahiko Sawada Date: Thu, 14 May 2026 17:32:34 +0000 (-0700) Subject: Fix attribute mapping for COPY TO on partitioned tables. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=82f0135a2630cc4465a8a424e38faf0f4e92f421;p=thirdparty%2Fpostgresql.git Fix attribute mapping for COPY TO on partitioned tables. Commit 4bea91f21f61 enabled COPY TO on a partitioned table to read tuples from its partitions and mapped them to the root table's tuple descriptor before output. However, it incorrectly built the attribute map from the root table to the partition. This commit fixes by building the attribute map from the partition to the root table, ensuring that partition attributes are correctly mapped to their corresponding root attributes. Author: Chao Li Reviewed-by: Fujii Masao Reviewed-by: Masahiko Sawada Discussion: https://postgr.es/m/85EA70F3-C3DB-477B-B856-EA569FDAAE7C@gmail.com --- diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c index 1085d0d5b8d..ffed63a2986 100644 --- a/src/backend/commands/copyto.c +++ b/src/backend/commands/copyto.c @@ -1348,8 +1348,8 @@ CopyRelationTo(CopyToState cstate, Relation rel, Relation root_rel, uint64 *proc if (root_rel != NULL) { root_slot = table_slot_create(root_rel, NULL); - map = build_attrmap_by_name_if_req(RelationGetDescr(root_rel), - RelationGetDescr(rel), + map = build_attrmap_by_name_if_req(RelationGetDescr(rel), + RelationGetDescr(root_rel), false); } diff --git a/src/test/regress/expected/copy.out b/src/test/regress/expected/copy.out index 1714faab39c..37498cdd6e7 100644 --- a/src/test/regress/expected/copy.out +++ b/src/test/regress/expected/copy.out @@ -594,3 +594,14 @@ id val 5 15 6 16 DROP TABLE PP; +-- Check if COPY TO handles dropped columns in partitions. +CREATE TABLE pp_dropcol (id int, val int) PARTITION BY RANGE (id); +CREATE TABLE pp_dropcol_1 (dropme int, id int, val int); +ALTER TABLE pp_dropcol_1 DROP COLUMN dropme; +ALTER TABLE pp_dropcol ATTACH PARTITION pp_dropcol_1 FOR VALUES FROM (1) TO (10); +INSERT INTO pp_dropcol VALUES (1, 11), (2, 12); +COPY pp_dropcol TO stdout(header); +id val +1 11 +2 12 +DROP TABLE pp_dropcol; diff --git a/src/test/regress/sql/copy.sql b/src/test/regress/sql/copy.sql index eaad290b257..094fd76c12b 100644 --- a/src/test/regress/sql/copy.sql +++ b/src/test/regress/sql/copy.sql @@ -535,3 +535,12 @@ CREATE TABLE pp_510 PARTITION OF pp_2 FOR VALUES FROM (5) TO (10); INSERT INTO pp SELECT g, 10 + g FROM generate_series(1,6) g; COPY pp TO stdout(header); DROP TABLE PP; + +-- Check if COPY TO handles dropped columns in partitions. +CREATE TABLE pp_dropcol (id int, val int) PARTITION BY RANGE (id); +CREATE TABLE pp_dropcol_1 (dropme int, id int, val int); +ALTER TABLE pp_dropcol_1 DROP COLUMN dropme; +ALTER TABLE pp_dropcol ATTACH PARTITION pp_dropcol_1 FOR VALUES FROM (1) TO (10); +INSERT INTO pp_dropcol VALUES (1, 11), (2, 12); +COPY pp_dropcol TO stdout(header); +DROP TABLE pp_dropcol;