@@ -700,25 +700,36 @@ tts_buffer_heap_materialize(TupleTableSlot *slot)
700
700
701
701
slot -> tts_flags |= TTS_FLAG_SHOULDFREE ;
702
702
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
-
710
703
oldContext = MemoryContextSwitchTo (slot -> tts_mcxt );
711
- bslot -> base .tuple = heap_copytuple (bslot -> base .tuple );
712
- MemoryContextSwitchTo (oldContext );
713
704
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 );
722
733
723
734
/*
724
735
* Have to deform from scratch, otherwise tts_values[] entries could point
@@ -752,6 +763,9 @@ tts_buffer_heap_copyslot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
752
763
}
753
764
else
754
765
{
766
+ if (!bsrcslot -> base .tuple )
767
+ tts_buffer_heap_materialize (srcslot );
768
+
755
769
tts_buffer_heap_store_tuple (dstslot , bsrcslot -> base .tuple ,
756
770
bsrcslot -> buffer , false);
757
771
0 commit comments