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:
parent
8e709a612f
commit
59f40566ca
@ -2773,6 +2773,9 @@ CopyFrom(CopyState cstate)
|
||||
ExecDropSingleTupleTableSlot(cstate->partition_tuple_slot);
|
||||
}
|
||||
|
||||
/* Close any trigger target relations */
|
||||
ExecCleanUpTriggerState(estate);
|
||||
|
||||
FreeExecutorState(estate);
|
||||
|
||||
/*
|
||||
|
@ -4110,16 +4110,7 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events,
|
||||
|
||||
if (local_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);
|
||||
}
|
||||
ExecCleanUpTriggerState(estate);
|
||||
FreeExecutorState(estate);
|
||||
}
|
||||
|
||||
|
@ -1446,6 +1446,24 @@ ExecGetTriggerResultRel(EState *estate, Oid relid)
|
||||
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
|
||||
*
|
||||
@ -1610,16 +1628,8 @@ ExecEndPlan(PlanState *planstate, EState *estate)
|
||||
resultRelInfo++;
|
||||
}
|
||||
|
||||
/*
|
||||
* likewise close any trigger target relations
|
||||
*/
|
||||
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);
|
||||
}
|
||||
/* likewise close any trigger target relations */
|
||||
ExecCleanUpTriggerState(estate);
|
||||
|
||||
/*
|
||||
* close any relations selected FOR [KEY] UPDATE/SHARE, again keeping
|
||||
@ -3173,14 +3183,7 @@ EvalPlanQualEnd(EPQState *epqstate)
|
||||
ExecResetTupleTable(estate->es_tupleTable, false);
|
||||
|
||||
/* close any trigger target relations attached to this 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);
|
||||
}
|
||||
ExecCleanUpTriggerState(estate);
|
||||
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
|
||||
|
@ -184,6 +184,7 @@ extern void InitResultRelInfo(ResultRelInfo *resultRelInfo,
|
||||
Relation partition_root,
|
||||
int instrument_options);
|
||||
extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);
|
||||
extern void ExecCleanUpTriggerState(EState *estate);
|
||||
extern bool ExecContextForcesOids(PlanState *planstate, bool *hasoids);
|
||||
extern void ExecConstraints(ResultRelInfo *resultRelInfo,
|
||||
TupleTableSlot *slot, EState *estate);
|
||||
|
@ -1882,4 +1882,14 @@ NOTICE: trigger on parted2_stmt_trig AFTER UPDATE for STATEMENT
|
||||
delete from parted_stmt_trig;
|
||||
NOTICE: trigger on parted_stmt_trig BEFORE 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;
|
||||
|
@ -1347,4 +1347,16 @@ with upd as (
|
||||
) update parted_stmt_trig set a = a;
|
||||
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user