package com.taobao.tddl.optimizer.utils; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import com.taobao.tddl.common.jdbc.ParameterContext; import com.taobao.tddl.common.utils.TStringUtil; import com.taobao.tddl.optimizer.config.table.ColumnMeta; import com.taobao.tddl.optimizer.config.table.IndexMeta; import com.taobao.tddl.optimizer.core.ASTNodeFactory; import com.taobao.tddl.optimizer.core.datatype.DataType; import com.taobao.tddl.optimizer.core.expression.IBooleanFilter; import com.taobao.tddl.optimizer.core.expression.IColumn; import com.taobao.tddl.optimizer.core.expression.IFilter; import com.taobao.tddl.optimizer.core.expression.IFunction; import com.taobao.tddl.optimizer.core.expression.ILogicalFilter; import com.taobao.tddl.optimizer.core.expression.IOrderBy; import com.taobao.tddl.optimizer.core.expression.ISelectable; import com.taobao.tddl.optimizer.core.expression.bean.BindVal; import com.taobao.tddl.optimizer.core.expression.bean.NullValue; import com.taobao.tddl.optimizer.parse.cobar.visitor.MySqlExprVisitor; /** * @since 5.0.0 */ public class OptimizerUtils { public static Object convertType(Object value, DataType type) { if (value == null) { return null; } if (type == null || value instanceof BindVal || value instanceof IFunction || value instanceof NullValue) { return value; } return type.convertFrom(value); } public static IFilter copyFilter(IFilter f) { return (IFilter) (f == null ? null : f.copy()); } public static Set<ISelectable> copySelectables(Set<ISelectable> cs) { if (cs == null) { return null; } Set<ISelectable> news = new HashSet(cs.size()); for (ISelectable c : cs) { news.add(c.copy()); } return news; } public static List<ISelectable> copySelectables(List<ISelectable> cs) { if (cs == null) { return null; } List<ISelectable> news = new ArrayList(cs.size()); for (ISelectable c : cs) { news.add(c.copy()); } return news; } public static List<IBooleanFilter> copyFilter(List<IBooleanFilter> filters) { if (filters == null) { return null; } List<IBooleanFilter> newFilters = new ArrayList<IBooleanFilter>(filters.size()); for (IBooleanFilter f : filters) { newFilters.add(f.copy()); } return newFilters; } public static List<IOrderBy> copyOrderBys(List<IOrderBy> orders) { if (orders == null) { return null; } List<IOrderBy> newOrders = new ArrayList<IOrderBy>(orders.size()); for (IOrderBy o : orders) { newOrders.add(o.copy()); } return newOrders; } public static List<ISelectable> copySelectables(List<ISelectable> selects, String tableName) { if (tableName == null) { return copySelectables(selects); } if (selects == null) { return null; } List<ISelectable> news = new ArrayList(selects.size()); for (ISelectable s : selects) { ISelectable a = s.copy(); if (a instanceof IColumn) { setColumn((IColumn) a, tableName); } else if (a instanceof IFilter) { setFilter((IFilter) a, tableName); } else if (a instanceof IFunction) { setFunction((IFunction) a, tableName); } news.add(a); } return news; } public static List<IOrderBy> copyOrderBys(List<IOrderBy> orderBys, String tableName) { if (tableName == null) { return copyOrderBys(orderBys); } if (orderBys == null) { return null; } List<IOrderBy> news = new ArrayList(orderBys.size()); for (IOrderBy o : orderBys) { IOrderBy a = o.copy(); if (a.getColumn() instanceof IColumn) { setColumn((IColumn) a.getColumn(), tableName); } else if (a.getColumn() instanceof IFilter) { setFilter((IFilter) a.getColumn(), tableName); } else if (a.getColumn() instanceof IFunction) { setFunction((IFunction) a.getColumn(), tableName); } news.add(a); } return news; } public static IFilter copyFilter(IFilter filter, String tableName) { if (filter == null) { return null; } IFilter newFilter = (IFilter) filter.copy(); if (tableName != null) { setFilter(newFilter, tableName); } return newFilter; } private static void setFunction(IFunction f, String tableName) { for (Object arg : f.getArgs()) { if (arg instanceof ISelectable) { if (arg instanceof IColumn) { setColumn((IColumn) arg, tableName); } else if (arg instanceof IFilter) { setFilter((IFilter) arg, tableName); } else if (arg instanceof IFunction) { setFunction((IFunction) arg, tableName); } } } } private static void setFilter(IFilter f, String tableName) { if (f instanceof IBooleanFilter) { Object column = ((IBooleanFilter) f).getColumn(); if (column instanceof IColumn) { setColumn((IColumn) column, tableName); } else if (column instanceof IFilter) { setFilter((IFilter) column, tableName); } else if (column instanceof IFunction) { setFunction((IFunction) column, tableName); } Object value = ((IBooleanFilter) f).getValue(); if (value instanceof IColumn) { setColumn((IColumn) value, tableName); } else if (value instanceof IFilter) { setFilter((IFilter) value, tableName); } else if (value instanceof IFunction) { setFunction((IFunction) value, tableName); } } else if (f instanceof ILogicalFilter) { for (IFilter sf : ((ILogicalFilter) f).getSubFilter()) { setFilter(sf, tableName); } } } private static void setColumn(IColumn c, String tableName) { if (tableName != null && c.getTableName() != null) { c.setTableName(tableName); } } /** * 根据索引信息,构建orderby条件 */ public static List<IOrderBy> getOrderBy(IndexMeta meta) { if (meta == null) { return new ArrayList<IOrderBy>(0); } List<IOrderBy> _orderBys = new ArrayList<IOrderBy>(); for (ColumnMeta c : meta.getKeyColumns()) { IColumn column = ASTNodeFactory.getInstance().createColumn(); column.setTableName(c.getTableName()) .setColumnName(c.getName()) .setDataType(c.getDataType()) .setAlias(c.getAlias()); IOrderBy orderBy = ASTNodeFactory.getInstance().createOrderBy().setColumn(column).setDirection(true); _orderBys.add(orderBy); } return _orderBys; } /** * 根据column string构造{@linkplain ISelectable}对象 * * @param columnStr * @return */ public static ISelectable createColumnFromString(String columnStr) { if (columnStr == null) { return null; } // 别名只能单独处理 if (TStringUtil.containsIgnoreCase(columnStr, " AS ")) { String tmp[] = TStringUtil.splitByWholeSeparator(columnStr, " AS "); if (tmp.length != 2) { throw new RuntimeException("createColumnFromString:" + columnStr); } ISelectable c = createColumnFromString(tmp[0].trim()); c.setAlias(tmp[1].trim()); return c; } else { MySqlExprVisitor visitor = MySqlExprVisitor.parser(columnStr); Comparable value = MySqlExprVisitor.parser(columnStr).getColumnOrValue(); if (value instanceof ISelectable) { return (ISelectable) value; } else if (value instanceof IFilter) { return (IFilter) value; } else { // 可能是常量 return visitor.buildConstanctFilter(value); } } } public static IColumn columnMetaToIColumn(ColumnMeta m, String tableName) { IColumn c = ASTNodeFactory.getInstance().createColumn(); c.setDataType(m.getDataType()); c.setColumnName(m.getName()); c.setTableName(tableName); c.setAlias(m.getAlias()); return c; } public static IColumn columnMetaToIColumn(ColumnMeta m) { IColumn c = ASTNodeFactory.getInstance().createColumn(); c.setDataType(m.getDataType()); c.setColumnName(m.getName()); c.setTableName(m.getTableName()); c.setAlias(m.getAlias()); return c; } public static IColumn getColumn(Object column) { if (column instanceof IFunction) { return ASTNodeFactory.getInstance() .createColumn() .setTableName(((IFunction) column).getTableName()) .setColumnName(((IFunction) column).getColumnName()) .setAlias(((IFunction) column).getAlias()) .setDataType(((IFunction) column).getDataType()); } else if (!(column instanceof IColumn)) { throw new IllegalArgumentException("column :" + column + " is not a icolumn"); } return (IColumn) column; } /** * 将columnMeta转化为column列 */ public static List<ISelectable> columnMetaListToIColumnList(Collection<ColumnMeta> ms, String tableName) { List<ISelectable> cs = new ArrayList(ms.size()); for (ColumnMeta m : ms) { cs.add(columnMetaToIColumn(m, tableName)); } return cs; } public static List<ISelectable> columnMetaListToIColumnList(Collection<ColumnMeta> ms) { List<ISelectable> cs = new ArrayList(ms.size()); for (ColumnMeta m : ms) { cs.add(columnMetaToIColumn(m)); } return cs; } // --------------------------- assignment -------------------------- public static IFilter assignment(IFilter f, Map<Integer, ParameterContext> parameterSettings) { if (f == null) { return null; } return (IFilter) f.assignment(parameterSettings); } public static ISelectable assignment(ISelectable c, Map<Integer, ParameterContext> parameterSettings) { if (c == null) { return c; } return c.assignment(parameterSettings); } public static List<ISelectable> assignment(List<ISelectable> cs, Map<Integer, ParameterContext> parameterSettings) { if (cs == null) { return cs; } for (ISelectable s : cs) { assignment(s, parameterSettings); } return cs; } }