LCOV - differential code coverage report
Current view: top level - src/include/executor - tuptable.h (source / functions) Coverage Total Hit GIC GNC CBC ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 100.0 % 43 43 36 4 3 40
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 10 10 10 10
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a