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