@@ -74,7 +74,11 @@ static TupleDesc ExecTypeFromTLInternal(List *targetList,
74
74
static pg_attribute_always_inline void
75
75
slot_deform_heap_tuple (TupleTableSlot * slot , HeapTuple tuple , uint32 * offp ,
76
76
int natts );
77
- static void tts_buffer_heap_store_tuple (TupleTableSlot * slot , HeapTuple tuple , Buffer buffer );
77
+ static inline void tts_buffer_heap_store_tuple (TupleTableSlot * slot ,
78
+ HeapTuple tuple ,
79
+ Buffer buffer ,
80
+ bool transfer_pin );
81
+ static void tts_heap_store_tuple (TupleTableSlot * slot , HeapTuple tuple , bool shouldFree );
78
82
79
83
80
84
const TupleTableSlotOps TTSOpsVirtual ;
@@ -743,7 +747,9 @@ tts_buffer_heap_copyslot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
743
747
}
744
748
else
745
749
{
746
- tts_buffer_heap_store_tuple (dstslot , bsrcslot -> base .tuple , bsrcslot -> buffer );
750
+ tts_buffer_heap_store_tuple (dstslot , bsrcslot -> base .tuple ,
751
+ bsrcslot -> buffer , false);
752
+
747
753
/*
748
754
* Need to materialize because the HeapTupleData portion of the tuple
749
755
* might be in a foreign memory context. That's annoying, but until
@@ -792,8 +798,9 @@ tts_buffer_heap_copy_minimal_tuple(TupleTableSlot *slot)
792
798
return minimal_tuple_from_heap_tuple (bslot -> base .tuple );
793
799
}
794
800
795
- static void
796
- tts_buffer_heap_store_tuple (TupleTableSlot * slot , HeapTuple tuple , Buffer buffer )
801
+ static inline void
802
+ tts_buffer_heap_store_tuple (TupleTableSlot * slot , HeapTuple tuple ,
803
+ Buffer buffer , bool transfer_pin )
797
804
{
798
805
BufferHeapTupleTableSlot * bslot = (BufferHeapTupleTableSlot * ) slot ;
799
806
@@ -813,7 +820,9 @@ tts_buffer_heap_store_tuple(TupleTableSlot *slot, HeapTuple tuple, Buffer buffer
813
820
814
821
/*
815
822
* If tuple is on a disk page, keep the page pinned as long as we hold a
816
- * pointer into it. We assume the caller already has such a pin.
823
+ * pointer into it. We assume the caller already has such a pin. If
824
+ * transfer_pin is true, we'll transfer that pin to this slot, if not
825
+ * we'll pin it again ourselves.
817
826
*
818
827
* This is coded to optimize the case where the slot previously held a
819
828
* tuple on the same disk page: in that case releasing and re-acquiring
@@ -824,8 +833,19 @@ tts_buffer_heap_store_tuple(TupleTableSlot *slot, HeapTuple tuple, Buffer buffer
824
833
{
825
834
if (BufferIsValid (bslot -> buffer ))
826
835
ReleaseBuffer (bslot -> buffer );
836
+
827
837
bslot -> buffer = buffer ;
828
- IncrBufferRefCount (buffer );
838
+
839
+ if (!transfer_pin && BufferIsValid (buffer ))
840
+ IncrBufferRefCount (buffer );
841
+ }
842
+ else if (transfer_pin && BufferIsValid (buffer ))
843
+ {
844
+ /*
845
+ * In transfer_pin mode the caller won't know about the same-page
846
+ * optimization, so we gotta release its pin.
847
+ */
848
+ ReleaseBuffer (buffer );
829
849
}
830
850
}
831
851
@@ -1321,7 +1341,32 @@ ExecStoreBufferHeapTuple(HeapTuple tuple,
1321
1341
1322
1342
if (unlikely (!TTS_IS_BUFFERTUPLE (slot )))
1323
1343
elog (ERROR , "trying to store an on-disk heap tuple into wrong type of slot" );
1324
- tts_buffer_heap_store_tuple (slot , tuple , buffer );
1344
+ tts_buffer_heap_store_tuple (slot , tuple , buffer , false);
1345
+
1346
+
1347
+ return slot ;
1348
+ }
1349
+
1350
+ /*
1351
+ * Like ExecStoreBufferHeapTuple, but transfer an existing pin from the caller
1352
+ * to the slot, i.e. the caller doesn't need to, and may not, release the pin.
1353
+ */
1354
+ TupleTableSlot *
1355
+ ExecStorePinnedBufferHeapTuple (HeapTuple tuple ,
1356
+ TupleTableSlot * slot ,
1357
+ Buffer buffer )
1358
+ {
1359
+ /*
1360
+ * sanity checks
1361
+ */
1362
+ Assert (tuple != NULL );
1363
+ Assert (slot != NULL );
1364
+ Assert (slot -> tts_tupleDescriptor != NULL );
1365
+ Assert (BufferIsValid (buffer ));
1366
+
1367
+ if (unlikely (!TTS_IS_BUFFERTUPLE (slot )))
1368
+ elog (ERROR , "trying to store an on-disk heap tuple into wrong type of slot" );
1369
+ tts_buffer_heap_store_tuple (slot , tuple , buffer , true);
1325
1370
1326
1371
return slot ;
1327
1372
}
0 commit comments