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);
}
}
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>
* 2-1、如果当前的条件列表 是 另外一个条件列表的 超集,更新,并标识已存在</br>
* 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;
}
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));
}
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;
}
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);
}
}
Aggregations