Search in sources :

Example 1 with SQLStatementParser

use of com.alibaba.druid.sql.parser.SQLStatementParser in project Mycat-Server by MyCATApache.

the class MycatPrivileges method checkDmlPrivilege.

// 审计SQL权限
@Override
public boolean checkDmlPrivilege(String user, String schema, String sql) {
    if (schema == null) {
        return true;
    }
    boolean isPassed = false;
    MycatConfig conf = MycatServer.getInstance().getConfig();
    UserConfig userConfig = conf.getUsers().get(user);
    if (userConfig != null) {
        UserPrivilegesConfig userPrivilege = userConfig.getPrivilegesConfig();
        if (userPrivilege != null && userPrivilege.isCheck()) {
            UserPrivilegesConfig.SchemaPrivilege schemaPrivilege = userPrivilege.getSchemaPrivilege(schema);
            if (schemaPrivilege != null) {
                String tableName = null;
                int index = -1;
                //TODO 此处待优化,寻找更优SQL 解析器
                SQLStatementParser parser = new MycatStatementParser(sql);
                SQLStatement stmt = parser.parseStatement();
                if (stmt instanceof MySqlReplaceStatement || stmt instanceof SQLInsertStatement) {
                    index = 0;
                } else if (stmt instanceof SQLUpdateStatement) {
                    index = 1;
                } else if (stmt instanceof SQLSelectStatement) {
                    index = 2;
                } else if (stmt instanceof SQLDeleteStatement) {
                    index = 3;
                }
                if (index > -1) {
                    SchemaStatVisitor schemaStatVisitor = new MycatSchemaStatVisitor();
                    stmt.accept(schemaStatVisitor);
                    String key = schemaStatVisitor.getCurrentTable();
                    if (key != null) {
                        if (key.contains("`")) {
                            key = key.replaceAll("`", "");
                        }
                        int dotIndex = key.indexOf(".");
                        if (dotIndex > 0) {
                            tableName = key.substring(dotIndex + 1);
                        } else {
                            tableName = key;
                        }
                        //获取table 权限, 此处不需要检测空值, 无设置则自动继承父级权限
                        UserPrivilegesConfig.TablePrivilege tablePrivilege = schemaPrivilege.getTablePrivilege(tableName);
                        if (tablePrivilege.getDml()[index] > 0) {
                            isPassed = true;
                        }
                    } else {
                        //skip
                        isPassed = true;
                    }
                } else {
                    //skip
                    isPassed = true;
                }
            } else {
                //skip
                isPassed = true;
            }
        } else {
            //skip
            isPassed = true;
        }
    } else {
        //skip
        isPassed = true;
    }
    if (!isPassed) {
        ALARM.error(new StringBuilder().append(Alarms.DML_ATTACK).append("[sql=").append(sql).append(",user=").append(user).append(']').toString());
    }
    return isPassed;
}
Also used : SQLStatementParser(com.alibaba.druid.sql.parser.SQLStatementParser) MycatStatementParser(io.mycat.route.parser.druid.MycatStatementParser) MycatSchemaStatVisitor(io.mycat.route.parser.druid.MycatSchemaStatVisitor) SQLUpdateStatement(com.alibaba.druid.sql.ast.statement.SQLUpdateStatement) UserConfig(io.mycat.config.model.UserConfig) UserPrivilegesConfig(io.mycat.config.model.UserPrivilegesConfig) SQLStatement(com.alibaba.druid.sql.ast.SQLStatement) MySqlReplaceStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement) SQLDeleteStatement(com.alibaba.druid.sql.ast.statement.SQLDeleteStatement) SQLInsertStatement(com.alibaba.druid.sql.ast.statement.SQLInsertStatement) SQLSelectStatement(com.alibaba.druid.sql.ast.statement.SQLSelectStatement) SchemaStatVisitor(com.alibaba.druid.sql.visitor.SchemaStatVisitor) MycatSchemaStatVisitor(io.mycat.route.parser.druid.MycatSchemaStatVisitor)

Example 2 with SQLStatementParser

use of com.alibaba.druid.sql.parser.SQLStatementParser 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 3 with SQLStatementParser

use of com.alibaba.druid.sql.parser.SQLStatementParser in project Mycat-Server by MyCATApache.

the class ExplainHandler method isMycatSeq.

private static boolean isMycatSeq(String stmt, SchemaConfig schema) {
    if (pattern.matcher(stmt).find()) {
        return true;
    }
    SQLStatementParser parser = new MySqlStatementParser(stmt);
    MySqlInsertStatement statement = (MySqlInsertStatement) parser.parseStatement();
    String tableName = statement.getTableName().getSimpleName();
    TableConfig tableConfig = schema.getTables().get(tableName.toUpperCase());
    if (tableConfig == null) {
        return false;
    }
    if (tableConfig.isAutoIncrement()) {
        boolean isHasIdInSql = false;
        String primaryKey = tableConfig.getPrimaryKey();
        List<SQLExpr> columns = statement.getColumns();
        for (SQLExpr column : columns) {
            String columnName = column.toString();
            if (primaryKey.equalsIgnoreCase(columnName)) {
                isHasIdInSql = true;
                break;
            }
        }
        if (!isHasIdInSql) {
            return true;
        }
    }
    return false;
}
Also used : SQLStatementParser(com.alibaba.druid.sql.parser.SQLStatementParser) TableConfig(io.mycat.config.model.TableConfig) MySqlInsertStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement) MySqlStatementParser(com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr)

Example 4 with SQLStatementParser

use of com.alibaba.druid.sql.parser.SQLStatementParser in project Mycat-Server by MyCATApache.

the class ServerLoadDataInfileHandler method start.

@Override
public void start(String sql) {
    clear();
    this.sql = sql;
    SQLStatementParser parser = new MycatStatementParser(sql);
    statement = (MySqlLoadDataInFileStatement) parser.parseStatement();
    fileName = parseFileName(sql);
    if (fileName == null) {
        serverConnection.writeErrMessage(ErrorCode.ER_FILE_NOT_FOUND, " file name is null !");
        clear();
        return;
    }
    schema = MycatServer.getInstance().getConfig().getSchemas().get(serverConnection.getSchema());
    tableId2DataNodeCache = (LayerCachePool) MycatServer.getInstance().getCacheService().getCachePool("TableID2DataNodeCache");
    tableName = statement.getTableName().getSimpleName().toUpperCase();
    tableConfig = schema.getTables().get(tableName);
    if (tableConfig.getRule().getRuleAlgorithm() instanceof SlotFunction) {
        shoudAddSlot = true;
    }
    tempPath = SystemConfig.getHomePath() + File.separator + "temp" + File.separator + serverConnection.getId() + File.separator;
    tempFile = tempPath + "clientTemp.txt";
    tempByteBuffer = new ByteArrayOutputStream();
    List<SQLExpr> columns = statement.getColumns();
    if (tableConfig != null) {
        String pColumn = getPartitionColumn();
        if (pColumn != null && columns != null && columns.size() > 0) {
            for (int i = 0, columnsSize = columns.size(); i < columnsSize; i++) {
                String column = StringUtil.removeBackquote(columns.get(i).toString());
                if (pColumn.equalsIgnoreCase(column)) {
                    partitionColumnIndex = i;
                }
                if ("_slot".equalsIgnoreCase(column)) {
                    shoudAddSlot = false;
                }
            }
        }
    }
    if (shoudAddSlot) {
        columns.add(new SQLIdentifierExpr("_slot"));
    }
    parseLoadDataPram();
    if (statement.isLocal()) {
        isStartLoadData = true;
        //向客户端请求发送文件
        ByteBuffer buffer = serverConnection.allocate();
        RequestFilePacket filePacket = new RequestFilePacket();
        filePacket.fileName = fileName.getBytes();
        filePacket.packetId = 1;
        filePacket.write(buffer, serverConnection, true);
    } else {
        if (!new File(fileName).exists()) {
            serverConnection.writeErrMessage(ErrorCode.ER_FILE_NOT_FOUND, fileName + " is not found!");
            clear();
        } else {
            parseFileByLine(fileName, loadData.getCharset(), loadData.getLineTerminatedBy());
            RouteResultset rrs = buildResultSet(routeResultMap);
            if (rrs != null) {
                flushDataToFile();
                isStartLoadData = false;
                serverConnection.getSession2().execute(rrs, ServerParse.LOAD_DATA_INFILE_SQL);
            }
        }
    }
}
Also used : RequestFilePacket(io.mycat.net.mysql.RequestFilePacket) SQLStatementParser(com.alibaba.druid.sql.parser.SQLStatementParser) MycatStatementParser(io.mycat.route.parser.druid.MycatStatementParser) SQLIdentifierExpr(com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr) ByteBuffer(java.nio.ByteBuffer) SlotFunction(io.mycat.route.function.SlotFunction) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr) RouteResultset(io.mycat.route.RouteResultset)

Example 5 with SQLStatementParser

use of com.alibaba.druid.sql.parser.SQLStatementParser 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)

Aggregations

SQLStatementParser (com.alibaba.druid.sql.parser.SQLStatementParser)436 SQLStatement (com.alibaba.druid.sql.ast.SQLStatement)431 MySqlStatementParser (com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser)382 ArrayList (java.util.ArrayList)21 SQLASTOutputVisitor (com.alibaba.druid.sql.visitor.SQLASTOutputVisitor)19 SchemaStatVisitor (com.alibaba.druid.sql.visitor.SchemaStatVisitor)14 MycatSchemaStatVisitor (io.mycat.route.parser.druid.MycatSchemaStatVisitor)6 SQLExpr (com.alibaba.druid.sql.ast.SQLExpr)5 MySqlExportParameterVisitor (com.alibaba.druid.sql.dialect.mysql.visitor.MySqlExportParameterVisitor)5 ExportParameterVisitor (com.alibaba.druid.sql.visitor.ExportParameterVisitor)5 TableStat (com.alibaba.druid.stat.TableStat)5 MycatStatementParser (io.mycat.route.parser.druid.MycatStatementParser)5 SQLIdentifierExpr (com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr)4 SQLSelectStatement (com.alibaba.druid.sql.ast.statement.SQLSelectStatement)4 OracleStatementParser (com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser)4 SQLVariantRefExpr (com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr)3 SQLSelectQuery (com.alibaba.druid.sql.ast.statement.SQLSelectQuery)3 SQLSelectQueryBlock (com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock)3 MySqlInsertStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement)3 RouteResultset (io.mycat.route.RouteResultset)3