PostgreSQL Source Code  git master
execProcnode.c File Reference
#include "postgres.h"
#include "executor/executor.h"
#include "executor/nodeAgg.h"
#include "executor/nodeAppend.h"
#include "executor/nodeBitmapAnd.h"
#include "executor/nodeBitmapHeapscan.h"
#include "executor/nodeBitmapIndexscan.h"
#include "executor/nodeBitmapOr.h"
#include "executor/nodeCtescan.h"
#include "executor/nodeCustom.h"
#include "executor/nodeForeignscan.h"
#include "executor/nodeFunctionscan.h"
#include "executor/nodeGather.h"
#include "executor/nodeGatherMerge.h"
#include "executor/nodeGroup.h"
#include "executor/nodeHash.h"
#include "executor/nodeHashjoin.h"
#include "executor/nodeIncrementalSort.h"
#include "executor/nodeIndexonlyscan.h"
#include "executor/nodeIndexscan.h"
#include "executor/nodeLimit.h"
#include "executor/nodeLockRows.h"
#include "executor/nodeMaterial.h"
#include "executor/nodeMemoize.h"
#include "executor/nodeMergeAppend.h"
#include "executor/nodeMergejoin.h"
#include "executor/nodeModifyTable.h"
#include "executor/nodeNamedtuplestorescan.h"
#include "executor/nodeNestloop.h"
#include "executor/nodeProjectSet.h"
#include "executor/nodeRecursiveunion.h"
#include "executor/nodeResult.h"
#include "executor/nodeSamplescan.h"
#include "executor/nodeSeqscan.h"
#include "executor/nodeSetOp.h"
#include "executor/nodeSort.h"
#include "executor/nodeSubplan.h"
#include "executor/nodeSubqueryscan.h"
#include "executor/nodeTableFuncscan.h"
#include "executor/nodeTidrangescan.h"
#include "executor/nodeTidscan.h"
#include "executor/nodeUnique.h"
#include "executor/nodeValuesscan.h"
#include "executor/nodeWindowAgg.h"
#include "executor/nodeWorktablescan.h"
#include "miscadmin.h"
#include "nodes/nodeFuncs.h"
Include dependency graph for execProcnode.c:

Go to the source code of this file.

Functions

static TupleTableSlotExecProcNodeFirst (PlanState *node)
 
static TupleTableSlotExecProcNodeInstr (PlanState *node)
 
static bool ExecShutdownNode_walker (PlanState *node, void *context)
 
PlanStateExecInitNode (Plan *node, EState *estate, int eflags)
 
void ExecSetExecProcNode (PlanState *node, ExecProcNodeMtd function)
 
NodeMultiExecProcNode (PlanState *node)
 
void ExecEndNode (PlanState *node)
 
void ExecShutdownNode (PlanState *node)
 
void ExecSetTupleBound (int64 tuples_needed, PlanState *child_node)
 

Function Documentation

◆ ExecEndNode()

void ExecEndNode ( PlanState node)

Definition at line 562 of file execProcnode.c.

563 {
564  /*
565  * do nothing when we get to the end of a leaf on tree.
566  */
567  if (node == NULL)
568  return;
569 
570  /*
571  * Make sure there's enough stack available. Need to check here, in
572  * addition to ExecProcNode() (via ExecProcNodeFirst()), because it's not
573  * guaranteed that ExecProcNode() is reached for all nodes.
574  */
576 
577  if (node->chgParam != NULL)
578  {
579  bms_free(node->chgParam);
580  node->chgParam = NULL;
581  }
582 
583  switch (nodeTag(node))
584  {
585  /*
586  * control nodes
587  */
588  case T_ResultState:
589  ExecEndResult((ResultState *) node);
590  break;
591 
592  case T_ProjectSetState:
594  break;
595 
596  case T_ModifyTableState:
598  break;
599 
600  case T_AppendState:
601  ExecEndAppend((AppendState *) node);
602  break;
603 
604  case T_MergeAppendState:
606  break;
607 
608  case T_RecursiveUnionState:
610  break;
611 
612  case T_BitmapAndState:
614  break;
615 
616  case T_BitmapOrState:
617  ExecEndBitmapOr((BitmapOrState *) node);
618  break;
619 
620  /*
621  * scan nodes
622  */
623  case T_SeqScanState:
624  ExecEndSeqScan((SeqScanState *) node);
625  break;
626 
627  case T_SampleScanState:
629  break;
630 
631  case T_GatherState:
632  ExecEndGather((GatherState *) node);
633  break;
634 
635  case T_GatherMergeState:
637  break;
638 
639  case T_IndexScanState:
641  break;
642 
643  case T_IndexOnlyScanState:
645  break;
646 
647  case T_BitmapIndexScanState:
649  break;
650 
651  case T_BitmapHeapScanState:
653  break;
654 
655  case T_TidScanState:
656  ExecEndTidScan((TidScanState *) node);
657  break;
658 
659  case T_TidRangeScanState:
661  break;
662 
663  case T_SubqueryScanState:
665  break;
666 
667  case T_FunctionScanState:
669  break;
670 
671  case T_TableFuncScanState:
673  break;
674 
675  case T_CteScanState:
676  ExecEndCteScan((CteScanState *) node);
677  break;
678 
679  case T_ForeignScanState:
681  break;
682 
683  case T_CustomScanState:
685  break;
686 
687  /*
688  * join nodes
689  */
690  case T_NestLoopState:
691  ExecEndNestLoop((NestLoopState *) node);
692  break;
693 
694  case T_MergeJoinState:
696  break;
697 
698  case T_HashJoinState:
699  ExecEndHashJoin((HashJoinState *) node);
700  break;
701 
702  /*
703  * materialization nodes
704  */
705  case T_MaterialState:
706  ExecEndMaterial((MaterialState *) node);
707  break;
708 
709  case T_SortState:
710  ExecEndSort((SortState *) node);
711  break;
712 
713  case T_IncrementalSortState:
715  break;
716 
717  case T_MemoizeState:
718  ExecEndMemoize((MemoizeState *) node);
719  break;
720 
721  case T_GroupState:
722  ExecEndGroup((GroupState *) node);
723  break;
724 
725  case T_AggState:
726  ExecEndAgg((AggState *) node);
727  break;
728 
729  case T_WindowAggState:
731  break;
732 
733  case T_UniqueState:
734  ExecEndUnique((UniqueState *) node);
735  break;
736 
737  case T_HashState:
738  ExecEndHash((HashState *) node);
739  break;
740 
741  case T_SetOpState:
742  ExecEndSetOp((SetOpState *) node);
743  break;
744 
745  case T_LockRowsState:
746  ExecEndLockRows((LockRowsState *) node);
747  break;
748 
749  case T_LimitState:
750  ExecEndLimit((LimitState *) node);
751  break;
752 
753  /* No clean up actions for these nodes. */
754  case T_ValuesScanState:
755  case T_NamedTuplestoreScanState:
756  case T_WorkTableScanState:
757  break;
758 
759  default:
760  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
761  break;
762  }
763 }
void bms_free(Bitmapset *a)
Definition: bitmapset.c:239
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
void ExecEndAgg(AggState *node)
Definition: nodeAgg.c:4303
void ExecEndAppend(AppendState *node)
Definition: nodeAppend.c:386
void ExecEndBitmapAnd(BitmapAndState *node)
void ExecEndBitmapHeapScan(BitmapHeapScanState *node)
void ExecEndBitmapIndexScan(BitmapIndexScanState *node)
void ExecEndBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:196
void ExecEndCteScan(CteScanState *node)
Definition: nodeCtescan.c:288
void ExecEndCustomScan(CustomScanState *node)
Definition: nodeCustom.c:125
void ExecEndForeignScan(ForeignScanState *node)
void ExecEndFunctionScan(FunctionScanState *node)
void ExecEndGatherMerge(GatherMergeState *node)
void ExecEndGather(GatherState *node)
Definition: nodeGather.c:251
void ExecEndGroup(GroupState *node)
Definition: nodeGroup.c:226
void ExecEndHash(HashState *node)
Definition: nodeHash.c:427
void ExecEndHashJoin(HashJoinState *node)
Definition: nodeHashjoin.c:948
void ExecEndIncrementalSort(IncrementalSortState *node)
void ExecEndIndexOnlyScan(IndexOnlyScanState *node)
void ExecEndIndexScan(IndexScanState *node)
void ExecEndLimit(LimitState *node)
Definition: nodeLimit.c:534
void ExecEndLockRows(LockRowsState *node)
Definition: nodeLockRows.c:385
void ExecEndMaterial(MaterialState *node)
Definition: nodeMaterial.c:240
void ExecEndMemoize(MemoizeState *node)
Definition: nodeMemoize.c:1079
void ExecEndMergeAppend(MergeAppendState *node)
void ExecEndMergeJoin(MergeJoinState *node)
void ExecEndModifyTable(ModifyTableState *node)
void ExecEndNestLoop(NestLoopState *node)
Definition: nodeNestloop.c:361
void ExecEndProjectSet(ProjectSetState *node)
void ExecEndRecursiveUnion(RecursiveUnionState *node)
void ExecEndResult(ResultState *node)
Definition: nodeResult.c:240
void ExecEndSampleScan(SampleScanState *node)
void ExecEndSeqScan(SeqScanState *node)
Definition: nodeSeqscan.c:184
void ExecEndSetOp(SetOpState *node)
Definition: nodeSetOp.c:583
void ExecEndSort(SortState *node)
Definition: nodeSort.c:301
void ExecEndSubqueryScan(SubqueryScanState *node)
void ExecEndTableFuncScan(TableFuncScanState *node)
void ExecEndTidRangeScan(TidRangeScanState *node)
void ExecEndTidScan(TidScanState *node)
Definition: nodeTidscan.c:470
void ExecEndUnique(UniqueState *node)
Definition: nodeUnique.c:168
void ExecEndWindowAgg(WindowAggState *node)
#define nodeTag(nodeptr)
Definition: nodes.h:133
void check_stack_depth(void)
Definition: postgres.c:3574
Bitmapset * chgParam
Definition: execnodes.h:1159

References bms_free(), check_stack_depth(), PlanState::chgParam, elog, ERROR, ExecEndAgg(), ExecEndAppend(), ExecEndBitmapAnd(), ExecEndBitmapHeapScan(), ExecEndBitmapIndexScan(), ExecEndBitmapOr(), ExecEndCteScan(), ExecEndCustomScan(), ExecEndForeignScan(), ExecEndFunctionScan(), ExecEndGather(), ExecEndGatherMerge(), ExecEndGroup(), ExecEndHash(), ExecEndHashJoin(), ExecEndIncrementalSort(), ExecEndIndexOnlyScan(), ExecEndIndexScan(), ExecEndLimit(), ExecEndLockRows(), ExecEndMaterial(), ExecEndMemoize(), ExecEndMergeAppend(), ExecEndMergeJoin(), ExecEndModifyTable(), ExecEndNestLoop(), ExecEndProjectSet(), ExecEndRecursiveUnion(), ExecEndResult(), ExecEndSampleScan(), ExecEndSeqScan(), ExecEndSetOp(), ExecEndSort(), ExecEndSubqueryScan(), ExecEndTableFuncScan(), ExecEndTidRangeScan(), ExecEndTidScan(), ExecEndUnique(), ExecEndWindowAgg(), and nodeTag.

Referenced by EvalPlanQualEnd(), ExecEndAgg(), ExecEndAppend(), ExecEndBitmapAnd(), ExecEndBitmapHeapScan(), ExecEndBitmapOr(), ExecEndForeignScan(), ExecEndGather(), ExecEndGatherMerge(), ExecEndGroup(), ExecEndHash(), ExecEndHashJoin(), ExecEndIncrementalSort(), ExecEndLimit(), ExecEndLockRows(), ExecEndMaterial(), ExecEndMemoize(), ExecEndMergeAppend(), ExecEndMergeJoin(), ExecEndModifyTable(), ExecEndNestLoop(), ExecEndPlan(), ExecEndProjectSet(), ExecEndRecursiveUnion(), ExecEndResult(), ExecEndSetOp(), ExecEndSort(), ExecEndSubqueryScan(), ExecEndUnique(), and ExecEndWindowAgg().

◆ ExecInitNode()

PlanState* ExecInitNode ( Plan node,
EState estate,
int  eflags 
)

Definition at line 142 of file execProcnode.c.

143 {
144  PlanState *result;
145  List *subps;
146  ListCell *l;
147 
148  /*
149  * do nothing when we get to the end of a leaf on tree.
150  */
151  if (node == NULL)
152  return NULL;
153 
154  /*
155  * Make sure there's enough stack available. Need to check here, in
156  * addition to ExecProcNode() (via ExecProcNodeFirst()), to ensure the
157  * stack isn't overrun while initializing the node tree.
158  */
160 
161  switch (nodeTag(node))
162  {
163  /*
164  * control nodes
165  */
166  case T_Result:
167  result = (PlanState *) ExecInitResult((Result *) node,
168  estate, eflags);
169  break;
170 
171  case T_ProjectSet:
172  result = (PlanState *) ExecInitProjectSet((ProjectSet *) node,
173  estate, eflags);
174  break;
175 
176  case T_ModifyTable:
177  result = (PlanState *) ExecInitModifyTable((ModifyTable *) node,
178  estate, eflags);
179  break;
180 
181  case T_Append:
182  result = (PlanState *) ExecInitAppend((Append *) node,
183  estate, eflags);
184  break;
185 
186  case T_MergeAppend:
187  result = (PlanState *) ExecInitMergeAppend((MergeAppend *) node,
188  estate, eflags);
189  break;
190 
191  case T_RecursiveUnion:
192  result = (PlanState *) ExecInitRecursiveUnion((RecursiveUnion *) node,
193  estate, eflags);
194  break;
195 
196  case T_BitmapAnd:
197  result = (PlanState *) ExecInitBitmapAnd((BitmapAnd *) node,
198  estate, eflags);
199  break;
200 
201  case T_BitmapOr:
202  result = (PlanState *) ExecInitBitmapOr((BitmapOr *) node,
203  estate, eflags);
204  break;
205 
206  /*
207  * scan nodes
208  */
209  case T_SeqScan:
210  result = (PlanState *) ExecInitSeqScan((SeqScan *) node,
211  estate, eflags);
212  break;
213 
214  case T_SampleScan:
215  result = (PlanState *) ExecInitSampleScan((SampleScan *) node,
216  estate, eflags);
217  break;
218 
219  case T_IndexScan:
220  result = (PlanState *) ExecInitIndexScan((IndexScan *) node,
221  estate, eflags);
222  break;
223 
224  case T_IndexOnlyScan:
225  result = (PlanState *) ExecInitIndexOnlyScan((IndexOnlyScan *) node,
226  estate, eflags);
227  break;
228 
229  case T_BitmapIndexScan:
230  result = (PlanState *) ExecInitBitmapIndexScan((BitmapIndexScan *) node,
231  estate, eflags);
232  break;
233 
234  case T_BitmapHeapScan:
235  result = (PlanState *) ExecInitBitmapHeapScan((BitmapHeapScan *) node,
236  estate, eflags);
237  break;
238 
239  case T_TidScan:
240  result = (PlanState *) ExecInitTidScan((TidScan *) node,
241  estate, eflags);
242  break;
243 
244  case T_TidRangeScan:
245  result = (PlanState *) ExecInitTidRangeScan((TidRangeScan *) node,
246  estate, eflags);
247  break;
248 
249  case T_SubqueryScan:
250  result = (PlanState *) ExecInitSubqueryScan((SubqueryScan *) node,
251  estate, eflags);
252  break;
253 
254  case T_FunctionScan:
255  result = (PlanState *) ExecInitFunctionScan((FunctionScan *) node,
256  estate, eflags);
257  break;
258 
259  case T_TableFuncScan:
260  result = (PlanState *) ExecInitTableFuncScan((TableFuncScan *) node,
261  estate, eflags);
262  break;
263 
264  case T_ValuesScan:
265  result = (PlanState *) ExecInitValuesScan((ValuesScan *) node,
266  estate, eflags);
267  break;
268 
269  case T_CteScan:
270  result = (PlanState *) ExecInitCteScan((CteScan *) node,
271  estate, eflags);
272  break;
273 
274  case T_NamedTuplestoreScan:
276  estate, eflags);
277  break;
278 
279  case T_WorkTableScan:
280  result = (PlanState *) ExecInitWorkTableScan((WorkTableScan *) node,
281  estate, eflags);
282  break;
283 
284  case T_ForeignScan:
285  result = (PlanState *) ExecInitForeignScan((ForeignScan *) node,
286  estate, eflags);
287  break;
288 
289  case T_CustomScan:
290  result = (PlanState *) ExecInitCustomScan((CustomScan *) node,
291  estate, eflags);
292  break;
293 
294  /*
295  * join nodes
296  */
297  case T_NestLoop:
298  result = (PlanState *) ExecInitNestLoop((NestLoop *) node,
299  estate, eflags);
300  break;
301 
302  case T_MergeJoin:
303  result = (PlanState *) ExecInitMergeJoin((MergeJoin *) node,
304  estate, eflags);
305  break;
306 
307  case T_HashJoin:
308  result = (PlanState *) ExecInitHashJoin((HashJoin *) node,
309  estate, eflags);
310  break;
311 
312  /*
313  * materialization nodes
314  */
315  case T_Material:
316  result = (PlanState *) ExecInitMaterial((Material *) node,
317  estate, eflags);
318  break;
319 
320  case T_Sort:
321  result = (PlanState *) ExecInitSort((Sort *) node,
322  estate, eflags);
323  break;
324 
325  case T_IncrementalSort:
326  result = (PlanState *) ExecInitIncrementalSort((IncrementalSort *) node,
327  estate, eflags);
328  break;
329 
330  case T_Memoize:
331  result = (PlanState *) ExecInitMemoize((Memoize *) node, estate,
332  eflags);
333  break;
334 
335  case T_Group:
336  result = (PlanState *) ExecInitGroup((Group *) node,
337  estate, eflags);
338  break;
339 
340  case T_Agg:
341  result = (PlanState *) ExecInitAgg((Agg *) node,
342  estate, eflags);
343  break;
344 
345  case T_WindowAgg:
346  result = (PlanState *) ExecInitWindowAgg((WindowAgg *) node,
347  estate, eflags);
348  break;
349 
350  case T_Unique:
351  result = (PlanState *) ExecInitUnique((Unique *) node,
352  estate, eflags);
353  break;
354 
355  case T_Gather:
356  result = (PlanState *) ExecInitGather((Gather *) node,
357  estate, eflags);
358  break;
359 
360  case T_GatherMerge:
361  result = (PlanState *) ExecInitGatherMerge((GatherMerge *) node,
362  estate, eflags);
363  break;
364 
365  case T_Hash:
366  result = (PlanState *) ExecInitHash((Hash *) node,
367  estate, eflags);
368  break;
369 
370  case T_SetOp:
371  result = (PlanState *) ExecInitSetOp((SetOp *) node,
372  estate, eflags);
373  break;
374 
375  case T_LockRows:
376  result = (PlanState *) ExecInitLockRows((LockRows *) node,
377  estate, eflags);
378  break;
379 
380  case T_Limit:
381  result = (PlanState *) ExecInitLimit((Limit *) node,
382  estate, eflags);
383  break;
384 
385  default:
386  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
387  result = NULL; /* keep compiler quiet */
388  break;
389  }
390 
391  ExecSetExecProcNode(result, result->ExecProcNode);
392 
393  /*
394  * Initialize any initPlans present in this node. The planner put them in
395  * a separate list for us.
396  *
397  * The defining characteristic of initplans is that they don't have
398  * arguments, so we don't need to evaluate them (in contrast to
399  * ExecInitSubPlanExpr()).
400  */
401  subps = NIL;
402  foreach(l, node->initPlan)
403  {
404  SubPlan *subplan = (SubPlan *) lfirst(l);
405  SubPlanState *sstate;
406 
407  Assert(IsA(subplan, SubPlan));
408  Assert(subplan->args == NIL);
409  sstate = ExecInitSubPlan(subplan, result);
410  subps = lappend(subps, sstate);
411  }
412  result->initPlan = subps;
413 
414  /* Set up instrumentation for this node if requested */
415  if (estate->es_instrument)
416  result->instrument = InstrAlloc(1, estate->es_instrument,
417  result->async_capable);
418 
419  return result;
420 }
#define Assert(condition)
Definition: c.h:812
void ExecSetExecProcNode(PlanState *node, ExecProcNodeMtd function)
Definition: execProcnode.c:430
Instrumentation * InstrAlloc(int n, int instrument_options, bool async_mode)
Definition: instrument.c:31
List * lappend(List *list, void *datum)
Definition: list.c:339
AggState * ExecInitAgg(Agg *node, EState *estate, int eflags)
Definition: nodeAgg.c:3172
AppendState * ExecInitAppend(Append *node, EState *estate, int eflags)
Definition: nodeAppend.c:109
BitmapAndState * ExecInitBitmapAnd(BitmapAnd *node, EState *estate, int eflags)
Definition: nodeBitmapAnd.c:55
BitmapHeapScanState * ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
BitmapIndexScanState * ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags)
BitmapOrState * ExecInitBitmapOr(BitmapOr *node, EState *estate, int eflags)
Definition: nodeBitmapOr.c:56
CteScanState * ExecInitCteScan(CteScan *node, EState *estate, int eflags)
Definition: nodeCtescan.c:175
CustomScanState * ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
Definition: nodeCustom.c:26
ForeignScanState * ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
FunctionScanState * ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
GatherMergeState * ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags)
GatherState * ExecInitGather(Gather *node, EState *estate, int eflags)
Definition: nodeGather.c:53
GroupState * ExecInitGroup(Group *node, EState *estate, int eflags)
Definition: nodeGroup.c:161
HashState * ExecInitHash(Hash *node, EState *estate, int eflags)
Definition: nodeHash.c:370
HashJoinState * ExecInitHashJoin(HashJoin *node, EState *estate, int eflags)
Definition: nodeHashjoin.c:716
IncrementalSortState * ExecInitIncrementalSort(IncrementalSort *node, EState *estate, int eflags)
IndexOnlyScanState * ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
IndexScanState * ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
LimitState * ExecInitLimit(Limit *node, EState *estate, int eflags)
Definition: nodeLimit.c:447
LockRowsState * ExecInitLockRows(LockRows *node, EState *estate, int eflags)
Definition: nodeLockRows.c:291
MaterialState * ExecInitMaterial(Material *node, EState *estate, int eflags)
Definition: nodeMaterial.c:164
MemoizeState * ExecInitMemoize(Memoize *node, EState *estate, int eflags)
Definition: nodeMemoize.c:951
MergeAppendState * ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags)
MergeJoinState * ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags)
ModifyTableState * ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
NamedTuplestoreScanState * ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags)
NestLoopState * ExecInitNestLoop(NestLoop *node, EState *estate, int eflags)
Definition: nodeNestloop.c:262
ProjectSetState * ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags)
RecursiveUnionState * ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags)
ResultState * ExecInitResult(Result *node, EState *estate, int eflags)
Definition: nodeResult.c:180
SampleScanState * ExecInitSampleScan(SampleScan *node, EState *estate, int eflags)
SeqScanState * ExecInitSeqScan(SeqScan *node, EState *estate, int eflags)
Definition: nodeSeqscan.c:123
SetOpState * ExecInitSetOp(SetOp *node, EState *estate, int eflags)
Definition: nodeSetOp.c:481
SortState * ExecInitSort(Sort *node, EState *estate, int eflags)
Definition: nodeSort.c:221
SubPlanState * ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
Definition: nodeSubplan.c:819
SubqueryScanState * ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
TableFuncScanState * ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags)
TidRangeScanState * ExecInitTidRangeScan(TidRangeScan *node, EState *estate, int eflags)
TidScanState * ExecInitTidScan(TidScan *node, EState *estate, int eflags)
Definition: nodeTidscan.c:488
UniqueState * ExecInitUnique(Unique *node, EState *estate, int eflags)
Definition: nodeUnique.c:114
ValuesScanState * ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags)
WindowAggState * ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
WorkTableScanState * ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags)
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
Definition: plannodes.h:998
Definition: pg_list.h:54
Instrumentation * instrument
Definition: execnodes.h:1137
List * initPlan
Definition: execnodes.h:1152
bool async_capable
Definition: execnodes.h:1169
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:1133
List * initPlan
Definition: plannodes.h:157
List * args
Definition: primnodes.h:1091

References SubPlan::args, Assert, PlanState::async_capable, check_stack_depth(), elog, ERROR, EState::es_instrument, ExecInitAgg(), ExecInitAppend(), ExecInitBitmapAnd(), ExecInitBitmapHeapScan(), ExecInitBitmapIndexScan(), ExecInitBitmapOr(), ExecInitCteScan(), ExecInitCustomScan(), ExecInitForeignScan(), ExecInitFunctionScan(), ExecInitGather(), ExecInitGatherMerge(), ExecInitGroup(), ExecInitHash(), ExecInitHashJoin(), ExecInitIncrementalSort(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), ExecInitLimit(), ExecInitLockRows(), ExecInitMaterial(), ExecInitMemoize(), ExecInitMergeAppend(), ExecInitMergeJoin(), ExecInitModifyTable(), ExecInitNamedTuplestoreScan(), ExecInitNestLoop(), ExecInitProjectSet(), ExecInitRecursiveUnion(), ExecInitResult(), ExecInitSampleScan(), ExecInitSeqScan(), ExecInitSetOp(), ExecInitSort(), ExecInitSubPlan(), ExecInitSubqueryScan(), ExecInitTableFuncScan(), ExecInitTidRangeScan(), ExecInitTidScan(), ExecInitUnique(), ExecInitValuesScan(), ExecInitWindowAgg(), ExecInitWorkTableScan(), PlanState::ExecProcNode, ExecSetExecProcNode(), PlanState::initPlan, Plan::initPlan, InstrAlloc(), PlanState::instrument, IsA, lappend(), lfirst, NIL, and nodeTag.

Referenced by EvalPlanQualStart(), ExecInitAgg(), ExecInitAppend(), ExecInitBitmapAnd(), ExecInitBitmapHeapScan(), ExecInitBitmapOr(), ExecInitForeignScan(), ExecInitGather(), ExecInitGatherMerge(), ExecInitGroup(), ExecInitHash(), ExecInitHashJoin(), ExecInitIncrementalSort(), ExecInitLimit(), ExecInitLockRows(), ExecInitMaterial(), ExecInitMemoize(), ExecInitMergeAppend(), ExecInitMergeJoin(), ExecInitModifyTable(), ExecInitNestLoop(), ExecInitProjectSet(), ExecInitRecursiveUnion(), ExecInitResult(), ExecInitSetOp(), ExecInitSort(), ExecInitSubqueryScan(), ExecInitUnique(), ExecInitWindowAgg(), and InitPlan().

◆ ExecProcNodeFirst()

static TupleTableSlot * ExecProcNodeFirst ( PlanState node)
static

Definition at line 448 of file execProcnode.c.

449 {
450  /*
451  * Perform stack depth check during the first execution of the node. We
452  * only do so the first time round because it turns out to not be cheap on
453  * some common architectures (eg. x86). This relies on the assumption
454  * that ExecProcNode calls for a given plan node will always be made at
455  * roughly the same stack depth.
456  */
458 
459  /*
460  * If instrumentation is required, change the wrapper to one that just
461  * does instrumentation. Otherwise we can dispense with all wrappers and
462  * have ExecProcNode() directly call the relevant function from now on.
463  */
464  if (node->instrument)
466  else
467  node->ExecProcNode = node->ExecProcNodeReal;
468 
469  return node->ExecProcNode(node);
470 }
static TupleTableSlot * ExecProcNodeInstr(PlanState *node)
Definition: execProcnode.c:479
ExecProcNodeMtd ExecProcNodeReal
Definition: execnodes.h:1134

References check_stack_depth(), PlanState::ExecProcNode, ExecProcNodeInstr(), PlanState::ExecProcNodeReal, and PlanState::instrument.

Referenced by ExecSetExecProcNode().

◆ ExecProcNodeInstr()

static TupleTableSlot * ExecProcNodeInstr ( PlanState node)
static

Definition at line 479 of file execProcnode.c.

480 {
481  TupleTableSlot *result;
482 
483  InstrStartNode(node->instrument);
484 
485  result = node->ExecProcNodeReal(node);
486 
487  InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0);
488 
489  return result;
490 }
void InstrStartNode(Instrumentation *instr)
Definition: instrument.c:68
void InstrStopNode(Instrumentation *instr, double nTuples)
Definition: instrument.c:84
#define TupIsNull(slot)
Definition: tuptable.h:306

References PlanState::ExecProcNodeReal, InstrStartNode(), InstrStopNode(), PlanState::instrument, and TupIsNull.

Referenced by ExecProcNodeFirst().

◆ ExecSetExecProcNode()

void ExecSetExecProcNode ( PlanState node,
ExecProcNodeMtd  function 
)

Definition at line 430 of file execProcnode.c.

431 {
432  /*
433  * Add a wrapper around the ExecProcNode callback that checks stack depth
434  * during the first execution and maybe adds an instrumentation wrapper.
435  * When the callback is changed after execution has already begun that
436  * means we'll superfluously execute ExecProcNodeFirst, but that seems ok.
437  */
438  node->ExecProcNodeReal = function;
440 }
static TupleTableSlot * ExecProcNodeFirst(PlanState *node)
Definition: execProcnode.c:448

References PlanState::ExecProcNode, ExecProcNodeFirst(), and PlanState::ExecProcNodeReal.

Referenced by ExecHashJoinInitializeDSM(), ExecHashJoinInitializeWorker(), and ExecInitNode().

◆ ExecSetTupleBound()

void ExecSetTupleBound ( int64  tuples_needed,
PlanState child_node 
)

Definition at line 848 of file execProcnode.c.

849 {
850  /*
851  * Since this function recurses, in principle we should check stack depth
852  * here. In practice, it's probably pointless since the earlier node
853  * initialization tree traversal would surely have consumed more stack.
854  */
855 
856  if (IsA(child_node, SortState))
857  {
858  /*
859  * If it is a Sort node, notify it that it can use bounded sort.
860  *
861  * Note: it is the responsibility of nodeSort.c to react properly to
862  * changes of these parameters. If we ever redesign this, it'd be a
863  * good idea to integrate this signaling with the parameter-change
864  * mechanism.
865  */
866  SortState *sortState = (SortState *) child_node;
867 
868  if (tuples_needed < 0)
869  {
870  /* make sure flag gets reset if needed upon rescan */
871  sortState->bounded = false;
872  }
873  else
874  {
875  sortState->bounded = true;
876  sortState->bound = tuples_needed;
877  }
878  }
879  else if (IsA(child_node, IncrementalSortState))
880  {
881  /*
882  * If it is an IncrementalSort node, notify it that it can use bounded
883  * sort.
884  *
885  * Note: it is the responsibility of nodeIncrementalSort.c to react
886  * properly to changes of these parameters. If we ever redesign this,
887  * it'd be a good idea to integrate this signaling with the
888  * parameter-change mechanism.
889  */
890  IncrementalSortState *sortState = (IncrementalSortState *) child_node;
891 
892  if (tuples_needed < 0)
893  {
894  /* make sure flag gets reset if needed upon rescan */
895  sortState->bounded = false;
896  }
897  else
898  {
899  sortState->bounded = true;
900  sortState->bound = tuples_needed;
901  }
902  }
903  else if (IsA(child_node, AppendState))
904  {
905  /*
906  * If it is an Append, we can apply the bound to any nodes that are
907  * children of the Append, since the Append surely need read no more
908  * than that many tuples from any one input.
909  */
910  AppendState *aState = (AppendState *) child_node;
911  int i;
912 
913  for (i = 0; i < aState->as_nplans; i++)
914  ExecSetTupleBound(tuples_needed, aState->appendplans[i]);
915  }
916  else if (IsA(child_node, MergeAppendState))
917  {
918  /*
919  * If it is a MergeAppend, we can apply the bound to any nodes that
920  * are children of the MergeAppend, since the MergeAppend surely need
921  * read no more than that many tuples from any one input.
922  */
923  MergeAppendState *maState = (MergeAppendState *) child_node;
924  int i;
925 
926  for (i = 0; i < maState->ms_nplans; i++)
927  ExecSetTupleBound(tuples_needed, maState->mergeplans[i]);
928  }
929  else if (IsA(child_node, ResultState))
930  {
931  /*
932  * Similarly, for a projecting Result, we can apply the bound to its
933  * child node.
934  *
935  * If Result supported qual checking, we'd have to punt on seeing a
936  * qual. Note that having a resconstantqual is not a showstopper: if
937  * that condition succeeds it affects nothing, while if it fails, no
938  * rows will be demanded from the Result child anyway.
939  */
940  if (outerPlanState(child_node))
941  ExecSetTupleBound(tuples_needed, outerPlanState(child_node));
942  }
943  else if (IsA(child_node, SubqueryScanState))
944  {
945  /*
946  * We can also descend through SubqueryScan, but only if it has no
947  * qual (otherwise it might discard rows).
948  */
949  SubqueryScanState *subqueryState = (SubqueryScanState *) child_node;
950 
951  if (subqueryState->ss.ps.qual == NULL)
952  ExecSetTupleBound(tuples_needed, subqueryState->subplan);
953  }
954  else if (IsA(child_node, GatherState))
955  {
956  /*
957  * A Gather node can propagate the bound to its workers. As with
958  * MergeAppend, no one worker could possibly need to return more
959  * tuples than the Gather itself needs to.
960  *
961  * Note: As with Sort, the Gather node is responsible for reacting
962  * properly to changes to this parameter.
963  */
964  GatherState *gstate = (GatherState *) child_node;
965 
966  gstate->tuples_needed = tuples_needed;
967 
968  /* Also pass down the bound to our own copy of the child plan */
969  ExecSetTupleBound(tuples_needed, outerPlanState(child_node));
970  }
971  else if (IsA(child_node, GatherMergeState))
972  {
973  /* Same comments as for Gather */
974  GatherMergeState *gstate = (GatherMergeState *) child_node;
975 
976  gstate->tuples_needed = tuples_needed;
977 
978  ExecSetTupleBound(tuples_needed, outerPlanState(child_node));
979  }
980 
981  /*
982  * In principle we could descend through any plan node type that is
983  * certain not to discard or combine input rows; but on seeing a node that
984  * can do that, we can't propagate the bound any further. For the moment
985  * it's unclear that any other cases are worth checking here.
986  */
987 }
void ExecSetTupleBound(int64 tuples_needed, PlanState *child_node)
Definition: execProcnode.c:848
#define outerPlanState(node)
Definition: execnodes.h:1223
int i
Definition: isn.c:72
PlanState ** appendplans
Definition: execnodes.h:1450
int64 tuples_needed
Definition: execnodes.h:2708
PlanState ** mergeplans
Definition: execnodes.h:1494
ExprState * qual
Definition: execnodes.h:1148
PlanState ps
Definition: execnodes.h:1574
bool bounded
Definition: execnodes.h:2368
int64 bound
Definition: execnodes.h:2369
PlanState * subplan
Definition: execnodes.h:1918

References AppendState::appendplans, AppendState::as_nplans, SortState::bound, IncrementalSortState::bound, SortState::bounded, IncrementalSortState::bounded, i, IsA, MergeAppendState::mergeplans, MergeAppendState::ms_nplans, outerPlanState, ScanState::ps, PlanState::qual, SubqueryScanState::ss, SubqueryScanState::subplan, GatherState::tuples_needed, and GatherMergeState::tuples_needed.

Referenced by ParallelQueryMain(), and recompute_limits().

◆ ExecShutdownNode()

void ExecShutdownNode ( PlanState node)

Definition at line 772 of file execProcnode.c.

773 {
774  (void) ExecShutdownNode_walker(node, NULL);
775 }
static bool ExecShutdownNode_walker(PlanState *node, void *context)
Definition: execProcnode.c:778

References ExecShutdownNode_walker().

Referenced by ExecutePlan().

◆ ExecShutdownNode_walker()

static bool ExecShutdownNode_walker ( PlanState node,
void *  context 
)
static

Definition at line 778 of file execProcnode.c.

779 {
780  if (node == NULL)
781  return false;
782 
784 
785  /*
786  * Treat the node as running while we shut it down, but only if it's run
787  * at least once already. We don't expect much CPU consumption during
788  * node shutdown, but in the case of Gather or Gather Merge, we may shut
789  * down workers at this stage. If so, their buffer usage will get
790  * propagated into pgBufferUsage at this point, and we want to make sure
791  * that it gets associated with the Gather node. We skip this if the node
792  * has never been executed, so as to avoid incorrectly making it appear
793  * that it has.
794  */
795  if (node->instrument && node->instrument->running)
796  InstrStartNode(node->instrument);
797 
799 
800  switch (nodeTag(node))
801  {
802  case T_GatherState:
804  break;
805  case T_ForeignScanState:
807  break;
808  case T_CustomScanState:
810  break;
811  case T_GatherMergeState:
813  break;
814  case T_HashState:
815  ExecShutdownHash((HashState *) node);
816  break;
817  case T_HashJoinState:
819  break;
820  default:
821  break;
822  }
823 
824  /* Stop the node if we started it above, reporting 0 tuples. */
825  if (node->instrument && node->instrument->running)
826  InstrStopNode(node->instrument, 0);
827 
828  return false;
829 }
void ExecShutdownCustomScan(CustomScanState *node)
Definition: nodeCustom.c:221
void ExecShutdownForeignScan(ForeignScanState *node)
#define planstate_tree_walker(ps, w, c)
Definition: nodeFuncs.h:179
void ExecShutdownGatherMerge(GatherMergeState *node)
void ExecShutdownGather(GatherState *node)
Definition: nodeGather.c:418
void ExecShutdownHash(HashState *node)
Definition: nodeHash.c:2696
void ExecShutdownHashJoin(HashJoinState *node)
tree context
Definition: radixtree.h:1835

References check_stack_depth(), context, ExecShutdownCustomScan(), ExecShutdownForeignScan(), ExecShutdownGather(), ExecShutdownGatherMerge(), ExecShutdownHash(), ExecShutdownHashJoin(), InstrStartNode(), InstrStopNode(), PlanState::instrument, nodeTag, planstate_tree_walker, and Instrumentation::running.

Referenced by ExecShutdownNode().

◆ MultiExecProcNode()

Node* MultiExecProcNode ( PlanState node)

Definition at line 507 of file execProcnode.c.

508 {
509  Node *result;
510 
512 
514 
515  if (node->chgParam != NULL) /* something changed */
516  ExecReScan(node); /* let ReScan handle this */
517 
518  switch (nodeTag(node))
519  {
520  /*
521  * Only node types that actually support multiexec will be listed
522  */
523 
524  case T_HashState:
525  result = MultiExecHash((HashState *) node);
526  break;
527 
528  case T_BitmapIndexScanState:
530  break;
531 
532  case T_BitmapAndState:
533  result = MultiExecBitmapAnd((BitmapAndState *) node);
534  break;
535 
536  case T_BitmapOrState:
537  result = MultiExecBitmapOr((BitmapOrState *) node);
538  break;
539 
540  default:
541  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
542  result = NULL;
543  break;
544  }
545 
546  return result;
547 }
void ExecReScan(PlanState *node)
Definition: execAmi.c:76
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
Node * MultiExecBitmapAnd(BitmapAndState *node)
Node * MultiExecBitmapIndexScan(BitmapIndexScanState *node)
Node * MultiExecBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:111
Node * MultiExecHash(HashState *node)
Definition: nodeHash.c:105
Definition: nodes.h:129

References CHECK_FOR_INTERRUPTS, check_stack_depth(), PlanState::chgParam, elog, ERROR, ExecReScan(), MultiExecBitmapAnd(), MultiExecBitmapIndexScan(), MultiExecBitmapOr(), MultiExecHash(), and nodeTag.

Referenced by BitmapHeapNext(), ExecHashJoinImpl(), MultiExecBitmapAnd(), and MultiExecBitmapOr().