mirror of
https://github.com/postgres/postgres.git
synced 2025-05-03 22:24:49 +03:00
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
This commit is contained in:
parent
f91c87b314
commit
e4b95b9b02
@ -158,10 +158,14 @@ static uint32
|
|||||||
MemoizeHash_hash(struct memoize_hash *tb, const MemoizeKey *key)
|
MemoizeHash_hash(struct memoize_hash *tb, const MemoizeKey *key)
|
||||||
{
|
{
|
||||||
MemoizeState *mstate = (MemoizeState *) tb->private_data;
|
MemoizeState *mstate = (MemoizeState *) tb->private_data;
|
||||||
|
ExprContext *econtext = mstate->ss.ps.ps_ExprContext;
|
||||||
|
MemoryContext oldcontext;
|
||||||
TupleTableSlot *pslot = mstate->probeslot;
|
TupleTableSlot *pslot = mstate->probeslot;
|
||||||
uint32 hashkey = 0;
|
uint32 hashkey = 0;
|
||||||
int numkeys = mstate->nkeys;
|
int numkeys = mstate->nkeys;
|
||||||
|
|
||||||
|
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
|
||||||
|
|
||||||
if (mstate->binary_mode)
|
if (mstate->binary_mode)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numkeys; i++)
|
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);
|
return murmurhash32(hashkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +232,11 @@ MemoizeHash_equal(struct memoize_hash *tb, const MemoizeKey *key1,
|
|||||||
|
|
||||||
if (mstate->binary_mode)
|
if (mstate->binary_mode)
|
||||||
{
|
{
|
||||||
|
MemoryContext oldcontext;
|
||||||
int numkeys = mstate->nkeys;
|
int numkeys = mstate->nkeys;
|
||||||
|
bool match = true;
|
||||||
|
|
||||||
|
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
|
||||||
|
|
||||||
slot_getallattrs(tslot);
|
slot_getallattrs(tslot);
|
||||||
slot_getallattrs(pslot);
|
slot_getallattrs(pslot);
|
||||||
@ -236,7 +246,10 @@ MemoizeHash_equal(struct memoize_hash *tb, const MemoizeKey *key1,
|
|||||||
FormData_pg_attribute *attr;
|
FormData_pg_attribute *attr;
|
||||||
|
|
||||||
if (tslot->tts_isnull[i] != pslot->tts_isnull[i])
|
if (tslot->tts_isnull[i] != pslot->tts_isnull[i])
|
||||||
return false;
|
{
|
||||||
|
match = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* both NULL? they're equal */
|
/* both NULL? they're equal */
|
||||||
if (tslot->tts_isnull[i])
|
if (tslot->tts_isnull[i])
|
||||||
@ -246,9 +259,15 @@ MemoizeHash_equal(struct memoize_hash *tb, const MemoizeKey *key1,
|
|||||||
attr = &tslot->tts_tupleDescriptor->attrs[i];
|
attr = &tslot->tts_tupleDescriptor->attrs[i];
|
||||||
if (!datum_image_eq(tslot->tts_values[i], pslot->tts_values[i],
|
if (!datum_image_eq(tslot->tts_values[i], pslot->tts_values[i],
|
||||||
attr->attbyval, attr->attlen))
|
attr->attbyval, attr->attlen))
|
||||||
return false;
|
{
|
||||||
|
match = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
ResetExprContext(econtext);
|
||||||
|
MemoryContextSwitchTo(oldcontext);
|
||||||
|
return match;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user