mirror of
https://github.com/postgres/postgres.git
synced 2025-06-26 12:21:12 +03:00
Fix relcache leak when row triggers on partitions are fired by COPY.
Thomas Munro, reviewed by Amit Langote Discussion: http://postgr.es/m/CAEepm=15Jss-yhFApuKzxcoCuFnb8TR8iQiWMjG=CLYPx48QLw@mail.gmail.com
This commit is contained in:
@ -2773,6 +2773,9 @@ CopyFrom(CopyState cstate)
|
|||||||
ExecDropSingleTupleTableSlot(cstate->partition_tuple_slot);
|
ExecDropSingleTupleTableSlot(cstate->partition_tuple_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Close any trigger target relations */
|
||||||
|
ExecCleanUpTriggerState(estate);
|
||||||
|
|
||||||
FreeExecutorState(estate);
|
FreeExecutorState(estate);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4110,16 +4110,7 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events,
|
|||||||
|
|
||||||
if (local_estate)
|
if (local_estate)
|
||||||
{
|
{
|
||||||
ListCell *l;
|
ExecCleanUpTriggerState(estate);
|
||||||
|
|
||||||
foreach(l, estate->es_trig_target_relations)
|
|
||||||
{
|
|
||||||
ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
|
|
||||||
|
|
||||||
/* Close indices and then the relation itself */
|
|
||||||
ExecCloseIndices(resultRelInfo);
|
|
||||||
heap_close(resultRelInfo->ri_RelationDesc, NoLock);
|
|
||||||
}
|
|
||||||
FreeExecutorState(estate);
|
FreeExecutorState(estate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1446,6 +1446,24 @@ ExecGetTriggerResultRel(EState *estate, Oid relid)
|
|||||||
return rInfo;
|
return rInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Close any relations that have been opened by ExecGetTriggerResultRel().
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ExecCleanUpTriggerState(EState *estate)
|
||||||
|
{
|
||||||
|
ListCell *l;
|
||||||
|
|
||||||
|
foreach(l, estate->es_trig_target_relations)
|
||||||
|
{
|
||||||
|
ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
|
||||||
|
|
||||||
|
/* Close indices and then the relation itself */
|
||||||
|
ExecCloseIndices(resultRelInfo);
|
||||||
|
heap_close(resultRelInfo->ri_RelationDesc, NoLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ExecContextForcesOids
|
* ExecContextForcesOids
|
||||||
*
|
*
|
||||||
@ -1610,16 +1628,8 @@ ExecEndPlan(PlanState *planstate, EState *estate)
|
|||||||
resultRelInfo++;
|
resultRelInfo++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* likewise close any trigger target relations */
|
||||||
* likewise close any trigger target relations
|
ExecCleanUpTriggerState(estate);
|
||||||
*/
|
|
||||||
foreach(l, estate->es_trig_target_relations)
|
|
||||||
{
|
|
||||||
resultRelInfo = (ResultRelInfo *) lfirst(l);
|
|
||||||
/* Close indices and then the relation itself */
|
|
||||||
ExecCloseIndices(resultRelInfo);
|
|
||||||
heap_close(resultRelInfo->ri_RelationDesc, NoLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* close any relations selected FOR [KEY] UPDATE/SHARE, again keeping
|
* close any relations selected FOR [KEY] UPDATE/SHARE, again keeping
|
||||||
@ -3173,14 +3183,7 @@ EvalPlanQualEnd(EPQState *epqstate)
|
|||||||
ExecResetTupleTable(estate->es_tupleTable, false);
|
ExecResetTupleTable(estate->es_tupleTable, false);
|
||||||
|
|
||||||
/* close any trigger target relations attached to this EState */
|
/* close any trigger target relations attached to this EState */
|
||||||
foreach(l, estate->es_trig_target_relations)
|
ExecCleanUpTriggerState(estate);
|
||||||
{
|
|
||||||
ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
|
|
||||||
|
|
||||||
/* Close indices and then the relation itself */
|
|
||||||
ExecCloseIndices(resultRelInfo);
|
|
||||||
heap_close(resultRelInfo->ri_RelationDesc, NoLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryContextSwitchTo(oldcontext);
|
MemoryContextSwitchTo(oldcontext);
|
||||||
|
|
||||||
|
@ -184,6 +184,7 @@ extern void InitResultRelInfo(ResultRelInfo *resultRelInfo,
|
|||||||
Relation partition_root,
|
Relation partition_root,
|
||||||
int instrument_options);
|
int instrument_options);
|
||||||
extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);
|
extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);
|
||||||
|
extern void ExecCleanUpTriggerState(EState *estate);
|
||||||
extern bool ExecContextForcesOids(PlanState *planstate, bool *hasoids);
|
extern bool ExecContextForcesOids(PlanState *planstate, bool *hasoids);
|
||||||
extern void ExecConstraints(ResultRelInfo *resultRelInfo,
|
extern void ExecConstraints(ResultRelInfo *resultRelInfo,
|
||||||
TupleTableSlot *slot, EState *estate);
|
TupleTableSlot *slot, EState *estate);
|
||||||
|
@ -1882,4 +1882,14 @@ NOTICE: trigger on parted2_stmt_trig AFTER UPDATE for STATEMENT
|
|||||||
delete from parted_stmt_trig;
|
delete from parted_stmt_trig;
|
||||||
NOTICE: trigger on parted_stmt_trig BEFORE DELETE for STATEMENT
|
NOTICE: trigger on parted_stmt_trig BEFORE DELETE for STATEMENT
|
||||||
NOTICE: trigger on parted_stmt_trig AFTER DELETE for STATEMENT
|
NOTICE: trigger on parted_stmt_trig AFTER DELETE for STATEMENT
|
||||||
|
-- insert via copy on the parent
|
||||||
|
copy parted_stmt_trig(a) from stdin;
|
||||||
|
NOTICE: trigger on parted_stmt_trig BEFORE INSERT for STATEMENT
|
||||||
|
NOTICE: trigger on parted_stmt_trig1 BEFORE INSERT for ROW
|
||||||
|
NOTICE: trigger on parted_stmt_trig1 AFTER INSERT for ROW
|
||||||
|
NOTICE: trigger on parted_stmt_trig AFTER INSERT for STATEMENT
|
||||||
|
-- insert via copy on the first partition
|
||||||
|
copy parted_stmt_trig1(a) from stdin;
|
||||||
|
NOTICE: trigger on parted_stmt_trig1 BEFORE INSERT for ROW
|
||||||
|
NOTICE: trigger on parted_stmt_trig1 AFTER INSERT for ROW
|
||||||
drop table parted_stmt_trig, parted2_stmt_trig;
|
drop table parted_stmt_trig, parted2_stmt_trig;
|
||||||
|
@ -1347,4 +1347,16 @@ with upd as (
|
|||||||
) update parted_stmt_trig set a = a;
|
) update parted_stmt_trig set a = a;
|
||||||
|
|
||||||
delete from parted_stmt_trig;
|
delete from parted_stmt_trig;
|
||||||
|
|
||||||
|
-- insert via copy on the parent
|
||||||
|
copy parted_stmt_trig(a) from stdin;
|
||||||
|
1
|
||||||
|
2
|
||||||
|
\.
|
||||||
|
|
||||||
|
-- insert via copy on the first partition
|
||||||
|
copy parted_stmt_trig1(a) from stdin;
|
||||||
|
1
|
||||||
|
\.
|
||||||
|
|
||||||
drop table parted_stmt_trig, parted2_stmt_trig;
|
drop table parted_stmt_trig, parted2_stmt_trig;
|
||||||
|
Reference in New Issue
Block a user