aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2017-10-06 14:28:42 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2017-10-06 14:28:42 -0400
commita1c2c430d33e0945da234b025b78bd265c8bdfb5 (patch)
tree58551341e368115efa072e8b7eee155828372e92
parent6b87416c9a4dd305b76e619ecac36e2b968462f8 (diff)
downloadpostgresql-a1c2c430d33e0945da234b025b78bd265c8bdfb5.tar.gz
postgresql-a1c2c430d33e0945da234b025b78bd265c8bdfb5.zip
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
-rw-r--r--src/backend/executor/execSRF.c2
-rw-r--r--src/backend/executor/nodeProjectSet.c6
2 files changed, 8 insertions, 0 deletions
diff --git a/src/backend/executor/execSRF.c b/src/backend/executor/execSRF.c
index 8bc90a6c7e8..1be683db83d 100644
--- a/src/backend/executor/execSRF.c
+++ b/src/backend/executor/execSRF.c
@@ -467,6 +467,8 @@ ExecInitFunctionResultSet(Expr *expr,
* function itself. The argument expressions may not contain set-returning
* 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.
*/
Datum
diff --git a/src/backend/executor/nodeProjectSet.c b/src/backend/executor/nodeProjectSet.c
index d93462c5421..68981296f90 100644
--- a/src/backend/executor/nodeProjectSet.c
+++ b/src/backend/executor/nodeProjectSet.c
@@ -124,12 +124,16 @@ ExecProjectSRF(ProjectSetState *node, bool continuing)
{
TupleTableSlot *resultSlot = node->ps.ps_ResultTupleSlot;
ExprContext *econtext = node->ps.ps_ExprContext;
+ MemoryContext oldcontext;
bool hassrf PG_USED_FOR_ASSERTS_ONLY;
bool hasresult;
int argno;
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
* encountered from a set returning function.
@@ -176,6 +180,8 @@ ExecProjectSRF(ProjectSetState *node, bool continuing)
}
}
+ MemoryContextSwitchTo(oldcontext);
+
/* ProjectSet should not be used if there's no SRFs */
Assert(hassrf);