Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Fix intra-query memory leakage in nodeProjectSet.c.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 6 Oct 2017 18:28:42 +0000 (14:28 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 6 Oct 2017 18:28:42 +0000 (14:28 -0400)
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

src/backend/executor/execSRF.c
src/backend/executor/nodeProjectSet.c

index 8bc90a6c7e83003070d28c991e007ce0519687ad..1be683db83d36e0bfe7503ffe54b889202bf5116 100644 (file)
@@ -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
index d93462c5421cbfc79ba001486738498e11078372..68981296f90a07f9ea2e02b23306a898ba107e6c 100644 (file)
@@ -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);