package com.taobao.tddl.executor.utils; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Comparator; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.taobao.tddl.common.utils.GeneralUtil; import com.taobao.tddl.common.utils.TStringUtil; import com.taobao.tddl.executor.common.IRowsValueScaner; import com.taobao.tddl.executor.common.KVPair; import com.taobao.tddl.executor.common.RowsValueScanerImp; import com.taobao.tddl.executor.cursor.ICursorMeta; import com.taobao.tddl.executor.cursor.impl.ColMetaAndIndex; import com.taobao.tddl.executor.cursor.impl.CursorMetaImp; import com.taobao.tddl.executor.record.CloneableRecord; import com.taobao.tddl.executor.record.FixedLengthRecord; import com.taobao.tddl.executor.rowset.ArrayRowSet; import com.taobao.tddl.executor.rowset.IRowSet; import com.taobao.tddl.executor.rowset.ResultSetRowSet; import com.taobao.tddl.executor.rowset.RowSetWrapper; 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.datatype.DataTypeUtil; 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.IOrderBy; import com.taobao.tddl.optimizer.core.expression.ISelectable; import com.taobao.tddl.optimizer.core.expression.bean.OrderBy; import com.taobao.tddl.optimizer.core.plan.IQueryTree; public class ExecUtils { static Pattern pattern = Pattern.compile("\\d+$"); public static void printMeta(ICursorMeta meta, int inden, StringBuilder sb) { if (meta != null) { sb.append(meta.toStringWithInden(inden)); sb.append("\n"); } } public static void printMeta(IndexMeta meta, int inden, StringBuilder sb) { if (meta != null) { sb.append(meta.toStringWithInden(inden)); sb.append("\n"); } } public static void printOrderBy(List<IOrderBy> orderBys, int inden, StringBuilder sb) { if (orderBys != null) { String tab = GeneralUtil.getTab(inden); sb.append(tab).append("order by : "); for (IOrderBy orderBy : orderBys) { sb.append(orderBy.toStringWithInden(inden + 1)).append(" "); } sb.append("\n"); } } public static KVPair rowSetTOKVPair(IRowSet rowSet, IndexMeta meta) { throw new RuntimeException("增加 IRowSet到 KVPair的实现"); } public static Date convertStringToDate(String s) { try { SimpleDateFormat dateformat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date d; d = dateformat1.parse(s); return d; } catch (ParseException e) { } try { SimpleDateFormat dateformat1 = new SimpleDateFormat("yyyy-MM-dd"); Date d; d = dateformat1.parse(s); return d; } catch (ParseException e) { } throw new RuntimeException("Date format:" + s + " is not supported"); } public static IRowSet fromIRowSetToArrayRowSet(IRowSet rsrs) { // 初衷是为了让mysql的代理换成实际数据 if (rsrs == null) { return null; } if (rsrs instanceof ResultSetRowSet) { List<Object> values = rsrs.getValues(); IRowSet rs = new ArrayRowSet(rsrs.getParentCursorMeta(), values.toArray()); return rs; } else if (rsrs instanceof RowSetWrapper) { return IRowSetWrapperToArrayRowSet((RowSetWrapper) rsrs); } else { return rsrs; } } public static Object get(ColumnMeta c, CloneableRecord r) { return r.get(c.getTableName(), c.getName()); } public static Object get(IColumn c, CloneableRecord r) { return r.get(c.getTableName(), c.getColumnName()); } public static String getColumFullName(Object column) { if (column instanceof IColumn) { IColumn col = getIColumn(column); String colName = col.getTableName() + "." + col.getColumnName(); if (col.getAlias() != null) { return colName + " as " + col.getAlias(); } else { return colName; } } else if (column instanceof IFunction && !(column instanceof IFilter)) { IFunction func = ((IFunction) column); StringBuilder sb = new StringBuilder(); sb.append(func.getFunctionName()); sb.append("("); boolean first = true; if (func.isDistinct()) { sb.append("DISTINCT "); } for (Object arg : func.getArgs()) { if (first) { first = false; } else { sb.append(","); } sb.append(getColumnName(arg)); } sb.append(")"); if (func.getAlias() != null) { sb.append(" as ").append(func.getAlias()); } return sb.toString(); } else { return String.valueOf(column); } } public static IColumn getColumn(Object column) { return getIColumn(column); } public static ColumnMeta getColumnMeta(Object o) { ISelectable c = (ISelectable) o; return new ColumnMeta(c.getTableName(), c.getColumnName(), c.getDataType(), c.getAlias(), true); } public static ColumnMeta getColumnMeta(Object o, String columnAlias) { ISelectable c = (ISelectable) o; return new ColumnMeta(c.getTableName(), columnAlias, c.getDataType(), c.getAlias(), true); } public static ColumnMeta getColumnMeta(Object o, String tableName, String columnAlias) { ISelectable c = (ISelectable) o; return new ColumnMeta(tableName, columnAlias, c.getDataType(), c.getAlias(), true); } public static ColumnMeta getColumnMetaTable(Object o, String tableName) { ISelectable c = (ISelectable) o; return new ColumnMeta(tableName, c.getColumnName(), c.getDataType(), c.getAlias(), true); } public static String getColumnName(int index, String columns) { String[] strs = columns.split(","); if (index >= strs.length) { return "error column name"; } return strs[index]; } public static String getColumnName(Object column) { if (column instanceof IColumn) { IColumn col = getIColumn(column); if (col.getAlias() != null) { return col.getAlias(); } else { return col.getColumnName(); } } else if (column instanceof IFunction) { IFunction func = ((IFunction) column); if (func.getAlias() != null) { return func.getAlias(); } else { return func.getColumnName(); } } else { return String.valueOf(column); } } public static String getColumnNameWithTableName(Object column) { if (column instanceof IColumn) { IColumn col = getIColumn(column); String colName = getRealTableName(col.getTableName()) + "." + col.getColumnName(); return colName; } else if (column instanceof IFunction) { IFunction func = ((IFunction) column); StringBuilder sb = new StringBuilder(); sb.append(func.getFunctionName()); sb.append("("); boolean first = true; if (func.isDistinct()) { sb.append("DISTINCT "); } for (Object arg : func.getArgs()) { if (first) { first = false; } else { sb.append(","); } sb.append(getColumnName(arg)); } sb.append(")"); return sb.toString(); } else { return String.valueOf(column); } } public static DataType getDataType(Object column) { if (column instanceof IColumn) { return getIColumn(column).getDataType(); } else if (column instanceof IFunction) { return ((IFunction) column).getDataType(); } else { throw new IllegalArgumentException("not support yet"); } } public static IColumn getIColumn(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; } public static String getLogicTableName(String indexName) { if (indexName == null) { return null; } int index = indexName.indexOf("."); if (index != -1) { return indexName.substring(0, index); } else { return indexName; } } 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 = new OrderBy().setColumn(column).setDirection(true); _orderBys.add(orderBy); } return _orderBys; } public static String getRealTableName(String indexName) { if (indexName == null) { return null; } if (indexName.contains(".")) { StringBuilder tableName = new StringBuilder(); String[] tmp = TStringUtil.split(indexName, "."); tableName.append(tmp[0]); Matcher matcher = pattern.matcher(tmp[1]); if (matcher.find()) { tableName.append("_").append(matcher.group()); } return tableName.toString(); } else { return indexName; } } /** * 将Wrapper实际包含的rowset中的代理去掉 * * @param rsrs * @return */ private static IRowSet IRowSetWrapperToArrayRowSet(RowSetWrapper rsrs) { if (rsrs == null) { return null; } IRowSet irs = rsrs.getParentRowSet(); if (irs instanceof ResultSetRowSet) { List<Object> values = rsrs.getValues(); IRowSet rs = new ArrayRowSet(irs.getParentCursorMeta(), values.toArray()); rsrs.setParentRowSet(rs); } else if (irs instanceof RowSetWrapper) { IRowSetWrapperToArrayRowSet((RowSetWrapper) irs); } return rsrs; } public static boolean isEqual(Object o1, Object o2) { if (o1 == o2) return true; return o1 == null ? o2.equals(o1) : o1.equals(o2); } public static Object getTargetValueByKey(KVPair kv, String name) { Object o = null; if (kv.getValue() != null) { o = kv.getValue().get(name); } if (o == null && kv.getKey() != null) { o = kv.getKey().get(name); } return o; } /** * 根据column meta取value * * @param from_kv * @param to_meta * @param icol * @return */ public static Object getValueByColumnMeta(IRowSet from_kv, ColumnMeta columnMeta) { return getValueByTableAndName(from_kv, columnMeta.getTableName(), columnMeta.getName()); } public static Object getValueByIColumn(IRowSet from_kv, ISelectable c) { if (from_kv == null) return null; Integer index = from_kv.getParentCursorMeta().getIndex(c.getTableName(), c.getColumnName()); if (index == null) return null; Object v = from_kv.getObject(index); return v; } public static Object getValueByTableAndName(IRowSet from_kv, String tableName, String columnName) { Integer index = from_kv.getParentCursorMeta().getIndex(tableName, columnName); if (index == null) { // throw new // RuntimeException(tableName+"."+columnName+" is not in "+from_kv); return null; } Object v = from_kv.getObject(index); return v; } public static List<ISelectable> getIColumnsWithISelectable(ColumnMeta[] columns) { List<ISelectable> _columns = new ArrayList<ISelectable>(columns.length); for (ColumnMeta c : columns) { IColumn ic = getIColumnsFromColumnMeta(c); _columns.add(ic); } return _columns; } public static IColumn getIColumnsFromColumnMeta(ColumnMeta c) { IColumn ic = ASTNodeFactory.getInstance().createColumn(); ic.setColumnName(c.getName()); ic.setTableName(c.getTableName()); ic.setDataType(c.getDataType()); ic.setAlias(c.getAlias()); if (ic.getDataType() == null) throw new RuntimeException("fuck!"); return ic; } public static IColumn getIColumnsFromColumnMeta(ColumnMeta c, String tableAlias) { IColumn ic = ASTNodeFactory.getInstance().createColumn(); ic.setColumnName(c.getName()); ic.setTableName(tableAlias); ic.setDataType(c.getDataType()); ic.setAlias(c.getAlias()); if (ic.getDataType() == null) throw new RuntimeException("fuck!"); return ic; } public static List<Object> getIColumnsWithISelectable(List<ColumnMeta> columns) { List<Object> _columns = new ArrayList<Object>(columns.size()); for (ColumnMeta c : columns) { IColumn ic = ASTNodeFactory.getInstance().createColumn(); ic.setColumnName(c.getName()); ic.setTableName(c.getTableName()); ic.setDataType(c.getDataType()); ic.setAlias(c.getAlias()); _columns.add(ic); // if (ic.getDataType() == null) // throw new RuntimeException("fuck!"); } return _columns; } public static List<ColumnMeta> getColumnMetas(List<ISelectable> columns) { List<ColumnMeta> _columns = new ArrayList<ColumnMeta>(columns.size()); for (ISelectable c : columns) { ColumnMeta ic = new ColumnMeta(c.getTableName(), c.getColumnName(), c.getDataType(), c.getAlias(), true); _columns.add(ic); } return _columns; } public static List<ColumnMeta> getColumnMetaWithLogicTables(List<ISelectable> columns) { List<ColumnMeta> _columns = new ArrayList<ColumnMeta>(columns.size()); for (ISelectable c : columns) { ColumnMeta ic = new ColumnMeta(getLogicTableName(c.getTableName()), c.getColumnName(), c.getDataType(), c.getAlias(), true); _columns.add(ic); // if (ic.getDataType() == null) // throw new RuntimeException("fuck!"); } return _columns; } public static List<ColumnMeta> getColumnMetaWithLogicTablesFromOrderBys(List<IOrderBy> columns) { List<ColumnMeta> _columns = new ArrayList<ColumnMeta>(columns.size()); for (IOrderBy c : columns) { ColumnMeta ic = new ColumnMeta(getLogicTableName(c.getTableName()), c.getColumnName(), c.getDataType(), c.getAlias(), true); _columns.add(ic); } return _columns; } public static String getAggColumnName(String columnName, String agg) { // 要把函数名前的merge去掉 // MERGECOUNT变成COUNT return (agg + "(" + columnName + ")").replace("MERGE", ""); } public static List<ColumnMeta> convertIColumnsToColumnMeta(List<Object> targetCOlumn) { List<ColumnMeta> colMetas = new ArrayList<ColumnMeta>(targetCOlumn.size()); for (Object icolObj : targetCOlumn) { colMetas.add(getColumnMeta(icolObj)); } return colMetas; } public static List<IColumn> convertColumnMetaToIColumn(List<ColumnMeta> targetCOlumn) { List<IColumn> icolumns = new ArrayList<IColumn>(targetCOlumn.size()); for (ColumnMeta cm : targetCOlumn) { IColumn c = ASTNodeFactory.getInstance().createColumn(); c.setDataType(cm.getDataType()); c.setColumnName(cm.getName()); c.setTableName(cm.getTableName()); c.setAlias(cm.getAlias()); icolumns.add(c); } return icolumns; } public static List<ColumnMeta> convertISelectablesToColumnMeta(List<ISelectable> targetCOlumn) { List<ColumnMeta> colMetas = new ArrayList<ColumnMeta>(targetCOlumn.size()); for (ISelectable icolObj : targetCOlumn) { colMetas.add(getColumnMeta(icolObj)); } return colMetas; } public static List<ColumnMeta> convertISelectablesToColumnMeta(List<ISelectable> columns, String tableAlias, Boolean isSubQuery) { List<ColumnMeta> colMetas = new ArrayList<ColumnMeta>(columns.size()); for (ISelectable c : columns) { // if (c instanceof IFunction && !isSubQuery) { // colMetas.add(new ColumnMeta(null , c.getAlias() == null ? c // .getColumnName() : c.getAlias(), c.getDataType(), c // .getAlias())); // } else { IFunction 没有table名,columnMeta里要有 colMetas.add(new ColumnMeta(tableAlias == null ? c.getTableName() : tableAlias, c.getAlias() == null ? c.getColumnName() : c.getAlias(), c.getDataType(), c.getAlias(), true)); // } } return colMetas; } /** * 根据order by 条件,从left和right KVPair里面拿到一个列所对应的值(从key或者从value里面) 然后进行比较。 * 相等则继续比较其他。 不相等则根据asc desc决定大小。 * * @param orderBys * @return */ public static Comparator<IRowSet> getComp(final List<IOrderBy> orderBys, final ICursorMeta meta) { return new Comparator<IRowSet>() { public IRowsValueScaner leftScaner; public IRowsValueScaner rightScaner; public List<ISelectable> cols; { cols = new ArrayList<ISelectable>(); for (IOrderBy ord : orderBys) { cols.add(ord.getColumn()); } leftScaner = new RowsValueScanerImp(meta, cols); } @Override public int compare(IRowSet o1, IRowSet o2) { if (rightScaner == null) { ICursorMeta rightCursorMeta = o2.getParentCursorMeta(); rightScaner = new RowsValueScanerImp(rightCursorMeta, cols); } Iterator<Object> leftIter = leftScaner.rowValueIterator(o1); Iterator<Object> rightIter = rightScaner.rowValueIterator(o2); for (IOrderBy orderBy : orderBys) { Comparable c1 = (Comparable) leftIter.next(); Comparable c2 = (Comparable) rightIter.next(); if (c1 == null && c2 == null) { continue; } int n = comp(c1, c2, orderBy); if (n == 0) continue; return n; } return 0; } }; } public static Comparator<IRowSet> getComp(final List<ISelectable> left_columns, final List<ISelectable> right_columns, final ICursorMeta leftMeta, final ICursorMeta rightMeta) { return new Comparator<IRowSet>() { public IRowsValueScaner leftScaner = new RowsValueScanerImp(leftMeta, left_columns); public IRowsValueScaner rightScaner = new RowsValueScanerImp(rightMeta, right_columns); /* * 沈洵 * 这个代码与com.taobao.ustore.spi.cursor.common.SortCursor.getComp(List * <IOrderBy> orderBys) * 唯一的不同,也只有compare的时候需要两个列的list,并且没有asc和desc条件。其他逻辑类似。 */ @Override public int compare(IRowSet o1, IRowSet o2) { Iterator<Object> leftIter = leftScaner.rowValueIterator(o1); Iterator<Object> rightIter = rightScaner.rowValueIterator(o2); for (int i = 0; i < left_columns.size(); i++) { Comparable c1 = (Comparable) leftIter.next(); Comparable c2 = (Comparable) rightIter.next(); int n = comp(c1, c2, left_columns.get(i).getDataType(), right_columns.get(i).getDataType()); if (n != 0) { return n; } } return 0; } }; } public static int comp(Object c1, Object c2, DataType type1, DataType type2) { if (type1 == null) { type1 = DataTypeUtil.getTypeOfObject(c1); } // 类型相同,直接比较 if (type1 == type2) { return type1.compare(c1, c2); } // 类型不同,先进行类型转换 c2 = type1.convertFrom(c2); return type1.compare(c1, c2); } public static int comp(Comparable c1, Comparable c2, IOrderBy order) { DataType type = order.getColumn().getDataType(); if (type == null) { type = DataTypeUtil.getTypeOfObject(c1); } int n = type.compare(c1, c2); if (n == 0) { return n; } boolean isAsc = order.getDirection(); if (isAsc) { return n; } else { return n < 0 ? 1 : -1; } } public static List<IOrderBy> copyOrderBys(List<IOrderBy> orders) { if (orders == null) return null; List<IOrderBy> news = new ArrayList(orders.size()); for (IOrderBy c : orders) { news.add(c.copy()); } return news; } public static CloneableRecord convertToClonableRecord(IRowSet iRowSet) { Iterator<ColMetaAndIndex> columnIterator = iRowSet.getParentCursorMeta().indexIterator(); CloneableRecord cr = new FixedLengthRecord(iRowSet.getParentCursorMeta().getColumns()); while (columnIterator.hasNext()) { ColMetaAndIndex cmAndIndex = columnIterator.next(); cr.put(cmAndIndex.getName(), iRowSet.getObject(cmAndIndex.getIndex())); } return cr; } public static ICursorMeta convertToICursorMeta(IQueryTree query) { if (query.getSql() != null) { return null; } ICursorMeta iCursorMeta = null; List<ColumnMeta> columns = convertISelectablesToColumnMeta(query.getColumns(), query.getAlias(), query.isSubQuery()); iCursorMeta = CursorMetaImp.buildNew(columns, columns.size()); return iCursorMeta; } public static ICursorMeta convertToICursorMeta(IndexMeta meta) { ICursorMeta iCursorMeta = null; List<ColumnMeta> columns = new ArrayList<ColumnMeta>(); List<ColumnMeta> columnMeta = meta.getKeyColumns(); addNewColumnMeta(columnMeta, columns); columnMeta = meta.getValueColumns(); addNewColumnMeta(columnMeta, columns); iCursorMeta = CursorMetaImp.buildNew(columns, columns.size()); return iCursorMeta; } private static void addNewColumnMeta(List<ColumnMeta> columnMeta, List<ColumnMeta> columns) { for (ColumnMeta cm : columnMeta) { ColumnMeta cmNew = new ColumnMeta(getLogicTableName(cm.getTableName()), cm.getName(), cm.getDataType(), cm.getAlias(), cm.isNullable()); columns.add(cmNew); } } public static Object getObject(final ICursorMeta meta, IRowSet rowSet, String tableName, String columnName) { Integer index = meta.getIndex(tableName, columnName); if (index == null) { throw new RuntimeException("在meta中没找到该列:" + tableName + "." + columnName + " ICursorMeta:" + meta); } return rowSet.getObject(index); } 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; } }