PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
nodeMaterial.c File Reference
#include "postgres.h"
#include "executor/executor.h"
#include "executor/nodeMaterial.h"
#include "miscadmin.h"
Include dependency graph for nodeMaterial.c:

Go to the source code of this file.

Functions

TupleTableSlotExecMaterial (MaterialState *node)
 
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

void ExecEndMaterial ( MaterialState node)

Definition at line 240 of file nodeMaterial.c.

References ExecClearTuple(), ExecEndNode(), NULL, outerPlanState, MaterialState::ss, ScanState::ss_ScanTupleSlot, tuplestore_end(), and MaterialState::tuplestorestate.

Referenced by ExecEndNode().

241 {
242  /*
243  * clean out the tuple table
244  */
246 
247  /*
248  * Release tuplestore resources
249  */
250  if (node->tuplestorestate != NULL)
252  node->tuplestorestate = NULL;
253 
254  /*
255  * shut down the subplan
256  */
258 }
Tuplestorestate * tuplestorestate
Definition: execnodes.h:1817
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:624
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
ScanState ss
Definition: execnodes.h:1814
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1291
#define outerPlanState(node)
Definition: execnodes.h:1090
#define NULL
Definition: c.h:226
void tuplestore_end(Tuplestorestate *state)
Definition: tuplestore.c:450
MaterialState* ExecInitMaterial ( Material node,
EState estate,
int  eflags 
)

Definition at line 163 of file nodeMaterial.c.

References MaterialState::eflags, MaterialState::eof_underlying, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, EXEC_FLAG_REWIND, ExecAssignResultTypeFromTL(), ExecAssignScanTypeFromOuterPlan(), ExecInitNode(), ExecInitResultTupleSlot(), ExecInitScanTupleSlot(), makeNode, NULL, outerPlan, outerPlanState, PlanState::plan, ScanState::ps, PlanState::ps_ProjInfo, MaterialState::ss, PlanState::state, and MaterialState::tuplestorestate.

Referenced by ExecInitNode().

164 {
165  MaterialState *matstate;
166  Plan *outerPlan;
167 
168  /*
169  * create state structure
170  */
171  matstate = makeNode(MaterialState);
172  matstate->ss.ps.plan = (Plan *) node;
173  matstate->ss.ps.state = estate;
174 
175  /*
176  * We must have a tuplestore buffering the subplan output to do backward
177  * scan or mark/restore. We also prefer to materialize the subplan output
178  * if we might be called on to rewind and replay it many times. However,
179  * if none of these cases apply, we can skip storing the data.
180  */
181  matstate->eflags = (eflags & (EXEC_FLAG_REWIND |
183  EXEC_FLAG_MARK));
184 
185  /*
186  * Tuplestore's interpretation of the flag bits is subtly different from
187  * the general executor meaning: it doesn't think BACKWARD necessarily
188  * means "backwards all the way to start". If told to support BACKWARD we
189  * must include REWIND in the tuplestore eflags, else tuplestore_trim
190  * might throw away too much.
191  */
192  if (eflags & EXEC_FLAG_BACKWARD)
193  matstate->eflags |= EXEC_FLAG_REWIND;
194 
195  matstate->eof_underlying = false;
196  matstate->tuplestorestate = NULL;
197 
198  /*
199  * Miscellaneous initialization
200  *
201  * Materialization nodes don't need ExprContexts because they never call
202  * ExecQual or ExecProject.
203  */
204 
205  /*
206  * tuple table initialization
207  *
208  * material nodes only return tuples from their materialized relation.
209  */
210  ExecInitResultTupleSlot(estate, &matstate->ss.ps);
211  ExecInitScanTupleSlot(estate, &matstate->ss);
212 
213  /*
214  * initialize child nodes
215  *
216  * We shield the child node from the need to support REWIND, BACKWARD, or
217  * MARK/RESTORE.
218  */
219  eflags &= ~(EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK);
220 
221  outerPlan = outerPlan(node);
222  outerPlanState(matstate) = ExecInitNode(outerPlan, estate, eflags);
223 
224  /*
225  * initialize tuple type. no need to initialize projection info because
226  * this node doesn't do projections.
227  */
228  ExecAssignResultTypeFromTL(&matstate->ss.ps);
230  matstate->ss.ps.ps_ProjInfo = NULL;
231 
232  return matstate;
233 }
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate)
Definition: execTuples.c:842
Tuplestorestate * tuplestorestate
Definition: execnodes.h:1817
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1079
ScanState ss
Definition: execnodes.h:1814
EState * state
Definition: execnodes.h:1049
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:430
PlanState ps
Definition: execnodes.h:1288
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:832
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
#define outerPlanState(node)
Definition: execnodes.h:1090
bool eof_underlying
Definition: execnodes.h:1816
#define EXEC_FLAG_REWIND
Definition: executor.h:59
#define outerPlan(node)
Definition: plannodes.h:159
Plan * plan
Definition: execnodes.h:1047
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
#define EXEC_FLAG_MARK
Definition: executor.h:61
void ExecAssignScanTypeFromOuterPlan(ScanState *scanstate)
Definition: execUtils.c:721
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:137
TupleTableSlot* ExecMaterial ( MaterialState node)

Definition at line 39 of file nodeMaterial.c.

References Assert, MaterialState::eflags, MaterialState::eof_underlying, EState::es_direction, EXEC_FLAG_MARK, ExecClearTuple(), ExecProcNode(), NULL, 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 ExecProcNode().

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

Definition at line 267 of file nodeMaterial.c.

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

Referenced by ExecMarkPos().

268 {
269  Assert(node->eflags & EXEC_FLAG_MARK);
270 
271  /*
272  * if we haven't materialized yet, just return.
273  */
274  if (!node->tuplestorestate)
275  return;
276 
277  /*
278  * copy the active read pointer to the mark.
279  */
281 
282  /*
283  * since we may have advanced the mark, try to truncate the tuplestore.
284  */
286 }
Tuplestorestate * tuplestorestate
Definition: execnodes.h:1817
void tuplestore_trim(Tuplestorestate *state)
Definition: tuplestore.c:1343
void tuplestore_copy_read_pointer(Tuplestorestate *state, int srcptr, int destptr)
Definition: tuplestore.c:1251
#define Assert(condition)
Definition: c.h:671
#define EXEC_FLAG_MARK
Definition: executor.h:61
void ExecMaterialRestrPos ( MaterialState node)

Definition at line 295 of file nodeMaterial.c.

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

Referenced by ExecRestrPos().

296 {
297  Assert(node->eflags & EXEC_FLAG_MARK);
298 
299  /*
300  * if we haven't materialized yet, just return.
301  */
302  if (!node->tuplestorestate)
303  return;
304 
305  /*
306  * copy the mark to the active read pointer.
307  */
309 }
Tuplestorestate * tuplestorestate
Definition: execnodes.h:1817
void tuplestore_copy_read_pointer(Tuplestorestate *state, int srcptr, int destptr)
Definition: tuplestore.c:1251
#define Assert(condition)
Definition: c.h:671
#define EXEC_FLAG_MARK
Definition: executor.h:61
void ExecReScanMaterial ( MaterialState node)

Definition at line 318 of file nodeMaterial.c.

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

Referenced by ExecReScan().

319 {
321 
323 
324  if (node->eflags != 0)
325  {
326  /*
327  * If we haven't materialized yet, just return. If outerplan's
328  * chgParam is not NULL then it will be re-scanned by ExecProcNode,
329  * else no reason to re-scan it at all.
330  */
331  if (!node->tuplestorestate)
332  return;
333 
334  /*
335  * If subnode is to be rescanned then we forget previous stored
336  * results; we have to re-read the subplan and re-store. Also, if we
337  * told tuplestore it needn't support rescan, we lose and must
338  * re-read. (This last should not happen in common cases; else our
339  * caller lied by not passing EXEC_FLAG_REWIND to us.)
340  *
341  * Otherwise we can just rewind and rescan the stored output. The
342  * state of the subnode does not change.
343  */
344  if (outerPlan->chgParam != NULL ||
345  (node->eflags & EXEC_FLAG_REWIND) == 0)
346  {
348  node->tuplestorestate = NULL;
349  if (outerPlan->chgParam == NULL)
350  ExecReScan(outerPlan);
351  node->eof_underlying = false;
352  }
353  else
355  }
356  else
357  {
358  /* In this case we are just passing on the subquery's output */
359 
360  /*
361  * if chgParam of subnode is not null then plan will be re-scanned by
362  * first ExecProcNode.
363  */
364  if (outerPlan->chgParam == NULL)
365  ExecReScan(outerPlan);
366  node->eof_underlying = false;
367  }
368 }
void tuplestore_rescan(Tuplestorestate *state)
Definition: tuplestore.c:1216
Tuplestorestate * tuplestorestate
Definition: execnodes.h:1817
void ExecReScan(PlanState *node)
Definition: execAmi.c:73
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
ScanState ss
Definition: execnodes.h:1814
PlanState ps
Definition: execnodes.h:1288
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1077
#define outerPlanState(node)
Definition: execnodes.h:1090
bool eof_underlying
Definition: execnodes.h:1816
#define EXEC_FLAG_REWIND
Definition: executor.h:59
Bitmapset * chgParam
Definition: execnodes.h:1072
#define outerPlan(node)
Definition: plannodes.h:159
#define NULL
Definition: c.h:226
void tuplestore_end(Tuplestorestate *state)
Definition: tuplestore.c:450