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));
}