diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateDatabaseStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateDatabaseStatement.java index 2041161358..f0e4440559 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateDatabaseStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateDatabaseStatement.java @@ -15,16 +15,21 @@ */ package com.alibaba.druid.sql.ast.statement; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLCommentHint; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLStatementImpl; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLCreateDatabaseStatement extends SQLStatementImpl { - private SQLName name; + private SQLName name; - private String characterSet; - private String collate; + private String characterSet; + private String collate; + + private List hints; public SQLCreateDatabaseStatement(){ } @@ -61,4 +66,12 @@ public class SQLCreateDatabaseStatement extends SQLStatementImpl { this.collate = collate; } + public List getHints() { + return hints; + } + + public void setHints(List hints) { + this.hints = hints; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExplainStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExplainStatement.java index 1ffbbe6481..02a0bdee9d 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExplainStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExplainStatement.java @@ -15,13 +15,18 @@ */ package com.alibaba.druid.sql.ast.statement; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLCommentHint; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.SQLStatementImpl; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLExplainStatement extends SQLStatementImpl { - protected SQLStatement statement; + protected SQLStatement statement; + + private List hints; public SQLStatement getStatement() { return statement; @@ -41,4 +46,12 @@ public class SQLExplainStatement extends SQLStatementImpl { } visitor.endVisit(this); } + + public List getHints() { + return hints; + } + + public void setHints(List hints) { + this.hints = hints; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index 56b3f29809..a0d0f3d961 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -2537,6 +2537,10 @@ public class MySqlStatementParser extends SQLStatementParser { if (lexer.token() == Token.DEFAULT) { lexer.nextToken(); } + + if (lexer.token() == Token.HINT) { + stmt.setHints(this.exprParser.parseHints()); + } return stmt; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index 4897da7bfb..1ae28929ea 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -1123,12 +1123,9 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV print(" WITH CONSISTENT SNAPSHOT"); } - List hints = x.getHints(); - if (hints != null && !hints.isEmpty()) { + if (x.getHints() != null && x.getHints().size() > 0) { print(" "); - for (SQLCommentHint hint : hints) { - hint.accept(this); - } + printAndAccept(x.getHints(), " "); } if (x.isBegin()) { @@ -2143,12 +2140,9 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV x.getTable().accept(this); } - List hints = x.getHints(); - if (hints != null && !hints.isEmpty()) { + if (x.getHints() != null && x.getHints().size() > 0) { print(" "); - for (SQLCommentHint hint : hints) { - hint.accept(this); - } + printAndAccept(x.getHints(), " "); } return false; @@ -2685,12 +2679,9 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV print(x.getLockType().name); } - List hints = x.getHints(); - if (hints != null && !hints.isEmpty()) { + if (x.getHints() != null && x.getHints().size() > 0) { print(" "); - for (SQLCommentHint hint : hints) { - hint.accept(this); - } + printAndAccept(x.getHints(), " "); } return false; } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index 93b2ded1f0..ccf68e08d4 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -1534,8 +1534,13 @@ public class SQLStatementParser extends SQLParser { if (lexer.token() == Token.FOR) { lexer.nextToken(); } - + SQLExplainStatement explain = new SQLExplainStatement(); + + if(lexer.token == Token.HINT) { + explain.setHints(this.exprParser.parseHints()); + } + explain.setStatement(parseStatement()); return explain; diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 535a48c133..42f289b8c5 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -1149,13 +1149,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab print("SET "); printAndAccept(x.getItems(), ", "); - List hints = x.getHints(); - if (hints != null && !hints.isEmpty()) { + if (x.getHints() != null && x.getHints().size() > 0) { print(" "); - for (SQLCommentHint hint : hints) { - hint.accept(this); - } + printAndAccept(x.getHints(), " "); } + return false; } @@ -1770,6 +1768,10 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab @Override public boolean visit(SQLExplainStatement x) { print("EXPLAIN"); + if (x.getHints() != null && x.getHints().size() > 0) { + print(" "); + printAndAccept(x.getHints(), " "); + } println(); x.getStatement().accept(this); return false; diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_hint.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_hint.java index 48eb654b1a..02cc439e46 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_hint.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_hint.java @@ -110,4 +110,22 @@ public class MySqlWallTest_hint extends TestCase { + ") /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */ "; Assert.assertTrue(WallUtils.isValidateMySql(sql, config)); // } + + public void test_true_10() throws Exception { + WallConfig config = new WallConfig(); + config.setHintAllow(true); + config.setMultiStatementAllow(true); + config.setNoneBaseStatementAllow(true); + String sql = "CREATE DATABASE `newsfocus` /*!40100 COLLATE 'big5_chinese_ci' */ "; + Assert.assertTrue(WallUtils.isValidateMySql(sql, config)); // + } + + public void test_true_11() throws Exception { + WallConfig config = new WallConfig(); + config.setHintAllow(true); + config.setMultiStatementAllow(true); + config.setNoneBaseStatementAllow(true); + String sql = "EXPLAIN /*!40100 EXTENDED */ SELECT * FROM trade_order_header WHERE id = ?"; + Assert.assertTrue(WallUtils.isValidateMySql(sql, config)); // + } }