8000 Fix memory leak in ARRAY(SELECT ...) subqueries. · sureandrew/postgres@b02cd9c · GitHub
[go: up one dir, main page]

Skip to content

Commit b02cd9c

Browse files
committed
Fix memory leak in ARRAY(SELECT ...) subqueries.
Repeated execution of an uncorrelated ARRAY_SUBLINK sub-select (which I think can only happen if the sub-select is embedded in a larger, correlated subquery) would leak memory for the duration of the query, due to not reclaiming the array generated in the previous execution. Per bug #6698 from Armando Miraglia. Diagnosis and fix idea by Heikki, patch itself by me. This has been like this all along, so back-patch to all supported versions.
1 parent 6d16507 commit b02cd9c

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

src/backend/executor/nodeSubplan.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
657657
* initialize my state
658658
*/
659659
sstate->curTuple = NULL;
660+
sstate->curArray = PointerGetDatum(NULL);
660661
sstate->projLeft = NULL;
661662
sstate->projRight = NULL;
662663
sstate->hashtable = NULL;
@@ -991,16 +992,23 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
991992
int paramid = linitial_int(subplan->setParam);
992993
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
993994

994-
prm->execPlan = NULL;
995-
/* We build the result in query context so it won't disappear */
995+
/*
996+
* We build the result array in query context so it won't disappear;
997+
* to avoid leaking memory across repeated calls, we have to remember
998+
* the latest value, much as for curTuple above.
999+
*/
1000+
if (node->curArray != PointerGetDatum(NULL))
1001+
pfree(DatumGetPointer(node->curArray));
9961002
if (astate != NULL)
997-
prm->value = makeArrayResult(astate,
998-
econtext->ecxt_per_query_memory);
1003+
node->curArray = makeArrayResult(astate,
1004+
econtext->ecxt_per_query_memory);
9991005
else
10001006
{
10011007
MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1002-
prm->value = PointerGetDatum(construct_empty_array(subplan->firstColType));
1008+
node->curArray = PointerGetDatum(construct_empty_array(subplan->firstColType));
10031009
}
1010+
prm->execPlan = NULL;
1011+
prm->value = node->curArray;
10041012
prm->isnull = false;
10051013
}
10061014
else if (!found)

src/include/nodes/execnodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ typedef struct SubPlanState
611611
ExprState *testexpr; /* state of combining expression */
612612
List *args; /* states of argument expression(s) */
613613
HeapTuple curTuple; /* copy of most recent tuple from subplan */
614+
Datum curArray; /* most recent array from ARRAY() subplan */
614615
/* these are used when hashing the subselect's output: */
615616
ProjectionInfo *projLeft; /* for projecting lefthand exprs */
616617
ProjectionInfo *projRight; /* for projecting subselect output */

0 commit comments

Comments
 (0)
0