Fix memory leak in Memoize cache key evaluation
authorDavid Rowley
Mon, 20 Mar 2023 00:30:15 +0000 (13:30 +1300)
committerDavid Rowley
Mon, 20 Mar 2023 00:30:15 +0000 (13:30 +1300)
When probing the Memoize cache to check if the current cache key values
exist in the cache, we perform an evaluation of the expressions making up
the cache key before probing the hash table for those values.  This
operation could leak memory as it is possible that the cache key is an
expression which requires allocation of memory, as was the case in bug
17844.

Here we fix this by correctly switching to the per tuple context before
evaluating the cache expressions so that the memory is freed next time the
per tuple context is reset.

Bug: 17844
Reported-by: Alexey Ermakov
Discussion: https://postgr.es/m/17844-d2f6f9e75a622bed@postgresql.org
Backpatch-through: 14, where Memoize was introduced

src/backend/executor/nodeMemoize.c

index d2bceb97c3a25b880634702f1c4f117bc387fecc..8106f3a29bc9d163f483bab3f494c61a1d15a45f 100644 (file)
@@ -289,11 +289,18 @@ prepare_probe_slot(MemoizeState *mstate, MemoizeKey *key)
 
    if (key == NULL)
    {
+       ExprContext *econtext = mstate->ss.ps.ps_ExprContext;
+       MemoryContext oldcontext;
+
+       oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
+
        /* Set the probeslot's values based on the current parameter values */
        for (int i = 0; i < numKeys; i++)
            pslot->tts_values[i] = ExecEvalExpr(mstate->param_exprs[i],
-                                               mstate->ss.ps.ps_ExprContext,
+                                               econtext,
                                                &pslot->tts_isnull[i]);
+
+       MemoryContextSwitchTo(oldcontext);
    }
    else
    {