aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeMemoize.c
diff options
context:
space:
mode:
authorDavid Rowley <drowley@postgresql.org>2023-10-05 20:30:47 +1300
committerDavid Rowley <drowley@postgresql.org>2023-10-05 20:30:47 +1300
commit0b053e78b5990cd01e7169ee5bd2bb8e4045deea (patch)
treef18695f27e0905a6e9bdd37a8ade115f0f77aa39 /src/backend/executor/nodeMemoize.c
parent688926633fc6663d632334b17b34b0384620a458 (diff)
downloadpostgresql-0b053e78b5990cd01e7169ee5bd2bb8e4045deea.tar.gz
postgresql-0b053e78b5990cd01e7169ee5bd2bb8e4045deea.zip
Fix memory leak in Memoize code
Ensure we switch to the per-tuple memory context to prevent any memory leaks of detoasted Datums in MemoizeHash_hash() and MemoizeHash_equal(). Reported-by: Orlov Aleksej Author: Orlov Aleksej, David Rowley Discussion: https://postgr.es/m/83281eed63c74e4f940317186372abfd%40cft.ru Backpatch-through: 14, where Memoize was added
Diffstat (limited to 'src/backend/executor/nodeMemoize.c')
-rw-r--r--src/backend/executor/nodeMemoize.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/backend/executor/nodeMemoize.c b/src/backend/executor/nodeMemoize.c
index 94bf4792873..1085b3c79dd 100644
--- a/src/backend/executor/nodeMemoize.c
+++ b/src/backend/executor/nodeMemoize.c
@@ -158,10 +158,14 @@ static uint32
MemoizeHash_hash(struct memoize_hash *tb, const MemoizeKey *key)
{
MemoizeState *mstate = (MemoizeState *) tb->private_data;
+ ExprContext *econtext = mstate->ss.ps.ps_ExprContext;
+ MemoryContext oldcontext;
TupleTableSlot *pslot = mstate->probeslot;
uint32 hashkey = 0;
int numkeys = mstate->nkeys;
+ oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
+
if (mstate->binary_mode)
{
for (int i = 0; i < numkeys; i++)
@@ -203,6 +207,8 @@ MemoizeHash_hash(struct memoize_hash *tb, const MemoizeKey *key)
}
}
+ ResetExprContext(econtext);
+ MemoryContextSwitchTo(oldcontext);
return murmurhash32(hashkey);
}
@@ -226,7 +232,11 @@ MemoizeHash_equal(struct memoize_hash *tb, const MemoizeKey *key1,
if (mstate->binary_mode)
{
+ MemoryContext oldcontext;
int numkeys = mstate->nkeys;
+ bool match = true;
+
+ oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
slot_getallattrs(tslot);
slot_getallattrs(pslot);
@@ -236,7 +246,10 @@ MemoizeHash_equal(struct memoize_hash *tb, const MemoizeKey *key1,
FormData_pg_attribute *attr;
if (tslot->tts_isnull[i] != pslot->tts_isnull[i])
- return false;
+ {
+ match = false;
+ break;
+ }
/* both NULL? they're equal */
if (tslot->tts_isnull[i])
@@ -246,9 +259,15 @@ MemoizeHash_equal(struct memoize_hash *tb, const MemoizeKey *key1,
attr = &tslot->tts_tupleDescriptor->attrs[i];
if (!datum_image_eq(tslot->tts_values[i], pslot->tts_values[i],
attr->attbyval, attr->attlen))
- return false;
+ {
+ match = false;
+ break;
+ }
}
- return true;
+
+ ResetExprContext(econtext);
+ MemoryContextSwitchTo(oldcontext);
+ return match;
}
else
{