Search in sources :

Example 16 with Condition

use of com.alibaba.druid.stat.TableStat.Condition in project Mycat_plus by coderczp.

the class MycatSchemaStatVisitor method getConditionsFromWhereUnit.

private void getConditionsFromWhereUnit(WhereUnit whereUnit) {
    List<List<Condition>> retList = new ArrayList<List<Condition>>();
    // or语句外层的条件:如where condition1 and (condition2 or condition3),condition1就会在外层条件中,因为之前提取
    List<Condition> outSideCondition = new ArrayList<Condition>();
    // stashOutSideConditions();
    outSideCondition.addAll(conditions);
    this.conditions.clear();
    for (SQLExpr sqlExpr : whereUnit.getSplitedExprList()) {
        sqlExpr.accept(this);
        // List<Condition> conditions = new ArrayList<Condition>();
        // conditions.addAll(getConditions()); conditions.addAll(outSideCondition);
        /**
         * 合并两个条件列表的元素为一个条件列表,减少不必要多的条件项</br>
         *
         * @author SvenAugustus
         */
        List<Condition> conditions = mergeSqlConditionList(getConditions(), outSideCondition);
        retList.add(conditions);
        this.conditions.clear();
    }
    whereUnit.setConditionList(retList);
    for (WhereUnit subWhere : whereUnit.getSubWhereUnit()) {
        getConditionsFromWhereUnit(subWhere);
    }
}
Also used : Condition(com.alibaba.druid.stat.TableStat.Condition) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr)

Example 17 with Condition

use of com.alibaba.druid.stat.TableStat.Condition in project Mycat_plus by coderczp.

the class MycatSchemaStatVisitor method merge.

/**
 * 两个list中的条件组合
 * @param list1
 * @param list2
 * @return
 */
private List<List<Condition>> merge(List<List<Condition>> list1, List<List<Condition>> list2) {
    if (list1.size() == 0) {
        return list2;
    } else if (list2.size() == 0) {
        return list1;
    }
    List<List<Condition>> retList = new ArrayList<List<Condition>>();
    for (int i = 0; i < list1.size(); i++) {
        for (int j = 0; j < list2.size(); j++) {
            // List<Condition> listTmp = new ArrayList<Condition>();
            // listTmp.addAll(list1.get(i));
            // listTmp.addAll(list2.get(j));
            // retList.add(listTmp);
            /**
             * 单纯做笛卡尔积运算,会导致非常多不必要的条件列表,</br>
             * 当whereUnit和条件相对多时,会急剧增长条件列表项,内存直线上升,导致假死状态</br>
             * 因此,修改算法为 </br>
             * 1、先合并两个条件列表的元素为一个条件列表</br>
             * 2、计算合并后的条件列表,在结果retList中:</br>
             * &nbsp;2-1、如果当前的条件列表 是 另外一个条件列表的 超集,更新,并标识已存在</br>
             * &nbsp;2-2、如果当前的条件列表 是 另外一个条件列表的 子集,标识已存在</br>
             * 3、最后,如果被标识不存在,加入结果retList,否则丢弃。</br>
             *
             * @author SvenAugustus
             */
            // 合并两个条件列表的元素为一个条件列表
            List<Condition> listTmp = mergeSqlConditionList(list1.get(i), list2.get(j));
            // 判定当前的条件列表 是否 另外一个条件列表的 子集
            boolean exists = false;
            Iterator<List<Condition>> it = retList.iterator();
            while (it.hasNext()) {
                List<Condition> result = (List<Condition>) it.next();
                if (result != null && listTmp != null && listTmp.size() > result.size()) {
                    // 如果当前的条件列表 是 另外一个条件列表的 超集,更新,并标识已存在
                    if (sqlConditionListInOther(result, listTmp)) {
                        result.clear();
                        result.addAll(listTmp);
                        exists = true;
                        break;
                    }
                } else {
                    // 如果当前的条件列表 是 另外一个条件列表的 子集,标识已存在
                    if (sqlConditionListInOther(listTmp, result)) {
                        exists = true;
                        break;
                    }
                }
            }
            if (!exists) {
                // 被标识不存在,加入
                retList.add(listTmp);
            }
        // 否则丢弃
        }
    }
    return retList;
}
Also used : Condition(com.alibaba.druid.stat.TableStat.Condition) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) SQLCommentHint(com.alibaba.druid.sql.ast.SQLCommentHint)

Example 18 with Condition

use of com.alibaba.druid.stat.TableStat.Condition in project Mycat_plus by coderczp.

the class DefaultDruidParser method visitorParse.

/**
 * 子类可覆盖(如果该方法解析得不到表名、字段等信息的,就覆盖该方法,覆盖成空方法,然后通过statementPparse去解析)
 * 通过visitor解析:有些类型的Statement通过visitor解析得不到表名、
 * @param stmt
 */
@Override
public void visitorParse(RouteResultset rrs, SQLStatement stmt, MycatSchemaStatVisitor visitor) throws SQLNonTransientException {
    stmt.accept(visitor);
    ctx.setVisitor(visitor);
    if (stmt instanceof SQLSelectStatement) {
        SQLSelectQuery query = ((SQLSelectStatement) stmt).getSelect().getQuery();
        if (query instanceof MySqlSelectQueryBlock) {
            if (((MySqlSelectQueryBlock) query).isForUpdate()) {
                rrs.setSelectForUpdate(true);
            }
        }
    }
    List<List<Condition>> mergedConditionList = new ArrayList<List<Condition>>();
    if (visitor.hasOrCondition()) {
        // 包含or语句
        // TODO
        // 根据or拆分
        mergedConditionList = visitor.splitConditions();
    } else {
        // 不包含OR语句
        mergedConditionList.add(visitor.getConditions());
    }
    if (visitor.isHasChange()) {
        // 在解析的过程中子查询被改写了.需要更新ctx.
        ctx.setSql(stmt.toString());
        rrs.setStatement(ctx.getSql());
    }
    if (visitor.getAliasMap() != null) {
        for (Map.Entry<String, String> entry : visitor.getAliasMap().entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (key != null && key.indexOf("`") >= 0) {
                key = key.replaceAll("`", "");
            }
            if (value != null && value.indexOf("`") >= 0) {
                value = value.replaceAll("`", "");
            }
            // 表名前面带database的,去掉
            if (key != null) {
                int pos = key.indexOf(".");
                if (pos > 0) {
                    key = key.substring(pos + 1);
                }
                tableAliasMap.put(key.toUpperCase(), value);
            }
        // else {
        // tableAliasMap.put(key, value);
        // }
        }
        ctx.addTables(visitor.getTables());
        visitor.getAliasMap().putAll(tableAliasMap);
        ctx.setTableAliasMap(tableAliasMap);
    }
    ctx.setRouteCalculateUnits(this.buildRouteCalculateUnits(visitor, mergedConditionList));
}
Also used : Condition(com.alibaba.druid.stat.TableStat.Condition) SQLSelectQuery(com.alibaba.druid.sql.ast.statement.SQLSelectQuery) ArrayList(java.util.ArrayList) SQLSelectStatement(com.alibaba.druid.sql.ast.statement.SQLSelectStatement) ArrayList(java.util.ArrayList) List(java.util.List) MySqlSelectQueryBlock(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock) HashMap(java.util.HashMap) Map(java.util.Map)

Example 19 with Condition

use of com.alibaba.druid.stat.TableStat.Condition in project Mycat_plus by coderczp.

the class DQLRouteTest method visitorParse.

@SuppressWarnings("unchecked")
private List<RouteCalculateUnit> visitorParse(RouteResultset rrs, SQLStatement stmt, MycatSchemaStatVisitor visitor) throws Exception {
    stmt.accept(visitor);
    List<List<Condition>> mergedConditionList = new ArrayList<List<Condition>>();
    if (visitor.hasOrCondition()) {
        // 包含or语句
        // TODO
        // 根据or拆分
        mergedConditionList = visitor.splitConditions();
    } else {
        // 不包含OR语句
        mergedConditionList.add(visitor.getConditions());
    }
    if (visitor.getAliasMap() != null) {
        for (Map.Entry<String, String> entry : visitor.getAliasMap().entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (key != null && key.indexOf("`") >= 0) {
                key = key.replaceAll("`", "");
            }
            if (value != null && value.indexOf("`") >= 0) {
                value = value.replaceAll("`", "");
            }
            // 表名前面带database的,去掉
            if (key != null) {
                int pos = key.indexOf(".");
                if (pos > 0) {
                    key = key.substring(pos + 1);
                }
            }
            if (key.equals(value)) {
                ctx.addTable(key.toUpperCase());
            }
            // else {
            // tableAliasMap.put(key, value);
            // }
            tableAliasMap.put(key.toUpperCase(), value);
        }
        visitor.getAliasMap().putAll(tableAliasMap);
        ctx.setTableAliasMap(tableAliasMap);
    }
    // 利用反射机制单元测试DefaultDruidParser类的私有方法buildRouteCalculateUnits
    Class<?> clazz = Class.forName("io.mycat.route.parser.druid.impl.DefaultDruidParser");
    Method buildRouteCalculateUnits = clazz.getDeclaredMethod("buildRouteCalculateUnits", new Class[] { SchemaStatVisitor.class, List.class });
    // System.out.println("buildRouteCalculateUnits:\t" + buildRouteCalculateUnits);
    Object newInstance = clazz.newInstance();
    buildRouteCalculateUnits.setAccessible(true);
    Object returnValue = buildRouteCalculateUnits.invoke(newInstance, new Object[] { visitor, mergedConditionList });
    List<RouteCalculateUnit> retList = new ArrayList<RouteCalculateUnit>();
    if (returnValue instanceof ArrayList<?>) {
        retList.add(((ArrayList<RouteCalculateUnit>) returnValue).get(0));
    // retList = (ArrayList<RouteCalculateUnit>)returnValue;
    // System.out.println(taskList.get(0).getTablesAndConditions().values());
    }
    return retList;
}
Also used : Condition(com.alibaba.druid.stat.TableStat.Condition) RouteCalculateUnit(io.mycat.route.parser.druid.RouteCalculateUnit) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map)

Example 20 with Condition

use of com.alibaba.druid.stat.TableStat.Condition in project dble by actiontech.

the class ServerSchemaStatVisitor method getConditionsFromWhereUnit.

private void getConditionsFromWhereUnit(WhereUnit whereUnit) {
    List<List<Condition>> retList = new ArrayList<>();
    List<Condition> outSideCondition = new ArrayList<>();
    outSideCondition.addAll(conditions);
    this.conditions.clear();
    for (SQLExpr sqlExpr : whereUnit.getSplitedExprList()) {
        sqlExpr.accept(this);
        List<Condition> conditions = new ArrayList<>();
        conditions.addAll(getConditions());
        conditions.addAll(outSideCondition);
        retList.add(conditions);
        this.conditions.clear();
    }
    whereUnit.setConditionList(retList);
    for (WhereUnit subWhere : whereUnit.getSubWhereUnit()) {
        getConditionsFromWhereUnit(subWhere);
    }
}
Also used : Condition(com.alibaba.druid.stat.TableStat.Condition) ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr)

Aggregations

Condition (com.alibaba.druid.stat.TableStat.Condition)28 ArrayList (java.util.ArrayList)22 List (java.util.List)16 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)9 Column (com.alibaba.druid.stat.TableStat.Column)7 SQLCommentHint (com.alibaba.druid.sql.ast.SQLCommentHint)6 SQLStatement (com.alibaba.druid.sql.ast.SQLStatement)6 HashMap (java.util.HashMap)5 Map (java.util.Map)5 SQLExpr (com.alibaba.druid.sql.ast.SQLExpr)4 RouteCalculateUnit (io.mycat.route.parser.druid.RouteCalculateUnit)4 MySqlStatementParser (com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser)3 SQLStatementParser (com.alibaba.druid.sql.parser.SQLStatementParser)3 Method (java.lang.reflect.Method)3 RouteCalculateUnit (com.actiontech.dble.route.parser.druid.RouteCalculateUnit)2 SQLObject (com.alibaba.druid.sql.ast.SQLObject)2 SQLCharExpr (com.alibaba.druid.sql.ast.expr.SQLCharExpr)2 SQLSelectQuery (com.alibaba.druid.sql.ast.statement.SQLSelectQuery)2 SQLSelectStatement (com.alibaba.druid.sql.ast.statement.SQLSelectStatement)2 MySqlSelectQueryBlock (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock)2