use of io.mycat.route.parser.druid.MycatSchemaStatVisitor 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;
}
use of io.mycat.route.parser.druid.MycatSchemaStatVisitor 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.MycatSchemaStatVisitor 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.MycatSchemaStatVisitor 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());
}
use of io.mycat.route.parser.druid.MycatSchemaStatVisitor in project Mycat-Server by MyCATApache.
the class MycatSchemaStatVisitorTest method getSchema.
private String getSchema(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);
return visitor.getCurrentTable();
}
Aggregations