LCOV - code coverage report
Current view: top level - src/include/executor - tuptable.h (source / functions) Coverage Total Hit
Test: Code coverage Lines: 100.0 % 49 49
Test Date: 2026-01-26 10:56:24 Functions: 100.0 % 12 12
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 70.8 % 24 17

             Branch data     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                 :    34606296 : slot_getsomeattrs(TupleTableSlot *slot, int attnum)
     359                 :             : {
     360         [ +  + ]:    34606296 :         if (slot->tts_nvalid < attnum)
     361                 :    27721211 :                 slot_getsomeattrs_int(slot, attnum);
     362                 :    34606296 : }
     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                 :      810324 : slot_getallattrs(TupleTableSlot *slot)
     372                 :             : {
     373                 :      810324 :         slot_getsomeattrs(slot, slot->tts_tupleDescriptor->natts);
     374                 :      810324 : }
     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                 :     1870329 : slot_attisnull(TupleTableSlot *slot, int attnum)
     385                 :             : {
     386         [ +  - ]:     1870329 :         Assert(attnum > 0);
     387                 :             : 
     388         [ +  + ]:     1870329 :         if (attnum > slot->tts_nvalid)
     389                 :     1652950 :                 slot_getsomeattrs(slot, attnum);
     390                 :             : 
     391                 :     1870329 :         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                 :     4921449 : slot_getattr(TupleTableSlot *slot, int attnum,
     399                 :             :                          bool *isnull)
     400                 :             : {
     401         [ +  - ]:     4921449 :         Assert(attnum > 0);
     402                 :             : 
     403         [ +  + ]:     4921449 :         if (attnum > slot->tts_nvalid)
     404                 :     2935167 :                 slot_getsomeattrs(slot, attnum);
     405                 :             : 
     406                 :     4921449 :         *isnull = slot->tts_isnull[attnum - 1];
     407                 :             : 
     408                 :     4921449 :         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                 :     1030763 : slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
     420                 :             : {
     421         [ +  - ]:     1030763 :         Assert(attnum < 0);                  /* caller error */
     422                 :             : 
     423         [ +  + ]:     1030763 :         if (attnum == TableOidAttributeNumber)
     424                 :             :         {
     425                 :       21831 :                 *isnull = false;
     426                 :       21831 :                 return ObjectIdGetDatum(slot->tts_tableOid);
     427                 :             :         }
     428         [ +  + ]:     1008932 :         else if (attnum == SelfItemPointerAttributeNumber)
     429                 :             :         {
     430                 :     1008884 :                 *isnull = false;
     431                 :     1008884 :                 return PointerGetDatum(&slot->tts_tid);
     432                 :             :         }
     433                 :             : 
     434                 :             :         /* Fetch the system attribute from the underlying tuple. */
     435                 :          48 :         return slot->tts_ops->getsysattr(slot, attnum, isnull);
     436                 :     1030763 : }
     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                 :          99 : slot_is_current_xact_tuple(TupleTableSlot *slot)
     449                 :             : {
     450                 :          99 :         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                 :    20502690 : ExecClearTuple(TupleTableSlot *slot)
     458                 :             : {
     459                 :    20502690 :         slot->tts_ops->clear(slot);
     460                 :             : 
     461                 :    20502690 :         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                 :      368877 : ExecMaterializeSlot(TupleTableSlot *slot)
     476                 :             : {
     477                 :      368877 :         slot->tts_ops->materialize(slot);
     478                 :      368877 : }
     479                 :             : 
     480                 :             : /*
     481                 :             :  * ExecCopySlotHeapTuple - return HeapTuple allocated in caller's context
     482                 :             :  */
     483                 :             : static inline HeapTuple
     484                 :     2865584 : ExecCopySlotHeapTuple(TupleTableSlot *slot)
     485                 :             : {
     486         [ +  - ]:     2865584 :         Assert(!TTS_EMPTY(slot));
     487                 :             : 
     488                 :     2865584 :         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                 :     1574568 : ExecCopySlotMinimalTuple(TupleTableSlot *slot)
     496                 :             : {
     497                 :     1574568 :         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                 :      148831 : ExecCopySlotMinimalTupleExtra(TupleTableSlot *slot, Size extra)
     508                 :             : {
     509                 :      148831 :         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                 :      174622 : ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
     525                 :             : {
     526         [ +  - ]:      174622 :         Assert(!TTS_EMPTY(srcslot));
     527         [ +  - ]:      174622 :         Assert(srcslot != dstslot);
     528         [ +  - ]:      174622 :         Assert(dstslot->tts_tupleDescriptor->natts ==
     529                 :             :                    srcslot->tts_tupleDescriptor->natts);
     530                 :             : 
     531                 :      174622 :         dstslot->tts_ops->copyslot(dstslot, srcslot);
     532                 :             : 
     533                 :      174622 :         return dstslot;
     534                 :             : }
     535                 :             : 
     536                 :             : #endif                                                  /* FRONTEND */
     537                 :             : 
     538                 :             : #endif                                                  /* TUPTABLE_H */
        

Generated by: LCOV version 2.3.2-1