diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCharExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCharExpr.java index 5b8fd0dc65..df0beeb5db 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCharExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCharExpr.java @@ -17,7 +17,7 @@ package com.alibaba.druid.sql.ast.expr; import com.alibaba.druid.sql.visitor.SQLASTVisitor; -public class SQLCharExpr extends SQLTextLiteralExpr { +public class SQLCharExpr extends SQLTextLiteralExpr implements SQLValuableExpr{ public SQLCharExpr(){ @@ -42,4 +42,9 @@ public class SQLCharExpr extends SQLTextLiteralExpr { visitor.visit(this); visitor.endVisit(this); } + + @Override + public Object getValue() { + return this.text; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIntegerExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIntegerExpr.java index 5838c6f230..e9f8b83371 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIntegerExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIntegerExpr.java @@ -17,7 +17,7 @@ package com.alibaba.druid.sql.ast.expr; import com.alibaba.druid.sql.visitor.SQLASTVisitor; -public class SQLIntegerExpr extends SQLNumericLiteralExpr { +public class SQLIntegerExpr extends SQLNumericLiteralExpr implements SQLValuableExpr{ private Number number; @@ -77,4 +77,9 @@ public class SQLIntegerExpr extends SQLNumericLiteralExpr { } return true; } + + @Override + public Object getValue() { + return this.number; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNullExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNullExpr.java index 5e0af25616..6a32194346 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNullExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNullExpr.java @@ -18,7 +18,9 @@ package com.alibaba.druid.sql.ast.expr; import com.alibaba.druid.sql.ast.SQLExprImpl; import com.alibaba.druid.sql.visitor.SQLASTVisitor; -public class SQLNullExpr extends SQLExprImpl implements SQLLiteralExpr { +import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE_NULL; + +public class SQLNullExpr extends SQLExprImpl implements SQLLiteralExpr, SQLValuableExpr { public SQLNullExpr(){ @@ -41,4 +43,9 @@ public class SQLNullExpr extends SQLExprImpl implements SQLLiteralExpr { public boolean equals(Object o) { return o instanceof SQLNullExpr; } + + @Override + public Object getValue() { + return EVAL_VALUE_NULL; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLValuableExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLValuableExpr.java new file mode 100644 index 0000000000..48287868e2 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLValuableExpr.java @@ -0,0 +1,24 @@ +/* + * 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.sql.ast.expr; + +import com.alibaba.druid.sql.ast.SQLExpr; + +public interface SQLValuableExpr extends SQLExpr { + + Object getValue(); + +} 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 30835ed3e7..2e14f2927f 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java @@ -403,7 +403,7 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi @Override public boolean visit(SQLCreateTableStatement x) { WallVisitorUtils.check(this, x); - return true; + return false; } @Override 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 3d897c6009..953d4e22d5 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java @@ -304,7 +304,7 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements @Override public boolean visit(SQLCreateTableStatement x) { WallVisitorUtils.check(this, x); - return true; + return false; } @Override 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 30d7111b58..95b9d835db 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -59,6 +59,7 @@ 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.expr.SQLUnaryExpr; +import com.alibaba.druid.sql.ast.expr.SQLValuableExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; import com.alibaba.druid.sql.ast.statement.SQLCallStatement; @@ -944,47 +945,6 @@ public class WallVisitorUtils { } public static Object getValue(WallVisitor visitor, SQLBinaryOpExpr x) { - if (x.getLeft() instanceof SQLName && x.getRight() instanceof SQLName) { - if (x.getLeft().toString().equalsIgnoreCase(x.getRight().toString())) { - if (x.getOperator() == SQLBinaryOperator.Equality) { - return Boolean.TRUE; - } else if (x.getOperator() == SQLBinaryOperator.NotEqual) { - return Boolean.FALSE; - } - - switch (x.getOperator()) { - case Equality: - case Like: - return Boolean.TRUE; - case NotEqual: - case GreaterThan: - case GreaterThanOrEqual: - case LessThan: - case LessThanOrEqual: - case LessThanOrGreater: - case NotLike: - return Boolean.FALSE; - default: - break; - } - } - } - - if (x.getLeft() instanceof SQLName && !(x.getRight() instanceof SQLName)) { - switch (x.getOperator()) { - case Equality: - case NotEqual: - case GreaterThan: - case GreaterThanOrEqual: - case LessThan: - case LessThanOrEqual: - case LessThanOrGreater: - return null; - default: - break; - } - } - if (x.getOperator() == SQLBinaryOperator.BooleanOr) { List groupList = SQLUtils.split(x); @@ -1058,6 +1018,55 @@ public class WallVisitorUtils { return null; } + if (x.getLeft() instanceof SQLName) { + if (x.getRight() instanceof SQLName) { + if (x.getLeft().toString().equalsIgnoreCase(x.getRight().toString())) { + switch (x.getOperator()) { + case Equality: + case Like: + return Boolean.TRUE; + case NotEqual: + case GreaterThan: + case GreaterThanOrEqual: + case LessThan: + case LessThanOrEqual: + case LessThanOrGreater: + case NotLike: + return Boolean.FALSE; + default: + break; + } + } + } else { + switch (x.getOperator()) { + case Equality: + case NotEqual: + case GreaterThan: + case GreaterThanOrEqual: + case LessThan: + case LessThanOrEqual: + case LessThanOrGreater: + return null; + default: + break; + } + } + } + + if (x.getLeft() instanceof SQLValuableExpr && x.getRight() instanceof SQLValuableExpr) { + Object leftValue = ((SQLValuableExpr) x.getLeft()).getValue(); + Object rightValue = ((SQLValuableExpr) x.getRight()).getValue(); + if (x.getOperator() == SQLBinaryOperator.Equality) { + boolean evalValue = SQLEvalVisitorUtils.eq(leftValue, rightValue); + x.putAttribute(EVAL_VALUE, evalValue); + return evalValue; + } else if (x.getOperator() == SQLBinaryOperator.NotEqual) { + boolean evalValue = SQLEvalVisitorUtils.eq(leftValue, rightValue); + x.putAttribute(EVAL_VALUE, !evalValue); + return !evalValue; + } + } + if (x.getOperator() == SQLBinaryOperator.Like || x.getOperator() == SQLBinaryOperator.NotLike) { Object leftResult = getValue(visitor, x.getLeft()); Object rightResult = getValue(visitor, x.getRight()); @@ -1083,6 +1092,7 @@ public class WallVisitorUtils { return eval(visitor, dbType, x, Collections.emptyList()); } + public static SQLExpr getFirst(SQLExpr x) { if (x instanceof SQLBinaryOpExpr) { diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallPerformanceTest_1.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallPerformanceTest_1.java index 3737a0b258..7de4e90650 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallPerformanceTest_1.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallPerformanceTest_1.java @@ -85,6 +85,59 @@ public class WallPerformanceTest_1 extends TestCase { } } + public void test_7() throws Exception { + String sql = "select * from( select a.*,(select WorkOrderName from WorkOrder where WorkOrder.WorkOrderID=a.WorkOrderID) as WorkOrderName, (select TrainName from Train where Train.TrainID=a.TrainID) as TrainName, (select MemberName from MemberInfo where MemberInfo.MemberID=a.MemberID) as MemberName, (select UserName from SYS_UserInfo where SYS_UserInfo.UserID=a.TaskCreaterID) as UserInfo_UserName, (select ProcessName from SYS_ProcessDefine where SYS_ProcessDefine.ProcessID=a.ProcessID) as ProcessName, (select ShopName from shop where shop.ShopID=a.ShopID) as ShopName, (select UserName from SYS_UserInfo where SYS_UserInfo.UserID=a.AssessID) as Assess_UserName, (select UserName from SYS_UserInfo where SYS_UserInfo.UserID=a.Executuserid) as Executuser_UserName, ROW_NUMBER() OVER(order by a.TaskID desc,a.TaskCreateDate asc) as row from [Task] as a where AccountID=48 and (( a.TaskExecutorID = 12 and a.TaskStatus !='2' and IFValid=1 ) or a.TaskID in (select a.TaskID from [Task] as a ,WorkOLDTaskMould as b where a.TaskMouldOLDID=b.TaskMouldOLDID and a.TaskExecutorID=0 and a.TaskStatus=0 and ( b.Deal_User like '%,12,%' or b.Deal_Dept like '%,18,%' or b.Deal_Dept like '%,53,%' or b.Deal_Dept like '%,129,%' or b.Deal_Dept like '%,151,%' or b.Deal_Dept like '%,79,%' or b.Deal_Dept like '%,116,%' or b.Deal_Dept like '%,117,%' or b.Deal_Post like '%,52,%' or b.Deal_Post like '%,6,%' or b.Deal_Post like '%,12,%' or b.Deal_Post like '%,13,%' or b.Deal_Post like '%,30,%' or b.Deal_Post like '%,64,%' or b.Deal_Post like '%,56,%' or b.Deal_Group like '%,6,%' or b.Deal_Group like '%,12,%' or b.Deal_Group like '%,14,%' ))) ) a where row between 1 and 100"; + // System.out.println("sql: \n" + ParameterizedOutputVisitorUtils.parameterize(sql, JdbcUtils.MYSQL)); + for (int i = 0; i < 5; i++) { + System.out.println("--7--use time:" + this.evaluate(sql, "mysql", 1000l)); + } + } + + public void test_8() throws Exception { + String sql = "SELECT pr.order_no,pr.receipt_no,pr.datetime, pt.type_name,pr.amount,u.username FROM payments_record pr inner join tasks t on t.order_no= pr.order_no inner join orders o on o.order_number=t.order_no inner join pay_type pt on pt.id=pr.payment_type inner join users u on u.id=pr.operator_id where t.order_no=o.order_number and o.order_status=4 and t.task_status=6 and o.station_collection=1 and pr.client_status='success' and pr.operator_id=29 and (pt.id=1 or pt.id=2) and pr.datetime between '2014-10-22 00:00:00' and '2014-10-22 23:59:59'"; + // System.out.println("sql: \n" + ParameterizedOutputVisitorUtils.parameterize(sql, JdbcUtils.MYSQL)); + for (int i = 0; i < 5; i++) { + System.out.println("--8--use time:" + this.evaluate(sql, "mysql", 1000l)); + } + } + + public void test_9() throws Exception { + String sql = "SELECT COUNT(*) FROM ReportSalesOrderList t0 LEFT JOIN ReportProductList t1 ON t0.SkuCode = t1.SkuCode WHERE (ShopId = 0 OR 0 = 0) AND (ShopOrderNo = '' OR '' = '') AND (CustomerName LIKE CONCAT ('%', '', '%') OR '' = '')AND (t0.OrderType = '0' OR '0' = '0')AND ( (t0.orderStatus >0 AND t0.orderStatus <=45 AND 10 = 20 ) OR (t0.orderStatus >45 AND t0.orderStatus <= 60 AND 10 = 30 ) OR (t0.orderStatus >60 AND t0.orderStatus <= 70 AND 10 = 40 ) OR (t0.orderStatus >70 AND t0.orderStatus <= 90 AND 10 = 50 )OR 10 = 10 ) AND ( ('30' = '10' AND t0.ShopPayTime >= '2014-10-01 00:00:00 ' AND t0.ShopPayTime < '2014-10-23 00:00:00 ' ) OR ('30' = '20' AND t0.DeliveryTime >= '2014-10-01 00:00:00 ' AND t0.DeliveryTime < '2014-10-23 00:00:00 ' ) OR ('30' = '30' AND t0.EndTime >= '2014-10-01 00:00:00 ' AND t0.EndTime < '2014-10-23 00:00:00 ' ) OR ('30' = '40' AND t0.RefundTime >= '2014-10-01 00:00:00 ' AND t0.RefundTime < '2014-10-23 00:00:00 ' ) ) GROUP BY t0.OrderNo HAVING ( GROUP_CONCAT(t1.ItemCode) LIKE CONCAT ('%', '', '%') OR GROUP_CONCAT(t1.ItemName) LIKE CONCAT ('%', '', '%') OR GROUP_CONCAT(t1.SkuCode) LIKE CONCAT ('%', '', '%') OR GROUP_CONCAT(DISTINCT t1.SkuName) LIKE CONCAT ('%', '', '%') OR '' = '') AND (GROUP_CONCAT(t1.BrandName) LIKE CONCAT ('%', '', '%') Or '' = '')AND ('10' = '10' OR ('10'= '20' AND GROUP_CONCAT(t0.RefundType) IS NULL ) OR('10' = '30' AND GROUP_CONCAT(t0.RefundType) != ''))"; + // System.out.println("sql: \n" + ParameterizedOutputVisitorUtils.parameterize(sql, JdbcUtils.MYSQL)); + for (int i = 0; i < 5; i++) { + System.out.println("--9--use time:" + this.evaluate(sql, "mysql", 1000l)); + } + } + + public void test_10() throws Exception { + String sql = "insert into saleB_63ceb9cbab074f3f91dda04a3fe79a57_z (billid,tblastmodate,seller_CourierId,r3_billtype,tags_color,seller_momo,buyer_momo,buyer_province,buyer_city,buyer_area,buyer_mail_code,post_fee,ele_shopname,ele_sordercode,type,codfee,codfamt,ExpressCode,PointFee,invoiceType,invoicePayer,invoiceContent) select 719685,Modified,0,isnull(r3_billtype,''),isnull(SellerFlag,''),isnull(SellerMemo,''),isnull(BuyerMessage,''),isnull(ReceiverState,''),isnull(ReceiverCity,''),isnull(ReceiverDistrict,''),isnull(ReceiverZip,''),isnull(PostFee,''),isnull(Title,''),isnull(Tid,''),isnull(type,''),isnull(codfee,''),isnull(ExpressAgencyFee,''),isnull(Ext5,''),isnull(PointFee,''),isnull(Ext1,''),isnull(Ext2,''),isnull(Ext3,'') from taobao_order where r3_billid=837361947087831 and shopConfigid=2"; + // System.out.println("sql: \n" + ParameterizedOutputVisitorUtils.parameterize(sql, JdbcUtils.MYSQL)); + for (int i = 0; i < 5; i++) { + System.out.println("--10--use time:" + this.evaluate(sql, "mssql", 1000l)); + } + } + + public void test_11() throws Exception { + String sql = "create view tempview_CTbillflow_material as SELECT billflow.billtype, billflow.billid, billflow.itemno, billflow.MaterialID, billflow.quantity, billflow.ioflag, billflow.storeid, content.CT1, content.CT2 FROM billflow INNER JOIN content ON billflow.billtype = content.tableid AND billflow.billid = content.billid AND billflow.itemno = content.itemno WHERE billflow.billflowid>0 and billflow.storeid<>1 and billflow.storeid<>2 and billflow.storeid<>3 and billflow.storeid<>5 and billflow.storeid<>7 and billflow.storeid<>8 and billflow.storeid<>9 and billflow.storeid<>10 and billflow.storeid<>11 and (1=2 or billflow.MaterialID=893 or billflow.MaterialID=904 or billflow.MaterialID=80 or billflow.MaterialID=8 or billflow.MaterialID=8) UNION ALL SELECT billflow.billtype, billflow.billid, billflow.itemno, billflow.MaterialID, billflow.quantity, billflow.ioflag, billflow.storeid, content.CT1, content.CT2 FROM billflow INNER JOIN content ON billflow.billtype = content.tableid AND billflow.billid = content.billid AND billflow.itemno = content.itemno inner join Material on billflow.MaterialID=Material.MaterialID and Material.feature=1 WHERE billflow.billflowid< 0 and (1=2 or content.CT1<>'' or content.CT2<>'') and billflow.storeid<>1 and billflow.storeid<>2 and billflow.storeid<>3 and billflow.storeid<>5 and billflow.storeid<>7 and billflow.storeid<>8 and billflow.storeid<>9 and billflow.storeid<>10 and billflow.storeid<>11 and (1=2 or billflow.MaterialID=893 or billflow.MaterialID=904 or billflow.MaterialID=80 or billflow.MaterialID=8 or billflow.MaterialID=8) UNION ALL SELECT billflow.billtype, billflow.billid, billflow.itemno, billflow.MaterialID, billflow.quantity, billflow.ioflag, billflow.storeid, content.CT1, content.CT2 FROM billflow INNER JOIN content ON billflow.billtype = content.tableid AND billflow.billid = content.billid AND billflow.itemno = content.itemno inner join Material on billflow.MaterialID=Material.MaterialID and Mater"; + for (int i = 0; i < 5; i++) { + System.out.println("--11--use time:" + this.evaluate(sql, "mssql", 1000l)); + } + } + + public void test_12() throws Exception { + String sql = "select b.*,c.county,c.shangquan,c.naturevar,directionsvar,fitmentvar,c.villagename,c.titles,c.address,c.smallpath,c.imgcount,c.hall,c.layer,c.totallayer,c.tags from (select * from(select rentid,room,updatetime,minarea,minprice,avgprice,labelstate,unixdate,isimgs,zongdianid,mendianid,zongdianval,mendianval, Row_Number() over(order by minarea desc,rentid desc) as RowID from house_rent_search_kunshan where isaudit=0 and isdel=0 and state=0 and countyid=@countyid and nature=@nature and directions=@directions) as a where RowID>=1 and RowID<=20) as b inner join house_rent_list_kunshan as c on b.rentid=c.rentid order by minarea desc,rentid desc"; + for (int i = 0; i < 5; i++) { + System.out.println("--12--use time:" + this.evaluate(sql, "mssql", 1000l)); + } + } + + public void test_13() throws Exception { + String sql = "SELECT COUNT(*) cn1 FROM KUKA_SystemOrder WHERE 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 AND 1=1 "; + for (int i = 0; i < 5; i++) { + System.out.println("--13--use time:" + this.evaluate(sql, "mssql", 1000l)); + } + } + public Long evaluate(String sql, String dbType, Long num) { if (sql == null || dbType == null) { return new Long(-1); @@ -109,7 +162,7 @@ public class WallPerformanceTest_1 extends TestCase { provider.getConfig().setConditionDoubleConstAllow(true); provider.getConfig().setCommentAllow(true); - provider.getConfig().setSelectUnionCheck(false); + // provider.getConfig().setSelectUnionCheck(false); // add by yanhui.liyh provider.setBlackListEnable(false);