From a294ed7a1dee681d8286a406092cb6f75bfd8af1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Thu, 15 Mar 2012 08:01:41 +0800 Subject: [PATCH] add sql wall support --- .../filter/wall/spi/MySqlWallVisitor.java | 6 ++ .../filter/wall/spi/OracleWallVisitor.java | 8 ++ .../filter/wall/spi/WallVisitorUtils.java | 84 +++++++++++++++---- .../bvt/filter/wall/WallVisitorUtilsTest.java | 3 + 4 files changed, 83 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/alibaba/druid/filter/wall/spi/MySqlWallVisitor.java b/src/main/java/com/alibaba/druid/filter/wall/spi/MySqlWallVisitor.java index 73c1510b02..7ae353da6e 100644 --- a/src/main/java/com/alibaba/druid/filter/wall/spi/MySqlWallVisitor.java +++ b/src/main/java/com/alibaba/druid/filter/wall/spi/MySqlWallVisitor.java @@ -8,6 +8,7 @@ import com.alibaba.druid.filter.wall.Violation; import com.alibaba.druid.filter.wall.WallVisitor; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; @@ -74,4 +75,9 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi public boolean visit(MySqlSelectQueryBlock x) { return visit((SQLSelectQueryBlock) x); } + + public boolean visit(SQLDropTableStatement x) { + violations.add(new IllegalStatementViolation(SQLUtils.toMySqlString(x))); + return false; + } } diff --git a/src/main/java/com/alibaba/druid/filter/wall/spi/OracleWallVisitor.java b/src/main/java/com/alibaba/druid/filter/wall/spi/OracleWallVisitor.java index 65abd7e9c8..6dc951b036 100644 --- a/src/main/java/com/alibaba/druid/filter/wall/spi/OracleWallVisitor.java +++ b/src/main/java/com/alibaba/druid/filter/wall/spi/OracleWallVisitor.java @@ -3,9 +3,12 @@ package com.alibaba.druid.filter.wall.spi; import java.util.ArrayList; import java.util.List; +import com.alibaba.druid.filter.wall.IllegalStatementViolation; import com.alibaba.druid.filter.wall.Violation; import com.alibaba.druid.filter.wall.WallVisitor; +import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVIsitorAdapter; public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVisitor { @@ -29,4 +32,9 @@ public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVi return true; } + + public boolean visit(SQLDropTableStatement x) { + violations.add(new IllegalStatementViolation(SQLUtils.toOracleString(x))); + return false; + } } diff --git a/src/main/java/com/alibaba/druid/filter/wall/spi/WallVisitorUtils.java b/src/main/java/com/alibaba/druid/filter/wall/spi/WallVisitorUtils.java index b96b3091fe..e42e51012a 100644 --- a/src/main/java/com/alibaba/druid/filter/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/filter/wall/spi/WallVisitorUtils.java @@ -4,12 +4,19 @@ import com.alibaba.druid.filter.wall.IllegalConditionViolation; import com.alibaba.druid.filter.wall.WallVisitor; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; import com.alibaba.druid.sql.ast.expr.SQLCharExpr; import com.alibaba.druid.sql.ast.expr.SQLNotExpr; import com.alibaba.druid.sql.ast.expr.SQLNullExpr; import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; +import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; +import com.alibaba.druid.sql.ast.statement.SQLSelect; +import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; +import com.alibaba.druid.sql.ast.statement.SQLTableSource; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr; public class WallVisitorUtils { @@ -42,82 +49,82 @@ public class WallVisitorUtils { return true; } } - + if (x.getOperator() == SQLBinaryOperator.Equality) { if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) { return true; } - + if (leftResult == null || rightResult == null) { return null; } - + return leftResult.equals(rightResult); } - + if (x.getOperator() == SQLBinaryOperator.NotEqual || x.getOperator() == SQLBinaryOperator.LessThanOrGreater) { if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) { return false; } - + if (leftResult == null || rightResult == null) { return null; } - + return !leftResult.equals(rightResult); } - + if (x.getOperator() == SQLBinaryOperator.GreaterThan) { if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) { return false; } - + if (leftResult == null || rightResult == null) { return null; } - + if (leftResult instanceof Comparable) { return (((Comparable) leftResult).compareTo(rightResult) > 0); } } - + if (x.getOperator() == SQLBinaryOperator.GreaterThanOrEqual) { if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) { return false; } - + if (leftResult == null || rightResult == null) { return null; } - + if (leftResult instanceof Comparable) { return ((Comparable) leftResult).compareTo(rightResult) >= 0; } } - + if (x.getOperator() == SQLBinaryOperator.LessThan) { if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) { return false; } - + if (leftResult == null || rightResult == null) { return null; } - + if (leftResult instanceof Comparable) { return (((Comparable) leftResult).compareTo(rightResult) < 0); } } - + if (x.getOperator() == SQLBinaryOperator.LessThanOrEqual) { if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) { return false; } - + if (leftResult == null || rightResult == null) { return null; } - + if (leftResult instanceof Comparable) { return ((Comparable) leftResult).compareTo(rightResult) <= 0; } @@ -162,7 +169,48 @@ public class WallVisitorUtils { return !((Boolean) result).booleanValue(); } } + + if (x instanceof SQLQueryExpr) { + if (isSimpleCountTableSource(((SQLQueryExpr) x).getSubQuery())) { + return Integer.valueOf(1); + } + } return null; } + + public static boolean isSimpleCountTableSource(SQLTableSource tableSource) { + if (!(tableSource instanceof SQLSubqueryTableSource)) { + return false; + } + + SQLSubqueryTableSource subQuery = (SQLSubqueryTableSource) tableSource; + + return isSimpleCountTableSource(subQuery.getSelect()); + } + + public static boolean isSimpleCountTableSource(SQLSelect select) { + SQLSelectQuery query = select.getQuery(); + + if (query instanceof SQLSelectQueryBlock) { + SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query; + + boolean allawTrueWhere = queryBlock.getWhere() == null || getValue(queryBlock.getWhere()) == Boolean.TRUE; + boolean simpleCount = false; + if (queryBlock.getSelectList().size() == 1) { + SQLExpr selectItemExpr = queryBlock.getSelectList().get(0).getExpr(); + if (selectItemExpr instanceof SQLAggregateExpr) { + if (((SQLAggregateExpr) selectItemExpr).getMethodName().equalsIgnoreCase("COUNT")) { + simpleCount = true; + } + } + } + + if (allawTrueWhere && simpleCount) { + return true; + } + } + + return false; + } } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallVisitorUtilsTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallVisitorUtilsTest.java index 24731dafb7..bc604aca7c 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallVisitorUtilsTest.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallVisitorUtilsTest.java @@ -26,5 +26,8 @@ public class WallVisitorUtilsTest extends TestCase { Assert.assertEquals(Boolean.TRUE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("2 > 1"))); Assert.assertEquals(Boolean.FALSE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("2 > 2"))); Assert.assertEquals(Boolean.TRUE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("2 >= 2"))); + + Assert.assertEquals(Boolean.TRUE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("(select count(*) from t) > 0"))); + Assert.assertEquals(Boolean.TRUE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("(select count(*) from t) >= 0"))); } }