diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-06-21 17:26:07 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-06-21 17:27:19 -0400 |
commit | d14241c2cf72966c09c1acece5cb44b5c84204b4 (patch) | |
tree | d9b2ea23d9e939414755ab070b2b9bbbd52be9d5 /src/backend/executor/nodeSubplan.c | |
parent | 68d0e3cbf9c4b5981679668ebb554a4ec050fc72 (diff) | |
download | postgresql-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.c | 18 |
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) |