Header And Logo

PostgreSQL
| The world's most advanced open source database.

execTuples.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * execTuples.c
00004  *    Routines dealing with TupleTableSlots.  These are used for resource
00005  *    management associated with tuples (eg, releasing buffer pins for
00006  *    tuples in disk buffers, or freeing the memory occupied by transient
00007  *    tuples).  Slots also provide access abstraction that lets us implement
00008  *    "virtual" tuples to reduce data-copying overhead.
00009  *
00010  *    Routines dealing with the type information for tuples. Currently,
00011  *    the type information for a tuple is an array of FormData_pg_attribute.
00012  *    This information is needed by routines manipulating tuples
00013  *    (getattribute, formtuple, etc.).
00014  *
00015  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00016  * Portions Copyright (c) 1994, Regents of the University of California
00017  *
00018  *
00019  * IDENTIFICATION
00020  *    src/backend/executor/execTuples.c
00021  *
00022  *-------------------------------------------------------------------------
00023  */
00024 /*
00025  * INTERFACE ROUTINES
00026  *
00027  *   SLOT CREATION/DESTRUCTION
00028  *      MakeTupleTableSlot      - create an empty slot
00029  *      ExecAllocTableSlot      - create a slot within a tuple table
00030  *      ExecResetTupleTable     - clear and optionally delete a tuple table
00031  *      MakeSingleTupleTableSlot - make a standalone slot, set its descriptor
00032  *      ExecDropSingleTupleTableSlot - destroy a standalone slot
00033  *
00034  *   SLOT ACCESSORS
00035  *      ExecSetSlotDescriptor   - set a slot's tuple descriptor
00036  *      ExecStoreTuple          - store a physical tuple in the slot
00037  *      ExecStoreMinimalTuple   - store a minimal physical tuple in the slot
00038  *      ExecClearTuple          - clear contents of a slot
00039  *      ExecStoreVirtualTuple   - mark slot as containing a virtual tuple
00040  *      ExecCopySlotTuple       - build a physical tuple from a slot
00041  *      ExecCopySlotMinimalTuple - build a minimal physical tuple from a slot
00042  *      ExecMaterializeSlot     - convert virtual to physical storage
00043  *      ExecCopySlot            - copy one slot's contents to another
00044  *
00045  *   CONVENIENCE INITIALIZATION ROUTINES
00046  *      ExecInitResultTupleSlot    \    convenience routines to initialize
00047  *      ExecInitScanTupleSlot       \   the various tuple slots for nodes
00048  *      ExecInitExtraTupleSlot      /   which store copies of tuples.
00049  *      ExecInitNullTupleSlot      /
00050  *
00051  *   Routines that probably belong somewhere else:
00052  *      ExecTypeFromTL          - form a TupleDesc from a target list
00053  *
00054  *   EXAMPLE OF HOW TABLE ROUTINES WORK
00055  *      Suppose we have a query such as SELECT emp.name FROM emp and we have
00056  *      a single SeqScan node in the query plan.
00057  *
00058  *      At ExecutorStart()
00059  *      ----------------
00060  *      - ExecInitSeqScan() calls ExecInitScanTupleSlot() and
00061  *        ExecInitResultTupleSlot() to construct TupleTableSlots
00062  *        for the tuples returned by the access methods and the
00063  *        tuples resulting from performing target list projections.
00064  *
00065  *      During ExecutorRun()
00066  *      ----------------
00067  *      - SeqNext() calls ExecStoreTuple() to place the tuple returned
00068  *        by the access methods into the scan tuple slot.
00069  *
00070  *      - ExecSeqScan() calls ExecStoreTuple() to take the result
00071  *        tuple from ExecProject() and place it into the result tuple slot.
00072  *
00073  *      - ExecutePlan() calls ExecSelect(), which passes the result slot
00074  *        to printtup(), which uses slot_getallattrs() to extract the
00075  *        individual Datums for printing.
00076  *
00077  *      At ExecutorEnd()
00078  *      ----------------
00079  *      - EndPlan() calls ExecResetTupleTable() to clean up any remaining
00080  *        tuples left over from executing the query.
00081  *
00082  *      The important thing to watch in the executor code is how pointers
00083  *      to the slots containing tuples are passed instead of the tuples
00084  *      themselves.  This facilitates the communication of related information
00085  *      (such as whether or not a tuple should be pfreed, what buffer contains
00086  *      this tuple, the tuple's tuple descriptor, etc).  It also allows us
00087  *      to avoid physically constructing projection tuples in many cases.
00088  */
00089 #include "postgres.h"
00090 
00091 #include "access/htup_details.h"
00092 #include "funcapi.h"
00093 #include "catalog/pg_type.h"
00094 #include "nodes/nodeFuncs.h"
00095 #include "storage/bufmgr.h"
00096 #include "utils/builtins.h"
00097 #include "utils/lsyscache.h"
00098 #include "utils/typcache.h"
00099 
00100 
00101 static TupleDesc ExecTypeFromTLInternal(List *targetList,
00102                        bool hasoid, bool skipjunk);
00103 
00104 
00105 /* ----------------------------------------------------------------
00106  *                tuple table create/delete functions
00107  * ----------------------------------------------------------------
00108  */
00109 
00110 /* --------------------------------
00111  *      MakeTupleTableSlot
00112  *
00113  *      Basic routine to make an empty TupleTableSlot.
00114  * --------------------------------
00115  */
00116 TupleTableSlot *
00117 MakeTupleTableSlot(void)
00118 {
00119     TupleTableSlot *slot = makeNode(TupleTableSlot);
00120 
00121     slot->tts_isempty = true;
00122     slot->tts_shouldFree = false;
00123     slot->tts_shouldFreeMin = false;
00124     slot->tts_tuple = NULL;
00125     slot->tts_tupleDescriptor = NULL;
00126     slot->tts_mcxt = CurrentMemoryContext;
00127     slot->tts_buffer = InvalidBuffer;
00128     slot->tts_nvalid = 0;
00129     slot->tts_values = NULL;
00130     slot->tts_isnull = NULL;
00131     slot->tts_mintuple = NULL;
00132 
00133     return slot;
00134 }
00135 
00136 /* --------------------------------
00137  *      ExecAllocTableSlot
00138  *
00139  *      Create a tuple table slot within a tuple table (which is just a List).
00140  * --------------------------------
00141  */
00142 TupleTableSlot *
00143 ExecAllocTableSlot(List **tupleTable)
00144 {
00145     TupleTableSlot *slot = MakeTupleTableSlot();
00146 
00147     *tupleTable = lappend(*tupleTable, slot);
00148 
00149     return slot;
00150 }
00151 
00152 /* --------------------------------
00153  *      ExecResetTupleTable
00154  *
00155  *      This releases any resources (buffer pins, tupdesc refcounts)
00156  *      held by the tuple table, and optionally releases the memory
00157  *      occupied by the tuple table data structure.
00158  *      It is expected that this routine be called by EndPlan().
00159  * --------------------------------
00160  */
00161 void
00162 ExecResetTupleTable(List *tupleTable,   /* tuple table */
00163                     bool shouldFree)    /* true if we should free memory */
00164 {
00165     ListCell   *lc;
00166 
00167     foreach(lc, tupleTable)
00168     {
00169         TupleTableSlot *slot = (TupleTableSlot *) lfirst(lc);
00170 
00171         /* Sanity checks */
00172         Assert(IsA(slot, TupleTableSlot));
00173 
00174         /* Always release resources and reset the slot to empty */
00175         ExecClearTuple(slot);
00176         if (slot->tts_tupleDescriptor)
00177         {
00178             ReleaseTupleDesc(slot->tts_tupleDescriptor);
00179             slot->tts_tupleDescriptor = NULL;
00180         }
00181 
00182         /* If shouldFree, release memory occupied by the slot itself */
00183         if (shouldFree)
00184         {
00185             if (slot->tts_values)
00186                 pfree(slot->tts_values);
00187             if (slot->tts_isnull)
00188                 pfree(slot->tts_isnull);
00189             pfree(slot);
00190         }
00191     }
00192 
00193     /* If shouldFree, release the list structure */
00194     if (shouldFree)
00195         list_free(tupleTable);
00196 }
00197 
00198 /* --------------------------------
00199  *      MakeSingleTupleTableSlot
00200  *
00201  *      This is a convenience routine for operations that need a
00202  *      standalone TupleTableSlot not gotten from the main executor
00203  *      tuple table.  It makes a single slot and initializes it
00204  *      to use the given tuple descriptor.
00205  * --------------------------------
00206  */
00207 TupleTableSlot *
00208 MakeSingleTupleTableSlot(TupleDesc tupdesc)
00209 {
00210     TupleTableSlot *slot = MakeTupleTableSlot();
00211 
00212     ExecSetSlotDescriptor(slot, tupdesc);
00213 
00214     return slot;
00215 }
00216 
00217 /* --------------------------------
00218  *      ExecDropSingleTupleTableSlot
00219  *
00220  *      Release a TupleTableSlot made with MakeSingleTupleTableSlot.
00221  *      DON'T use this on a slot that's part of a tuple table list!
00222  * --------------------------------
00223  */
00224 void
00225 ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
00226 {
00227     /* This should match ExecResetTupleTable's processing of one slot */
00228     Assert(IsA(slot, TupleTableSlot));
00229     ExecClearTuple(slot);
00230     if (slot->tts_tupleDescriptor)
00231         ReleaseTupleDesc(slot->tts_tupleDescriptor);
00232     if (slot->tts_values)
00233         pfree(slot->tts_values);
00234     if (slot->tts_isnull)
00235         pfree(slot->tts_isnull);
00236     pfree(slot);
00237 }
00238 
00239 
00240 /* ----------------------------------------------------------------
00241  *                tuple table slot accessor functions
00242  * ----------------------------------------------------------------
00243  */
00244 
00245 /* --------------------------------
00246  *      ExecSetSlotDescriptor
00247  *
00248  *      This function is used to set the tuple descriptor associated
00249  *      with the slot's tuple.  The passed descriptor must have lifespan
00250  *      at least equal to the slot's.  If it is a reference-counted descriptor
00251  *      then the reference count is incremented for as long as the slot holds
00252  *      a reference.
00253  * --------------------------------
00254  */
00255 void
00256 ExecSetSlotDescriptor(TupleTableSlot *slot,     /* slot to change */
00257                       TupleDesc tupdesc)        /* new tuple descriptor */
00258 {
00259     /* For safety, make sure slot is empty before changing it */
00260     ExecClearTuple(slot);
00261 
00262     /*
00263      * Release any old descriptor.  Also release old Datum/isnull arrays if
00264      * present (we don't bother to check if they could be re-used).
00265      */
00266     if (slot->tts_tupleDescriptor)
00267         ReleaseTupleDesc(slot->tts_tupleDescriptor);
00268 
00269     if (slot->tts_values)
00270         pfree(slot->tts_values);
00271     if (slot->tts_isnull)
00272         pfree(slot->tts_isnull);
00273 
00274     /*
00275      * Install the new descriptor; if it's refcounted, bump its refcount.
00276      */
00277     slot->tts_tupleDescriptor = tupdesc;
00278     PinTupleDesc(tupdesc);
00279 
00280     /*
00281      * Allocate Datum/isnull arrays of the appropriate size.  These must have
00282      * the same lifetime as the slot, so allocate in the slot's own context.
00283      */
00284     slot->tts_values = (Datum *)
00285         MemoryContextAlloc(slot->tts_mcxt, tupdesc->natts * sizeof(Datum));
00286     slot->tts_isnull = (bool *)
00287         MemoryContextAlloc(slot->tts_mcxt, tupdesc->natts * sizeof(bool));
00288 }
00289 
00290 /* --------------------------------
00291  *      ExecStoreTuple
00292  *
00293  *      This function is used to store a physical tuple into a specified
00294  *      slot in the tuple table.
00295  *
00296  *      tuple:  tuple to store
00297  *      slot:   slot to store it in
00298  *      buffer: disk buffer if tuple is in a disk page, else InvalidBuffer
00299  *      shouldFree: true if ExecClearTuple should pfree() the tuple
00300  *                  when done with it
00301  *
00302  * If 'buffer' is not InvalidBuffer, the tuple table code acquires a pin
00303  * on the buffer which is held until the slot is cleared, so that the tuple
00304  * won't go away on us.
00305  *
00306  * shouldFree is normally set 'true' for tuples constructed on-the-fly.
00307  * It must always be 'false' for tuples that are stored in disk pages,
00308  * since we don't want to try to pfree those.
00309  *
00310  * Another case where it is 'false' is when the referenced tuple is held
00311  * in a tuple table slot belonging to a lower-level executor Proc node.
00312  * In this case the lower-level slot retains ownership and responsibility
00313  * for eventually releasing the tuple.  When this method is used, we must
00314  * be certain that the upper-level Proc node will lose interest in the tuple
00315  * sooner than the lower-level one does!  If you're not certain, copy the
00316  * lower-level tuple with heap_copytuple and let the upper-level table
00317  * slot assume ownership of the copy!
00318  *
00319  * Return value is just the passed-in slot pointer.
00320  *
00321  * NOTE: before PostgreSQL 8.1, this function would accept a NULL tuple
00322  * pointer and effectively behave like ExecClearTuple (though you could
00323  * still specify a buffer to pin, which would be an odd combination).
00324  * This saved a couple lines of code in a few places, but seemed more likely
00325  * to mask logic errors than to be really useful, so it's now disallowed.
00326  * --------------------------------
00327  */
00328 TupleTableSlot *
00329 ExecStoreTuple(HeapTuple tuple,
00330                TupleTableSlot *slot,
00331                Buffer buffer,
00332                bool shouldFree)
00333 {
00334     /*
00335      * sanity checks
00336      */
00337     Assert(tuple != NULL);
00338     Assert(slot != NULL);
00339     Assert(slot->tts_tupleDescriptor != NULL);
00340     /* passing shouldFree=true for a tuple on a disk page is not sane */
00341     Assert(BufferIsValid(buffer) ? (!shouldFree) : true);
00342 
00343     /*
00344      * Free any old physical tuple belonging to the slot.
00345      */
00346     if (slot->tts_shouldFree)
00347         heap_freetuple(slot->tts_tuple);
00348     if (slot->tts_shouldFreeMin)
00349         heap_free_minimal_tuple(slot->tts_mintuple);
00350 
00351     /*
00352      * Store the new tuple into the specified slot.
00353      */
00354     slot->tts_isempty = false;
00355     slot->tts_shouldFree = shouldFree;
00356     slot->tts_shouldFreeMin = false;
00357     slot->tts_tuple = tuple;
00358     slot->tts_mintuple = NULL;
00359 
00360     /* Mark extracted state invalid */
00361     slot->tts_nvalid = 0;
00362 
00363     /*
00364      * If tuple is on a disk page, keep the page pinned as long as we hold a
00365      * pointer into it.  We assume the caller already has such a pin.
00366      *
00367      * This is coded to optimize the case where the slot previously held a
00368      * tuple on the same disk page: in that case releasing and re-acquiring
00369      * the pin is a waste of cycles.  This is a common situation during
00370      * seqscans, so it's worth troubling over.
00371      */
00372     if (slot->tts_buffer != buffer)
00373     {
00374         if (BufferIsValid(slot->tts_buffer))
00375             ReleaseBuffer(slot->tts_buffer);
00376         slot->tts_buffer = buffer;
00377         if (BufferIsValid(buffer))
00378             IncrBufferRefCount(buffer);
00379     }
00380 
00381     return slot;
00382 }
00383 
00384 /* --------------------------------
00385  *      ExecStoreMinimalTuple
00386  *
00387  *      Like ExecStoreTuple, but insert a "minimal" tuple into the slot.
00388  *
00389  * No 'buffer' parameter since minimal tuples are never stored in relations.
00390  * --------------------------------
00391  */
00392 TupleTableSlot *
00393 ExecStoreMinimalTuple(MinimalTuple mtup,
00394                       TupleTableSlot *slot,
00395                       bool shouldFree)
00396 {
00397     /*
00398      * sanity checks
00399      */
00400     Assert(mtup != NULL);
00401     Assert(slot != NULL);
00402     Assert(slot->tts_tupleDescriptor != NULL);
00403 
00404     /*
00405      * Free any old physical tuple belonging to the slot.
00406      */
00407     if (slot->tts_shouldFree)
00408         heap_freetuple(slot->tts_tuple);
00409     if (slot->tts_shouldFreeMin)
00410         heap_free_minimal_tuple(slot->tts_mintuple);
00411 
00412     /*
00413      * Drop the pin on the referenced buffer, if there is one.
00414      */
00415     if (BufferIsValid(slot->tts_buffer))
00416         ReleaseBuffer(slot->tts_buffer);
00417 
00418     slot->tts_buffer = InvalidBuffer;
00419 
00420     /*
00421      * Store the new tuple into the specified slot.
00422      */
00423     slot->tts_isempty = false;
00424     slot->tts_shouldFree = false;
00425     slot->tts_shouldFreeMin = shouldFree;
00426     slot->tts_tuple = &slot->tts_minhdr;
00427     slot->tts_mintuple = mtup;
00428 
00429     slot->tts_minhdr.t_len = mtup->t_len + MINIMAL_TUPLE_OFFSET;
00430     slot->tts_minhdr.t_data = (HeapTupleHeader) ((char *) mtup - MINIMAL_TUPLE_OFFSET);
00431     /* no need to set t_self or t_tableOid since we won't allow access */
00432 
00433     /* Mark extracted state invalid */
00434     slot->tts_nvalid = 0;
00435 
00436     return slot;
00437 }
00438 
00439 /* --------------------------------
00440  *      ExecClearTuple
00441  *
00442  *      This function is used to clear out a slot in the tuple table.
00443  *
00444  *      NB: only the tuple is cleared, not the tuple descriptor (if any).
00445  * --------------------------------
00446  */
00447 TupleTableSlot *                /* return: slot passed */
00448 ExecClearTuple(TupleTableSlot *slot)    /* slot in which to store tuple */
00449 {
00450     /*
00451      * sanity checks
00452      */
00453     Assert(slot != NULL);
00454 
00455     /*
00456      * Free the old physical tuple if necessary.
00457      */
00458     if (slot->tts_shouldFree)
00459         heap_freetuple(slot->tts_tuple);
00460     if (slot->tts_shouldFreeMin)
00461         heap_free_minimal_tuple(slot->tts_mintuple);
00462 
00463     slot->tts_tuple = NULL;
00464     slot->tts_mintuple = NULL;
00465     slot->tts_shouldFree = false;
00466     slot->tts_shouldFreeMin = false;
00467 
00468     /*
00469      * Drop the pin on the referenced buffer, if there is one.
00470      */
00471     if (BufferIsValid(slot->tts_buffer))
00472         ReleaseBuffer(slot->tts_buffer);
00473 
00474     slot->tts_buffer = InvalidBuffer;
00475 
00476     /*
00477      * Mark it empty.
00478      */
00479     slot->tts_isempty = true;
00480     slot->tts_nvalid = 0;
00481 
00482     return slot;
00483 }
00484 
00485 /* --------------------------------
00486  *      ExecStoreVirtualTuple
00487  *          Mark a slot as containing a virtual tuple.
00488  *
00489  * The protocol for loading a slot with virtual tuple data is:
00490  *      * Call ExecClearTuple to mark the slot empty.
00491  *      * Store data into the Datum/isnull arrays.
00492  *      * Call ExecStoreVirtualTuple to mark the slot valid.
00493  * This is a bit unclean but it avoids one round of data copying.
00494  * --------------------------------
00495  */
00496 TupleTableSlot *
00497 ExecStoreVirtualTuple(TupleTableSlot *slot)
00498 {
00499     /*
00500      * sanity checks
00501      */
00502     Assert(slot != NULL);
00503     Assert(slot->tts_tupleDescriptor != NULL);
00504     Assert(slot->tts_isempty);
00505 
00506     slot->tts_isempty = false;
00507     slot->tts_nvalid = slot->tts_tupleDescriptor->natts;
00508 
00509     return slot;
00510 }
00511 
00512 /* --------------------------------
00513  *      ExecStoreAllNullTuple
00514  *          Set up the slot to contain a null in every column.
00515  *
00516  * At first glance this might sound just like ExecClearTuple, but it's
00517  * entirely different: the slot ends up full, not empty.
00518  * --------------------------------
00519  */
00520 TupleTableSlot *
00521 ExecStoreAllNullTuple(TupleTableSlot *slot)
00522 {
00523     /*
00524      * sanity checks
00525      */
00526     Assert(slot != NULL);
00527     Assert(slot->tts_tupleDescriptor != NULL);
00528 
00529     /* Clear any old contents */
00530     ExecClearTuple(slot);
00531 
00532     /*
00533      * Fill all the columns of the virtual tuple with nulls
00534      */
00535     MemSet(slot->tts_values, 0,
00536            slot->tts_tupleDescriptor->natts * sizeof(Datum));
00537     memset(slot->tts_isnull, true,
00538            slot->tts_tupleDescriptor->natts * sizeof(bool));
00539 
00540     return ExecStoreVirtualTuple(slot);
00541 }
00542 
00543 /* --------------------------------
00544  *      ExecCopySlotTuple
00545  *          Obtain a copy of a slot's regular physical tuple.  The copy is
00546  *          palloc'd in the current memory context.
00547  *          The slot itself is undisturbed.
00548  *
00549  *      This works even if the slot contains a virtual or minimal tuple;
00550  *      however the "system columns" of the result will not be meaningful.
00551  * --------------------------------
00552  */
00553 HeapTuple
00554 ExecCopySlotTuple(TupleTableSlot *slot)
00555 {
00556     /*
00557      * sanity checks
00558      */
00559     Assert(slot != NULL);
00560     Assert(!slot->tts_isempty);
00561 
00562     /*
00563      * If we have a physical tuple (either format) then just copy it.
00564      */
00565     if (TTS_HAS_PHYSICAL_TUPLE(slot))
00566         return heap_copytuple(slot->tts_tuple);
00567     if (slot->tts_mintuple)
00568         return heap_tuple_from_minimal_tuple(slot->tts_mintuple);
00569 
00570     /*
00571      * Otherwise we need to build a tuple from the Datum array.
00572      */
00573     return heap_form_tuple(slot->tts_tupleDescriptor,
00574                            slot->tts_values,
00575                            slot->tts_isnull);
00576 }
00577 
00578 /* --------------------------------
00579  *      ExecCopySlotMinimalTuple
00580  *          Obtain a copy of a slot's minimal physical tuple.  The copy is
00581  *          palloc'd in the current memory context.
00582  *          The slot itself is undisturbed.
00583  * --------------------------------
00584  */
00585 MinimalTuple
00586 ExecCopySlotMinimalTuple(TupleTableSlot *slot)
00587 {
00588     /*
00589      * sanity checks
00590      */
00591     Assert(slot != NULL);
00592     Assert(!slot->tts_isempty);
00593 
00594     /*
00595      * If we have a physical tuple then just copy it.  Prefer to copy
00596      * tts_mintuple since that's a tad cheaper.
00597      */
00598     if (slot->tts_mintuple)
00599         return heap_copy_minimal_tuple(slot->tts_mintuple);
00600     if (slot->tts_tuple)
00601         return minimal_tuple_from_heap_tuple(slot->tts_tuple);
00602 
00603     /*
00604      * Otherwise we need to build a tuple from the Datum array.
00605      */
00606     return heap_form_minimal_tuple(slot->tts_tupleDescriptor,
00607                                    slot->tts_values,
00608                                    slot->tts_isnull);
00609 }
00610 
00611 /* --------------------------------
00612  *      ExecFetchSlotTuple
00613  *          Fetch the slot's regular physical tuple.
00614  *
00615  *      If the slot contains a virtual tuple, we convert it to physical
00616  *      form.  The slot retains ownership of the physical tuple.
00617  *      If it contains a minimal tuple we convert to regular form and store
00618  *      that in addition to the minimal tuple (not instead of, because
00619  *      callers may hold pointers to Datums within the minimal tuple).
00620  *
00621  * The main difference between this and ExecMaterializeSlot() is that this
00622  * does not guarantee that the contained tuple is local storage.
00623  * Hence, the result must be treated as read-only.
00624  * --------------------------------
00625  */
00626 HeapTuple
00627 ExecFetchSlotTuple(TupleTableSlot *slot)
00628 {
00629     /*
00630      * sanity checks
00631      */
00632     Assert(slot != NULL);
00633     Assert(!slot->tts_isempty);
00634 
00635     /*
00636      * If we have a regular physical tuple then just return it.
00637      */
00638     if (TTS_HAS_PHYSICAL_TUPLE(slot))
00639         return slot->tts_tuple;
00640 
00641     /*
00642      * Otherwise materialize the slot...
00643      */
00644     return ExecMaterializeSlot(slot);
00645 }
00646 
00647 /* --------------------------------
00648  *      ExecFetchSlotMinimalTuple
00649  *          Fetch the slot's minimal physical tuple.
00650  *
00651  *      If the slot contains a virtual tuple, we convert it to minimal
00652  *      physical form.  The slot retains ownership of the minimal tuple.
00653  *      If it contains a regular tuple we convert to minimal form and store
00654  *      that in addition to the regular tuple (not instead of, because
00655  *      callers may hold pointers to Datums within the regular tuple).
00656  *
00657  * As above, the result must be treated as read-only.
00658  * --------------------------------
00659  */
00660 MinimalTuple
00661 ExecFetchSlotMinimalTuple(TupleTableSlot *slot)
00662 {
00663     MemoryContext oldContext;
00664 
00665     /*
00666      * sanity checks
00667      */
00668     Assert(slot != NULL);
00669     Assert(!slot->tts_isempty);
00670 
00671     /*
00672      * If we have a minimal physical tuple (local or not) then just return it.
00673      */
00674     if (slot->tts_mintuple)
00675         return slot->tts_mintuple;
00676 
00677     /*
00678      * Otherwise, copy or build a minimal tuple, and store it into the slot.
00679      *
00680      * We may be called in a context that is shorter-lived than the tuple
00681      * slot, but we have to ensure that the materialized tuple will survive
00682      * anyway.
00683      */
00684     oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
00685     slot->tts_mintuple = ExecCopySlotMinimalTuple(slot);
00686     slot->tts_shouldFreeMin = true;
00687     MemoryContextSwitchTo(oldContext);
00688 
00689     /*
00690      * Note: we may now have a situation where we have a local minimal tuple
00691      * attached to a virtual or non-local physical tuple.  There seems no harm
00692      * in that at the moment, but if any materializes, we should change this
00693      * function to force the slot into minimal-tuple-only state.
00694      */
00695 
00696     return slot->tts_mintuple;
00697 }
00698 
00699 /* --------------------------------
00700  *      ExecFetchSlotTupleDatum
00701  *          Fetch the slot's tuple as a composite-type Datum.
00702  *
00703  *      We convert the slot's contents to local physical-tuple form,
00704  *      and fill in the Datum header fields.  Note that the result
00705  *      always points to storage owned by the slot.
00706  * --------------------------------
00707  */
00708 Datum
00709 ExecFetchSlotTupleDatum(TupleTableSlot *slot)
00710 {
00711     HeapTuple   tup;
00712     HeapTupleHeader td;
00713     TupleDesc   tupdesc;
00714 
00715     /* Make sure we can scribble on the slot contents ... */
00716     tup = ExecMaterializeSlot(slot);
00717     /* ... and set up the composite-Datum header fields, in case not done */
00718     td = tup->t_data;
00719     tupdesc = slot->tts_tupleDescriptor;
00720     HeapTupleHeaderSetDatumLength(td, tup->t_len);
00721     HeapTupleHeaderSetTypeId(td, tupdesc->tdtypeid);
00722     HeapTupleHeaderSetTypMod(td, tupdesc->tdtypmod);
00723     return PointerGetDatum(td);
00724 }
00725 
00726 /* --------------------------------
00727  *      ExecMaterializeSlot
00728  *          Force a slot into the "materialized" state.
00729  *
00730  *      This causes the slot's tuple to be a local copy not dependent on
00731  *      any external storage.  A pointer to the contained tuple is returned.
00732  *
00733  *      A typical use for this operation is to prepare a computed tuple
00734  *      for being stored on disk.  The original data may or may not be
00735  *      virtual, but in any case we need a private copy for heap_insert
00736  *      to scribble on.
00737  * --------------------------------
00738  */
00739 HeapTuple
00740 ExecMaterializeSlot(TupleTableSlot *slot)
00741 {
00742     MemoryContext oldContext;
00743 
00744     /*
00745      * sanity checks
00746      */
00747     Assert(slot != NULL);
00748     Assert(!slot->tts_isempty);
00749 
00750     /*
00751      * If we have a regular physical tuple, and it's locally palloc'd, we have
00752      * nothing to do.
00753      */
00754     if (slot->tts_tuple && slot->tts_shouldFree)
00755         return slot->tts_tuple;
00756 
00757     /*
00758      * Otherwise, copy or build a physical tuple, and store it into the slot.
00759      *
00760      * We may be called in a context that is shorter-lived than the tuple
00761      * slot, but we have to ensure that the materialized tuple will survive
00762      * anyway.
00763      */
00764     oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
00765     slot->tts_tuple = ExecCopySlotTuple(slot);
00766     slot->tts_shouldFree = true;
00767     MemoryContextSwitchTo(oldContext);
00768 
00769     /*
00770      * Drop the pin on the referenced buffer, if there is one.
00771      */
00772     if (BufferIsValid(slot->tts_buffer))
00773         ReleaseBuffer(slot->tts_buffer);
00774 
00775     slot->tts_buffer = InvalidBuffer;
00776 
00777     /*
00778      * Mark extracted state invalid.  This is important because the slot is
00779      * not supposed to depend any more on the previous external data; we
00780      * mustn't leave any dangling pass-by-reference datums in tts_values.
00781      * However, we have not actually invalidated any such datums, if there
00782      * happen to be any previously fetched from the slot.  (Note in particular
00783      * that we have not pfree'd tts_mintuple, if there is one.)
00784      */
00785     slot->tts_nvalid = 0;
00786 
00787     /*
00788      * On the same principle of not depending on previous remote storage,
00789      * forget the mintuple if it's not local storage.  (If it is local
00790      * storage, we must not pfree it now, since callers might have already
00791      * fetched datum pointers referencing it.)
00792      */
00793     if (!slot->tts_shouldFreeMin)
00794         slot->tts_mintuple = NULL;
00795 
00796     return slot->tts_tuple;
00797 }
00798 
00799 /* --------------------------------
00800  *      ExecCopySlot
00801  *          Copy the source slot's contents into the destination slot.
00802  *
00803  *      The destination acquires a private copy that will not go away
00804  *      if the source is cleared.
00805  *
00806  *      The caller must ensure the slots have compatible tupdescs.
00807  * --------------------------------
00808  */
00809 TupleTableSlot *
00810 ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
00811 {
00812     HeapTuple   newTuple;
00813     MemoryContext oldContext;
00814 
00815     /*
00816      * There might be ways to optimize this when the source is virtual, but
00817      * for now just always build a physical copy.  Make sure it is in the
00818      * right context.
00819      */
00820     oldContext = MemoryContextSwitchTo(dstslot->tts_mcxt);
00821     newTuple = ExecCopySlotTuple(srcslot);
00822     MemoryContextSwitchTo(oldContext);
00823 
00824     return ExecStoreTuple(newTuple, dstslot, InvalidBuffer, true);
00825 }
00826 
00827 
00828 /* ----------------------------------------------------------------
00829  *              convenience initialization routines
00830  * ----------------------------------------------------------------
00831  */
00832 
00833 /* --------------------------------
00834  *      ExecInit{Result,Scan,Extra}TupleSlot
00835  *
00836  *      These are convenience routines to initialize the specified slot
00837  *      in nodes inheriting the appropriate state.  ExecInitExtraTupleSlot
00838  *      is used for initializing special-purpose slots.
00839  * --------------------------------
00840  */
00841 
00842 /* ----------------
00843  *      ExecInitResultTupleSlot
00844  * ----------------
00845  */
00846 void
00847 ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
00848 {
00849     planstate->ps_ResultTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable);
00850 }
00851 
00852 /* ----------------
00853  *      ExecInitScanTupleSlot
00854  * ----------------
00855  */
00856 void
00857 ExecInitScanTupleSlot(EState *estate, ScanState *scanstate)
00858 {
00859     scanstate->ss_ScanTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable);
00860 }
00861 
00862 /* ----------------
00863  *      ExecInitExtraTupleSlot
00864  * ----------------
00865  */
00866 TupleTableSlot *
00867 ExecInitExtraTupleSlot(EState *estate)
00868 {
00869     return ExecAllocTableSlot(&estate->es_tupleTable);
00870 }
00871 
00872 /* ----------------
00873  *      ExecInitNullTupleSlot
00874  *
00875  * Build a slot containing an all-nulls tuple of the given type.
00876  * This is used as a substitute for an input tuple when performing an
00877  * outer join.
00878  * ----------------
00879  */
00880 TupleTableSlot *
00881 ExecInitNullTupleSlot(EState *estate, TupleDesc tupType)
00882 {
00883     TupleTableSlot *slot = ExecInitExtraTupleSlot(estate);
00884 
00885     ExecSetSlotDescriptor(slot, tupType);
00886 
00887     return ExecStoreAllNullTuple(slot);
00888 }
00889 
00890 /* ----------------------------------------------------------------
00891  *      ExecTypeFromTL
00892  *
00893  *      Generate a tuple descriptor for the result tuple of a targetlist.
00894  *      (A parse/plan tlist must be passed, not an ExprState tlist.)
00895  *      Note that resjunk columns, if any, are included in the result.
00896  *
00897  *      Currently there are about 4 different places where we create
00898  *      TupleDescriptors.  They should all be merged, or perhaps
00899  *      be rewritten to call BuildDesc().
00900  * ----------------------------------------------------------------
00901  */
00902 TupleDesc
00903 ExecTypeFromTL(List *targetList, bool hasoid)
00904 {
00905     return ExecTypeFromTLInternal(targetList, hasoid, false);
00906 }
00907 
00908 /* ----------------------------------------------------------------
00909  *      ExecCleanTypeFromTL
00910  *
00911  *      Same as above, but resjunk columns are omitted from the result.
00912  * ----------------------------------------------------------------
00913  */
00914 TupleDesc
00915 ExecCleanTypeFromTL(List *targetList, bool hasoid)
00916 {
00917     return ExecTypeFromTLInternal(targetList, hasoid, true);
00918 }
00919 
00920 static TupleDesc
00921 ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
00922 {
00923     TupleDesc   typeInfo;
00924     ListCell   *l;
00925     int         len;
00926     int         cur_resno = 1;
00927 
00928     if (skipjunk)
00929         len = ExecCleanTargetListLength(targetList);
00930     else
00931         len = ExecTargetListLength(targetList);
00932     typeInfo = CreateTemplateTupleDesc(len, hasoid);
00933 
00934     foreach(l, targetList)
00935     {
00936         TargetEntry *tle = lfirst(l);
00937 
00938         if (skipjunk && tle->resjunk)
00939             continue;
00940         TupleDescInitEntry(typeInfo,
00941                            cur_resno,
00942                            tle->resname,
00943                            exprType((Node *) tle->expr),
00944                            exprTypmod((Node *) tle->expr),
00945                            0);
00946         TupleDescInitEntryCollation(typeInfo,
00947                                     cur_resno,
00948                                     exprCollation((Node *) tle->expr));
00949         cur_resno++;
00950     }
00951 
00952     return typeInfo;
00953 }
00954 
00955 /*
00956  * ExecTypeFromExprList - build a tuple descriptor from a list of Exprs
00957  *
00958  * Caller must also supply a list of field names (String nodes).
00959  */
00960 TupleDesc
00961 ExecTypeFromExprList(List *exprList, List *namesList)
00962 {
00963     TupleDesc   typeInfo;
00964     ListCell   *le;
00965     ListCell   *ln;
00966     int         cur_resno = 1;
00967 
00968     Assert(list_length(exprList) == list_length(namesList));
00969 
00970     typeInfo = CreateTemplateTupleDesc(list_length(exprList), false);
00971 
00972     forboth(le, exprList, ln, namesList)
00973     {
00974         Node       *e = lfirst(le);
00975         char       *n = strVal(lfirst(ln));
00976 
00977         TupleDescInitEntry(typeInfo,
00978                            cur_resno,
00979                            n,
00980                            exprType(e),
00981                            exprTypmod(e),
00982                            0);
00983         TupleDescInitEntryCollation(typeInfo,
00984                                     cur_resno,
00985                                     exprCollation(e));
00986         cur_resno++;
00987     }
00988 
00989     return typeInfo;
00990 }
00991 
00992 /*
00993  * BlessTupleDesc - make a completed tuple descriptor useful for SRFs
00994  *
00995  * Rowtype Datums returned by a function must contain valid type information.
00996  * This happens "for free" if the tupdesc came from a relcache entry, but
00997  * not if we have manufactured a tupdesc for a transient RECORD datatype.
00998  * In that case we have to notify typcache.c of the existence of the type.
00999  */
01000 TupleDesc
01001 BlessTupleDesc(TupleDesc tupdesc)
01002 {
01003     if (tupdesc->tdtypeid == RECORDOID &&
01004         tupdesc->tdtypmod < 0)
01005         assign_record_type_typmod(tupdesc);
01006 
01007     return tupdesc;             /* just for notational convenience */
01008 }
01009 
01010 /*
01011  * TupleDescGetSlot - Initialize a slot based on the supplied tupledesc
01012  *
01013  * Note: this is obsolete; it is sufficient to call BlessTupleDesc on
01014  * the tupdesc.  We keep it around just for backwards compatibility with
01015  * existing user-written SRFs.
01016  */
01017 TupleTableSlot *
01018 TupleDescGetSlot(TupleDesc tupdesc)
01019 {
01020     TupleTableSlot *slot;
01021 
01022     /* The useful work is here */
01023     BlessTupleDesc(tupdesc);
01024 
01025     /* Make a standalone slot */
01026     slot = MakeSingleTupleTableSlot(tupdesc);
01027 
01028     /* Return the slot */
01029     return slot;
01030 }
01031 
01032 /*
01033  * TupleDescGetAttInMetadata - Build an AttInMetadata structure based on the
01034  * supplied TupleDesc. AttInMetadata can be used in conjunction with C strings
01035  * to produce a properly formed tuple.
01036  */
01037 AttInMetadata *
01038 TupleDescGetAttInMetadata(TupleDesc tupdesc)
01039 {
01040     int         natts = tupdesc->natts;
01041     int         i;
01042     Oid         atttypeid;
01043     Oid         attinfuncid;
01044     FmgrInfo   *attinfuncinfo;
01045     Oid        *attioparams;
01046     int32      *atttypmods;
01047     AttInMetadata *attinmeta;
01048 
01049     attinmeta = (AttInMetadata *) palloc(sizeof(AttInMetadata));
01050 
01051     /* "Bless" the tupledesc so that we can make rowtype datums with it */
01052     attinmeta->tupdesc = BlessTupleDesc(tupdesc);
01053 
01054     /*
01055      * Gather info needed later to call the "in" function for each attribute
01056      */
01057     attinfuncinfo = (FmgrInfo *) palloc0(natts * sizeof(FmgrInfo));
01058     attioparams = (Oid *) palloc0(natts * sizeof(Oid));
01059     atttypmods = (int32 *) palloc0(natts * sizeof(int32));
01060 
01061     for (i = 0; i < natts; i++)
01062     {
01063         /* Ignore dropped attributes */
01064         if (!tupdesc->attrs[i]->attisdropped)
01065         {
01066             atttypeid = tupdesc->attrs[i]->atttypid;
01067             getTypeInputInfo(atttypeid, &attinfuncid, &attioparams[i]);
01068             fmgr_info(attinfuncid, &attinfuncinfo[i]);
01069             atttypmods[i] = tupdesc->attrs[i]->atttypmod;
01070         }
01071     }
01072     attinmeta->attinfuncs = attinfuncinfo;
01073     attinmeta->attioparams = attioparams;
01074     attinmeta->atttypmods = atttypmods;
01075 
01076     return attinmeta;
01077 }
01078 
01079 /*
01080  * BuildTupleFromCStrings - build a HeapTuple given user data in C string form.
01081  * values is an array of C strings, one for each attribute of the return tuple.
01082  * A NULL string pointer indicates we want to create a NULL field.
01083  */
01084 HeapTuple
01085 BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
01086 {
01087     TupleDesc   tupdesc = attinmeta->tupdesc;
01088     int         natts = tupdesc->natts;
01089     Datum      *dvalues;
01090     bool       *nulls;
01091     int         i;
01092     HeapTuple   tuple;
01093 
01094     dvalues = (Datum *) palloc(natts * sizeof(Datum));
01095     nulls = (bool *) palloc(natts * sizeof(bool));
01096 
01097     /* Call the "in" function for each non-dropped attribute */
01098     for (i = 0; i < natts; i++)
01099     {
01100         if (!tupdesc->attrs[i]->attisdropped)
01101         {
01102             /* Non-dropped attributes */
01103             dvalues[i] = InputFunctionCall(&attinmeta->attinfuncs[i],
01104                                            values[i],
01105                                            attinmeta->attioparams[i],
01106                                            attinmeta->atttypmods[i]);
01107             if (values[i] != NULL)
01108                 nulls[i] = false;
01109             else
01110                 nulls[i] = true;
01111         }
01112         else
01113         {
01114             /* Handle dropped attributes by setting to NULL */
01115             dvalues[i] = (Datum) 0;
01116             nulls[i] = true;
01117         }
01118     }
01119 
01120     /*
01121      * Form a tuple
01122      */
01123     tuple = heap_form_tuple(tupdesc, dvalues, nulls);
01124 
01125     /*
01126      * Release locally palloc'd space.  XXX would probably be good to pfree
01127      * values of pass-by-reference datums, as well.
01128      */
01129     pfree(dvalues);
01130     pfree(nulls);
01131 
01132     return tuple;
01133 }
01134 
01135 /*
01136  * Functions for sending tuples to the frontend (or other specified destination)
01137  * as though it is a SELECT result. These are used by utility commands that
01138  * need to project directly to the destination and don't need or want full
01139  * table function capability. Currently used by EXPLAIN and SHOW ALL.
01140  */
01141 TupOutputState *
01142 begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
01143 {
01144     TupOutputState *tstate;
01145 
01146     tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
01147 
01148     tstate->slot = MakeSingleTupleTableSlot(tupdesc);
01149     tstate->dest = dest;
01150 
01151     (*tstate->dest->rStartup) (tstate->dest, (int) CMD_SELECT, tupdesc);
01152 
01153     return tstate;
01154 }
01155 
01156 /*
01157  * write a single tuple
01158  */
01159 void
01160 do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
01161 {
01162     TupleTableSlot *slot = tstate->slot;
01163     int         natts = slot->tts_tupleDescriptor->natts;
01164 
01165     /* make sure the slot is clear */
01166     ExecClearTuple(slot);
01167 
01168     /* insert data */
01169     memcpy(slot->tts_values, values, natts * sizeof(Datum));
01170     memcpy(slot->tts_isnull, isnull, natts * sizeof(bool));
01171 
01172     /* mark slot as containing a virtual tuple */
01173     ExecStoreVirtualTuple(slot);
01174 
01175     /* send the tuple to the receiver */
01176     (*tstate->dest->receiveSlot) (slot, tstate->dest);
01177 
01178     /* clean up */
01179     ExecClearTuple(slot);
01180 }
01181 
01182 /*
01183  * write a chunk of text, breaking at newline characters
01184  *
01185  * Should only be used with a single-TEXT-attribute tupdesc.
01186  */
01187 void
01188 do_text_output_multiline(TupOutputState *tstate, char *text)
01189 {
01190     Datum       values[1];
01191     bool        isnull[1] = {false};
01192 
01193     while (*text)
01194     {
01195         char       *eol;
01196         int         len;
01197 
01198         eol = strchr(text, '\n');
01199         if (eol)
01200         {
01201             len = eol - text;
01202 
01203             eol++;
01204         }
01205         else
01206         {
01207             len = strlen(text);
01208             eol += len;
01209         }
01210 
01211         values[0] = PointerGetDatum(cstring_to_text_with_len(text, len));
01212         do_tup_output(tstate, values, isnull);
01213         pfree(DatumGetPointer(values[0]));
01214         text = eol;
01215     }
01216 }
01217 
01218 void
01219 end_tup_output(TupOutputState *tstate)
01220 {
01221     (*tstate->dest->rShutdown) (tstate->dest);
01222     /* note that destroying the dest is not ours to do */
01223     ExecDropSingleTupleTableSlot(tstate->slot);
01224     pfree(tstate);
01225 }