---------------------------------------------------------------- * ExecNestLoop(node) * * old comments * Returns the tuple joined from inner and outer tuples which * satisfies the qualification clause. * * It scans the inner relation to join with current outer tuple. * * If none is found, next tuple from the outer relation is retrieved * and the inner relation is scanned from the b
| 67 | * ---------------------------------------------------------------- |
| 68 | */ |
| 69 | static TupleTableSlot * |
| 70 | ExecNestLoop_guts(PlanState *pstate) |
| 71 | { |
| 72 | NestLoopState *node = castNode(NestLoopState, pstate); |
| 73 | NestLoop *nl; |
| 74 | PlanState *innerPlan; |
| 75 | PlanState *outerPlan; |
| 76 | TupleTableSlot *outerTupleSlot; |
| 77 | TupleTableSlot *innerTupleSlot; |
| 78 | ExprState *joinqual; |
| 79 | ExprState *otherqual; |
| 80 | ExprContext *econtext; |
| 81 | ListCell *lc; |
| 82 | |
| 83 | CHECK_FOR_INTERRUPTS(); |
| 84 | |
| 85 | /* |
| 86 | * get information from the node |
| 87 | */ |
| 88 | ENL1_printf("getting info from node"); |
| 89 | |
| 90 | nl = (NestLoop *) node->js.ps.plan; |
| 91 | joinqual = node->js.joinqual; |
| 92 | otherqual = node->js.ps.qual; |
| 93 | outerPlan = outerPlanState(node); |
| 94 | innerPlan = innerPlanState(node); |
| 95 | econtext = node->js.ps.ps_ExprContext; |
| 96 | |
| 97 | /* |
| 98 | * Reset per-tuple memory context to free any expression evaluation |
| 99 | * storage allocated in the previous tuple cycle. |
| 100 | */ |
| 101 | ResetExprContext(econtext); |
| 102 | |
| 103 | /* |
| 104 | * MPP-4165: My fix for MPP-3300 was correct in that we avoided |
| 105 | * the *deadlock* but had very unexpected (and painful) |
| 106 | * performance characteristics: we basically de-pipeline and |
| 107 | * de-parallelize execution of any query which has motion below |
| 108 | * us. |
| 109 | * |
| 110 | * So now prefetch_inner is set (see createplan.c) if we have *any* motion |
| 111 | * below us. If we don't have any motion, it doesn't matter. |
| 112 | * |
| 113 | * See motion_sanity_walker() for details on how a deadlock may occur. |
| 114 | */ |
| 115 | if (node->prefetch_inner) |
| 116 | { |
| 117 | /* |
| 118 | * Prefetch inner is Cloudberry specific behavior. |
| 119 | * However, inner plan may depend on outer plan as |
| 120 | * outerParams. If so, we have to fake those params |
| 121 | * to avoid null pointer reference issue. And because |
| 122 | * of the nestParams, those inner results prefetched |
| 123 | * will be discarded (following code will rescan inner, |
| 124 | * even if inner's top is material node because of chgParam |
| 125 | * it will be re-executed too) that it is safe to fake |
| 126 | * nestParams here. The target is to materialize motion scan. |
no test coverage detected