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

Go to the source code of this file.

Functions

static TupleTableSlotExecAppend (PlanState *pstate)
 
static bool exec_append_initialize_next (AppendState *appendstate)
 
AppendStateExecInitAppend (Append *node, EState *estate, int eflags)
 
void ExecEndAppend (AppendState *node)
 
void ExecReScanAppend (AppendState *node)
 

Function Documentation

static bool exec_append_initialize_next ( AppendState appendstate)
static

Definition at line 77 of file nodeAppend.c.

References AppendState::as_nplans, AppendState::as_whichplan, FALSE, and TRUE.

Referenced by ExecAppend(), ExecInitAppend(), and ExecReScanAppend().

78 {
79  int whichplan;
80 
81  /*
82  * get information from the append node
83  */
84  whichplan = appendstate->as_whichplan;
85 
86  if (whichplan < 0)
87  {
88  /*
89  * if scanning in reverse, we start at the last scan in the list and
90  * then proceed back to the first.. in any case we inform ExecAppend
91  * that we are at the end of the line by returning FALSE
92  */
93  appendstate->as_whichplan = 0;
94  return FALSE;
95  }
96  else if (whichplan >= appendstate->as_nplans)
97  {
98  /*
99  * as above, end the scan if we go beyond the last scan in our list..
100  */
101  appendstate->as_whichplan = appendstate->as_nplans - 1;
102  return FALSE;
103  }
104  else
105  {
106  return TRUE;
107  }
108 }
#define FALSE
Definition: c.h:219
int as_whichplan
Definition: execnodes.h:1006
#define TRUE
Definition: c.h:215
static TupleTableSlot * ExecAppend ( PlanState pstate)
static

Definition at line 203 of file nodeAppend.c.

References AppendState::appendplans, AppendState::as_whichplan, castNode, CHECK_FOR_INTERRUPTS, EState::es_direction, exec_append_initialize_next(), ExecClearTuple(), ExecProcNode(), AppendState::ps, PlanState::ps_ResultTupleSlot, ScanDirectionIsForward, PlanState::state, and TupIsNull.

Referenced by ExecInitAppend().

204 {
205  AppendState *node = castNode(AppendState, pstate);
206 
207  for (;;)
208  {
209  PlanState *subnode;
210  TupleTableSlot *result;
211 
213 
214  /*
215  * figure out which subplan we are currently processing
216  */
217  subnode = node->appendplans[node->as_whichplan];
218 
219  /*
220  * get a tuple from the subplan
221  */
222  result = ExecProcNode(subnode);
223 
224  if (!TupIsNull(result))
225  {
226  /*
227  * If the subplan gave us something then return it as-is. We do
228  * NOT make use of the result slot that was set up in
229  * ExecInitAppend; there's no need for it.
230  */
231  return result;
232  }
233 
234  /*
235  * Go on to the "next" subplan in the appropriate direction. If no
236  * more subplans, return the empty slot set up for us by
237  * ExecInitAppend.
238  */
240  node->as_whichplan++;
241  else
242  node->as_whichplan--;
243  if (!exec_append_initialize_next(node))
244  return ExecClearTuple(node->ps.ps_ResultTupleSlot);
245 
246  /* Else loop back and try to get a tuple from the new subplan */
247  }
248 }
#define ScanDirectionIsForward(direction)
Definition: sdir.h:55
#define castNode(_type_, nodeptr)
Definition: nodes.h:579
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
EState * state
Definition: execnodes.h:849
ScanDirection es_direction
Definition: execnodes.h:428
PlanState ps
Definition: execnodes.h:1003
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:880
#define TupIsNull(slot)
Definition: tuptable.h:138
static TupleTableSlot * ExecProcNode(PlanState *node)
Definition: executor.h:246
int as_whichplan
Definition: execnodes.h:1006
static bool exec_append_initialize_next(AppendState *appendstate)
Definition: nodeAppend.c:77
PlanState ** appendplans
Definition: execnodes.h:1004
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
void ExecEndAppend ( AppendState node)

Definition at line 259 of file nodeAppend.c.

References AppendState::appendplans, AppendState::as_nplans, ExecEndNode(), and i.

Referenced by ExecEndNode().

260 {
261  PlanState **appendplans;
262  int nplans;
263  int i;
264 
265  /*
266  * get information from the node
267  */
268  appendplans = node->appendplans;
269  nplans = node->as_nplans;
270 
271  /*
272  * shut down each of the subscans
273  */
274  for (i = 0; i < nplans; i++)
275  ExecEndNode(appendplans[i]);
276 }
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:523
PlanState ** appendplans
Definition: execnodes.h:1004
int i
AppendState* ExecInitAppend ( Append node,
EState estate,
int  eflags 
)

Definition at line 122 of file nodeAppend.c.

References Append::appendplans, AppendState::appendplans, AppendState::as_nplans, AppendState::as_whichplan, Assert, exec_append_initialize_next(), EXEC_FLAG_MARK, ExecAppend(), ExecAssignResultTypeFromTL(), ExecInitNode(), ExecInitResultTupleSlot(), ExecLockNonLeafAppendTables(), PlanState::ExecProcNode, i, lfirst, list_length(), makeNode, palloc0(), Append::partitioned_rels, PlanState::plan, AppendState::ps, PlanState::ps_ProjInfo, and PlanState::state.

Referenced by ExecInitNode().

123 {
124  AppendState *appendstate = makeNode(AppendState);
125  PlanState **appendplanstates;
126  int nplans;
127  int i;
128  ListCell *lc;
129 
130  /* check for unsupported flags */
131  Assert(!(eflags & EXEC_FLAG_MARK));
132 
133  /*
134  * Lock the non-leaf tables in the partition tree controlled by this node.
135  * It's a no-op for non-partitioned parent tables.
136  */
138 
139  /*
140  * Set up empty vector of subplan states
141  */
142  nplans = list_length(node->appendplans);
143 
144  appendplanstates = (PlanState **) palloc0(nplans * sizeof(PlanState *));
145 
146  /*
147  * create new AppendState for our append node
148  */
149  appendstate->ps.plan = (Plan *) node;
150  appendstate->ps.state = estate;
151  appendstate->ps.ExecProcNode = ExecAppend;
152  appendstate->appendplans = appendplanstates;
153  appendstate->as_nplans = nplans;
154 
155  /*
156  * Miscellaneous initialization
157  *
158  * Append plans don't have expression contexts because they never call
159  * ExecQual or ExecProject.
160  */
161 
162  /*
163  * append nodes still have Result slots, which hold pointers to tuples, so
164  * we have to initialize them.
165  */
166  ExecInitResultTupleSlot(estate, &appendstate->ps);
167 
168  /*
169  * call ExecInitNode on each of the plans to be executed and save the
170  * results into the array "appendplans".
171  */
172  i = 0;
173  foreach(lc, node->appendplans)
174  {
175  Plan *initNode = (Plan *) lfirst(lc);
176 
177  appendplanstates[i] = ExecInitNode(initNode, estate, eflags);
178  i++;
179  }
180 
181  /*
182  * initialize output tuple type
183  */
184  ExecAssignResultTypeFromTL(&appendstate->ps);
185  appendstate->ps.ps_ProjInfo = NULL;
186 
187  /*
188  * initialize to scan first subplan
189  */
190  appendstate->as_whichplan = 0;
191  exec_append_initialize_next(appendstate);
192 
193  return appendstate;
194 }
void ExecLockNonLeafAppendTables(List *partitioned_rels, EState *estate)
Definition: execUtils.c:831
static TupleTableSlot * ExecAppend(PlanState *pstate)
Definition: nodeAppend.c:203
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:882
EState * state
Definition: execnodes.h:849
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:445
PlanState ps
Definition: execnodes.h:1003
List * appendplans
Definition: plannodes.h:250
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:832
List * partitioned_rels
Definition: plannodes.h:249
void * palloc0(Size size)
Definition: mcxt.c:877
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:853
Plan * plan
Definition: execnodes.h:847
#define makeNode(_type_)
Definition: nodes.h:558
#define Assert(condition)
Definition: c.h:681
#define lfirst(lc)
Definition: pg_list.h:106
#define EXEC_FLAG_MARK
Definition: executor.h:61
int as_whichplan
Definition: execnodes.h:1006
static int list_length(const List *l)
Definition: pg_list.h:89
static bool exec_append_initialize_next(AppendState *appendstate)
Definition: nodeAppend.c:77
PlanState ** appendplans
Definition: execnodes.h:1004
int i
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:139
void ExecReScanAppend ( AppendState node)

Definition at line 279 of file nodeAppend.c.

References AppendState::appendplans, AppendState::as_nplans, AppendState::as_whichplan, PlanState::chgParam, exec_append_initialize_next(), ExecReScan(), i, AppendState::ps, and UpdateChangedParamSet().

Referenced by ExecReScan().

280 {
281  int i;
282 
283  for (i = 0; i < node->as_nplans; i++)
284  {
285  PlanState *subnode = node->appendplans[i];
286 
287  /*
288  * ExecReScan doesn't know about my subplans, so I have to do
289  * changed-parameter signaling myself.
290  */
291  if (node->ps.chgParam != NULL)
292  UpdateChangedParamSet(subnode, node->ps.chgParam);
293 
294  /*
295  * If chgParam of subnode is not null then plan will be re-scanned by
296  * first ExecProcNode.
297  */
298  if (subnode->chgParam == NULL)
299  ExecReScan(subnode);
300  }
301  node->as_whichplan = 0;
303 }
void ExecReScan(PlanState *node)
Definition: execAmi.c:76
PlanState ps
Definition: execnodes.h:1003
Bitmapset * chgParam
Definition: execnodes.h:875
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:676
int as_whichplan
Definition: execnodes.h:1006
static bool exec_append_initialize_next(AppendState *appendstate)
Definition: nodeAppend.c:77
PlanState ** appendplans
Definition: execnodes.h:1004
int i