Commit a1c2c430 authored by Tom Lane's avatar Tom Lane

Fix intra-query memory leakage in nodeProjectSet.c.

Both ExecMakeFunctionResultSet() and evaluation of simple expressions
need to be done in the per-tuple memory context, not per-query, else
we leak data until end of query.  This is a consideration that was
missed while refactoring code in the ProjectSet patch (note that in
pre-v10, ExecMakeFunctionResult is called in the per-tuple context).

Per bug #14843 from Ben M.  Diagnosed independently by Andres and myself.

Discussion: https://postgr.es/m/20171005230321.28561.15927@wrigleys.postgresql.org
parent 6b87416c
...@@ -467,6 +467,8 @@ ExecInitFunctionResultSet(Expr *expr, ...@@ -467,6 +467,8 @@ ExecInitFunctionResultSet(Expr *expr,
* function itself. The argument expressions may not contain set-returning * function itself. The argument expressions may not contain set-returning
* functions (the planner is supposed to have separated evaluation for those). * functions (the planner is supposed to have separated evaluation for those).
* *
* This should be called in a short-lived (per-tuple) context.
*
* This is used by nodeProjectSet.c. * This is used by nodeProjectSet.c.
*/ */
Datum Datum
......
...@@ -124,12 +124,16 @@ ExecProjectSRF(ProjectSetState *node, bool continuing) ...@@ -124,12 +124,16 @@ ExecProjectSRF(ProjectSetState *node, bool continuing)
{ {
TupleTableSlot *resultSlot = node->ps.ps_ResultTupleSlot; TupleTableSlot *resultSlot = node->ps.ps_ResultTupleSlot;
ExprContext *econtext = node->ps.ps_ExprContext; ExprContext *econtext = node->ps.ps_ExprContext;
MemoryContext oldcontext;
bool hassrf PG_USED_FOR_ASSERTS_ONLY; bool hassrf PG_USED_FOR_ASSERTS_ONLY;
bool hasresult; bool hasresult;
int argno; int argno;
ExecClearTuple(resultSlot); ExecClearTuple(resultSlot);
/* Call SRFs, as well as plain expressions, in per-tuple context */
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
/* /*
* Assume no further tuples are produced unless an ExprMultipleResult is * Assume no further tuples are produced unless an ExprMultipleResult is
* encountered from a set returning function. * encountered from a set returning function.
...@@ -176,6 +180,8 @@ ExecProjectSRF(ProjectSetState *node, bool continuing) ...@@ -176,6 +180,8 @@ ExecProjectSRF(ProjectSetState *node, bool continuing)
} }
} }
MemoryContextSwitchTo(oldcontext);
/* ProjectSet should not be used if there's no SRFs */ /* ProjectSet should not be used if there's no SRFs */
Assert(hassrf); Assert(hassrf);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment