use of io.mycat.route.parser.druid.DruidShardingParseInfo in project Mycat-Server by MyCATApache.
the class DruidMycatRouteStrategy method routeNormalSqlWithAST.
@Override
public RouteResultset routeNormalSqlWithAST(SchemaConfig schema, String stmt, RouteResultset rrs, String charset, LayerCachePool cachePool) throws SQLNonTransientException {
/**
* 只有mysql时只支持mysql语法
*/
SQLStatementParser parser = null;
if (schema.isNeedSupportMultiDBType()) {
parser = new MycatStatementParser(stmt);
} else {
parser = new MySqlStatementParser(stmt);
}
MycatSchemaStatVisitor visitor = null;
SQLStatement statement;
/**
* 解析出现问题统一抛SQL语法错误
*/
try {
statement = parser.parseStatement();
visitor = new MycatSchemaStatVisitor();
} catch (Exception t) {
LOGGER.error("DruidMycatRouteStrategyError", t);
throw new SQLSyntaxErrorException(t);
}
/**
* 检验unsupported statement
*/
checkUnSupportedStatement(statement);
DruidParser druidParser = DruidParserFactory.create(schema, statement, visitor);
druidParser.parser(schema, rrs, statement, stmt, cachePool, visitor);
DruidShardingParseInfo ctx = druidParser.getCtx();
rrs.setTables(ctx.getTables());
/**
* DruidParser 解析过程中已完成了路由的直接返回
*/
if (rrs.isFinishedRoute()) {
return rrs;
}
/**
* 没有from的select语句或其他
*/
if ((ctx.getTables() == null || ctx.getTables().size() == 0) && (ctx.getTableAliasMap() == null || ctx.getTableAliasMap().isEmpty())) {
return RouterUtil.routeToSingleNode(rrs, schema.getRandomDataNode(), druidParser.getCtx().getSql());
}
if (druidParser.getCtx().getRouteCalculateUnits().size() == 0) {
RouteCalculateUnit routeCalculateUnit = new RouteCalculateUnit();
druidParser.getCtx().addRouteCalculateUnit(routeCalculateUnit);
}
SortedSet<RouteResultsetNode> nodeSet = new TreeSet<RouteResultsetNode>();
for (RouteCalculateUnit unit : druidParser.getCtx().getRouteCalculateUnits()) {
RouteResultset rrsTmp = RouterUtil.tryRouteForTables(schema, druidParser.getCtx(), unit, rrs, isSelect(statement), cachePool);
if (rrsTmp != null) {
for (RouteResultsetNode node : rrsTmp.getNodes()) {
nodeSet.add(node);
}
}
}
RouteResultsetNode[] nodes = new RouteResultsetNode[nodeSet.size()];
int i = 0;
for (RouteResultsetNode aNodeSet : nodeSet) {
nodes[i] = aNodeSet;
if (statement instanceof MySqlInsertStatement && ctx.getTables().size() == 1 && schema.getTables().containsKey(ctx.getTables().get(0))) {
RuleConfig rule = schema.getTables().get(ctx.getTables().get(0)).getRule();
if (rule != null && rule.getRuleAlgorithm() instanceof SlotFunction) {
aNodeSet.setStatement(ParseUtil.changeInsertAddSlot(aNodeSet.getStatement(), aNodeSet.getSlot()));
}
}
i++;
}
rrs.setNodes(nodes);
/**
* subTables="t_order$1-2,t_order3"
*目前分表 1.6 开始支持 幵丏 dataNode 在分表条件下只能配置一个,分表条件下不支持join。
*/
if (rrs.isDistTable()) {
return this.routeDisTable(statement, rrs);
}
return rrs;
}
use of io.mycat.route.parser.druid.DruidShardingParseInfo in project Mycat-Server by MyCATApache.
the class DefaultDruidParser method parser.
/**
* 使用MycatSchemaStatVisitor解析,得到tables、tableAliasMap、conditions等
* @param schema
* @param stmt
*/
public void parser(SchemaConfig schema, RouteResultset rrs, SQLStatement stmt, String originSql, LayerCachePool cachePool, MycatSchemaStatVisitor schemaStatVisitor) throws SQLNonTransientException {
ctx = new DruidShardingParseInfo();
//设置为原始sql,如果有需要改写sql的,可以通过修改SQLStatement中的属性,然后调用SQLStatement.toString()得到改写的sql
ctx.setSql(originSql);
//通过visitor解析
visitorParse(rrs, stmt, schemaStatVisitor);
//通过Statement解析
statementParse(schema, rrs, stmt);
//改写sql:如insert语句主键自增长的可以
changeSql(schema, rrs, stmt, cachePool);
}
use of io.mycat.route.parser.druid.DruidShardingParseInfo in project Mycat-Server by MyCATApache.
the class ServerLoadDataInfileHandler method tryDirectRoute.
private RouteResultset tryDirectRoute(String sql, String[] lineList) {
RouteResultset rrs = new RouteResultset(sql, ServerParse.INSERT);
rrs.setLoadData(true);
if (tableConfig == null && schema.getDataNode() != null) {
//走默认节点
RouteResultsetNode rrNode = new RouteResultsetNode(schema.getDataNode(), ServerParse.INSERT, sql);
rrNode.setSource(rrs);
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, sql);
rrsNodes[i] = rrNode;
if (rrs.getDataNodeSlotMap().containsKey(dataNode)) {
rrsNodes[i].setSlot(rrs.getDataNodeSlotMap().get(dataNode));
}
rrsNodes[i].setSource(rrs);
}
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()));
ctx.addRouteCalculateUnit(routeCalculateUnit);
try {
SortedSet<RouteResultsetNode> nodeSet = new TreeSet<RouteResultsetNode>();
for (RouteCalculateUnit unit : ctx.getRouteCalculateUnits()) {
RouteResultset rrsTmp = RouterUtil.tryRouteForTables(schema, ctx, unit, rrs, false, tableId2DataNodeCache);
if (rrsTmp != null) {
for (RouteResultsetNode node : rrsTmp.getNodes()) {
nodeSet.add(node);
}
}
}
RouteResultsetNode[] nodes = new RouteResultsetNode[nodeSet.size()];
int i = 0;
for (Iterator<RouteResultsetNode> iterator = nodeSet.iterator(); iterator.hasNext(); ) {
nodes[i] = (RouteResultsetNode) iterator.next();
i++;
}
rrs.setNodes(nodes);
return rrs;
} catch (SQLNonTransientException e) {
throw new RuntimeException(e);
}
}
}
return null;
}
use of io.mycat.route.parser.druid.DruidShardingParseInfo in project Mycat-Server by MyCATApache.
the class DefaultDruidParserTest method getParseTables.
private Object[] getParseTables(String sql) throws Exception {
SQLStatementParser parser = new MySqlStatementParser(sql);
SQLStatement statement = parser.parseStatement();
MycatSchemaStatVisitor visitor = new MycatSchemaStatVisitor();
LayerCachePool cachePool = mock(LayerCachePool.class);
RouteResultset rrs = new RouteResultset(sql, ServerParse.SELECT);
druidParser.parser(schema, rrs, statement, sql, cachePool, visitor);
DruidShardingParseInfo ctx = druidParser.getCtx();
return ctx.getTables().toArray();
}
use of io.mycat.route.parser.druid.DruidShardingParseInfo in project Mycat-Server by MyCATApache.
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;
if (schema.isNeedSupportMultiDBType()) {
parser = new MycatStatementParser(stmt);
} else {
parser = new MySqlStatementParser(stmt);
}
SQLStatement statement;
MycatSchemaStatVisitor visitor = null;
try {
statement = parser.parseStatement();
visitor = new MycatSchemaStatVisitor();
} catch (Exception t) {
throw new SQLSyntaxErrorException(t);
}
ctx = new DruidShardingParseInfo();
ctx.setSql(stmt);
List<RouteCalculateUnit> taskList = visitorParse(rrs, statement, visitor);
Assert.assertEquals(true, !taskList.get(0).getTablesAndConditions().isEmpty());
}
Aggregations