use of com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHintStatement in project druid by alibaba.
the class WallVisitorUtils method preVisitCheck.
public static void preVisitCheck(WallVisitor visitor, SQLObject x) {
WallConfig config = visitor.getProvider().getConfig();
if (!(x instanceof SQLStatement)) {
return;
}
boolean allow = false;
int errorCode;
String denyMessage;
if (x instanceof SQLInsertStatement) {
allow = config.isInsertAllow();
denyMessage = "insert not allow";
errorCode = ErrorCode.INSERT_NOT_ALLOW;
} else if (x instanceof SQLSelectStatement) {
allow = true;
denyMessage = "select not allow";
errorCode = ErrorCode.SELECT_NOT_ALLOW;
} else if (x instanceof SQLDeleteStatement) {
allow = config.isDeleteAllow();
denyMessage = "delete not allow";
errorCode = ErrorCode.DELETE_NOT_ALLOW;
} else if (x instanceof SQLUpdateStatement) {
allow = config.isUpdateAllow();
denyMessage = "update not allow";
errorCode = ErrorCode.UPDATE_NOT_ALLOW;
} else if (x instanceof OracleMultiInsertStatement) {
allow = true;
denyMessage = "multi-insert not allow";
errorCode = ErrorCode.INSERT_NOT_ALLOW;
} else if (x instanceof SQLMergeStatement) {
allow = config.isMergeAllow();
denyMessage = "merge not allow";
errorCode = ErrorCode.MERGE_NOT_ALLOW;
} else if (x instanceof SQLCallStatement || x instanceof SQLServerExecStatement) {
allow = config.isCallAllow();
denyMessage = "call not allow";
errorCode = ErrorCode.CALL_NOT_ALLOW;
} else if (x instanceof SQLTruncateStatement) {
allow = config.isTruncateAllow();
denyMessage = "truncate not allow";
errorCode = ErrorCode.TRUNCATE_NOT_ALLOW;
} else if (//
x instanceof SQLCreateTableStatement || //
x instanceof SQLCreateIndexStatement || //
x instanceof SQLCreateViewStatement || //
x instanceof SQLCreateTriggerStatement || //
x instanceof SQLCreateSequenceStatement) {
allow = config.isCreateTableAllow();
denyMessage = "create table not allow";
errorCode = ErrorCode.CREATE_TABLE_NOT_ALLOW;
} else if (x instanceof SQLAlterTableStatement) {
allow = config.isAlterTableAllow();
denyMessage = "alter table not allow";
errorCode = ErrorCode.ALTER_TABLE_NOT_ALLOW;
} else if (//
x instanceof SQLDropTableStatement || //
x instanceof SQLDropIndexStatement || //
x instanceof SQLDropViewStatement || //
x instanceof SQLDropTriggerStatement || //
x instanceof SQLDropSequenceStatement || //
x instanceof SQLDropProcedureStatement) {
allow = config.isDropTableAllow();
denyMessage = "drop table not allow";
errorCode = ErrorCode.DROP_TABLE_NOT_ALLOW;
} else if (//
x instanceof MySqlSetCharSetStatement || //
x instanceof MySqlSetNamesStatement || //
x instanceof SQLSetStatement || x instanceof SQLServerSetStatement) {
allow = config.isSetAllow();
denyMessage = "set not allow";
errorCode = ErrorCode.SET_NOT_ALLOW;
} else if (x instanceof MySqlReplaceStatement) {
allow = config.isReplaceAllow();
denyMessage = "replace not allow";
errorCode = ErrorCode.REPLACE_NOT_ALLOW;
} else if (x instanceof MySqlDescribeStatement) {
allow = config.isDescribeAllow();
denyMessage = "describe not allow";
errorCode = ErrorCode.DESC_NOT_ALLOW;
} else if (x instanceof MySqlShowStatement || x instanceof PGShowStatement || x instanceof SQLShowTablesStatement) {
allow = config.isShowAllow();
denyMessage = "show not allow";
errorCode = ErrorCode.SHOW_NOT_ALLOW;
} else if (x instanceof MySqlCommitStatement || x instanceof SQLServerCommitStatement) {
allow = config.isCommitAllow();
denyMessage = "commit not allow";
errorCode = ErrorCode.COMMIT_NOT_ALLOW;
} else if (x instanceof SQLRollbackStatement) {
allow = config.isRollbackAllow();
denyMessage = "rollback not allow";
errorCode = ErrorCode.ROLLBACK_NOT_ALLOW;
} else if (x instanceof SQLUseStatement) {
allow = config.isUseAllow();
denyMessage = "use not allow";
errorCode = ErrorCode.USE_NOT_ALLOW;
} else if (x instanceof MySqlRenameTableStatement) {
allow = config.isRenameTableAllow();
denyMessage = "rename table not allow";
errorCode = ErrorCode.RENAME_TABLE_NOT_ALLOW;
} else if (x instanceof MySqlHintStatement) {
allow = config.isHintAllow();
denyMessage = "hint not allow";
errorCode = ErrorCode.HINT_NOT_ALLOW;
} else if (x instanceof MySqlLockTableStatement) {
allow = config.isLockTableAllow();
denyMessage = "lock table not allow";
errorCode = ErrorCode.LOCK_TABLE_NOT_ALLOW;
} else if (x instanceof SQLStartTransactionStatement) {
allow = config.isStartTransactionAllow();
denyMessage = "start transaction not allow";
errorCode = ErrorCode.START_TRANSACTION_NOT_ALLOW;
} else if (x instanceof SQLBlockStatement) {
allow = config.isBlockAllow();
denyMessage = "block statement not allow";
errorCode = ErrorCode.BLOCK_NOT_ALLOW;
} else {
allow = config.isNoneBaseStatementAllow();
errorCode = ErrorCode.NONE_BASE_STATEMENT_NOT_ALLOW;
denyMessage = x.getClass() + " not allow";
}
if (!allow) {
addViolation(visitor, errorCode, denyMessage, x);
}
}
use of com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHintStatement in project druid by alibaba.
the class MySqlStatementParser method parseStatementListDialect.
public boolean parseStatementListDialect(List<SQLStatement> statementList) {
if (lexer.token() == Token.KILL) {
SQLStatement stmt = parseKill();
statementList.add(stmt);
return true;
}
if (identifierEquals("PREPARE")) {
MySqlPrepareStatement stmt = parsePrepare();
statementList.add(stmt);
return true;
}
if (identifierEquals("EXECUTE")) {
MySqlExecuteStatement stmt = parseExecute();
statementList.add(stmt);
return true;
}
if (identifierEquals("DEALLOCATE")) {
MysqlDeallocatePrepareStatement stmt = parseDeallocatePrepare();
statementList.add(stmt);
return true;
}
if (identifierEquals("LOAD")) {
SQLStatement stmt = parseLoad();
statementList.add(stmt);
return true;
}
if (lexer.token() == Token.REPLACE) {
MySqlReplaceStatement stmt = parseReplicate();
statementList.add(stmt);
return true;
}
if (identifierEquals("START")) {
SQLStartTransactionStatement stmt = parseStart();
statementList.add(stmt);
return true;
}
if (lexer.token() == Token.SHOW) {
SQLStatement stmt = parseShow();
statementList.add(stmt);
return true;
}
if (identifierEquals(BINLOG)) {
SQLStatement stmt = parseBinlog();
statementList.add(stmt);
return true;
}
if (identifierEquals(RESET)) {
SQLStatement stmt = parseReset();
statementList.add(stmt);
return true;
}
if (lexer.token() == Token.ANALYZE) {
SQLStatement stmt = parseAnalyze();
statementList.add(stmt);
return true;
}
if (lexer.token() == Token.OPTIMIZE) {
SQLStatement stmt = parseOptimize();
statementList.add(stmt);
return true;
}
if (identifierEquals("HELP")) {
lexer.nextToken();
MySqlHelpStatement stmt = new MySqlHelpStatement();
stmt.setContent(this.exprParser.primary());
statementList.add(stmt);
return true;
}
if (lexer.token() == Token.DESC || identifierEquals(DESCRIBE)) {
SQLStatement stmt = parseDescribe();
statementList.add(stmt);
return true;
}
if (lexer.token() == Token.LOCK) {
lexer.nextToken();
String val = lexer.stringVal();
boolean isLockTables = TABLES.equalsIgnoreCase(val) && lexer.token() == Token.IDENTIFIER;
boolean isLockTable = "TABLE".equalsIgnoreCase(val) && lexer.token() == Token.TABLE;
if (isLockTables || isLockTable) {
lexer.nextToken();
} else {
setErrorEndPos(lexer.pos());
throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token());
}
MySqlLockTableStatement stmt = new MySqlLockTableStatement();
stmt.setTableSource(this.exprParser.name());
if (identifierEquals(READ)) {
lexer.nextToken();
if (identifierEquals(LOCAL)) {
lexer.nextToken();
stmt.setLockType(LockType.READ_LOCAL);
} else {
stmt.setLockType(LockType.READ);
}
} else if (identifierEquals(WRITE)) {
stmt.setLockType(LockType.WRITE);
} else if (identifierEquals(LOW_PRIORITY)) {
lexer.nextToken();
acceptIdentifier(WRITE);
stmt.setLockType(LockType.LOW_PRIORITY_WRITE);
} else {
throw new ParserException("syntax error, expect READ or WRITE, actual " + lexer.token());
}
if (lexer.token() == Token.HINT) {
stmt.setHints(this.exprParser.parseHints());
}
statementList.add(stmt);
return true;
}
if (identifierEquals("UNLOCK")) {
lexer.nextToken();
String val = lexer.stringVal();
boolean isUnLockTables = TABLES.equalsIgnoreCase(val) && lexer.token() == Token.IDENTIFIER;
boolean isUnLockTable = "TABLE".equalsIgnoreCase(val) && lexer.token() == Token.TABLE;
statementList.add(new MySqlUnlockTablesStatement());
if (isUnLockTables || isUnLockTable) {
lexer.nextToken();
} else {
setErrorEndPos(lexer.pos());
throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token());
}
return true;
}
if (lexer.token() == Token.HINT) {
List<SQLCommentHint> hints = this.exprParser.parseHints();
boolean tddlSelectHints = false;
if (hints.size() == 1 && statementList.size() == 0 && lexer.token() == Token.SELECT) {
SQLCommentHint hint = hints.get(0);
String hintText = hint.getText();
if (hintText.startsWith("+TDDL")) {
tddlSelectHints = true;
}
}
if (tddlSelectHints) {
SQLSelectStatement stmt = (SQLSelectStatement) this.parseStatement();
stmt.setHeadHints(hints);
statementList.add(stmt);
return true;
}
MySqlHintStatement stmt = new MySqlHintStatement();
stmt.setHints(hints);
statementList.add(stmt);
return true;
}
if (lexer.token() == Token.BEGIN) {
statementList.add(this.parseBlock());
return true;
}
return false;
}
use of com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHintStatement in project druid by alibaba.
the class WallProvider method checkInternal.
private WallCheckResult checkInternal(String sql) {
checkCount.incrementAndGet();
WallContext context = WallContext.current();
if (config.isDoPrivilegedAllow() && ispPrivileged()) {
WallCheckResult checkResult = new WallCheckResult();
checkResult.setSql(sql);
return checkResult;
}
// first step, check whiteList
boolean mulltiTenant = config.getTenantTablePattern() != null && config.getTenantTablePattern().length() > 0;
if (!mulltiTenant) {
WallCheckResult checkResult = checkWhiteAndBlackList(sql);
if (checkResult != null) {
checkResult.setSql(sql);
return checkResult;
}
}
hardCheckCount.incrementAndGet();
final List<Violation> violations = new ArrayList<Violation>();
List<SQLStatement> statementList = new ArrayList<SQLStatement>();
boolean syntaxError = false;
boolean endOfComment = false;
try {
SQLStatementParser parser = createParser(sql);
parser.getLexer().setCommentHandler(WallCommentHandler.instance);
if (!config.isCommentAllow()) {
// deny comment
parser.getLexer().setAllowComment(false);
}
if (!config.isCompleteInsertValuesCheck()) {
parser.setParseCompleteValues(false);
parser.setParseValuesSize(config.getInsertValuesCheckSize());
}
parser.parseStatementList(statementList);
final Token lastToken = parser.getLexer().token();
if (lastToken != Token.EOF && config.isStrictSyntaxCheck()) {
violations.add(new IllegalSQLObjectViolation(ErrorCode.SYNTAX_ERROR, "not terminal sql, token " + lastToken, sql));
}
endOfComment = parser.getLexer().isEndOfComment();
} catch (NotAllowCommentException e) {
violations.add(new IllegalSQLObjectViolation(ErrorCode.COMMENT_STATEMENT_NOT_ALLOW, "comment not allow", sql));
incrementCommentDeniedCount();
} catch (ParserException e) {
syntaxErrorCount.incrementAndGet();
syntaxError = true;
if (config.isStrictSyntaxCheck()) {
violations.add(new SyntaxErrorViolation(e, sql));
}
} catch (Exception e) {
if (config.isStrictSyntaxCheck()) {
violations.add(new SyntaxErrorViolation(e, sql));
}
}
if (statementList.size() > 1 && !config.isMultiStatementAllow()) {
violations.add(new IllegalSQLObjectViolation(ErrorCode.MULTI_STATEMENT, "multi-statement not allow", sql));
}
WallVisitor visitor = createWallVisitor();
visitor.setSqlEndOfComment(endOfComment);
if (statementList.size() > 0) {
boolean lastIsHint = false;
for (int i = 0; i < statementList.size(); i++) {
SQLStatement stmt = statementList.get(i);
if ((i == 0 || lastIsHint) && stmt instanceof MySqlHintStatement) {
lastIsHint = true;
continue;
}
try {
stmt.accept(visitor);
} catch (ParserException e) {
violations.add(new SyntaxErrorViolation(e, sql));
}
}
}
if (visitor.getViolations().size() > 0) {
violations.addAll(visitor.getViolations());
}
WallSqlStat sqlStat = null;
if (violations.size() > 0) {
violationCount.incrementAndGet();
if (sql.length() < MAX_SQL_LENGTH) {
sqlStat = addBlackSql(sql, context.getTableStats(), context.getFunctionStats(), violations, syntaxError);
}
} else {
if (sql.length() < MAX_SQL_LENGTH) {
sqlStat = addWhiteSql(sql, context.getTableStats(), context.getFunctionStats(), syntaxError);
}
}
Map<String, WallSqlTableStat> tableStats = null;
Map<String, WallSqlFunctionStat> functionStats = null;
if (context != null) {
tableStats = context.getTableStats();
functionStats = context.getFunctionStats();
recordStats(tableStats, functionStats);
}
WallCheckResult result;
if (sqlStat != null) {
context.setSqlStat(sqlStat);
result = new WallCheckResult(sqlStat, statementList);
} else {
result = new WallCheckResult(null, violations, tableStats, functionStats, statementList, syntaxError);
}
String resultSql;
if (visitor.isSqlModified()) {
resultSql = SQLUtils.toSQLString(statementList, dbType);
} else {
resultSql = sql;
}
result.setSql(resultSql);
return result;
}
Aggregations