Commit 59f40566 authored by Robert Haas's avatar Robert Haas

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
parent 8e709a61
...@@ -2773,6 +2773,9 @@ CopyFrom(CopyState cstate) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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 ...@@ -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 ( ...@@ -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;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment