LCOV - code coverage report
Current view: top level - src/backend/executor - execTuples.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 329 345 95.4 %
Date: 2017-09-29 15:12:54 Functions: 35 36 97.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * execTuples.c
       4             :  *    Routines dealing with TupleTableSlots.  These are used for resource
       5             :  *    management associated with tuples (eg, releasing buffer pins for
       6             :  *    tuples in disk buffers, or freeing the memory occupied by transient
       7             :  *    tuples).  Slots also provide access abstraction that lets us implement
       8             :  *    "virtual" tuples to reduce data-copying overhead.
       9             :  *
      10             :  *    Routines dealing with the type information for tuples. Currently,
      11             :  *    the type information for a tuple is an array of FormData_pg_attribute.
      12             :  *    This information is needed by routines manipulating tuples
      13             :  *    (getattribute, formtuple, etc.).
      14             :  *
      15             :  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
      16             :  * Portions Copyright (c) 1994, Regents of the University of California
      17             :  *
      18             :  *
      19             :  * IDENTIFICATION
      20             :  *    src/backend/executor/execTuples.c
      21             :  *
      22             :  *-------------------------------------------------------------------------
      23             :  */
      24             : /*
      25             :  * INTERFACE ROUTINES
      26             :  *
      27             :  *   SLOT CREATION/DESTRUCTION
      28             :  *      MakeTupleTableSlot      - create an empty slot
      29             :  *      ExecAllocTableSlot      - create a slot within a tuple table
      30             :  *      ExecResetTupleTable     - clear and optionally delete a tuple table
      31             :  *      MakeSingleTupleTableSlot - make a standalone slot, set its descriptor
      32             :  *      ExecDropSingleTupleTableSlot - destroy a standalone slot
      33             :  *
      34             :  *   SLOT ACCESSORS
      35             :  *      ExecSetSlotDescriptor   - set a slot's tuple descriptor
      36             :  *      ExecStoreTuple          - store a physical tuple in the slot
      37             :  *      ExecStoreMinimalTuple   - store a minimal physical tuple in the slot
      38             :  *      ExecClearTuple          - clear contents of a slot
      39             :  *      ExecStoreVirtualTuple   - mark slot as containing a virtual tuple
      40             :  *      ExecCopySlotTuple       - build a physical tuple from a slot
      41             :  *      ExecCopySlotMinimalTuple - build a minimal physical tuple from a slot
      42             :  *      ExecMaterializeSlot     - convert virtual to physical storage
      43             :  *      ExecCopySlot            - copy one slot's contents to another
      44             :  *
      45             :  *   CONVENIENCE INITIALIZATION ROUTINES
      46             :  *      ExecInitResultTupleSlot    \    convenience routines to initialize
      47             :  *      ExecInitScanTupleSlot       \   the various tuple slots for nodes
      48             :  *      ExecInitExtraTupleSlot      /   which store copies of tuples.
      49             :  *      ExecInitNullTupleSlot      /
      50             :  *
      51             :  *   Routines that probably belong somewhere else:
      52             :  *      ExecTypeFromTL          - form a TupleDesc from a target list
      53             :  *
      54             :  *   EXAMPLE OF HOW TABLE ROUTINES WORK
      55             :  *      Suppose we have a query such as SELECT emp.name FROM emp and we have
      56             :  *      a single SeqScan node in the query plan.
      57             :  *
      58             :  *      At ExecutorStart()
      59             :  *      ----------------
      60             :  *      - ExecInitSeqScan() calls ExecInitScanTupleSlot() and
      61             :  *        ExecInitResultTupleSlot() to construct TupleTableSlots
      62             :  *        for the tuples returned by the access methods and the
      63             :  *        tuples resulting from performing target list projections.
      64             :  *
      65             :  *      During ExecutorRun()
      66             :  *      ----------------
      67             :  *      - SeqNext() calls ExecStoreTuple() to place the tuple returned
      68             :  *        by the access methods into the scan tuple slot.
      69             :  *
      70             :  *      - ExecSeqScan() calls ExecStoreTuple() to take the result
      71             :  *        tuple from ExecProject() and place it into the result tuple slot.
      72             :  *
      73             :  *      - ExecutePlan() calls the output function.
      74             :  *
      75             :  *      The important thing to watch in the executor code is how pointers
      76             :  *      to the slots containing tuples are passed instead of the tuples
      77             :  *      themselves.  This facilitates the communication of related information
      78             :  *      (such as whether or not a tuple should be pfreed, what buffer contains
      79             :  *      this tuple, the tuple's tuple descriptor, etc).  It also allows us
      80             :  *      to avoid physically constructing projection tuples in many cases.
      81             :  */
      82             : #include "postgres.h"
      83             : 
      84             : #include "access/htup_details.h"
      85             : #include "access/tuptoaster.h"
      86             : #include "funcapi.h"
      87             : #include "catalog/pg_type.h"
      88             : #include "nodes/nodeFuncs.h"
      89             : #include "storage/bufmgr.h"
      90             : #include "utils/builtins.h"
      91             : #include "utils/lsyscache.h"
      92             : #include "utils/typcache.h"
      93             : 
      94             : 
      95             : static TupleDesc ExecTypeFromTLInternal(List *targetList,
      96             :                        bool hasoid, bool skipjunk);
      97             : 
      98             : 
      99             : /* ----------------------------------------------------------------
     100             :  *                tuple table create/delete functions
     101             :  * ----------------------------------------------------------------
     102             :  */
     103             : 
     104             : /* --------------------------------
     105             :  *      MakeTupleTableSlot
     106             :  *
     107             :  *      Basic routine to make an empty TupleTableSlot.
     108             :  * --------------------------------
     109             :  */
     110             : TupleTableSlot *
     111      167314 : MakeTupleTableSlot(void)
     112             : {
     113      167314 :     TupleTableSlot *slot = makeNode(TupleTableSlot);
     114             : 
     115      167314 :     slot->tts_isempty = true;
     116      167314 :     slot->tts_shouldFree = false;
     117      167314 :     slot->tts_shouldFreeMin = false;
     118      167314 :     slot->tts_tuple = NULL;
     119      167314 :     slot->tts_tupleDescriptor = NULL;
     120      167314 :     slot->tts_mcxt = CurrentMemoryContext;
     121      167314 :     slot->tts_buffer = InvalidBuffer;
     122      167314 :     slot->tts_nvalid = 0;
     123      167314 :     slot->tts_values = NULL;
     124      167314 :     slot->tts_isnull = NULL;
     125      167314 :     slot->tts_mintuple = NULL;
     126             : 
     127      167314 :     return slot;
     128             : }
     129             : 
     130             : /* --------------------------------
     131             :  *      ExecAllocTableSlot
     132             :  *
     133             :  *      Create a tuple table slot within a tuple table (which is just a List).
     134             :  * --------------------------------
     135             :  */
     136             : TupleTableSlot *
     137       94599 : ExecAllocTableSlot(List **tupleTable)
     138             : {
     139       94599 :     TupleTableSlot *slot = MakeTupleTableSlot();
     140             : 
     141       94599 :     *tupleTable = lappend(*tupleTable, slot);
     142             : 
     143       94599 :     return slot;
     144             : }
     145             : 
     146             : /* --------------------------------
     147             :  *      ExecResetTupleTable
     148             :  *
     149             :  *      This releases any resources (buffer pins, tupdesc refcounts)
     150             :  *      held by the tuple table, and optionally releases the memory
     151             :  *      occupied by the tuple table data structure.
     152             :  *      It is expected that this routine be called by EndPlan().
     153             :  * --------------------------------
     154             :  */
     155             : void
     156       21414 : ExecResetTupleTable(List *tupleTable,   /* tuple table */
     157             :                     bool shouldFree)    /* true if we should free memory */
     158             : {
     159             :     ListCell   *lc;
     160             : 
     161      111370 :     foreach(lc, tupleTable)
     162             :     {
     163       89956 :         TupleTableSlot *slot = lfirst_node(TupleTableSlot, lc);
     164             : 
     165             :         /* Always release resources and reset the slot to empty */
     166       89956 :         ExecClearTuple(slot);
     167       89956 :         if (slot->tts_tupleDescriptor)
     168             :         {
     169       83464 :             ReleaseTupleDesc(slot->tts_tupleDescriptor);
     170       83464 :             slot->tts_tupleDescriptor = NULL;
     171             :         }
     172             : 
     173             :         /* If shouldFree, release memory occupied by the slot itself */
     174       89956 :         if (shouldFree)
     175             :         {
     176           0 :             if (slot->tts_values)
     177           0 :                 pfree(slot->tts_values);
     178           0 :             if (slot->tts_isnull)
     179           0 :                 pfree(slot->tts_isnull);
     180           0 :             pfree(slot);
     181             :         }
     182             :     }
     183             : 
     184             :     /* If shouldFree, release the list structure */
     185       21414 :     if (shouldFree)
     186           0 :         list_free(tupleTable);
     187       21414 : }
     188             : 
     189             : /* --------------------------------
     190             :  *      MakeSingleTupleTableSlot
     191             :  *
     192             :  *      This is a convenience routine for operations that need a
     193             :  *      standalone TupleTableSlot not gotten from the main executor
     194             :  *      tuple table.  It makes a single slot and initializes it
     195             :  *      to use the given tuple descriptor.
     196             :  * --------------------------------
     197             :  */
     198             : TupleTableSlot *
     199       72646 : MakeSingleTupleTableSlot(TupleDesc tupdesc)
     200             : {
     201       72646 :     TupleTableSlot *slot = MakeTupleTableSlot();
     202             : 
     203       72646 :     ExecSetSlotDescriptor(slot, tupdesc);
     204             : 
     205       72646 :     return slot;
     206             : }
     207             : 
     208             : /* --------------------------------
     209             :  *      ExecDropSingleTupleTableSlot
     210             :  *
     211             :  *      Release a TupleTableSlot made with MakeSingleTupleTableSlot.
     212             :  *      DON'T use this on a slot that's part of a tuple table list!
     213             :  * --------------------------------
     214             :  */
     215             : void
     216       69301 : ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
     217             : {
     218             :     /* This should match ExecResetTupleTable's processing of one slot */
     219       69301 :     Assert(IsA(slot, TupleTableSlot));
     220       69301 :     ExecClearTuple(slot);
     221       69301 :     if (slot->tts_tupleDescriptor)
     222       69268 :         ReleaseTupleDesc(slot->tts_tupleDescriptor);
     223       69301 :     if (slot->tts_values)
     224       69268 :         pfree(slot->tts_values);
     225       69301 :     if (slot->tts_isnull)
     226       69268 :         pfree(slot->tts_isnull);
     227       69301 :     pfree(slot);
     228       69301 : }
     229             : 
     230             : 
     231             : /* ----------------------------------------------------------------
     232             :  *                tuple table slot accessor functions
     233             :  * ----------------------------------------------------------------
     234             :  */
     235             : 
     236             : /* --------------------------------
     237             :  *      ExecSetSlotDescriptor
     238             :  *
     239             :  *      This function is used to set the tuple descriptor associated
     240             :  *      with the slot's tuple.  The passed descriptor must have lifespan
     241             :  *      at least equal to the slot's.  If it is a reference-counted descriptor
     242             :  *      then the reference count is incremented for as long as the slot holds
     243             :  *      a reference.
     244             :  * --------------------------------
     245             :  */
     246             : void
     247      160473 : ExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */
     248             :                       TupleDesc tupdesc)    /* new tuple descriptor */
     249             : {
     250             :     /* For safety, make sure slot is empty before changing it */
     251      160473 :     ExecClearTuple(slot);
     252             : 
     253             :     /*
     254             :      * Release any old descriptor.  Also release old Datum/isnull arrays if
     255             :      * present (we don't bother to check if they could be re-used).
     256             :      */
     257      160473 :     if (slot->tts_tupleDescriptor)
     258          38 :         ReleaseTupleDesc(slot->tts_tupleDescriptor);
     259             : 
     260      160473 :     if (slot->tts_values)
     261          38 :         pfree(slot->tts_values);
     262      160473 :     if (slot->tts_isnull)
     263          38 :         pfree(slot->tts_isnull);
     264             : 
     265             :     /*
     266             :      * Install the new descriptor; if it's refcounted, bump its refcount.
     267             :      */
     268      160473 :     slot->tts_tupleDescriptor = tupdesc;
     269      160473 :     PinTupleDesc(tupdesc);
     270             : 
     271             :     /*
     272             :      * Allocate Datum/isnull arrays of the appropriate size.  These must have
     273             :      * the same lifetime as the slot, so allocate in the slot's own context.
     274             :      */
     275      160473 :     slot->tts_values = (Datum *)
     276      160473 :         MemoryContextAlloc(slot->tts_mcxt, tupdesc->natts * sizeof(Datum));
     277      160473 :     slot->tts_isnull = (bool *)
     278      160473 :         MemoryContextAlloc(slot->tts_mcxt, tupdesc->natts * sizeof(bool));
     279      160473 : }
     280             : 
     281             : /* --------------------------------
     282             :  *      ExecStoreTuple
     283             :  *
     284             :  *      This function is used to store a physical tuple into a specified
     285             :  *      slot in the tuple table.
     286             :  *
     287             :  *      tuple:  tuple to store
     288             :  *      slot:   slot to store it in
     289             :  *      buffer: disk buffer if tuple is in a disk page, else InvalidBuffer
     290             :  *      shouldFree: true if ExecClearTuple should pfree() the tuple
     291             :  *                  when done with it
     292             :  *
     293             :  * If 'buffer' is not InvalidBuffer, the tuple table code acquires a pin
     294             :  * on the buffer which is held until the slot is cleared, so that the tuple
     295             :  * won't go away on us.
     296             :  *
     297             :  * shouldFree is normally set 'true' for tuples constructed on-the-fly.
     298             :  * It must always be 'false' for tuples that are stored in disk pages,
     299             :  * since we don't want to try to pfree those.
     300             :  *
     301             :  * Another case where it is 'false' is when the referenced tuple is held
     302             :  * in a tuple table slot belonging to a lower-level executor Proc node.
     303             :  * In this case the lower-level slot retains ownership and responsibility
     304             :  * for eventually releasing the tuple.  When this method is used, we must
     305             :  * be certain that the upper-level Proc node will lose interest in the tuple
     306             :  * sooner than the lower-level one does!  If you're not certain, copy the
     307             :  * lower-level tuple with heap_copytuple and let the upper-level table
     308             :  * slot assume ownership of the copy!
     309             :  *
     310             :  * Return value is just the passed-in slot pointer.
     311             :  *
     312             :  * NOTE: before PostgreSQL 8.1, this function would accept a NULL tuple
     313             :  * pointer and effectively behave like ExecClearTuple (though you could
     314             :  * still specify a buffer to pin, which would be an odd combination).
     315             :  * This saved a couple lines of code in a few places, but seemed more likely
     316             :  * to mask logic errors than to be really useful, so it's now disallowed.
     317             :  * --------------------------------
     318             :  */
     319             : TupleTableSlot *
     320     4006212 : ExecStoreTuple(HeapTuple tuple,
     321             :                TupleTableSlot *slot,
     322             :                Buffer buffer,
     323             :                bool shouldFree)
     324             : {
     325             :     /*
     326             :      * sanity checks
     327             :      */
     328     4006212 :     Assert(tuple != NULL);
     329     4006212 :     Assert(slot != NULL);
     330     4006212 :     Assert(slot->tts_tupleDescriptor != NULL);
     331             :     /* passing shouldFree=true for a tuple on a disk page is not sane */
     332     4006212 :     Assert(BufferIsValid(buffer) ? (!shouldFree) : true);
     333             : 
     334             :     /*
     335             :      * Free any old physical tuple belonging to the slot.
     336             :      */
     337     4006212 :     if (slot->tts_shouldFree)
     338       97742 :         heap_freetuple(slot->tts_tuple);
     339     4006212 :     if (slot->tts_shouldFreeMin)
     340         501 :         heap_free_minimal_tuple(slot->tts_mintuple);
     341             : 
     342             :     /*
     343             :      * Store the new tuple into the specified slot.
     344             :      */
     345     4006212 :     slot->tts_isempty = false;
     346     4006212 :     slot->tts_shouldFree = shouldFree;
     347     4006212 :     slot->tts_shouldFreeMin = false;
     348     4006212 :     slot->tts_tuple = tuple;
     349     4006212 :     slot->tts_mintuple = NULL;
     350             : 
     351             :     /* Mark extracted state invalid */
     352     4006212 :     slot->tts_nvalid = 0;
     353             : 
     354             :     /*
     355             :      * If tuple is on a disk page, keep the page pinned as long as we hold a
     356             :      * pointer into it.  We assume the caller already has such a pin.
     357             :      *
     358             :      * This is coded to optimize the case where the slot previously held a
     359             :      * tuple on the same disk page: in that case releasing and re-acquiring
     360             :      * the pin is a waste of cycles.  This is a common situation during
     361             :      * seqscans, so it's worth troubling over.
     362             :      */
     363     4006212 :     if (slot->tts_buffer != buffer)
     364             :     {
     365      254889 :         if (BufferIsValid(slot->tts_buffer))
     366      128000 :             ReleaseBuffer(slot->tts_buffer);
     367      254889 :         slot->tts_buffer = buffer;
     368      254889 :         if (BufferIsValid(buffer))
     369      254878 :             IncrBufferRefCount(buffer);
     370             :     }
     371             : 
     372     4006212 :     return slot;
     373             : }
     374             : 
     375             : /* --------------------------------
     376             :  *      ExecStoreMinimalTuple
     377             :  *
     378             :  *      Like ExecStoreTuple, but insert a "minimal" tuple into the slot.
     379             :  *
     380             :  * No 'buffer' parameter since minimal tuples are never stored in relations.
     381             :  * --------------------------------
     382             :  */
     383             : TupleTableSlot *
     384     9844354 : ExecStoreMinimalTuple(MinimalTuple mtup,
     385             :                       TupleTableSlot *slot,
     386             :                       bool shouldFree)
     387             : {
     388             :     /*
     389             :      * sanity checks
     390             :      */
     391     9844354 :     Assert(mtup != NULL);
     392     9844354 :     Assert(slot != NULL);
     393     9844354 :     Assert(slot->tts_tupleDescriptor != NULL);
     394             : 
     395             :     /*
     396             :      * Free any old physical tuple belonging to the slot.
     397             :      */
     398     9844354 :     if (slot->tts_shouldFree)
     399        7992 :         heap_freetuple(slot->tts_tuple);
     400     9844354 :     if (slot->tts_shouldFreeMin)
     401      282923 :         heap_free_minimal_tuple(slot->tts_mintuple);
     402             : 
     403             :     /*
     404             :      * Drop the pin on the referenced buffer, if there is one.
     405             :      */
     406     9844354 :     if (BufferIsValid(slot->tts_buffer))
     407           0 :         ReleaseBuffer(slot->tts_buffer);
     408             : 
     409     9844354 :     slot->tts_buffer = InvalidBuffer;
     410             : 
     411             :     /*
     412             :      * Store the new tuple into the specified slot.
     413             :      */
     414     9844354 :     slot->tts_isempty = false;
     415     9844354 :     slot->tts_shouldFree = false;
     416     9844354 :     slot->tts_shouldFreeMin = shouldFree;
     417     9844354 :     slot->tts_tuple = &slot->tts_minhdr;
     418     9844354 :     slot->tts_mintuple = mtup;
     419             : 
     420     9844354 :     slot->tts_minhdr.t_len = mtup->t_len + MINIMAL_TUPLE_OFFSET;
     421     9844354 :     slot->tts_minhdr.t_data = (HeapTupleHeader) ((char *) mtup - MINIMAL_TUPLE_OFFSET);
     422             :     /* no need to set t_self or t_tableOid since we won't allow access */
     423             : 
     424             :     /* Mark extracted state invalid */
     425     9844354 :     slot->tts_nvalid = 0;
     426             : 
     427     9844354 :     return slot;
     428             : }
     429             : 
     430             : /* --------------------------------
     431             :  *      ExecClearTuple
     432             :  *
     433             :  *      This function is used to clear out a slot in the tuple table.
     434             :  *
     435             :  *      NB: only the tuple is cleared, not the tuple descriptor (if any).
     436             :  * --------------------------------
     437             :  */
     438             : TupleTableSlot *                /* return: slot passed */
     439    21552830 : ExecClearTuple(TupleTableSlot *slot)    /* slot in which to store tuple */
     440             : {
     441             :     /*
     442             :      * sanity checks
     443             :      */
     444    21552830 :     Assert(slot != NULL);
     445             : 
     446             :     /*
     447             :      * Free the old physical tuple if necessary.
     448             :      */
     449    21552830 :     if (slot->tts_shouldFree)
     450      532888 :         heap_freetuple(slot->tts_tuple);
     451    21552830 :     if (slot->tts_shouldFreeMin)
     452      307935 :         heap_free_minimal_tuple(slot->tts_mintuple);
     453             : 
     454    21552830 :     slot->tts_tuple = NULL;
     455    21552830 :     slot->tts_mintuple = NULL;
     456    21552830 :     slot->tts_shouldFree = false;
     457    21552830 :     slot->tts_shouldFreeMin = false;
     458             : 
     459             :     /*
     460             :      * Drop the pin on the referenced buffer, if there is one.
     461             :      */
     462    21552830 :     if (BufferIsValid(slot->tts_buffer))
     463      106222 :         ReleaseBuffer(slot->tts_buffer);
     464             : 
     465    21552830 :     slot->tts_buffer = InvalidBuffer;
     466             : 
     467             :     /*
     468             :      * Mark it empty.
     469             :      */
     470    21552830 :     slot->tts_isempty = true;
     471    21552830 :     slot->tts_nvalid = 0;
     472             : 
     473    21552830 :     return slot;
     474             : }
     475             : 
     476             : /* --------------------------------
     477             :  *      ExecStoreVirtualTuple
     478             :  *          Mark a slot as containing a virtual tuple.
     479             :  *
     480             :  * The protocol for loading a slot with virtual tuple data is:
     481             :  *      * Call ExecClearTuple to mark the slot empty.
     482             :  *      * Store data into the Datum/isnull arrays.
     483             :  *      * Call ExecStoreVirtualTuple to mark the slot valid.
     484             :  * This is a bit unclean but it avoids one round of data copying.
     485             :  * --------------------------------
     486             :  */
     487             : TupleTableSlot *
     488      768704 : ExecStoreVirtualTuple(TupleTableSlot *slot)
     489             : {
     490             :     /*
     491             :      * sanity checks
     492             :      */
     493      768704 :     Assert(slot != NULL);
     494      768704 :     Assert(slot->tts_tupleDescriptor != NULL);
     495      768704 :     Assert(slot->tts_isempty);
     496             : 
     497      768704 :     slot->tts_isempty = false;
     498      768704 :     slot->tts_nvalid = slot->tts_tupleDescriptor->natts;
     499             : 
     500      768704 :     return slot;
     501             : }
     502             : 
     503             : /* --------------------------------
     504             :  *      ExecStoreAllNullTuple
     505             :  *          Set up the slot to contain a null in every column.
     506             :  *
     507             :  * At first glance this might sound just like ExecClearTuple, but it's
     508             :  * entirely different: the slot ends up full, not empty.
     509             :  * --------------------------------
     510             :  */
     511             : TupleTableSlot *
     512        1082 : ExecStoreAllNullTuple(TupleTableSlot *slot)
     513             : {
     514             :     /*
     515             :      * sanity checks
     516             :      */
     517        1082 :     Assert(slot != NULL);
     518        1082 :     Assert(slot->tts_tupleDescriptor != NULL);
     519             : 
     520             :     /* Clear any old contents */
     521        1082 :     ExecClearTuple(slot);
     522             : 
     523             :     /*
     524             :      * Fill all the columns of the virtual tuple with nulls
     525             :      */
     526        1082 :     MemSet(slot->tts_values, 0,
     527             :            slot->tts_tupleDescriptor->natts * sizeof(Datum));
     528        1082 :     memset(slot->tts_isnull, true,
     529        1082 :            slot->tts_tupleDescriptor->natts * sizeof(bool));
     530             : 
     531        1082 :     return ExecStoreVirtualTuple(slot);
     532             : }
     533             : 
     534             : /* --------------------------------
     535             :  *      ExecCopySlotTuple
     536             :  *          Obtain a copy of a slot's regular physical tuple.  The copy is
     537             :  *          palloc'd in the current memory context.
     538             :  *          The slot itself is undisturbed.
     539             :  *
     540             :  *      This works even if the slot contains a virtual or minimal tuple;
     541             :  *      however the "system columns" of the result will not be meaningful.
     542             :  * --------------------------------
     543             :  */
     544             : HeapTuple
     545      667362 : ExecCopySlotTuple(TupleTableSlot *slot)
     546             : {
     547             :     /*
     548             :      * sanity checks
     549             :      */
     550      667362 :     Assert(slot != NULL);
     551      667362 :     Assert(!slot->tts_isempty);
     552             : 
     553             :     /*
     554             :      * If we have a physical tuple (either format) then just copy it.
     555             :      */
     556      667362 :     if (TTS_HAS_PHYSICAL_TUPLE(slot))
     557       23489 :         return heap_copytuple(slot->tts_tuple);
     558      643873 :     if (slot->tts_mintuple)
     559       62904 :         return heap_tuple_from_minimal_tuple(slot->tts_mintuple);
     560             : 
     561             :     /*
     562             :      * Otherwise we need to build a tuple from the Datum array.
     563             :      */
     564      580969 :     return heap_form_tuple(slot->tts_tupleDescriptor,
     565             :                            slot->tts_values,
     566             :                            slot->tts_isnull);
     567             : }
     568             : 
     569             : /* --------------------------------
     570             :  *      ExecCopySlotMinimalTuple
     571             :  *          Obtain a copy of a slot's minimal physical tuple.  The copy is
     572             :  *          palloc'd in the current memory context.
     573             :  *          The slot itself is undisturbed.
     574             :  * --------------------------------
     575             :  */
     576             : MinimalTuple
     577      749010 : ExecCopySlotMinimalTuple(TupleTableSlot *slot)
     578             : {
     579             :     /*
     580             :      * sanity checks
     581             :      */
     582      749010 :     Assert(slot != NULL);
     583      749010 :     Assert(!slot->tts_isempty);
     584             : 
     585             :     /*
     586             :      * If we have a physical tuple then just copy it.  Prefer to copy
     587             :      * tts_mintuple since that's a tad cheaper.
     588             :      */
     589      749010 :     if (slot->tts_mintuple)
     590       47327 :         return heap_copy_minimal_tuple(slot->tts_mintuple);
     591      701683 :     if (slot->tts_tuple)
     592       36218 :         return minimal_tuple_from_heap_tuple(slot->tts_tuple);
     593             : 
     594             :     /*
     595             :      * Otherwise we need to build a tuple from the Datum array.
     596             :      */
     597      665465 :     return heap_form_minimal_tuple(slot->tts_tupleDescriptor,
     598             :                                    slot->tts_values,
     599             :                                    slot->tts_isnull);
     600             : }
     601             : 
     602             : /* --------------------------------
     603             :  *      ExecFetchSlotTuple
     604             :  *          Fetch the slot's regular physical tuple.
     605             :  *
     606             :  *      If the slot contains a virtual tuple, we convert it to physical
     607             :  *      form.  The slot retains ownership of the physical tuple.
     608             :  *      If it contains a minimal tuple we convert to regular form and store
     609             :  *      that in addition to the minimal tuple (not instead of, because
     610             :  *      callers may hold pointers to Datums within the minimal tuple).
     611             :  *
     612             :  * The main difference between this and ExecMaterializeSlot() is that this
     613             :  * does not guarantee that the contained tuple is local storage.
     614             :  * Hence, the result must be treated as read-only.
     615             :  * --------------------------------
     616             :  */
     617             : HeapTuple
     618        9831 : ExecFetchSlotTuple(TupleTableSlot *slot)
     619             : {
     620             :     /*
     621             :      * sanity checks
     622             :      */
     623        9831 :     Assert(slot != NULL);
     624        9831 :     Assert(!slot->tts_isempty);
     625             : 
     626             :     /*
     627             :      * If we have a regular physical tuple then just return it.
     628             :      */
     629        9831 :     if (TTS_HAS_PHYSICAL_TUPLE(slot))
     630          22 :         return slot->tts_tuple;
     631             : 
     632             :     /*
     633             :      * Otherwise materialize the slot...
     634             :      */
     635        9809 :     return ExecMaterializeSlot(slot);
     636             : }
     637             : 
     638             : /* --------------------------------
     639             :  *      ExecFetchSlotMinimalTuple
     640             :  *          Fetch the slot's minimal physical tuple.
     641             :  *
     642             :  *      If the slot contains a virtual tuple, we convert it to minimal
     643             :  *      physical form.  The slot retains ownership of the minimal tuple.
     644             :  *      If it contains a regular tuple we convert to minimal form and store
     645             :  *      that in addition to the regular tuple (not instead of, because
     646             :  *      callers may hold pointers to Datums within the regular tuple).
     647             :  *
     648             :  * As above, the result must be treated as read-only.
     649             :  * --------------------------------
     650             :  */
     651             : MinimalTuple
     652      297167 : ExecFetchSlotMinimalTuple(TupleTableSlot *slot)
     653             : {
     654             :     MemoryContext oldContext;
     655             : 
     656             :     /*
     657             :      * sanity checks
     658             :      */
     659      297167 :     Assert(slot != NULL);
     660      297167 :     Assert(!slot->tts_isempty);
     661             : 
     662             :     /*
     663             :      * If we have a minimal physical tuple (local or not) then just return it.
     664             :      */
     665      297167 :     if (slot->tts_mintuple)
     666       12343 :         return slot->tts_mintuple;
     667             : 
     668             :     /*
     669             :      * Otherwise, copy or build a minimal tuple, and store it into the slot.
     670             :      *
     671             :      * We may be called in a context that is shorter-lived than the tuple
     672             :      * slot, but we have to ensure that the materialized tuple will survive
     673             :      * anyway.
     674             :      */
     675      284824 :     oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
     676      284824 :     slot->tts_mintuple = ExecCopySlotMinimalTuple(slot);
     677      284824 :     slot->tts_shouldFreeMin = true;
     678      284824 :     MemoryContextSwitchTo(oldContext);
     679             : 
     680             :     /*
     681             :      * Note: we may now have a situation where we have a local minimal tuple
     682             :      * attached to a virtual or non-local physical tuple.  There seems no harm
     683             :      * in that at the moment, but if any materializes, we should change this
     684             :      * function to force the slot into minimal-tuple-only state.
     685             :      */
     686             : 
     687      284824 :     return slot->tts_mintuple;
     688             : }
     689             : 
     690             : /* --------------------------------
     691             :  *      ExecFetchSlotTupleDatum
     692             :  *          Fetch the slot's tuple as a composite-type Datum.
     693             :  *
     694             :  *      The result is always freshly palloc'd in the caller's memory context.
     695             :  * --------------------------------
     696             :  */
     697             : Datum
     698        9809 : ExecFetchSlotTupleDatum(TupleTableSlot *slot)
     699             : {
     700             :     HeapTuple   tup;
     701             :     TupleDesc   tupdesc;
     702             : 
     703             :     /* Fetch slot's contents in regular-physical-tuple form */
     704        9809 :     tup = ExecFetchSlotTuple(slot);
     705        9809 :     tupdesc = slot->tts_tupleDescriptor;
     706             : 
     707             :     /* Convert to Datum form */
     708        9809 :     return heap_copy_tuple_as_datum(tup, tupdesc);
     709             : }
     710             : 
     711             : /* --------------------------------
     712             :  *      ExecMaterializeSlot
     713             :  *          Force a slot into the "materialized" state.
     714             :  *
     715             :  *      This causes the slot's tuple to be a local copy not dependent on
     716             :  *      any external storage.  A pointer to the contained tuple is returned.
     717             :  *
     718             :  *      A typical use for this operation is to prepare a computed tuple
     719             :  *      for being stored on disk.  The original data may or may not be
     720             :  *      virtual, but in any case we need a private copy for heap_insert
     721             :  *      to scribble on.
     722             :  * --------------------------------
     723             :  */
     724             : HeapTuple
     725      559752 : ExecMaterializeSlot(TupleTableSlot *slot)
     726             : {
     727             :     MemoryContext oldContext;
     728             : 
     729             :     /*
     730             :      * sanity checks
     731             :      */
     732      559752 :     Assert(slot != NULL);
     733      559752 :     Assert(!slot->tts_isempty);
     734             : 
     735             :     /*
     736             :      * If we have a regular physical tuple, and it's locally palloc'd, we have
     737             :      * nothing to do.
     738             :      */
     739      559752 :     if (slot->tts_tuple && slot->tts_shouldFree)
     740         506 :         return slot->tts_tuple;
     741             : 
     742             :     /*
     743             :      * Otherwise, copy or build a physical tuple, and store it into the slot.
     744             :      *
     745             :      * We may be called in a context that is shorter-lived than the tuple
     746             :      * slot, but we have to ensure that the materialized tuple will survive
     747             :      * anyway.
     748             :      */
     749      559246 :     oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
     750      559246 :     slot->tts_tuple = ExecCopySlotTuple(slot);
     751      559246 :     slot->tts_shouldFree = true;
     752      559246 :     MemoryContextSwitchTo(oldContext);
     753             : 
     754             :     /*
     755             :      * Drop the pin on the referenced buffer, if there is one.
     756             :      */
     757      559246 :     if (BufferIsValid(slot->tts_buffer))
     758       20551 :         ReleaseBuffer(slot->tts_buffer);
     759             : 
     760      559246 :     slot->tts_buffer = InvalidBuffer;
     761             : 
     762             :     /*
     763             :      * Mark extracted state invalid.  This is important because the slot is
     764             :      * not supposed to depend any more on the previous external data; we
     765             :      * mustn't leave any dangling pass-by-reference datums in tts_values.
     766             :      * However, we have not actually invalidated any such datums, if there
     767             :      * happen to be any previously fetched from the slot.  (Note in particular
     768             :      * that we have not pfree'd tts_mintuple, if there is one.)
     769             :      */
     770      559246 :     slot->tts_nvalid = 0;
     771             : 
     772             :     /*
     773             :      * On the same principle of not depending on previous remote storage,
     774             :      * forget the mintuple if it's not local storage.  (If it is local
     775             :      * storage, we must not pfree it now, since callers might have already
     776             :      * fetched datum pointers referencing it.)
     777             :      */
     778      559246 :     if (!slot->tts_shouldFreeMin)
     779      559246 :         slot->tts_mintuple = NULL;
     780             : 
     781      559246 :     return slot->tts_tuple;
     782             : }
     783             : 
     784             : /* --------------------------------
     785             :  *      ExecCopySlot
     786             :  *          Copy the source slot's contents into the destination slot.
     787             :  *
     788             :  *      The destination acquires a private copy that will not go away
     789             :  *      if the source is cleared.
     790             :  *
     791             :  *      The caller must ensure the slots have compatible tupdescs.
     792             :  * --------------------------------
     793             :  */
     794             : TupleTableSlot *
     795       57153 : ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
     796             : {
     797             :     HeapTuple   newTuple;
     798             :     MemoryContext oldContext;
     799             : 
     800             :     /*
     801             :      * There might be ways to optimize this when the source is virtual, but
     802             :      * for now just always build a physical copy.  Make sure it is in the
     803             :      * right context.
     804             :      */
     805       57153 :     oldContext = MemoryContextSwitchTo(dstslot->tts_mcxt);
     806       57153 :     newTuple = ExecCopySlotTuple(srcslot);
     807       57153 :     MemoryContextSwitchTo(oldContext);
     808             : 
     809       57153 :     return ExecStoreTuple(newTuple, dstslot, InvalidBuffer, true);
     810             : }
     811             : 
     812             : 
     813             : /* ----------------------------------------------------------------
     814             :  *              convenience initialization routines
     815             :  * ----------------------------------------------------------------
     816             :  */
     817             : 
     818             : /* --------------------------------
     819             :  *      ExecInit{Result,Scan,Extra}TupleSlot
     820             :  *
     821             :  *      These are convenience routines to initialize the specified slot
     822             :  *      in nodes inheriting the appropriate state.  ExecInitExtraTupleSlot
     823             :  *      is used for initializing special-purpose slots.
     824             :  * --------------------------------
     825             :  */
     826             : 
     827             : /* ----------------
     828             :  *      ExecInitResultTupleSlot
     829             :  * ----------------
     830             :  */
     831             : void
     832       50679 : ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
     833             : {
     834       50679 :     planstate->ps_ResultTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable);
     835       50679 : }
     836             : 
     837             : /* ----------------
     838             :  *      ExecInitScanTupleSlot
     839             :  * ----------------
     840             :  */
     841             : void
     842       27584 : ExecInitScanTupleSlot(EState *estate, ScanState *scanstate)
     843             : {
     844       27584 :     scanstate->ss_ScanTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable);
     845       27584 : }
     846             : 
     847             : /* ----------------
     848             :  *      ExecInitExtraTupleSlot
     849             :  * ----------------
     850             :  */
     851             : TupleTableSlot *
     852       16336 : ExecInitExtraTupleSlot(EState *estate)
     853             : {
     854       16336 :     return ExecAllocTableSlot(&estate->es_tupleTable);
     855             : }
     856             : 
     857             : /* ----------------
     858             :  *      ExecInitNullTupleSlot
     859             :  *
     860             :  * Build a slot containing an all-nulls tuple of the given type.
     861             :  * This is used as a substitute for an input tuple when performing an
     862             :  * outer join.
     863             :  * ----------------
     864             :  */
     865             : TupleTableSlot *
     866        1074 : ExecInitNullTupleSlot(EState *estate, TupleDesc tupType)
     867             : {
     868        1074 :     TupleTableSlot *slot = ExecInitExtraTupleSlot(estate);
     869             : 
     870        1074 :     ExecSetSlotDescriptor(slot, tupType);
     871             : 
     872        1074 :     return ExecStoreAllNullTuple(slot);
     873             : }
     874             : 
     875             : /* ----------------------------------------------------------------
     876             :  *      ExecTypeFromTL
     877             :  *
     878             :  *      Generate a tuple descriptor for the result tuple of a targetlist.
     879             :  *      (A parse/plan tlist must be passed, not an ExprState tlist.)
     880             :  *      Note that resjunk columns, if any, are included in the result.
     881             :  *
     882             :  *      Currently there are about 4 different places where we create
     883             :  *      TupleDescriptors.  They should all be merged, or perhaps
     884             :  *      be rewritten to call BuildDesc().
     885             :  * ----------------------------------------------------------------
     886             :  */
     887             : TupleDesc
     888       54990 : ExecTypeFromTL(List *targetList, bool hasoid)
     889             : {
     890       54990 :     return ExecTypeFromTLInternal(targetList, hasoid, false);
     891             : }
     892             : 
     893             : /* ----------------------------------------------------------------
     894             :  *      ExecCleanTypeFromTL
     895             :  *
     896             :  *      Same as above, but resjunk columns are omitted from the result.
     897             :  * ----------------------------------------------------------------
     898             :  */
     899             : TupleDesc
     900        7789 : ExecCleanTypeFromTL(List *targetList, bool hasoid)
     901             : {
     902        7789 :     return ExecTypeFromTLInternal(targetList, hasoid, true);
     903             : }
     904             : 
     905             : static TupleDesc
     906       62779 : ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
     907             : {
     908             :     TupleDesc   typeInfo;
     909             :     ListCell   *l;
     910             :     int         len;
     911       62779 :     int         cur_resno = 1;
     912             : 
     913       62779 :     if (skipjunk)
     914        7789 :         len = ExecCleanTargetListLength(targetList);
     915             :     else
     916       54990 :         len = ExecTargetListLength(targetList);
     917       62779 :     typeInfo = CreateTemplateTupleDesc(len, hasoid);
     918             : 
     919      203902 :     foreach(l, targetList)
     920             :     {
     921      141123 :         TargetEntry *tle = lfirst(l);
     922             : 
     923      141123 :         if (skipjunk && tle->resjunk)
     924        2410 :             continue;
     925      416139 :         TupleDescInitEntry(typeInfo,
     926             :                            cur_resno,
     927      138713 :                            tle->resname,
     928      138713 :                            exprType((Node *) tle->expr),
     929      138713 :                            exprTypmod((Node *) tle->expr),
     930             :                            0);
     931      138713 :         TupleDescInitEntryCollation(typeInfo,
     932             :                                     cur_resno,
     933      138713 :                                     exprCollation((Node *) tle->expr));
     934      138713 :         cur_resno++;
     935             :     }
     936             : 
     937       62779 :     return typeInfo;
     938             : }
     939             : 
     940             : /*
     941             :  * ExecTypeFromExprList - build a tuple descriptor from a list of Exprs
     942             :  *
     943             :  * This is roughly like ExecTypeFromTL, but we work from bare expressions
     944             :  * not TargetEntrys.  No names are attached to the tupledesc's columns.
     945             :  */
     946             : TupleDesc
     947         733 : ExecTypeFromExprList(List *exprList)
     948             : {
     949             :     TupleDesc   typeInfo;
     950             :     ListCell   *lc;
     951         733 :     int         cur_resno = 1;
     952             : 
     953         733 :     typeInfo = CreateTemplateTupleDesc(list_length(exprList), false);
     954             : 
     955        1909 :     foreach(lc, exprList)
     956             :     {
     957        1176 :         Node       *e = lfirst(lc);
     958             : 
     959        1176 :         TupleDescInitEntry(typeInfo,
     960             :                            cur_resno,
     961             :                            NULL,
     962             :                            exprType(e),
     963             :                            exprTypmod(e),
     964             :                            0);
     965        1176 :         TupleDescInitEntryCollation(typeInfo,
     966             :                                     cur_resno,
     967             :                                     exprCollation(e));
     968        1176 :         cur_resno++;
     969             :     }
     970             : 
     971         733 :     return typeInfo;
     972             : }
     973             : 
     974             : /*
     975             :  * ExecTypeSetColNames - set column names in a TupleDesc
     976             :  *
     977             :  * Column names must be provided as an alias list (list of String nodes).
     978             :  *
     979             :  * For some callers, the supplied tupdesc has a named rowtype (not RECORD)
     980             :  * and it is moderately likely that the alias list matches the column names
     981             :  * already present in the tupdesc.  If we do change any column names then
     982             :  * we must reset the tupdesc's type to anonymous RECORD; but we avoid doing
     983             :  * so if no names change.
     984             :  */
     985             : void
     986         556 : ExecTypeSetColNames(TupleDesc typeInfo, List *namesList)
     987             : {
     988         556 :     bool        modified = false;
     989         556 :     int         colno = 0;
     990             :     ListCell   *lc;
     991             : 
     992        1418 :     foreach(lc, namesList)
     993             :     {
     994         862 :         char       *cname = strVal(lfirst(lc));
     995             :         Form_pg_attribute attr;
     996             : 
     997             :         /* Guard against too-long names list */
     998         862 :         if (colno >= typeInfo->natts)
     999           0 :             break;
    1000         862 :         attr = TupleDescAttr(typeInfo, colno);
    1001         862 :         colno++;
    1002             : 
    1003             :         /* Ignore empty aliases (these must be for dropped columns) */
    1004         862 :         if (cname[0] == '\0')
    1005          18 :             continue;
    1006             : 
    1007             :         /* Change tupdesc only if alias is actually different */
    1008         844 :         if (strcmp(cname, NameStr(attr->attname)) != 0)
    1009             :         {
    1010         313 :             namestrcpy(&(attr->attname), cname);
    1011         313 :             modified = true;
    1012             :         }
    1013             :     }
    1014             : 
    1015             :     /* If we modified the tupdesc, it's now a new record type */
    1016         556 :     if (modified)
    1017             :     {
    1018         172 :         typeInfo->tdtypeid = RECORDOID;
    1019         172 :         typeInfo->tdtypmod = -1;
    1020             :     }
    1021         556 : }
    1022             : 
    1023             : /*
    1024             :  * BlessTupleDesc - make a completed tuple descriptor useful for SRFs
    1025             :  *
    1026             :  * Rowtype Datums returned by a function must contain valid type information.
    1027             :  * This happens "for free" if the tupdesc came from a relcache entry, but
    1028             :  * not if we have manufactured a tupdesc for a transient RECORD datatype.
    1029             :  * In that case we have to notify typcache.c of the existence of the type.
    1030             :  */
    1031             : TupleDesc
    1032        3576 : BlessTupleDesc(TupleDesc tupdesc)
    1033             : {
    1034        6492 :     if (tupdesc->tdtypeid == RECORDOID &&
    1035        2916 :         tupdesc->tdtypmod < 0)
    1036         803 :         assign_record_type_typmod(tupdesc);
    1037             : 
    1038        3576 :     return tupdesc;             /* just for notational convenience */
    1039             : }
    1040             : 
    1041             : /*
    1042             :  * TupleDescGetSlot - Initialize a slot based on the supplied tupledesc
    1043             :  *
    1044             :  * Note: this is obsolete; it is sufficient to call BlessTupleDesc on
    1045             :  * the tupdesc.  We keep it around just for backwards compatibility with
    1046             :  * existing user-written SRFs.
    1047             :  */
    1048             : TupleTableSlot *
    1049           0 : TupleDescGetSlot(TupleDesc tupdesc)
    1050             : {
    1051             :     TupleTableSlot *slot;
    1052             : 
    1053             :     /* The useful work is here */
    1054           0 :     BlessTupleDesc(tupdesc);
    1055             : 
    1056             :     /* Make a standalone slot */
    1057           0 :     slot = MakeSingleTupleTableSlot(tupdesc);
    1058             : 
    1059             :     /* Return the slot */
    1060           0 :     return slot;
    1061             : }
    1062             : 
    1063             : /*
    1064             :  * TupleDescGetAttInMetadata - Build an AttInMetadata structure based on the
    1065             :  * supplied TupleDesc. AttInMetadata can be used in conjunction with C strings
    1066             :  * to produce a properly formed tuple.
    1067             :  */
    1068             : AttInMetadata *
    1069          32 : TupleDescGetAttInMetadata(TupleDesc tupdesc)
    1070             : {
    1071          32 :     int         natts = tupdesc->natts;
    1072             :     int         i;
    1073             :     Oid         atttypeid;
    1074             :     Oid         attinfuncid;
    1075             :     FmgrInfo   *attinfuncinfo;
    1076             :     Oid        *attioparams;
    1077             :     int32      *atttypmods;
    1078             :     AttInMetadata *attinmeta;
    1079             : 
    1080          32 :     attinmeta = (AttInMetadata *) palloc(sizeof(AttInMetadata));
    1081             : 
    1082             :     /* "Bless" the tupledesc so that we can make rowtype datums with it */
    1083          32 :     attinmeta->tupdesc = BlessTupleDesc(tupdesc);
    1084             : 
    1085             :     /*
    1086             :      * Gather info needed later to call the "in" function for each attribute
    1087             :      */
    1088          32 :     attinfuncinfo = (FmgrInfo *) palloc0(natts * sizeof(FmgrInfo));
    1089          32 :     attioparams = (Oid *) palloc0(natts * sizeof(Oid));
    1090          32 :     atttypmods = (int32 *) palloc0(natts * sizeof(int32));
    1091             : 
    1092         135 :     for (i = 0; i < natts; i++)
    1093             :     {
    1094         103 :         Form_pg_attribute att = TupleDescAttr(tupdesc, i);
    1095             : 
    1096             :         /* Ignore dropped attributes */
    1097         103 :         if (!att->attisdropped)
    1098             :         {
    1099         103 :             atttypeid = att->atttypid;
    1100         103 :             getTypeInputInfo(atttypeid, &attinfuncid, &attioparams[i]);
    1101         103 :             fmgr_info(attinfuncid, &attinfuncinfo[i]);
    1102         103 :             atttypmods[i] = att->atttypmod;
    1103             :         }
    1104             :     }
    1105          32 :     attinmeta->attinfuncs = attinfuncinfo;
    1106          32 :     attinmeta->attioparams = attioparams;
    1107          32 :     attinmeta->atttypmods = atttypmods;
    1108             : 
    1109          32 :     return attinmeta;
    1110             : }
    1111             : 
    1112             : /*
    1113             :  * BuildTupleFromCStrings - build a HeapTuple given user data in C string form.
    1114             :  * values is an array of C strings, one for each attribute of the return tuple.
    1115             :  * A NULL string pointer indicates we want to create a NULL field.
    1116             :  */
    1117             : HeapTuple
    1118        2107 : BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
    1119             : {
    1120        2107 :     TupleDesc   tupdesc = attinmeta->tupdesc;
    1121        2107 :     int         natts = tupdesc->natts;
    1122             :     Datum      *dvalues;
    1123             :     bool       *nulls;
    1124             :     int         i;
    1125             :     HeapTuple   tuple;
    1126             : 
    1127        2107 :     dvalues = (Datum *) palloc(natts * sizeof(Datum));
    1128        2107 :     nulls = (bool *) palloc(natts * sizeof(bool));
    1129             : 
    1130             :     /* Call the "in" function for each non-dropped attribute */
    1131       12006 :     for (i = 0; i < natts; i++)
    1132             :     {
    1133        9899 :         if (!TupleDescAttr(tupdesc, i)->attisdropped)
    1134             :         {
    1135             :             /* Non-dropped attributes */
    1136       39596 :             dvalues[i] = InputFunctionCall(&attinmeta->attinfuncs[i],
    1137        9899 :                                            values[i],
    1138        9899 :                                            attinmeta->attioparams[i],
    1139        9899 :                                            attinmeta->atttypmods[i]);
    1140        9899 :             if (values[i] != NULL)
    1141        8403 :                 nulls[i] = false;
    1142             :             else
    1143        1496 :                 nulls[i] = true;
    1144             :         }
    1145             :         else
    1146             :         {
    1147             :             /* Handle dropped attributes by setting to NULL */
    1148           0 :             dvalues[i] = (Datum) 0;
    1149           0 :             nulls[i] = true;
    1150             :         }
    1151             :     }
    1152             : 
    1153             :     /*
    1154             :      * Form a tuple
    1155             :      */
    1156        2107 :     tuple = heap_form_tuple(tupdesc, dvalues, nulls);
    1157             : 
    1158             :     /*
    1159             :      * Release locally palloc'd space.  XXX would probably be good to pfree
    1160             :      * values of pass-by-reference datums, as well.
    1161             :      */
    1162        2107 :     pfree(dvalues);
    1163        2107 :     pfree(nulls);
    1164             : 
    1165        2107 :     return tuple;
    1166             : }
    1167             : 
    1168             : /*
    1169             :  * HeapTupleHeaderGetDatum - convert a HeapTupleHeader pointer to a Datum.
    1170             :  *
    1171             :  * This must *not* get applied to an on-disk tuple; the tuple should be
    1172             :  * freshly made by heap_form_tuple or some wrapper routine for it (such as
    1173             :  * BuildTupleFromCStrings).  Be sure also that the tupledesc used to build
    1174             :  * the tuple has a properly "blessed" rowtype.
    1175             :  *
    1176             :  * Formerly this was a macro equivalent to PointerGetDatum, relying on the
    1177             :  * fact that heap_form_tuple fills in the appropriate tuple header fields
    1178             :  * for a composite Datum.  However, we now require that composite Datums not
    1179             :  * contain any external TOAST pointers.  We do not want heap_form_tuple itself
    1180             :  * to enforce that; more specifically, the rule applies only to actual Datums
    1181             :  * and not to HeapTuple structures.  Therefore, HeapTupleHeaderGetDatum is
    1182             :  * now a function that detects whether there are externally-toasted fields
    1183             :  * and constructs a new tuple with inlined fields if so.  We still need
    1184             :  * heap_form_tuple to insert the Datum header fields, because otherwise this
    1185             :  * code would have no way to obtain a tupledesc for the tuple.
    1186             :  *
    1187             :  * Note that if we do build a new tuple, it's palloc'd in the current
    1188             :  * memory context.  Beware of code that changes context between the initial
    1189             :  * heap_form_tuple/etc call and calling HeapTuple(Header)GetDatum.
    1190             :  *
    1191             :  * For performance-critical callers, it could be worthwhile to take extra
    1192             :  * steps to ensure that there aren't TOAST pointers in the output of
    1193             :  * heap_form_tuple to begin with.  It's likely however that the costs of the
    1194             :  * typcache lookup and tuple disassembly/reassembly are swamped by TOAST
    1195             :  * dereference costs, so that the benefits of such extra effort would be
    1196             :  * minimal.
    1197             :  *
    1198             :  * XXX it would likely be better to create wrapper functions that produce
    1199             :  * a composite Datum from the field values in one step.  However, there's
    1200             :  * enough code using the existing APIs that we couldn't get rid of this
    1201             :  * hack anytime soon.
    1202             :  */
    1203             : Datum
    1204        6109 : HeapTupleHeaderGetDatum(HeapTupleHeader tuple)
    1205             : {
    1206             :     Datum       result;
    1207             :     TupleDesc   tupDesc;
    1208             : 
    1209             :     /* No work if there are no external TOAST pointers in the tuple */
    1210        6109 :     if (!HeapTupleHeaderHasExternal(tuple))
    1211        6107 :         return PointerGetDatum(tuple);
    1212             : 
    1213             :     /* Use the type data saved by heap_form_tuple to look up the rowtype */
    1214           2 :     tupDesc = lookup_rowtype_tupdesc(HeapTupleHeaderGetTypeId(tuple),
    1215             :                                      HeapTupleHeaderGetTypMod(tuple));
    1216             : 
    1217             :     /* And do the flattening */
    1218           2 :     result = toast_flatten_tuple_to_datum(tuple,
    1219           2 :                                           HeapTupleHeaderGetDatumLength(tuple),
    1220             :                                           tupDesc);
    1221             : 
    1222           2 :     ReleaseTupleDesc(tupDesc);
    1223             : 
    1224           2 :     return result;
    1225             : }
    1226             : 
    1227             : 
    1228             : /*
    1229             :  * Functions for sending tuples to the frontend (or other specified destination)
    1230             :  * as though it is a SELECT result. These are used by utility commands that
    1231             :  * need to project directly to the destination and don't need or want full
    1232             :  * table function capability. Currently used by EXPLAIN and SHOW ALL.
    1233             :  */
    1234             : TupOutputState *
    1235        1180 : begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
    1236             : {
    1237             :     TupOutputState *tstate;
    1238             : 
    1239        1180 :     tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
    1240             : 
    1241        1180 :     tstate->slot = MakeSingleTupleTableSlot(tupdesc);
    1242        1180 :     tstate->dest = dest;
    1243             : 
    1244        1180 :     (*tstate->dest->rStartup) (tstate->dest, (int) CMD_SELECT, tupdesc);
    1245             : 
    1246        1180 :     return tstate;
    1247             : }
    1248             : 
    1249             : /*
    1250             :  * write a single tuple
    1251             :  */
    1252             : void
    1253        5943 : do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
    1254             : {
    1255        5943 :     TupleTableSlot *slot = tstate->slot;
    1256        5943 :     int         natts = slot->tts_tupleDescriptor->natts;
    1257             : 
    1258             :     /* make sure the slot is clear */
    1259        5943 :     ExecClearTuple(slot);
    1260             : 
    1261             :     /* insert data */
    1262        5943 :     memcpy(slot->tts_values, values, natts * sizeof(Datum));
    1263        5943 :     memcpy(slot->tts_isnull, isnull, natts * sizeof(bool));
    1264             : 
    1265             :     /* mark slot as containing a virtual tuple */
    1266        5943 :     ExecStoreVirtualTuple(slot);
    1267             : 
    1268             :     /* send the tuple to the receiver */
    1269        5943 :     (void) (*tstate->dest->receiveSlot) (slot, tstate->dest);
    1270             : 
    1271             :     /* clean up */
    1272        5943 :     ExecClearTuple(slot);
    1273        5943 : }
    1274             : 
    1275             : /*
    1276             :  * write a chunk of text, breaking at newline characters
    1277             :  *
    1278             :  * Should only be used with a single-TEXT-attribute tupdesc.
    1279             :  */
    1280             : void
    1281        1115 : do_text_output_multiline(TupOutputState *tstate, const char *txt)
    1282             : {
    1283             :     Datum       values[1];
    1284        1115 :     bool        isnull[1] = {false};
    1285             : 
    1286        8108 :     while (*txt)
    1287             :     {
    1288             :         const char *eol;
    1289             :         int         len;
    1290             : 
    1291        5878 :         eol = strchr(txt, '\n');
    1292        5878 :         if (eol)
    1293             :         {
    1294        5878 :             len = eol - txt;
    1295        5878 :             eol++;
    1296             :         }
    1297             :         else
    1298             :         {
    1299           0 :             len = strlen(txt);
    1300           0 :             eol = txt + len;
    1301             :         }
    1302             : 
    1303        5878 :         values[0] = PointerGetDatum(cstring_to_text_with_len(txt, len));
    1304        5878 :         do_tup_output(tstate, values, isnull);
    1305        5878 :         pfree(DatumGetPointer(values[0]));
    1306        5878 :         txt = eol;
    1307             :     }
    1308        1115 : }
    1309             : 
    1310             : void
    1311        1180 : end_tup_output(TupOutputState *tstate)
    1312             : {
    1313        1180 :     (*tstate->dest->rShutdown) (tstate->dest);
    1314             :     /* note that destroying the dest is not ours to do */
    1315        1180 :     ExecDropSingleTupleTableSlot(tstate->slot);
    1316        1180 :     pfree(tstate);
    1317        1180 : }

Generated by: LCOV version 1.11