Skip to content

Commit f414abd

Browse files
committed
Allow buffer tuple table slots to materialize after ExecStoreVirtualTuple().
While not common, it can be useful to store a virtual tuple into a buffer tuple table slot, and then materialize that slot. So far we've asserted out, which surprisingly wasn't a problem for anything in core. But that seems fragile, and it also breaks redis_fdw after ff11e7f. Thus, allow materializing a virtual tuple stored in a buffer tuple table slot. Author: Andres Freund Discussion: https://postgr.es/m/20190227181621.xholonj7ff7ohxsg@alap3.anarazel.de https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
1 parent 19455c9 commit f414abd

File tree

1 file changed

+31
-17
lines changed

1 file changed

+31
-17
lines changed

src/backend/executor/execTuples.c

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -700,25 +700,36 @@ tts_buffer_heap_materialize(TupleTableSlot *slot)
700700

701701
slot->tts_flags |= TTS_FLAG_SHOULDFREE;
702702

703-
/*
704-
* A heap tuple stored in a BufferHeapTupleTableSlot should have a buffer
705-
* associated with it, unless it's materialized (which would've returned
706-
* above).
707-
*/
708-
Assert(bslot->base.tuple);
709-
710703
oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
711-
bslot->base.tuple = heap_copytuple(bslot->base.tuple);
712-
MemoryContextSwitchTo(oldContext);
713704

714-
/*
715-
* A heap tuple stored in a BufferHeapTupleTableSlot should have a buffer
716-
* associated with it, unless it's materialized.
717-
*/
718-
Assert(BufferIsValid(bslot->buffer));
719-
if (likely(BufferIsValid(bslot->buffer)))
720-
ReleaseBuffer(bslot->buffer);
721-
bslot->buffer = InvalidBuffer;
705+
if (!bslot->base.tuple)
706+
{
707+
/*
708+
* Normally BufferHeapTupleTableSlot should have a tuple + buffer
709+
* associated with it, unless it's materialized (which would've
710+
* returned above). But when it's useful to allow storing virtual
711+
* tuples in a buffer slot, which then also needs to be
712+
* materializable.
713+
*/
714+
bslot->base.tuple = heap_form_tuple(slot->tts_tupleDescriptor,
715+
slot->tts_values,
716+
slot->tts_isnull);
717+
718+
}
719+
else
720+
{
721+
bslot->base.tuple = heap_copytuple(bslot->base.tuple);
722+
723+
/*
724+
* A heap tuple stored in a BufferHeapTupleTableSlot should have a
725+
* buffer associated with it, unless it's materialized or virtual.
726+
*/
727+
Assert(BufferIsValid(bslot->buffer));
728+
if (likely(BufferIsValid(bslot->buffer)))
729+
ReleaseBuffer(bslot->buffer);
730+
bslot->buffer = InvalidBuffer;
731+
}
732+
MemoryContextSwitchTo(oldContext);
722733

723734
/*
724735
* Have to deform from scratch, otherwise tts_values[] entries could point
@@ -752,6 +763,9 @@ tts_buffer_heap_copyslot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
752763
}
753764
else
754765
{
766+
if (!bsrcslot->base.tuple)
767+
tts_buffer_heap_materialize(srcslot);
768+
755769
tts_buffer_heap_store_tuple(dstslot, bsrcslot->base.tuple,
756770
bsrcslot->buffer, false);
757771

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy