Inherit parent's AM for partition MERGE/SPLIT operations
This commit makes new partitions created by ALTER TABLE ... SPLIT PARTITION and ALTER TABLE ... MERGE PARTITIONS commands inherit the paret table access method. Reported-by: Alexander Lakhin Discussion: https://postgr.es/m/84ada05b-be5c-473e-6d1c-ebe5dd21b190%40gmail.com Reviewed-by: Pavel Borisov
This commit is contained in:
parent
60ae37a8bc
commit
259c96fa8f
6 changed files with 74 additions and 2 deletions
|
@ -1158,6 +1158,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
|
|||
SQL command <literal>CREATE TABLE <replaceable class="parameter">partition_nameN</replaceable> (LIKE <replaceable class="parameter">name</replaceable> INCLUDING ALL EXCLUDING INDEXES EXCLUDING IDENTITY)</literal>.
|
||||
The indexes and identity are created later, after moving the data
|
||||
into the new partitions.
|
||||
New partitions will have the same table access method as the parent.
|
||||
If the parent table is persistent then new partitions are created
|
||||
persistent. If the parent table is temporary then new partitions
|
||||
are also created temporary.
|
||||
|
@ -1227,6 +1228,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
|
|||
SQL command <literal>CREATE TABLE <replaceable class="parameter">partition_name</replaceable> (LIKE <replaceable class="parameter">name</replaceable> INCLUDING ALL EXCLUDING INDEXES EXCLUDING IDENTITY)</literal>.
|
||||
The indexes and identity are created later, after moving the data
|
||||
into the new partition.
|
||||
The new partition will have the same table access method as the parent.
|
||||
If the parent table is persistent then the new partition is created
|
||||
persistent. If the parent table is temporary then the new partition
|
||||
is also created temporary.
|
||||
|
|
|
@ -21213,6 +21213,11 @@ moveSplitTableRows(Relation rel, Relation splitRel, List *partlist, List *newPar
|
|||
*
|
||||
* Emulates command: CREATE [TEMP] TABLE <newPartName> (LIKE <modelRel's name>
|
||||
* INCLUDING ALL EXCLUDING INDEXES EXCLUDING IDENTITY)
|
||||
*
|
||||
* Also, this function sets the new partition access method same as parent
|
||||
* table access methods (similarly to CREATE TABLE ... PARTITION OF). It
|
||||
* checks that parent and child tables have compatible persistence.
|
||||
*
|
||||
* Function returns the created relation (locked in AccessExclusiveLock mode).
|
||||
*/
|
||||
static Relation
|
||||
|
@ -21243,6 +21248,7 @@ createPartitionTable(RangeVar *newPartName, Relation modelRel,
|
|||
createStmt->oncommit = ONCOMMIT_NOOP;
|
||||
createStmt->tablespacename = NULL;
|
||||
createStmt->if_not_exists = false;
|
||||
createStmt->accessMethod = get_am_name(modelRel->rd_rel->relam);
|
||||
|
||||
tlc = makeNode(TableLikeClause);
|
||||
tlc->relation = makeRangeVar(get_namespace_name(RelationGetNamespace(modelRel)),
|
||||
|
|
|
@ -862,6 +862,24 @@ SET search_path = partitions_merge_schema, pg_temp, public;
|
|||
-- Can't merge temporary partitions into a persistent partition
|
||||
ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
|
||||
ROLLBACK;
|
||||
-- Check the new partition inherits parent's table access method
|
||||
SET search_path = partitions_merge_schema, public;
|
||||
CREATE ACCESS METHOD partitions_merge_heap TYPE TABLE HANDLER heap_tableam_handler;
|
||||
CREATE TABLE t (i int) PARTITION BY RANGE (i) USING partitions_merge_heap;
|
||||
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);
|
||||
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 IN ('t'::regclass, 'tp_0_2'::regclass);
|
||||
relname | amname
|
||||
---------+-----------------------
|
||||
tp_0_2 | partitions_merge_heap
|
||||
t | partitions_merge_heap
|
||||
(2 rows)
|
||||
|
||||
DROP TABLE t;
|
||||
DROP ACCESS METHOD partitions_merge_heap;
|
||||
RESET search_path;
|
||||
--
|
||||
DROP SCHEMA partitions_merge_schema;
|
||||
|
|
|
@ -85,8 +85,8 @@ ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
|
|||
PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
|
||||
PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-01'));
|
||||
ERROR: upper bound of partition "sales_apr2022" is greater than upper bound of split partition
|
||||
LINE 4: PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO...
|
||||
^
|
||||
LINE 4: ... sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-0...
|
||||
^
|
||||
-- ERROR: lower bound of partition "sales_mar2022" conflicts with upper bound of previous partition "sales_feb2022"
|
||||
ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
|
||||
(PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
|
||||
|
@ -1494,6 +1494,25 @@ SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
|
|||
(2 rows)
|
||||
|
||||
DROP TABLE t;
|
||||
-- Check new partitions inherits parent's table access method
|
||||
CREATE ACCESS METHOD partition_split_heap TYPE TABLE HANDLER heap_tableam_handler;
|
||||
CREATE TABLE t (i int) PARTITION BY RANGE (i) USING partition_split_heap;
|
||||
CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2);
|
||||
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 ('t'::regclass, 'tp_0_1'::regclass, 'tp_1_2'::regclass);
|
||||
relname | amname
|
||||
---------+----------------------
|
||||
t | partition_split_heap
|
||||
tp_0_1 | partition_split_heap
|
||||
tp_1_2 | partition_split_heap
|
||||
(3 rows)
|
||||
|
||||
DROP TABLE t;
|
||||
DROP ACCESS METHOD partition_split_heap;
|
||||
--
|
||||
DROP SCHEMA partition_split_schema;
|
||||
DROP SCHEMA partition_split_schema2;
|
||||
|
|
|
@ -535,6 +535,19 @@ SET search_path = partitions_merge_schema, pg_temp, public;
|
|||
ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
|
||||
ROLLBACK;
|
||||
|
||||
-- Check the new partition inherits parent's table access method
|
||||
SET search_path = partitions_merge_schema, public;
|
||||
CREATE ACCESS METHOD partitions_merge_heap TYPE TABLE HANDLER heap_tableam_handler;
|
||||
CREATE TABLE t (i int) PARTITION BY RANGE (i) USING partitions_merge_heap;
|
||||
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);
|
||||
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 IN ('t'::regclass, 'tp_0_2'::regclass);
|
||||
DROP TABLE t;
|
||||
DROP ACCESS METHOD partitions_merge_heap;
|
||||
|
||||
RESET search_path;
|
||||
|
||||
--
|
||||
|
|
|
@ -880,6 +880,20 @@ SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
|
|||
|
||||
DROP TABLE t;
|
||||
|
||||
-- Check new partitions inherits parent's table access method
|
||||
CREATE ACCESS METHOD partition_split_heap TYPE TABLE HANDLER heap_tableam_handler;
|
||||
CREATE TABLE t (i int) PARTITION BY RANGE (i) USING partition_split_heap;
|
||||
CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2);
|
||||
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 ('t'::regclass, 'tp_0_1'::regclass, 'tp_1_2'::regclass);
|
||||
DROP TABLE t;
|
||||
DROP ACCESS METHOD partition_split_heap;
|
||||
|
||||
|
||||
--
|
||||
DROP SCHEMA partition_split_schema;
|
||||
DROP SCHEMA partition_split_schema2;
|
||||
|
|
Loading…
Reference in a new issue