~ubuntu-branches/debian/experimental/postgresql-11/experimental

« back to all changes in this revision

Viewing changes to src/include/executor/tuptable.h

  • Committer: Package Import Robot
  • Author(s): Christoph Berg
  • Date: 2018-05-22 14:19:08 UTC
  • Revision ID: package-import@ubuntu.com-20180522141908-0oy9ujs1b5vrda74
Tags: upstream-11~beta1
ImportĀ upstreamĀ versionĀ 11~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * tuptable.h
 
4
 *        tuple table support stuff
 
5
 *
 
6
 *
 
7
 * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
 
8
 * Portions Copyright (c) 1994, Regents of the University of California
 
9
 *
 
10
 * src/include/executor/tuptable.h
 
11
 *
 
12
 *-------------------------------------------------------------------------
 
13
 */
 
14
#ifndef TUPTABLE_H
 
15
#define TUPTABLE_H
 
16
 
 
17
#include "access/htup.h"
 
18
#include "access/tupdesc.h"
 
19
#include "storage/buf.h"
 
20
 
 
21
/*----------
 
22
 * The executor stores tuples in a "tuple table" which is a List of
 
23
 * independent TupleTableSlots.  There are several cases we need to handle:
 
24
 *              1. physical tuple in a disk buffer page
 
25
 *              2. physical tuple constructed in palloc'ed memory
 
26
 *              3. "minimal" physical tuple constructed in palloc'ed memory
 
27
 *              4. "virtual" tuple consisting of Datum/isnull arrays
 
28
 *
 
29
 * The first two cases are similar in that they both deal with "materialized"
 
30
 * tuples, but resource management is different.  For a tuple in a disk page
 
31
 * we need to hold a pin on the buffer until the TupleTableSlot's reference
 
32
 * to the tuple is dropped; while for a palloc'd tuple we usually want the
 
33
 * tuple pfree'd when the TupleTableSlot's reference is dropped.
 
34
 *
 
35
 * A "minimal" tuple is handled similarly to a palloc'd regular tuple.
 
36
 * At present, minimal tuples never are stored in buffers, so there is no
 
37
 * parallel to case 1.  Note that a minimal tuple has no "system columns".
 
38
 * (Actually, it could have an OID, but we have no need to access the OID.)
 
39
 *
 
40
 * A "virtual" tuple is an optimization used to minimize physical data
 
41
 * copying in a nest of plan nodes.  Any pass-by-reference Datums in the
 
42
 * tuple point to storage that is not directly associated with the
 
43
 * TupleTableSlot; generally they will point to part of a tuple stored in
 
44
 * a lower plan node's output TupleTableSlot, or to a function result
 
45
 * constructed in a plan node's per-tuple econtext.  It is the responsibility
 
46
 * of the generating plan node to be sure these resources are not released
 
47
 * for as long as the virtual tuple needs to be valid.  We only use virtual
 
48
 * tuples in the result slots of plan nodes --- tuples to be copied anywhere
 
49
 * else need to be "materialized" into physical tuples.  Note also that a
 
50
 * virtual tuple does not have any "system columns".
 
51
 *
 
52
 * It is also possible for a TupleTableSlot to hold both physical and minimal
 
53
 * copies of a tuple.  This is done when the slot is requested to provide
 
54
 * the format other than the one it currently holds.  (Originally we attempted
 
55
 * to handle such requests by replacing one format with the other, but that
 
56
 * had the fatal defect of invalidating any pass-by-reference Datums pointing
 
57
 * into the existing slot contents.)  Both copies must contain identical data
 
58
 * payloads when this is the case.
 
59
 *
 
60
 * The Datum/isnull arrays of a TupleTableSlot serve double duty.  When the
 
61
 * slot contains a virtual tuple, they are the authoritative data.  When the
 
62
 * slot contains a physical tuple, the arrays contain data extracted from
 
63
 * the tuple.  (In this state, any pass-by-reference Datums point into
 
64
 * the physical tuple.)  The extracted information is built "lazily",
 
65
 * ie, only as needed.  This serves to avoid repeated extraction of data
 
66
 * from the physical tuple.
 
67
 *
 
68
 * A TupleTableSlot can also be "empty", holding no valid data.  This is
 
69
 * the only valid state for a freshly-created slot that has not yet had a
 
70
 * tuple descriptor assigned to it.  In this state, tts_isempty must be
 
71
 * true, tts_shouldFree false, tts_tuple NULL, tts_buffer InvalidBuffer,
 
72
 * and tts_nvalid zero.
 
73
 *
 
74
 * The tupleDescriptor is simply referenced, not copied, by the TupleTableSlot
 
75
 * code.  The caller of ExecSetSlotDescriptor() is responsible for providing
 
76
 * a descriptor that will live as long as the slot does.  (Typically, both
 
77
 * slots and descriptors are in per-query memory and are freed by memory
 
78
 * context deallocation at query end; so it's not worth providing any extra
 
79
 * mechanism to do more.  However, the slot will increment the tupdesc
 
80
 * reference count if a reference-counted tupdesc is supplied.)
 
81
 *
 
82
 * When tts_shouldFree is true, the physical tuple is "owned" by the slot
 
83
 * and should be freed when the slot's reference to the tuple is dropped.
 
84
 *
 
85
 * If tts_buffer is not InvalidBuffer, then the slot is holding a pin
 
86
 * on the indicated buffer page; drop the pin when we release the
 
87
 * slot's reference to that buffer.  (tts_shouldFree should always be
 
88
 * false in such a case, since presumably tts_tuple is pointing at the
 
89
 * buffer page.)
 
90
 *
 
91
 * tts_nvalid indicates the number of valid columns in the tts_values/isnull
 
92
 * arrays.  When the slot is holding a "virtual" tuple this must be equal
 
93
 * to the descriptor's natts.  When the slot is holding a physical tuple
 
94
 * this is equal to the number of columns we have extracted (we always
 
95
 * extract columns from left to right, so there are no holes).
 
96
 *
 
97
 * tts_values/tts_isnull are allocated when a descriptor is assigned to the
 
98
 * slot; they are of length equal to the descriptor's natts.
 
99
 *
 
100
 * tts_mintuple must always be NULL if the slot does not hold a "minimal"
 
101
 * tuple.  When it does, tts_mintuple points to the actual MinimalTupleData
 
102
 * object (the thing to be pfree'd if tts_shouldFreeMin is true).  If the slot
 
103
 * has only a minimal and not also a regular physical tuple, then tts_tuple
 
104
 * points at tts_minhdr and the fields of that struct are set correctly
 
105
 * for access to the minimal tuple; in particular, tts_minhdr.t_data points
 
106
 * MINIMAL_TUPLE_OFFSET bytes before tts_mintuple.  This allows column
 
107
 * extraction to treat the case identically to regular physical tuples.
 
108
 *
 
109
 * tts_slow/tts_off are saved state for slot_deform_tuple, and should not
 
110
 * be touched by any other code.
 
111
 *----------
 
112
 */
 
113
typedef struct TupleTableSlot
 
114
{
 
115
        NodeTag         type;
 
116
        bool            tts_isempty;    /* true = slot is empty */
 
117
        bool            tts_shouldFree; /* should pfree tts_tuple? */
 
118
        bool            tts_shouldFreeMin;      /* should pfree tts_mintuple? */
 
119
#define FIELDNO_TUPLETABLESLOT_SLOW 4
 
120
        bool            tts_slow;               /* saved state for slot_deform_tuple */
 
121
#define FIELDNO_TUPLETABLESLOT_TUPLE 5
 
122
        HeapTuple       tts_tuple;              /* physical tuple, or NULL if virtual */
 
123
#define FIELDNO_TUPLETABLESLOT_TUPLEDESCRIPTOR 6
 
124
        TupleDesc       tts_tupleDescriptor;    /* slot's tuple descriptor */
 
125
        MemoryContext tts_mcxt;         /* slot itself is in this context */
 
126
        Buffer          tts_buffer;             /* tuple's buffer, or InvalidBuffer */
 
127
#define FIELDNO_TUPLETABLESLOT_NVALID 9
 
128
        int                     tts_nvalid;             /* # of valid values in tts_values */
 
129
#define FIELDNO_TUPLETABLESLOT_VALUES 10
 
130
        Datum      *tts_values;         /* current per-attribute values */
 
131
#define FIELDNO_TUPLETABLESLOT_ISNULL 11
 
132
        bool       *tts_isnull;         /* current per-attribute isnull flags */
 
133
        MinimalTuple tts_mintuple;      /* minimal tuple, or NULL if none */
 
134
        HeapTupleData tts_minhdr;       /* workspace for minimal-tuple-only case */
 
135
#define FIELDNO_TUPLETABLESLOT_OFF 14
 
136
        uint32          tts_off;                /* saved state for slot_deform_tuple */
 
137
        bool            tts_fixedTupleDescriptor;       /* descriptor can't be changed */
 
138
} TupleTableSlot;
 
139
 
 
140
#define TTS_HAS_PHYSICAL_TUPLE(slot)  \
 
141
        ((slot)->tts_tuple != NULL && (slot)->tts_tuple != &((slot)->tts_minhdr))
 
142
 
 
143
/*
 
144
 * TupIsNull -- is a TupleTableSlot empty?
 
145
 */
 
146
#define TupIsNull(slot) \
 
147
        ((slot) == NULL || (slot)->tts_isempty)
 
148
 
 
149
/* in executor/execTuples.c */
 
150
extern TupleTableSlot *MakeTupleTableSlot(TupleDesc desc);
 
151
extern TupleTableSlot *ExecAllocTableSlot(List **tupleTable, TupleDesc desc);
 
152
extern void ExecResetTupleTable(List *tupleTable, bool shouldFree);
 
153
extern TupleTableSlot *MakeSingleTupleTableSlot(TupleDesc tupdesc);
 
154
extern void ExecDropSingleTupleTableSlot(TupleTableSlot *slot);
 
155
extern void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc);
 
156
extern TupleTableSlot *ExecStoreTuple(HeapTuple tuple,
 
157
                           TupleTableSlot *slot,
 
158
                           Buffer buffer,
 
159
                           bool shouldFree);
 
160
extern TupleTableSlot *ExecStoreMinimalTuple(MinimalTuple mtup,
 
161
                                          TupleTableSlot *slot,
 
162
                                          bool shouldFree);
 
163
extern TupleTableSlot *ExecClearTuple(TupleTableSlot *slot);
 
164
extern TupleTableSlot *ExecStoreVirtualTuple(TupleTableSlot *slot);
 
165
extern TupleTableSlot *ExecStoreAllNullTuple(TupleTableSlot *slot);
 
166
extern HeapTuple ExecCopySlotTuple(TupleTableSlot *slot);
 
167
extern MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot);
 
168
extern HeapTuple ExecFetchSlotTuple(TupleTableSlot *slot);
 
169
extern MinimalTuple ExecFetchSlotMinimalTuple(TupleTableSlot *slot);
 
170
extern Datum ExecFetchSlotTupleDatum(TupleTableSlot *slot);
 
171
extern HeapTuple ExecMaterializeSlot(TupleTableSlot *slot);
 
172
extern TupleTableSlot *ExecCopySlot(TupleTableSlot *dstslot,
 
173
                         TupleTableSlot *srcslot);
 
174
 
 
175
/* in access/common/heaptuple.c */
 
176
extern Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull);
 
177
extern void slot_getallattrs(TupleTableSlot *slot);
 
178
extern void slot_getsomeattrs(TupleTableSlot *slot, int attnum);
 
179
extern bool slot_attisnull(TupleTableSlot *slot, int attnum);
 
180
extern bool slot_getsysattr(TupleTableSlot *slot, int attnum,
 
181
                                Datum *value, bool *isnull);
 
182
extern void slot_getmissingattrs(TupleTableSlot *slot, int startAttNum, int lastAttNum);
 
183
 
 
184
#endif                                                  /* TUPTABLE_H */