From 4e00ace631c06215629f7fdc1fe324502a119530 Mon Sep 17 00:00:00 2001 From: wenshao Date: Tue, 18 Apr 2017 17:08:07 +0800 Subject: [PATCH] add method PageUtils.hasUnorderedLimit for mysql. for issue #1688 --- .../com/alibaba/druid/sql/PagerUtils.java | 32 +++++++++++++++++++ .../sql/PagerUtilsTest_hasUnorderedLimit.java | 24 ++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/PagerUtilsTest_hasUnorderedLimit.java diff --git a/src/main/java/com/alibaba/druid/sql/PagerUtils.java b/src/main/java/com/alibaba/druid/sql/PagerUtils.java index 03a9fa54ce..786dcb006f 100644 --- a/src/main/java/com/alibaba/druid/sql/PagerUtils.java +++ b/src/main/java/com/alibaba/druid/sql/PagerUtils.java @@ -16,7 +16,9 @@ package com.alibaba.druid.sql; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import com.alibaba.druid.DruidRuntimeException; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLOrderBy; import com.alibaba.druid.sql.ast.SQLOver; @@ -42,11 +44,13 @@ import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; import com.alibaba.druid.sql.ast.SQLLimit; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; import com.alibaba.druid.util.JdbcConstants; import com.alibaba.druid.util.JdbcUtils; @@ -503,4 +507,32 @@ public class PagerUtils { return -1; } + + public static boolean hasUnorderedLimit(String sql, String dbType) { + List stmtList = SQLUtils.parseStatements(sql, dbType); + + if (!JdbcConstants.MYSQL.equals(dbType)) { + throw new DruidRuntimeException("not supported. dbType : " + dbType); + } + + final AtomicInteger unorderedLimitCount = new AtomicInteger(); + MySqlASTVisitorAdapter visitor = new MySqlASTVisitorAdapter() { + @Override + public boolean visit(MySqlSelectQueryBlock x) { + SQLOrderBy orderBy = x.getOrderBy(); + SQLLimit limit = x.getLimit(); + + if (limit != null && (orderBy == null || orderBy.getItems().size() == 0)) { + unorderedLimitCount.incrementAndGet(); + } + return false; + } + }; + + for (SQLStatement stmt : stmtList) { + stmt.accept(visitor); + } + + return unorderedLimitCount.get() > 0; + } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/PagerUtilsTest_hasUnorderedLimit.java b/src/test/java/com/alibaba/druid/bvt/sql/PagerUtilsTest_hasUnorderedLimit.java new file mode 100644 index 0000000000..41d13a2bb7 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/PagerUtilsTest_hasUnorderedLimit.java @@ -0,0 +1,24 @@ +package com.alibaba.druid.bvt.sql; + +import com.alibaba.druid.sql.PagerUtils; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; +import org.junit.Assert; + +public class PagerUtilsTest_hasUnorderedLimit extends TestCase { + + public void test_false() throws Exception { + String sql = " select * from test t order by id limit 3"; + assertFalse(PagerUtils.hasUnorderedLimit(sql, JdbcConstants.MYSQL)); + } + + public void test_false_1() throws Exception { + String sql = " select * from test t"; + assertFalse(PagerUtils.hasUnorderedLimit(sql, JdbcConstants.MYSQL)); + } + + public void test_true() throws Exception { + String sql = " select * from test t limit 3"; + assertTrue(PagerUtils.hasUnorderedLimit(sql, JdbcConstants.MYSQL)); + } +}