From d87b94d555c1d863a65e738a6953a1c87b0af2b2 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 23 Apr 2019 10:18:39 +0200 Subject: [PATCH] Don't form heap tuple in ExecComputeStoredGenerated --- src/backend/executor/nodeModifyTable.c | 27 ++++++++++++-------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 444c0c0574..216c3baa64 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -53,6 +53,7 @@ #include "storage/bufmgr.h" #include "storage/lmgr.h" #include "utils/builtins.h" +#include "utils/datum.h" #include "utils/memutils.h" #include "utils/rel.h" @@ -254,9 +255,6 @@ ExecComputeStoredGenerated(EState *estate, TupleTableSlot *slot) MemoryContext oldContext; Datum *values; bool *nulls; - bool *replaces; - HeapTuple oldtuple, newtuple; - bool should_free; Assert(tupdesc->constr && tupdesc->constr->has_generated_stored); @@ -294,7 +292,10 @@ ExecComputeStoredGenerated(EState *estate, TupleTableSlot *slot) values = palloc(sizeof(*values) * natts); nulls = palloc(sizeof(*nulls) * natts); - replaces = palloc0(sizeof(*replaces) * natts); + + slot_getallattrs(slot); + memcpy(values, slot->tts_values, sizeof(*values) * natts); + memcpy(nulls, slot->tts_isnull, sizeof(*nulls) * natts); for (int i = 0; i < natts; i++) { @@ -311,20 +312,16 @@ ExecComputeStoredGenerated(EState *estate, TupleTableSlot *slot) values[i] = val; nulls[i] = isnull; - replaces[i] = true; } + else + values[i] = datumCopy(values[i], TupleDescAttr(tupdesc, i)->attbyval, TupleDescAttr(tupdesc, i)->attlen); } - oldtuple = ExecFetchSlotHeapTuple(slot, true, &should_free); - newtuple = heap_modify_tuple(oldtuple, tupdesc, values, nulls, replaces); - /* - * 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); + ExecClearTuple(slot); + memcpy(slot->tts_values, values, sizeof(*values) * natts); + memcpy(slot->tts_isnull, nulls, sizeof(*nulls) * natts); + ExecStoreVirtualTuple(slot); + ExecMaterializeSlot(slot); MemoryContextSwitchTo(oldContext); } -- 2.21.0