summaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execIndexing.c2
-rw-r--r--src/backend/executor/execMain.c8
-rw-r--r--src/backend/executor/execPartition.c4
-rw-r--r--src/backend/executor/execReplication.c4
-rw-r--r--src/backend/executor/execScan.c4
-rw-r--r--src/backend/executor/execTuples.c124
-rw-r--r--src/backend/executor/nodeAgg.c7
-rw-r--r--src/backend/executor/nodeBitmapHeapscan.c7
-rw-r--r--src/backend/executor/nodeGather.c8
-rw-r--r--src/backend/executor/nodeGatherMerge.c9
-rw-r--r--src/backend/executor/nodeIndexonlyscan.c2
-rw-r--r--src/backend/executor/nodeIndexscan.c20
-rw-r--r--src/backend/executor/nodeModifyTable.c4
-rw-r--r--src/backend/executor/nodeSamplescan.c7
-rw-r--r--src/backend/executor/nodeSeqscan.c11
-rw-r--r--src/backend/executor/nodeSetOp.c7
-rw-r--r--src/backend/executor/nodeTidscan.c16
17 files changed, 135 insertions, 109 deletions
diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c
index 903076ee3c4..9927ad70e66 100644
--- a/src/backend/executor/execIndexing.c
+++ b/src/backend/executor/execIndexing.c
@@ -750,7 +750,7 @@ retry:
* Extract the index column values and isnull flags from the existing
* tuple.
*/
- ExecStoreTuple(tup, existing_slot, InvalidBuffer, false);
+ ExecStoreHeapTuple(tup, existing_slot, false);
FormIndexDatum(indexInfo, existing_slot, estate,
existing_values, existing_isnull);
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 04f14c91787..5443cbf67db 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1957,7 +1957,7 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo,
{
tuple = do_convert_tuple(tuple, map);
ExecSetSlotDescriptor(slot, tupdesc);
- ExecStoreTuple(tuple, slot, InvalidBuffer, false);
+ ExecStoreHeapTuple(tuple, slot, false);
}
}
@@ -2036,7 +2036,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
{
tuple = do_convert_tuple(tuple, map);
ExecSetSlotDescriptor(slot, tupdesc);
- ExecStoreTuple(tuple, slot, InvalidBuffer, false);
+ ExecStoreHeapTuple(tuple, slot, false);
}
}
@@ -2084,7 +2084,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
{
tuple = do_convert_tuple(tuple, map);
ExecSetSlotDescriptor(slot, tupdesc);
- ExecStoreTuple(tuple, slot, InvalidBuffer, false);
+ ExecStoreHeapTuple(tuple, slot, false);
}
}
@@ -2190,7 +2190,7 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo,
{
tuple = do_convert_tuple(tuple, map);
ExecSetSlotDescriptor(slot, tupdesc);
- ExecStoreTuple(tuple, slot, InvalidBuffer, false);
+ ExecStoreHeapTuple(tuple, slot, false);
}
}
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index 38ecc4192ee..ec7a5267c34 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -258,7 +258,7 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
if (myslot != NULL && map != NULL)
{
tuple = do_convert_tuple(tuple, map);
- ExecStoreTuple(tuple, myslot, InvalidBuffer, true);
+ ExecStoreHeapTuple(tuple, myslot, true);
slot = myslot;
}
@@ -842,7 +842,7 @@ ConvertPartitionTupleSlot(TupleConversionMap *map,
*p_my_slot = new_slot;
Assert(new_slot != NULL);
ExecSetSlotDescriptor(new_slot, map->outdesc);
- ExecStoreTuple(tuple, new_slot, InvalidBuffer, shouldFree);
+ ExecStoreHeapTuple(tuple, new_slot, shouldFree);
return tuple;
}
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index 9a7dedf5aa2..25ba93e03c3 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -146,7 +146,7 @@ retry:
if ((scantuple = index_getnext(scan, ForwardScanDirection)) != NULL)
{
found = true;
- ExecStoreTuple(scantuple, outslot, InvalidBuffer, false);
+ ExecStoreHeapTuple(scantuple, outslot, false);
ExecMaterializeSlot(outslot);
xwait = TransactionIdIsValid(snap.xmin) ?
@@ -310,7 +310,7 @@ retry:
continue;
found = true;
- ExecStoreTuple(scantuple, outslot, InvalidBuffer, false);
+ ExecStoreHeapTuple(scantuple, outslot, false);
ExecMaterializeSlot(outslot);
xwait = TransactionIdIsValid(snap.xmin) ?
diff --git a/src/backend/executor/execScan.c b/src/backend/executor/execScan.c
index f84a3fb0dbc..233cc280608 100644
--- a/src/backend/executor/execScan.c
+++ b/src/backend/executor/execScan.c
@@ -78,8 +78,8 @@ ExecScanFetch(ScanState *node,
return ExecClearTuple(slot);
/* Store test tuple in the plan node's scan slot */
- ExecStoreTuple(estate->es_epqTuple[scanrelid - 1],
- slot, InvalidBuffer, false);
+ ExecStoreHeapTuple(estate->es_epqTuple[scanrelid - 1],
+ slot, false);
/* Check if it meets the access-method conditions */
if (!(*recheckMtd) (node, slot))
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index c45dc246f68..573677af725 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -26,10 +26,10 @@
*
* During ExecutorRun()
* ----------------
- * - SeqNext() calls ExecStoreTuple() to place the tuple returned
- * by the access methods into the scan tuple slot.
+ * - SeqNext() calls ExecStoreBufferHeapTuple() to place the tuple
+ * returned by the access methods into the scan tuple slot.
*
- * - ExecSeqScan() calls ExecStoreTuple() to take the result
+ * - ExecSeqScan() calls ExecStoreHeapTuple() to take the result
* tuple from ExecProject() and place it into the result tuple slot.
*
* - ExecutePlan() calls the output function.
@@ -287,48 +287,88 @@ ExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */
}
/* --------------------------------
- * ExecStoreTuple
+ * ExecStoreHeapTuple
*
- * This function is used to store a physical tuple into a specified
+ * This function is used to store an on-the-fly physical tuple into a specified
* slot in the tuple table.
*
* tuple: tuple to store
* slot: slot to store it in
- * buffer: disk buffer if tuple is in a disk page, else InvalidBuffer
* shouldFree: true if ExecClearTuple should pfree() the tuple
* when done with it
*
- * If 'buffer' is not InvalidBuffer, the tuple table code acquires a pin
- * on the buffer which is held until the slot is cleared, so that the tuple
- * won't go away on us.
+ * shouldFree is normally set 'true' for tuples constructed on-the-fly. But it
+ * can be 'false' when the referenced tuple is held in a tuple table slot
+ * belonging to a lower-level executor Proc node. In this case the lower-level
+ * slot retains ownership and responsibility for eventually releasing the
+ * tuple. When this method is used, we must be certain that the upper-level
+ * Proc node will lose interest in the tuple sooner than the lower-level one
+ * does! If you're not certain, copy the lower-level tuple with heap_copytuple
+ * and let the upper-level table slot assume ownership of the copy!
*
- * shouldFree is normally set 'true' for tuples constructed on-the-fly.
- * It must always be 'false' for tuples that are stored in disk pages,
- * since we don't want to try to pfree those.
+ * Return value is just the passed-in slot pointer.
+ * --------------------------------
+ */
+TupleTableSlot *
+ExecStoreHeapTuple(HeapTuple tuple,
+ TupleTableSlot *slot,
+ bool shouldFree)
+{
+ /*
+ * sanity checks
+ */
+ Assert(tuple != NULL);
+ Assert(slot != NULL);
+ Assert(slot->tts_tupleDescriptor != NULL);
+
+ /*
+ * Free any old physical tuple belonging to the slot.
+ */
+ if (slot->tts_shouldFree)
+ heap_freetuple(slot->tts_tuple);
+ if (slot->tts_shouldFreeMin)
+ heap_free_minimal_tuple(slot->tts_mintuple);
+
+ /*
+ * Store the new tuple into the specified slot.
+ */
+ slot->tts_isempty = false;
+ slot->tts_shouldFree = shouldFree;
+ slot->tts_shouldFreeMin = false;
+ slot->tts_tuple = tuple;
+ slot->tts_mintuple = NULL;
+
+ /* Mark extracted state invalid */
+ slot->tts_nvalid = 0;
+
+ /* Unpin any buffer pinned by the slot. */
+ if (BufferIsValid(slot->tts_buffer))
+ ReleaseBuffer(slot->tts_buffer);
+ slot->tts_buffer = InvalidBuffer;
+
+ return slot;
+}
+
+/* --------------------------------
+ * ExecStoreBufferHeapTuple
*
- * Another case where it is 'false' is when the referenced tuple is held
- * in a tuple table slot belonging to a lower-level executor Proc node.
- * In this case the lower-level slot retains ownership and responsibility
- * for eventually releasing the tuple. When this method is used, we must
- * be certain that the upper-level Proc node will lose interest in the tuple
- * sooner than the lower-level one does! If you're not certain, copy the
- * lower-level tuple with heap_copytuple and let the upper-level table
- * slot assume ownership of the copy!
+ * This function is used to store an on-disk physical tuple from a buffer
+ * into a specified slot in the tuple table.
*
- * Return value is just the passed-in slot pointer.
+ * tuple: tuple to store
+ * slot: slot to store it in
+ * buffer: disk buffer if tuple is in a disk page, else InvalidBuffer
+ *
+ * The tuple table code acquires a pin on the buffer which is held until the
+ * slot is cleared, so that the tuple won't go away on us.
*
- * NOTE: before PostgreSQL 8.1, this function would accept a NULL tuple
- * pointer and effectively behave like ExecClearTuple (though you could
- * still specify a buffer to pin, which would be an odd combination).
- * This saved a couple lines of code in a few places, but seemed more likely
- * to mask logic errors than to be really useful, so it's now disallowed.
+ * Return value is just the passed-in slot pointer.
* --------------------------------
*/
TupleTableSlot *
-ExecStoreTuple(HeapTuple tuple,
- TupleTableSlot *slot,
- Buffer buffer,
- bool shouldFree)
+ExecStoreBufferHeapTuple(HeapTuple tuple,
+ TupleTableSlot *slot,
+ Buffer buffer)
{
/*
* sanity checks
@@ -336,8 +376,7 @@ ExecStoreTuple(HeapTuple tuple,
Assert(tuple != NULL);
Assert(slot != NULL);
Assert(slot->tts_tupleDescriptor != NULL);
- /* passing shouldFree=true for a tuple on a disk page is not sane */
- Assert(BufferIsValid(buffer) ? (!shouldFree) : true);
+ Assert(BufferIsValid(buffer));
/*
* Free any old physical tuple belonging to the slot.
@@ -351,7 +390,7 @@ ExecStoreTuple(HeapTuple tuple,
* Store the new tuple into the specified slot.
*/
slot->tts_isempty = false;
- slot->tts_shouldFree = shouldFree;
+ slot->tts_shouldFree = false;
slot->tts_shouldFreeMin = false;
slot->tts_tuple = tuple;
slot->tts_mintuple = NULL;
@@ -360,21 +399,20 @@ ExecStoreTuple(HeapTuple tuple,
slot->tts_nvalid = 0;
/*
- * If tuple is on a disk page, keep the page pinned as long as we hold a
- * pointer into it. We assume the caller already has such a pin.
+ * Keep the disk page containing the given tuple pinned as long as we hold
+ * a pointer into it. We assume the caller already has such a pin.
*
* This is coded to optimize the case where the slot previously held a
- * tuple on the same disk page: in that case releasing and re-acquiring
- * the pin is a waste of cycles. This is a common situation during
- * seqscans, so it's worth troubling over.
+ * tuple on the same disk page: in that case releasing and re-acquiring the
+ * pin is a waste of cycles. This is a common situation during seqscans,
+ * so it's worth troubling over.
*/
if (slot->tts_buffer != buffer)
{
if (BufferIsValid(slot->tts_buffer))
ReleaseBuffer(slot->tts_buffer);
slot->tts_buffer = buffer;
- if (BufferIsValid(buffer))
- IncrBufferRefCount(buffer);
+ IncrBufferRefCount(buffer);
}
return slot;
@@ -383,7 +421,7 @@ ExecStoreTuple(HeapTuple tuple,
/* --------------------------------
* ExecStoreMinimalTuple
*
- * Like ExecStoreTuple, but insert a "minimal" tuple into the slot.
+ * Like ExecStoreHeapTuple, but insert a "minimal" tuple into the slot.
*
* No 'buffer' parameter since minimal tuples are never stored in relations.
* --------------------------------
@@ -652,7 +690,7 @@ ExecFetchSlotTuple(TupleTableSlot *slot)
tuple = heap_expand_tuple(slot->tts_tuple,
slot->tts_tupleDescriptor);
MemoryContextSwitchTo(oldContext);
- slot = ExecStoreTuple(tuple, slot, InvalidBuffer, true);
+ slot = ExecStoreHeapTuple(tuple, slot, true);
}
return slot->tts_tuple;
}
@@ -834,7 +872,7 @@ ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
newTuple = ExecCopySlotTuple(srcslot);
MemoryContextSwitchTo(oldContext);
- return ExecStoreTuple(newTuple, dstslot, InvalidBuffer, true);
+ return ExecStoreHeapTuple(newTuple, dstslot, true);
}
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 0fe0c22c1ea..98d8483b720 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -1799,10 +1799,9 @@ agg_retrieve_direct(AggState *aggstate)
* reserved for it. The tuple will be deleted when it is
* cleared from the slot.
*/
- ExecStoreTuple(aggstate->grp_firstTuple,
- firstSlot,
- InvalidBuffer,
- true);
+ ExecStoreHeapTuple(aggstate->grp_firstTuple,
+ firstSlot,
+ true);
aggstate->grp_firstTuple = NULL; /* don't keep two pointers */
/* set up for first advance_aggregates call */
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 3e1c9e07145..baffae27e3e 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -340,10 +340,9 @@ BitmapHeapNext(BitmapHeapScanState *node)
* Set up the result slot to point to this tuple. Note that the
* slot acquires a pin on the buffer.
*/
- ExecStoreTuple(&scan->rs_ctup,
- slot,
- scan->rs_cbuf,
- false);
+ ExecStoreBufferHeapTuple(&scan->rs_ctup,
+ slot,
+ scan->rs_cbuf);
/*
* If we are using lossy info, we have to recheck the qual
diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c
index 4a700b7b30e..ad16c783bd8 100644
--- a/src/backend/executor/nodeGather.c
+++ b/src/backend/executor/nodeGather.c
@@ -257,11 +257,9 @@ gather_getnext(GatherState *gatherstate)
if (HeapTupleIsValid(tup))
{
- ExecStoreTuple(tup, /* tuple to store */
- fslot, /* slot in which to store the tuple */
- InvalidBuffer, /* buffer associated with this
- * tuple */
- true); /* pfree tuple when done with it */
+ ExecStoreHeapTuple(tup, /* tuple to store */
+ fslot, /* slot to store the tuple */
+ true); /* pfree tuple when done with it */
return fslot;
}
}
diff --git a/src/backend/executor/nodeGatherMerge.c b/src/backend/executor/nodeGatherMerge.c
index a0b3334bedf..a1a11dfda1d 100644
--- a/src/backend/executor/nodeGatherMerge.c
+++ b/src/backend/executor/nodeGatherMerge.c
@@ -679,11 +679,10 @@ gather_merge_readnext(GatherMergeState *gm_state, int reader, bool nowait)
Assert(HeapTupleIsValid(tup));
/* Build the TupleTableSlot for the given tuple */
- ExecStoreTuple(tup, /* tuple to store */
- gm_state->gm_slots[reader], /* slot in which to store the
- * tuple */
- InvalidBuffer, /* no buffer associated with tuple */
- true); /* pfree tuple when done with it */
+ ExecStoreHeapTuple(tup, /* tuple to store */
+ gm_state->gm_slots[reader], /* slot in which to store
+ * the tuple */
+ true); /* pfree tuple when done with it */
return true;
}
diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c
index 8c32a74d39e..4b6d531810c 100644
--- a/src/backend/executor/nodeIndexonlyscan.c
+++ b/src/backend/executor/nodeIndexonlyscan.c
@@ -199,7 +199,7 @@ IndexOnlyNext(IndexOnlyScanState *node)
*/
Assert(slot->tts_tupleDescriptor->natts ==
scandesc->xs_hitupdesc->natts);
- ExecStoreTuple(scandesc->xs_hitup, slot, InvalidBuffer, false);
+ ExecStoreHeapTuple(scandesc->xs_hitup, slot, false);
}
else if (scandesc->xs_itup)
StoreIndexTuple(slot, scandesc->xs_itup, scandesc->xs_itupdesc);
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 10891bc3f46..6285a2114e8 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -140,10 +140,10 @@ IndexNext(IndexScanState *node)
* Note: we pass 'false' because tuples returned by amgetnext are
* pointers onto disk pages and must not be pfree()'d.
*/
- ExecStoreTuple(tuple, /* tuple to store */
- slot, /* slot to store in */
- scandesc->xs_cbuf, /* buffer containing tuple */
- false); /* don't pfree */
+ ExecStoreBufferHeapTuple(tuple, /* tuple to store */
+ slot, /* slot to store in */
+ scandesc->xs_cbuf); /* buffer containing
+ * tuple */
/*
* If the index was lossy, we have to recheck the index quals using
@@ -257,7 +257,7 @@ IndexNextWithReorder(IndexScanState *node)
tuple = reorderqueue_pop(node);
/* Pass 'true', as the tuple in the queue is a palloc'd copy */
- ExecStoreTuple(tuple, slot, InvalidBuffer, true);
+ ExecStoreHeapTuple(tuple, slot, true);
return slot;
}
}
@@ -284,13 +284,11 @@ next_indextuple:
/*
* Store the scanned tuple in the scan tuple slot of the scan state.
- * Note: we pass 'false' because tuples returned by amgetnext are
- * pointers onto disk pages and must not be pfree()'d.
*/
- ExecStoreTuple(tuple, /* tuple to store */
- slot, /* slot to store in */
- scandesc->xs_cbuf, /* buffer containing tuple */
- false); /* don't pfree */
+ ExecStoreBufferHeapTuple(tuple, /* tuple to store */
+ slot, /* slot to store in */
+ scandesc->xs_cbuf); /* buffer containing
+ * tuple */
/*
* If the index was lossy, we have to recheck the index quals and
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index d8d89c7983c..bf0d5e8edb5 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -888,7 +888,7 @@ ldelete:;
if (slot->tts_tupleDescriptor != RelationGetDescr(resultRelationDesc))
ExecSetSlotDescriptor(slot, RelationGetDescr(resultRelationDesc));
- ExecStoreTuple(&deltuple, slot, InvalidBuffer, false);
+ ExecStoreHeapTuple(&deltuple, slot, false);
}
rslot = ExecProcessReturning(resultRelInfo, slot, planSlot);
@@ -1479,7 +1479,7 @@ ExecOnConflictUpdate(ModifyTableState *mtstate,
ExecCheckHeapTupleVisible(estate, &tuple, buffer);
/* Store target's existing tuple in the state's dedicated slot */
- ExecStoreTuple(&tuple, mtstate->mt_existing, buffer, false);
+ ExecStoreBufferHeapTuple(&tuple, mtstate->mt_existing, buffer);
/*
* Make tuple and any needed join variables available to ExecQual and
diff --git a/src/backend/executor/nodeSamplescan.c b/src/backend/executor/nodeSamplescan.c
index 15177dbed7a..99528be84a6 100644
--- a/src/backend/executor/nodeSamplescan.c
+++ b/src/backend/executor/nodeSamplescan.c
@@ -63,10 +63,9 @@ SampleNext(SampleScanState *node)
slot = node->ss.ss_ScanTupleSlot;
if (tuple)
- ExecStoreTuple(tuple, /* tuple to store */
- slot, /* slot to store in */
- node->ss.ss_currentScanDesc->rs_cbuf, /* tuple's buffer */
- false); /* don't pfree this pointer */
+ ExecStoreBufferHeapTuple(tuple, /* tuple to store */
+ slot, /* slot to store in */
+ node->ss.ss_currentScanDesc->rs_cbuf); /* tuple's buffer */
else
ExecClearTuple(slot);
diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c
index c7849de6bca..cd53491be0a 100644
--- a/src/backend/executor/nodeSeqscan.c
+++ b/src/backend/executor/nodeSeqscan.c
@@ -84,15 +84,14 @@ SeqNext(SeqScanState *node)
* our scan tuple slot and return the slot. Note: we pass 'false' because
* tuples returned by heap_getnext() are pointers onto disk pages and were
* not created with palloc() and so should not be pfree()'d. Note also
- * that ExecStoreTuple will increment the refcount of the buffer; the
+ * that ExecStoreHeapTuple will increment the refcount of the buffer; the
* refcount will not be dropped until the tuple table slot is cleared.
*/
if (tuple)
- ExecStoreTuple(tuple, /* tuple to store */
- slot, /* slot to store in */
- scandesc->rs_cbuf, /* buffer associated with this
- * tuple */
- false); /* don't pfree this pointer */
+ ExecStoreBufferHeapTuple(tuple, /* tuple to store */
+ slot, /* slot to store in */
+ scandesc->rs_cbuf); /* buffer associated
+ * with this tuple */
else
ExecClearTuple(slot);
diff --git a/src/backend/executor/nodeSetOp.c b/src/backend/executor/nodeSetOp.c
index 3fa4a5fcc65..3535b19c41d 100644
--- a/src/backend/executor/nodeSetOp.c
+++ b/src/backend/executor/nodeSetOp.c
@@ -267,10 +267,9 @@ setop_retrieve_direct(SetOpState *setopstate)
* for it. The tuple will be deleted when it is cleared from the
* slot.
*/
- ExecStoreTuple(setopstate->grp_firstTuple,
- resultTupleSlot,
- InvalidBuffer,
- true);
+ ExecStoreHeapTuple(setopstate->grp_firstTuple,
+ resultTupleSlot,
+ true);
setopstate->grp_firstTuple = NULL; /* don't keep two pointers */
/* Initialize working state for a new input tuple group */
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index e207b1ffb51..0cb1946a3e3 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -377,20 +377,18 @@ TidNext(TidScanState *node)
if (heap_fetch(heapRelation, snapshot, tuple, &buffer, false, NULL))
{
/*
- * store the scanned tuple in the scan tuple slot of the scan
+ * Store the scanned tuple in the scan tuple slot of the scan
* state. Eventually we will only do this and not return a tuple.
- * Note: we pass 'false' because tuples returned by amgetnext are
- * pointers onto disk pages and were not created with palloc() and
- * so should not be pfree()'d.
*/
- ExecStoreTuple(tuple, /* tuple to store */
- slot, /* slot to store in */
- buffer, /* buffer associated with tuple */
- false); /* don't pfree */
+ ExecStoreBufferHeapTuple(tuple, /* tuple to store */
+ slot, /* slot to store in */
+ buffer); /* buffer associated with
+ * tuple */
/*
* At this point we have an extra pin on the buffer, because
- * ExecStoreTuple incremented the pin count. Drop our local pin.
+ * ExecStoreHeapTuple incremented the pin count. Drop our local
+ * pin.
*/
ReleaseBuffer(buffer);