use of com.alibaba.druid.stat.TableStat.Condition in project Mycat-Server by MyCATApache.
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-Server by MyCATApache.
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-Server by MyCATApache.
the class MycatSchemaStatVisitorTest method getConditionList.
private List<List<Condition>> getConditionList(String sql) {
SQLStatementParser parser = null;
parser = new MySqlStatementParser(sql);
MycatSchemaStatVisitor visitor = null;
SQLStatement statement = null;
// 解析出现问题统一抛SQL语法错误
try {
statement = parser.parseStatement();
visitor = new MycatSchemaStatVisitor();
} catch (Exception e) {
e.printStackTrace();
}
statement.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());
}
return mergedConditionList;
}
Aggregations