From 40b78f838af24970bb51674de1783a1ebb9cbd17 Mon Sep 17 00:00:00 2001 From: jian he Date: Thu, 20 Aug 2026 15:15:00 +0800 Subject: [PATCH v6 1/1] Fix access method for new partition tables If the partitioned table has a valid table access method, newly created partitions for MERGE/SPLIT PARTITIONS use the parent table's access method. Otherwise, fall back to default_table_access_method. --- src/backend/commands/tablecmds.c | 5 ++++- src/test/regress/expected/partition_merge.out | 15 +++++++++++++++ src/test/regress/expected/partition_split.out | 18 ++++++++++++++++++ src/test/regress/sql/partition_merge.sql | 11 +++++++++++ src/test/regress/sql/partition_split.sql | 12 ++++++++++++ 5 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 1840738f3f4..4371694ed8d 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -23334,7 +23334,10 @@ createPartitionTable(RangeVar *newPartName, descriptor = BuildDescForRelation(colList); /* Look up the access method for the new relation. */ - relamId = (parent_relform->relam != InvalidOid) ? parent_relform->relam : HEAP_TABLE_AM_OID; + if (OidIsValid(parent_relform->relam)) + relamId = parent_relform->relam; + else + relamId = get_table_am_oid(default_table_access_method, false); /* Look up the namespace in which we are supposed to create the relation. */ namespaceId = diff --git a/src/test/regress/expected/partition_merge.out b/src/test/regress/expected/partition_merge.out index 7e1aac3b44d..d16a898e6c0 100644 --- a/src/test/regress/expected/partition_merge.out +++ b/src/test/regress/expected/partition_merge.out @@ -791,6 +791,21 @@ ORDER BY c.relname COLLATE "C"; tp_0_2 | partitions_merge_heap (2 rows) +DROP TABLE t; +CREATE TABLE t (i int) PARTITION BY RANGE (i); +CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); +CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); +BEGIN; +SET LOCAL default_table_access_method to partitions_merge_heap; +ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; +SELECT c.relname, a.amname FROM pg_class c, pg_am a +WHERE c.relname = 'tp_0_2' AND a.oid = c.relam; + relname | amname +---------+----------------------- + tp_0_2 | partitions_merge_heap +(1 row) + +COMMIT; DROP TABLE t; DROP ACCESS METHOD partitions_merge_heap; -- Test permission checks. The user needs to own the parent table and all diff --git a/src/test/regress/expected/partition_split.out b/src/test/regress/expected/partition_split.out index 98575e00119..8780d19f90a 100644 --- a/src/test/regress/expected/partition_split.out +++ b/src/test/regress/expected/partition_split.out @@ -1355,6 +1355,24 @@ ORDER BY c.relname COLLATE "C"; tp_1_2 | partition_split_heap (3 rows) +DROP TABLE t; +CREATE TABLE t (i int) PARTITION BY RANGE (i); +CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2); +BEGIN; +SET LOCAL default_table_access_method to partition_split_heap; +ALTER TABLE t SPLIT PARTITION tp_0_2 INTO + (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), + PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); +SELECT c.relname, a.amname FROM pg_class c, pg_am a +WHERE c.relname IN ('tp_0_1', 'tp_1_2') +AND a.oid = c.relam; + relname | amname +---------+---------------------- + tp_0_1 | partition_split_heap + tp_1_2 | partition_split_heap +(2 rows) + +COMMIT; DROP TABLE t; DROP ACCESS METHOD partition_split_heap; -- Split partition of a temporary table when one of the partitions after diff --git a/src/test/regress/sql/partition_merge.sql b/src/test/regress/sql/partition_merge.sql index 0fcda645147..11550a00be8 100644 --- a/src/test/regress/sql/partition_merge.sql +++ b/src/test/regress/sql/partition_merge.sql @@ -550,6 +550,17 @@ FROM pg_class c JOIN pg_am a ON c.relam = a.oid WHERE c.oid IN ('t'::regclass, 'tp_0_2'::regclass) ORDER BY c.relname COLLATE "C"; DROP TABLE t; + +CREATE TABLE t (i int) PARTITION BY RANGE (i); +CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); +CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); +BEGIN; +SET LOCAL default_table_access_method to partitions_merge_heap; +ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; +SELECT c.relname, a.amname FROM pg_class c, pg_am a +WHERE c.relname = 'tp_0_2' AND a.oid = c.relam; +COMMIT; +DROP TABLE t; DROP ACCESS METHOD partitions_merge_heap; -- Test permission checks. The user needs to own the parent table and all diff --git a/src/test/regress/sql/partition_split.sql b/src/test/regress/sql/partition_split.sql index e97f13f749c..b734d69ba68 100644 --- a/src/test/regress/sql/partition_split.sql +++ b/src/test/regress/sql/partition_split.sql @@ -970,6 +970,18 @@ FROM pg_class c JOIN pg_am a ON c.relam = a.oid WHERE c.oid IN ('t'::regclass, 'tp_0_1'::regclass, 'tp_1_2'::regclass) ORDER BY c.relname COLLATE "C"; DROP TABLE t; +CREATE TABLE t (i int) PARTITION BY RANGE (i); +CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2); +BEGIN; +SET LOCAL default_table_access_method to partition_split_heap; +ALTER TABLE t SPLIT PARTITION tp_0_2 INTO + (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), + PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); +SELECT c.relname, a.amname FROM pg_class c, pg_am a +WHERE c.relname IN ('tp_0_1', 'tp_1_2') +AND a.oid = c.relam; +COMMIT; +DROP TABLE t; DROP ACCESS METHOD partition_split_heap; -- Split partition of a temporary table when one of the partitions after -- 2.34.1