---------------------------------------------------------------- * ExecMergeJoin * ---------------------------------------------------------------- */
| 635 | * ---------------------------------------------------------------- |
| 636 | */ |
| 637 | static TupleTableSlot * |
| 638 | ExecMergeJoin_guts(PlanState *pstate) |
| 639 | { |
| 640 | MergeJoinState *node = castNode(MergeJoinState, pstate); |
| 641 | ExprState *joinqual; |
| 642 | ExprState *otherqual; |
| 643 | bool qualResult; |
| 644 | int compareResult; |
| 645 | PlanState *innerPlan; |
| 646 | TupleTableSlot *innerTupleSlot; |
| 647 | PlanState *outerPlan; |
| 648 | TupleTableSlot *outerTupleSlot; |
| 649 | ExprContext *econtext; |
| 650 | bool doFillOuter; |
| 651 | bool doFillInner; |
| 652 | |
| 653 | CHECK_FOR_INTERRUPTS(); |
| 654 | |
| 655 | /* |
| 656 | * get information from node |
| 657 | */ |
| 658 | innerPlan = innerPlanState(node); |
| 659 | outerPlan = outerPlanState(node); |
| 660 | econtext = node->js.ps.ps_ExprContext; |
| 661 | joinqual = node->js.joinqual; |
| 662 | otherqual = node->js.ps.qual; |
| 663 | doFillOuter = node->mj_FillOuter; |
| 664 | doFillInner = node->mj_FillInner; |
| 665 | |
| 666 | /* |
| 667 | * Reset per-tuple memory context to free any expression evaluation |
| 668 | * storage allocated in the previous tuple cycle. |
| 669 | */ |
| 670 | ResetExprContext(econtext); |
| 671 | |
| 672 | /* |
| 673 | * MPP-4165: My fix for MPP-3300 was correct in that we avoided |
| 674 | * the *deadlock* but had very unexpected (and painful) |
| 675 | * performance characteristics: we basically de-pipeline and |
| 676 | * de-parallelize execution of any query which has motion below |
| 677 | * us. |
| 678 | * |
| 679 | * So now prefetch_inner is set (see createplan.c) if we have *any* motion |
| 680 | * below us. If we don't have any motion, it doesn't matter. |
| 681 | * |
| 682 | * See motion_sanity_walker() for details on how a deadlock may occur. |
| 683 | */ |
| 684 | if (node->prefetch_inner) |
| 685 | { |
| 686 | innerTupleSlot = ExecProcNode(innerPlan); |
| 687 | node->mj_InnerTupleSlot = innerTupleSlot; |
| 688 | |
| 689 | ExecReScan(innerPlan); |
| 690 | ResetExprContext(econtext); |
| 691 | |
| 692 | node->prefetch_inner = false; |
| 693 | } |
| 694 |
no test coverage detected