package com.taobao.tddl.optimizer.core.ast.query; import static com.taobao.tddl.optimizer.utils.OptimizerToString.appendField; import static com.taobao.tddl.optimizer.utils.OptimizerToString.appendln; import static com.taobao.tddl.optimizer.utils.OptimizerToString.printFilterString; import java.util.List; import com.taobao.tddl.common.utils.GeneralUtil; import com.taobao.tddl.optimizer.core.ASTNodeFactory; import com.taobao.tddl.optimizer.core.ast.ASTNode; import com.taobao.tddl.optimizer.core.ast.QueryTreeNode; import com.taobao.tddl.optimizer.core.ast.build.QueryNodeBuilder; import com.taobao.tddl.optimizer.core.ast.build.QueryTreeNodeBuilder; import com.taobao.tddl.optimizer.core.expression.IFilter; import com.taobao.tddl.optimizer.core.expression.IOrderBy; import com.taobao.tddl.optimizer.core.plan.IQueryTree; import com.taobao.tddl.optimizer.core.plan.query.IQuery; import com.taobao.tddl.optimizer.exceptions.QueryException; /** * @author Dreamond 对于一个单个逻辑表的query,处理node. * @author whisper */ public class QueryNode extends QueryTreeNode { private QueryNodeBuilder builder; public QueryNode(QueryTreeNode child){ this(child, null); } public QueryNode(QueryTreeNode child, IFilter filter){ this.builder = new QueryNodeBuilder(this); this.whereFilter = filter; this.setChild(child); if (child != null) { child.setSubQuery(true);// 默认设置为subQuery } } public QueryTreeNode getChild() { if (this.getChildren().isEmpty()) { return null; } return (QueryTreeNode) this.getChildren().get(0); } public void setChild(QueryTreeNode child) { if (child == null) { return; } if (this.getChildren().isEmpty()) { this.getChildren().add(child); } else { this.getChildren().set(0, child); } setNeedBuild(true); } public List<ASTNode> getChildren() { if (super.getChildren() != null && super.getChildren().size() == 1) { if (super.getChildren().get(0) == null) { super.getChildren().remove(0); } } return super.getChildren(); } public void build() { if (this.isNeedBuild()) { this.builder.build(); } setNeedBuild(false); } public List getImplicitOrderBys() { List<IOrderBy> orderByCombineWithGroupBy = getOrderByCombineWithGroupBy(); if (orderByCombineWithGroupBy != null) { return orderByCombineWithGroupBy; } else { return this.getChild().getImplicitOrderBys(); } } public QueryTreeNodeBuilder getBuilder() { return builder; } public String getName() { return this.getAlias(); } public IQueryTree toDataNodeExecutor() throws QueryException { IQuery query = ASTNodeFactory.getInstance().createQuery(); query.setAlias(this.getAlias()); query.setColumns(this.getColumnsSelected()); query.setConsistent(this.getConsistent()); query.setGroupBys(this.getGroupBys()); query.setKeyFilter(this.getKeyFilter()); query.setValueFilter(this.getResultFilter()); query.setLimitFrom(this.getLimitFrom()); query.setLimitTo(this.getLimitTo()); query.setLockModel(this.getLockModel()); query.setOrderBys(this.getOrderBys()); query.setSubQuery(this.getChild().toDataNodeExecutor()); query.executeOn(this.getDataNode()); query.setSql(this.getSql()); query.setIsSubQuery(this.isSubQuery()); return query; } public QueryNode copy() { QueryNode newTableNode = new QueryNode((QueryTreeNode) this.getChild().copy()); this.copySelfTo(newTableNode); newTableNode.setNeedBuild(false); return newTableNode; } public QueryNode deepCopy() { QueryNode newTableNode = new QueryNode((QueryTreeNode) this.getChild().deepCopy()); this.deepCopySelfTo(newTableNode); newTableNode.setNeedBuild(false); return newTableNode; } public String toString(int inden) { String tabTittle = GeneralUtil.getTab(inden); String tabContent = GeneralUtil.getTab(inden + 1); StringBuilder sb = new StringBuilder(); if (this.getAlias() != null) { appendln(sb, tabTittle + "SubQuery" + " as " + this.getAlias()); } else { appendln(sb, tabTittle + "SubQuery"); } appendField(sb, "keyFilter", printFilterString(this.getKeyFilter(), inden + 2), tabContent); appendField(sb, "resultFilter", printFilterString(this.getResultFilter(), inden + 2), tabContent); appendField(sb, "whereFilter", printFilterString(this.getWhereFilter(), inden + 2), tabContent); appendField(sb, "otherJoinOnFilter", printFilterString(this.getOtherJoinOnFilter(), inden + 2), tabContent); appendField(sb, "having", printFilterString(this.getHavingFilter(), inden + 2), tabContent); if (!(this.getLimitFrom() != null && this.getLimitFrom().equals(0L) && this.getLimitTo() != null && this.getLimitTo() .equals(0L))) { appendField(sb, "limitFrom", this.getLimitFrom(), tabContent); appendField(sb, "limitTo", this.getLimitTo(), tabContent); } if (this.isSubQuery()) { appendField(sb, "isSubQuery", this.isSubQuery(), tabContent); } appendField(sb, "orderBy", this.getOrderBys(), tabContent); appendField(sb, "queryConcurrency", this.getQueryConcurrency(), tabContent); appendField(sb, "lockModel", this.getLockModel(), tabContent); appendField(sb, "columns", this.getColumnsSelected(), tabContent); appendField(sb, "groupBys", this.getGroupBys(), tabContent); appendField(sb, "sql", this.getSql(), tabContent); appendField(sb, "executeOn", this.getDataNode(), tabContent); if (this.getChild() != null) { appendln(sb, tabContent + "from:"); sb.append(this.getChild().toString(inden + 2)); } return sb.toString(); } }