* Prefetch JoinQual or NonJoinQual to prevent motion hazard. * * A motion hazard is a deadlock between motions, a classic motion hazard in a * join executor is formed by its inner and outer motions, it can be prevented * by prefetching the inner plan, refer to motion_sanity_check() for details. * * A similar motion hazard can be formed by the outer motion and the join qual * motion(or non j
| 1526 | * Return true if the JoinQual or NonJoinQual is prefetched. |
| 1527 | */ |
| 1528 | void |
| 1529 | ExecPrefetchQual(JoinState *node, bool isJoinQual) |
| 1530 | { |
| 1531 | EState *estate = node->ps.state; |
| 1532 | ExprContext *econtext = node->ps.ps_ExprContext; |
| 1533 | PlanState *inner = innerPlanState(node); |
| 1534 | PlanState *outer = outerPlanState(node); |
| 1535 | TupleTableSlot *innertuple = econtext->ecxt_innertuple; |
| 1536 | |
| 1537 | ListCell *lc = NULL; |
| 1538 | List *quals = NIL; |
| 1539 | |
| 1540 | ExprState *qual; |
| 1541 | |
| 1542 | if (isJoinQual) |
| 1543 | qual = node->joinqual; |
| 1544 | else |
| 1545 | qual = node->ps.qual; |
| 1546 | |
| 1547 | Assert(qual); |
| 1548 | |
| 1549 | /* Outer tuples should not be fetched before us */ |
| 1550 | Assert(econtext->ecxt_outertuple == NULL); |
| 1551 | |
| 1552 | /* Build fake inner & outer tuples */ |
| 1553 | econtext->ecxt_innertuple = ExecInitNullTupleSlot(estate, |
| 1554 | ExecGetResultType(inner), |
| 1555 | &TTSOpsVirtual); |
| 1556 | econtext->ecxt_outertuple = ExecInitNullTupleSlot(estate, |
| 1557 | ExecGetResultType(outer), |
| 1558 | &TTSOpsVirtual); |
| 1559 | |
| 1560 | if (IsA(node->ps.plan, NestLoop)) |
| 1561 | { |
| 1562 | NestLoop *nl = (NestLoop *) (node->ps.plan); |
| 1563 | if (nl->nestParams) |
| 1564 | fake_outer_params(node); |
| 1565 | } |
| 1566 | |
| 1567 | quals = flatten_logic_exprs((Node *) qual); |
| 1568 | |
| 1569 | /* Fetch subplan with the fake inner & outer tuples */ |
| 1570 | foreach(lc, quals) |
| 1571 | { |
| 1572 | /* |
| 1573 | * Force every qual is prefech because |
| 1574 | * our target is to materialize motion node. |
| 1575 | */ |
| 1576 | ExprState *clause = (ExprState *) lfirst(lc); |
| 1577 | (void) ExecQual(clause, econtext); |
| 1578 | } |
| 1579 | |
| 1580 | /* Restore previous state */ |
| 1581 | econtext->ecxt_innertuple = innertuple; |
| 1582 | econtext->ecxt_outertuple = NULL; |
| 1583 | } |
| 1584 | |
| 1585 | /* ---------------------------------------------------------------- |
no test coverage detected