aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Rowley <drowley@postgresql.org>2023-03-20 13:30:55 +1300
committerDavid Rowley <drowley@postgresql.org>2023-03-20 13:30:55 +1300
commitf654f343c6a89f76aa0385bb92a1c6802126974c (patch)
tree1ea954016788a33956407557a27913d9f74c707a
parent6fe609496beadfe85124290f220a25075d7f2c04 (diff)
downloadpostgresql-f654f343c6a89f76aa0385bb92a1c6802126974c.tar.gz
postgresql-f654f343c6a89f76aa0385bb92a1c6802126974c.zip
Fix memory leak in Memoize cache key evaluation
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
-rw-r--r--src/backend/executor/nodeMemoize.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/backend/executor/nodeMemoize.c b/src/backend/executor/nodeMemoize.c
index f82f41f3725..8f79a232849 100644
--- a/src/backend/executor/nodeMemoize.c
+++ b/src/backend/executor/nodeMemoize.c
@@ -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
{