Skip to content

Commit 0b053e7

Browse files
committed
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
1 parent 6889266 commit 0b053e7

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

src/backend/executor/nodeMemoize.c

+22-3
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,14 @@ static uint32
158158
MemoizeHash_hash(struct memoize_hash *tb, const MemoizeKey *key)
159159
{
160160
MemoizeState *mstate = (MemoizeState *) tb->private_data;
161+
ExprContext *econtext = mstate->ss.ps.ps_ExprContext;
162+
MemoryContext oldcontext;
161163
TupleTableSlot *pslot = mstate->probeslot;
162164
uint32 hashkey = 0;
163165
int numkeys = mstate->nkeys;
164166

167+
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
168+
165169
if (mstate->binary_mode)
166170
{
167171
for (int i = 0; i < numkeys; i++)
@@ -203,6 +207,8 @@ MemoizeHash_hash(struct memoize_hash *tb, const MemoizeKey *key)
203207
}
204208
}
205209

210+
ResetExprContext(econtext);
211+
MemoryContextSwitchTo(oldcontext);
206212
return murmurhash32(hashkey);
207213
}
208214

@@ -226,7 +232,11 @@ MemoizeHash_equal(struct memoize_hash *tb, const MemoizeKey *key1,
226232

227233
if (mstate->binary_mode)
228234
{
235+
MemoryContext oldcontext;
229236
int numkeys = mstate->nkeys;
237+
bool match = true;
238+
239+
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
230240

231241
slot_getallattrs(tslot);
232242
slot_getallattrs(pslot);
@@ -236,7 +246,10 @@ MemoizeHash_equal(struct memoize_hash *tb, const MemoizeKey *key1,
236246
FormData_pg_attribute *attr;
237247

238248
if (tslot->tts_isnull[i] != pslot->tts_isnull[i])
239-
return false;
249+
{
250+
match = false;
251+
break;
252+
}
240253

241254
/* both NULL? they're equal */
242255
if (tslot->tts_isnull[i])
@@ -246,9 +259,15 @@ MemoizeHash_equal(struct memoize_hash *tb, const MemoizeKey *key1,
246259
attr = &tslot->tts_tupleDescriptor->attrs[i];
247260
if (!datum_image_eq(tslot->tts_values[i], pslot->tts_values[i],
248261
attr->attbyval, attr->attlen))
249-
return false;
262+
{
263+
match = false;
264+
break;
265+
}
250266
}
251-
return true;
267+
268+
ResetExprContext(econtext);
269+
MemoryContextSwitchTo(oldcontext);
270+
return match;
252271
}
253272
else
254273
{

0 commit comments

Comments
 (0)