!1969 issue处理:ignore关键字在指定分区/二级分区插入,且插入分区键超出分区范围时,无法将error降级为warning问题修复

Merge pull request !1969 from zhangzhixian/master
This commit is contained in:
opengauss-bot
2022-07-29 03:11:31 +00:00
committed by Gitee
3 changed files with 114 additions and 7 deletions

View File

@ -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);

View File

@ -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

View File

@ -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