From 674ded743b26d2cdb3a3e4586cdc70fd9b6f1c30 Mon Sep 17 00:00:00 2001 From: teooooozhang Date: Mon, 25 Jul 2022 14:55:48 +0800 Subject: [PATCH] issue fix for I5HSHT --- .../runtime/executor/nodeModifyTable.cpp | 33 +++++++++--- .../ignore/ignore_no_matched_partition.out | 54 +++++++++++++++++++ .../ignore/ignore_no_matched_partition.sql | 34 ++++++++++++ 3 files changed, 114 insertions(+), 7 deletions(-) diff --git a/src/gausskernel/runtime/executor/nodeModifyTable.cpp b/src/gausskernel/runtime/executor/nodeModifyTable.cpp index 59f1772b1..943b4ff85 100644 --- a/src/gausskernel/runtime/executor/nodeModifyTable.cpp +++ b/src/gausskernel/runtime/executor/nodeModifyTable.cpp @@ -551,22 +551,29 @@ static inline void ReleaseResourcesForUpsertGPI(bool isgpi, Relation parentRel, } } -void CheckPartitionOidForSpecifiedPartition(RangeTblEntry *rte, Oid partitionid) +bool CheckPartitionOidForSpecifiedPartition(RangeTblEntry *rte, Oid partitionid, bool canIgnore = false) { + int level = canIgnore ? WARNING : ERROR; if (rte->isContainPartition && rte->partitionOid != partitionid) { - ereport(ERROR, (errcode(ERRCODE_NO_DATA_FOUND), + ereport(level, (errcode(ERRCODE_NO_DATA_FOUND), (errmsg("inserted partition key does not map to the table partition"), errdetail("N/A."), errcause("The value is incorrect."), erraction("Use the correct value.")))); + return false; } + return true; } -void CheckSubpartitionOidForSpecifiedSubpartition(RangeTblEntry *rte, Oid partitionid, Oid subPartitionId) +bool CheckSubpartitionOidForSpecifiedSubpartition(RangeTblEntry *rte, Oid partitionid, Oid subPartitionId, + bool canIgnore = false) { + int level = canIgnore ? WARNING : ERROR; if (rte->isContainSubPartition && (rte->partitionOid != partitionid || rte->subpartitionOid != subPartitionId)) { - ereport(ERROR, (errcode(ERRCODE_NO_DATA_FOUND), + ereport(level, (errcode(ERRCODE_NO_DATA_FOUND), (errmsg("inserted subpartition key does not map to the table subpartition"), errdetail("N/A."), errcause("The value is incorrect."), erraction("Use the correct value.")))); + return false; } + return true; } static void ReportErrorForSpecifiedPartitionOfUpsert(char *partition, char *table) @@ -1125,7 +1132,11 @@ TupleTableSlot* ExecInsertT(ModifyTableState* state, TupleTableSlot* slot, Tuple if (estate->es_plannedstmt->hasIgnore && partition_id == InvalidOid) { return NULL; } - CheckPartitionOidForSpecifiedPartition(rte, partition_id); + bool partitionCheckPassed = CheckPartitionOidForSpecifiedPartition( + rte, partition_id, estate->es_plannedstmt->hasIgnore); + if (!partitionCheckPassed) { + return NULL; + } searchFakeReationForPartitionOid(estate->esfRelations, estate->es_query_cxt, result_relation_desc, partition_id, heap_rel, partition, RowExclusiveLock); @@ -1175,7 +1186,11 @@ TupleTableSlot* ExecInsertT(ModifyTableState* state, TupleTableSlot* slot, Tuple if (estate->es_plannedstmt->hasIgnore && partitionId == InvalidOid) { return NULL; } - CheckPartitionOidForSpecifiedPartition(rte, partitionId); + bool partitionCheckPassed = + CheckPartitionOidForSpecifiedPartition(rte, partitionId, estate->es_plannedstmt->hasIgnore); + if (!partitionCheckPassed) { + return NULL; + } searchFakeReationForPartitionOid(estate->esfRelations, estate->es_query_cxt, result_relation_desc, partitionId, partRel, part, @@ -1186,7 +1201,11 @@ TupleTableSlot* ExecInsertT(ModifyTableState* state, TupleTableSlot* slot, Tuple if (estate->es_plannedstmt->hasIgnore && subPartitionId == InvalidOid) { return NULL; } - CheckSubpartitionOidForSpecifiedSubpartition(rte, partitionId, subPartitionId); + bool subpartitionCheckPassed = CheckSubpartitionOidForSpecifiedSubpartition( + rte, partitionId, subPartitionId, estate->es_plannedstmt->hasIgnore); + if (!subpartitionCheckPassed) { + return NULL; + } searchFakeReationForPartitionOid(estate->esfRelations, estate->es_query_cxt, partRel, subPartitionId, subPartRel, subPart, RowExclusiveLock); diff --git a/src/test/regress/expected/ignore/ignore_no_matched_partition.out b/src/test/regress/expected/ignore/ignore_no_matched_partition.out index f31207504..fd2b12c57 100644 --- a/src/test/regress/expected/ignore/ignore_no_matched_partition.out +++ b/src/test/regress/expected/ignore/ignore_no_matched_partition.out @@ -173,6 +173,60 @@ select * from ignore_range_range; 201901 | 1 | 1 | 1 (1 row) +drop table if exists t_specified_partition; +NOTICE: table "t_specified_partition" does not exist, skipping +-- test for table with specified partition/subpartition provided +create table t_specified_partition( + month_code VARCHAR2(30) primary key, + dept_code VARCHAR2(30) NOT NULL, + user_no VARCHAR2(30) NOT NULL, + sales_amt int +) +PARTITION BY RANGE(month_code) SUBPARTITION BY LIST(dept_code) +( + PARTITION p_201901 VALUES LESS THAN('201906') + ( + SUBPARTITION p_201901_a values('1'), + SUBPARTITION p_201901_b values('2') + ), + PARTITION p_201902 VALUES LESS THAN('201910') + ( + SUBPARTITION p_201902_a values('1'), + SUBPARTITION p_201902_b values('2') + ) +); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_specified_partition_pkey" for table "t_specified_partition" +set enable_opfusion = on; +set enable_partition_opfusion = on; +insert /*+ ignore_error */ into t_specified_partition partition(p_201901) values('201906', '1', '1', 1); +WARNING: inserted partition key does not map to the table partition +DETAIL: N/A. +insert /*+ ignore_error */ into t_specified_partition subpartition(p_201901_a) values('201905', '2', '1', 1); +WARNING: inserted subpartition key does not map to the table subpartition +DETAIL: N/A. +insert /*+ ignore_error */ into t_specified_partition partition(p_201901) values('201904', '1', '1', 1); +select * from t_specified_partition; + month_code | dept_code | user_no | sales_amt +------------+-----------+---------+----------- + 201904 | 1 | 1 | 1 +(1 row) + +set enable_opfusion = off; +set enable_partition_opfusion = off; +insert /*+ ignore_error */ into t_specified_partition partition(p_201901) values('201906', '1', '1', 1); +WARNING: inserted partition key does not map to the table partition +DETAIL: N/A. +insert /*+ ignore_error */ into t_specified_partition subpartition(p_201901_a) values('201905', '2', '1', 1); +WARNING: inserted subpartition key does not map to the table subpartition +DETAIL: N/A. +insert /*+ ignore_error */ into t_specified_partition subpartition(p_201901_a) values('201903', '1', '1', 1); +select * from t_specified_partition; + month_code | dept_code | user_no | sales_amt +------------+-----------+---------+----------- + 201904 | 1 | 1 | 1 + 201903 | 1 | 1 | 1 +(2 rows) + -- test for ustore table drop table if exists t_ignore; CREATE TABLE t_ignore diff --git a/src/test/regress/sql/ignore/ignore_no_matched_partition.sql b/src/test/regress/sql/ignore/ignore_no_matched_partition.sql index 2fd2bb11a..a626de04e 100644 --- a/src/test/regress/sql/ignore/ignore_no_matched_partition.sql +++ b/src/test/regress/sql/ignore/ignore_no_matched_partition.sql @@ -86,6 +86,40 @@ select * from ignore_range_range; update /*+ ignore_error */ ignore_range_range set dept_code = '4' where dept_code = '1'; select * from ignore_range_range; +drop table if exists t_specified_partition; +-- test for table with specified partition/subpartition provided +create table t_specified_partition( + month_code VARCHAR2(30) primary key, + dept_code VARCHAR2(30) NOT NULL, + user_no VARCHAR2(30) NOT NULL, + sales_amt int +) +PARTITION BY RANGE(month_code) SUBPARTITION BY LIST(dept_code) +( + PARTITION p_201901 VALUES LESS THAN('201906') + ( + SUBPARTITION p_201901_a values('1'), + SUBPARTITION p_201901_b values('2') + ), + PARTITION p_201902 VALUES LESS THAN('201910') + ( + SUBPARTITION p_201902_a values('1'), + SUBPARTITION p_201902_b values('2') + ) +); +set enable_opfusion = on; +set enable_partition_opfusion = on; +insert /*+ ignore_error */ into t_specified_partition partition(p_201901) values('201906', '1', '1', 1); +insert /*+ ignore_error */ into t_specified_partition subpartition(p_201901_a) values('201905', '2', '1', 1); +insert /*+ ignore_error */ into t_specified_partition partition(p_201901) values('201904', '1', '1', 1); +select * from t_specified_partition; +set enable_opfusion = off; +set enable_partition_opfusion = off; +insert /*+ ignore_error */ into t_specified_partition partition(p_201901) values('201906', '1', '1', 1); +insert /*+ ignore_error */ into t_specified_partition subpartition(p_201901_a) values('201905', '2', '1', 1); +insert /*+ ignore_error */ into t_specified_partition subpartition(p_201901_a) values('201903', '1', '1', 1); +select * from t_specified_partition; + -- test for ustore table drop table if exists t_ignore; CREATE TABLE t_ignore