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 a295bc1a84..b56cacc88a 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 @@ -47,6 +47,7 @@ public class MySqlLexer extends Lexer { map.put("LIMIT", Token.LIMIT); map.put("TRUE", Token.TRUE); map.put("BINARY", Token.BINARY); + map.put("SHOW", Token.SHOW); DEFAULT_MYSQL_KEYWORDS = new Keywords(map); } 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 335a572894..20272a1b53 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 @@ -173,7 +173,6 @@ public class MySqlStatementParser extends SQLStatementParser { private static final String USER = "USER"; private static final String SPATIAL = "SPATIAL"; private static final String FULLTEXT = "FULLTEXT"; - private static final String REPLACE = "REPLACE"; private static final String DELAYED = "DELAYED"; private static final String LOW_PRIORITY = "LOW_PRIORITY"; @@ -306,7 +305,7 @@ public class MySqlStatementParser extends SQLStatementParser { boolean replace = false; if (lexer.token() == Token.OR) { lexer.nextToken(); - acceptIdentifier("REPLACE"); + accept(Token.REPLACE); replace = true; } @@ -544,7 +543,7 @@ public class MySqlStatementParser extends SQLStatementParser { return true; } - if (identifierEquals(REPLACE)) { + if (lexer.token() == Token.REPLACE) { MySqlReplaceStatement stmt = parseReplicate(); statementList.add(stmt); return true; @@ -556,7 +555,7 @@ public class MySqlStatementParser extends SQLStatementParser { return true; } - if (identifierEquals("SHOW")) { + if (lexer.token() == Token.SHOW) { SQLStatement stmt = parseShow(); statementList.add(stmt); return true; @@ -639,7 +638,7 @@ public class MySqlStatementParser extends SQLStatementParser { } public SQLStatement parseShow() { - acceptIdentifier("SHOW"); + accept(Token.SHOW); if (lexer.token() == Token.COMMENT) { lexer.nextToken(); @@ -1511,7 +1510,7 @@ public class MySqlStatementParser extends SQLStatementParser { public MySqlReplaceStatement parseReplicate() { MySqlReplaceStatement stmt = new MySqlReplaceStatement(); - acceptIdentifier(REPLACE); + accept(Token.REPLACE); if (lexer.token() == Token.COMMENT) { lexer.nextToken(); @@ -1624,7 +1623,7 @@ public class MySqlStatementParser extends SQLStatementParser { SQLLiteralExpr fileName = (SQLLiteralExpr) exprParser.expr(); stmt.setFileName(fileName); - if (identifierEquals(REPLACE)) { + if (lexer.token() == Token.REPLACE) { stmt.setReplicate(true); lexer.nextToken(); } @@ -1697,7 +1696,7 @@ public class MySqlStatementParser extends SQLStatementParser { SQLLiteralExpr fileName = (SQLLiteralExpr) exprParser.expr(); stmt.setFileName(fileName); - if (identifierEquals(REPLACE)) { + if (lexer.token() == Token.REPLACE) { stmt.setReplicate(true); lexer.nextToken(); } 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 f367cb814c..65d6e718e9 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 @@ -1676,7 +1676,7 @@ public class OracleStatementParser extends SQLStatementParser { accept(Token.CREATE); if (lexer.token() == Token.OR) { lexer.nextToken(); - acceptIdentifier("REPLACE"); + accept(Token.REPLACE); stmt.setOrReplace(true); } diff --git a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java index fda68bb56c..5abf4068bb 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java @@ -114,6 +114,8 @@ public class Keywords { map.put("OVER", Token.OVER); map.put("TO", Token.TO); map.put("USE", Token.USE); + + map.put("REPLACE", Token.REPLACE); DEFAULT_KEYWORDS = new Keywords(map); } 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 10756dfede..f5c2ddae07 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -195,7 +195,7 @@ public class SQLStatementParser extends SQLParser { continue; } - if (identifierEquals("SHOW")) { + if (lexer.token() == Token.SHOW) { SQLStatement stmt = parseShow(); statementList.add(stmt); @@ -489,7 +489,7 @@ public class SQLStatementParser extends SQLParser { return parseCreateSequence(false); } else if (token == Token.OR) { lexer.nextToken(); - acceptIdentifier("REPLACE"); + accept(Token.REPLACE); if (lexer.token() == Token.PROCEDURE) { lexer.reset(markBp, markChar, Token.CREATE); return parseCreateProcedure(); @@ -651,7 +651,7 @@ public class SQLStatementParser extends SQLParser { if (lexer.token() == Token.OR) { lexer.nextToken(); - acceptIdentifier("REPLACE"); + accept(Token.REPLACE); createView.setOrReplace(true); } diff --git a/src/main/java/com/alibaba/druid/sql/parser/Token.java b/src/main/java/com/alibaba/druid/sql/parser/Token.java index 2410cf69ee..d4eca19223 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -107,6 +107,8 @@ public enum Token { PASSWORD("PASSWORD"), DUAL("DUAL"), BINARY("BINARY"), + SHOW("SHOW"), + REPLACE("REPLACE"), //postgresql WINDOW("WINDOW"), diff --git a/src/main/java/com/alibaba/druid/stat/DruidStatManagerFacade.java b/src/main/java/com/alibaba/druid/stat/DruidStatManagerFacade.java index 57a3790e8b..dd650e20f6 100644 --- a/src/main/java/com/alibaba/druid/stat/DruidStatManagerFacade.java +++ b/src/main/java/com/alibaba/druid/stat/DruidStatManagerFacade.java @@ -214,7 +214,7 @@ public final class DruidStatManagerFacade { Collection collectionA = (Collection) valueA; for (String blackItem : collectionA) { - if (newSet.size() >= 500) { + if (newSet.size() >= 1000) { break; } newSet.add(blackItem); @@ -222,7 +222,7 @@ public final class DruidStatManagerFacade { Collection collectionB = (Collection) valueB; for (String blackItem : collectionB) { - if (newSet.size() >= 50) { + if (newSet.size() >= 1000) { break; } newSet.add(blackItem); diff --git a/src/main/java/com/alibaba/druid/wall/WallConfig.java b/src/main/java/com/alibaba/druid/wall/WallConfig.java index bd5ae92796..868a0628b4 100644 --- a/src/main/java/com/alibaba/druid/wall/WallConfig.java +++ b/src/main/java/com/alibaba/druid/wall/WallConfig.java @@ -65,6 +65,7 @@ public class WallConfig implements WallConfigMBean { private boolean commentAllow = false; private boolean strictSyntaxCheck = true; private boolean constArithmeticAllow = true; + private boolean limitZeroAllow = false; private boolean describeAllow = true; private boolean showAllow = true; @@ -109,10 +110,20 @@ public class WallConfig implements WallConfigMBean { } + public boolean isLimitZeroAllow() { + return limitZeroAllow; + } + + public void setLimitZeroAllow(boolean limitZero) { + this.limitZeroAllow = limitZero; + } + + + public boolean isConditionAndAlwayTrueAllow() { return conditionAndAlwayTrueAllow; } - + public void setConditionAndAlwayTrueAllow(boolean conditionAndAlwayTrueAllow) { this.conditionAndAlwayTrueAllow = conditionAndAlwayTrueAllow; } diff --git a/src/main/java/com/alibaba/druid/wall/WallProvider.java b/src/main/java/com/alibaba/druid/wall/WallProvider.java index 16dbe67a4b..6e23464b7b 100644 --- a/src/main/java/com/alibaba/druid/wall/WallProvider.java +++ b/src/main/java/com/alibaba/druid/wall/WallProvider.java @@ -596,11 +596,13 @@ public abstract class WallProvider { case CREATE: case ALTER: case DROP: + case SHOW: + case REPLACE: return true; default: break; } - + return false; } } 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 b2dee5b6f3..7c4c051c73 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java @@ -172,7 +172,7 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi public boolean visit(Limit x) { if (x.getRowCount() instanceof SQLNumericLiteralExpr) { int rowCount = ((SQLNumericLiteralExpr) x.getRowCount()).getNumber().intValue(); - if (rowCount == 0) { + if (rowCount == 0 && !provider.getConfig().isLimitZeroAllow()) { this.getViolations().add(new IllegalSQLObjectViolation("limit row 0", this.toSQL(x))); } } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest50.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest50.java new file mode 100644 index 0000000000..dd5cf41e1d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest50.java @@ -0,0 +1,42 @@ +/* + * 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.WallProvider; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest50 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + Assert.assertTrue(provider.checkValid(// + "SHOW /* 113.97.255.240 */ GLOBAL VARIABLES LIKE 'ft\\_min\\_word\\_len'")); + + Assert.assertEquals(0, provider.getTableStats().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest51.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest51.java new file mode 100644 index 0000000000..6d30309728 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest51.java @@ -0,0 +1,42 @@ +/* + * 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.WallProvider; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest51 extends TestCase { + + public void test_true() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + Assert.assertTrue(provider.checkValid(// + "REPLACE /* SearchMySQL::update Wikiadmin */ INTO `wiki_searchindex` (si_page,si_title,si_text) VALUES ('15',' u8e5858d u8e8b4a3 u8e5a3b0 u8e6988e')")); + + Assert.assertEquals(1, provider.getTableStats().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest52.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest52.java new file mode 100644 index 0000000000..27fa0ac67b --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest52.java @@ -0,0 +1,52 @@ +/* + * 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.WallProvider; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest52 extends TestCase { + + public void test_true() throws Exception { + WallProvider provider = new MySqlWallProvider(); + provider.getConfig().setLimitZeroAllow(true); + + Assert.assertTrue(provider.checkValid(// + "select * from t limit 0")); + + Assert.assertEquals(1, provider.getTableStats().size()); + } + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + Assert.assertFalse(provider.checkValid(// + "select * from t limit 0")); + + Assert.assertEquals(1, provider.getTableStats().size()); + } +}