From cc6be115f19f8fea706e82e7effcf77f2852aaca Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Thu, 20 Aug 2026 14:33:33 +0300 Subject: [PATCH v6 5/5] Use default_table_access_method for MERGE/SPLIT PARTITION When the partitioned table has no access method of its own, the partitions created by ALTER TABLE ... MERGE/SPLIT PARTITION were given heap rather than the access method CREATE TABLE ... PARTITION OF would have picked. Both should follow default_table_access_method in that case; an access method on the partitioned table still wins, as before. Author: jian he Reviewed-by: Alexander Korotkov Discussion: https://postgr.es/m/CACJufxG0Kqu2Qnei_xZ%2BDsQVohX95eO9FRNB9ncKOmOPFsFF-A%40mail.gmail.com --- src/backend/commands/tablecmds.c | 5 ++++- src/test/regress/expected/partition_merge.out | 19 ++++++++++++++++ src/test/regress/expected/partition_split.out | 22 +++++++++++++++++++ src/test/regress/sql/partition_merge.sql | 15 +++++++++++++ src/test/regress/sql/partition_split.sql | 17 ++++++++++++++ 5 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index b9dd714bedd..fca524fcf7e 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 02488636519..bc4963b06c3 100644 --- a/src/test/regress/expected/partition_merge.out +++ b/src/test/regress/expected/partition_merge.out @@ -791,6 +791,25 @@ ORDER BY c.relname COLLATE "C"; tp_0_2 | partitions_merge_heap (2 rows) +DROP TABLE t; +-- With no access method on the partitioned table, the new partition falls +-- back to default_table_access_method, just as CREATE TABLE ... PARTITION OF +-- would. +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 = 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 JOIN pg_am a ON c.relam = a.oid +WHERE c.oid = 'tp_0_2'::regclass; + 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 e0f2774c38f..49e63d66aef 100644 --- a/src/test/regress/expected/partition_split.out +++ b/src/test/regress/expected/partition_split.out @@ -1355,6 +1355,28 @@ ORDER BY c.relname COLLATE "C"; tp_1_2 | partition_split_heap (3 rows) +DROP TABLE t; +-- With no access method on the partitioned table, the new partitions fall +-- back to default_table_access_method, just as CREATE TABLE ... PARTITION OF +-- would. +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 = 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 JOIN pg_am a ON c.relam = a.oid +WHERE c.oid IN ('tp_0_1'::regclass, 'tp_1_2'::regclass) +ORDER BY c.relname COLLATE "C"; + 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..558f5a12a86 100644 --- a/src/test/regress/sql/partition_merge.sql +++ b/src/test/regress/sql/partition_merge.sql @@ -550,6 +550,21 @@ 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; + +-- With no access method on the partitioned table, the new partition falls +-- back to default_table_access_method, just as CREATE TABLE ... PARTITION OF +-- would. +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 = 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 JOIN pg_am a ON c.relam = a.oid +WHERE c.oid = 'tp_0_2'::regclass; +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 89c63bac890..e255cff077c 100644 --- a/src/test/regress/sql/partition_split.sql +++ b/src/test/regress/sql/partition_split.sql @@ -970,6 +970,23 @@ 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; + +-- With no access method on the partitioned table, the new partitions fall +-- back to default_table_access_method, just as CREATE TABLE ... PARTITION OF +-- would. +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 = 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 JOIN pg_am a ON c.relam = a.oid +WHERE c.oid IN ('tp_0_1'::regclass, 'tp_1_2'::regclass) +ORDER BY c.relname COLLATE "C"; +COMMIT; +DROP TABLE t; DROP ACCESS METHOD partition_split_heap; -- Split partition of a temporary table when one of the partitions after -- 2.55.0