}
                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
                        {