public void implementContext()

in src/query-common/src/main/java/org/apache/kylin/query/relnode/OlapJoinRel.java [255:321]


    public void implementContext(ContextImpl contextImpl, ContextVisitorState state) {
        ContextVisitorState leftState = ContextVisitorState.init();
        contextImpl.fixSharedOlapTableScanOnTheLeft(this);
        contextImpl.visitChild(getInput(0), this, leftState);

        ContextVisitorState rightState = ContextVisitorState.init();
        contextImpl.fixSharedOlapTableScanOnTheRight(this);
        contextImpl.visitChild(getInput(1), this, rightState);

        if (leftState.hasModelView() || rightState.hasModelView()) {
            if (leftState.hasFreeTable()) {
                contextImpl.allocateContext((OlapRel) getInput(0), this);
                leftState.setHasFreeTable(false);
            }

            if (rightState.hasFreeTable()) {
                contextImpl.allocateContext((OlapRel) getInput(1), this);
                rightState.setHasFreeTable(false);
            }
        }

        // special case for left join
        if (getJoinType() == JoinRelType.LEFT && rightState.hasFilter() && rightState.hasFreeTable()) {
            contextImpl.allocateContext((OlapRel) getInput(1), this);
            rightState.setHasFreeTable(false);
        }

        if (getJoinType() == JoinRelType.INNER || getJoinType() == JoinRelType.LEFT) {

            // if one side of join has no free table, the other side should have separate context
            if (!leftState.hasFreeTable() && rightState.hasFreeTable()) {
                contextImpl.allocateContext((OlapRel) right, this);
                rightState.setHasFreeTable(false);
            } else if (leftState.hasFreeTable() && !rightState.hasFreeTable()) {
                contextImpl.allocateContext((OlapRel) left, this);
                leftState.setHasFreeTable(false);
            } else if (leftState.hasFreeTable() && rightState.hasFreeTable()
                    && (isCrossJoin() || hasSameFirstTable(leftState, rightState)
                            || isRightSideIncrementalTable(rightState) || RexUtils.joinMoreThanOneTable(this)
                            || !RexUtils.isMerelyTableColumnReference(this, condition) || joinCondEqualNullSafe)) {
                contextImpl.allocateContext((OlapRel) left, this);
                contextImpl.allocateContext((OlapRel) right, this);
                leftState.setHasFreeTable(false);
                rightState.setHasFreeTable(false);
            }

            state.merge(leftState).merge(rightState);
            subContexts.addAll(ContextUtil.collectSubContext(this.left));
            subContexts.addAll(ContextUtil.collectSubContext(this.right));
            return;
        }

        // other join types (RIGHT or FULL), two sides two contexts
        if (leftState.hasFreeTable()) {
            contextImpl.allocateContext((OlapRel) left, this);
            leftState.setHasFreeTable(false);
        }

        if (rightState.hasFreeTable()) {
            contextImpl.allocateContext((OlapRel) right, this);
            rightState.setHasFreeTable(false);
        }

        state.merge(leftState).merge(rightState);
        subContexts.addAll(ContextUtil.collectSubContext(this.left));
        subContexts.addAll(ContextUtil.collectSubContext(this.right));
    }