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-2021, 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/nodeAgg.h"
77 #include "executor/nodeAppend.h"
78 #include "executor/nodeBitmapAnd.h"
79 #include "executor/nodeBitmapHeapscan.h"
80 #include "executor/nodeBitmapIndexscan.h"
81 #include "executor/nodeBitmapOr.h"
82 #include "executor/nodeCtescan.h"
83 #include "executor/nodeCustom.h"
84 #include "executor/nodeForeignscan.h"
85 #include "executor/nodeFunctionscan.h"
86 #include "executor/nodeGather.h"
87 #include "executor/nodeGatherMerge.h"
88 #include "executor/nodeGroup.h"
89 #include "executor/nodeHash.h"
90 #include "executor/nodeHashjoin.h"
91 #include "executor/nodeIncrementalSort.h"
92 #include "executor/nodeIndexonlyscan.h"
93 #include "executor/nodeIndexscan.h"
94 #include "executor/nodeLimit.h"
95 #include "executor/nodeLockRows.h"
96 #include "executor/nodeMaterial.h"
97 #include "executor/nodeMemoize.h"
98 #include "executor/nodeMergeAppend.h"
99 #include "executor/nodeMergejoin.h"
100 #include "executor/nodeModifyTable.h"
101 #include "executor/nodeNamedtuplestorescan.h"
102 #include "executor/nodeNestloop.h"
103 #include "executor/nodeProjectSet.h"
104 #include "executor/nodeRecursiveunion.h"
105 #include "executor/nodeResult.h"
106 #include "executor/nodeSamplescan.h"
107 #include "executor/nodeSeqscan.h"
108 #include "executor/nodeSetOp.h"
109 #include "executor/nodeSort.h"
110 #include "executor/nodeSubplan.h"
111 #include "executor/nodeSubqueryscan.h"
112 #include "executor/nodeTableFuncscan.h"
113 #include "executor/nodeTidrangescan.h"
114 #include "executor/nodeTidscan.h"
115 #include "executor/nodeUnique.h"
116 #include "executor/nodeValuesscan.h"
117 #include "executor/nodeWindowAgg.h"
118 #include "executor/nodeWorktablescan.h"
119 #include "miscadmin.h"
120 #include "nodes/nodeFuncs.h"
121
122 static TupleTableSlot *ExecProcNodeFirst(PlanState *node);
123 static TupleTableSlot *ExecProcNodeInstr(PlanState *node);
124
125
126 /* ------------------------------------------------------------------------
127 * ExecInitNode
128 *
129 * Recursively initializes all the nodes in the plan tree rooted
130 * at 'node'.
131 *
132 * Inputs:
133 * 'node' is the current node of the plan produced by the query planner
134 * 'estate' is the shared execution state for the plan tree
135 * 'eflags' is a bitwise OR of flag bits described in executor.h
136 *
137 * Returns a PlanState node corresponding to the given Plan node.
138 * ------------------------------------------------------------------------
139 */
140 PlanState *
ExecInitNode(Plan * node,EState * estate,int eflags)141 ExecInitNode(Plan *node, EState *estate, int eflags)
142 {
143 PlanState *result;
144 List *subps;
145 ListCell *l;
146
147 /*
148 * do nothing when we get to the end of a leaf on tree.
149 */
150 if (node == NULL)
151 return NULL;
152
153 /*
154 * Make sure there's enough stack available. Need to check here, in
155 * addition to ExecProcNode() (via ExecProcNodeFirst()), to ensure the
156 * stack isn't overrun while initializing the node tree.
157 */
158 check_stack_depth();
159
160 switch (nodeTag(node))
161 {
162 /*
163 * control nodes
164 */
165 case T_Result:
166 result = (PlanState *) ExecInitResult((Result *) node,
167 estate, eflags);
168 break;
169
170 case T_ProjectSet:
171 result = (PlanState *) ExecInitProjectSet((ProjectSet *) node,
172 estate, eflags);
173 break;
174
175 case T_ModifyTable:
176 result = (PlanState *) ExecInitModifyTable((ModifyTable *) node,
177 estate, eflags);
178 break;
179
180 case T_Append:
181 result = (PlanState *) ExecInitAppend((Append *) node,
182 estate, eflags);
183 break;
184
185 case T_MergeAppend:
186 result = (PlanState *) ExecInitMergeAppend((MergeAppend *) node,
187 estate, eflags);
188 break;
189
190 case T_RecursiveUnion:
191 result = (PlanState *) ExecInitRecursiveUnion((RecursiveUnion *) node,
192 estate, eflags);
193 break;
194
195 case T_BitmapAnd:
196 result = (PlanState *) ExecInitBitmapAnd((BitmapAnd *) node,
197 estate, eflags);
198 break;
199
200 case T_BitmapOr:
201 result = (PlanState *) ExecInitBitmapOr((BitmapOr *) node,
202 estate, eflags);
203 break;
204
205 /*
206 * scan nodes
207 */
208 case T_SeqScan:
209 result = (PlanState *) ExecInitSeqScan((SeqScan *) node,
210 estate, eflags);
211 break;
212
213 case T_SampleScan:
214 result = (PlanState *) ExecInitSampleScan((SampleScan *) node,
215 estate, eflags);
216 break;
217
218 case T_IndexScan:
219 result = (PlanState *) ExecInitIndexScan((IndexScan *) node,
220 estate, eflags);
221 break;
222
223 case T_IndexOnlyScan:
224 result = (PlanState *) ExecInitIndexOnlyScan((IndexOnlyScan *) node,
225 estate, eflags);
226 break;
227
228 case T_BitmapIndexScan:
229 result = (PlanState *) ExecInitBitmapIndexScan((BitmapIndexScan *) node,
230 estate, eflags);
231 break;
232
233 case T_BitmapHeapScan:
234 result = (PlanState *) ExecInitBitmapHeapScan((BitmapHeapScan *) node,
235 estate, eflags);
236 break;
237
238 case T_TidScan:
239 result = (PlanState *) ExecInitTidScan((TidScan *) node,
240 estate, eflags);
241 break;
242
243 case T_TidRangeScan:
244 result = (PlanState *) ExecInitTidRangeScan((TidRangeScan *) node,
245 estate, eflags);
246 break;
247
248 case T_SubqueryScan:
249 result = (PlanState *) ExecInitSubqueryScan((SubqueryScan *) node,
250 estate, eflags);
251 break;
252
253 case T_FunctionScan:
254 result = (PlanState *) ExecInitFunctionScan((FunctionScan *) node,
255 estate, eflags);
256 break;
257
258 case T_TableFuncScan:
259 result = (PlanState *) ExecInitTableFuncScan((TableFuncScan *) node,
260 estate, eflags);
261 break;
262
263 case T_ValuesScan:
264 result = (PlanState *) ExecInitValuesScan((ValuesScan *) node,
265 estate, eflags);
266 break;
267
268 case T_CteScan:
269 result = (PlanState *) ExecInitCteScan((CteScan *) node,
270 estate, eflags);
271 break;
272
273 case T_NamedTuplestoreScan:
274 result = (PlanState *) ExecInitNamedTuplestoreScan((NamedTuplestoreScan *) node,
275 estate, eflags);
276 break;
277
278 case T_WorkTableScan:
279 result = (PlanState *) ExecInitWorkTableScan((WorkTableScan *) node,
280 estate, eflags);
281 break;
282
283 case T_ForeignScan:
284 result = (PlanState *) ExecInitForeignScan((ForeignScan *) node,
285 estate, eflags);
286 break;
287
288 case T_CustomScan:
289 result = (PlanState *) ExecInitCustomScan((CustomScan *) node,
290 estate, eflags);
291 break;
292
293 /*
294 * join nodes
295 */
296 case T_NestLoop:
297 result = (PlanState *) ExecInitNestLoop((NestLoop *) node,
298 estate, eflags);
299 break;
300
301 case T_MergeJoin:
302 result = (PlanState *) ExecInitMergeJoin((MergeJoin *) node,
303 estate, eflags);
304 break;
305
306 case T_HashJoin:
307 result = (PlanState *) ExecInitHashJoin((HashJoin *) node,
308 estate, eflags);
309 break;
310
311 /*
312 * materialization nodes
313 */
314 case T_Material:
315 result = (PlanState *) ExecInitMaterial((Material *) node,
316 estate, eflags);
317 break;
318
319 case T_Sort:
320 result = (PlanState *) ExecInitSort((Sort *) node,
321 estate, eflags);
322 break;
323
324 case T_IncrementalSort:
325 result = (PlanState *) ExecInitIncrementalSort((IncrementalSort *) node,
326 estate, eflags);
327 break;
328
329 case T_Memoize:
330 result = (PlanState *) ExecInitMemoize((Memoize *) node, estate,
331 eflags);
332 break;
333
334 case T_Group:
335 result = (PlanState *) ExecInitGroup((Group *) node,
336 estate, eflags);
337 break;
338
339 case T_Agg:
340 result = (PlanState *) ExecInitAgg((Agg *) node,
341 estate, eflags);
342 break;
343
344 case T_WindowAgg:
345 result = (PlanState *) ExecInitWindowAgg((WindowAgg *) node,
346 estate, eflags);
347 break;
348
349 case T_Unique:
350 result = (PlanState *) ExecInitUnique((Unique *) node,
351 estate, eflags);
352 break;
353
354 case T_Gather:
355 result = (PlanState *) ExecInitGather((Gather *) node,
356 estate, eflags);
357 break;
358
359 case T_GatherMerge:
360 result = (PlanState *) ExecInitGatherMerge((GatherMerge *) node,
361 estate, eflags);
362 break;
363
364 case T_Hash:
365 result = (PlanState *) ExecInitHash((Hash *) node,
366 estate, eflags);
367 break;
368
369 case T_SetOp:
370 result = (PlanState *) ExecInitSetOp((SetOp *) node,
371 estate, eflags);
372 break;
373
374 case T_LockRows:
375 result = (PlanState *) ExecInitLockRows((LockRows *) node,
376 estate, eflags);
377 break;
378
379 case T_Limit:
380 result = (PlanState *) ExecInitLimit((Limit *) node,
381 estate, eflags);
382 break;
383
384 default:
385 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
386 result = NULL; /* keep compiler quiet */
387 break;
388 }
389
390 ExecSetExecProcNode(result, result->ExecProcNode);
391
392 /*
393 * Initialize any initPlans present in this node. The planner put them in
394 * a separate list for us.
395 */
396 subps = NIL;
397 foreach(l, node->initPlan)
398 {
399 SubPlan *subplan = (SubPlan *) lfirst(l);
400 SubPlanState *sstate;
401
402 Assert(IsA(subplan, SubPlan));
403 sstate = ExecInitSubPlan(subplan, result);
404 subps = lappend(subps, sstate);
405 }
406 result->initPlan = subps;
407
408 /* Set up instrumentation for this node if requested */
409 if (estate->es_instrument)
410 result->instrument = InstrAlloc(1, estate->es_instrument,
411 result->async_capable);
412
413 return result;
414 }
415
416
417 /*
418 * If a node wants to change its ExecProcNode function after ExecInitNode()
419 * has finished, it should do so with this function. That way any wrapper
420 * functions can be reinstalled, without the node having to know how that
421 * works.
422 */
423 void
ExecSetExecProcNode(PlanState * node,ExecProcNodeMtd function)424 ExecSetExecProcNode(PlanState *node, ExecProcNodeMtd function)
425 {
426 /*
427 * Add a wrapper around the ExecProcNode callback that checks stack depth
428 * during the first execution and maybe adds an instrumentation wrapper.
429 * When the callback is changed after execution has already begun that
430 * means we'll superfluously execute ExecProcNodeFirst, but that seems ok.
431 */
432 node->ExecProcNodeReal = function;
433 node->ExecProcNode = ExecProcNodeFirst;
434 }
435
436
437 /*
438 * ExecProcNode wrapper that performs some one-time checks, before calling
439 * the relevant node method (possibly via an instrumentation wrapper).
440 */
441 static TupleTableSlot *
ExecProcNodeFirst(PlanState * node)442 ExecProcNodeFirst(PlanState *node)
443 {
444 /*
445 * Perform stack depth check during the first execution of the node. We
446 * only do so the first time round because it turns out to not be cheap on
447 * some common architectures (eg. x86). This relies on the assumption
448 * that ExecProcNode calls for a given plan node will always be made at
449 * roughly the same stack depth.
450 */
451 check_stack_depth();
452
453 /*
454 * If instrumentation is required, change the wrapper to one that just
455 * does instrumentation. Otherwise we can dispense with all wrappers and
456 * have ExecProcNode() directly call the relevant function from now on.
457 */
458 if (node->instrument)
459 node->ExecProcNode = ExecProcNodeInstr;
460 else
461 node->ExecProcNode = node->ExecProcNodeReal;
462
463 return node->ExecProcNode(node);
464 }
465
466
467 /*
468 * ExecProcNode wrapper that performs instrumentation calls. By keeping
469 * this a separate function, we avoid overhead in the normal case where
470 * no instrumentation is wanted.
471 */
472 static TupleTableSlot *
ExecProcNodeInstr(PlanState * node)473 ExecProcNodeInstr(PlanState *node)
474 {
475 TupleTableSlot *result;
476
477 InstrStartNode(node->instrument);
478
479 result = node->ExecProcNodeReal(node);
480
481 InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0);
482
483 return result;
484 }
485
486
487 /* ----------------------------------------------------------------
488 * MultiExecProcNode
489 *
490 * Execute a node that doesn't return individual tuples
491 * (it might return a hashtable, bitmap, etc). Caller should
492 * check it got back the expected kind of Node.
493 *
494 * This has essentially the same responsibilities as ExecProcNode,
495 * but it does not do InstrStartNode/InstrStopNode (mainly because
496 * it can't tell how many returned tuples to count). Each per-node
497 * function must provide its own instrumentation support.
498 * ----------------------------------------------------------------
499 */
500 Node *
MultiExecProcNode(PlanState * node)501 MultiExecProcNode(PlanState *node)
502 {
503 Node *result;
504
505 check_stack_depth();
506
507 CHECK_FOR_INTERRUPTS();
508
509 if (node->chgParam != NULL) /* something changed */
510 ExecReScan(node); /* let ReScan handle this */
511
512 switch (nodeTag(node))
513 {
514 /*
515 * Only node types that actually support multiexec will be listed
516 */
517
518 case T_HashState:
519 result = MultiExecHash((HashState *) node);
520 break;
521
522 case T_BitmapIndexScanState:
523 result = MultiExecBitmapIndexScan((BitmapIndexScanState *) node);
524 break;
525
526 case T_BitmapAndState:
527 result = MultiExecBitmapAnd((BitmapAndState *) node);
528 break;
529
530 case T_BitmapOrState:
531 result = MultiExecBitmapOr((BitmapOrState *) node);
532 break;
533
534 default:
535 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
536 result = NULL;
537 break;
538 }
539
540 return result;
541 }
542
543
544 /* ----------------------------------------------------------------
545 * ExecEndNode
546 *
547 * Recursively cleans up all the nodes in the plan rooted
548 * at 'node'.
549 *
550 * After this operation, the query plan will not be able to be
551 * processed any further. This should be called only after
552 * the query plan has been fully executed.
553 * ----------------------------------------------------------------
554 */
555 void
ExecEndNode(PlanState * node)556 ExecEndNode(PlanState *node)
557 {
558 /*
559 * do nothing when we get to the end of a leaf on tree.
560 */
561 if (node == NULL)
562 return;
563
564 /*
565 * Make sure there's enough stack available. Need to check here, in
566 * addition to ExecProcNode() (via ExecProcNodeFirst()), because it's not
567 * guaranteed that ExecProcNode() is reached for all nodes.
568 */
569 check_stack_depth();
570
571 if (node->chgParam != NULL)
572 {
573 bms_free(node->chgParam);
574 node->chgParam = NULL;
575 }
576
577 switch (nodeTag(node))
578 {
579 /*
580 * control nodes
581 */
582 case T_ResultState:
583 ExecEndResult((ResultState *) node);
584 break;
585
586 case T_ProjectSetState:
587 ExecEndProjectSet((ProjectSetState *) node);
588 break;
589
590 case T_ModifyTableState:
591 ExecEndModifyTable((ModifyTableState *) node);
592 break;
593
594 case T_AppendState:
595 ExecEndAppend((AppendState *) node);
596 break;
597
598 case T_MergeAppendState:
599 ExecEndMergeAppend((MergeAppendState *) node);
600 break;
601
602 case T_RecursiveUnionState:
603 ExecEndRecursiveUnion((RecursiveUnionState *) node);
604 break;
605
606 case T_BitmapAndState:
607 ExecEndBitmapAnd((BitmapAndState *) node);
608 break;
609
610 case T_BitmapOrState:
611 ExecEndBitmapOr((BitmapOrState *) node);
612 break;
613
614 /*
615 * scan nodes
616 */
617 case T_SeqScanState:
618 ExecEndSeqScan((SeqScanState *) node);
619 break;
620
621 case T_SampleScanState:
622 ExecEndSampleScan((SampleScanState *) node);
623 break;
624
625 case T_GatherState:
626 ExecEndGather((GatherState *) node);
627 break;
628
629 case T_GatherMergeState:
630 ExecEndGatherMerge((GatherMergeState *) node);
631 break;
632
633 case T_IndexScanState:
634 ExecEndIndexScan((IndexScanState *) node);
635 break;
636
637 case T_IndexOnlyScanState:
638 ExecEndIndexOnlyScan((IndexOnlyScanState *) node);
639 break;
640
641 case T_BitmapIndexScanState:
642 ExecEndBitmapIndexScan((BitmapIndexScanState *) node);
643 break;
644
645 case T_BitmapHeapScanState:
646 ExecEndBitmapHeapScan((BitmapHeapScanState *) node);
647 break;
648
649 case T_TidScanState:
650 ExecEndTidScan((TidScanState *) node);
651 break;
652
653 case T_TidRangeScanState:
654 ExecEndTidRangeScan((TidRangeScanState *) node);
655 break;
656
657 case T_SubqueryScanState:
658 ExecEndSubqueryScan((SubqueryScanState *) node);
659 break;
660
661 case T_FunctionScanState:
662 ExecEndFunctionScan((FunctionScanState *) node);
663 break;
664
665 case T_TableFuncScanState:
666 ExecEndTableFuncScan((TableFuncScanState *) node);
667 break;
668
669 case T_ValuesScanState:
670 ExecEndValuesScan((ValuesScanState *) node);
671 break;
672
673 case T_CteScanState:
674 ExecEndCteScan((CteScanState *) node);
675 break;
676
677 case T_NamedTuplestoreScanState:
678 ExecEndNamedTuplestoreScan((NamedTuplestoreScanState *) node);
679 break;
680
681 case T_WorkTableScanState:
682 ExecEndWorkTableScan((WorkTableScanState *) node);
683 break;
684
685 case T_ForeignScanState:
686 ExecEndForeignScan((ForeignScanState *) node);
687 break;
688
689 case T_CustomScanState:
690 ExecEndCustomScan((CustomScanState *) node);
691 break;
692
693 /*
694 * join nodes
695 */
696 case T_NestLoopState:
697 ExecEndNestLoop((NestLoopState *) node);
698 break;
699
700 case T_MergeJoinState:
701 ExecEndMergeJoin((MergeJoinState *) node);
702 break;
703
704 case T_HashJoinState:
705 ExecEndHashJoin((HashJoinState *) node);
706 break;
707
708 /*
709 * materialization nodes
710 */
711 case T_MaterialState:
712 ExecEndMaterial((MaterialState *) node);
713 break;
714
715 case T_SortState:
716 ExecEndSort((SortState *) node);
717 break;
718
719 case T_IncrementalSortState:
720 ExecEndIncrementalSort((IncrementalSortState *) node);
721 break;
722
723 case T_MemoizeState:
724 ExecEndMemoize((MemoizeState *) node);
725 break;
726
727 case T_GroupState:
728 ExecEndGroup((GroupState *) node);
729 break;
730
731 case T_AggState:
732 ExecEndAgg((AggState *) node);
733 break;
734
735 case T_WindowAggState:
736 ExecEndWindowAgg((WindowAggState *) node);
737 break;
738
739 case T_UniqueState:
740 ExecEndUnique((UniqueState *) node);
741 break;
742
743 case T_HashState:
744 ExecEndHash((HashState *) node);
745 break;
746
747 case T_SetOpState:
748 ExecEndSetOp((SetOpState *) node);
749 break;
750
751 case T_LockRowsState:
752 ExecEndLockRows((LockRowsState *) node);
753 break;
754
755 case T_LimitState:
756 ExecEndLimit((LimitState *) node);
757 break;
758
759 default:
760 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
761 break;
762 }
763 }
764
765 /*
766 * ExecShutdownNode
767 *
768 * Give execution nodes a chance to stop asynchronous resource consumption
769 * and release any resources still held.
770 */
771 bool
ExecShutdownNode(PlanState * node)772 ExecShutdownNode(PlanState *node)
773 {
774 if (node == NULL)
775 return false;
776
777 check_stack_depth();
778
779 /*
780 * Treat the node as running while we shut it down, but only if it's run
781 * at least once already. We don't expect much CPU consumption during
782 * node shutdown, but in the case of Gather or Gather Merge, we may shut
783 * down workers at this stage. If so, their buffer usage will get
784 * propagated into pgBufferUsage at this point, and we want to make sure
785 * that it gets associated with the Gather node. We skip this if the node
786 * has never been executed, so as to avoid incorrectly making it appear
787 * that it has.
788 */
789 if (node->instrument && node->instrument->running)
790 InstrStartNode(node->instrument);
791
792 planstate_tree_walker(node, ExecShutdownNode, NULL);
793
794 switch (nodeTag(node))
795 {
796 case T_GatherState:
797 ExecShutdownGather((GatherState *) node);
798 break;
799 case T_ForeignScanState:
800 ExecShutdownForeignScan((ForeignScanState *) node);
801 break;
802 case T_CustomScanState:
803 ExecShutdownCustomScan((CustomScanState *) node);
804 break;
805 case T_GatherMergeState:
806 ExecShutdownGatherMerge((GatherMergeState *) node);
807 break;
808 case T_HashState:
809 ExecShutdownHash((HashState *) node);
810 break;
811 case T_HashJoinState:
812 ExecShutdownHashJoin((HashJoinState *) node);
813 break;
814 default:
815 break;
816 }
817
818 /* Stop the node if we started it above, reporting 0 tuples. */
819 if (node->instrument && node->instrument->running)
820 InstrStopNode(node->instrument, 0);
821
822 return false;
823 }
824
825 /*
826 * ExecSetTupleBound
827 *
828 * Set a tuple bound for a planstate node. This lets child plan nodes
829 * optimize based on the knowledge that the maximum number of tuples that
830 * their parent will demand is limited. The tuple bound for a node may
831 * only be changed between scans (i.e., after node initialization or just
832 * before an ExecReScan call).
833 *
834 * Any negative tuples_needed value means "no limit", which should be the
835 * default assumption when this is not called at all for a particular node.
836 *
837 * Note: if this is called repeatedly on a plan tree, the exact same set
838 * of nodes must be updated with the new limit each time; be careful that
839 * only unchanging conditions are tested here.
840 */
841 void
ExecSetTupleBound(int64 tuples_needed,PlanState * child_node)842 ExecSetTupleBound(int64 tuples_needed, PlanState *child_node)
843 {
844 /*
845 * Since this function recurses, in principle we should check stack depth
846 * here. In practice, it's probably pointless since the earlier node
847 * initialization tree traversal would surely have consumed more stack.
848 */
849
850 if (IsA(child_node, SortState))
851 {
852 /*
853 * If it is a Sort node, notify it that it can use bounded sort.
854 *
855 * Note: it is the responsibility of nodeSort.c to react properly to
856 * changes of these parameters. If we ever redesign this, it'd be a
857 * good idea to integrate this signaling with the parameter-change
858 * mechanism.
859 */
860 SortState *sortState = (SortState *) child_node;
861
862 if (tuples_needed < 0)
863 {
864 /* make sure flag gets reset if needed upon rescan */
865 sortState->bounded = false;
866 }
867 else
868 {
869 sortState->bounded = true;
870 sortState->bound = tuples_needed;
871 }
872 }
873 else if (IsA(child_node, IncrementalSortState))
874 {
875 /*
876 * If it is an IncrementalSort node, notify it that it can use bounded
877 * sort.
878 *
879 * Note: it is the responsibility of nodeIncrementalSort.c to react
880 * properly to changes of these parameters. If we ever redesign this,
881 * it'd be a good idea to integrate this signaling with the
882 * parameter-change mechanism.
883 */
884 IncrementalSortState *sortState = (IncrementalSortState *) child_node;
885
886 if (tuples_needed < 0)
887 {
888 /* make sure flag gets reset if needed upon rescan */
889 sortState->bounded = false;
890 }
891 else
892 {
893 sortState->bounded = true;
894 sortState->bound = tuples_needed;
895 }
896 }
897 else if (IsA(child_node, AppendState))
898 {
899 /*
900 * If it is an Append, we can apply the bound to any nodes that are
901 * children of the Append, since the Append surely need read no more
902 * than that many tuples from any one input.
903 */
904 AppendState *aState = (AppendState *) child_node;
905 int i;
906
907 for (i = 0; i < aState->as_nplans; i++)
908 ExecSetTupleBound(tuples_needed, aState->appendplans[i]);
909 }
910 else if (IsA(child_node, MergeAppendState))
911 {
912 /*
913 * If it is a MergeAppend, we can apply the bound to any nodes that
914 * are children of the MergeAppend, since the MergeAppend surely need
915 * read no more than that many tuples from any one input.
916 */
917 MergeAppendState *maState = (MergeAppendState *) child_node;
918 int i;
919
920 for (i = 0; i < maState->ms_nplans; i++)
921 ExecSetTupleBound(tuples_needed, maState->mergeplans[i]);
922 }
923 else if (IsA(child_node, ResultState))
924 {
925 /*
926 * Similarly, for a projecting Result, we can apply the bound to its
927 * child node.
928 *
929 * If Result supported qual checking, we'd have to punt on seeing a
930 * qual. Note that having a resconstantqual is not a showstopper: if
931 * that condition succeeds it affects nothing, while if it fails, no
932 * rows will be demanded from the Result child anyway.
933 */
934 if (outerPlanState(child_node))
935 ExecSetTupleBound(tuples_needed, outerPlanState(child_node));
936 }
937 else if (IsA(child_node, SubqueryScanState))
938 {
939 /*
940 * We can also descend through SubqueryScan, but only if it has no
941 * qual (otherwise it might discard rows).
942 */
943 SubqueryScanState *subqueryState = (SubqueryScanState *) child_node;
944
945 if (subqueryState->ss.ps.qual == NULL)
946 ExecSetTupleBound(tuples_needed, subqueryState->subplan);
947 }
948 else if (IsA(child_node, GatherState))
949 {
950 /*
951 * A Gather node can propagate the bound to its workers. As with
952 * MergeAppend, no one worker could possibly need to return more
953 * tuples than the Gather itself needs to.
954 *
955 * Note: As with Sort, the Gather node is responsible for reacting
956 * properly to changes to this parameter.
957 */
958 GatherState *gstate = (GatherState *) child_node;
959
960 gstate->tuples_needed = tuples_needed;
961
962 /* Also pass down the bound to our own copy of the child plan */
963 ExecSetTupleBound(tuples_needed, outerPlanState(child_node));
964 }
965 else if (IsA(child_node, GatherMergeState))
966 {
967 /* Same comments as for Gather */
968 GatherMergeState *gstate = (GatherMergeState *) child_node;
969
970 gstate->tuples_needed = tuples_needed;
971
972 ExecSetTupleBound(tuples_needed, outerPlanState(child_node));
973 }
974
975 /*
976 * In principle we could descend through any plan node type that is
977 * certain not to discard or combine input rows; but on seeing a node that
978 * can do that, we can't propagate the bound any further. For the moment
979 * it's unclear that any other cases are worth checking here.
980 */
981 }
982