Header And Logo

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

tuptable.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * tuptable.h
00004  *    tuple table support stuff
00005  *
00006  *
00007  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00008  * Portions Copyright (c) 1994, Regents of the University of California
00009  *
00010  * src/include/executor/tuptable.h
00011  *
00012  *-------------------------------------------------------------------------
00013  */
00014 #ifndef TUPTABLE_H
00015 #define TUPTABLE_H
00016 
00017 #include "access/htup.h"
00018 #include "access/tupdesc.h"
00019 #include "storage/buf.h"
00020 
00021 /*----------
00022  * The executor stores tuples in a "tuple table" which is a List of
00023  * independent TupleTableSlots.  There are several cases we need to handle:
00024  *      1. physical tuple in a disk buffer page
00025  *      2. physical tuple constructed in palloc'ed memory
00026  *      3. "minimal" physical tuple constructed in palloc'ed memory
00027  *      4. "virtual" tuple consisting of Datum/isnull arrays
00028  *
00029  * The first two cases are similar in that they both deal with "materialized"
00030  * tuples, but resource management is different.  For a tuple in a disk page
00031  * we need to hold a pin on the buffer until the TupleTableSlot's reference
00032  * to the tuple is dropped; while for a palloc'd tuple we usually want the
00033  * tuple pfree'd when the TupleTableSlot's reference is dropped.
00034  *
00035  * A "minimal" tuple is handled similarly to a palloc'd regular tuple.
00036  * At present, minimal tuples never are stored in buffers, so there is no
00037  * parallel to case 1.  Note that a minimal tuple has no "system columns".
00038  * (Actually, it could have an OID, but we have no need to access the OID.)
00039  *
00040  * A "virtual" tuple is an optimization used to minimize physical data
00041  * copying in a nest of plan nodes.  Any pass-by-reference Datums in the
00042  * tuple point to storage that is not directly associated with the
00043  * TupleTableSlot; generally they will point to part of a tuple stored in
00044  * a lower plan node's output TupleTableSlot, or to a function result
00045  * constructed in a plan node's per-tuple econtext.  It is the responsibility
00046  * of the generating plan node to be sure these resources are not released
00047  * for as long as the virtual tuple needs to be valid.  We only use virtual
00048  * tuples in the result slots of plan nodes --- tuples to be copied anywhere
00049  * else need to be "materialized" into physical tuples.  Note also that a
00050  * virtual tuple does not have any "system columns".
00051  *
00052  * It is also possible for a TupleTableSlot to hold both physical and minimal
00053  * copies of a tuple.  This is done when the slot is requested to provide
00054  * the format other than the one it currently holds.  (Originally we attempted
00055  * to handle such requests by replacing one format with the other, but that
00056  * had the fatal defect of invalidating any pass-by-reference Datums pointing
00057  * into the existing slot contents.)  Both copies must contain identical data
00058  * payloads when this is the case.
00059  *
00060  * The Datum/isnull arrays of a TupleTableSlot serve double duty.  When the
00061  * slot contains a virtual tuple, they are the authoritative data.  When the
00062  * slot contains a physical tuple, the arrays contain data extracted from
00063  * the tuple.  (In this state, any pass-by-reference Datums point into
00064  * the physical tuple.)  The extracted information is built "lazily",
00065  * ie, only as needed.  This serves to avoid repeated extraction of data
00066  * from the physical tuple.
00067  *
00068  * A TupleTableSlot can also be "empty", holding no valid data.  This is
00069  * the only valid state for a freshly-created slot that has not yet had a
00070  * tuple descriptor assigned to it.  In this state, tts_isempty must be
00071  * TRUE, tts_shouldFree FALSE, tts_tuple NULL, tts_buffer InvalidBuffer,
00072  * and tts_nvalid zero.
00073  *
00074  * The tupleDescriptor is simply referenced, not copied, by the TupleTableSlot
00075  * code.  The caller of ExecSetSlotDescriptor() is responsible for providing
00076  * a descriptor that will live as long as the slot does.  (Typically, both
00077  * slots and descriptors are in per-query memory and are freed by memory
00078  * context deallocation at query end; so it's not worth providing any extra
00079  * mechanism to do more.  However, the slot will increment the tupdesc
00080  * reference count if a reference-counted tupdesc is supplied.)
00081  *
00082  * When tts_shouldFree is true, the physical tuple is "owned" by the slot
00083  * and should be freed when the slot's reference to the tuple is dropped.
00084  *
00085  * If tts_buffer is not InvalidBuffer, then the slot is holding a pin
00086  * on the indicated buffer page; drop the pin when we release the
00087  * slot's reference to that buffer.  (tts_shouldFree should always be
00088  * false in such a case, since presumably tts_tuple is pointing at the
00089  * buffer page.)
00090  *
00091  * tts_nvalid indicates the number of valid columns in the tts_values/isnull
00092  * arrays.  When the slot is holding a "virtual" tuple this must be equal
00093  * to the descriptor's natts.  When the slot is holding a physical tuple
00094  * this is equal to the number of columns we have extracted (we always
00095  * extract columns from left to right, so there are no holes).
00096  *
00097  * tts_values/tts_isnull are allocated when a descriptor is assigned to the
00098  * slot; they are of length equal to the descriptor's natts.
00099  *
00100  * tts_mintuple must always be NULL if the slot does not hold a "minimal"
00101  * tuple.  When it does, tts_mintuple points to the actual MinimalTupleData
00102  * object (the thing to be pfree'd if tts_shouldFreeMin is true).  If the slot
00103  * has only a minimal and not also a regular physical tuple, then tts_tuple
00104  * points at tts_minhdr and the fields of that struct are set correctly
00105  * for access to the minimal tuple; in particular, tts_minhdr.t_data points
00106  * MINIMAL_TUPLE_OFFSET bytes before tts_mintuple.  This allows column
00107  * extraction to treat the case identically to regular physical tuples.
00108  *
00109  * tts_slow/tts_off are saved state for slot_deform_tuple, and should not
00110  * be touched by any other code.
00111  *----------
00112  */
00113 typedef struct TupleTableSlot
00114 {
00115     NodeTag     type;
00116     bool        tts_isempty;    /* true = slot is empty */
00117     bool        tts_shouldFree; /* should pfree tts_tuple? */
00118     bool        tts_shouldFreeMin;      /* should pfree tts_mintuple? */
00119     bool        tts_slow;       /* saved state for slot_deform_tuple */
00120     HeapTuple   tts_tuple;      /* physical tuple, or NULL if virtual */
00121     TupleDesc   tts_tupleDescriptor;    /* slot's tuple descriptor */
00122     MemoryContext tts_mcxt;     /* slot itself is in this context */
00123     Buffer      tts_buffer;     /* tuple's buffer, or InvalidBuffer */
00124     int         tts_nvalid;     /* # of valid values in tts_values */
00125     Datum      *tts_values;     /* current per-attribute values */
00126     bool       *tts_isnull;     /* current per-attribute isnull flags */
00127     MinimalTuple tts_mintuple;  /* minimal tuple, or NULL if none */
00128     HeapTupleData tts_minhdr;   /* workspace for minimal-tuple-only case */
00129     long        tts_off;        /* saved state for slot_deform_tuple */
00130 } TupleTableSlot;
00131 
00132 #define TTS_HAS_PHYSICAL_TUPLE(slot)  \
00133     ((slot)->tts_tuple != NULL && (slot)->tts_tuple != &((slot)->tts_minhdr))
00134 
00135 /*
00136  * TupIsNull -- is a TupleTableSlot empty?
00137  */
00138 #define TupIsNull(slot) \
00139     ((slot) == NULL || (slot)->tts_isempty)
00140 
00141 /* in executor/execTuples.c */
00142 extern TupleTableSlot *MakeTupleTableSlot(void);
00143 extern TupleTableSlot *ExecAllocTableSlot(List **tupleTable);
00144 extern void ExecResetTupleTable(List *tupleTable, bool shouldFree);
00145 extern TupleTableSlot *MakeSingleTupleTableSlot(TupleDesc tupdesc);
00146 extern void ExecDropSingleTupleTableSlot(TupleTableSlot *slot);
00147 extern void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc);
00148 extern TupleTableSlot *ExecStoreTuple(HeapTuple tuple,
00149                TupleTableSlot *slot,
00150                Buffer buffer,
00151                bool shouldFree);
00152 extern TupleTableSlot *ExecStoreMinimalTuple(MinimalTuple mtup,
00153                       TupleTableSlot *slot,
00154                       bool shouldFree);
00155 extern TupleTableSlot *ExecClearTuple(TupleTableSlot *slot);
00156 extern TupleTableSlot *ExecStoreVirtualTuple(TupleTableSlot *slot);
00157 extern TupleTableSlot *ExecStoreAllNullTuple(TupleTableSlot *slot);
00158 extern HeapTuple ExecCopySlotTuple(TupleTableSlot *slot);
00159 extern MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot);
00160 extern HeapTuple ExecFetchSlotTuple(TupleTableSlot *slot);
00161 extern MinimalTuple ExecFetchSlotMinimalTuple(TupleTableSlot *slot);
00162 extern Datum ExecFetchSlotTupleDatum(TupleTableSlot *slot);
00163 extern HeapTuple ExecMaterializeSlot(TupleTableSlot *slot);
00164 extern TupleTableSlot *ExecCopySlot(TupleTableSlot *dstslot,
00165              TupleTableSlot *srcslot);
00166 
00167 /* in access/common/heaptuple.c */
00168 extern Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull);
00169 extern void slot_getallattrs(TupleTableSlot *slot);
00170 extern void slot_getsomeattrs(TupleTableSlot *slot, int attnum);
00171 extern bool slot_attisnull(TupleTableSlot *slot, int attnum);
00172 
00173 #endif   /* TUPTABLE_H */