aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2019-02-28 13:55:27 -0800
committerAndres Freund <andres@anarazel.de>2019-02-28 14:54:12 -0800
commit8f0577386e68c3b1c83a07b95756e5ee3f4ae73f (patch)
treed83f5e6daed6cbf07ec0fffb1bb826f544ab3e94
parent2c31825fb9a95914418f1e376917f60841a26c78 (diff)
downloadpostgresql-8f0577386e68c3b1c83a07b95756e5ee3f4ae73f.tar.gz
postgresql-8f0577386e68c3b1c83a07b95756e5ee3f4ae73f.zip
Don't force materializing when copying a buffer tuple table slot.
After 5408e233f0667478 it's not necessary to force materializing the target slot when copying from one buffer slot to another. Previously that was required because the HeapTupleData portion of the source slot wasn't guaranteed to stay valid long enough, but now we can simply copy that part into the destination slot's tupdata. Author: Andres Freund
-rw-r--r--src/backend/executor/execTuples.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index 121649f3435..e1948670490 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -747,10 +747,12 @@ tts_buffer_heap_copyslot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
/*
* If the source slot is of a different kind, or is a buffer slot that has
- * been materialized, make a new copy of the tuple.
+ * been materialized / is virtual, make a new copy of the tuple. Otherwise
+ * make a new reference to the in-buffer tuple.
*/
if (dstslot->tts_ops != srcslot->tts_ops ||
- TTS_SHOULDFREE(srcslot))
+ TTS_SHOULDFREE(srcslot) ||
+ !bsrcslot->base.tuple)
{
MemoryContext oldContext;
@@ -763,18 +765,19 @@ tts_buffer_heap_copyslot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
}
else
{
- if (!bsrcslot->base.tuple)
- tts_buffer_heap_materialize(srcslot);
+ Assert(BufferIsValid(bsrcslot->buffer));
tts_buffer_heap_store_tuple(dstslot, bsrcslot->base.tuple,
bsrcslot->buffer, false);
/*
- * Need to materialize because the HeapTupleData portion of the tuple
- * might be in a foreign memory context. That's annoying, but until
- * that's moved into the slot, unavoidable.
+ * The HeapTupleData portion of the source tuple might be shorter
+ * lived than the destination slot. Therefore copy the HeapTuple into
+ * our slot's tupdata, which is guaranteed to live long enough (but
+ * will still point into the buffer).
*/
- tts_buffer_heap_materialize(dstslot);
+ memcpy(&bdstslot->base.tupdata, bdstslot->base.tuple, sizeof(HeapTupleData));
+ bdstslot->base.tuple = &bdstslot->base.tupdata;
}
}