From 0c9186c0dc65a495ed4bfac0e63b0369ef8a1c6c Mon Sep 17 00:00:00 2001 From: wenshao Date: Sun, 7 Apr 2013 19:46:37 +0800 Subject: [PATCH] improve wall filter --- .../sql/visitor/SQLEvalVisitorUtils.java | 39 ++++++++++- .../druid/stat/DruidStatManagerFacade.java | 4 +- .../alibaba/druid/wall/WallFunctionStat.java | 2 +- .../druid/wall/spi/WallVisitorUtils.java | 2 +- .../bvt/filter/wall/MySqlWallTest36.java | 44 ++++++++++++ .../bvt/sql/oracle/OracleMergeTest6.java | 70 +++++++++++++++++++ 6 files changed, 155 insertions(+), 6 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest36.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest6.java diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java index 0479024ef4..3cd47d54b2 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java @@ -194,7 +194,7 @@ public class SQLEvalVisitorUtils { if (function != null) { Object result = function.eval(visitor, x); - + if (result != SQLEvalVisitor.EVAL_ERROR) { x.getAttributes().put(EVAL_VALUE, result); } @@ -954,6 +954,10 @@ public class SQLEvalVisitorUtils { if (val instanceof Short) { return (Short) val; } + + if (val instanceof String) { + return Short.parseShort((String) val); + } return ((Number) val).shortValue(); } @@ -967,6 +971,17 @@ public class SQLEvalVisitorUtils { return (Integer) val; } + if (val instanceof String) { + return Integer.parseInt((String) val); + } + + if (val instanceof List) { + List list = (List) val; + if (list.size() == 1) { + return castToInteger(list.get(0)); + } + } + return ((Number) val).intValue(); } @@ -978,6 +993,18 @@ public class SQLEvalVisitorUtils { if (val instanceof Long) { return (Long) val; } + + if (val instanceof String) { + return Long.parseLong((String) val); + } + + + if (val instanceof List) { + List list = (List) val; + if (list.size() == 1) { + return castToLong(list.get(0)); + } + } return ((Number) val).longValue(); } @@ -1395,6 +1422,10 @@ public class SQLEvalVisitorUtils { if (b == null) { return a; } + + if (a instanceof Date || b instanceof Date) { + return SQLEvalVisitor.EVAL_ERROR; + } if (a instanceof BigDecimal || b instanceof BigDecimal) { return castToDecimal(a).subtract(castToDecimal(b)); @@ -1427,8 +1458,12 @@ public class SQLEvalVisitorUtils { if (a instanceof Byte || b instanceof Byte) { return castToByte(a) - castToByte(b); } + + if(a instanceof String && b instanceof String) { + return castToLong(a) - castToLong(b); + } - throw new IllegalArgumentException(); + return SQLEvalVisitor.EVAL_ERROR; } public static Object multi(Object a, Object b) { diff --git a/src/main/java/com/alibaba/druid/stat/DruidStatManagerFacade.java b/src/main/java/com/alibaba/druid/stat/DruidStatManagerFacade.java index 49d2f60f80..718151aa94 100644 --- a/src/main/java/com/alibaba/druid/stat/DruidStatManagerFacade.java +++ b/src/main/java/com/alibaba/druid/stat/DruidStatManagerFacade.java @@ -189,11 +189,11 @@ public final class DruidStatManagerFacade { @SuppressWarnings({ "rawtypes", "unchecked" }) public static Map mergWallStat(Map mapA, Map mapB) { - if (mapA.size() == 0) { + if (mapA == null || mapA.size() == 0) { return mapB; } - if (mapB.size() == 0) { + if (mapB == null || mapB.size() == 0) { return mapA; } diff --git a/src/main/java/com/alibaba/druid/wall/WallFunctionStat.java b/src/main/java/com/alibaba/druid/wall/WallFunctionStat.java index acbae8fb3c..4b589b3f00 100644 --- a/src/main/java/com/alibaba/druid/wall/WallFunctionStat.java +++ b/src/main/java/com/alibaba/druid/wall/WallFunctionStat.java @@ -30,7 +30,7 @@ public class WallFunctionStat { } public void incrementInvokeCount() { - this.invokeCount++; + invokeCountUpdater.incrementAndGet(this); } public void addSqlFunctionStat(WallSqlFunctionStat sqlFunctionStat) { 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 199c7e441d..80be0c15e0 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -223,7 +223,7 @@ public class WallVisitorUtils { } public static void checkDelete(WallVisitor visitor, SQLDeleteStatement x) { - checkReadOnly(visitor, x.getExprTableSource()); + checkReadOnly(visitor, x.getTableSource()); WallConfig config = visitor.getConfig(); if (!config.isDeleteAllow()) { diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest36.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest36.java new file mode 100644 index 0000000000..5054037393 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest36.java @@ -0,0 +1,44 @@ +/* + * 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.support.json.JSONUtils; +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 MySqlWallTest36 extends TestCase { + + public void test_true() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + Assert.assertTrue(provider.checkValid(// + "select * FROM `13452845947` WHERE gpstime < (now()-90) order by gpstime desc")); // + + Assert.assertEquals(1, provider.getTableStat("13452845947").getSelectCount()); + System.out.println(JSONUtils.toJSONString(provider.getStatsMap())); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest6.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest6.java new file mode 100644 index 0000000000..ac4d9549d2 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest6.java @@ -0,0 +1,70 @@ +/* + * 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.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleMergeTest6 extends OracleTest { + + public void test_0() throws Exception { + String sql = "MERGE INTO console_stb_ipstatus T1 " + + // + "USING (SELECT '02222601005592002863423471' AS stbid FROM dual) T2 " + + // + "ON ( T1.stbid=T2.stbid) " + + // + "WHEN MATCHED THEN update set t1.ip='10.104.131.175',t1.port='6666',t1.status = 1, t1.time = to_char(sysdate, 'yyyy-MM-dd HH24:mi:ss') " + + // + "WHEN NOT MATCHED THEN insert (id, stbid, ip, port, time, firsttime, status) " + // + "values (CONSOLE_SEQ.nextval,'02222601005592002863423471','10.104.131.175','6666',to_char(sysdate, 'yyyy-MM-dd HH24:mi:ss'),to_char(sysdate, 'yyyy-MM-dd HH24:mi:ss'),1) "; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("console_stb_ipstatus"))); + + Assert.assertEquals(7, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "employee_id"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "bonus"))); + } + +}