LCOV - code coverage report
Current view: top level - src/include/executor - tuptable.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 41 41
Test Date: 2026-03-24 02:15:55 Functions: 100.0 % 12 12
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * tuptable.h
       4              :  *    tuple table support stuff
       5              :  *
       6              :  *
       7              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       8              :  * Portions Copyright (c) 1994, Regents of the University of California
       9              :  *
      10              :  * src/include/executor/tuptable.h
      11              :  *
      12              :  *-------------------------------------------------------------------------
      13              :  */
      14              : #ifndef TUPTABLE_H
      15              : #define TUPTABLE_H
      16              : 
      17              : #include "access/htup.h"
      18              : #include "access/sysattr.h"
      19              : #include "access/tupdesc.h"
      20              : #include "storage/buf.h"
      21              : 
      22              : /*----------
      23              :  * The executor stores tuples in a "tuple table" which is a List of
      24              :  * independent TupleTableSlots.
      25              :  *
      26              :  * There's various different types of tuple table slots, each being able to
      27              :  * store different types of tuples. Additional types of slots can be added
      28              :  * without modifying core code. The type of a slot is determined by the
      29              :  * TupleTableSlotOps* passed to the slot creation routine. The builtin types
      30              :  * of slots are
      31              :  *
      32              :  * 1. physical tuple in a disk buffer page (TTSOpsBufferHeapTuple)
      33              :  * 2. physical tuple constructed in palloc'ed memory (TTSOpsHeapTuple)
      34              :  * 3. "minimal" physical tuple constructed in palloc'ed memory
      35              :  *    (TTSOpsMinimalTuple)
      36              :  * 4. "virtual" tuple consisting of Datum/isnull arrays (TTSOpsVirtual)
      37              :  *
      38              :  *
      39              :  * The first two cases are similar in that they both deal with "materialized"
      40              :  * tuples, but resource management is different.  For a tuple in a disk page
      41              :  * we need to hold a pin on the buffer until the TupleTableSlot's reference
      42              :  * to the tuple is dropped; while for a palloc'd tuple we usually want the
      43              :  * tuple pfree'd when the TupleTableSlot's reference is dropped.
      44              :  *
      45              :  * A "minimal" tuple is handled similarly to a palloc'd regular tuple.
      46              :  * At present, minimal tuples never are stored in buffers, so there is no
      47              :  * parallel to case 1.  Note that a minimal tuple has no "system columns".
      48              :  *
      49              :  * A "virtual" tuple is an optimization used to minimize physical data copying
      50              :  * in a nest of plan nodes.  Until materialized pass-by-reference Datums in
      51              :  * the slot point to storage that is not directly associated with the
      52              :  * TupleTableSlot; generally they will point to part of a tuple stored in a
      53              :  * lower plan node's output TupleTableSlot, or to a function result
      54              :  * constructed in a plan node's per-tuple econtext.  It is the responsibility
      55              :  * of the generating plan node to be sure these resources are not released for
      56              :  * as long as the virtual tuple needs to be valid or is materialized.  Note
      57              :  * also that a virtual tuple does not have any "system columns".
      58              :  *
      59              :  * The Datum/isnull arrays of a TupleTableSlot serve double duty.  For virtual
      60              :  * slots they are the authoritative data.  For the other builtin slots,
      61              :  * the arrays contain data extracted from the tuple.  (In this state, any
      62              :  * pass-by-reference Datums point into the physical tuple.)  The extracted
      63              :  * information is built "lazily", ie, only as needed.  This serves to avoid
      64              :  * repeated extraction of data from the physical tuple.
      65              :  *
      66              :  * A TupleTableSlot can also be "empty", indicated by flag TTS_FLAG_EMPTY set
      67              :  * in tts_flags, holding no valid data.  This is the only valid state for a
      68              :  * freshly-created slot that has not yet had a tuple descriptor assigned to
      69              :  * it.  In this state, TTS_FLAG_SHOULDFREE should not be set in tts_flags and
      70              :  * tts_nvalid should be set to zero.
      71              :  *
      72              :  * The tupleDescriptor is simply referenced, not copied, by the TupleTableSlot
      73              :  * code.  The caller of ExecSetSlotDescriptor() is responsible for providing
      74              :  * a descriptor that will live as long as the slot does.  (Typically, both
      75              :  * slots and descriptors are in per-query memory and are freed by memory
      76              :  * context deallocation at query end; so it's not worth providing any extra
      77              :  * mechanism to do more.  However, the slot will increment the tupdesc
      78              :  * reference count if a reference-counted tupdesc is supplied.)
      79              :  *
      80              :  * When TTS_FLAG_SHOULDFREE is set in tts_flags, the physical tuple is "owned"
      81              :  * by the slot and should be freed when the slot's reference to the tuple is
      82              :  * dropped.
      83              :  *
      84              :  * tts_values/tts_isnull are allocated either when the slot is created (when
      85              :  * the descriptor is provided), or when a descriptor is assigned to the slot;
      86              :  * they are of length equal to the descriptor's natts.
      87              :  *----------
      88              :  */
      89              : 
      90              : /* true = slot is empty */
      91              : #define         TTS_FLAG_EMPTY          (1 << 1)
      92              : #define TTS_EMPTY(slot) (((slot)->tts_flags & TTS_FLAG_EMPTY) != 0)
      93              : 
      94              : /* should pfree tuple "owned" by the slot? */
      95              : #define         TTS_FLAG_SHOULDFREE     (1 << 2)
      96              : #define TTS_SHOULDFREE(slot) (((slot)->tts_flags & TTS_FLAG_SHOULDFREE) != 0)
      97              : 
      98              : /*
      99              :  * true = slot's formed tuple guaranteed to not have NULLs in NOT NULLable
     100              :  * columns.
     101              :  */
     102              : #define         TTS_FLAG_OBEYS_NOT_NULL_CONSTRAINTS     (1 << 3)
     103              : #define TTS_OBEYS_NOT_NULL_CONSTRAINTS(slot) \
     104              :     (((slot)->tts_flags & TTS_FLAG_OBEYS_NOT_NULL_CONSTRAINTS) != 0)
     105              : 
     106              : /* fixed tuple descriptor */
     107              : #define         TTS_FLAG_FIXED      (1 << 4)
     108              : #define TTS_FIXED(slot) (((slot)->tts_flags & TTS_FLAG_FIXED) != 0)
     109              : 
     110              : /*
     111              :  * Defines which of the above flags should never be set in tts_flags when the
     112              :  * TupleTableSlot is created.
     113              :  */
     114              : #define         TTS_FLAGS_TRANSIENT (TTS_FLAG_EMPTY|TTS_FLAG_SHOULDFREE)
     115              : 
     116              : struct TupleTableSlotOps;
     117              : typedef struct TupleTableSlotOps TupleTableSlotOps;
     118              : 
     119              : /* base tuple table slot type */
     120              : typedef struct TupleTableSlot
     121              : {
     122              :     NodeTag     type;
     123              : #define FIELDNO_TUPLETABLESLOT_FLAGS 1
     124              :     uint16      tts_flags;      /* Boolean states */
     125              : #define FIELDNO_TUPLETABLESLOT_NVALID 2
     126              :     AttrNumber  tts_nvalid;     /* # of valid values in tts_values */
     127              :     const TupleTableSlotOps *const tts_ops; /* implementation of slot */
     128              : #define FIELDNO_TUPLETABLESLOT_TUPLEDESCRIPTOR 4
     129              :     TupleDesc   tts_tupleDescriptor;    /* slot's tuple descriptor */
     130              : #define FIELDNO_TUPLETABLESLOT_VALUES 5
     131              :     Datum      *tts_values;     /* current per-attribute values */
     132              : #define FIELDNO_TUPLETABLESLOT_ISNULL 6
     133              :     bool       *tts_isnull;     /* current per-attribute isnull flags.  Array
     134              :                                  * size must always be rounded up to the next
     135              :                                  * multiple of 8 elements. */
     136              :     int         tts_first_nonguaranteed;    /* The value from the TupleDesc's
     137              :                                              * firstNonGuaranteedAttr, or 0
     138              :                                              * when tts_flags does not contain
     139              :                                              * TTS_FLAG_OBEYS_NOT_NULL_CONSTRAINTS */
     140              : 
     141              :     MemoryContext tts_mcxt;     /* slot itself is in this context */
     142              :     ItemPointerData tts_tid;    /* stored tuple's tid */
     143              :     Oid         tts_tableOid;   /* table oid of tuple */
     144              : } TupleTableSlot;
     145              : 
     146              : /* routines for a TupleTableSlot implementation */
     147              : struct TupleTableSlotOps
     148              : {
     149              :     /* Minimum size of the slot */
     150              :     size_t      base_slot_size;
     151              : 
     152              :     /* Initialization. */
     153              :     void        (*init) (TupleTableSlot *slot);
     154              : 
     155              :     /* Destruction. */
     156              :     void        (*release) (TupleTableSlot *slot);
     157              : 
     158              :     /*
     159              :      * Clear the contents of the slot. Only the contents are expected to be
     160              :      * cleared and not the tuple descriptor. Typically an implementation of
     161              :      * this callback should free the memory allocated for the tuple contained
     162              :      * in the slot.
     163              :      */
     164              :     void        (*clear) (TupleTableSlot *slot);
     165              : 
     166              :     /*
     167              :      * Fill up first natts entries of tts_values and tts_isnull arrays with
     168              :      * values from the tuple contained in the slot and set the slot's
     169              :      * tts_nvalid to natts. The function may be called with an natts value
     170              :      * more than the number of attributes available in the tuple, in which
     171              :      * case the function must call slot_getmissingattrs() to populate the
     172              :      * remaining attributes.  The function must raise an ERROR if 'natts' is
     173              :      * higher than the number of attributes in the slot's TupleDesc.
     174              :      */
     175              :     void        (*getsomeattrs) (TupleTableSlot *slot, int natts);
     176              : 
     177              :     /*
     178              :      * Returns value of the given system attribute as a datum and sets isnull
     179              :      * to false, if it's not NULL. Throws an error if the slot type does not
     180              :      * support system attributes.
     181              :      */
     182              :     Datum       (*getsysattr) (TupleTableSlot *slot, int attnum, bool *isnull);
     183              : 
     184              :     /*
     185              :      * Check if the tuple is created by the current transaction. Throws an
     186              :      * error if the slot doesn't contain the storage tuple.
     187              :      */
     188              :     bool        (*is_current_xact_tuple) (TupleTableSlot *slot);
     189              : 
     190              :     /*
     191              :      * Make the contents of the slot solely depend on the slot, and not on
     192              :      * underlying resources (like another memory context, buffers, etc).
     193              :      */
     194              :     void        (*materialize) (TupleTableSlot *slot);
     195              : 
     196              :     /*
     197              :      * Copy the contents of the source slot into the destination slot's own
     198              :      * context. Invoked using callback of the destination slot.  'dstslot' and
     199              :      * 'srcslot' can be assumed to have the same number of attributes.
     200              :      */
     201              :     void        (*copyslot) (TupleTableSlot *dstslot, TupleTableSlot *srcslot);
     202              : 
     203              :     /*
     204              :      * Return a heap tuple "owned" by the slot. It is slot's responsibility to
     205              :      * free the memory consumed by the heap tuple. If the slot can not "own" a
     206              :      * heap tuple, it should not implement this callback and should set it as
     207              :      * NULL.
     208              :      */
     209              :     HeapTuple   (*get_heap_tuple) (TupleTableSlot *slot);
     210              : 
     211              :     /*
     212              :      * Return a minimal tuple "owned" by the slot. It is slot's responsibility
     213              :      * to free the memory consumed by the minimal tuple. If the slot can not
     214              :      * "own" a minimal tuple, it should not implement this callback and should
     215              :      * set it as NULL.
     216              :      */
     217              :     MinimalTuple (*get_minimal_tuple) (TupleTableSlot *slot);
     218              : 
     219              :     /*
     220              :      * Return a copy of heap tuple representing the contents of the slot. The
     221              :      * copy needs to be palloc'd in the current memory context. The slot
     222              :      * itself is expected to remain unaffected. It is *not* expected to have
     223              :      * meaningful "system columns" in the copy. The copy is not be "owned" by
     224              :      * the slot i.e. the caller has to take responsibility to free memory
     225              :      * consumed by the slot.
     226              :      */
     227              :     HeapTuple   (*copy_heap_tuple) (TupleTableSlot *slot);
     228              : 
     229              :     /*
     230              :      * Return a copy of minimal tuple representing the contents of the slot.
     231              :      * The copy needs to be palloc'd in the current memory context. The slot
     232              :      * itself is expected to remain unaffected. It is *not* expected to have
     233              :      * meaningful "system columns" in the copy. The copy is not be "owned" by
     234              :      * the slot i.e. the caller has to take responsibility to free memory
     235              :      * consumed by the slot.
     236              :      *
     237              :      * The copy has "extra" bytes (maxaligned and zeroed) available before the
     238              :      * tuple, which is useful so that some callers may store extra data along
     239              :      * with the minimal tuple without the need for an additional allocation.
     240              :      */
     241              :     MinimalTuple (*copy_minimal_tuple) (TupleTableSlot *slot, Size extra);
     242              : };
     243              : 
     244              : /*
     245              :  * Predefined TupleTableSlotOps for various types of TupleTableSlotOps. The
     246              :  * same are used to identify the type of a given slot.
     247              :  */
     248              : extern PGDLLIMPORT const TupleTableSlotOps TTSOpsVirtual;
     249              : extern PGDLLIMPORT const TupleTableSlotOps TTSOpsHeapTuple;
     250              : extern PGDLLIMPORT const TupleTableSlotOps TTSOpsMinimalTuple;
     251              : extern PGDLLIMPORT const TupleTableSlotOps TTSOpsBufferHeapTuple;
     252              : 
     253              : #define TTS_IS_VIRTUAL(slot) ((slot)->tts_ops == &TTSOpsVirtual)
     254              : #define TTS_IS_HEAPTUPLE(slot) ((slot)->tts_ops == &TTSOpsHeapTuple)
     255              : #define TTS_IS_MINIMALTUPLE(slot) ((slot)->tts_ops == &TTSOpsMinimalTuple)
     256              : #define TTS_IS_BUFFERTUPLE(slot) ((slot)->tts_ops == &TTSOpsBufferHeapTuple)
     257              : 
     258              : 
     259              : /*
     260              :  * Tuple table slot implementations.
     261              :  */
     262              : 
     263              : typedef struct VirtualTupleTableSlot
     264              : {
     265              :     pg_node_attr(abstract)
     266              : 
     267              :     TupleTableSlot base;
     268              : 
     269              :     char       *data;           /* data for materialized slots */
     270              : } VirtualTupleTableSlot;
     271              : 
     272              : typedef struct HeapTupleTableSlot
     273              : {
     274              :     pg_node_attr(abstract)
     275              : 
     276              :     TupleTableSlot base;
     277              : 
     278              : #define FIELDNO_HEAPTUPLETABLESLOT_TUPLE 1
     279              :     HeapTuple   tuple;          /* physical tuple */
     280              : #define FIELDNO_HEAPTUPLETABLESLOT_OFF 2
     281              :     uint32      off;            /* saved state for slot_deform_heap_tuple */
     282              :     HeapTupleData tupdata;      /* optional workspace for storing tuple */
     283              : } HeapTupleTableSlot;
     284              : 
     285              : /* heap tuple residing in a buffer */
     286              : typedef struct BufferHeapTupleTableSlot
     287              : {
     288              :     pg_node_attr(abstract)
     289              : 
     290              :     HeapTupleTableSlot base;
     291              : 
     292              :     /*
     293              :      * If buffer is not InvalidBuffer, then the slot is holding a pin on the
     294              :      * indicated buffer page; drop the pin when we release the slot's
     295              :      * reference to that buffer.  (TTS_FLAG_SHOULDFREE should not be set in
     296              :      * such a case, since presumably base.tuple is pointing into the buffer.)
     297              :      */
     298              :     Buffer      buffer;         /* tuple's buffer, or InvalidBuffer */
     299              : } BufferHeapTupleTableSlot;
     300              : 
     301              : typedef struct MinimalTupleTableSlot
     302              : {
     303              :     pg_node_attr(abstract)
     304              : 
     305              :     TupleTableSlot base;
     306              : 
     307              :     /*
     308              :      * In a minimal slot tuple points at minhdr and the fields of that struct
     309              :      * are set correctly for access to the minimal tuple; in particular,
     310              :      * minhdr.t_data points MINIMAL_TUPLE_OFFSET bytes before mintuple.  This
     311              :      * allows column extraction to treat the case identically to regular
     312              :      * physical tuples.
     313              :      */
     314              : #define FIELDNO_MINIMALTUPLETABLESLOT_TUPLE 1
     315              :     HeapTuple   tuple;          /* tuple wrapper */
     316              :     MinimalTuple mintuple;      /* minimal tuple, or NULL if none */
     317              :     HeapTupleData minhdr;       /* workspace for minimal-tuple-only case */
     318              : #define FIELDNO_MINIMALTUPLETABLESLOT_OFF 4
     319              :     uint32      off;            /* saved state for slot_deform_heap_tuple */
     320              : } MinimalTupleTableSlot;
     321              : 
     322              : /*
     323              :  * TupIsNull -- is a TupleTableSlot empty?
     324              :  */
     325              : #define TupIsNull(slot) \
     326              :     ((slot) == NULL || TTS_EMPTY(slot))
     327              : 
     328              : /* in executor/execTuples.c */
     329              : extern TupleTableSlot *MakeTupleTableSlot(TupleDesc tupleDesc,
     330              :                                           const TupleTableSlotOps *tts_ops,
     331              :                                           uint16 flags);
     332              : extern TupleTableSlot *ExecAllocTableSlot(List **tupleTable, TupleDesc desc,
     333              :                                           const TupleTableSlotOps *tts_ops,
     334              :                                           uint16 flags);
     335              : extern void ExecResetTupleTable(List *tupleTable, bool shouldFree);
     336              : extern TupleTableSlot *MakeSingleTupleTableSlot(TupleDesc tupdesc,
     337              :                                                 const TupleTableSlotOps *tts_ops);
     338              : extern void ExecDropSingleTupleTableSlot(TupleTableSlot *slot);
     339              : extern void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc);
     340              : extern TupleTableSlot *ExecStoreHeapTuple(HeapTuple tuple,
     341              :                                           TupleTableSlot *slot,
     342              :                                           bool shouldFree);
     343              : extern void ExecForceStoreHeapTuple(HeapTuple tuple,
     344              :                                     TupleTableSlot *slot,
     345              :                                     bool shouldFree);
     346              : extern TupleTableSlot *ExecStoreBufferHeapTuple(HeapTuple tuple,
     347              :                                                 TupleTableSlot *slot,
     348              :                                                 Buffer buffer);
     349              : extern TupleTableSlot *ExecStorePinnedBufferHeapTuple(HeapTuple tuple,
     350              :                                                       TupleTableSlot *slot,
     351              :                                                       Buffer buffer);
     352              : extern TupleTableSlot *ExecStoreMinimalTuple(MinimalTuple mtup,
     353              :                                              TupleTableSlot *slot,
     354              :                                              bool shouldFree);
     355              : extern void ExecForceStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot,
     356              :                                        bool shouldFree);
     357              : extern TupleTableSlot *ExecStoreVirtualTuple(TupleTableSlot *slot);
     358              : extern TupleTableSlot *ExecStoreAllNullTuple(TupleTableSlot *slot);
     359              : extern void ExecStoreHeapTupleDatum(Datum data, TupleTableSlot *slot);
     360              : extern HeapTuple ExecFetchSlotHeapTuple(TupleTableSlot *slot, bool materialize, bool *shouldFree);
     361              : extern MinimalTuple ExecFetchSlotMinimalTuple(TupleTableSlot *slot,
     362              :                                               bool *shouldFree);
     363              : extern Datum ExecFetchSlotHeapTupleDatum(TupleTableSlot *slot);
     364              : extern void slot_getmissingattrs(TupleTableSlot *slot, int startAttNum,
     365              :                                  int lastAttNum);
     366              : extern void slot_getsomeattrs_int(TupleTableSlot *slot, int attnum);
     367              : 
     368              : 
     369              : #ifndef FRONTEND
     370              : 
     371              : /*
     372              :  * This function forces the entries of the slot's Datum/isnull arrays to be
     373              :  * valid at least up through the attnum'th entry.
     374              :  */
     375              : static inline void
     376    179279882 : slot_getsomeattrs(TupleTableSlot *slot, int attnum)
     377              : {
     378              :     /* Populate slot with attributes up to 'attnum', if it's not already */
     379    179279882 :     if (slot->tts_nvalid < attnum)
     380    134380975 :         slot->tts_ops->getsomeattrs(slot, attnum);
     381    179279882 : }
     382              : 
     383              : /*
     384              :  * slot_getallattrs
     385              :  *      This function forces all the entries of the slot's Datum/isnull
     386              :  *      arrays to be valid.  The caller may then extract data directly
     387              :  *      from those arrays instead of using slot_getattr.
     388              :  */
     389              : static inline void
     390     10463458 : slot_getallattrs(TupleTableSlot *slot)
     391              : {
     392     10463458 :     slot_getsomeattrs(slot, slot->tts_tupleDescriptor->natts);
     393     10463458 : }
     394              : 
     395              : 
     396              : /*
     397              :  * slot_attisnull
     398              :  *
     399              :  * Detect whether an attribute of the slot is null, without actually fetching
     400              :  * it.
     401              :  */
     402              : static inline bool
     403      7163970 : slot_attisnull(TupleTableSlot *slot, int attnum)
     404              : {
     405              :     Assert(attnum > 0);
     406              : 
     407      7163970 :     if (attnum > slot->tts_nvalid)
     408      5845897 :         slot_getsomeattrs(slot, attnum);
     409              : 
     410      7163970 :     return slot->tts_isnull[attnum - 1];
     411              : }
     412              : 
     413              : /*
     414              :  * slot_getattr - fetch one attribute of the slot's contents.
     415              :  */
     416              : static inline Datum
     417     43938969 : slot_getattr(TupleTableSlot *slot, int attnum,
     418              :              bool *isnull)
     419              : {
     420              :     Assert(attnum > 0);
     421              : 
     422     43938969 :     if (attnum > slot->tts_nvalid)
     423     33113784 :         slot_getsomeattrs(slot, attnum);
     424              : 
     425     43938969 :     *isnull = slot->tts_isnull[attnum - 1];
     426              : 
     427     43938969 :     return slot->tts_values[attnum - 1];
     428              : }
     429              : 
     430              : /*
     431              :  * slot_getsysattr - fetch a system attribute of the slot's current tuple.
     432              :  *
     433              :  *  If the slot type does not contain system attributes, this will throw an
     434              :  *  error.  Hence before calling this function, callers should make sure that
     435              :  *  the slot type is the one that supports system attributes.
     436              :  */
     437              : static inline Datum
     438      5457612 : slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
     439              : {
     440              :     Assert(attnum < 0);          /* caller error */
     441              : 
     442      5457612 :     if (attnum == TableOidAttributeNumber)
     443              :     {
     444      1968812 :         *isnull = false;
     445      1968812 :         return ObjectIdGetDatum(slot->tts_tableOid);
     446              :     }
     447      3488800 :     else if (attnum == SelfItemPointerAttributeNumber)
     448              :     {
     449      3416007 :         *isnull = false;
     450      3416007 :         return PointerGetDatum(&slot->tts_tid);
     451              :     }
     452              : 
     453              :     /* Fetch the system attribute from the underlying tuple. */
     454        72793 :     return slot->tts_ops->getsysattr(slot, attnum, isnull);
     455              : }
     456              : 
     457              : /*
     458              :  * slot_is_current_xact_tuple - check if the slot's current tuple is created
     459              :  *                              by the current transaction.
     460              :  *
     461              :  *  If the slot does not contain a storage tuple, this will throw an error.
     462              :  *  Hence before calling this function, callers should make sure that the
     463              :  *  slot type supports storage tuples and that there is currently one inside
     464              :  *  the slot.
     465              :  */
     466              : static inline bool
     467          564 : slot_is_current_xact_tuple(TupleTableSlot *slot)
     468              : {
     469          564 :     return slot->tts_ops->is_current_xact_tuple(slot);
     470              : }
     471              : 
     472              : /*
     473              :  * ExecClearTuple - clear the slot's contents
     474              :  */
     475              : static inline TupleTableSlot *
     476    105445119 : ExecClearTuple(TupleTableSlot *slot)
     477              : {
     478    105445119 :     slot->tts_ops->clear(slot);
     479              : 
     480    105445119 :     return slot;
     481              : }
     482              : 
     483              : /* ExecMaterializeSlot - force a slot into the "materialized" state.
     484              :  *
     485              :  * This causes the slot's tuple to be a local copy not dependent on any
     486              :  * external storage (i.e. pointing into a Buffer, or having allocations in
     487              :  * another memory context).
     488              :  *
     489              :  * A typical use for this operation is to prepare a computed tuple for being
     490              :  * stored on disk.  The original data may or may not be virtual, but in any
     491              :  * case we need a private copy for heap_insert to scribble on.
     492              :  */
     493              : static inline void
     494      9734698 : ExecMaterializeSlot(TupleTableSlot *slot)
     495              : {
     496      9734698 :     slot->tts_ops->materialize(slot);
     497      9734698 : }
     498              : 
     499              : /*
     500              :  * ExecCopySlotHeapTuple - return HeapTuple allocated in caller's context
     501              :  */
     502              : static inline HeapTuple
     503     14923062 : ExecCopySlotHeapTuple(TupleTableSlot *slot)
     504              : {
     505              :     Assert(!TTS_EMPTY(slot));
     506              : 
     507     14923062 :     return slot->tts_ops->copy_heap_tuple(slot);
     508              : }
     509              : 
     510              : /*
     511              :  * ExecCopySlotMinimalTuple - return MinimalTuple allocated in caller's context
     512              :  */
     513              : static inline MinimalTuple
     514     10880200 : ExecCopySlotMinimalTuple(TupleTableSlot *slot)
     515              : {
     516     10880200 :     return slot->tts_ops->copy_minimal_tuple(slot, 0);
     517              : }
     518              : 
     519              : /*
     520              :  * ExecCopySlotMinimalTupleExtra - return MinimalTuple allocated in caller's
     521              :  * context, with extra bytes (maxaligned and zeroed) before the tuple for data
     522              :  * the caller wishes to store along with the tuple (without requiring the
     523              :  * caller to make an additional allocation).
     524              :  */
     525              : static inline MinimalTuple
     526       660133 : ExecCopySlotMinimalTupleExtra(TupleTableSlot *slot, Size extra)
     527              : {
     528       660133 :     return slot->tts_ops->copy_minimal_tuple(slot, extra);
     529              : }
     530              : 
     531              : /*
     532              :  * ExecCopySlot - copy one slot's contents into another.
     533              :  *
     534              :  * If a source's system attributes are supposed to be accessed in the target
     535              :  * slot, the target slot and source slot types need to match.
     536              :  *
     537              :  * Currently, 'dstslot' and 'srcslot' must have the same number of attributes.
     538              :  * Future work could see this relaxed to allow the source to contain
     539              :  * additional attributes and have the code here only copy over the leading
     540              :  * attributes.
     541              :  */
     542              : static inline TupleTableSlot *
     543      7919188 : ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
     544              : {
     545              :     Assert(!TTS_EMPTY(srcslot));
     546              :     Assert(srcslot != dstslot);
     547              :     Assert(dstslot->tts_tupleDescriptor->natts ==
     548              :            srcslot->tts_tupleDescriptor->natts);
     549              : 
     550      7919188 :     dstslot->tts_ops->copyslot(dstslot, srcslot);
     551              : 
     552      7919188 :     return dstslot;
     553              : }
     554              : 
     555              : #endif                          /* FRONTEND */
     556              : 
     557              : #endif                          /* TUPTABLE_H */
        

Generated by: LCOV version 2.0-1