issue修复:ignore在向主键列插入null时资源泄漏修复

This commit is contained in:
teooooozhang
2023-01-11 14:46:41 +08:00
parent e7ff8013f6
commit 9e6b14bd1c
4 changed files with 56 additions and 31 deletions

View File

@ -246,6 +246,23 @@ Datum ComputePartKeyExprTuple(Relation rel, EState *estate, TupleTableSlot *slot
return val;
}
static void ExecReleaseResource(Tuple tuple, TupleTableSlot *slot, ResultRelInfo *result_rel_info, EState *estate,
Relation bucket_rel, Relation rel, Partition part, Relation partRel)
{
tableam_tops_free_tuple(tuple);
(void)ExecClearTuple(slot);
ExecCloseIndices(result_rel_info);
ExecDoneStepInFusion(estate);
if (bucket_rel != NULL) {
bucketCloseRelation(bucket_rel);
}
if (RELATION_IS_PARTITIONED(rel) && part != NULL) {
partitionClose(rel, part, RowExclusiveLock);
releaseDummyRelation(&partRel);
}
}
unsigned long InsertFusion::ExecInsert(Relation rel, ResultRelInfo* result_rel_info)
{
/*******************
@ -270,6 +287,8 @@ unsigned long InsertFusion::ExecInsert(Relation rel, ResultRelInfo* result_rel_i
m_c_local.m_estate->esfRelations = NULL;
partOid = heapTupleGetPartitionId(rel, tuple, 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);
return 0;
}
part = partitionOpen(rel, partOid, RowExclusiveLock);
@ -301,6 +320,8 @@ unsigned long InsertFusion::ExecInsert(Relation rel, ResultRelInfo* result_rel_i
*/
if(!ExecConstraints(result_rel_info, m_local.m_reslot, m_c_local.m_estate, true)) {
if (u_sess->utils_cxt.sql_ignore_strategy_val != SQL_OVERWRITE_NULL) {
ExecReleaseResource(tuple, m_local.m_reslot, result_rel_info, m_c_local.m_estate, bucket_rel, rel, part,
partRel);
return 0;
}
tuple = ReplaceTupleNullCol(RelationGetDescr(result_rel_info->ri_RelationDesc), m_local.m_reslot);
@ -336,20 +357,8 @@ unsigned long InsertFusion::ExecInsert(Relation rel, ResultRelInfo* result_rel_i
&conflictInfo, &conflictPartOid, &conflictBucketid)) {
ereport(WARNING, (errmsg("duplicate key value violates unique constraint in table \"%s\"",
RelationGetRelationName(target_rel))));
/* clear before ended */
tableam_tops_free_tuple(tuple);
(void)ExecClearTuple(m_local.m_reslot);
ExecCloseIndices(result_rel_info);
ExecDoneStepInFusion(m_c_local.m_estate);
if (bucket_rel != NULL) {
bucketCloseRelation(bucket_rel);
}
if (RELATION_IS_PARTITIONED(rel)) {
partitionClose(rel, part, RowExclusiveLock);
releaseDummyRelation(&partRel);
}
ExecReleaseResource(tuple, m_local.m_reslot, result_rel_info, m_c_local.m_estate, bucket_rel, rel, part,
partRel);
return 0;
}
@ -386,25 +395,10 @@ unsigned long InsertFusion::ExecInsert(Relation rel, ResultRelInfo* result_rel_i
if (result_rel_info->ri_WithCheckOptions != NIL)
ExecWithCheckOptions(result_rel_info, m_local.m_reslot, m_c_local.m_estate);
tableam_tops_free_tuple(tuple);
(void)ExecClearTuple(m_local.m_reslot);
/****************
* step 3: done *
****************/
ExecCloseIndices(result_rel_info);
ExecDoneStepInFusion(m_c_local.m_estate);
if (bucket_rel != NULL) {
bucketCloseRelation(bucket_rel);
}
if (RELATION_IS_PARTITIONED(rel)) {
partitionClose(rel, part, RowExclusiveLock);
releaseDummyRelation(&partRel);
}
ExecReleaseResource(tuple, m_local.m_reslot, result_rel_info, m_c_local.m_estate, bucket_rel, rel, part, partRel);
return 1;
}

View File

@ -356,7 +356,7 @@ lreplace:
if (rel->rd_att->constr) {
if (!ExecConstraints(result_rel_info, m_local.m_reslot, m_c_local.m_estate)) {
if (u_sess->utils_cxt.sql_ignore_strategy_val != SQL_OVERWRITE_NULL) {
return 0;
break;
}
tup = ReplaceTupleNullCol(RelationGetDescr(result_rel_info->ri_RelationDesc), m_local.m_reslot);
/* Double check constraints in case that new val in column with not null constraints

View File

@ -365,6 +365,24 @@ select * from t_ignore;
2
(2 rows)
-- test for insert table with primary key
drop table if exists t_pri_key_insert;
NOTICE: table "t_pri_key_insert" does not exist, skipping
create table t_pri_key_insert(id int primary key);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_pri_key_insert_pkey" for table "t_pri_key_insert"
insert /*+ ignore_error */ into t_pri_key_insert values(null);
WARNING: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null).
insert /*+ ignore_error */ into t_pri_key_insert values(1);
insert /*+ ignore_error */ into t_pri_key_insert values(1);
WARNING: duplicate key value violates unique constraint in table "t_pri_key_insert"
select * from t_pri_key_insert;
id
----
1
(1 row)
drop table t_pri_key_insert;
-- test for update table with primary key
drop table if exists t_pri_key_update;
NOTICE: table "t_pri_key_update" does not exist, skipping
@ -372,6 +390,9 @@ create table t_pri_key_update(c1 int primary key, c2 int);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_pri_key_update_pkey" for table "t_pri_key_update"
insert into t_pri_key_update values(1, 101), (2, 201);
update /*+ ignore_error */ t_pri_key_update set c2 = 999 where c1 = 2;
update /*+ ignore_error */ t_pri_key_update set c1 = null where c1 = 2;
WARNING: null value in column "c1" violates not-null constraint
DETAIL: Failing row contains (null, 999).
select * from t_pri_key_update;
c1 | c2
----+-----

View File

@ -177,11 +177,21 @@ insert into t_ignore values(2);
update /*+ ignore_error */ t_ignore set num = 1 where num = 2;
select * from t_ignore;
-- test for insert table with primary key
drop table if exists t_pri_key_insert;
create table t_pri_key_insert(id int primary key);
insert /*+ ignore_error */ into t_pri_key_insert values(null);
insert /*+ ignore_error */ into t_pri_key_insert values(1);
insert /*+ ignore_error */ into t_pri_key_insert values(1);
select * from t_pri_key_insert;
drop table t_pri_key_insert;
-- test for update table with primary key
drop table if exists t_pri_key_update;
create table t_pri_key_update(c1 int primary key, c2 int);
insert into t_pri_key_update values(1, 101), (2, 201);
update /*+ ignore_error */ t_pri_key_update set c2 = 999 where c1 = 2;
update /*+ ignore_error */ t_pri_key_update set c1 = null where c1 = 2;
select * from t_pri_key_update;
drop table t_pri_key_update;