package com.taobao.tddl.repo.mysql.sqlconvertor; import java.util.HashMap; import java.util.List; import java.util.Map; import com.taobao.tddl.optimizer.core.plan.IDataNodeExecutor; import com.taobao.tddl.optimizer.core.plan.IPut; import com.taobao.tddl.optimizer.core.plan.IQueryTree; import com.taobao.tddl.optimizer.core.plan.query.IMerge; public class SqlConvertor { public SqlMergeNode convert(Map<String, String> extraCmd, IDataNodeExecutor node, boolean bindval) { SqlMergeNode sqlMergeNode = new SqlMergeNode(); Map<String/* node name */, Sqls> sqlsMap = new HashMap<String, Sqls>(); sqlMergeNode.setSubQuerys(sqlsMap); if (node instanceof IMerge) { IMerge merge = (IMerge) node; List<IDataNodeExecutor> subNodes = merge.getSubNode(); if (subNodes == null) { throw new IllegalArgumentException("should not be here"); } for (IDataNodeExecutor subNode : subNodes) { processOnenoMergeExecutor(bindval, sqlMergeNode, subNode); } fillOtherValues(sqlMergeNode, merge); } else if (node instanceof IQueryTree) { processOnenoMergeExecutor(bindval, sqlMergeNode, node); fillOtherValues(sqlMergeNode, (IQueryTree) node); } else if (node instanceof IPut) { processOnenoMergeExecutor(bindval, sqlMergeNode, node); } return sqlMergeNode; } private void fillOtherValues(SqlMergeNode sqlMergeNode, IQueryTree merge) { sqlMergeNode.setColumns(merge.getColumns()); sqlMergeNode.setGroupBys(merge.getGroupBys()); sqlMergeNode.setLimitFrom(merge.getLimitFrom()); sqlMergeNode.setLimitTo(merge.getLimitTo()); sqlMergeNode.setOrderBy(merge.getOrderBys()); } /** * 因为原则上,目前简化版本的执行树只有一个merge,所以抽一个方法公用 * * @param sqlMergeNode * @param nodeExecutor */ private void processOnenoMergeExecutor(boolean bindVal, SqlMergeNode sqlMergeNode, IDataNodeExecutor nodeExecutor) { if (nodeExecutor instanceof IMerge) { throw new IllegalStateException("sub query is merge , not supported yet ."); } if (nodeExecutor instanceof IPut) { // 写入相关 String nodeName = nodeExecutor.getDataNode(); addOneSql(bindVal, sqlMergeNode, nodeName, (IPut) nodeExecutor); } else if (nodeExecutor instanceof IQueryTree) { String nodeName = nodeExecutor.getDataNode(); // query or join addOneSql(bindVal, sqlMergeNode, nodeName, (IQueryTree) nodeExecutor); } } private void addOneSql(boolean bindVal, SqlMergeNode sqlMergeNode, String nodeName, IDataNodeExecutor oneQuery) { Map<String, Sqls> subQuerys = sqlMergeNode.getSubQuerys(); Sqls sqls = subQuerys.get(nodeName); if (sqls == null) { sqls = new Sqls(); subQuerys.put(nodeName, sqls); } if (oneQuery instanceof IQueryTree) { ((IQueryTree) oneQuery).setTopQuery(true); } MysqlPlanVisitorImpl visitor = new MysqlPlanVisitorImpl(oneQuery, null, null, true); oneQuery.accept(visitor); Sql sql = new Sql(); sql.setSql(visitor.getString()); sql.setParam(visitor.getParamMap()); sqls.add(sql); } }