Search in sources :

Example 1 with DruidShardingParseInfo

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;
}
Also used : DruidShardingParseInfo(io.mycat.route.parser.druid.DruidShardingParseInfo) RouteCalculateUnit(io.mycat.route.parser.druid.RouteCalculateUnit) SQLStatementParser(com.alibaba.druid.sql.parser.SQLStatementParser) MycatStatementParser(io.mycat.route.parser.druid.MycatStatementParser) MycatSchemaStatVisitor(io.mycat.route.parser.druid.MycatSchemaStatVisitor) SQLSyntaxErrorException(java.sql.SQLSyntaxErrorException) MySqlInsertStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement) SQLStatement(com.alibaba.druid.sql.ast.SQLStatement) SQLNonTransientException(java.sql.SQLNonTransientException) SQLSyntaxErrorException(java.sql.SQLSyntaxErrorException) SlotFunction(io.mycat.route.function.SlotFunction) DruidParser(io.mycat.route.parser.druid.DruidParser) TreeSet(java.util.TreeSet) RouteResultsetNode(io.mycat.route.RouteResultsetNode) RuleConfig(io.mycat.config.model.rule.RuleConfig) MySqlStatementParser(com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser) RouteResultset(io.mycat.route.RouteResultset)

Example 2 with DruidShardingParseInfo

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);
}
Also used : DruidShardingParseInfo(io.mycat.route.parser.druid.DruidShardingParseInfo)

Example 3 with DruidShardingParseInfo

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;
}
Also used : DruidShardingParseInfo(io.mycat.route.parser.druid.DruidShardingParseInfo) RouteCalculateUnit(io.mycat.route.parser.druid.RouteCalculateUnit) ArrayList(java.util.ArrayList) SQLNonTransientException(java.sql.SQLNonTransientException) TreeSet(java.util.TreeSet) RouteResultsetNode(io.mycat.route.RouteResultsetNode) RouteResultset(io.mycat.route.RouteResultset)

Example 4 with DruidShardingParseInfo

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();
}
Also used : DruidShardingParseInfo(io.mycat.route.parser.druid.DruidShardingParseInfo) SQLStatementParser(com.alibaba.druid.sql.parser.SQLStatementParser) MycatSchemaStatVisitor(io.mycat.route.parser.druid.MycatSchemaStatVisitor) LayerCachePool(io.mycat.cache.LayerCachePool) MySqlStatementParser(com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser) SQLStatement(com.alibaba.druid.sql.ast.SQLStatement) RouteResultset(io.mycat.route.RouteResultset)

Example 5 with DruidShardingParseInfo

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());
}
Also used : DruidShardingParseInfo(io.mycat.route.parser.druid.DruidShardingParseInfo) RouteCalculateUnit(io.mycat.route.parser.druid.RouteCalculateUnit) SchemaConfig(io.mycat.config.model.SchemaConfig) SQLStatementParser(com.alibaba.druid.sql.parser.SQLStatementParser) MycatStatementParser(io.mycat.route.parser.druid.MycatStatementParser) MycatSchemaStatVisitor(io.mycat.route.parser.druid.MycatSchemaStatVisitor) SQLSyntaxErrorException(java.sql.SQLSyntaxErrorException) SQLStatement(com.alibaba.druid.sql.ast.SQLStatement) SQLSyntaxErrorException(java.sql.SQLSyntaxErrorException) MySqlStatementParser(com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser) Test(org.junit.Test)

Aggregations

DruidShardingParseInfo (io.mycat.route.parser.druid.DruidShardingParseInfo)5 SQLStatement (com.alibaba.druid.sql.ast.SQLStatement)3 MySqlStatementParser (com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser)3 SQLStatementParser (com.alibaba.druid.sql.parser.SQLStatementParser)3 RouteResultset (io.mycat.route.RouteResultset)3 MycatSchemaStatVisitor (io.mycat.route.parser.druid.MycatSchemaStatVisitor)3 RouteCalculateUnit (io.mycat.route.parser.druid.RouteCalculateUnit)3 RouteResultsetNode (io.mycat.route.RouteResultsetNode)2 MycatStatementParser (io.mycat.route.parser.druid.MycatStatementParser)2 SQLNonTransientException (java.sql.SQLNonTransientException)2 SQLSyntaxErrorException (java.sql.SQLSyntaxErrorException)2 TreeSet (java.util.TreeSet)2 MySqlInsertStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement)1 LayerCachePool (io.mycat.cache.LayerCachePool)1 SchemaConfig (io.mycat.config.model.SchemaConfig)1 RuleConfig (io.mycat.config.model.rule.RuleConfig)1 SlotFunction (io.mycat.route.function.SlotFunction)1 DruidParser (io.mycat.route.parser.druid.DruidParser)1 ArrayList (java.util.ArrayList)1 Test (org.junit.Test)1