class RouteService implements IRouteService {

    public ExecutePlan route(List<String> tables, List<CalculateUnit> units, String sql, SqlType sqlType){
        if (logger.isDebugEnabled()){
            logger.debug("计算单元:" + PrintUtil.printCalculates(units));
        }

        // 判断是否解析到表名
        if (tables == null || tables.size() == 0){
            return buildExecutePlanTypeNo(sql, null, sqlType);
        }
        // 查找逻辑表对应的分区规则
        PartitionTable partitionTable = null;
        for (String tableName : tables){
            if (BaymaxContext.isPartitionTable(tableName)){
                if (partitionTable != null){
                    throw new BayMaxException("sql中包含了两个分区表");
                }else {
                    partitionTable = BaymaxContext.getPartitionTable(tableName);
                }
            }
        }
        // 没有规则 无需路由
        if (partitionTable == null){
            return buildExecutePlanTypeNo(sql, null, sqlType);
        }

        // 没有计算单元 全表扫描
        if (units == null || units.size() == 0){
            return buildExecutePlanTypeAll(partitionTable, sqlType);
        }

        // 路由单元计算-合并
        Set<TargetTableEntity> nodeSet = new LinkedHashSet<TargetTableEntity>();
        for (CalculateUnit unit : units) {
            List<TargetTableEntity> temp = partitionTable.execute(unit);
            if (temp == null || temp.size() == 0){
                // 这个单元没有路由结果 需要全表扫描
                return buildExecutePlanTypeAll(partitionTable, sqlType);
            }else {
                nodeSet.addAll(temp);
            }
        }

        if (nodeSet.size() == 0){
            return buildExecutePlanTypeNo(sql, partitionTable.getLogicTableName(), sqlType);
        }

        return buildExecutePlanTypePartition(partitionTable, sqlType, nodeSet);
    }

}