mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve sqlwall: 'hints' and 'start transaction'
This commit is contained in:
@@ -18,6 +18,7 @@ package com.alibaba.druid.sql.ast.statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLCommentHint;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
@@ -25,6 +26,8 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
public class SQLSetStatement extends SQLStatementImpl {
|
||||
|
||||
private List<SQLAssignItem> items = new ArrayList<SQLAssignItem>();
|
||||
|
||||
private List<SQLCommentHint> hints;
|
||||
|
||||
public SQLSetStatement(){
|
||||
}
|
||||
@@ -41,10 +44,19 @@ public class SQLSetStatement extends SQLStatementImpl {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public List<SQLCommentHint> getHints() {
|
||||
return hints;
|
||||
}
|
||||
|
||||
public void setHints(List<SQLCommentHint> hints) {
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, this.items);
|
||||
acceptChild(visitor, this.hints);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
+13
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLCommentHint;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
@@ -24,6 +27,8 @@ public class MySqlLockTableStatement extends MySqlStatementImpl {
|
||||
private SQLExprTableSource tableSource;
|
||||
|
||||
private LockType lockType;
|
||||
|
||||
private List<SQLCommentHint> hints;
|
||||
|
||||
public SQLExprTableSource getTableSource() {
|
||||
return tableSource;
|
||||
@@ -64,4 +69,12 @@ public class MySqlLockTableStatement extends MySqlStatementImpl {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public List<SQLCommentHint> getHints() {
|
||||
return hints;
|
||||
}
|
||||
|
||||
public void setHints(List<SQLCommentHint> hints) {
|
||||
this.hints = hints;
|
||||
}
|
||||
}
|
||||
|
||||
+14
-2
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLCommentHint;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
@@ -22,8 +25,9 @@ import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
|
||||
public class MySqlShowIndexesStatement extends MySqlStatementImpl implements MySqlShowStatement {
|
||||
|
||||
private SQLName table;
|
||||
private SQLName database;
|
||||
private SQLName table;
|
||||
private SQLName database;
|
||||
private List<SQLCommentHint> hints;
|
||||
|
||||
public SQLName getTable() {
|
||||
return table;
|
||||
@@ -54,4 +58,12 @@ public class MySqlShowIndexesStatement extends MySqlStatementImpl implements MyS
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public List<SQLCommentHint> getHints() {
|
||||
return hints;
|
||||
}
|
||||
|
||||
public void setHints(List<SQLCommentHint> hints) {
|
||||
this.hints = hints;
|
||||
}
|
||||
}
|
||||
|
||||
+16
-3
@@ -15,14 +15,19 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLCommentHint;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
|
||||
public class MySqlStartTransactionStatement extends MySqlStatementImpl {
|
||||
|
||||
private boolean consistentSnapshot = false;
|
||||
private boolean consistentSnapshot = false;
|
||||
|
||||
private boolean begin = false;
|
||||
private boolean work = false;
|
||||
private boolean begin = false;
|
||||
private boolean work = false;
|
||||
|
||||
private List<SQLCommentHint> hints;
|
||||
|
||||
public boolean isConsistentSnapshot() {
|
||||
return consistentSnapshot;
|
||||
@@ -53,4 +58,12 @@ public class MySqlStartTransactionStatement extends MySqlStatementImpl {
|
||||
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public List<SQLCommentHint> getHints() {
|
||||
return hints;
|
||||
}
|
||||
|
||||
public void setHints(List<SQLCommentHint> hints) {
|
||||
this.hints = hints;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,6 +654,9 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
stmt.setLockType(LockType.LOW_PRIORITY_WRITE);
|
||||
}
|
||||
|
||||
if(lexer.token() == Token.HINT) {
|
||||
stmt.setHints(this.exprParser.parseHints());
|
||||
}
|
||||
statementList.add(stmt);
|
||||
return true;
|
||||
}
|
||||
@@ -1101,6 +1104,10 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
stmt.setDatabase(database);
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.HINT) {
|
||||
stmt.setHints(this.exprParser.parseHints());
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
@@ -1492,6 +1499,10 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
stmt.setWork(true);
|
||||
}
|
||||
}
|
||||
|
||||
if(lexer.token() == Token.HINT) {
|
||||
stmt.setHints(this.exprParser.parseHints());
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
@@ -2123,6 +2134,10 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
SQLVariantRefExpr varRef = (SQLVariantRefExpr) stmt.getItems().get(0).getTarget();
|
||||
varRef.setGlobal(true);
|
||||
}
|
||||
|
||||
if(lexer.token() == Token.HINT) {
|
||||
stmt.setHints(this.exprParser.parseHints());
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@@ -1118,6 +1118,14 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
if (x.isConsistentSnapshot()) {
|
||||
print(" WITH CONSISTENT SNAPSHOT");
|
||||
}
|
||||
|
||||
List<SQLCommentHint> hints = x.getHints();
|
||||
if (hints != null && !hints.isEmpty()) {
|
||||
print(" ");
|
||||
for (SQLCommentHint hint : hints) {
|
||||
hint.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (x.isBegin()) {
|
||||
print(" BEGIN");
|
||||
@@ -2130,6 +2138,14 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
}
|
||||
x.getTable().accept(this);
|
||||
}
|
||||
|
||||
List<SQLCommentHint> hints = x.getHints();
|
||||
if (hints != null && !hints.isEmpty()) {
|
||||
print(" ");
|
||||
for (SQLCommentHint hint : hints) {
|
||||
hint.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -2664,6 +2680,14 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
print(' ');
|
||||
print(x.getLockType().name);
|
||||
}
|
||||
|
||||
List<SQLCommentHint> hints = x.getHints();
|
||||
if (hints != null && !hints.isEmpty()) {
|
||||
print(" ");
|
||||
for (SQLCommentHint hint : hints) {
|
||||
hint.accept(this);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1148,6 +1148,14 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
|
||||
public boolean visit(SQLSetStatement x) {
|
||||
print("SET ");
|
||||
printAndAccept(x.getItems(), ", ");
|
||||
|
||||
List<SQLCommentHint> hints = x.getHints();
|
||||
if (hints != null && !hints.isEmpty()) {
|
||||
print(" ");
|
||||
for (SQLCommentHint hint : hints) {
|
||||
hint.accept(this);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ public class WallConfig implements WallConfigMBean {
|
||||
private boolean renameTableAllow = true;
|
||||
private boolean hintAllow = true;
|
||||
private boolean lockTableAllow = true;
|
||||
private boolean startTransactionAllow = true;
|
||||
|
||||
private boolean conditionAndAlwayTrueAllow = false;
|
||||
private boolean conditionAndAlwayFalseAllow = false;
|
||||
@@ -761,4 +762,12 @@ public class WallConfig implements WallConfigMBean {
|
||||
this.lockTableAllow = lockTableAllow;
|
||||
}
|
||||
|
||||
public boolean isStartTransactionAllow() {
|
||||
return startTransactionAllow;
|
||||
}
|
||||
|
||||
public void setStartTransactionAllow(boolean startTransactionAllow) {
|
||||
this.startTransactionAllow = startTransactionAllow;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatemen
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowGrantsStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStartTransactionStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStatement;
|
||||
@@ -2416,6 +2417,10 @@ public class WallVisitorUtils {
|
||||
allow = config.isLockTableAllow();
|
||||
denyMessage = "lock table not allow";
|
||||
errorCode = ErrorCode.LOCK_TABLE_NOT_ALLOW;
|
||||
} else if (x instanceof MySqlStartTransactionStatement) {
|
||||
allow = config.isStartTransactionAllow();
|
||||
denyMessage = "start transaction not allow";
|
||||
errorCode = ErrorCode.START_TRANSACTION_NOT_ALLOW;
|
||||
} else {
|
||||
allow = config.isNoneBaseStatementAllow();
|
||||
errorCode = ErrorCode.NONE_BASE_STATEMENT_NOT_ALLOW;
|
||||
|
||||
@@ -33,6 +33,7 @@ public interface ErrorCode {
|
||||
public final static int CALL_NOT_ALLOW = 1300;
|
||||
public final static int COMMIT_NOT_ALLOW = 1301;
|
||||
public final static int ROLLBACK_NOT_ALLOW = 1302;
|
||||
public final static int START_TRANSACTION_NOT_ALLOW = 1303;
|
||||
|
||||
public final static int SET_NOT_ALLOW = 1200;
|
||||
public final static int DESC_NOT_ALLOW = 1201;
|
||||
@@ -47,7 +48,7 @@ public interface ErrorCode {
|
||||
public final static int DROP_TABLE_NOT_ALLOW = 1103;
|
||||
public final static int COMMENT_STATEMENT_NOT_ALLOW = 1104;
|
||||
public final static int RENAME_TABLE_NOT_ALLOW = 1105;
|
||||
public final static int LOCK_TABLE_NOT_ALLOW = 1105;
|
||||
public final static int LOCK_TABLE_NOT_ALLOW = 1106;
|
||||
|
||||
public final static int LIMIT_ZERO = 2200;
|
||||
public final static int MULTI_STATEMENT = 2201;
|
||||
|
||||
@@ -17,8 +17,11 @@ public class MySqlWallTest_hint extends TestCase {
|
||||
}
|
||||
|
||||
public void test_false_1() throws Exception {
|
||||
WallConfig config = new WallConfig();
|
||||
config.setHintAllow(true);
|
||||
config.setMultiStatementAllow(true);
|
||||
String sql = "select * from person where id = '3'/**/union select 0,1,v from (select 1,2,user/*!() as v*/) a where '1'<>''";
|
||||
Assert.assertFalse(WallUtils.isValidateMySql(sql)); //
|
||||
Assert.assertFalse(WallUtils.isValidateMySql(sql, config)); //
|
||||
}
|
||||
|
||||
public void test_true() throws Exception {
|
||||
@@ -77,4 +80,19 @@ public class MySqlWallTest_hint extends TestCase {
|
||||
Assert.assertTrue(WallUtils.isValidateMySql(sql, config)); //
|
||||
}
|
||||
|
||||
public void test_true_6() throws Exception {
|
||||
String sql = "START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */";
|
||||
Assert.assertTrue(WallUtils.isValidateMySql(sql)); //
|
||||
}
|
||||
|
||||
public void test_true_7() throws Exception {
|
||||
String sql = "LOCK TABLES `m_rpt_adgroupeffect` READ /*!32311 LOCAL */";
|
||||
Assert.assertTrue(WallUtils.isValidateMySql(sql)); //
|
||||
}
|
||||
|
||||
public void test_true_8() throws Exception {
|
||||
String sql = "SET SQL_QUOTE_SHOW_CREATE=1/*!40102 ,SQL_MODE=concat(@@sql_mode, _utf8 ',NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS') */";
|
||||
Assert.assertTrue(WallUtils.isValidateMySql(sql)); //
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user