diff --git a/src/common/backend/catalog/heap.cpp b/src/common/backend/catalog/heap.cpp index d29d62d462273357b8eecfaefb094e092cf2b00e..150e121d2b75defff0d02473ce6d0fc5ddc6ed4b 100644 --- a/src/common/backend/catalog/heap.cpp +++ b/src/common/backend/catalog/heap.cpp @@ -7488,6 +7488,22 @@ int lookupHBucketid(oidvector *buckets, int low, int2 bktId) return -1; } +extern Datum ComputePartKeyExprTuple(Relation rel, EState *estate, TupleTableSlot *slot, Relation partRel, char* partExprKeyStr); +Oid getPartitionIdFromTuple(Relation rel, void *tuple, EState* estate, TupleTableSlot* slot, int *partitionno, bool isDDL, bool canIgnore) +{ + char* partExprKeyStr = NULL; + Oid targetOid = InvalidOid; + bool partExprKeyIsNull = PartExprKeyIsNull(rel, NULL, &partExprKeyStr); + if (partExprKeyIsNull) { + targetOid = heapTupleGetPartitionId(rel, tuple, partitionno, isDDL, canIgnore); + } else { + Datum newval = ComputePartKeyExprTuple(rel, estate, slot, NULL, partExprKeyStr); + targetOid = heapTupleGetPartitionId(rel, (void*)newval, partitionno, isDDL, canIgnore, false); + } + pfree_ext(partExprKeyStr); + return targetOid; +} + /* * @@GaussDB@@ * Target : data partition diff --git a/src/gausskernel/optimizer/commands/copy.cpp b/src/gausskernel/optimizer/commands/copy.cpp index d9094ebc43acbe13094b131dd9385d9ba4995228..aeb1fe5720f792cb155ebbae2db958529026be61 100644 --- a/src/gausskernel/optimizer/commands/copy.cpp +++ b/src/gausskernel/optimizer/commands/copy.cpp @@ -4834,7 +4834,7 @@ uint64 CopyFrom(CopyState cstate) if (RelationIsSubPartitioned(resultRelationDesc)) { targetOid = heapTupleGetSubPartitionId(resultRelationDesc, tuple); } else { - targetOid = heapTupleGetPartitionId(resultRelationDesc, tuple, NULL); + targetOid = getPartitionIdFromTuple(resultRelationDesc, tuple, estate, slot, NULL); } } else { targetOid = RelationGetRelid(resultRelationDesc); @@ -4887,7 +4887,7 @@ uint64 CopyFrom(CopyState cstate) if (RelationIsSubPartitioned(resultRelationDesc)) { targetPartOid = heapTupleGetSubPartitionId(resultRelationDesc, tuple); } else { - targetPartOid = heapTupleGetPartitionId(resultRelationDesc, tuple, NULL); + targetPartOid = getPartitionIdFromTuple(resultRelationDesc, tuple, estate, slot, NULL); } partitionList = list_append_unique_oid(partitionList, targetPartOid); } @@ -4900,7 +4900,7 @@ uint64 CopyFrom(CopyState cstate) if (isPartitionRel) { /* get partititon oid to insert the record */ int partitionno = INVALID_PARTITION_NO; - partitionid = heapTupleGetPartitionId(resultRelationDesc, tuple, &partitionno); + partitionid = getPartitionIdFromTuple(resultRelationDesc, tuple, estate, slot, &partitionno); searchFakeReationForPartitionOid(estate->esfRelations, estate->es_query_cxt, resultRelationDesc, @@ -4912,7 +4912,7 @@ uint64 CopyFrom(CopyState cstate) if (RelationIsSubPartitioned(resultRelationDesc)) { int subpartitionno = INVALID_PARTITION_NO; - partitionid = heapTupleGetPartitionId(heaprel, tuple, &subpartitionno); + partitionid = getPartitionIdFromTuple(heaprel, tuple, estate, slot, &subpartitionno); searchFakeReationForPartitionOid(estate->esfRelations, estate->es_query_cxt, heaprel, partitionid, subpartitionno, subPartRel, subPart, RowExclusiveLock); heaprel = subPartRel; diff --git a/src/gausskernel/runtime/opfusion/opfusion_insert.cpp b/src/gausskernel/runtime/opfusion/opfusion_insert.cpp index b560c0e2729a240a7973891de4bad31037e930ec..5ad238a07848fdf087606150bbc7e41c5a88d608 100644 --- a/src/gausskernel/runtime/opfusion/opfusion_insert.cpp +++ b/src/gausskernel/runtime/opfusion/opfusion_insert.cpp @@ -266,8 +266,8 @@ unsigned long InsertFusion::ExecInsert(Relation rel, ResultRelInfo* result_rel_i if (RELATION_IS_PARTITIONED(rel)) { m_c_local.m_estate->esfRelations = NULL; int partitionno = INVALID_PARTITION_NO; - partOid = - heapTupleGetPartitionId(rel, tuple, &partitionno, false, m_c_local.m_estate->es_plannedstmt->hasIgnore); + m_local.m_reslot->tts_tuple = tuple; + partOid = getPartitionIdFromTuple(rel, tuple, m_c_local.m_estate, m_local.m_reslot, &partitionno, false, m_c_local.m_estate->es_plannedstmt->hasIgnore); if (m_c_local.m_estate->es_plannedstmt->hasIgnore && partOid == InvalidOid) { ExecReleaseResource(tuple, m_local.m_reslot, result_rel_info, m_c_local.m_estate, bucket_rel, rel, part, partRel); diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 38db47865dec112325508f0f9d0c8f30ca248e87..bae80534daf0e8ed2f27b9c244d00e063a6e164d 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -173,6 +173,7 @@ extern void heapDropPartitionIndex(Relation parentIndex, Oid partIndexId); extern void addNewPartitionTuple(Relation pg_part_desc, Partition new_part_desc, PartitionTupleInfo *partTupleInfo); extern void heap_truncate_one_part(Relation rel , Oid partOid); +extern Oid getPartitionIdFromTuple(Relation rel, void *tuple, EState* estate, TupleTableSlot* slot, int *partitionno, bool isDDL = false, bool canIgnore = false); extern Oid heapTupleGetPartitionId(Relation rel, void *tuple, int *partitionno, bool isDDL = false, bool canIgnore = false, bool partExprKeyIsNull = true); extern Oid heapTupleGetSubPartitionId(Relation rel, void *tuple); diff --git a/src/test/regress/input/partition_expr_key.source b/src/test/regress/input/partition_expr_key.source index f0f6401eab38cec973bf7c29ab8757132508ddaa..e55b2923e5dfb3395dacef1af4b821224b853c7e 100644 --- a/src/test/regress/input/partition_expr_key.source +++ b/src/test/regress/input/partition_expr_key.source @@ -217,6 +217,23 @@ select * from b_bug_2 partition(p2); select * from b_bug_2 partition(p3); --test some bug fix +CREATE TABLE opfusion_part_table (a int) PARTITION BY RANGE (a+100) +(PARTITION p0 VALUES LESS THAN (200), + PARTITION p1 VALUES LESS THAN (2000), + PARTITION p2 VALUES LESS THAN (20000)); +set enable_opfusion to on; +set enable_partition_opfusion to on; +insert into opfusion_part_table values(99),(999),(9999); +copy opfusion_part_table from stdin; +888 +\. +select * from opfusion_part_table partition(p0); +select * from opfusion_part_table partition(p1); +select * from opfusion_part_table partition(p2); +reset enable_opfusion; +reset enable_partition_opfusion; +drop table opfusion_part_table; + create table subpart_range_add (col1 int, col2 int) partition by range( abs(col2) ) subpartition by hash( abs(col1) ) ( diff --git a/src/test/regress/output/partition_expr_key.source b/src/test/regress/output/partition_expr_key.source index cb4c0ff02654ea8e9d40497824b00090853ac37f..d961364a1e513979be101ddee16ba21d6f228522 100644 --- a/src/test/regress/output/partition_expr_key.source +++ b/src/test/regress/output/partition_expr_key.source @@ -605,6 +605,36 @@ select * from b_bug_2 partition(p3); (1 row) --test some bug fix +CREATE TABLE opfusion_part_table (a int) PARTITION BY RANGE (a+100) +(PARTITION p0 VALUES LESS THAN (200), + PARTITION p1 VALUES LESS THAN (2000), + PARTITION p2 VALUES LESS THAN (20000)); +set enable_opfusion to on; +set enable_partition_opfusion to on; +insert into opfusion_part_table values(99),(999),(9999); +copy opfusion_part_table from stdin; +select * from opfusion_part_table partition(p0); + a +---- + 99 +(1 row) + +select * from opfusion_part_table partition(p1); + a +----- + 999 + 888 +(2 rows) + +select * from opfusion_part_table partition(p2); + a +------ + 9999 +(1 row) + +reset enable_opfusion; +reset enable_partition_opfusion; +drop table opfusion_part_table; create table subpart_range_add (col1 int, col2 int) partition by range( abs(col2) ) subpartition by hash( abs(col1) ) (