use of com.actiontech.dble.route.parser.druid.RouteCalculateUnit in project dble by actiontech.
the class DQLRouteTest method test.
@Test
public void test() throws Exception {
String stmt = "select * from `offer` where id = 100";
SchemaConfig schema = schemaMap.get("mysqldb");
RouteResultset rrs = new RouteResultset(stmt, 7);
SQLStatementParser parser = null;
parser = new MySqlStatementParser(stmt);
SQLStatement statement;
ServerSchemaStatVisitor visitor = null;
try {
statement = parser.parseStatement();
visitor = new ServerSchemaStatVisitor();
} catch (Exception t) {
throw new SQLSyntaxErrorException(t);
}
ctx = new DruidShardingParseInfo();
List<RouteCalculateUnit> taskList = visitorParse(rrs, statement, visitor);
Assert.assertEquals(true, !taskList.get(0).getTablesAndConditions().isEmpty());
}
use of com.actiontech.dble.route.parser.druid.RouteCalculateUnit in project dble by actiontech.
the class DQLRouteTest method visitorParse.
@SuppressWarnings("unchecked")
private List<RouteCalculateUnit> visitorParse(RouteResultset rrs, SQLStatement stmt, ServerSchemaStatVisitor visitor) throws Exception {
stmt.accept(visitor);
List<List<Condition>> mergedConditionList = new ArrayList<List<Condition>>();
if (visitor.hasOrCondition()) {
// contains or
mergedConditionList = visitor.splitConditions();
} else {
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("`", "");
}
// remove the database of table
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);
}
Class<?> clazz = Class.forName("com.actiontech.dble.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.actiontech.dble.route.parser.druid.RouteCalculateUnit in project dble by actiontech.
the class ServerLoadDataInfileHandler method tryDirectRoute.
private RouteResultset tryDirectRoute(String strSql, String[] lineList) {
RouteResultset rrs = new RouteResultset(strSql, ServerParse.INSERT);
rrs.setLoadData(true);
if (tableConfig == null && schema.getDataNode() != null) {
// default node
RouteResultsetNode rrNode = new RouteResultsetNode(schema.getDataNode(), ServerParse.INSERT, strSql);
rrs.setNodes(new RouteResultsetNode[] { rrNode });
return rrs;
} else if (tableConfig != null && tableConfig.isGlobalTable()) {
ArrayList<String> dataNodes = tableConfig.getDataNodes();
RouteResultsetNode[] rrsNodes = new RouteResultsetNode[dataNodes.size()];
for (int i = 0, dataNodesSize = dataNodes.size(); i < dataNodesSize; i++) {
String dataNode = dataNodes.get(i);
RouteResultsetNode rrNode = new RouteResultsetNode(dataNode, ServerParse.INSERT, strSql);
rrsNodes[i] = rrNode;
}
rrs.setNodes(rrsNodes);
return rrs;
} else if (tableConfig != null) {
DruidShardingParseInfo ctx = new DruidShardingParseInfo();
ctx.addTable(tableName);
if (partitionColumnIndex == -1 || partitionColumnIndex >= lineList.length) {
return null;
} else {
String value = lineList[partitionColumnIndex];
RouteCalculateUnit routeCalculateUnit = new RouteCalculateUnit();
routeCalculateUnit.addShardingExpr(tableName, getPartitionColumn(), parseFieldString(value, loadData.getEnclose(), loadData.getEscape()));
ctx.addRouteCalculateUnit(routeCalculateUnit);
try {
SortedSet<RouteResultsetNode> nodeSet = new TreeSet<>();
for (RouteCalculateUnit unit : ctx.getRouteCalculateUnits()) {
RouteResultset rrsTmp = RouterUtil.tryRouteForTables(schema, ctx, unit, rrs, false, tableId2DataNodeCache);
if (rrsTmp != null) {
Collections.addAll(nodeSet, rrsTmp.getNodes());
}
}
RouteResultsetNode[] nodes = new RouteResultsetNode[nodeSet.size()];
int i = 0;
for (RouteResultsetNode aNodeSet : nodeSet) {
nodes[i] = aNodeSet;
i++;
}
rrs.setNodes(nodes);
return rrs;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
return null;
}
use of com.actiontech.dble.route.parser.druid.RouteCalculateUnit in project dble by actiontech.
the class DefaultDruidParser method buildRouteCalculateUnits.
private List<RouteCalculateUnit> buildRouteCalculateUnits(Map<String, String> tableAliasMap, List<List<Condition>> conditionList) {
List<RouteCalculateUnit> retList = new ArrayList<>();
// find partition column in condition
for (List<Condition> aConditionList : conditionList) {
RouteCalculateUnit routeCalculateUnit = new RouteCalculateUnit();
for (Condition condition : aConditionList) {
List<Object> values = condition.getValues();
if (values.size() == 0) {
continue;
}
if (checkConditionValues(values)) {
String columnName = StringUtil.removeBackQuote(condition.getColumn().getName().toUpperCase());
String tableName = StringUtil.removeBackQuote(condition.getColumn().getTable());
if (DbleServer.getInstance().getSystemVariables().isLowerCaseTableNames()) {
tableName = tableName.toLowerCase();
}
if (tableAliasMap != null && tableAliasMap.get(tableName) == null) {
// ignore subQuery's alias
continue;
}
if (tableAliasMap != null && tableAliasMap.get(tableName) != null && !tableAliasMap.get(tableName).equals(tableName)) {
tableName = tableAliasMap.get(tableName);
}
String operator = condition.getOperator();
// execute only between ,in and =
if (operator.equals("between")) {
RangeValue rv = new RangeValue(values.get(0), values.get(1), RangeValue.EE);
routeCalculateUnit.addShardingExpr(tableName, columnName, rv);
} else if (operator.equals("=") || operator.toLowerCase().equals("in")) {
routeCalculateUnit.addShardingExpr(tableName, columnName, values.toArray());
}
}
}
retList.add(routeCalculateUnit);
}
return retList;
}
use of com.actiontech.dble.route.parser.druid.RouteCalculateUnit in project dble by actiontech.
the class DruidSelectParser method tryRouteSingleTable.
private void tryRouteSingleTable(SchemaConfig schema, RouteResultset rrs, LayerCachePool cachePool) throws SQLException {
if (rrs.isFinishedRoute()) {
return;
}
SortedSet<RouteResultsetNode> nodeSet = new TreeSet<>();
String table = ctx.getTables().get(0);
if (RouterUtil.isNoSharding(schema, table)) {
RouterUtil.routeToSingleNode(rrs, schema.getDataNode());
return;
}
for (RouteCalculateUnit unit : ctx.getRouteCalculateUnits()) {
RouteResultset rrsTmp = RouterUtil.tryRouteForOneTable(schema, unit, table, rrs, true, cachePool);
if (rrsTmp != null && rrsTmp.getNodes() != null) {
Collections.addAll(nodeSet, rrsTmp.getNodes());
if (rrsTmp.isGlobalTable()) {
break;
}
}
}
if (nodeSet.size() == 0) {
String msg = " find no Route:" + rrs.getStatement();
LOGGER.info(msg);
throw new SQLNonTransientException(msg);
}
RouteResultsetNode[] nodes = new RouteResultsetNode[nodeSet.size()];
int i = 0;
for (RouteResultsetNode aNodeSet : nodeSet) {
nodes[i] = aNodeSet;
i++;
}
rrs.setNodes(nodes);
rrs.setFinishedRoute(true);
}
Aggregations