From cc6be115f19f8fea706e82e7effcf77f2852aaca Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
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 <jian.universality@gmail.com>
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
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

