aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeSubplan.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-06-21 17:26:07 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-06-21 17:27:19 -0400
commitd14241c2cf72966c09c1acece5cb44b5c84204b4 (patch)
treed9b2ea23d9e939414755ab070b2b9bbbd52be9d5 /src/backend/executor/nodeSubplan.c
parent68d0e3cbf9c4b5981679668ebb554a4ec050fc72 (diff)
downloadpostgresql-d14241c2cf72966c09c1acece5cb44b5c84204b4.tar.gz
postgresql-d14241c2cf72966c09c1acece5cb44b5c84204b4.zip
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.
Diffstat (limited to 'src/backend/executor/nodeSubplan.c')
-rw-r--r--src/backend/executor/nodeSubplan.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c
index da31820e2d9..4b8746f4f26 100644
--- a/src/backend/executor/nodeSubplan.c
+++ b/src/backend/executor/nodeSubplan.c
@@ -668,6 +668,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
* initialize my state
*/
sstate->curTuple = NULL;
+ sstate->curArray = PointerGetDatum(NULL);
sstate->projLeft = NULL;
sstate->projRight = NULL;
sstate->hashtable = NULL;
@@ -994,16 +995,23 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
int paramid = linitial_int(subplan->setParam);
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
- prm->execPlan = NULL;
- /* We build the result in query context so it won't disappear */
+ /*
+ * We build the result array in query context so it won't disappear;
+ * to avoid leaking memory across repeated calls, we have to remember
+ * the latest value, much as for curTuple above.
+ */
+ if (node->curArray != PointerGetDatum(NULL))
+ pfree(DatumGetPointer(node->curArray));
if (astate != NULL)
- prm->value = makeArrayResult(astate,
- econtext->ecxt_per_query_memory);
+ node->curArray = makeArrayResult(astate,
+ econtext->ecxt_per_query_memory);
else
{
MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
- prm->value = PointerGetDatum(construct_empty_array(subplan->firstColType));
+ node->curArray = PointerGetDatum(construct_empty_array(subplan->firstColType));
}
+ prm->execPlan = NULL;
+ prm->value = node->curArray;
prm->isnull = false;
}
else if (!found)