PostgreSQL Source Code git master
Loading...
Searching...
No Matches
nodeMaterial.c File Reference
#include "postgres.h"
#include "executor/executor.h"
#include "executor/nodeMaterial.h"
#include "miscadmin.h"
#include "utils/tuplestore.h"
Include dependency graph for nodeMaterial.c:

Go to the source code of this file.

Functions

static TupleTableSlotExecMaterial (PlanState *pstate)
 
MaterialStateExecInitMaterial (Material *node, EState *estate, int eflags)
 
void ExecEndMaterial (MaterialState *node)
 
void ExecMaterialMarkPos (MaterialState *node)
 
void ExecMaterialRestrPos (MaterialState *node)
 
void ExecReScanMaterial (MaterialState *node)
 

Function Documentation

◆ ExecEndMaterial()

void ExecEndMaterial ( MaterialState node)

Definition at line 241 of file nodeMaterial.c.

242{
243 /*
244 * Release tuplestore resources
245 */
246 if (node->tuplestorestate != NULL)
248 node->tuplestorestate = NULL;
249
250 /*
251 * shut down the subplan
252 */
254}
void ExecEndNode(PlanState *node)
#define outerPlanState(node)
Definition execnodes.h:1273
static int fb(int x)
Tuplestorestate * tuplestorestate
Definition execnodes.h:2260
void tuplestore_end(Tuplestorestate *state)
Definition tuplestore.c:493

References ExecEndNode(), fb(), outerPlanState, tuplestore_end(), and MaterialState::tuplestorestate.

Referenced by ExecEndNode().

◆ ExecInitMaterial()

MaterialState * ExecInitMaterial ( Material node,
EState estate,
int  eflags 
)

Definition at line 165 of file nodeMaterial.c.

166{
169
170 /*
171 * create state structure
172 */
174 matstate->ss.ps.plan = (Plan *) node;
175 matstate->ss.ps.state = estate;
176 matstate->ss.ps.ExecProcNode = ExecMaterial;
177
178 /*
179 * We must have a tuplestore buffering the subplan output to do backward
180 * scan or mark/restore. We also prefer to materialize the subplan output
181 * if we might be called on to rewind and replay it many times. However,
182 * if none of these cases apply, we can skip storing the data.
183 */
184 matstate->eflags = (eflags & (EXEC_FLAG_REWIND |
187
188 /*
189 * Tuplestore's interpretation of the flag bits is subtly different from
190 * the general executor meaning: it doesn't think BACKWARD necessarily
191 * means "backwards all the way to start". If told to support BACKWARD we
192 * must include REWIND in the tuplestore eflags, else tuplestore_trim
193 * might throw away too much.
194 */
195 if (eflags & EXEC_FLAG_BACKWARD)
196 matstate->eflags |= EXEC_FLAG_REWIND;
197
198 matstate->eof_underlying = false;
199 matstate->tuplestorestate = NULL;
200
201 /*
202 * Miscellaneous initialization
203 *
204 * Materialization nodes don't need ExprContexts because they never call
205 * ExecQual or ExecProject.
206 */
207
208 /*
209 * initialize child nodes
210 *
211 * We shield the child node from the need to support REWIND, BACKWARD, or
212 * MARK/RESTORE.
213 */
215
216 outerPlan = outerPlan(node);
217 outerPlanState(matstate) = ExecInitNode(outerPlan, estate, eflags);
218
219 /*
220 * Initialize result type and slot. No need to initialize projection info
221 * because this node doesn't do projections.
222 *
223 * material nodes only return tuples from their materialized relation.
224 */
226 matstate->ss.ps.ps_ProjInfo = NULL;
227
228 /*
229 * initialize tuple type.
230 */
232
233 return matstate;
234}
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)
const TupleTableSlotOps TTSOpsMinimalTuple
Definition execTuples.c:86
void ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate, const TupleTableSlotOps *tts_ops)
Definition execUtils.c:709
#define EXEC_FLAG_BACKWARD
Definition executor.h:70
#define EXEC_FLAG_REWIND
Definition executor.h:69
#define EXEC_FLAG_MARK
Definition executor.h:71
static TupleTableSlot * ExecMaterial(PlanState *pstate)
#define makeNode(_type_)
Definition nodes.h:161
#define outerPlan(node)
Definition plannodes.h:265

References EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, EXEC_FLAG_REWIND, ExecCreateScanSlotFromOuterPlan(), ExecInitNode(), ExecInitResultTupleSlotTL(), ExecMaterial(), fb(), makeNode, outerPlan, outerPlanState, and TTSOpsMinimalTuple.

Referenced by ExecInitNode().

◆ ExecMaterial()

static TupleTableSlot * ExecMaterial ( PlanState pstate)
static

Definition at line 40 of file nodeMaterial.c.

41{
42 MaterialState *node = castNode(MaterialState, pstate);
43 EState *estate;
44 ScanDirection dir;
45 bool forward;
46 Tuplestorestate *tuplestorestate;
47 bool eof_tuplestore;
48 TupleTableSlot *slot;
49
51
52 /*
53 * get state info from node
54 */
55 estate = node->ss.ps.state;
56 dir = estate->es_direction;
58 tuplestorestate = node->tuplestorestate;
59
60 /*
61 * If first time through, and we need a tuplestore, initialize it.
62 */
63 if (tuplestorestate == NULL && node->eflags != 0)
64 {
65 tuplestorestate = tuplestore_begin_heap(true, false, work_mem);
66 tuplestore_set_eflags(tuplestorestate, node->eflags);
67 if (node->eflags & EXEC_FLAG_MARK)
68 {
69 /*
70 * Allocate a second read pointer to serve as the mark. We know it
71 * must have index 1, so needn't store that.
72 */
74
75 ptrno = tuplestore_alloc_read_pointer(tuplestorestate,
76 node->eflags);
77 Assert(ptrno == 1);
78 }
79 node->tuplestorestate = tuplestorestate;
80 }
81
82 /*
83 * If we are not at the end of the tuplestore, or are going backwards, try
84 * to fetch a tuple from tuplestore.
85 */
86 eof_tuplestore = (tuplestorestate == NULL) ||
87 tuplestore_ateof(tuplestorestate);
88
89 if (!forward && eof_tuplestore)
90 {
91 if (!node->eof_underlying)
92 {
93 /*
94 * When reversing direction at tuplestore EOF, the first
95 * gettupleslot call will fetch the last-added tuple; but we want
96 * to return the one before that, if possible. So do an extra
97 * fetch.
98 */
99 if (!tuplestore_advance(tuplestorestate, forward))
100 return NULL; /* the tuplestore must be empty */
101 }
102 eof_tuplestore = false;
103 }
104
105 /*
106 * If we can fetch another tuple from the tuplestore, return it.
107 */
108 slot = node->ss.ps.ps_ResultTupleSlot;
109 if (!eof_tuplestore)
110 {
111 if (tuplestore_gettupleslot(tuplestorestate, forward, false, slot))
112 return slot;
113 if (forward)
114 eof_tuplestore = true;
115 }
116
117 /*
118 * If necessary, try to fetch another row from the subplan.
119 *
120 * Note: the eof_underlying state variable exists to short-circuit further
121 * subplan calls. It's not optional, unfortunately, because some plan
122 * node types are not robust about being called again when they've already
123 * returned NULL.
124 */
125 if (eof_tuplestore && !node->eof_underlying)
126 {
129
130 /*
131 * We can only get here with forward==true, so no need to worry about
132 * which direction the subplan will go.
133 */
136 if (TupIsNull(outerslot))
137 {
138 node->eof_underlying = true;
139 return NULL;
140 }
141
142 /*
143 * Append a copy of the returned tuple to tuplestore. NOTE: because
144 * the tuplestore is certainly in EOF state, its read position will
145 * move forward over the added tuple. This is what we want.
146 */
147 if (tuplestorestate)
148 tuplestore_puttupleslot(tuplestorestate, outerslot);
149
150 ExecCopySlot(slot, outerslot);
151 return slot;
152 }
153
154 /*
155 * Nothing left ...
156 */
157 return ExecClearTuple(slot);
158}
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:243
#define Assert(condition)
Definition c.h:945
static TupleTableSlot * ExecProcNode(PlanState *node)
Definition executor.h:315
int work_mem
Definition globals.c:131
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123
#define castNode(_type_, nodeptr)
Definition nodes.h:182
#define ScanDirectionIsForward(direction)
Definition sdir.h:64
ScanDirection
Definition sdir.h:25
ScanDirection es_direction
Definition execnodes.h:671
bool eof_underlying
Definition execnodes.h:2259
ScanState ss
Definition execnodes.h:2257
EState * state
Definition execnodes.h:1179
TupleTableSlot * ps_ResultTupleSlot
Definition execnodes.h:1215
PlanState ps
Definition execnodes.h:1633
bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward, bool copy, TupleTableSlot *slot)
void tuplestore_puttupleslot(Tuplestorestate *state, TupleTableSlot *slot)
Definition tuplestore.c:743
int tuplestore_alloc_read_pointer(Tuplestorestate *state, int eflags)
Definition tuplestore.c:396
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition tuplestore.c:331
bool tuplestore_advance(Tuplestorestate *state, bool forward)
bool tuplestore_ateof(Tuplestorestate *state)
Definition tuplestore.c:592
void tuplestore_set_eflags(Tuplestorestate *state, int eflags)
Definition tuplestore.c:372
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition tuptable.h:476
#define TupIsNull(slot)
Definition tuptable.h:325
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
Definition tuptable.h:543

References Assert, castNode, CHECK_FOR_INTERRUPTS, MaterialState::eflags, MaterialState::eof_underlying, EState::es_direction, EXEC_FLAG_MARK, ExecClearTuple(), ExecCopySlot(), ExecProcNode(), fb(), outerPlanState, PG_USED_FOR_ASSERTS_ONLY, ScanState::ps, PlanState::ps_ResultTupleSlot, ScanDirectionIsForward, MaterialState::ss, PlanState::state, TupIsNull, tuplestore_advance(), tuplestore_alloc_read_pointer(), tuplestore_ateof(), tuplestore_begin_heap(), tuplestore_gettupleslot(), tuplestore_puttupleslot(), tuplestore_set_eflags(), MaterialState::tuplestorestate, and work_mem.

Referenced by ExecInitMaterial().

◆ ExecMaterialMarkPos()

void ExecMaterialMarkPos ( MaterialState node)

Definition at line 263 of file nodeMaterial.c.

264{
266
267 /*
268 * if we haven't materialized yet, just return.
269 */
270 if (!node->tuplestorestate)
271 return;
272
273 /*
274 * copy the active read pointer to the mark.
275 */
277
278 /*
279 * since we may have advanced the mark, try to truncate the tuplestore.
280 */
282}
void tuplestore_trim(Tuplestorestate *state)
void tuplestore_copy_read_pointer(Tuplestorestate *state, int srcptr, int destptr)

References Assert, MaterialState::eflags, EXEC_FLAG_MARK, tuplestore_copy_read_pointer(), tuplestore_trim(), and MaterialState::tuplestorestate.

Referenced by ExecMarkPos().

◆ ExecMaterialRestrPos()

void ExecMaterialRestrPos ( MaterialState node)

Definition at line 291 of file nodeMaterial.c.

292{
294
295 /*
296 * if we haven't materialized yet, just return.
297 */
298 if (!node->tuplestorestate)
299 return;
300
301 /*
302 * copy the mark to the active read pointer.
303 */
305}

References Assert, MaterialState::eflags, EXEC_FLAG_MARK, tuplestore_copy_read_pointer(), and MaterialState::tuplestorestate.

Referenced by ExecRestrPos().

◆ ExecReScanMaterial()

void ExecReScanMaterial ( MaterialState node)

Definition at line 314 of file nodeMaterial.c.

315{
317
319
320 if (node->eflags != 0)
321 {
322 /*
323 * If we haven't materialized yet, just return. If outerplan's
324 * chgParam is not NULL then it will be re-scanned by ExecProcNode,
325 * else no reason to re-scan it at all.
326 */
327 if (!node->tuplestorestate)
328 return;
329
330 /*
331 * If subnode is to be rescanned then we forget previous stored
332 * results; we have to re-read the subplan and re-store. Also, if we
333 * told tuplestore it needn't support rescan, we lose and must
334 * re-read. (This last should not happen in common cases; else our
335 * caller lied by not passing EXEC_FLAG_REWIND to us.)
336 *
337 * Otherwise we can just rewind and rescan the stored output. The
338 * state of the subnode does not change.
339 */
340 if (outerPlan->chgParam != NULL ||
341 (node->eflags & EXEC_FLAG_REWIND) == 0)
342 {
344 node->tuplestorestate = NULL;
345 if (outerPlan->chgParam == NULL)
347 node->eof_underlying = false;
348 }
349 else
351 }
352 else
353 {
354 /* In this case we are just passing on the subquery's output */
355
356 /*
357 * if chgParam of subnode is not null then plan will be re-scanned by
358 * first ExecProcNode.
359 */
360 if (outerPlan->chgParam == NULL)
362 node->eof_underlying = false;
363 }
364}
void ExecReScan(PlanState *node)
Definition execAmi.c:78
void tuplestore_rescan(Tuplestorestate *state)

References MaterialState::eflags, MaterialState::eof_underlying, EXEC_FLAG_REWIND, ExecClearTuple(), ExecReScan(), fb(), outerPlan, outerPlanState, ScanState::ps, PlanState::ps_ResultTupleSlot, MaterialState::ss, tuplestore_end(), tuplestore_rescan(), and MaterialState::tuplestorestate.

Referenced by ExecReScan().