}
else if (newtuple != oldtuple)
{
- ExecForceStoreHeapTuple(newtuple, slot);
+ ExecForceStoreHeapTuple(newtuple, slot, false);
if (should_free)
heap_freetuple(oldtuple);
}
else if (newtuple != oldtuple)
{
- ExecForceStoreHeapTuple(newtuple, slot);
+ ExecForceStoreHeapTuple(newtuple, slot, false);
if (should_free)
heap_freetuple(oldtuple);
else
{
trigtuple = fdw_trigtuple;
- ExecForceStoreHeapTuple(trigtuple, slot);
+ ExecForceStoreHeapTuple(trigtuple, slot, false);
}
LocTriggerData.type = T_TriggerData;
slot,
NULL);
else
- ExecForceStoreHeapTuple(fdw_trigtuple, slot);
+ ExecForceStoreHeapTuple(fdw_trigtuple, slot, false);
AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_DELETE,
true, slot, NULL, NIL, NULL,
LocTriggerData.tg_oldtable = NULL;
LocTriggerData.tg_newtable = NULL;
- ExecForceStoreHeapTuple(trigtuple, slot);
+ ExecForceStoreHeapTuple(trigtuple, slot, false);
for (i = 0; i < trigdesc->numtriggers; i++)
{
}
else
{
- ExecForceStoreHeapTuple(fdw_trigtuple, oldslot);
+ ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false);
trigtuple = fdw_trigtuple;
}
}
else if (newtuple != oldtuple)
{
- ExecForceStoreHeapTuple(newtuple, newslot);
+ ExecForceStoreHeapTuple(newtuple, newslot, false);
/*
* If the tuple returned by the trigger / being stored, is the old
oldslot,
NULL);
else if (fdw_trigtuple != NULL)
- ExecForceStoreHeapTuple(fdw_trigtuple, oldslot);
+ ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false);
AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_UPDATE,
true, oldslot, newslot, recheckIndexes,
LocTriggerData.tg_oldtable = NULL;
LocTriggerData.tg_newtable = NULL;
- ExecForceStoreHeapTuple(trigtuple, oldslot);
+ ExecForceStoreHeapTuple(trigtuple, oldslot, false);
for (i = 0; i < trigdesc->numtriggers; i++)
{
}
else if (newtuple != oldtuple)
{
- ExecForceStoreHeapTuple(newtuple, newslot);
+ ExecForceStoreHeapTuple(newtuple, newslot, false);
if (should_free)
heap_freetuple(oldtuple);
*/
void
ExecForceStoreHeapTuple(HeapTuple tuple,
- TupleTableSlot *slot)
+ TupleTableSlot *slot,
+ bool shouldFree)
{
if (TTS_IS_HEAPTUPLE(slot))
{
- ExecStoreHeapTuple(tuple, slot, false);
+ ExecStoreHeapTuple(tuple, slot, shouldFree);
}
else if (TTS_IS_BUFFERTUPLE(slot))
{
oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
bslot->base.tuple = heap_copytuple(tuple);
MemoryContextSwitchTo(oldContext);
+
+ if (shouldFree)
+ pfree(tuple);
}
else
{
heap_deform_tuple(tuple, slot->tts_tupleDescriptor,
slot->tts_values, slot->tts_isnull);
ExecStoreVirtualTuple(slot);
+
+ if (shouldFree)
+ {
+ ExecMaterializeSlot(slot);
+ pfree(tuple);
+ }
}
}
heap_deform_tuple(&htup, slot->tts_tupleDescriptor,
slot->tts_values, slot->tts_isnull);
ExecStoreVirtualTuple(slot);
+
+ if (shouldFree)
+ {
+ ExecMaterializeSlot(slot);
+ pfree(mtup);
+ }
}
}
oldtuple = ExecFetchSlotHeapTuple(slot, true, &should_free);
newtuple = heap_modify_tuple(oldtuple, tupdesc, values, nulls, replaces);
- ExecForceStoreHeapTuple(newtuple, slot);
+ /*
+ * The tuple will be freed by way of the memory context - the slot might
+ * only be cleared after the context is reset, and we'd thus potentially
+ * double free.
+ */
+ ExecForceStoreHeapTuple(newtuple, slot, false);
if (should_free)
heap_freetuple(oldtuple);
slot = ExecGetReturningSlot(estate, resultRelInfo);
if (oldtuple != NULL)
{
- ExecForceStoreHeapTuple(oldtuple, slot);
+ ExecForceStoreHeapTuple(oldtuple, slot, false);
}
else
{