!1969 issue处理:ignore关键字在指定分区/二级分区插入,且插入分区键超出分区范围时,无法将error降级为warning问题修复
Merge pull request !1969 from zhangzhixian/master
This commit is contained in:
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user