diff --git a/src/common/backend/catalog/heap.cpp b/src/common/backend/catalog/heap.cpp index 2452e6fa7..38ecd1b3e 100644 --- a/src/common/backend/catalog/heap.cpp +++ b/src/common/backend/catalog/heap.cpp @@ -6230,7 +6230,7 @@ Datum GetPartBoundaryByTuple(Relation rel, HeapTuple tuple) return Timestamp2Boundarys(rel, Align2UpBoundary(value, partMap->intervalValue, boundaryTs)); } -Oid AddNewIntervalPartition(Relation rel, void* insertTuple) +Oid AddNewIntervalPartition(Relation rel, void* insertTuple, bool isDDL) { Relation pgPartRel = NULL; Oid newPartOid = InvalidOid; @@ -6327,7 +6327,13 @@ Oid AddNewIntervalPartition(Relation rel, void* insertTuple) */ CommandCounterIncrement(); - UpdatePgObjectChangecsn(RelationGetRelid(rel), rel->rd_rel->relkind); + /* + * If add interval partition in the DDL, do not need to change the csn + * because the scn has been changed in the DDL. + */ + if (!isDDL) { + UpdatePgObjectChangecsn(RelationGetRelid(rel), rel->rd_rel->relkind); + } return newPartOid; } @@ -7113,7 +7119,7 @@ int lookupHBucketid(oidvector *buckets, int low, int2 bktId) * Description : * Notes : */ -Oid heapTupleGetPartitionId(Relation rel, void *tuple) +Oid heapTupleGetPartitionId(Relation rel, void *tuple, bool isDDL) { Oid partitionid = InvalidOid; @@ -7140,7 +7146,7 @@ Oid heapTupleGetPartitionId(Relation rel, void *tuple) (errcode(ERRCODE_NO_DATA_FOUND), errmsg("inserted partition key does not map to any table partition"))); } break; case PART_AREA_INTERVAL: { - return AddNewIntervalPartition(rel, tuple); + return AddNewIntervalPartition(rel, tuple, isDDL); } break; case PART_AREA_LIST: { ereport(ERROR, diff --git a/src/gausskernel/optimizer/commands/tablecmds.cpp b/src/gausskernel/optimizer/commands/tablecmds.cpp index eebee65e2..b9fa817ab 100644 --- a/src/gausskernel/optimizer/commands/tablecmds.cpp +++ b/src/gausskernel/optimizer/commands/tablecmds.cpp @@ -23175,7 +23175,7 @@ static void checkValidationForExchangeTable(Relation partTableRel, Relation ordT int2 bucketId = InvalidBktId; // get right partition oid for the tuple - targetPartOid = heapTupleGetPartitionId(partTableRel, (HeapTuple) tuple); + targetPartOid = heapTupleGetPartitionId(partTableRel, (HeapTuple)tuple, true); searchFakeReationForPartitionOid( partRelHTAB, CurrentMemoryContext, partTableRel, targetPartOid, partRel, part, RowExclusiveLock); @@ -25099,11 +25099,11 @@ static void readTuplesAndInsertInternal(Relation tempTableRel, Relation partTabl /* tableam_tops_copy_tuple is not ready so we add UStore hack path */ copyTuple = tableam_tops_copy_tuple(tuple); - targetPartOid = heapTupleGetPartitionId(partTableRel, (void *)tuple); + targetPartOid = heapTupleGetPartitionId(partTableRel, (void *)tuple, true); searchFakeReationForPartitionOid( partRelHTAB, CurrentMemoryContext, partTableRel, targetPartOid, partRel, part, RowExclusiveLock); if (RelationIsSubPartitioned(partTableRel)) { - targetPartOid = heapTupleGetPartitionId(partRel, (void *)tuple); + targetPartOid = heapTupleGetPartitionId(partRel, (void *)tuple, true); searchFakeReationForPartitionOid(partRelHTAB, CurrentMemoryContext, partRel, targetPartOid, subPartRel, subPart, RowExclusiveLock); partRel = subPartRel; diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 2732efe40..6bc3d9258 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -165,7 +165,7 @@ extern void addNewPartitionTuple(Relation pg_part_desc, Partition new_part_desc, Datum interval, Datum maxValues, Datum transitionPoint, Datum reloptions); extern void heap_truncate_one_part(Relation rel , Oid partOid); -extern Oid heapTupleGetPartitionId(Relation rel, void *tuple); +extern Oid heapTupleGetPartitionId(Relation rel, void *tuple, bool isDDL = false); extern Oid heapTupleGetSubPartitionId(Relation rel, void *tuple); extern void heap_truncate(List *relids); extern void heap_truncate_one_rel(Relation rel); @@ -240,7 +240,7 @@ extern char* make_column_map(TupleDesc tuple_desc); */ extern bool* CheckPartkeyHasTimestampwithzone(Relation partTableRel, bool isForSubPartition = false); -extern Oid AddNewIntervalPartition(Relation rel, void* insertTuple); +extern Oid AddNewIntervalPartition(Relation rel, void* insertTuple, bool isDDL = false); extern int GetIndexKeyAttsByTuple(Relation relation, HeapTuple indexTuple); diff --git a/src/test/regress/expected/hw_partition_interval_exchange.out b/src/test/regress/expected/hw_partition_interval_exchange.out index 4de0545da..ecfa36185 100644 --- a/src/test/regress/expected/hw_partition_interval_exchange.out +++ b/src/test/regress/expected/hw_partition_interval_exchange.out @@ -215,3 +215,107 @@ select * from interval_normal_exchange where logdate > '2020-06-01' order by log (0 rows) drop table interval_normal_exchange; +drop table table_001; +ERROR: table "table_001" does not exist +create table table_001( + COL_1 smallint, + COL_2 char(5), + COL_3 int, + COL_4 date, + COL_5 boolean, + COL_6 nchar(5), + COL_7 float + ); +drop table partition_table_001; +ERROR: table "partition_table_001" does not exist +create table partition_table_001( + COL_1 smallint, + COL_2 char(5), + COL_3 int, + COL_4 date, + COL_5 boolean, + COL_6 nchar(5), + COL_7 float + ) + PARTITION BY RANGE (COL_4) + INTERVAL ('1 month') + ( + PARTITION partition_table_001_p1 VALUES LESS THAN ('2020-03-01'), + PARTITION partition_table_001_p2 VALUES LESS THAN ('2020-04-01'), + PARTITION partition_table_001_p3 VALUES LESS THAN ('2020-05-01') + ); +insert into partition_table_001 values (1,'aaa',1,'2020-02-23',true,'aaa',1.1); +insert into partition_table_001 values (2,'bbb',2,'2020-03-23',false,'bbb',2.2); +insert into partition_table_001 values (3,'ccc',3,'2020-04-23',true,'ccc',3.3); +insert into partition_table_001 values (4,'ddd',4,'2020-05-23',false,'ddd',4.4); +insert into partition_table_001 values (5,'eee',5,'2020-06-23',true,'eee',5.5); +insert into partition_table_001 values (6,'fff',6,'2020-07-23',false,'fff',6.6); +ALTER TABLE partition_table_001 EXCHANGE PARTITION (sys_p1) WITH TABLE table_001; +select * from table_001 order by 1; + col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | col_7 +-------+-------+-------+--------------------------+-------+-------+------- + 4 | ddd | 4 | Sat May 23 00:00:00 2020 | f | ddd | 4.4 +(1 row) + +select * from partition_table_001 order by 1; + col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | col_7 +-------+-------+-------+--------------------------+-------+-------+------- + 1 | aaa | 1 | Sun Feb 23 00:00:00 2020 | t | aaa | 1.1 + 2 | bbb | 2 | Mon Mar 23 00:00:00 2020 | f | bbb | 2.2 + 3 | ccc | 3 | Thu Apr 23 00:00:00 2020 | t | ccc | 3.3 + 5 | eee | 5 | Tue Jun 23 00:00:00 2020 | t | eee | 5.5 + 6 | fff | 6 | Thu Jul 23 00:00:00 2020 | f | fff | 6.6 +(5 rows) + +select relname, parttype, partstrategy, boundaries from pg_partition + where parentid = (select oid from pg_class where relname = 'partition_table_001') + order by relname; + relname | parttype | partstrategy | boundaries +------------------------+----------+--------------+------------------------------ + partition_table_001 | r | i | + partition_table_001_p1 | p | r | {2020-03-01} + partition_table_001_p2 | p | r | {2020-04-01} + partition_table_001_p3 | p | r | {2020-05-01} + sys_p1 | p | i | {"Mon Jun 01 00:00:00 2020"} + sys_p2 | p | i | {"Wed Jul 01 00:00:00 2020"} + sys_p3 | p | i | {"Sat Aug 01 00:00:00 2020"} +(7 rows) + +ALTER TABLE partition_table_001 EXCHANGE PARTITION (sys_p1) WITH TABLE table_001; +select * from table_001 order by 1; + col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | col_7 +-------+-------+-------+-------+-------+-------+------- +(0 rows) + +select * from partition_table_001 order by 1; + col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | col_7 +-------+-------+-------+--------------------------+-------+-------+------- + 1 | aaa | 1 | Sun Feb 23 00:00:00 2020 | t | aaa | 1.1 + 2 | bbb | 2 | Mon Mar 23 00:00:00 2020 | f | bbb | 2.2 + 3 | ccc | 3 | Thu Apr 23 00:00:00 2020 | t | ccc | 3.3 + 4 | ddd | 4 | Sat May 23 00:00:00 2020 | f | ddd | 4.4 + 5 | eee | 5 | Tue Jun 23 00:00:00 2020 | t | eee | 5.5 + 6 | fff | 6 | Thu Jul 23 00:00:00 2020 | f | fff | 6.6 +(6 rows) + +insert into table_001 values (7,'eee',7,'2020-08-23',true,'eee',7.7); +ALTER TABLE partition_table_001 EXCHANGE PARTITION (sys_p1) WITH TABLE table_001 with validation verbose; +select * from table_001 order by 1; + col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | col_7 +-------+-------+-------+--------------------------+-------+-------+------- + 4 | ddd | 4 | Sat May 23 00:00:00 2020 | f | ddd | 4.4 +(1 row) + +select * from partition_table_001 order by 1; + col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | col_7 +-------+-------+-------+--------------------------+-------+-------+------- + 1 | aaa | 1 | Sun Feb 23 00:00:00 2020 | t | aaa | 1.1 + 2 | bbb | 2 | Mon Mar 23 00:00:00 2020 | f | bbb | 2.2 + 3 | ccc | 3 | Thu Apr 23 00:00:00 2020 | t | ccc | 3.3 + 5 | eee | 5 | Tue Jun 23 00:00:00 2020 | t | eee | 5.5 + 6 | fff | 6 | Thu Jul 23 00:00:00 2020 | f | fff | 6.6 + 7 | eee | 7 | Sun Aug 23 00:00:00 2020 | t | eee | 7.7 +(6 rows) + +drop table table_001; +drop table partition_table_001; diff --git a/src/test/regress/sql/hw_partition_interval_exchange.sql b/src/test/regress/sql/hw_partition_interval_exchange.sql index f8c88c316..cdecd29e5 100644 --- a/src/test/regress/sql/hw_partition_interval_exchange.sql +++ b/src/test/regress/sql/hw_partition_interval_exchange.sql @@ -97,3 +97,61 @@ select * from interval_exchange_test order by logdate; select * from interval_normal_exchange order by logdate; select * from interval_normal_exchange where logdate > '2020-06-01' order by logdate; drop table interval_normal_exchange; + +drop table table_001; +create table table_001( + COL_1 smallint, + COL_2 char(5), + COL_3 int, + COL_4 date, + COL_5 boolean, + COL_6 nchar(5), + COL_7 float + ); + +drop table partition_table_001; +create table partition_table_001( + COL_1 smallint, + COL_2 char(5), + COL_3 int, + COL_4 date, + COL_5 boolean, + COL_6 nchar(5), + COL_7 float + ) + PARTITION BY RANGE (COL_4) + INTERVAL ('1 month') + ( + PARTITION partition_table_001_p1 VALUES LESS THAN ('2020-03-01'), + PARTITION partition_table_001_p2 VALUES LESS THAN ('2020-04-01'), + PARTITION partition_table_001_p3 VALUES LESS THAN ('2020-05-01') + ); + +insert into partition_table_001 values (1,'aaa',1,'2020-02-23',true,'aaa',1.1); +insert into partition_table_001 values (2,'bbb',2,'2020-03-23',false,'bbb',2.2); +insert into partition_table_001 values (3,'ccc',3,'2020-04-23',true,'ccc',3.3); +insert into partition_table_001 values (4,'ddd',4,'2020-05-23',false,'ddd',4.4); +insert into partition_table_001 values (5,'eee',5,'2020-06-23',true,'eee',5.5); +insert into partition_table_001 values (6,'fff',6,'2020-07-23',false,'fff',6.6); + +ALTER TABLE partition_table_001 EXCHANGE PARTITION (sys_p1) WITH TABLE table_001; +select * from table_001 order by 1; +select * from partition_table_001 order by 1; + +select relname, parttype, partstrategy, boundaries from pg_partition + where parentid = (select oid from pg_class where relname = 'partition_table_001') + order by relname; + +ALTER TABLE partition_table_001 EXCHANGE PARTITION (sys_p1) WITH TABLE table_001; +select * from table_001 order by 1; +select * from partition_table_001 order by 1; + +insert into table_001 values (7,'eee',7,'2020-08-23',true,'eee',7.7); + +ALTER TABLE partition_table_001 EXCHANGE PARTITION (sys_p1) WITH TABLE table_001 with validation verbose; + +select * from table_001 order by 1; +select * from partition_table_001 order by 1; + +drop table table_001; +drop table partition_table_001;