package com.taobao.tddl.optimizer.costbased;
import com.taobao.tddl.optimizer.core.ast.ASTNode;
import com.taobao.tddl.optimizer.core.ast.QueryTreeNode;
import com.taobao.tddl.optimizer.core.ast.query.JoinNode;
import com.taobao.tddl.optimizer.exceptions.QueryException;
/**
* 预先处理join
*
* <pre>
* 1. 会遍历所有节点将right join的左右节点进行调换,转换成left join.
*
* 比如 A right join B on A.id = B.id
* 转化为 B left join B on A.id = B.id
*
* </pre>
*/
public class JoinPreProcessor {
public static QueryTreeNode optimize(QueryTreeNode qtn) throws QueryException {
qtn = findAndChangeRightJoinToLeftJoin(qtn);
return qtn;
}
/**
* 会遍历所有节点将right join的左右节点进行调换,转换成left join.
*
* <pre>
* 比如 A right join B on A.id = B.id
* 转化为 B left join B on A.id = B.id
* </pre>
*/
private static QueryTreeNode findAndChangeRightJoinToLeftJoin(QueryTreeNode qtn) {
for (ASTNode child : qtn.getChildren()) {
findAndChangeRightJoinToLeftJoin((QueryTreeNode) child);
}
if (qtn instanceof JoinNode && ((JoinNode) qtn).isRightOuterJoin()) {
/**
* 如果带有其他非column=column条件,不能做这种转换,否则语义改变
*/
if (qtn.getOtherJoinOnFilter() != null) {
return qtn;
}
JoinNode jn = (JoinNode) qtn;
jn.exchangeLeftAndRight();
jn.build();
}
return qtn;
}
}