LCOV - code coverage report
Current view: top level - src/include/executor - tuptable.h (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 100.0 % 41 41
Test Date: 2026-07-26 07:15:44 Functions: 100.0 % 12 12
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 100.0 % 10 10

             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                 :             :  */
      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                 :   177939992 : slot_getsomeattrs(TupleTableSlot *slot, int attnum)
     377                 :             : {
     378                 :             :     /* Populate slot with attributes up to 'attnum', if it's not already */
     379         [ +  + ]:   177939992 :     if (slot->tts_nvalid < attnum)
     380                 :   131842747 :         slot->tts_ops->getsomeattrs(slot, attnum);
     381                 :   177939992 : }
     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                 :     9392587 : slot_getallattrs(TupleTableSlot *slot)
     391                 :             : {
     392                 :     9392587 :     slot_getsomeattrs(slot, slot->tts_tupleDescriptor->natts);
     393                 :     9392587 : }
     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                 :     7932227 : slot_attisnull(TupleTableSlot *slot, int attnum)
     404                 :             : {
     405                 :             :     Assert(attnum > 0);
     406                 :             : 
     407         [ +  + ]:     7932227 :     if (attnum > slot->tts_nvalid)
     408                 :     6493233 :         slot_getsomeattrs(slot, attnum);
     409                 :             : 
     410                 :     7932227 :     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                 :    48567734 : slot_getattr(TupleTableSlot *slot, int attnum,
     418                 :             :              bool *isnull)
     419                 :             : {
     420                 :             :     Assert(attnum > 0);
     421                 :             : 
     422         [ +  + ]:    48567734 :     if (attnum > slot->tts_nvalid)
     423                 :    35930763 :         slot_getsomeattrs(slot, attnum);
     424                 :             : 
     425                 :    48567734 :     *isnull = slot->tts_isnull[attnum - 1];
     426                 :             : 
     427                 :    48567734 :     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                 :     6680051 : slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
     439                 :             : {
     440                 :             :     Assert(attnum < 0);          /* caller error */
     441                 :             : 
     442         [ +  + ]:     6680051 :     if (attnum == TableOidAttributeNumber)
     443                 :             :     {
     444                 :     1496912 :         *isnull = false;
     445                 :     1496912 :         return ObjectIdGetDatum(slot->tts_tableOid);
     446                 :             :     }
     447         [ +  + ]:     5183139 :     else if (attnum == SelfItemPointerAttributeNumber)
     448                 :             :     {
     449                 :     5110316 :         *isnull = false;
     450                 :     5110316 :         return PointerGetDatum(&slot->tts_tid);
     451                 :             :     }
     452                 :             : 
     453                 :             :     /* Fetch the system attribute from the underlying tuple. */
     454                 :       72823 :     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                 :   107494486 : ExecClearTuple(TupleTableSlot *slot)
     477                 :             : {
     478                 :   107494486 :     slot->tts_ops->clear(slot);
     479                 :             : 
     480                 :   107494486 :     return slot;
     481                 :             : }
     482                 :             : 
     483                 :             : /*
     484                 :             :  * ExecMaterializeSlot - force a slot into the "materialized" state.
     485                 :             :  *
     486                 :             :  * This causes the slot's tuple to be a local copy not dependent on any
     487                 :             :  * external storage (i.e. pointing into a Buffer, or having allocations in
     488                 :             :  * another memory context).
     489                 :             :  *
     490                 :             :  * A typical use for this operation is to prepare a computed tuple for being
     491                 :             :  * stored on disk.  The original data may or may not be virtual, but in any
     492                 :             :  * case we need a private copy for heap_insert to scribble on.
     493                 :             :  */
     494                 :             : static inline void
     495                 :    14434328 : ExecMaterializeSlot(TupleTableSlot *slot)
     496                 :             : {
     497                 :    14434328 :     slot->tts_ops->materialize(slot);
     498                 :    14434328 : }
     499                 :             : 
     500                 :             : /*
     501                 :             :  * ExecCopySlotHeapTuple - return HeapTuple allocated in caller's context
     502                 :             :  */
     503                 :             : static inline HeapTuple
     504                 :    15634272 : ExecCopySlotHeapTuple(TupleTableSlot *slot)
     505                 :             : {
     506                 :             :     Assert(!TTS_EMPTY(slot));
     507                 :             : 
     508                 :    15634272 :     return slot->tts_ops->copy_heap_tuple(slot);
     509                 :             : }
     510                 :             : 
     511                 :             : /*
     512                 :             :  * ExecCopySlotMinimalTuple - return MinimalTuple allocated in caller's context
     513                 :             :  */
     514                 :             : static inline MinimalTuple
     515                 :    10307861 : ExecCopySlotMinimalTuple(TupleTableSlot *slot)
     516                 :             : {
     517                 :    10307861 :     return slot->tts_ops->copy_minimal_tuple(slot, 0);
     518                 :             : }
     519                 :             : 
     520                 :             : /*
     521                 :             :  * ExecCopySlotMinimalTupleExtra - return MinimalTuple allocated in caller's
     522                 :             :  * context, with extra bytes (maxaligned and zeroed) before the tuple for data
     523                 :             :  * the caller wishes to store along with the tuple (without requiring the
     524                 :             :  * caller to make an additional allocation).
     525                 :             :  */
     526                 :             : static inline MinimalTuple
     527                 :      710003 : ExecCopySlotMinimalTupleExtra(TupleTableSlot *slot, Size extra)
     528                 :             : {
     529                 :      710003 :     return slot->tts_ops->copy_minimal_tuple(slot, extra);
     530                 :             : }
     531                 :             : 
     532                 :             : /*
     533                 :             :  * ExecCopySlot - copy one slot's contents into another.
     534                 :             :  *
     535                 :             :  * If a source's system attributes are supposed to be accessed in the target
     536                 :             :  * slot, the target slot and source slot types need to match.
     537                 :             :  *
     538                 :             :  * Currently, 'dstslot' and 'srcslot' must have the same number of attributes.
     539                 :             :  * Future work could see this relaxed to allow the source to contain
     540                 :             :  * additional attributes and have the code here only copy over the leading
     541                 :             :  * attributes.
     542                 :             :  */
     543                 :             : static inline TupleTableSlot *
     544                 :     8516634 : ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
     545                 :             : {
     546                 :             :     Assert(!TTS_EMPTY(srcslot));
     547                 :             :     Assert(srcslot != dstslot);
     548                 :             :     Assert(dstslot->tts_tupleDescriptor->natts ==
     549                 :             :            srcslot->tts_tupleDescriptor->natts);
     550                 :             : 
     551                 :     8516634 :     dstslot->tts_ops->copyslot(dstslot, srcslot);
     552                 :             : 
     553                 :     8516634 :     return dstslot;
     554                 :             : }
     555                 :             : 
     556                 :             : #endif                          /* FRONTEND */
     557                 :             : 
     558                 :             : #endif                          /* TUPTABLE_H */
        

Generated by: LCOV version 2.0-1