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>.
|
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
|
The indexes and identity are created later, after moving the data
|
||||||
into the new partitions.
|
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
|
If the parent table is persistent then new partitions are created
|
||||||
persistent. If the parent table is temporary then new partitions
|
persistent. If the parent table is temporary then new partitions
|
||||||
are also created temporary.
|
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>.
|
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
|
The indexes and identity are created later, after moving the data
|
||||||
into the new partition.
|
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
|
If the parent table is persistent then the new partition is created
|
||||||
persistent. If the parent table is temporary then the new partition
|
persistent. If the parent table is temporary then the new partition
|
||||||
is also created temporary.
|
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>
|
* Emulates command: CREATE [TEMP] TABLE <newPartName> (LIKE <modelRel's name>
|
||||||
* INCLUDING ALL EXCLUDING INDEXES EXCLUDING IDENTITY)
|
* 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).
|
* Function returns the created relation (locked in AccessExclusiveLock mode).
|
||||||
*/
|
*/
|
||||||
static Relation
|
static Relation
|
||||||
|
@ -21243,6 +21248,7 @@ createPartitionTable(RangeVar *newPartName, Relation modelRel,
|
||||||
createStmt->oncommit = ONCOMMIT_NOOP;
|
createStmt->oncommit = ONCOMMIT_NOOP;
|
||||||
createStmt->tablespacename = NULL;
|
createStmt->tablespacename = NULL;
|
||||||
createStmt->if_not_exists = false;
|
createStmt->if_not_exists = false;
|
||||||
|
createStmt->accessMethod = get_am_name(modelRel->rd_rel->relam);
|
||||||
|
|
||||||
tlc = makeNode(TableLikeClause);
|
tlc = makeNode(TableLikeClause);
|
||||||
tlc->relation = makeRangeVar(get_namespace_name(RelationGetNamespace(modelRel)),
|
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
|
-- Can't merge temporary partitions into a persistent partition
|
||||||
ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
|
ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
|
||||||
ROLLBACK;
|
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;
|
RESET search_path;
|
||||||
--
|
--
|
||||||
DROP SCHEMA partitions_merge_schema;
|
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_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
|
||||||
PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-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
|
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"
|
-- 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
|
ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
|
||||||
(PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
|
(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)
|
(2 rows)
|
||||||
|
|
||||||
DROP TABLE t;
|
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_schema;
|
||||||
DROP SCHEMA partition_split_schema2;
|
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;
|
ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
|
||||||
ROLLBACK;
|
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;
|
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;
|
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_schema;
|
||||||
DROP SCHEMA partition_split_schema2;
|
DROP SCHEMA partition_split_schema2;
|
||||||
|
|
Loading…
Reference in a new issue