issue修复:ignore在向主键列插入null时资源泄漏修复
This commit is contained in:
@ -246,6 +246,23 @@ Datum ComputePartKeyExprTuple(Relation rel, EState *estate, TupleTableSlot *slot
|
|||||||
return val;
|
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)
|
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;
|
m_c_local.m_estate->esfRelations = NULL;
|
||||||
partOid = heapTupleGetPartitionId(rel, tuple, false, m_c_local.m_estate->es_plannedstmt->hasIgnore);
|
partOid = heapTupleGetPartitionId(rel, tuple, false, m_c_local.m_estate->es_plannedstmt->hasIgnore);
|
||||||
if (m_c_local.m_estate->es_plannedstmt->hasIgnore && partOid == InvalidOid) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
part = partitionOpen(rel, partOid, RowExclusiveLock);
|
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(!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) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
tuple = ReplaceTupleNullCol(RelationGetDescr(result_rel_info->ri_RelationDesc), m_local.m_reslot);
|
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)) {
|
&conflictInfo, &conflictPartOid, &conflictBucketid)) {
|
||||||
ereport(WARNING, (errmsg("duplicate key value violates unique constraint in table \"%s\"",
|
ereport(WARNING, (errmsg("duplicate key value violates unique constraint in table \"%s\"",
|
||||||
RelationGetRelationName(target_rel))));
|
RelationGetRelationName(target_rel))));
|
||||||
|
ExecReleaseResource(tuple, m_local.m_reslot, result_rel_info, m_c_local.m_estate, bucket_rel, rel, part,
|
||||||
/* clear before ended */
|
partRel);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,25 +395,10 @@ unsigned long InsertFusion::ExecInsert(Relation rel, ResultRelInfo* result_rel_i
|
|||||||
if (result_rel_info->ri_WithCheckOptions != NIL)
|
if (result_rel_info->ri_WithCheckOptions != NIL)
|
||||||
ExecWithCheckOptions(result_rel_info, m_local.m_reslot, m_c_local.m_estate);
|
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 *
|
* step 3: done *
|
||||||
****************/
|
****************/
|
||||||
ExecCloseIndices(result_rel_info);
|
ExecReleaseResource(tuple, m_local.m_reslot, result_rel_info, m_c_local.m_estate, bucket_rel, rel, part, partRel);
|
||||||
|
|
||||||
|
|
||||||
ExecDoneStepInFusion(m_c_local.m_estate);
|
|
||||||
|
|
||||||
if (bucket_rel != NULL) {
|
|
||||||
bucketCloseRelation(bucket_rel);
|
|
||||||
}
|
|
||||||
if (RELATION_IS_PARTITIONED(rel)) {
|
|
||||||
partitionClose(rel, part, RowExclusiveLock);
|
|
||||||
releaseDummyRelation(&partRel);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ lreplace:
|
|||||||
if (rel->rd_att->constr) {
|
if (rel->rd_att->constr) {
|
||||||
if (!ExecConstraints(result_rel_info, m_local.m_reslot, m_c_local.m_estate)) {
|
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) {
|
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);
|
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
|
/* Double check constraints in case that new val in column with not null constraints
|
||||||
|
@ -365,6 +365,24 @@ select * from t_ignore;
|
|||||||
2
|
2
|
||||||
(2 rows)
|
(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
|
-- test for update table with primary key
|
||||||
drop table if exists t_pri_key_update;
|
drop table if exists t_pri_key_update;
|
||||||
NOTICE: table "t_pri_key_update" does not exist, skipping
|
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"
|
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);
|
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 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;
|
select * from t_pri_key_update;
|
||||||
c1 | c2
|
c1 | c2
|
||||||
----+-----
|
----+-----
|
||||||
|
@ -177,11 +177,21 @@ insert into t_ignore values(2);
|
|||||||
update /*+ ignore_error */ t_ignore set num = 1 where num = 2;
|
update /*+ ignore_error */ t_ignore set num = 1 where num = 2;
|
||||||
select * from t_ignore;
|
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
|
-- test for update table with primary key
|
||||||
drop table if exists t_pri_key_update;
|
drop table if exists t_pri_key_update;
|
||||||
create table t_pri_key_update(c1 int primary key, c2 int);
|
create table t_pri_key_update(c1 int primary key, c2 int);
|
||||||
insert into t_pri_key_update values(1, 101), (2, 201);
|
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 c2 = 999 where c1 = 2;
|
||||||
|
update /*+ ignore_error */ t_pri_key_update set c1 = null where c1 = 2;
|
||||||
select * from t_pri_key_update;
|
select * from t_pri_key_update;
|
||||||
drop table t_pri_key_update;
|
drop table t_pri_key_update;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user