PostgreSQL Source Code git master
Loading...
Searching...
No Matches
execProcnode.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * execProcnode.c
4 * contains dispatch functions which call the appropriate "initialize",
5 * "get a tuple", and "cleanup" routines for the given node type.
6 * If the node has children, then it will presumably call ExecInitNode,
7 * ExecProcNode, or ExecEndNode on its subnodes and do the appropriate
8 * processing.
9 *
10 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
11 * Portions Copyright (c) 1994, Regents of the University of California
12 *
13 *
14 * IDENTIFICATION
15 * src/backend/executor/execProcnode.c
16 *
17 *-------------------------------------------------------------------------
18 */
19/*
20 * NOTES
21 * This used to be three files. It is now all combined into
22 * one file so that it is easier to keep the dispatch routines
23 * in sync when new nodes are added.
24 *
25 * EXAMPLE
26 * Suppose we want the age of the manager of the shoe department and
27 * the number of employees in that department. So we have the query:
28 *
29 * select DEPT.no_emps, EMP.age
30 * from DEPT, EMP
31 * where EMP.name = DEPT.mgr and
32 * DEPT.name = "shoe"
33 *
34 * Suppose the planner gives us the following plan:
35 *
36 * Nest Loop (DEPT.mgr = EMP.name)
37 * / \
38 * / \
39 * Seq Scan Seq Scan
40 * DEPT EMP
41 * (name = "shoe")
42 *
43 * ExecutorStart() is called first.
44 * It calls InitPlan() which calls ExecInitNode() on
45 * the root of the plan -- the nest loop node.
46 *
47 * * ExecInitNode() notices that it is looking at a nest loop and
48 * as the code below demonstrates, it calls ExecInitNestLoop().
49 * Eventually this calls ExecInitNode() on the right and left subplans
50 * and so forth until the entire plan is initialized. The result
51 * of ExecInitNode() is a plan state tree built with the same structure
52 * as the underlying plan tree.
53 *
54 * * Then when ExecutorRun() is called, it calls ExecutePlan() which calls
55 * ExecProcNode() repeatedly on the top node of the plan state tree.
56 * Each time this happens, ExecProcNode() will end up calling
57 * ExecNestLoop(), which calls ExecProcNode() on its subplans.
58 * Each of these subplans is a sequential scan so ExecSeqScan() is
59 * called. The slots returned by ExecSeqScan() may contain
60 * tuples which contain the attributes ExecNestLoop() uses to
61 * form the tuples it returns.
62 *
63 * * Eventually ExecSeqScan() stops returning tuples and the nest
64 * loop join ends. Lastly, ExecutorEnd() calls ExecEndNode() which
65 * calls ExecEndNestLoop() which in turn calls ExecEndNode() on
66 * its subplans which result in ExecEndSeqScan().
67 *
68 * This should show how the executor works by having
69 * ExecInitNode(), ExecProcNode() and ExecEndNode() dispatch
70 * their work to the appropriate node support routines which may
71 * in turn call these routines themselves on their subplans.
72 */
73#include "postgres.h"
74
75#include "executor/executor.h"
76#include "executor/instrument.h"
77#include "executor/nodeAgg.h"
78#include "executor/nodeAppend.h"
84#include "executor/nodeCustom.h"
87#include "executor/nodeGather.h"
89#include "executor/nodeGroup.h"
90#include "executor/nodeHash.h"
95#include "executor/nodeLimit.h"
106#include "executor/nodeResult.h"
108#include "executor/nodeSeqscan.h"
109#include "executor/nodeSetOp.h"
110#include "executor/nodeSort.h"
111#include "executor/nodeSubplan.h"
115#include "executor/nodeTidscan.h"
116#include "executor/nodeUnique.h"
120#include "miscadmin.h"
121#include "nodes/nodeFuncs.h"
122
125static bool ExecShutdownNode_walker(PlanState *node, void *context);
126
127
128/* ------------------------------------------------------------------------
129 * ExecInitNode
130 *
131 * Recursively initializes all the nodes in the plan tree rooted
132 * at 'node'.
133 *
134 * Inputs:
135 * 'node' is the current node of the plan produced by the query planner
136 * 'estate' is the shared execution state for the plan tree
137 * 'eflags' is a bitwise OR of flag bits described in executor.h
138 *
139 * Returns a PlanState node corresponding to the given Plan node.
140 * ------------------------------------------------------------------------
141 */
142PlanState *
143ExecInitNode(Plan *node, EState *estate, int eflags)
144{
145 PlanState *result;
146 List *subps;
147 ListCell *l;
148
149 /*
150 * do nothing when we get to the end of a leaf on tree.
151 */
152 if (node == NULL)
153 return NULL;
154
155 /*
156 * Make sure there's enough stack available. Need to check here, in
157 * addition to ExecProcNode() (via ExecProcNodeFirst()), to ensure the
158 * stack isn't overrun while initializing the node tree.
159 */
161
162 switch (nodeTag(node))
163 {
164 /*
165 * control nodes
166 */
167 case T_Result:
168 result = (PlanState *) ExecInitResult((Result *) node,
169 estate, eflags);
170 break;
171
172 case T_ProjectSet:
173 result = (PlanState *) ExecInitProjectSet((ProjectSet *) node,
174 estate, eflags);
175 break;
176
177 case T_ModifyTable:
178 result = (PlanState *) ExecInitModifyTable((ModifyTable *) node,
179 estate, eflags);
180 break;
181
182 case T_Append:
183 result = (PlanState *) ExecInitAppend((Append *) node,
184 estate, eflags);
185 break;
186
187 case T_MergeAppend:
188 result = (PlanState *) ExecInitMergeAppend((MergeAppend *) node,
189 estate, eflags);
190 break;
191
192 case T_RecursiveUnion:
193 result = (PlanState *) ExecInitRecursiveUnion((RecursiveUnion *) node,
194 estate, eflags);
195 break;
196
197 case T_BitmapAnd:
198 result = (PlanState *) ExecInitBitmapAnd((BitmapAnd *) node,
199 estate, eflags);
200 break;
201
202 case T_BitmapOr:
203 result = (PlanState *) ExecInitBitmapOr((BitmapOr *) node,
204 estate, eflags);
205 break;
206
207 /*
208 * scan nodes
209 */
210 case T_SeqScan:
211 result = (PlanState *) ExecInitSeqScan((SeqScan *) node,
212 estate, eflags);
213 break;
214
215 case T_SampleScan:
216 result = (PlanState *) ExecInitSampleScan((SampleScan *) node,
217 estate, eflags);
218 break;
219
220 case T_IndexScan:
221 result = (PlanState *) ExecInitIndexScan((IndexScan *) node,
222 estate, eflags);
223 break;
224
225 case T_IndexOnlyScan:
226 result = (PlanState *) ExecInitIndexOnlyScan((IndexOnlyScan *) node,
227 estate, eflags);
228 break;
229
232 estate, eflags);
233 break;
234
235 case T_BitmapHeapScan:
236 result = (PlanState *) ExecInitBitmapHeapScan((BitmapHeapScan *) node,
237 estate, eflags);
238 break;
239
240 case T_TidScan:
241 result = (PlanState *) ExecInitTidScan((TidScan *) node,
242 estate, eflags);
243 break;
244
245 case T_TidRangeScan:
246 result = (PlanState *) ExecInitTidRangeScan((TidRangeScan *) node,
247 estate, eflags);
248 break;
249
250 case T_SubqueryScan:
251 result = (PlanState *) ExecInitSubqueryScan((SubqueryScan *) node,
252 estate, eflags);
253 break;
254
255 case T_FunctionScan:
256 result = (PlanState *) ExecInitFunctionScan((FunctionScan *) node,
257 estate, eflags);
258 break;
259
260 case T_TableFuncScan:
261 result = (PlanState *) ExecInitTableFuncScan((TableFuncScan *) node,
262 estate, eflags);
263 break;
264
265 case T_ValuesScan:
266 result = (PlanState *) ExecInitValuesScan((ValuesScan *) node,
267 estate, eflags);
268 break;
269
270 case T_CteScan:
271 result = (PlanState *) ExecInitCteScan((CteScan *) node,
272 estate, eflags);
273 break;
274
277 estate, eflags);
278 break;
279
280 case T_WorkTableScan:
281 result = (PlanState *) ExecInitWorkTableScan((WorkTableScan *) node,
282 estate, eflags);
283 break;
284
285 case T_ForeignScan:
286 result = (PlanState *) ExecInitForeignScan((ForeignScan *) node,
287 estate, eflags);
288 break;
289
290 case T_CustomScan:
291 result = (PlanState *) ExecInitCustomScan((CustomScan *) node,
292 estate, eflags);
293 break;
294
295 /*
296 * join nodes
297 */
298 case T_NestLoop:
299 result = (PlanState *) ExecInitNestLoop((NestLoop *) node,
300 estate, eflags);
301 break;
302
303 case T_MergeJoin:
304 result = (PlanState *) ExecInitMergeJoin((MergeJoin *) node,
305 estate, eflags);
306 break;
307
308 case T_HashJoin:
309 result = (PlanState *) ExecInitHashJoin((HashJoin *) node,
310 estate, eflags);
311 break;
312
313 /*
314 * materialization nodes
315 */
316 case T_Material:
317 result = (PlanState *) ExecInitMaterial((Material *) node,
318 estate, eflags);
319 break;
320
321 case T_Sort:
322 result = (PlanState *) ExecInitSort((Sort *) node,
323 estate, eflags);
324 break;
325
328 estate, eflags);
329 break;
330
331 case T_Memoize:
332 result = (PlanState *) ExecInitMemoize((Memoize *) node, estate,
333 eflags);
334 break;
335
336 case T_Group:
337 result = (PlanState *) ExecInitGroup((Group *) node,
338 estate, eflags);
339 break;
340
341 case T_Agg:
342 result = (PlanState *) ExecInitAgg((Agg *) node,
343 estate, eflags);
344 break;
345
346 case T_WindowAgg:
347 result = (PlanState *) ExecInitWindowAgg((WindowAgg *) node,
348 estate, eflags);
349 break;
350
351 case T_Unique:
352 result = (PlanState *) ExecInitUnique((Unique *) node,
353 estate, eflags);
354 break;
355
356 case T_Gather:
357 result = (PlanState *) ExecInitGather((Gather *) node,
358 estate, eflags);
359 break;
360
361 case T_GatherMerge:
362 result = (PlanState *) ExecInitGatherMerge((GatherMerge *) node,
363 estate, eflags);
364 break;
365
366 case T_Hash:
367 result = (PlanState *) ExecInitHash((Hash *) node,
368 estate, eflags);
369 break;
370
371 case T_SetOp:
372 result = (PlanState *) ExecInitSetOp((SetOp *) node,
373 estate, eflags);
374 break;
375
376 case T_LockRows:
377 result = (PlanState *) ExecInitLockRows((LockRows *) node,
378 estate, eflags);
379 break;
380
381 case T_Limit:
382 result = (PlanState *) ExecInitLimit((Limit *) node,
383 estate, eflags);
384 break;
385
386 default:
387 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
388 result = NULL; /* keep compiler quiet */
389 break;
390 }
391
392 ExecSetExecProcNode(result, result->ExecProcNode);
393
394 /*
395 * Initialize any initPlans present in this node. The planner put them in
396 * a separate list for us.
397 *
398 * The defining characteristic of initplans is that they don't have
399 * arguments, so we don't need to evaluate them (in contrast to
400 * ExecInitSubPlanExpr()).
401 */
402 subps = NIL;
403 foreach(l, node->initPlan)
404 {
405 SubPlan *subplan = (SubPlan *) lfirst(l);
406 SubPlanState *sstate;
407
408 Assert(IsA(subplan, SubPlan));
409 Assert(subplan->args == NIL);
410 sstate = ExecInitSubPlan(subplan, result);
411 subps = lappend(subps, sstate);
412 }
413 result->initPlan = subps;
414
415 /* Set up instrumentation for this node if requested */
416 if (estate->es_instrument)
417 result->instrument = InstrAlloc(1, estate->es_instrument,
418 result->async_capable);
419
420 return result;
421}
422
423
424/*
425 * If a node wants to change its ExecProcNode function after ExecInitNode()
426 * has finished, it should do so with this function. That way any wrapper
427 * functions can be reinstalled, without the node having to know how that
428 * works.
429 */
430void
432{
433 /*
434 * Add a wrapper around the ExecProcNode callback that checks stack depth
435 * during the first execution and maybe adds an instrumentation wrapper.
436 * When the callback is changed after execution has already begun that
437 * means we'll superfluously execute ExecProcNodeFirst, but that seems ok.
438 */
441}
442
443
444/*
445 * ExecProcNode wrapper that performs some one-time checks, before calling
446 * the relevant node method (possibly via an instrumentation wrapper).
447 */
448static TupleTableSlot *
450{
451 /*
452 * Perform stack depth check during the first execution of the node. We
453 * only do so the first time round because it turns out to not be cheap on
454 * some common architectures (eg. x86). This relies on the assumption
455 * that ExecProcNode calls for a given plan node will always be made at
456 * roughly the same stack depth.
457 */
459
460 /*
461 * If instrumentation is required, change the wrapper to one that just
462 * does instrumentation. Otherwise we can dispense with all wrappers and
463 * have ExecProcNode() directly call the relevant function from now on.
464 */
465 if (node->instrument)
467 else
468 node->ExecProcNode = node->ExecProcNodeReal;
469
470 return node->ExecProcNode(node);
471}
472
473
474/*
475 * ExecProcNode wrapper that performs instrumentation calls. By keeping
476 * this a separate function, we avoid overhead in the normal case where
477 * no instrumentation is wanted.
478 */
479static TupleTableSlot *
481{
482 TupleTableSlot *result;
483
485
486 result = node->ExecProcNodeReal(node);
487
488 InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0);
489
490 return result;
491}
492
493
494/* ----------------------------------------------------------------
495 * MultiExecProcNode
496 *
497 * Execute a node that doesn't return individual tuples
498 * (it might return a hashtable, bitmap, etc). Caller should
499 * check it got back the expected kind of Node.
500 *
501 * This has essentially the same responsibilities as ExecProcNode,
502 * but it does not do InstrStartNode/InstrStopNode (mainly because
503 * it can't tell how many returned tuples to count). Each per-node
504 * function must provide its own instrumentation support.
505 * ----------------------------------------------------------------
506 */
507Node *
509{
510 Node *result;
511
513
515
516 if (node->chgParam != NULL) /* something changed */
517 ExecReScan(node); /* let ReScan handle this */
518
519 switch (nodeTag(node))
520 {
521 /*
522 * Only node types that actually support multiexec will be listed
523 */
524
525 case T_HashState:
526 result = MultiExecHash((HashState *) node);
527 break;
528
531 break;
532
533 case T_BitmapAndState:
534 result = MultiExecBitmapAnd((BitmapAndState *) node);
535 break;
536
537 case T_BitmapOrState:
538 result = MultiExecBitmapOr((BitmapOrState *) node);
539 break;
540
541 default:
542 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
543 result = NULL;
544 break;
545 }
546
547 return result;
548}
549
550
551/* ----------------------------------------------------------------
552 * ExecEndNode
553 *
554 * Recursively cleans up all the nodes in the plan rooted
555 * at 'node'.
556 *
557 * After this operation, the query plan will not be able to be
558 * processed any further. This should be called only after
559 * the query plan has been fully executed.
560 * ----------------------------------------------------------------
561 */
562void
564{
565 /*
566 * do nothing when we get to the end of a leaf on tree.
567 */
568 if (node == NULL)
569 return;
570
571 /*
572 * Make sure there's enough stack available. Need to check here, in
573 * addition to ExecProcNode() (via ExecProcNodeFirst()), because it's not
574 * guaranteed that ExecProcNode() is reached for all nodes.
575 */
577
578 if (node->chgParam != NULL)
579 {
580 bms_free(node->chgParam);
581 node->chgParam = NULL;
582 }
583
584 switch (nodeTag(node))
585 {
586 /*
587 * control nodes
588 */
589 case T_ResultState:
590 ExecEndResult((ResultState *) node);
591 break;
592
595 break;
596
599 break;
600
601 case T_AppendState:
602 ExecEndAppend((AppendState *) node);
603 break;
604
607 break;
608
611 break;
612
613 case T_BitmapAndState:
615 break;
616
617 case T_BitmapOrState:
619 break;
620
621 /*
622 * scan nodes
623 */
624 case T_SeqScanState:
626 break;
627
630 break;
631
632 case T_GatherState:
633 ExecEndGather((GatherState *) node);
634 break;
635
638 break;
639
640 case T_IndexScanState:
642 break;
643
646 break;
647
650 break;
651
654 break;
655
656 case T_TidScanState:
658 break;
659
662 break;
663
666 break;
667
670 break;
671
674 break;
675
676 case T_CteScanState:
678 break;
679
682 break;
683
686 break;
687
688 /*
689 * join nodes
690 */
691 case T_NestLoopState:
693 break;
694
695 case T_MergeJoinState:
697 break;
698
699 case T_HashJoinState:
701 break;
702
703 /*
704 * materialization nodes
705 */
706 case T_MaterialState:
708 break;
709
710 case T_SortState:
711 ExecEndSort((SortState *) node);
712 break;
713
716 break;
717
718 case T_MemoizeState:
720 break;
721
722 case T_GroupState:
723 ExecEndGroup((GroupState *) node);
724 break;
725
726 case T_AggState:
727 ExecEndAgg((AggState *) node);
728 break;
729
730 case T_WindowAggState:
732 break;
733
734 case T_UniqueState:
735 ExecEndUnique((UniqueState *) node);
736 break;
737
738 case T_HashState:
739 ExecEndHash((HashState *) node);
740 break;
741
742 case T_SetOpState:
743 ExecEndSetOp((SetOpState *) node);
744 break;
745
746 case T_LockRowsState:
748 break;
749
750 case T_LimitState:
751 ExecEndLimit((LimitState *) node);
752 break;
753
754 /* No clean up actions for these nodes. */
758 break;
759
760 default:
761 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
762 break;
763 }
764}
765
766/*
767 * ExecShutdownNode
768 *
769 * Give execution nodes a chance to stop asynchronous resource consumption
770 * and release any resources still held.
771 */
772void
777
778static bool
780{
781 if (node == NULL)
782 return false;
783
785
786 /*
787 * Treat the node as running while we shut it down, but only if it's run
788 * at least once already. We don't expect much CPU consumption during
789 * node shutdown, but in the case of Gather or Gather Merge, we may shut
790 * down workers at this stage. If so, their buffer usage will get
791 * propagated into pgBufferUsage at this point, and we want to make sure
792 * that it gets associated with the Gather node. We skip this if the node
793 * has never been executed, so as to avoid incorrectly making it appear
794 * that it has.
795 */
796 if (node->instrument && node->instrument->running)
798
800
801 switch (nodeTag(node))
802 {
803 case T_GatherState:
805 break;
808 break;
811 break;
814 break;
815 case T_HashState:
816 ExecShutdownHash((HashState *) node);
817 break;
818 case T_HashJoinState:
820 break;
821 default:
822 break;
823 }
824
825 /* Stop the node if we started it above, reporting 0 tuples. */
826 if (node->instrument && node->instrument->running)
827 InstrStopNode(node->instrument, 0);
828
829 return false;
830}
831
832/*
833 * ExecSetTupleBound
834 *
835 * Set a tuple bound for a planstate node. This lets child plan nodes
836 * optimize based on the knowledge that the maximum number of tuples that
837 * their parent will demand is limited. The tuple bound for a node may
838 * only be changed between scans (i.e., after node initialization or just
839 * before an ExecReScan call).
840 *
841 * Any negative tuples_needed value means "no limit", which should be the
842 * default assumption when this is not called at all for a particular node.
843 *
844 * Note: if this is called repeatedly on a plan tree, the exact same set
845 * of nodes must be updated with the new limit each time; be careful that
846 * only unchanging conditions are tested here.
847 */
848void
850{
851 /*
852 * Since this function recurses, in principle we should check stack depth
853 * here. In practice, it's probably pointless since the earlier node
854 * initialization tree traversal would surely have consumed more stack.
855 */
856
858 {
859 /*
860 * If it is a Sort node, notify it that it can use bounded sort.
861 *
862 * Note: it is the responsibility of nodeSort.c to react properly to
863 * changes of these parameters. If we ever redesign this, it'd be a
864 * good idea to integrate this signaling with the parameter-change
865 * mechanism.
866 */
868
869 if (tuples_needed < 0)
870 {
871 /* make sure flag gets reset if needed upon rescan */
872 sortState->bounded = false;
873 }
874 else
875 {
876 sortState->bounded = true;
877 sortState->bound = tuples_needed;
878 }
879 }
881 {
882 /*
883 * If it is an IncrementalSort node, notify it that it can use bounded
884 * sort.
885 *
886 * Note: it is the responsibility of nodeIncrementalSort.c to react
887 * properly to changes of these parameters. If we ever redesign this,
888 * it'd be a good idea to integrate this signaling with the
889 * parameter-change mechanism.
890 */
892
893 if (tuples_needed < 0)
894 {
895 /* make sure flag gets reset if needed upon rescan */
896 sortState->bounded = false;
897 }
898 else
899 {
900 sortState->bounded = true;
901 sortState->bound = tuples_needed;
902 }
903 }
904 else if (IsA(child_node, AppendState))
905 {
906 /*
907 * If it is an Append, we can apply the bound to any nodes that are
908 * children of the Append, since the Append surely need read no more
909 * than that many tuples from any one input.
910 */
912 int i;
913
914 for (i = 0; i < aState->as_nplans; i++)
915 ExecSetTupleBound(tuples_needed, aState->appendplans[i]);
916 }
918 {
919 /*
920 * If it is a MergeAppend, we can apply the bound to any nodes that
921 * are children of the MergeAppend, since the MergeAppend surely need
922 * read no more than that many tuples from any one input.
923 */
925 int i;
926
927 for (i = 0; i < maState->ms_nplans; i++)
928 ExecSetTupleBound(tuples_needed, maState->mergeplans[i]);
929 }
930 else if (IsA(child_node, ResultState))
931 {
932 /*
933 * Similarly, for a projecting Result, we can apply the bound to its
934 * child node.
935 *
936 * If Result supported qual checking, we'd have to punt on seeing a
937 * qual. Note that having a resconstantqual is not a showstopper: if
938 * that condition succeeds it affects nothing, while if it fails, no
939 * rows will be demanded from the Result child anyway.
940 */
943 }
945 {
946 /*
947 * We can also descend through SubqueryScan, but only if it has no
948 * qual (otherwise it might discard rows).
949 */
951
952 if (subqueryState->ss.ps.qual == NULL)
953 ExecSetTupleBound(tuples_needed, subqueryState->subplan);
954 }
955 else if (IsA(child_node, GatherState))
956 {
957 /*
958 * A Gather node can propagate the bound to its workers. As with
959 * MergeAppend, no one worker could possibly need to return more
960 * tuples than the Gather itself needs to.
961 *
962 * Note: As with Sort, the Gather node is responsible for reacting
963 * properly to changes to this parameter.
964 */
966
967 gstate->tuples_needed = tuples_needed;
968
969 /* Also pass down the bound to our own copy of the child plan */
971 }
973 {
974 /* Same comments as for Gather */
976
977 gstate->tuples_needed = tuples_needed;
978
980 }
981
982 /*
983 * In principle we could descend through any plan node type that is
984 * certain not to discard or combine input rows; but on seeing a node that
985 * can do that, we can't propagate the bound any further. For the moment
986 * it's unclear that any other cases are worth checking here.
987 */
988}
void bms_free(Bitmapset *a)
Definition bitmapset.c:239
#define Assert(condition)
Definition c.h:945
int64_t int64
Definition c.h:615
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
void ExecReScan(PlanState *node)
Definition execAmi.c:78
static bool ExecShutdownNode_walker(PlanState *node, void *context)
Node * MultiExecProcNode(PlanState *node)
void ExecSetTupleBound(int64 tuples_needed, PlanState *child_node)
void ExecEndNode(PlanState *node)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
void ExecShutdownNode(PlanState *node)
static TupleTableSlot * ExecProcNodeInstr(PlanState *node)
static TupleTableSlot * ExecProcNodeFirst(PlanState *node)
void ExecSetExecProcNode(PlanState *node, ExecProcNodeMtd function)
#define outerPlanState(node)
Definition execnodes.h:1273
TupleTableSlot *(* ExecProcNodeMtd)(PlanState *pstate)
Definition execnodes.h:1162
Instrumentation * InstrAlloc(int n, int instrument_options, bool async_mode)
Definition instrument.c:31
void InstrStartNode(Instrumentation *instr)
Definition instrument.c:68
void InstrStopNode(Instrumentation *instr, double nTuples)
Definition instrument.c:88
int i
Definition isn.c:77
List * lappend(List *list, void *datum)
Definition list.c:339
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123
void ExecEndAgg(AggState *node)
Definition nodeAgg.c:4396
AggState * ExecInitAgg(Agg *node, EState *estate, int eflags)
Definition nodeAgg.c:3281
void ExecEndAppend(AppendState *node)
Definition nodeAppend.c:403
AppendState * ExecInitAppend(Append *node, EState *estate, int eflags)
Definition nodeAppend.c:111
BitmapAndState * ExecInitBitmapAnd(BitmapAnd *node, EState *estate, int eflags)
Node * MultiExecBitmapAnd(BitmapAndState *node)
void ExecEndBitmapAnd(BitmapAndState *node)
void ExecEndBitmapHeapScan(BitmapHeapScanState *node)
BitmapHeapScanState * ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
Node * MultiExecBitmapIndexScan(BitmapIndexScanState *node)
void ExecEndBitmapIndexScan(BitmapIndexScanState *node)
BitmapIndexScanState * ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags)
void ExecEndBitmapOr(BitmapOrState *node)
Node * MultiExecBitmapOr(BitmapOrState *node)
BitmapOrState * ExecInitBitmapOr(BitmapOr *node, EState *estate, int eflags)
CteScanState * ExecInitCteScan(CteScan *node, EState *estate, int eflags)
void ExecEndCteScan(CteScanState *node)
void ExecShutdownCustomScan(CustomScanState *node)
Definition nodeCustom.c:221
void ExecEndCustomScan(CustomScanState *node)
Definition nodeCustom.c:125
CustomScanState * ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
Definition nodeCustom.c:26
ForeignScanState * ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
void ExecShutdownForeignScan(ForeignScanState *node)
void ExecEndForeignScan(ForeignScanState *node)
#define planstate_tree_walker(ps, w, c)
Definition nodeFuncs.h:179
FunctionScanState * ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
void ExecEndFunctionScan(FunctionScanState *node)
void ExecShutdownGatherMerge(GatherMergeState *node)
GatherMergeState * ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags)
void ExecEndGatherMerge(GatherMergeState *node)
void ExecEndGather(GatherState *node)
Definition nodeGather.c:252
void ExecShutdownGather(GatherState *node)
Definition nodeGather.c:419
GatherState * ExecInitGather(Gather *node, EState *estate, int eflags)
Definition nodeGather.c:54
GroupState * ExecInitGroup(Group *node, EState *estate, int eflags)
Definition nodeGroup.c:162
void ExecEndGroup(GroupState *node)
Definition nodeGroup.c:227
Node * MultiExecHash(HashState *node)
Definition nodeHash.c:106
HashState * ExecInitHash(Hash *node, EState *estate, int eflags)
Definition nodeHash.c:399
void ExecEndHash(HashState *node)
Definition nodeHash.c:452
void ExecShutdownHash(HashState *node)
Definition nodeHash.c:2889
void ExecEndHashJoin(HashJoinState *node)
void ExecShutdownHashJoin(HashJoinState *node)
HashJoinState * ExecInitHashJoin(HashJoin *node, EState *estate, int eflags)
void ExecEndIncrementalSort(IncrementalSortState *node)
IncrementalSortState * ExecInitIncrementalSort(IncrementalSort *node, EState *estate, int eflags)
void ExecEndIndexOnlyScan(IndexOnlyScanState *node)
IndexOnlyScanState * ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
IndexScanState * ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
void ExecEndIndexScan(IndexScanState *node)
LimitState * ExecInitLimit(Limit *node, EState *estate, int eflags)
Definition nodeLimit.c:447
void ExecEndLimit(LimitState *node)
Definition nodeLimit.c:534
LockRowsState * ExecInitLockRows(LockRows *node, EState *estate, int eflags)
void ExecEndLockRows(LockRowsState *node)
MaterialState * ExecInitMaterial(Material *node, EState *estate, int eflags)
void ExecEndMaterial(MaterialState *node)
MemoizeState * ExecInitMemoize(Memoize *node, EState *estate, int eflags)
void ExecEndMemoize(MemoizeState *node)
MergeAppendState * ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags)
void ExecEndMergeAppend(MergeAppendState *node)
MergeJoinState * ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags)
void ExecEndMergeJoin(MergeJoinState *node)
ModifyTableState * ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
void ExecEndModifyTable(ModifyTableState *node)
NamedTuplestoreScanState * ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags)
void ExecEndNestLoop(NestLoopState *node)
NestLoopState * ExecInitNestLoop(NestLoop *node, EState *estate, int eflags)
ProjectSetState * ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags)
void ExecEndProjectSet(ProjectSetState *node)
void ExecEndRecursiveUnion(RecursiveUnionState *node)
RecursiveUnionState * ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags)
ResultState * ExecInitResult(Result *node, EState *estate, int eflags)
Definition nodeResult.c:180
void ExecEndResult(ResultState *node)
Definition nodeResult.c:240
SampleScanState * ExecInitSampleScan(SampleScan *node, EState *estate, int eflags)
void ExecEndSampleScan(SampleScanState *node)
void ExecEndSeqScan(SeqScanState *node)
SeqScanState * ExecInitSeqScan(SeqScan *node, EState *estate, int eflags)
void ExecEndSetOp(SetOpState *node)
Definition nodeSetOp.c:692
SetOpState * ExecInitSetOp(SetOp *node, EState *estate, int eflags)
Definition nodeSetOp.c:573
SortState * ExecInitSort(Sort *node, EState *estate, int eflags)
Definition nodeSort.c:221
void ExecEndSort(SortState *node)
Definition nodeSort.c:301
SubPlanState * ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
void ExecEndSubqueryScan(SubqueryScanState *node)
SubqueryScanState * ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
void ExecEndTableFuncScan(TableFuncScanState *node)
TableFuncScanState * ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags)
void ExecEndTidRangeScan(TidRangeScanState *node)
TidRangeScanState * ExecInitTidRangeScan(TidRangeScan *node, EState *estate, int eflags)
TidScanState * ExecInitTidScan(TidScan *node, EState *estate, int eflags)
void ExecEndTidScan(TidScanState *node)
void ExecEndUnique(UniqueState *node)
Definition nodeUnique.c:168
UniqueState * ExecInitUnique(Unique *node, EState *estate, int eflags)
Definition nodeUnique.c:114
ValuesScanState * ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags)
void ExecEndWindowAgg(WindowAggState *node)
WindowAggState * ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
WorkTableScanState * ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags)
#define IsA(nodeptr, _type_)
Definition nodes.h:164
#define nodeTag(nodeptr)
Definition nodes.h:139
on_exit_nicely_callback function
#define lfirst(lc)
Definition pg_list.h:172
#define NIL
Definition pg_list.h:68
static int fb(int x)
void check_stack_depth(void)
Definition stack_depth.c:95
int es_instrument
Definition execnodes.h:732
int64 tuples_needed
Definition execnodes.h:2616
Definition pg_list.h:54
Definition nodes.h:135
Instrumentation * instrument
Definition execnodes.h:1187
ExecProcNodeMtd ExecProcNodeReal
Definition execnodes.h:1184
List * initPlan
Definition execnodes.h:1202
Bitmapset * chgParam
Definition execnodes.h:1209
bool async_capable
Definition execnodes.h:1219
ExecProcNodeMtd ExecProcNode
Definition execnodes.h:1183
List * initPlan
Definition plannodes.h:240
bool bounded
Definition execnodes.h:2330
List * args
Definition primnodes.h:1125
#define TupIsNull(slot)
Definition tuptable.h:325