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-02-28 14:14:49 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              :  * The TTS_FLAG_SLOW flag is saved state for
      89              :  * slot_deform_heap_tuple, and should not be touched by any other code.
      90              :  *----------
      91              :  */
      92              : 
      93              : /* true = slot is empty */
      94              : #define         TTS_FLAG_EMPTY          (1 << 1)
      95              : #define TTS_EMPTY(slot) (((slot)->tts_flags & TTS_FLAG_EMPTY) != 0)
      96              : 
      97              : /* should pfree tuple "owned" by the slot? */
      98              : #define         TTS_FLAG_SHOULDFREE     (1 << 2)
      99              : #define TTS_SHOULDFREE(slot) (((slot)->tts_flags & TTS_FLAG_SHOULDFREE) != 0)
     100              : 
     101              : /* saved state for slot_deform_heap_tuple */
     102              : #define         TTS_FLAG_SLOW       (1 << 3)
     103              : #define TTS_SLOW(slot) (((slot)->tts_flags & TTS_FLAG_SLOW) != 0)
     104              : 
     105              : /* fixed tuple descriptor */
     106              : #define         TTS_FLAG_FIXED      (1 << 4)
     107              : #define TTS_FIXED(slot) (((slot)->tts_flags & TTS_FLAG_FIXED) != 0)
     108              : 
     109              : struct TupleTableSlotOps;
     110              : typedef struct TupleTableSlotOps TupleTableSlotOps;
     111              : 
     112              : /* base tuple table slot type */
     113              : typedef struct TupleTableSlot
     114              : {
     115              :     NodeTag     type;
     116              : #define FIELDNO_TUPLETABLESLOT_FLAGS 1
     117              :     uint16      tts_flags;      /* Boolean states */
     118              : #define FIELDNO_TUPLETABLESLOT_NVALID 2
     119              :     AttrNumber  tts_nvalid;     /* # of valid values in tts_values */
     120              :     const TupleTableSlotOps *const tts_ops; /* implementation of slot */
     121              : #define FIELDNO_TUPLETABLESLOT_TUPLEDESCRIPTOR 4
     122              :     TupleDesc   tts_tupleDescriptor;    /* slot's tuple descriptor */
     123              : #define FIELDNO_TUPLETABLESLOT_VALUES 5
     124              :     Datum      *tts_values;     /* current per-attribute values */
     125              : #define FIELDNO_TUPLETABLESLOT_ISNULL 6
     126              :     bool       *tts_isnull;     /* current per-attribute isnull flags */
     127              :     MemoryContext tts_mcxt;     /* slot itself is in this context */
     128              :     ItemPointerData tts_tid;    /* stored tuple's tid */
     129              :     Oid         tts_tableOid;   /* table oid of tuple */
     130              : } TupleTableSlot;
     131              : 
     132              : /* routines for a TupleTableSlot implementation */
     133              : struct TupleTableSlotOps
     134              : {
     135              :     /* Minimum size of the slot */
     136              :     size_t      base_slot_size;
     137              : 
     138              :     /* Initialization. */
     139              :     void        (*init) (TupleTableSlot *slot);
     140              : 
     141              :     /* Destruction. */
     142              :     void        (*release) (TupleTableSlot *slot);
     143              : 
     144              :     /*
     145              :      * Clear the contents of the slot. Only the contents are expected to be
     146              :      * cleared and not the tuple descriptor. Typically an implementation of
     147              :      * this callback should free the memory allocated for the tuple contained
     148              :      * in the slot.
     149              :      */
     150              :     void        (*clear) (TupleTableSlot *slot);
     151              : 
     152              :     /*
     153              :      * Fill up first natts entries of tts_values and tts_isnull arrays with
     154              :      * values from the tuple contained in the slot. The function may be called
     155              :      * with natts more than the number of attributes available in the tuple,
     156              :      * in which case it should set tts_nvalid to the number of returned
     157              :      * columns.
     158              :      */
     159              :     void        (*getsomeattrs) (TupleTableSlot *slot, int natts);
     160              : 
     161              :     /*
     162              :      * Returns value of the given system attribute as a datum and sets isnull
     163              :      * to false, if it's not NULL. Throws an error if the slot type does not
     164              :      * support system attributes.
     165              :      */
     166              :     Datum       (*getsysattr) (TupleTableSlot *slot, int attnum, bool *isnull);
     167              : 
     168              :     /*
     169              :      * Check if the tuple is created by the current transaction. Throws an
     170              :      * error if the slot doesn't contain the storage tuple.
     171              :      */
     172              :     bool        (*is_current_xact_tuple) (TupleTableSlot *slot);
     173              : 
     174              :     /*
     175              :      * Make the contents of the slot solely depend on the slot, and not on
     176              :      * underlying resources (like another memory context, buffers, etc).
     177              :      */
     178              :     void        (*materialize) (TupleTableSlot *slot);
     179              : 
     180              :     /*
     181              :      * Copy the contents of the source slot into the destination slot's own
     182              :      * context. Invoked using callback of the destination slot.  'dstslot' and
     183              :      * 'srcslot' can be assumed to have the same number of attributes.
     184              :      */
     185              :     void        (*copyslot) (TupleTableSlot *dstslot, TupleTableSlot *srcslot);
     186              : 
     187              :     /*
     188              :      * Return a heap tuple "owned" by the slot. It is slot's responsibility to
     189              :      * free the memory consumed by the heap tuple. If the slot can not "own" a
     190              :      * heap tuple, it should not implement this callback and should set it as
     191              :      * NULL.
     192              :      */
     193              :     HeapTuple   (*get_heap_tuple) (TupleTableSlot *slot);
     194              : 
     195              :     /*
     196              :      * Return a minimal tuple "owned" by the slot. It is slot's responsibility
     197              :      * to free the memory consumed by the minimal tuple. If the slot can not
     198              :      * "own" a minimal tuple, it should not implement this callback and should
     199              :      * set it as NULL.
     200              :      */
     201              :     MinimalTuple (*get_minimal_tuple) (TupleTableSlot *slot);
     202              : 
     203              :     /*
     204              :      * Return a copy of heap tuple representing the contents of the slot. The
     205              :      * copy needs to be palloc'd in the current memory context. The slot
     206              :      * itself is expected to remain unaffected. It is *not* expected to have
     207              :      * meaningful "system columns" in the copy. The copy is not be "owned" by
     208              :      * the slot i.e. the caller has to take responsibility to free memory
     209              :      * consumed by the slot.
     210              :      */
     211              :     HeapTuple   (*copy_heap_tuple) (TupleTableSlot *slot);
     212              : 
     213              :     /*
     214              :      * Return a copy of minimal tuple representing the contents of the slot.
     215              :      * The copy needs to be palloc'd in the current memory context. The slot
     216              :      * itself is expected to remain unaffected. It is *not* expected to have
     217              :      * meaningful "system columns" in the copy. The copy is not be "owned" by
     218              :      * the slot i.e. the caller has to take responsibility to free memory
     219              :      * consumed by the slot.
     220              :      *
     221              :      * The copy has "extra" bytes (maxaligned and zeroed) available before the
     222              :      * tuple, which is useful so that some callers may store extra data along
     223              :      * with the minimal tuple without the need for an additional allocation.
     224              :      */
     225              :     MinimalTuple (*copy_minimal_tuple) (TupleTableSlot *slot, Size extra);
     226              : };
     227              : 
     228              : /*
     229              :  * Predefined TupleTableSlotOps for various types of TupleTableSlotOps. The
     230              :  * same are used to identify the type of a given slot.
     231              :  */
     232              : extern PGDLLIMPORT const TupleTableSlotOps TTSOpsVirtual;
     233              : extern PGDLLIMPORT const TupleTableSlotOps TTSOpsHeapTuple;
     234              : extern PGDLLIMPORT const TupleTableSlotOps TTSOpsMinimalTuple;
     235              : extern PGDLLIMPORT const TupleTableSlotOps TTSOpsBufferHeapTuple;
     236              : 
     237              : #define TTS_IS_VIRTUAL(slot) ((slot)->tts_ops == &TTSOpsVirtual)
     238              : #define TTS_IS_HEAPTUPLE(slot) ((slot)->tts_ops == &TTSOpsHeapTuple)
     239              : #define TTS_IS_MINIMALTUPLE(slot) ((slot)->tts_ops == &TTSOpsMinimalTuple)
     240              : #define TTS_IS_BUFFERTUPLE(slot) ((slot)->tts_ops == &TTSOpsBufferHeapTuple)
     241              : 
     242              : 
     243              : /*
     244              :  * Tuple table slot implementations.
     245              :  */
     246              : 
     247              : typedef struct VirtualTupleTableSlot
     248              : {
     249              :     pg_node_attr(abstract)
     250              : 
     251              :     TupleTableSlot base;
     252              : 
     253              :     char       *data;           /* data for materialized slots */
     254              : } VirtualTupleTableSlot;
     255              : 
     256              : typedef struct HeapTupleTableSlot
     257              : {
     258              :     pg_node_attr(abstract)
     259              : 
     260              :     TupleTableSlot base;
     261              : 
     262              : #define FIELDNO_HEAPTUPLETABLESLOT_TUPLE 1
     263              :     HeapTuple   tuple;          /* physical tuple */
     264              : #define FIELDNO_HEAPTUPLETABLESLOT_OFF 2
     265              :     uint32      off;            /* saved state for slot_deform_heap_tuple */
     266              :     HeapTupleData tupdata;      /* optional workspace for storing tuple */
     267              : } HeapTupleTableSlot;
     268              : 
     269              : /* heap tuple residing in a buffer */
     270              : typedef struct BufferHeapTupleTableSlot
     271              : {
     272              :     pg_node_attr(abstract)
     273              : 
     274              :     HeapTupleTableSlot base;
     275              : 
     276              :     /*
     277              :      * If buffer is not InvalidBuffer, then the slot is holding a pin on the
     278              :      * indicated buffer page; drop the pin when we release the slot's
     279              :      * reference to that buffer.  (TTS_FLAG_SHOULDFREE should not be set in
     280              :      * such a case, since presumably base.tuple is pointing into the buffer.)
     281              :      */
     282              :     Buffer      buffer;         /* tuple's buffer, or InvalidBuffer */
     283              : } BufferHeapTupleTableSlot;
     284              : 
     285              : typedef struct MinimalTupleTableSlot
     286              : {
     287              :     pg_node_attr(abstract)
     288              : 
     289              :     TupleTableSlot base;
     290              : 
     291              :     /*
     292              :      * In a minimal slot tuple points at minhdr and the fields of that struct
     293              :      * are set correctly for access to the minimal tuple; in particular,
     294              :      * minhdr.t_data points MINIMAL_TUPLE_OFFSET bytes before mintuple.  This
     295              :      * allows column extraction to treat the case identically to regular
     296              :      * physical tuples.
     297              :      */
     298              : #define FIELDNO_MINIMALTUPLETABLESLOT_TUPLE 1
     299              :     HeapTuple   tuple;          /* tuple wrapper */
     300              :     MinimalTuple mintuple;      /* minimal tuple, or NULL if none */
     301              :     HeapTupleData minhdr;       /* workspace for minimal-tuple-only case */
     302              : #define FIELDNO_MINIMALTUPLETABLESLOT_OFF 4
     303              :     uint32      off;            /* saved state for slot_deform_heap_tuple */
     304              : } MinimalTupleTableSlot;
     305              : 
     306              : /*
     307              :  * TupIsNull -- is a TupleTableSlot empty?
     308              :  */
     309              : #define TupIsNull(slot) \
     310              :     ((slot) == NULL || TTS_EMPTY(slot))
     311              : 
     312              : /* in executor/execTuples.c */
     313              : extern TupleTableSlot *MakeTupleTableSlot(TupleDesc tupleDesc,
     314              :                                           const TupleTableSlotOps *tts_ops);
     315              : extern TupleTableSlot *ExecAllocTableSlot(List **tupleTable, TupleDesc desc,
     316              :                                           const TupleTableSlotOps *tts_ops);
     317              : extern void ExecResetTupleTable(List *tupleTable, bool shouldFree);
     318              : extern TupleTableSlot *MakeSingleTupleTableSlot(TupleDesc tupdesc,
     319              :                                                 const TupleTableSlotOps *tts_ops);
     320              : extern void ExecDropSingleTupleTableSlot(TupleTableSlot *slot);
     321              : extern void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc);
     322              : extern TupleTableSlot *ExecStoreHeapTuple(HeapTuple tuple,
     323              :                                           TupleTableSlot *slot,
     324              :                                           bool shouldFree);
     325              : extern void ExecForceStoreHeapTuple(HeapTuple tuple,
     326              :                                     TupleTableSlot *slot,
     327              :                                     bool shouldFree);
     328              : extern TupleTableSlot *ExecStoreBufferHeapTuple(HeapTuple tuple,
     329              :                                                 TupleTableSlot *slot,
     330              :                                                 Buffer buffer);
     331              : extern TupleTableSlot *ExecStorePinnedBufferHeapTuple(HeapTuple tuple,
     332              :                                                       TupleTableSlot *slot,
     333              :                                                       Buffer buffer);
     334              : extern TupleTableSlot *ExecStoreMinimalTuple(MinimalTuple mtup,
     335              :                                              TupleTableSlot *slot,
     336              :                                              bool shouldFree);
     337              : extern void ExecForceStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot,
     338              :                                        bool shouldFree);
     339              : extern TupleTableSlot *ExecStoreVirtualTuple(TupleTableSlot *slot);
     340              : extern TupleTableSlot *ExecStoreAllNullTuple(TupleTableSlot *slot);
     341              : extern void ExecStoreHeapTupleDatum(Datum data, TupleTableSlot *slot);
     342              : extern HeapTuple ExecFetchSlotHeapTuple(TupleTableSlot *slot, bool materialize, bool *shouldFree);
     343              : extern MinimalTuple ExecFetchSlotMinimalTuple(TupleTableSlot *slot,
     344              :                                               bool *shouldFree);
     345              : extern Datum ExecFetchSlotHeapTupleDatum(TupleTableSlot *slot);
     346              : extern void slot_getmissingattrs(TupleTableSlot *slot, int startAttNum,
     347              :                                  int lastAttNum);
     348              : extern void slot_getsomeattrs_int(TupleTableSlot *slot, int attnum);
     349              : 
     350              : 
     351              : #ifndef FRONTEND
     352              : 
     353              : /*
     354              :  * This function forces the entries of the slot's Datum/isnull arrays to be
     355              :  * valid at least up through the attnum'th entry.
     356              :  */
     357              : static inline void
     358    135761074 : slot_getsomeattrs(TupleTableSlot *slot, int attnum)
     359              : {
     360    135761074 :     if (slot->tts_nvalid < attnum)
     361    101991509 :         slot_getsomeattrs_int(slot, attnum);
     362    135761074 : }
     363              : 
     364              : /*
     365              :  * slot_getallattrs
     366              :  *      This function forces all the entries of the slot's Datum/isnull
     367              :  *      arrays to be valid.  The caller may then extract data directly
     368              :  *      from those arrays instead of using slot_getattr.
     369              :  */
     370              : static inline void
     371      9425428 : slot_getallattrs(TupleTableSlot *slot)
     372              : {
     373      9425428 :     slot_getsomeattrs(slot, slot->tts_tupleDescriptor->natts);
     374      9425428 : }
     375              : 
     376              : 
     377              : /*
     378              :  * slot_attisnull
     379              :  *
     380              :  * Detect whether an attribute of the slot is null, without actually fetching
     381              :  * it.
     382              :  */
     383              : static inline bool
     384      5248884 : slot_attisnull(TupleTableSlot *slot, int attnum)
     385              : {
     386              :     Assert(attnum > 0);
     387              : 
     388      5248884 :     if (attnum > slot->tts_nvalid)
     389      4114127 :         slot_getsomeattrs(slot, attnum);
     390              : 
     391      5248884 :     return slot->tts_isnull[attnum - 1];
     392              : }
     393              : 
     394              : /*
     395              :  * slot_getattr - fetch one attribute of the slot's contents.
     396              :  */
     397              : static inline Datum
     398     34692623 : slot_getattr(TupleTableSlot *slot, int attnum,
     399              :              bool *isnull)
     400              : {
     401              :     Assert(attnum > 0);
     402              : 
     403     34692623 :     if (attnum > slot->tts_nvalid)
     404     27525951 :         slot_getsomeattrs(slot, attnum);
     405              : 
     406     34692623 :     *isnull = slot->tts_isnull[attnum - 1];
     407              : 
     408     34692623 :     return slot->tts_values[attnum - 1];
     409              : }
     410              : 
     411              : /*
     412              :  * slot_getsysattr - fetch a system attribute of the slot's current tuple.
     413              :  *
     414              :  *  If the slot type does not contain system attributes, this will throw an
     415              :  *  error.  Hence before calling this function, callers should make sure that
     416              :  *  the slot type is the one that supports system attributes.
     417              :  */
     418              : static inline Datum
     419      4281978 : slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
     420              : {
     421              :     Assert(attnum < 0);          /* caller error */
     422              : 
     423      4281978 :     if (attnum == TableOidAttributeNumber)
     424              :     {
     425      1848386 :         *isnull = false;
     426      1848386 :         return ObjectIdGetDatum(slot->tts_tableOid);
     427              :     }
     428      2433592 :     else if (attnum == SelfItemPointerAttributeNumber)
     429              :     {
     430      2360883 :         *isnull = false;
     431      2360883 :         return PointerGetDatum(&slot->tts_tid);
     432              :     }
     433              : 
     434              :     /* Fetch the system attribute from the underlying tuple. */
     435        72709 :     return slot->tts_ops->getsysattr(slot, attnum, isnull);
     436              : }
     437              : 
     438              : /*
     439              :  * slot_is_current_xact_tuple - check if the slot's current tuple is created
     440              :  *                              by the current transaction.
     441              :  *
     442              :  *  If the slot does not contain a storage tuple, this will throw an error.
     443              :  *  Hence before calling this function, callers should make sure that the
     444              :  *  slot type supports storage tuples and that there is currently one inside
     445              :  *  the slot.
     446              :  */
     447              : static inline bool
     448          465 : slot_is_current_xact_tuple(TupleTableSlot *slot)
     449              : {
     450          465 :     return slot->tts_ops->is_current_xact_tuple(slot);
     451              : }
     452              : 
     453              : /*
     454              :  * ExecClearTuple - clear the slot's contents
     455              :  */
     456              : static inline TupleTableSlot *
     457     81475669 : ExecClearTuple(TupleTableSlot *slot)
     458              : {
     459     81475669 :     slot->tts_ops->clear(slot);
     460              : 
     461     81475669 :     return slot;
     462              : }
     463              : 
     464              : /* ExecMaterializeSlot - force a slot into the "materialized" state.
     465              :  *
     466              :  * This causes the slot's tuple to be a local copy not dependent on any
     467              :  * external storage (i.e. pointing into a Buffer, or having allocations in
     468              :  * another memory context).
     469              :  *
     470              :  * A typical use for this operation is to prepare a computed tuple for being
     471              :  * stored on disk.  The original data may or may not be virtual, but in any
     472              :  * case we need a private copy for heap_insert to scribble on.
     473              :  */
     474              : static inline void
     475      8011693 : ExecMaterializeSlot(TupleTableSlot *slot)
     476              : {
     477      8011693 :     slot->tts_ops->materialize(slot);
     478      8011693 : }
     479              : 
     480              : /*
     481              :  * ExecCopySlotHeapTuple - return HeapTuple allocated in caller's context
     482              :  */
     483              : static inline HeapTuple
     484     11798584 : ExecCopySlotHeapTuple(TupleTableSlot *slot)
     485              : {
     486              :     Assert(!TTS_EMPTY(slot));
     487              : 
     488     11798584 :     return slot->tts_ops->copy_heap_tuple(slot);
     489              : }
     490              : 
     491              : /*
     492              :  * ExecCopySlotMinimalTuple - return MinimalTuple allocated in caller's context
     493              :  */
     494              : static inline MinimalTuple
     495      9002314 : ExecCopySlotMinimalTuple(TupleTableSlot *slot)
     496              : {
     497      9002314 :     return slot->tts_ops->copy_minimal_tuple(slot, 0);
     498              : }
     499              : 
     500              : /*
     501              :  * ExecCopySlotMinimalTupleExtra - return MinimalTuple allocated in caller's
     502              :  * context, with extra bytes (maxaligned and zeroed) before the tuple for data
     503              :  * the caller wishes to store along with the tuple (without requiring the
     504              :  * caller to make an additional allocation).
     505              :  */
     506              : static inline MinimalTuple
     507       513251 : ExecCopySlotMinimalTupleExtra(TupleTableSlot *slot, Size extra)
     508              : {
     509       513251 :     return slot->tts_ops->copy_minimal_tuple(slot, extra);
     510              : }
     511              : 
     512              : /*
     513              :  * ExecCopySlot - copy one slot's contents into another.
     514              :  *
     515              :  * If a source's system attributes are supposed to be accessed in the target
     516              :  * slot, the target slot and source slot types need to match.
     517              :  *
     518              :  * Currently, 'dstslot' and 'srcslot' must have the same number of attributes.
     519              :  * Future work could see this relaxed to allow the source to contain
     520              :  * additional attributes and have the code here only copy over the leading
     521              :  * attributes.
     522              :  */
     523              : static inline TupleTableSlot *
     524      6476822 : ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
     525              : {
     526              :     Assert(!TTS_EMPTY(srcslot));
     527              :     Assert(srcslot != dstslot);
     528              :     Assert(dstslot->tts_tupleDescriptor->natts ==
     529              :            srcslot->tts_tupleDescriptor->natts);
     530              : 
     531      6476822 :     dstslot->tts_ops->copyslot(dstslot, srcslot);
     532              : 
     533      6476822 :     return dstslot;
     534              : }
     535              : 
     536              : #endif                          /* FRONTEND */
     537              : 
     538              : #endif                          /* TUPTABLE_H */
        

Generated by: LCOV version 2.0-1