Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 59f4056

Browse files
committed
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
1 parent 8e709a6 commit 59f4056

File tree

6 files changed

+48
-28
lines changed

6 files changed

+48
-28
lines changed

src/backend/commands/copy.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2773,6 +2773,9 @@ CopyFrom(CopyState cstate)
27732773
ExecDropSingleTupleTableSlot(cstate->partition_tuple_slot);
27742774
}
27752775

2776+
/* Close any trigger target relations */
2777+
ExecCleanUpTriggerState(estate);
2778+
27762779
FreeExecutorState(estate);
27772780

27782781
/*

src/backend/commands/trigger.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4110,16 +4110,7 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events,
41104110

41114111
if (local_estate)
41124112
{
4113-
ListCell *l;
4114-
4115-
foreach(l, estate->es_trig_target_relations)
4116-
{
4117-
ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
4118-
4119-
/* Close indices and then the relation itself */
4120-
ExecCloseIndices(resultRelInfo);
4121-
heap_close(resultRelInfo->ri_RelationDesc, NoLock);
4122-
}
4113+
ExecCleanUpTriggerState(estate);
41234114
FreeExecutorState(estate);
41244115
}
41254116

src/backend/executor/execMain.c

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,24 @@ ExecGetTriggerResultRel(EState *estate, Oid relid)
14461446
return rInfo;
14471447
}
14481448

1449+
/*
1450+
* Close any relations that have been opened by ExecGetTriggerResultRel().
1451+
*/
1452+
void
1453+
ExecCleanUpTriggerState(EState *estate)
1454+
{
1455+
ListCell *l;
1456+
1457+
foreach(l, estate->es_trig_target_relations)
1458+
{
1459+
ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
1460+
1461+
/* Close indices and then the relation itself */
1462+
ExecCloseIndices(resultRelInfo);
1463+
heap_close(resultRelInfo->ri_RelationDesc, NoLock);
1464+
}
1465+
}
1466+
14491467
/*
14501468
* ExecContextForcesOids
14511469
*
@@ -1610,16 +1628,8 @@ ExecEndPlan(PlanState *planstate, EState *estate)
16101628
resultRelInfo++;
16111629
}
16121630

1613-
/*
1614-
* likewise close any trigger target relations
1615-
*/
1616-
foreach(l, estate->es_trig_target_relations)
1617-
{
1618-
resultRelInfo = (ResultRelInfo *) lfirst(l);
1619-
/* Close indices and then the relation itself */
1620-
ExecCloseIndices(resultRelInfo);
1621-
heap_close(resultRelInfo->ri_RelationDesc, NoLock);
1622-
}
1631+
/* likewise close any trigger target relations */
1632+
ExecCleanUpTriggerState(estate);
16231633

16241634
/*
16251635
* close any relations selected FOR [KEY] UPDATE/SHARE, again keeping
@@ -3173,14 +3183,7 @@ EvalPlanQualEnd(EPQState *epqstate)
31733183
ExecResetTupleTable(estate->es_tupleTable, false);
31743184

31753185
/* close any trigger target relations attached to this EState */
3176-
foreach(l, estate->es_trig_target_relations)
3177-
{
3178-
ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
3179-
3180-
/* Close indices and then the relation itself */
3181-
ExecCloseIndices(resultRelInfo);
3182-
heap_close(resultRelInfo->ri_RelationDesc, NoLock);
3183-
}
3186+
ExecCleanUpTriggerState(estate);
31843187

31853188
MemoryContextSwitchTo(oldcontext);
31863189

src/include/executor/executor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ extern void InitResultRelInfo(ResultRelInfo *resultRelInfo,
184184
Relation partition_root,
185185
int instrument_options);
186186
extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);
187+
extern void ExecCleanUpTriggerState(EState *estate);
187188
extern bool ExecContextForcesOids(PlanState *planstate, bool *hasoids);
188189
extern void ExecConstraints(ResultRelInfo *resultRelInfo,
189190
TupleTableSlot *slot, EState *estate);

src/test/regress/expected/triggers.out

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,4 +1882,14 @@ NOTICE: trigger on parted2_stmt_trig AFTER UPDATE for STATEMENT
18821882
delete from parted_stmt_trig;
18831883
NOTICE: trigger on parted_stmt_trig BEFORE DELETE for STATEMENT
18841884
NOTICE: trigger on parted_stmt_trig AFTER DELETE for STATEMENT
1885+
-- insert via copy on the parent
1886+
copy parted_stmt_trig(a) from stdin;
1887+
NOTICE: trigger on parted_stmt_trig BEFORE INSERT for STATEMENT
1888+
NOTICE: trigger on parted_stmt_trig1 BEFORE INSERT for ROW
1889+
NOTICE: trigger on parted_stmt_trig1 AFTER INSERT for ROW
1890+
NOTICE: trigger on parted_stmt_trig AFTER INSERT for STATEMENT
1891+
-- insert via copy on the first partition
1892+
copy parted_stmt_trig1(a) from stdin;
1893+
NOTICE: trigger on parted_stmt_trig1 BEFORE INSERT for ROW
1894+
NOTICE: trigger on parted_stmt_trig1 AFTER INSERT for ROW
18851895
drop table parted_stmt_trig, parted2_stmt_trig;

src/test/regress/sql/triggers.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,4 +1347,16 @@ with upd as (
13471347
) update parted_stmt_trig set a = a;
13481348

13491349
delete from parted_stmt_trig;
1350+
1351+
-- insert via copy on the parent
1352+
copy parted_stmt_trig(a) from stdin;
1353+
1
1354+
2
1355+
\.
1356+
1357+
-- insert via copy on the first partition
1358+
copy parted_stmt_trig1(a) from stdin;
1359+
1
1360+
\.
1361+
13501362
drop table parted_stmt_trig, parted2_stmt_trig;

0 commit comments

Comments
 (0)