issue修复:ignore在向主键列插入null时资源泄漏修复
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
----+-----
|
||||
|
@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user