Split ExecStoreTuple into ExecStoreHeapTuple and ExecStoreBufferHeapTuple.
authorAndres Freund <andres@anarazel.de>
Tue, 25 Sep 2018 23:27:48 +0000 (16:27 -0700)
committerAndres Freund <andres@anarazel.de>
Tue, 25 Sep 2018 23:27:48 +0000 (16:27 -0700)
Upcoming changes introduce further types of tuple table slots, in
preparation of making table storage pluggable. New storage methods
will have different representation of tuples, therefore the slot
accessor should refer explicitly to heap tuples.

Instead of just renaming the functions, split it into one function
that accepts heap tuples not residing in buffers, and one accepting
ones in buffers.  Previously one function was used for both, but that
was a bit awkward already, and splitting will allow us to represent
slot types for tuples in buffers and normal memory separately.

This is split out from the patch introducing abstract slots, as this
largely consists out of mechanical changes.

Author: Ashutosh Bapat
Reviewed-By: Andres Freund
Discussion: https://postgr.es/m/20180220224318.gw4oe5jadhpmcdnm@alap3.anarazel.de

32 files changed:
contrib/postgres_fdw/postgres_fdw.c
src/backend/access/heap/heapam.c
src/backend/catalog/index.c
src/backend/catalog/indexing.c
src/backend/commands/analyze.c
src/backend/commands/constraint.c
src/backend/commands/copy.c
src/backend/commands/functioncmds.c
src/backend/commands/tablecmds.c
src/backend/commands/trigger.c
src/backend/executor/execIndexing.c
src/backend/executor/execMain.c
src/backend/executor/execPartition.c
src/backend/executor/execReplication.c
src/backend/executor/execScan.c
src/backend/executor/execTuples.c
src/backend/executor/nodeAgg.c
src/backend/executor/nodeBitmapHeapscan.c
src/backend/executor/nodeGather.c
src/backend/executor/nodeGatherMerge.c
src/backend/executor/nodeIndexonlyscan.c
src/backend/executor/nodeIndexscan.c
src/backend/executor/nodeModifyTable.c
src/backend/executor/nodeSamplescan.c
src/backend/executor/nodeSeqscan.c
src/backend/executor/nodeSetOp.c
src/backend/executor/nodeTidscan.c
src/backend/partitioning/partbounds.c
src/backend/replication/logical/worker.c
src/backend/utils/adt/selfuncs.c
src/backend/utils/sort/tuplesort.c
src/include/executor/tuptable.h

index e4e330397ee8cdcc4592a736270fefd0bf248e89..6cbba97c22390297dba25135e7d649aa28550a48 100644 (file)
@@ -1443,10 +1443,9 @@ postgresIterateForeignScan(ForeignScanState *node)
        /*
         * Return the next tuple.
         */
-       ExecStoreTuple(fsstate->tuples[fsstate->next_tuple++],
-                                  slot,
-                                  InvalidBuffer,
-                                  false);
+       ExecStoreHeapTuple(fsstate->tuples[fsstate->next_tuple++],
+                                          slot,
+                                          false);
 
        return slot;
 }
@@ -3517,7 +3516,7 @@ store_returning_result(PgFdwModifyState *fmstate,
                                                                                        NULL,
                                                                                        fmstate->temp_cxt);
                /* tuple will be deleted when it is cleared from the slot */
-               ExecStoreTuple(newtup, slot, InvalidBuffer, true);
+               ExecStoreHeapTuple(newtup, slot, true);
        }
        PG_CATCH();
        {
@@ -3790,7 +3789,7 @@ get_returning_data(ForeignScanState *node)
                                                                                                dmstate->retrieved_attrs,
                                                                                                node,
                                                                                                dmstate->temp_cxt);
-                       ExecStoreTuple(newtup, slot, InvalidBuffer, false);
+                       ExecStoreHeapTuple(newtup, slot, false);
                }
                PG_CATCH();
                {
index 56f1d82f962c43e44bc538f607b9b875972ca0e2..3395445a9a432621ea1000d44b3d0c50a3bd59c7 100644 (file)
@@ -4502,14 +4502,14 @@ ProjIndexIsUnchanged(Relation relation, HeapTuple oldtup, HeapTuple newtup)
                        int                     i;
 
                        ResetExprContext(econtext);
-                       ExecStoreTuple(oldtup, slot, InvalidBuffer, false);
+                       ExecStoreHeapTuple(oldtup, slot, false);
                        FormIndexDatum(indexInfo,
                                                   slot,
                                                   estate,
                                                   old_values,
                                                   old_isnull);
 
-                       ExecStoreTuple(newtup, slot, InvalidBuffer, false);
+                       ExecStoreHeapTuple(newtup, slot, false);
                        FormIndexDatum(indexInfo,
                                                   slot,
                                                   estate,
index 7eb3e351667c8c5b6b32cf18cc5dcf850352a30e..9229f619d29efa2f08b2bb91b32bb4286ce66703 100644 (file)
@@ -2866,7 +2866,7 @@ IndexBuildHeapRangeScan(Relation heapRelation,
                MemoryContextReset(econtext->ecxt_per_tuple_memory);
 
                /* Set up for predicate or expression evaluation */
-               ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);
+               ExecStoreHeapTuple(heapTuple, slot, false);
 
                /*
                 * In a partial index, discard tuples that don't satisfy the
@@ -3015,7 +3015,7 @@ IndexCheckExclusion(Relation heapRelation,
                MemoryContextReset(econtext->ecxt_per_tuple_memory);
 
                /* Set up for predicate or expression evaluation */
-               ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);
+               ExecStoreHeapTuple(heapTuple, slot, false);
 
                /*
                 * In a partial index, ignore tuples that don't satisfy the predicate.
@@ -3436,7 +3436,7 @@ validate_index_heapscan(Relation heapRelation,
                        MemoryContextReset(econtext->ecxt_per_tuple_memory);
 
                        /* Set up for predicate or expression evaluation */
-                       ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);
+                       ExecStoreHeapTuple(heapTuple, slot, false);
 
                        /*
                         * In a partial index, discard tuples that don't satisfy the
index 5a361683da4cc8d04b710e6803ba57d5255f5b8f..4674beaf3e77413d8179a64764e5fe3e2f2e1c57 100644 (file)
@@ -96,7 +96,7 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
 
        /* Need a slot to hold the tuple being examined */
        slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation));
-       ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);
+       ExecStoreHeapTuple(heapTuple, slot, false);
 
        /*
         * for each index, form and insert the index tuple
index 2503ac651022801e801cc3e21a5e1bbbbb60aafe..d11b559b20a382ac907c085a14921a4806bb9881 100644 (file)
@@ -799,7 +799,7 @@ compute_index_stats(Relation onerel, double totalrows,
                        ResetExprContext(econtext);
 
                        /* Set up for predicate or expression evaluation */
-                       ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);
+                       ExecStoreHeapTuple(heapTuple, slot, false);
 
                        /* If index is partial, check predicate */
                        if (predicate != NULL)
index 90f19ad3dd99bbb64c37085b01b8e444bc211ad5..f472355b48f676972c948ff55bf0052c90fac554 100644 (file)
@@ -124,7 +124,7 @@ unique_key_recheck(PG_FUNCTION_ARGS)
         */
        slot = MakeSingleTupleTableSlot(RelationGetDescr(trigdata->tg_relation));
 
-       ExecStoreTuple(new_row, slot, InvalidBuffer, false);
+       ExecStoreHeapTuple(new_row, slot, false);
 
        /*
         * Typically the index won't have expressions, but if it does we need an
index 9bc67ce60fe28b73ddbee7d8ae89477a741d03f2..d06662bd32eb86d4a4ac8880b78f1d777b843695 100644 (file)
@@ -2684,7 +2684,7 @@ CopyFrom(CopyState cstate)
 
                /* Place tuple in tuple slot --- but slot shouldn't free it */
                slot = myslot;
-               ExecStoreTuple(tuple, slot, InvalidBuffer, false);
+               ExecStoreHeapTuple(tuple, slot, false);
 
                /* Determine the partition to heap_insert the tuple into */
                if (proute)
@@ -3119,7 +3119,7 @@ CopyFromInsertBatch(CopyState cstate, EState *estate, CommandId mycid,
                        List       *recheckIndexes;
 
                        cstate->cur_lineno = firstBufferedLineNo + i;
-                       ExecStoreTuple(bufferedTuples[i], myslot, InvalidBuffer, false);
+                       ExecStoreHeapTuple(bufferedTuples[i], myslot, false);
                        recheckIndexes =
                                ExecInsertIndexTuples(myslot, &(bufferedTuples[i]->t_self),
                                                                          estate, false, NULL, NIL);
index 68109bfda063200d8724b6e5723052e0aa296c1b..6f629a00e8ac57287fafbd48f3eaa316ac328d79 100644 (file)
@@ -2337,7 +2337,7 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
                rettupdata.t_tableOid = InvalidOid;
                rettupdata.t_data = td;
 
-               slot = ExecStoreTuple(&rettupdata, tstate->slot, InvalidBuffer, false);
+               slot = ExecStoreHeapTuple(&rettupdata, tstate->slot, false);
                tstate->dest->receiveSlot(slot, tstate->dest);
 
                end_tup_output(tstate);
index 03c0b739b3643586c05ae76c5a797b55a7f15d65..1205dbc0b5e7c29ebe24f8eb0b8dfcb3590ee634 100644 (file)
@@ -4776,7 +4776,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
                                 * Process supplied expressions to replace selected columns.
                                 * Expression inputs come from the old tuple.
                                 */
-                               ExecStoreTuple(tuple, oldslot, InvalidBuffer, false);
+                               ExecStoreHeapTuple(tuple, oldslot, false);
                                econtext->ecxt_scantuple = oldslot;
 
                                foreach(l, tab->newvals)
@@ -4806,7 +4806,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
                        }
 
                        /* Now check any constraints on the possibly-changed tuple */
-                       ExecStoreTuple(tuple, newslot, InvalidBuffer, false);
+                       ExecStoreHeapTuple(tuple, newslot, false);
                        econtext->ecxt_scantuple = newslot;
 
                        foreach(l, notnull_attrs)
@@ -8526,7 +8526,7 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup)
 
        while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
        {
-               ExecStoreTuple(tuple, slot, InvalidBuffer, false);
+               ExecStoreHeapTuple(tuple, slot, false);
 
                if (!ExecCheck(exprstate, econtext))
                        ereport(ERROR,
index 0665f110ba34c966e32e6665f2f32534141de270..36778b6f4d54e3db36cfc67f0cd461063c5b6376 100644 (file)
@@ -2571,7 +2571,7 @@ ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
 
                if (newslot->tts_tupleDescriptor != tupdesc)
                        ExecSetSlotDescriptor(newslot, tupdesc);
-               ExecStoreTuple(newtuple, newslot, InvalidBuffer, false);
+               ExecStoreHeapTuple(newtuple, newslot, false);
                slot = newslot;
        }
        return slot;
@@ -2652,7 +2652,7 @@ ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
 
                if (newslot->tts_tupleDescriptor != tupdesc)
                        ExecSetSlotDescriptor(newslot, tupdesc);
-               ExecStoreTuple(newtuple, newslot, InvalidBuffer, false);
+               ExecStoreHeapTuple(newtuple, newslot, false);
                slot = newslot;
        }
        return slot;
@@ -3078,7 +3078,7 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate,
 
                if (newslot->tts_tupleDescriptor != tupdesc)
                        ExecSetSlotDescriptor(newslot, tupdesc);
-               ExecStoreTuple(newtuple, newslot, InvalidBuffer, false);
+               ExecStoreHeapTuple(newtuple, newslot, false);
                slot = newslot;
        }
        return slot;
@@ -3186,7 +3186,7 @@ ExecIRUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
 
                if (newslot->tts_tupleDescriptor != tupdesc)
                        ExecSetSlotDescriptor(newslot, tupdesc);
-               ExecStoreTuple(newtuple, newslot, InvalidBuffer, false);
+               ExecStoreHeapTuple(newtuple, newslot, false);
                slot = newslot;
        }
        return slot;
@@ -3514,7 +3514,7 @@ TriggerEnabled(EState *estate, ResultRelInfo *relinfo,
                        oldslot = estate->es_trig_oldtup_slot;
                        if (oldslot->tts_tupleDescriptor != tupdesc)
                                ExecSetSlotDescriptor(oldslot, tupdesc);
-                       ExecStoreTuple(oldtup, oldslot, InvalidBuffer, false);
+                       ExecStoreHeapTuple(oldtup, oldslot, false);
                }
                if (HeapTupleIsValid(newtup))
                {
@@ -3528,7 +3528,7 @@ TriggerEnabled(EState *estate, ResultRelInfo *relinfo,
                        newslot = estate->es_trig_newtup_slot;
                        if (newslot->tts_tupleDescriptor != tupdesc)
                                ExecSetSlotDescriptor(newslot, tupdesc);
-                       ExecStoreTuple(newtup, newslot, InvalidBuffer, false);
+                       ExecStoreHeapTuple(newtup, newslot, false);
                }
 
                /*
index 903076ee3c4a45851bbc7f0251a6326e1b27aa5d..9927ad70e66c948f8477c399fb19ad2c8122c65f 100644 (file)
@@ -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);
 
index 04f14c91787bfe83f0c7bdde7dcf333e6c6f585f..5443cbf67db356ad7af6e2acb5aedd6be34cb59f 100644 (file)
@@ -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);
                                                }
                                        }
 
index 38ecc4192eeeca3654845bf2132fdc8715577506..ec7a5267c34be6dee884dbd8a2faba4e8bc6ae67 100644 (file)
@@ -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;
 }
index 9a7dedf5aa22b887e9fd547b4a333f4194b3651e..25ba93e03c38f39a9a0523ac23f0d023faa58921 100644 (file)
@@ -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) ?
index f84a3fb0dbc8aca182d3a1299874f24d2f50b4fc..233cc280608ad7ff30a4dba07140c8442acac973 100644 (file)
@@ -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))
index c45dc246f68da5eb2f283a0c5f5367fd4e2ac688..573677af7253b2b0ad78ef7489b2c0cf5668a244 100644 (file)
  *
  *             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
+        * 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);
 }
 
 
index 0fe0c22c1ea4365cb79038c64f86fe1fcc9651fb..98d8483b7201d626bc5f5118a7cb7ede2a6c8b99 100644 (file)
@@ -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 */
index 3e1c9e07145e322fc6ee2192fe7dbc61b32aed10..baffae27e3e7fc6a87b8450e361563c9a641c742 100644 (file)
@@ -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
index 4a700b7b30e8fe7f5b8b086902d2060d99c91d48..ad16c783bd826152c55a890afc3bdb9746d00984 100644 (file)
@@ -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;
                        }
                }
index a0b3334bedf67dea9dec560eaedf5ed8d0bd77a7..a1a11dfda1d462a33e471d6a9ec7eb9916f984cb 100644 (file)
@@ -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;
 }
index 8c32a74d39ea1856bcdaffdbd0302436b3efcbf4..4b6d531810c6f714934a1dcf3eba5da7b16fb0ce 100644 (file)
@@ -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);
index 10891bc3f46d51d0ac0e5c5dcba7bd99933d03e2..6285a2114e8f29fae9c7b1a848802af7803a7819 100644 (file)
@@ -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
index d8d89c7983cb7508be96684ceab46522325d6d74..bf0d5e8edb5919f88e18f265e318023376ee120c 100644 (file)
@@ -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
index 15177dbed7a1f101eefa6a3ff2cb4061ac206c2c..99528be84a685573a0638297801a6d428ddf2dc0 100644 (file)
@@ -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);
 
index c7849de6bca69587484266d6e487dfc30126f9e2..cd53491be0a6a71530e4069d2e3eee5dbd84742b 100644 (file)
@@ -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);
 
index 3fa4a5fcc6554ccb328d48b901bdc155f8fcd196..3535b19c41d04d2d7a47574e757e37eb5ba5f476 100644 (file)
@@ -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 */
index e207b1ffb511d168d55c43296591dbc37108e3d0..0cb1946a3e3e4d6a327860714e7bda0ce4f9c80f 100644 (file)
@@ -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);
 
index 4ed99206181120171a96f7788639a173014a5fe3..c94f73aadc14201674ae07ad681595bfaf7f182c 100644 (file)
@@ -715,7 +715,7 @@ check_default_partition_contents(Relation parent, Relation default_rel,
 
                while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
                {
-                       ExecStoreTuple(tuple, tupslot, InvalidBuffer, false);
+                       ExecStoreHeapTuple(tuple, tupslot, false);
                        econtext->ecxt_scantuple = tupslot;
 
                        if (!ExecCheck(partqualstate, econtext))
index 2054abe6532d6c8ad41ed6461f2b32364bed4e1b..42345f94d33450e85c036e61830d3cf4c637b6be 100644 (file)
@@ -755,7 +755,7 @@ apply_handle_update(StringInfo s)
        {
                /* Process and store remote tuple in the slot */
                oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
-               ExecStoreTuple(localslot->tts_tuple, remoteslot, InvalidBuffer, false);
+               ExecStoreHeapTuple(localslot->tts_tuple, remoteslot, false);
                slot_modify_cstrings(remoteslot, rel, newtup.values, newtup.changed);
                MemoryContextSwitchTo(oldctx);
 
index f1c78ffb65631d11b7910e48f550cacbf0c5c751..b8c0e034ca1df01335439a9684c30bda5acd41f9 100644 (file)
@@ -5607,7 +5607,7 @@ get_actual_variable_range(PlannerInfo *root, VariableStatData *vardata,
                                                                                 indexscandir)) != NULL)
                                {
                                        /* Extract the index column values from the heap tuple */
-                                       ExecStoreTuple(tup, slot, InvalidBuffer, false);
+                                       ExecStoreHeapTuple(tup, slot, false);
                                        FormIndexDatum(indexInfo, slot, estate,
                                                                   values, isnull);
 
@@ -5640,7 +5640,7 @@ get_actual_variable_range(PlannerInfo *root, VariableStatData *vardata,
                                                                                 -indexscandir)) != NULL)
                                {
                                        /* Extract the index column values from the heap tuple */
-                                       ExecStoreTuple(tup, slot, InvalidBuffer, false);
+                                       ExecStoreHeapTuple(tup, slot, false);
                                        FormIndexDatum(indexInfo, slot, estate,
                                                                   values, isnull);
 
index 9fb33b9035e198782cc8e02efdc36485e4001641..a649dc54eb18219c3eb372ebb627b1b754e37ecd 100644 (file)
@@ -3792,11 +3792,11 @@ comparetup_cluster(const SortTuple *a, const SortTuple *b,
 
                ecxt_scantuple = GetPerTupleExprContext(state->estate)->ecxt_scantuple;
 
-               ExecStoreTuple(ltup, ecxt_scantuple, InvalidBuffer, false);
+               ExecStoreHeapTuple(ltup, ecxt_scantuple, false);
                FormIndexDatum(state->indexInfo, ecxt_scantuple, state->estate,
                                           l_index_values, l_index_isnull);
 
-               ExecStoreTuple(rtup, ecxt_scantuple, InvalidBuffer, false);
+               ExecStoreHeapTuple(rtup, ecxt_scantuple, false);
                FormIndexDatum(state->indexInfo, ecxt_scantuple, state->estate,
                                           r_index_values, r_index_isnull);
 
index c51d89b0c0a4542c54cb7b2bfe6119b26bf871d3..43150d13b1e9f26d8e2d69327c6a5121228b38e7 100644 (file)
@@ -153,10 +153,12 @@ extern void ExecResetTupleTable(List *tupleTable, bool shouldFree);
 extern TupleTableSlot *MakeSingleTupleTableSlot(TupleDesc tupdesc);
 extern void ExecDropSingleTupleTableSlot(TupleTableSlot *slot);
 extern void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc);
-extern TupleTableSlot *ExecStoreTuple(HeapTuple tuple,
-                          TupleTableSlot *slot,
-                          Buffer buffer,
-                          bool shouldFree);
+extern TupleTableSlot *ExecStoreHeapTuple(HeapTuple tuple,
+                                  TupleTableSlot *slot,
+                                  bool shouldFree);
+extern TupleTableSlot *ExecStoreBufferHeapTuple(HeapTuple tuple,
+                                                TupleTableSlot *slot,
+                                                Buffer buffer);
 extern TupleTableSlot *ExecStoreMinimalTuple(MinimalTuple mtup,
                                          TupleTableSlot *slot,
                                          bool shouldFree);