Skip to content

Commit d14241c

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 68d0e3c commit d14241c

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
@@ -668,6 +668,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
668668
* initialize my state
669669
*/
670670
sstate->curTuple = NULL;
671+
sstate->curArray = PointerGetDatum(NULL);
671672
sstate->projLeft = NULL;
672673
sstate->projRight = NULL;
673674
sstate->hashtable = NULL;
@@ -994,16 +995,23 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
994995
int paramid = linitial_int(subplan->setParam);
995996
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
996997

997-
prm->execPlan = NULL;
998-
/* We build the result in query context so it won't disappear */
998+
/*
999+
* We build the result array in query context so it won't disappear;
1000+
* to avoid leaking memory across repeated calls, we have to remember
1001+
* the latest value, much as for curTuple above.
1002+
*/
1003+
if (node->curArray != PointerGetDatum(NULL))
1004+
pfree(DatumGetPointer(node->curArray));
9991005
if (astate != NULL)
1000-
prm->value = makeArrayResult(astate,
1001-
econtext->ecxt_per_query_memory);
1006+
node->curArray = makeArrayResult(astate,
1007+
econtext->ecxt_per_query_memory);
10021008
else
10031009
{
10041010
MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1005-
prm->value = PointerGetDatum(construct_empty_array(subplan->firstColType));
1011+
node->curArray = PointerGetDatum(construct_empty_array(subplan->firstColType));
10061012
}
1013+
prm->execPlan = NULL;
1014+
prm->value = node->curArray;
10071015
prm->isnull = false;
10081016
}
10091017
else if (!found)

src/include/nodes/execnodes.h

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

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy