From 032c5762e22c2243fa7a7741fd0485244d05c83e Mon Sep 17 00:00:00 2001 From: wenshao Date: Mon, 1 Apr 2013 20:05:46 +0800 Subject: [PATCH] improve wall filter --- .../druid/sql/ast/expr/SQLPropertyExpr.java | 7 +- .../ast/statement/SQLAlterTableStatement.java | 11 + .../sql/ast/statement/SQLDeleteStatement.java | 3 + .../sql/ast/statement/SQLInsertInto.java | 3 + .../sql/ast/statement/SQLJoinTableSource.java | 9 + .../ast/statement/SQLSelectQueryBlock.java | 5 +- .../ast/statement/SQLTruncateStatement.java | 4 +- .../sql/ast/statement/SQLUpdateStatement.java | 3 + .../sql/dialect/mysql/parser/MySqlLexer.java | 20 +- .../mysql/parser/MySqlSelectParser.java | 5 + .../mysql/parser/MySqlStatementParser.java | 4 + .../oracle/parser/OracleSelectParser.java | 4 + .../oracle/parser/OracleStatementParser.java | 4 + .../ast/stmt/PGInsertStatement.java | 5 + .../parser/PGSQLStatementParser.java | 7 +- .../postgresql/parser/PGSelectParser.java | 4 + .../parser/SQLServerSelectParser.java | 4 + .../com/alibaba/druid/sql/parser/Lexer.java | 15 + .../sql/parser/NotAllowCommentException.java | 2 +- .../druid/sql/parser/SQLSelectParser.java | 4 + .../druid/sql/parser/SQLStatementParser.java | 4 + .../druid/sql/visitor/SQLASTVisitor.java | 5 + .../sql/visitor/SQLASTVisitorAdapter.java | 11 + .../com/alibaba/druid/wall/WallConfig.java | 27 ++ .../com/alibaba/druid/wall/WallContext.java | 33 ++ .../com/alibaba/druid/wall/WallProvider.java | 297 +++++++++++++++--- .../com/alibaba/druid/wall/WallSqlStat.java | 25 +- .../alibaba/druid/wall/WallSqlTableStat.java | 102 ++++++ .../com/alibaba/druid/wall/WallTableStat.java | 182 +++++++++++ .../druid/wall/spi/MySqlWallVisitor.java | 110 +++---- .../druid/wall/spi/OracleWallVisitor.java | 70 +++-- .../alibaba/druid/wall/spi/PGWallVisitor.java | 65 ++-- .../druid/wall/spi/SQLServerWallVisitor.java | 60 ++-- .../druid/wall/spi/WallVisitorUtils.java | 158 ++++++++++ .../wall/MySqlWallTest_var_autoincrement.java | 40 +++ .../druid/bvt/filter/wall/WallDropTest1.java | 2 +- .../filter/wall/WallStatTest_alter_table.java | 54 ++++ .../filter/wall/WallStatTest_blacklist.java | 36 +++ .../wall/WallStatTest_create_table.java | 54 ++++ .../bvt/filter/wall/WallStatTest_delete.java | 55 ++++ .../filter/wall/WallStatTest_drop_table.java | 63 ++++ .../bvt/filter/wall/WallStatTest_insert.java | 46 +++ .../bvt/filter/wall/WallStatTest_select.java | 55 ++++ .../filter/wall/WallStatTest_select_1.java | 79 +++++ .../filter/wall/WallStatTest_select_into.java | 64 ++++ .../bvt/filter/wall/WallStatTest_update.java | 55 ++++ 46 files changed, 1653 insertions(+), 222 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/wall/WallSqlTableStat.java create mode 100644 src/main/java/com/alibaba/druid/wall/WallTableStat.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_var_autoincrement.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_alter_table.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_blacklist.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_create_table.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_delete.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_drop_table.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_insert.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_select.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_select_1.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_select_into.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_update.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java index 5220ff9cef..69b0ad7fa3 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java @@ -28,7 +28,9 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName { private String name; public SQLPropertyExpr(SQLExpr owner, String name){ - + if (owner != null) { + owner.setParent(this); + } this.owner = owner; this.name = name; } @@ -46,6 +48,9 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName { } public void setOwner(SQLExpr owner) { + if (owner != null) { + owner.setParent(this); + } this.owner = owner; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableStatement.java index 0361be89d6..2f66eee136 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableStatement.java @@ -20,6 +20,8 @@ import java.util.List; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLStatementImpl; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLAlterTableStatement extends SQLStatementImpl implements SQLDDLStatement { @@ -54,4 +56,13 @@ public class SQLAlterTableStatement extends SQLStatementImpl implements SQLDDLSt public void setName(SQLName name) { this.setTableSource(new SQLExprTableSource(name)); } + + @Override + protected void accept0(SQLASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, getTableSource()); + acceptChild(visitor, getItems()); + } + visitor.endVisit(this); + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDeleteStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDeleteStatement.java index efb3607131..3f1c828f89 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDeleteStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDeleteStatement.java @@ -44,6 +44,9 @@ public class SQLDeleteStatement extends SQLStatementImpl { } public void setTableSource(SQLTableSource tableSource) { + if (tableSource != null) { + tableSource.setParent(this); + } this.tableSource = tableSource; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertInto.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertInto.java index 9acb59dfaf..6396ae3985 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertInto.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertInto.java @@ -49,6 +49,9 @@ public abstract class SQLInsertInto extends SQLObjectImpl { } public void setTableSource(SQLExprTableSource tableSource) { + if (tableSource != null) { + tableSource.setParent(this); + } this.tableSource = tableSource; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java index 5c3d822f18..1af33c8274 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java @@ -63,6 +63,9 @@ public class SQLJoinTableSource extends SQLTableSourceImpl { } public void setLeft(SQLTableSource left) { + if (left != null) { + left.setParent(this); + } this.left = left; } @@ -71,6 +74,9 @@ public class SQLJoinTableSource extends SQLTableSourceImpl { } public void setRight(SQLTableSource right) { + if (right != null) { + right.setParent(this); + } this.right = right; } @@ -79,6 +85,9 @@ public class SQLJoinTableSource extends SQLTableSourceImpl { } public void setCondition(SQLExpr condition) { + if (condition != null) { + condition.setParent(this); + } this.condition = condition; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java index b2cb7b96bf..30abaf4596 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java @@ -43,10 +43,13 @@ public class SQLSelectQueryBlock extends SQLSelectQuery { } public void setInto(SQLExpr into) { - this.into = new SQLExprTableSource(into); + this.setInto(new SQLExprTableSource(into)); } public void setInto(SQLExprTableSource into) { + if (into != null) { + into.setParent(this); + } this.into = into; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTruncateStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTruncateStatement.java index 3a70032ac2..2ba1b69b61 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTruncateStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTruncateStatement.java @@ -36,7 +36,9 @@ public class SQLTruncateStatement extends SQLStatementImpl { } public void addTableSource(SQLName name) { - this.tableSources.add(new SQLExprTableSource(name)); + SQLExprTableSource tableSource = new SQLExprTableSource(name); + tableSource.setParent(this); + this.tableSources.add(tableSource); } @Override diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUpdateStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUpdateStatement.java index ae582b381a..ce6fb1deec 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUpdateStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUpdateStatement.java @@ -45,6 +45,9 @@ public class SQLUpdateStatement extends SQLStatementImpl { } public void setTableSource(SQLTableSource tableSource) { + if (tableSource != null) { + tableSource.setParent(this); + } this.tableSource = tableSource; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java index 7d13919037..b1a20fd311 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java @@ -203,12 +203,12 @@ public class MySqlLexer extends Lexer { } } } - + protected final void scanString() { { boolean hasSpecial = false; int startIndex = pos + 1; - int endIndex = -1; //text.indexOf('\'', startIndex); + int endIndex = -1; // text.indexOf('\'', startIndex); for (int i = startIndex; i < text.length(); ++i) { final char ch = text.charAt(i); if (ch == '\\') { @@ -219,13 +219,13 @@ public class MySqlLexer extends Lexer { break; } } - + if (endIndex == -1) { throw new ParserException("unclosed str"); } String stringVal = subString(startIndex, endIndex - startIndex); -// hasSpecial = stringVal.indexOf('\\') != -1; + // hasSpecial = stringVal.indexOf('\\') != -1; if (!hasSpecial) { this.stringVal = stringVal; @@ -328,6 +328,8 @@ public class MySqlLexer extends Lexer { } public void scanComment() { + Token lastToken = this.token; + if (ch != '/' && ch != '-') { throw new IllegalStateException(); } @@ -374,8 +376,14 @@ public class MySqlLexer extends Lexer { token = Token.MULTI_LINE_COMMENT; } - if (token != Token.HINT && !isAllowComment()) { - throw new NotAllowCommentException(); + if (token != Token.HINT) { + if (commentHandler != null && commentHandler.handle(lastToken, stringVal)) { + return; + } + + if (!isAllowComment()) { + throw new NotAllowCommentException(); + } } return; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java index 7ff2309813..10d1f4c99e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java @@ -64,10 +64,15 @@ public class MySqlSelectParser extends SQLSelectParser { if (lexer.token() == Token.SELECT) { lexer.nextToken(); + if (lexer.token() == Token.HINT) { this.exprParser.parseHints(queryBlock.getHints()); } + + if (lexer.token() == Token.COMMENT) { + lexer.nextToken(); + } if (lexer.token() == (Token.DISTINCT)) { queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT); 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 d45e69c51a..e08c2afefb 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 @@ -235,6 +235,10 @@ public class MySqlStatementParser extends SQLStatementParser { if (lexer.token() == Token.DELETE) { lexer.nextToken(); + + if (lexer.token() == Token.COMMENT) { + lexer.nextToken(); + } if (identifierEquals(LOW_PRIORITY)) { deleteStatement.setLowPriority(true); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java index 353ef149f1..644ea15a13 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java @@ -244,6 +244,10 @@ public class OracleSelectParser extends SQLSelectParser { OracleSelectQueryBlock queryBlock = new OracleSelectQueryBlock(); if (lexer.token() == Token.SELECT) { lexer.nextToken(); + + if (lexer.token() == Token.COMMENT) { + lexer.nextToken(); + } parseHints(queryBlock); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java index 84d52d4b47..f367cb814c 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java @@ -1462,6 +1462,10 @@ public class OracleStatementParser extends SQLStatementParser { if (lexer.token() == Token.DELETE) { lexer.nextToken(); + + if (lexer.token() == Token.COMMENT) { + lexer.nextToken(); + } parseHints(deleteStatement.getHints()); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGInsertStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGInsertStatement.java index f07a3b9eec..1cd0dde67e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGInsertStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGInsertStatement.java @@ -66,6 +66,11 @@ public class PGInsertStatement extends SQLInsertStatement implements PGSQLStatem public List getValuesList() { return valuesList; } + + public void addValueCause(ValuesClause valueClause) { + valueClause.setParent(this); + valuesList.add(valueClause); + } protected void accept0(SQLASTVisitor visitor) { accept0((PGASTVisitor) visitor); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java index e8cb151bc2..30750644ab 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java @@ -110,9 +110,10 @@ public class PGSQLStatementParser extends SQLStatementParser { for (;;) { accept(Token.LPAREN); - SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause(); - this.exprParser.exprList(values.getValues()); - stmt.getValuesList().add(values); + SQLInsertStatement.ValuesClause valuesCaluse = new SQLInsertStatement.ValuesClause(); + this.exprParser.exprList(valuesCaluse.getValues()); + stmt.addValueCause(valuesCaluse); + accept(Token.RPAREN); if (lexer.token() == Token.COMMA) { lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java index 743122bcb3..8ce42e0cb7 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java @@ -52,6 +52,10 @@ public class PGSelectParser extends SQLSelectParser { if (lexer.token() == Token.SELECT) { lexer.nextToken(); + + if (lexer.token() == Token.COMMENT) { + lexer.nextToken(); + } if (lexer.token() == Token.DISTINCT) { queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerSelectParser.java index ee69d85354..5db2dd4994 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerSelectParser.java @@ -66,6 +66,10 @@ public class SQLServerSelectParser extends SQLSelectParser { if (lexer.token() == Token.SELECT) { lexer.nextToken(); + + if (lexer.token() == Token.COMMENT) { + lexer.nextToken(); + } if (lexer.token() == Token.DISTINCT) { queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT); diff --git a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java index 267d07491e..1283bf9528 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -68,10 +68,20 @@ public class Lexer { private int varIndex = -1; + protected CommentHandler commentHandler; + public Lexer(String input){ this(input, true); } + public CommentHandler getCommentHandler() { + return commentHandler; + } + + public void setCommentHandler(CommentHandler commentHandler) { + this.commentHandler = commentHandler; + } + public final char charAt(int index) { if (index >= text.length()) { return EOI; @@ -1008,4 +1018,9 @@ public class Lexer { public BigDecimal decimalValue() { return new BigDecimal(text.toCharArray(), mark, bufPos); } + + public static interface CommentHandler { + + boolean handle(Token lastToken, String comment); + } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/NotAllowCommentException.java b/src/main/java/com/alibaba/druid/sql/parser/NotAllowCommentException.java index 1dbe8d3f83..21ec93ba69 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/NotAllowCommentException.java +++ b/src/main/java/com/alibaba/druid/sql/parser/NotAllowCommentException.java @@ -20,7 +20,7 @@ public class NotAllowCommentException extends ParserException { private static final long serialVersionUID = 1L; public NotAllowCommentException(){ - super(); + this("comment not allow"); } public NotAllowCommentException(String message, Throwable e){ diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java index 53c0afe809..7487e8b2b7 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java @@ -141,6 +141,10 @@ public class SQLSelectParser extends SQLParser { } accept(Token.SELECT); + + if (lexer.token() == Token.COMMENT) { + lexer.nextToken(); + } SQLSelectQueryBlock queryBlock = new SQLSelectQueryBlock(); 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 d34bee1e6d..d34f71c4c7 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -617,6 +617,10 @@ public class SQLStatementParser extends SQLParser { if (lexer.token() == (Token.FROM)) { lexer.nextToken(); } + + if (lexer.token() == Token.COMMENT) { + lexer.nextToken(); + } SQLName tableName = exprParser.name(); diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java index 9a5f61e649..f1cefe8b41 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java @@ -62,6 +62,7 @@ import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropForeinKey; import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropIndex; import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropPrimaryKey; import com.alibaba.druid.sql.ast.statement.SQLAlterTableEnableKeys; +import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; import com.alibaba.druid.sql.ast.statement.SQLAssignItem; import com.alibaba.druid.sql.ast.statement.SQLCallStatement; import com.alibaba.druid.sql.ast.statement.SQLCharactorDataType; @@ -449,4 +450,8 @@ public interface SQLASTVisitor { boolean visit(SQLAlterTableEnableKeys x); void endVisit(SQLAlterTableEnableKeys x); + + boolean visit(SQLAlterTableStatement x); + + void endVisit(SQLAlterTableStatement x); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java index 9f80ac7596..afe0b2ad3b 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java @@ -62,6 +62,7 @@ import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropForeinKey; import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropIndex; import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropPrimaryKey; import com.alibaba.druid.sql.ast.statement.SQLAlterTableEnableKeys; +import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; import com.alibaba.druid.sql.ast.statement.SQLAssignItem; import com.alibaba.druid.sql.ast.statement.SQLCallStatement; import com.alibaba.druid.sql.ast.statement.SQLCharactorDataType; @@ -831,4 +832,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { public void endVisit(SQLAlterTableEnableKeys x) { } + + @Override + public boolean visit(SQLAlterTableStatement x) { + return true; + } + + @Override + public void endVisit(SQLAlterTableStatement x) { + + } } diff --git a/src/main/java/com/alibaba/druid/wall/WallConfig.java b/src/main/java/com/alibaba/druid/wall/WallConfig.java index 08e98d9097..ac9e41ff9f 100644 --- a/src/main/java/com/alibaba/druid/wall/WallConfig.java +++ b/src/main/java/com/alibaba/druid/wall/WallConfig.java @@ -33,6 +33,9 @@ public class WallConfig implements WallConfigMBean { private boolean selectWhereAlwayTrueCheck = true; private boolean selectHavingAlwayTrueCheck = true; private boolean selectUnionCheck = true; + private boolean createTableAllow = false; + private boolean dropTableAllow = false; + private boolean alterTableAllow = false; private boolean selectAllColumnAllow = true; @@ -285,6 +288,30 @@ public class WallConfig implements WallConfigMBean { this.selectIntoOutfileAllow = selectIntoOutfileAllow; } + public boolean isCreateTableAllow() { + return createTableAllow; + } + + public void setCreateTableAllow(boolean createTableAllow) { + this.createTableAllow = createTableAllow; + } + + public boolean isDropTableAllow() { + return dropTableAllow; + } + + public void setDropTableAllow(boolean dropTableAllow) { + this.dropTableAllow = dropTableAllow; + } + + public boolean isAlterTableAllow() { + return alterTableAllow; + } + + public void setAlterTableAllow(boolean alterTableAllow) { + this.alterTableAllow = alterTableAllow; + } + public boolean isSelectUnionCheck() { return selectUnionCheck; } diff --git a/src/main/java/com/alibaba/druid/wall/WallContext.java b/src/main/java/com/alibaba/druid/wall/WallContext.java index 59dd7ecc4d..7aabe333e2 100644 --- a/src/main/java/com/alibaba/druid/wall/WallContext.java +++ b/src/main/java/com/alibaba/druid/wall/WallContext.java @@ -15,17 +15,40 @@ */ package com.alibaba.druid.wall; +import java.util.HashMap; +import java.util.Map; + public class WallContext { private final static ThreadLocal contextLocal = new ThreadLocal(); private WallSqlStat sqlState; + private Map tableStats; private final String dbType; public WallContext(String dbType){ this.dbType = dbType; } + public WallSqlTableStat getTableStat(String tableName) { + if (tableStats == null) { + tableStats = new HashMap(2); + } + + String lowerCaseName = tableName.toLowerCase(); + + WallSqlTableStat stat = tableStats.get(lowerCaseName); + if (stat == null) { + if (tableStats.size() > 10000) { + return null; + } + + stat = new WallSqlTableStat(); + tableStats.put(tableName, stat); + } + return stat; + } + public static WallContext createIfNotExists(String dbType) { WallContext context = contextLocal.get(); if (context == null) { @@ -35,6 +58,12 @@ public class WallContext { return context; } + public static WallContext create(String dbType) { + WallContext context = new WallContext(dbType); + contextLocal.set(context); + return context; + } + public static WallContext current() { return contextLocal.get(); } @@ -51,6 +80,10 @@ public class WallContext { this.sqlState = sqlState; } + public Map getTableStats() { + return tableStats; + } + public String getDbType() { return dbType; } diff --git a/src/main/java/com/alibaba/druid/wall/WallProvider.java b/src/main/java/com/alibaba/druid/wall/WallProvider.java index 9980d7a782..fcbd955796 100644 --- a/src/main/java/com/alibaba/druid/wall/WallProvider.java +++ b/src/main/java/com/alibaba/druid/wall/WallProvider.java @@ -16,14 +16,18 @@ package com.alibaba.druid.wall; import java.security.PrivilegedAction; +import java.util.Collections; import java.util.HashSet; -import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReentrantReadWriteLock; import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.Lexer; import com.alibaba.druid.sql.parser.NotAllowCommentException; import com.alibaba.druid.sql.parser.ParserException; import com.alibaba.druid.sql.parser.SQLStatementParser; @@ -36,25 +40,36 @@ import com.alibaba.druid.wall.violation.SyntaxErrorViolation; public abstract class WallProvider { - private LinkedHashMap whiteList; + private LRUCache whiteList; - private int whileListMaxSize = 1024; + private int MAX_SQL_SIZE = 2048; // 1k - private int whiteSqlMaxLength = 1024; // 1k + private int whiteSqlMaxLength = 1024; // 1k - protected final WallConfig config; + private LRUCache blackList; - private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + private int blackSqlMaxLength = 1024; // 1k - private static final ThreadLocal privileged = new ThreadLocal(); + protected final WallConfig config; - private final ConcurrentMap deniedTables = new ConcurrentHashMap(); - private final ConcurrentMap deniedFunctions = new ConcurrentHashMap(); - private final ConcurrentMap deniedSchemas = new ConcurrentHashMap(); + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - public final WallDenyStat commentDeniedStat = new WallDenyStat(); + private static final ThreadLocal privileged = new ThreadLocal(); - protected String dbType = null; + private final ConcurrentMap deniedTables = new ConcurrentHashMap(); + private final ConcurrentMap deniedFunctions = new ConcurrentHashMap(); + private final ConcurrentMap deniedSchemas = new ConcurrentHashMap(); + + private final ConcurrentMap tableStats = new ConcurrentHashMap(); + + public final WallDenyStat commentDeniedStat = new WallDenyStat(); + + protected String dbType = null; + protected AtomicLong checkCount = new AtomicLong(); + protected AtomicLong whiteListHitCount = new AtomicLong(); + protected AtomicLong blackListHitCount = new AtomicLong(); + protected AtomicLong syntaxErrrorCount = new AtomicLong(); + protected AtomicLong violationCount = new AtomicLong(); public WallProvider(WallConfig config){ this.config = config; @@ -65,18 +80,70 @@ public abstract class WallProvider { this.dbType = dbType; } + public void reset() { + this.clearWhiteList(); + this.deniedTables.clear(); + this.deniedFunctions.clear(); + this.deniedSchemas.clear(); + this.tableStats.clear(); + } + + public ConcurrentMap getTableStats() { + return this.tableStats; + } + + public WallTableStat getTableStat(String tableName) { + String lowerCaseName = tableName.toLowerCase(); + + WallTableStat stat = tableStats.get(lowerCaseName); + if (stat == null) { + if (tableStats.size() > 10000) { + return null; + } + + tableStats.putIfAbsent(lowerCaseName, new WallTableStat()); + stat = tableStats.get(lowerCaseName); + } + return stat; + } + public WallConfig getConfig() { return config; } - public void addWhiteSql(String sql) { + public WallSqlStat addWhiteSql(String sql, Map tableStats) { lock.writeLock().lock(); try { if (whiteList == null) { - whiteList = new LRUCache(whileListMaxSize); + whiteList = new LRUCache(whiteSqlMaxLength); } - whiteList.put(sql, new WallSqlStat()); + WallSqlStat wallStat = whiteList.get(sql); + if (wallStat == null) { + wallStat = new WallSqlStat(tableStats); + whiteList.put(sql, wallStat); + } + + return wallStat; + } finally { + lock.writeLock().unlock(); + } + } + + public WallSqlStat addBlackSql(String sql, Map tableStats, List violations) { + lock.writeLock().lock(); + try { + if (blackList == null) { + blackList = new LRUCache(blackSqlMaxLength); + } + + WallSqlStat wallStat = blackList.get(sql); + if (wallStat == null) { + wallStat = new WallSqlStat(tableStats, violations); + blackList.put(sql, wallStat); + } + + return wallStat; } finally { lock.writeLock().unlock(); } @@ -93,7 +160,21 @@ public abstract class WallProvider { lock.readLock().unlock(); } - return hashSet; + return Collections. unmodifiableSet(hashSet); + } + + public Set getBlackList() { + Set hashSet = new HashSet(); + lock.readLock().lock(); + try { + if (blackList != null) { + hashSet.addAll(blackList.keySet()); + } + } finally { + lock.readLock().unlock(); + } + + return Collections. unmodifiableSet(hashSet); } public void clearCache() { @@ -124,6 +205,19 @@ public abstract class WallProvider { } } + public WallSqlStat getBlackSql(String sql) { + lock.readLock().lock(); + try { + if (blackList == null) { + return null; + } + + return blackList.get(sql); + } finally { + lock.readLock().unlock(); + } + } + public boolean whiteContains(String sql) { return getWhiteSql(sql) != null; } @@ -138,10 +232,11 @@ public abstract class WallProvider { WallContext originalContext = WallContext.current(); try { - WallContext.createIfNotExists(dbType); - WallCheckResult result = check(sql); + WallContext.create(dbType); + WallCheckResult result = checkInternal(sql); return result.getViolations().isEmpty(); } finally { + if (originalContext == null) { WallContext.clearContext(); } @@ -251,6 +346,21 @@ public abstract class WallProvider { } public WallCheckResult check(String sql) { + WallContext originalContext = WallContext.current(); + + try { + WallContext.create(dbType); + return checkInternal(sql); + } finally { + if (originalContext == null) { + WallContext.clearContext(); + } + } + } + + public WallCheckResult checkInternal(String sql) { + checkCount.incrementAndGet(); + WallContext context = WallContext.current(); if (context != null && !this.dbType.equals(context.getDbType())) { @@ -265,14 +375,53 @@ public abstract class WallProvider { } // first step, check whiteList - WallSqlStat sqlStat = getWhiteSql(sql); - if (sqlStat != null) { - sqlStat.incrementAndGetExecuteCount(); - return result; + { + WallSqlStat sqlStat = getWhiteSql(sql); + if (sqlStat != null) { + whiteListHitCount.incrementAndGet(); + sqlStat.incrementAndGetExecuteCount(); + + if (sqlStat.getTableStats() != null) { + for (Map.Entry entry : sqlStat.getTableStats().entrySet()) { + String tableName = entry.getKey(); + WallSqlTableStat sqlTableStat = entry.getValue(); + WallTableStat tableStat = getTableStat(tableName); + if (tableStat != null) { + tableStat.addSqlTableStat(sqlTableStat); + } + } + } + return result; + } + } + // check black list + { + WallSqlStat sqlStat = getBlackSql(sql); + if (sqlStat != null) { + blackListHitCount.incrementAndGet(); + sqlStat.incrementAndGetExecuteCount(); + + if (sqlStat.getTableStats() != null) { + for (Map.Entry entry : sqlStat.getTableStats().entrySet()) { + String tableName = entry.getKey(); + WallSqlTableStat sqlTableStat = entry.getValue(); + WallTableStat tableStat = getTableStat(tableName); + if (tableStat != null) { + tableStat.addSqlTableStat(sqlTableStat); + } + } + } + + List blackViolations = sqlStat.getViolations(); + + result.getViolations().addAll(blackViolations); + return result; + } } try { SQLStatementParser parser = createParser(sql); + parser.getLexer().setCommentHandler(WallCommentHandler.instance); if (!config.isCommentAllow()) { parser.getLexer().setAllowComment(false); // deny comment @@ -283,49 +432,62 @@ public abstract class WallProvider { final Token lastToken = parser.getLexer().token(); if (lastToken != Token.EOF) { result.getViolations().add(new IllegalSQLObjectViolation("not terminal sql, token " + lastToken, sql)); - return result; } } catch (NotAllowCommentException e) { result.getViolations().add(new SyntaxErrorViolation(e, sql)); incrementCommentDeniedCount(); - return result; } catch (ParserException e) { + syntaxErrrorCount.incrementAndGet(); if (config.isStrictSyntaxCheck()) { result.getViolations().add(new SyntaxErrorViolation(e, sql)); } - return result; } catch (Exception e) { result.getViolations().add(new SyntaxErrorViolation(e, sql)); - return result; } - if (result.getStatementList().size() == 0) { - return result; - } - - if (result.getStatementList().size() > 1 && !config.isMultiStatementAllow()) { + if (result.getViolations().size() == 0 && result.getStatementList().size() > 1 + && !config.isMultiStatementAllow()) { result.getViolations().add(new IllegalSQLObjectViolation("multi-statement not allow", sql)); - return result; } - SQLStatement stmt = result.getStatementList().get(0); - WallVisitor visitor = createWallVisitor(); - try { - stmt.accept(visitor); - } catch (ParserException e) { - result.getViolations().add(new SyntaxErrorViolation(e, sql)); - return result; + if (result.getStatementList().size() > 0) { + SQLStatement stmt = result.getStatementList().get(0); + try { + stmt.accept(visitor); + } catch (ParserException e) { + result.getViolations().add(new SyntaxErrorViolation(e, sql)); + } } - if (visitor.getViolations().size() == 0) { - if (sql.length() < whiteSqlMaxLength) { - this.addWhiteSql(sql); + if (visitor.getViolations().size() > 0) { + result.getViolations().addAll(visitor.getViolations()); + } + + if (result.getViolations().size() > 0) { + violationCount.incrementAndGet(); + + if (sql.length() < MAX_SQL_SIZE) { + addBlackSql(sql, context.getTableStats(), result.getViolations()); + } + } else { + if (sql.length() < MAX_SQL_SIZE) { + addWhiteSql(sql, context.getTableStats()); + } + } + + if (context != null && context.getTableStats() != null) { + for (Map.Entry entry : context.getTableStats().entrySet()) { + String tableName = entry.getKey(); + WallSqlTableStat sqlTableStat = entry.getValue(); + WallTableStat tableStat = getTableStat(tableName); + if (tableStat != null) { + tableStat.addSqlTableStat(sqlTableStat); + } } } - result.getViolations().addAll(visitor.getViolations()); return result; } @@ -356,4 +518,53 @@ public abstract class WallProvider { public static Object getTenantValue() { return tenantValueLocal.get(); } + + public long getWhiteListHitCount() { + return whiteListHitCount.get(); + } + + public long getBlackListHitCount() { + return blackListHitCount.get(); + } + + public long getSyntaxErrorCount() { + return syntaxErrrorCount.get(); + } + + public long getCheckCount() { + return checkCount.get(); + } + + public long getViolationCount() { + return violationCount.get(); + } + + public static class WallCommentHandler implements Lexer.CommentHandler { + public final static WallCommentHandler instance = new WallCommentHandler(); + + @Override + public boolean handle(Token lastToken, String comment) { + if (lastToken == null) { + return false; + } + + switch (lastToken) { + case SELECT: + case INSERT: + case DELETE: + case UPDATE: + case TRUNCATE: + case SET: + case CREATE: + case ALTER: + case DROP: + return true; + default: + break; + } + + return false; + } + + } } diff --git a/src/main/java/com/alibaba/druid/wall/WallSqlStat.java b/src/main/java/com/alibaba/druid/wall/WallSqlStat.java index c91e939fd3..52030a5925 100644 --- a/src/main/java/com/alibaba/druid/wall/WallSqlStat.java +++ b/src/main/java/com/alibaba/druid/wall/WallSqlStat.java @@ -15,6 +15,9 @@ */ package com.alibaba.druid.wall; +import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicLongFieldUpdater; public class WallSqlStat { @@ -23,6 +26,18 @@ public class WallSqlStat { final static AtomicLongFieldUpdater executeCountUpdater = AtomicLongFieldUpdater.newUpdater(WallSqlStat.class, "executeCount"); + private final Map tableStats; + + private final List violations; + + public WallSqlStat(Map tableStats){ + this(tableStats, Collections. emptyList()); + } + + public WallSqlStat(Map tableStats, List violations){ + this.violations = violations; + this.tableStats = tableStats; + } public long incrementAndGetExecuteCount() { return executeCountUpdater.incrementAndGet(this); @@ -31,5 +46,13 @@ public class WallSqlStat { public long getExecuteCount() { return executeCount; } - + + public Map getTableStats() { + return tableStats; + } + + public List getViolations() { + return violations; + } + } diff --git a/src/main/java/com/alibaba/druid/wall/WallSqlTableStat.java b/src/main/java/com/alibaba/druid/wall/WallSqlTableStat.java new file mode 100644 index 0000000000..36e8ce1112 --- /dev/null +++ b/src/main/java/com/alibaba/druid/wall/WallSqlTableStat.java @@ -0,0 +1,102 @@ +package com.alibaba.druid.wall; + +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +public class WallSqlTableStat { + + private int selectCount; + private int selectIntoCount; + private int insertCount; + private int updateCount; + private int deleteCount; + private int truncateCount; + private int createCount; + private int alterCount; + private int dropCount; + + public int getSelectCount() { + return selectCount; + } + + public void incrementSelectCount() { + this.selectCount++; + } + + public int getSelectIntoCount() { + return selectIntoCount; + } + + public void incrementSelectIntoCount() { + this.selectIntoCount++; + } + + public int getInsertCount() { + return insertCount; + } + + public void incrementInsertCount() { + this.insertCount++; + } + + public int getUpdateCount() { + return updateCount; + } + + public void incrementUpdateCount() { + this.updateCount++; + } + + public int getDeleteCount() { + return deleteCount; + } + + public void incrementDeleteCount() { + this.deleteCount++; + } + + public int getTruncateCount() { + return truncateCount; + } + + public void incrementTruncateCount() { + this.truncateCount++; + } + + public int getCreateCount() { + return createCount; + } + + public void incrementCreateCount() { + this.createCount++; + } + + public int getAlterCount() { + return alterCount; + } + + public void incrementAlterCount() { + this.alterCount++; + } + + public int getDropCount() { + return dropCount; + } + + public void incrementDropCount() { + this.dropCount++; + } + +} diff --git a/src/main/java/com/alibaba/druid/wall/WallTableStat.java b/src/main/java/com/alibaba/druid/wall/WallTableStat.java new file mode 100644 index 0000000000..c6621f406c --- /dev/null +++ b/src/main/java/com/alibaba/druid/wall/WallTableStat.java @@ -0,0 +1,182 @@ +package com.alibaba.druid.wall; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; + +import com.alibaba.druid.support.json.JSONUtils; + +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +public class WallTableStat { + + private volatile long selectCount; + private volatile long selectIntoCount; + private volatile long insertCount; + private volatile long updateCount; + private volatile long deleteCount; + private volatile long truncateCount; + private volatile long createCount; + private volatile long alterCount; + private volatile long dropCount; + + final static AtomicLongFieldUpdater selectCountUpdater = AtomicLongFieldUpdater.newUpdater(WallTableStat.class, + "selectCount"); + final static AtomicLongFieldUpdater selectIntoCountUpdater = AtomicLongFieldUpdater.newUpdater(WallTableStat.class, + "selectIntoCount"); + final static AtomicLongFieldUpdater insertCountUpdater = AtomicLongFieldUpdater.newUpdater(WallTableStat.class, + "insertCount"); + final static AtomicLongFieldUpdater updateCountUpdater = AtomicLongFieldUpdater.newUpdater(WallTableStat.class, + "updateCount"); + final static AtomicLongFieldUpdater deleteCountUpdater = AtomicLongFieldUpdater.newUpdater(WallTableStat.class, + "deleteCount"); + final static AtomicLongFieldUpdater truncateCountUpdater = AtomicLongFieldUpdater.newUpdater(WallTableStat.class, + "truncateCount"); + final static AtomicLongFieldUpdater createCountUpdater = AtomicLongFieldUpdater.newUpdater(WallTableStat.class, + "createCount"); + final static AtomicLongFieldUpdater alterCountUpdater = AtomicLongFieldUpdater.newUpdater(WallTableStat.class, + "alterCount"); + final static AtomicLongFieldUpdater dropCountUpdater = AtomicLongFieldUpdater.newUpdater(WallTableStat.class, + "dropCount"); + + public WallTableStat(){ + + } + + public long getSelectCount() { + return selectCount; + } + + public long getSelectIntoCount() { + return selectIntoCount; + } + + public long getInsertCount() { + return insertCount; + } + + public long getUpdateCount() { + return updateCount; + } + + public long getDeleteCount() { + return deleteCount; + } + + public long getTruncateCount() { + return truncateCount; + } + + public long getCreateCount() { + return createCount; + } + + public long getAlterCount() { + return alterCount; + } + + public long getDropCount() { + return dropCount; + } + + public void addSqlTableStat(WallSqlTableStat stat) { + { + long val = stat.getSelectCount(); + if (val > 0) { + selectCountUpdater.addAndGet(this, val); + } + } + { + long val = stat.getSelectIntoCount(); + if (val > 0) { + selectIntoCountUpdater.addAndGet(this, val); + } + } + { + long val = stat.getInsertCount(); + if (val > 0) { + insertCountUpdater.addAndGet(this, val); + } + } + { + long val = stat.getUpdateCount(); + if (val > 0) { + updateCountUpdater.addAndGet(this, val); + } + } + { + long val = stat.getDeleteCount(); + if (val > 0) { + deleteCountUpdater.addAndGet(this, val); + } + } + { + long val = stat.getAlterCount(); + if (val > 0) { + alterCountUpdater.addAndGet(this, val); + } + } + { + long val = stat.getTruncateCount(); + if (val > 0) { + truncateCountUpdater.addAndGet(this, val); + } + } + { + long val = stat.getCreateCount(); + if (val > 0) { + createCountUpdater.addAndGet(this, val); + } + } + { + long val = stat.getDropCount(); + if (val > 0) { + dropCountUpdater.addAndGet(this, val); + } + } + } + + public String toString() { + + Map map = new HashMap(); + if (selectCount > 0) { + map.put("selectCount", selectCount); + } + if (deleteCount > 0) { + map.put("deleteCount", deleteCount); + } + if (insertCount > 0) { + map.put("insertCount", insertCount); + } + if (updateCount > 0) { + map.put("updateCount", updateCount); + } + if (alterCount > 0) { + map.put("alterCount", alterCount); + } + if (dropCount > 0) { + map.put("dropCount", dropCount); + } + if (createCount > 0) { + map.put("createCount", createCount); + } + if (truncateCount > 0) { + map.put("truncateCount", truncateCount); + } + + return JSONUtils.toJSONString(map); + } +} diff --git a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java index 517e2b9191..3bb1594b8a 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java @@ -21,36 +21,33 @@ import java.util.List; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObject; -import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLInListExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; -import com.alibaba.druid.sql.ast.statement.SQLCallStatement; +import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; +import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; -import com.alibaba.druid.sql.ast.statement.SQLSetStatement; -import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDropTableStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; @@ -190,6 +187,16 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi } if (config.isVariantCheck() && varName.startsWith("@@")) { + if ("@@session".equals(varName)) { + SQLObject parent = x.getParent(); + if (parent instanceof SQLPropertyExpr) { + String propName = ((SQLPropertyExpr) parent).getName(); + if (propName.equals("auto_increment_increment")) { + return false; + } + } + } + violations.add(new IllegalSQLObjectViolation("global variable", toSQL(x))); } @@ -251,56 +258,7 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi } public void preVisit(SQLObject x) { - if (!(x instanceof SQLStatement)) { - return; - } - - boolean allow = false; - String denyMessage = null; - if (x instanceof SQLInsertStatement) { - allow = true; - denyMessage = "insert not allow"; - } else if (x instanceof SQLSelectStatement) { - allow = true; - denyMessage = "select not allow"; - } else if (x instanceof SQLDeleteStatement) { - allow = true; - denyMessage = "delete not allow"; - } else if (x instanceof SQLUpdateStatement) { - allow = true; - denyMessage = "update not allow"; - } else if (x instanceof SQLCallStatement) { - allow = true; - denyMessage = "call not allow"; - } else if (x instanceof SQLTruncateStatement) { - allow = config.isTruncateAllow(); - denyMessage = "truncate not allow"; - } else if (x instanceof MySqlDescribeStatement) { - allow = config.isDescribeAllow(); - denyMessage = "describe not allow"; - } else if (x instanceof MySqlReplaceStatement) { - allow = config.isReplaceAllow(); - denyMessage = "replace not allow"; - } else if (x instanceof MySqlSetCharSetStatement // - || x instanceof MySqlSetNamesStatement // - || x instanceof SQLSetStatement) { - allow = config.isSetAllow(); - denyMessage = "set not allow"; - } else if (x instanceof MySqlShowStatement) { - allow = config.isShowAllow(); - denyMessage = "show not allow"; - } else { - if (config.isNoneBaseStatementAllow()) { - return; - } - } - - if (!allow) { - if (denyMessage == null) { - denyMessage = x.getClass() + " not allow"; - } - violations.add(new IllegalSQLObjectViolation(denyMessage + " not allow", toSQL(x))); - } + WallVisitorUtils.preVisitCheck(this, x); } @Override @@ -308,4 +266,38 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi WallVisitorUtils.check(this, x); return true; } + + @Override + public boolean visit(SQLCreateTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(MySqlCreateTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + public boolean visit(SQLAlterTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(MySqlAlterTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + public boolean visit(SQLDropTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(MySqlDropTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java index 57ceaf436d..ad630467f0 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java @@ -21,26 +21,27 @@ import java.util.List; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObject; -import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLInListExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; -import com.alibaba.druid.sql.ast.statement.SQLCallStatement; +import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; +import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; -import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.InsertIntoClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock; @@ -170,36 +171,7 @@ public class OracleWallVisitor extends OracleASTVisitorAdapter implements WallVi } public void preVisit(SQLObject x) { - if (!(x instanceof SQLStatement)) { - return; - } - - if (config.isNoneBaseStatementAllow()) { - return; - } - - boolean allow = false; - if (x instanceof SQLInsertStatement) { - allow = true; - } else if (x instanceof SQLSelectStatement) { - allow = true; - } else if (x instanceof SQLDeleteStatement) { - allow = true; - } else if (x instanceof SQLUpdateStatement) { - allow = true; - } else if (x instanceof OracleMultiInsertStatement) { - allow = true; - } else if (x instanceof OracleMergeStatement) { - allow = true; - } else if (x instanceof SQLCallStatement) { - allow = true; - } else if (x instanceof SQLTruncateStatement) { - allow = config.isTruncateAllow(); - } - - if (!allow) { - violations.add(new IllegalSQLObjectViolation("not allow statement", toSQL(x))); - } + WallVisitorUtils.preVisitCheck(this, x); } @Override @@ -269,4 +241,34 @@ public class OracleWallVisitor extends OracleASTVisitorAdapter implements WallVi WallVisitorUtils.check(this, x); return true; } + + @Override + public boolean visit(SQLCreateTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(OracleCreateTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLAlterTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(OracleAlterTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLDropTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java index 9b868922aa..aa54fe7521 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java @@ -21,26 +21,25 @@ import java.util.List; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObject; -import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLInListExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; -import com.alibaba.druid.sql.ast.statement.SQLCallStatement; +import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; +import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; -import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference; +import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock; import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitorAdapter; import com.alibaba.druid.wall.Violation; import com.alibaba.druid.wall.WallConfig; @@ -131,6 +130,13 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { return true; } + + @Override + public boolean visit(PGSelectQueryBlock x) { + WallVisitorUtils.checkSelelct(this, x); + + return true; + } @Override public boolean visit(SQLUnionQuery x) { @@ -158,36 +164,7 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { } public void preVisit(SQLObject x) { - if (!(x instanceof SQLStatement)) { - return; - } - - if (config.isNoneBaseStatementAllow()) { - return; - } - - boolean allow = false; - if (x instanceof SQLInsertStatement) { - allow = true; - } else if (x instanceof SQLSelectStatement) { - allow = true; - } else if (x instanceof SQLDeleteStatement) { - allow = true; - } else if (x instanceof SQLUpdateStatement) { - allow = true; - } else if (x instanceof OracleMultiInsertStatement) { - allow = true; - } else if (x instanceof OracleMergeStatement) { - allow = true; - } else if (x instanceof SQLCallStatement) { - allow = true; - } else if (x instanceof SQLTruncateStatement) { - allow = config.isTruncateAllow(); - } - - if (!allow) { - violations.add(new IllegalSQLObjectViolation("not allow statement", toSQL(x))); - } + WallVisitorUtils.preVisitCheck(this, x); } @Override @@ -225,4 +202,22 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { WallVisitorUtils.check(this, x); return true; } + + @Override + public boolean visit(SQLCreateTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLAlterTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLDropTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java index a6fac68760..ff8e774367 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java @@ -21,22 +21,22 @@ import java.util.List; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObject; -import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLInListExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; -import com.alibaba.druid.sql.ast.statement.SQLCallStatement; +import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; +import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; -import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; @@ -161,32 +161,7 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements } public void preVisit(SQLObject x) { - if (!(x instanceof SQLStatement)) { - return; - } - - if (config.isNoneBaseStatementAllow()) { - return; - } - - boolean allow = false; - if (x instanceof SQLInsertStatement) { - allow = true; - } else if (x instanceof SQLSelectStatement) { - allow = true; - } else if (x instanceof SQLDeleteStatement) { - allow = true; - } else if (x instanceof SQLUpdateStatement) { - allow = true; - } else if (x instanceof SQLCallStatement) { - allow = true; - } else if (x instanceof SQLTruncateStatement) { - allow = config.isTruncateAllow(); - } - - if (!allow) { - violations.add(new IllegalSQLObjectViolation("not allow statement", toSQL(x))); - } + WallVisitorUtils.preVisitCheck(this, x); } @Override @@ -201,11 +176,7 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements @Override public boolean visit(SQLInsertStatement x) { - if (!config.isInsertAllow()) { - this.getViolations().add(new IllegalSQLObjectViolation("insert not allow", this.toSQL(x))); - return false; - } - + WallVisitorUtils.checkInsert(this, x); return true; } @@ -249,8 +220,7 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements @Override public boolean visit(SQLServerInsertStatement x) { - this.visit((SQLInsertStatement) x); - return false; + return this.visit((SQLInsertStatement) x); } @Override @@ -263,4 +233,22 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements WallVisitorUtils.check(this, x); return true; } + + @Override + public boolean visit(SQLCreateTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLAlterTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLDropTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java index 4ba2b46c97..a0d844a684 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -29,6 +29,7 @@ import java.util.Set; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr; import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; @@ -44,29 +45,46 @@ import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; +import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCallStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; +import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLInsertInto; +import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.ast.statement.SQLSetStatement; import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableSource; +import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionOperator; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement; import com.alibaba.druid.sql.visitor.ExportParameterVisitor; import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils; import com.alibaba.druid.support.logging.Log; import com.alibaba.druid.support.logging.LogFactory; import com.alibaba.druid.util.JdbcUtils; import com.alibaba.druid.util.ServletPathMatcher; +import com.alibaba.druid.wall.WallConfig; import com.alibaba.druid.wall.WallContext; import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallSqlTableStat; import com.alibaba.druid.wall.WallVisitor; import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation; @@ -82,6 +100,44 @@ public class WallVisitorUtils { } + public static void check(WallVisitor visitor, SQLCreateTableStatement x) { + String tableName = ((SQLName) x.getName()).getSimleName(); + WallContext context = WallContext.current(); + if (context != null) { + WallSqlTableStat tableStat = context.getTableStat(tableName); + if (tableStat != null) { + tableStat.incrementCreateCount(); + } + } + } + + public static void check(WallVisitor visitor, SQLAlterTableStatement x) { + String tableName = ((SQLName) x.getName()).getSimleName(); + WallContext context = WallContext.current(); + if (context != null) { + WallSqlTableStat tableStat = context.getTableStat(tableName); + if (tableStat != null) { + tableStat.incrementAlterCount(); + } + } + } + + public static void check(WallVisitor visitor, SQLDropTableStatement x) { + for (SQLTableSource item : x.getTableSources()) { + if (item instanceof SQLExprTableSource) { + SQLExpr expr = ((SQLExprTableSource) item).getExpr(); + String tableName = ((SQLName) expr).getSimleName(); + WallContext context = WallContext.current(); + if (context != null) { + WallSqlTableStat tableStat = context.getTableStat(tableName); + if (tableStat != null) { + tableStat.incrementDropCount(); + } + } + } + } + } + public static void check(WallVisitor visitor, SQLSelectItem x) { if (visitor.getConfig().isSelectAllColumnAllow()) { return; @@ -124,6 +180,10 @@ public class WallVisitorUtils { return; } + if (x.getFrom() != null) { + x.getFrom().setParent(x); + } + SQLExpr where = x.getWhere(); if (where != null) { @@ -777,6 +837,36 @@ public class WallVisitorUtils { if (expr instanceof SQLName) { String tableName = ((SQLName) expr).getSimleName(); + + WallContext context = WallContext.current(); + if (context != null) { + WallSqlTableStat tableStat = context.getTableStat(tableName); + if (tableStat != null) { + SQLObject parent = x.getParent(); + + while (parent instanceof SQLTableSource) { + parent = parent.getParent(); + } + + if (parent instanceof SQLSelectQueryBlock) { + SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) parent; + if (x == queryBlock.getInto()) { + tableStat.incrementSelectIntoCount(); + } else { + tableStat.incrementSelectCount(); + } + } else if (parent instanceof SQLTruncateStatement) { + tableStat.incrementTruncateCount(); + } else if (parent instanceof SQLInsertStatement) { + tableStat.incrementInsertCount(); + } else if (parent instanceof SQLDeleteStatement) { + tableStat.incrementDeleteCount(); + } else if (parent instanceof SQLUpdateStatement) { + tableStat.incrementUpdateCount(); + } + } + } + if (visitor.isDenyTable(tableName)) { addViolation(visitor, "deny table : " + tableName, x); return false; @@ -901,4 +991,72 @@ public class WallVisitorUtils { LOG.error("load oracle deny tables errror", e); } } + + public static void preVisitCheck(WallVisitor visitor, SQLObject x) { + WallConfig config = visitor.getProvider().getConfig(); + + if (!(x instanceof SQLStatement)) { + return; + } + + boolean allow = false; + String denyMessage = null; + if (x instanceof SQLInsertStatement) { + allow = true; + denyMessage = "insert not allow"; + } else if (x instanceof SQLSelectStatement) { + allow = true; + denyMessage = "select not allow"; + } else if (x instanceof SQLDeleteStatement) { + allow = true; + denyMessage = "delete not allow"; + } else if (x instanceof SQLUpdateStatement) { + allow = true; + denyMessage = "update not allow"; + } else if (x instanceof OracleMultiInsertStatement) { + allow = true; + denyMessage = "multi-insert not allow"; + } else if (x instanceof OracleMergeStatement) { + allow = true; + denyMessage = "merge not allow"; + } else if (x instanceof SQLCallStatement) { + allow = true; + denyMessage = "call not allow"; + } else if (x instanceof SQLTruncateStatement) { + allow = config.isTruncateAllow(); + denyMessage = "truncate not allow"; + } else if (x instanceof SQLCreateTableStatement) { + allow = config.isCreateTableAllow(); + denyMessage = "create table not allow"; + } else if (x instanceof SQLAlterTableStatement) { + allow = config.isAlterTableAllow(); + denyMessage = "alter table not allow"; + } else if (x instanceof SQLDropTableStatement) { + allow = config.isDropTableAllow(); + denyMessage = "drop table not allow"; + } else if (x instanceof MySqlSetCharSetStatement // + || x instanceof MySqlSetNamesStatement // + || x instanceof SQLSetStatement) { + allow = config.isSetAllow(); + denyMessage = "set not allow"; + } else if (x instanceof MySqlReplaceStatement) { + allow = config.isReplaceAllow(); + denyMessage = "replace not allow"; + } else if (x instanceof MySqlDescribeStatement) { + allow = config.isDescribeAllow(); + denyMessage = "describe not allow"; + } else if (x instanceof MySqlShowStatement) { + allow = config.isShowAllow(); + denyMessage = "show not allow"; + } else { + allow = config.isNoneBaseStatementAllow(); + } + + if (!allow) { + if (denyMessage == null) { + denyMessage = x.getClass() + " not allow"; + } + addViolation(visitor, denyMessage, x); + } + } } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_var_autoincrement.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_var_autoincrement.java new file mode 100644 index 0000000000..174556d987 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_var_autoincrement.java @@ -0,0 +1,40 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallConfig; +import com.alibaba.druid.wall.WallUtils; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest_var_autoincrement extends TestCase { + + + public void test_true() throws Exception { + WallConfig config = new WallConfig(); + Assert.assertTrue(WallUtils.isValidateMySql(// + "/* mysql-connector-java-5.? ( Revision: bzr.revision-id ) */SELECT @@session.auto_increment_increment", config)); // + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDropTest1.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDropTest1.java index 4084308f25..eef70873d5 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDropTest1.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDropTest1.java @@ -29,7 +29,7 @@ public class WallDropTest1 extends TestCase { private WallConfig config = new WallConfig(); protected void setUp() throws Exception { - config.setNoneBaseStatementAllow(true); + config.setDropTableAllow(true); } public void testMySql() throws Exception { diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_alter_table.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_alter_table.java new file mode 100644 index 0000000000..81f2e049ce --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_alter_table.java @@ -0,0 +1,54 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallTableStat; +import com.alibaba.druid.wall.spi.MySqlWallProvider; +import com.alibaba.druid.wall.spi.OracleWallProvider; +import com.alibaba.druid.wall.spi.PGWallProvider; +import com.alibaba.druid.wall.spi.SQLServerWallProvider; + + +public class WallStatTest_alter_table extends TestCase { + public void testMySql() throws Exception { + String sql = "alter table t add column fname varchar(50)"; + WallProvider provider = new MySqlWallProvider(); + provider.getConfig().setAlterTableAllow(true); + + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getAlterCount()); + } + + public void testOracle() throws Exception { + String sql = "alter table t add (fname varchar(50))"; + WallProvider provider = new OracleWallProvider(); + provider.getConfig().setAlterTableAllow(true); + + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getAlterCount()); + } + +// public void testPG() throws Exception { +// WallProvider provider = new PGWallProvider(); +// provider.getConfig().setAlterTableAllow(true); +// +// Assert.assertTrue(provider.checkValid(sql)); +// WallTableStat tableStat = provider.getTableStat("t"); +// Assert.assertEquals(1, tableStat.getAlterCount()); +// } +// +// public void testSQLServer() throws Exception { +// WallProvider provider = new SQLServerWallProvider(); +// provider.getConfig().setAlterTableAllow(true); +// +// Assert.assertTrue(provider.checkValid(sql)); +// WallTableStat tableStat = provider.getTableStat("t"); +// Assert.assertEquals(1, tableStat.getAlterCount()); +// } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_blacklist.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_blacklist.java new file mode 100644 index 0000000000..3840a6802e --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_blacklist.java @@ -0,0 +1,36 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallContext; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallTableStat; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +public class WallStatTest_blacklist extends TestCase { + + private String sql = "select * from t where id = ? and 1 = 1"; + + protected void setUp() throws Exception { + WallContext.clearContext(); + } + + protected void tearDown() throws Exception { + WallContext.clearContext(); + } + + public void testMySql() throws Exception { + WallProvider provider = new MySqlWallProvider(); + for (int i = 0; i < 10; ++i) { + Assert.assertFalse(provider.checkValid(sql)); + } + + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(10, tableStat.getSelectCount()); + Assert.assertEquals(0, provider.getWhiteListHitCount()); + Assert.assertEquals(9, provider.getBlackListHitCount()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_create_table.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_create_table.java new file mode 100644 index 0000000000..996ef88dab --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_create_table.java @@ -0,0 +1,54 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallTableStat; +import com.alibaba.druid.wall.spi.MySqlWallProvider; +import com.alibaba.druid.wall.spi.OracleWallProvider; +import com.alibaba.druid.wall.spi.PGWallProvider; +import com.alibaba.druid.wall.spi.SQLServerWallProvider; + + +public class WallStatTest_create_table extends TestCase { + private String sql = "create table t (fid int, fname varchar(50))"; + + public void testMySql() throws Exception { + WallProvider provider = new MySqlWallProvider(); + provider.getConfig().setCreateTableAllow(true); + + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getCreateCount()); + } + + public void testOracle() throws Exception { + WallProvider provider = new OracleWallProvider(); + provider.getConfig().setCreateTableAllow(true); + + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getCreateCount()); + } + + public void testPG() throws Exception { + WallProvider provider = new PGWallProvider(); + provider.getConfig().setCreateTableAllow(true); + + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getCreateCount()); + } + + public void testSQLServer() throws Exception { + WallProvider provider = new SQLServerWallProvider(); + provider.getConfig().setCreateTableAllow(true); + + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getCreateCount()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_delete.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_delete.java new file mode 100644 index 0000000000..e5c7005f33 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_delete.java @@ -0,0 +1,55 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallContext; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallTableStat; +import com.alibaba.druid.wall.spi.MySqlWallProvider; +import com.alibaba.druid.wall.spi.OracleWallProvider; +import com.alibaba.druid.wall.spi.PGWallProvider; +import com.alibaba.druid.wall.spi.SQLServerWallProvider; + +public class WallStatTest_delete extends TestCase { + + private String sql = "delete from t where fid = ?"; + + protected void setUp() throws Exception { + WallContext.clearContext(); + } + + protected void tearDown() throws Exception { + WallContext.clearContext(); + } + + public void testMySql() throws Exception { + WallProvider provider = new MySqlWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getDeleteCount()); + } + + public void testOracle() throws Exception { + WallProvider provider = new OracleWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getDeleteCount()); + } + + public void testPG() throws Exception { + WallProvider provider = new PGWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getDeleteCount()); + } + + public void testSQLServer() throws Exception { + WallProvider provider = new SQLServerWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getDeleteCount()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_drop_table.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_drop_table.java new file mode 100644 index 0000000000..a2cdc60008 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_drop_table.java @@ -0,0 +1,63 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallContext; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallTableStat; +import com.alibaba.druid.wall.spi.MySqlWallProvider; +import com.alibaba.druid.wall.spi.OracleWallProvider; +import com.alibaba.druid.wall.spi.PGWallProvider; +import com.alibaba.druid.wall.spi.SQLServerWallProvider; + +public class WallStatTest_drop_table extends TestCase { + + private String sql = "drop table t"; + + protected void setUp() throws Exception { + WallContext.clearContext(); + } + + protected void tearDown() throws Exception { + WallContext.clearContext(); + } + + public void testMySql() throws Exception { + WallProvider provider = new MySqlWallProvider(); + provider.getConfig().setDropTableAllow(true); + + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getDropCount()); + } + + public void testOracle() throws Exception { + WallProvider provider = new OracleWallProvider(); + provider.getConfig().setDropTableAllow(true); + + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getDropCount()); + } + + public void testPG() throws Exception { + WallProvider provider = new PGWallProvider(); + provider.getConfig().setDropTableAllow(true); + + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getDropCount()); + } + + public void testSQLServer() throws Exception { + WallProvider provider = new SQLServerWallProvider(); + provider.getConfig().setDropTableAllow(true); + + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getDropCount()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_insert.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_insert.java new file mode 100644 index 0000000000..21d13bc62b --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_insert.java @@ -0,0 +1,46 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallTableStat; +import com.alibaba.druid.wall.spi.MySqlWallProvider; +import com.alibaba.druid.wall.spi.OracleWallProvider; +import com.alibaba.druid.wall.spi.PGWallProvider; +import com.alibaba.druid.wall.spi.SQLServerWallProvider; + + +public class WallStatTest_insert extends TestCase { + private String sql = "insert into t (fid, fname) values (?, ?)"; + + public void testMySql() throws Exception { + WallProvider provider = new MySqlWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getInsertCount()); + } + + public void testOracle() throws Exception { + WallProvider provider = new OracleWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getInsertCount()); + } + + public void testPG() throws Exception { + WallProvider provider = new PGWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getInsertCount()); + } + + public void testSQLServer() throws Exception { + WallProvider provider = new SQLServerWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getInsertCount()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_select.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_select.java new file mode 100644 index 0000000000..b2ab732de8 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_select.java @@ -0,0 +1,55 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallContext; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallTableStat; +import com.alibaba.druid.wall.spi.MySqlWallProvider; +import com.alibaba.druid.wall.spi.OracleWallProvider; +import com.alibaba.druid.wall.spi.PGWallProvider; +import com.alibaba.druid.wall.spi.SQLServerWallProvider; + +public class WallStatTest_select extends TestCase { + + private String sql = "select * from t where id = ?"; + + protected void setUp() throws Exception { + WallContext.clearContext(); + } + + protected void tearDown() throws Exception { + WallContext.clearContext(); + } + + public void testMySql() throws Exception { + WallProvider provider = new MySqlWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + + public void testOracle() throws Exception { + WallProvider provider = new OracleWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + + public void testPG() throws Exception { + WallProvider provider = new PGWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + + public void testSQLServer() throws Exception { + WallProvider provider = new SQLServerWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_select_1.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_select_1.java new file mode 100644 index 0000000000..5ffb05c620 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_select_1.java @@ -0,0 +1,79 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallContext; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallTableStat; +import com.alibaba.druid.wall.spi.MySqlWallProvider; +import com.alibaba.druid.wall.spi.OracleWallProvider; +import com.alibaba.druid.wall.spi.PGWallProvider; +import com.alibaba.druid.wall.spi.SQLServerWallProvider; + +public class WallStatTest_select_1 extends TestCase { + + private String sql = "SELECT b.* FROM lhwbbs_posts_reply a LEFT JOIN lhwbbs_posts b ON a.pid=b.pid WHERE a.rpid=? AND b.disabled=? ORDER BY a.pid DESC"; + + protected void setUp() throws Exception { + WallContext.clearContext(); + } + + protected void tearDown() throws Exception { + WallContext.clearContext(); + } + + public void testMySql() throws Exception { + WallProvider provider = new MySqlWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + { + WallTableStat tableStat = provider.getTableStat("lhwbbs_posts_reply"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + { + WallTableStat tableStat = provider.getTableStat("lhwbbs_posts"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + } + + public void testOracle() throws Exception { + WallProvider provider = new OracleWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + { + WallTableStat tableStat = provider.getTableStat("lhwbbs_posts_reply"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + { + WallTableStat tableStat = provider.getTableStat("lhwbbs_posts"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + } + + public void testPG() throws Exception { + WallProvider provider = new PGWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + { + WallTableStat tableStat = provider.getTableStat("lhwbbs_posts_reply"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + { + WallTableStat tableStat = provider.getTableStat("lhwbbs_posts"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + } + + public void testSQLServer() throws Exception { + WallProvider provider = new SQLServerWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + { + WallTableStat tableStat = provider.getTableStat("lhwbbs_posts_reply"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + { + WallTableStat tableStat = provider.getTableStat("lhwbbs_posts"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_select_into.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_select_into.java new file mode 100644 index 0000000000..0ba4ecb6b6 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_select_into.java @@ -0,0 +1,64 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallContext; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallTableStat; +import com.alibaba.druid.wall.spi.MySqlWallProvider; +import com.alibaba.druid.wall.spi.OracleWallProvider; +import com.alibaba.druid.wall.spi.PGWallProvider; +import com.alibaba.druid.wall.spi.SQLServerWallProvider; + +public class WallStatTest_select_into extends TestCase { + + private String sql = "select * into x from t where id = ?"; + + protected void setUp() throws Exception { + WallContext.clearContext(); + } + + protected void tearDown() throws Exception { + WallContext.clearContext(); + } + + public void testMySql() throws Exception { + WallProvider provider = new MySqlWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + + { + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getSelectCount()); + Assert.assertEquals(0, tableStat.getSelectIntoCount()); + } + { + WallTableStat tableStat = provider.getTableStat("x"); + Assert.assertEquals(0, tableStat.getSelectCount()); + Assert.assertEquals(1, tableStat.getSelectIntoCount()); + } + } + + public void testOracle() throws Exception { + WallProvider provider = new OracleWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + + public void testPG() throws Exception { + WallProvider provider = new PGWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + + public void testSQLServer() throws Exception { + WallProvider provider = new SQLServerWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getSelectCount()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_update.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_update.java new file mode 100644 index 0000000000..f936b83883 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_update.java @@ -0,0 +1,55 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallContext; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallTableStat; +import com.alibaba.druid.wall.spi.MySqlWallProvider; +import com.alibaba.druid.wall.spi.OracleWallProvider; +import com.alibaba.druid.wall.spi.PGWallProvider; +import com.alibaba.druid.wall.spi.SQLServerWallProvider; + + +public class WallStatTest_update extends TestCase { + private String sql = "update t set fname = ? where fid = ?"; + + protected void setUp() throws Exception { + WallContext.clearContext(); + } + + protected void tearDown() throws Exception { + WallContext.clearContext(); + } + + public void testMySql() throws Exception { + WallProvider provider = new MySqlWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getUpdateCount()); + } + + public void testOracle() throws Exception { + WallProvider provider = new OracleWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getUpdateCount()); + } + + public void testPG() throws Exception { + WallProvider provider = new PGWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getUpdateCount()); + } + + public void testSQLServer() throws Exception { + WallProvider provider = new SQLServerWallProvider(); + Assert.assertTrue(provider.checkValid(sql)); + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(1, tableStat.getUpdateCount()); + } + +}