From 541ed5c7f246ddf23ffed35fae48a592d6b589de Mon Sep 17 00:00:00 2001 From: melin Date: Fri, 26 Jul 2013 16:17:44 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BC=98=E5=85=88=E6=A3=80=E6=B5=8Bslf4j?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../druid/support/logging/LogFactory.java | 202 +++++++++--------- 1 file changed, 101 insertions(+), 101 deletions(-) diff --git a/src/main/java/com/alibaba/druid/support/logging/LogFactory.java b/src/main/java/com/alibaba/druid/support/logging/LogFactory.java index 04be43ea72..63effb848c 100644 --- a/src/main/java/com/alibaba/druid/support/logging/LogFactory.java +++ b/src/main/java/com/alibaba/druid/support/logging/LogFactory.java @@ -1,101 +1,101 @@ -/* - * 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.support.logging; - -import java.lang.reflect.Constructor; - -@SuppressWarnings("rawtypes") -public class LogFactory { - - private static Constructor logConstructor; - - static { - // TODO add slf4j logging - - // 优先选择log4j,而非Apache Common Logging. 因为后者无法设置真实Log调用者的信息 - tryImplementation("org.apache.log4j.Logger", "com.alibaba.druid.support.logging.Log4jImpl"); - tryImplementation("java.util.logging.Logger", "com.alibaba.druid.support.logging.Jdk14LoggingImpl"); - tryImplementation("org.slf4j.Logger", "com.alibaba.druid.support.logging.SLF4JImpl"); - tryImplementation("org.apache.commons.logging.LogFactory", - "com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl"); - - if (logConstructor == null) { - try { - logConstructor = NoLoggingImpl.class.getConstructor(String.class); - } catch (Exception e) { - throw new IllegalStateException(e.getMessage(), e); - } - } - } - - @SuppressWarnings("unchecked") - private static void tryImplementation(String testClassName, String implClassName) { - if (logConstructor != null) { - return; - } - - try { - Resources.classForName(testClassName); - Class implClass = Resources.classForName(implClassName); - logConstructor = implClass.getConstructor(new Class[] { String.class }); - - Class declareClass = logConstructor.getDeclaringClass(); - if (!Log.class.isAssignableFrom(declareClass)) { - logConstructor = null; - } - - try { - logConstructor.newInstance(LogFactory.class.getName()); - } catch (Throwable t) { - logConstructor = null; - } - } catch (Throwable t) { - // skip - } - } - - public static Log getLog(Class clazz) { - return getLog(clazz.getName()); - } - - public static Log getLog(String loggerName) { - try { - return (Log) logConstructor.newInstance(new Object[] { loggerName }); - } catch (Throwable t) { - throw new RuntimeException("Error creating logger for logger '" + loggerName + "'. Cause: " + t, t); - } - } - - @SuppressWarnings("unchecked") - public static synchronized void selectLog4JLogging() { - try { - Resources.classForName("org.apache.log4j.Logger"); - Class implClass = Resources.classForName("com.alibaba.druid.support.logging.Log4jImpl"); - logConstructor = implClass.getConstructor(new Class[] { String.class }); - } catch (Throwable t) { - } - } - - @SuppressWarnings("unchecked") - public static synchronized void selectJavaLogging() { - try { - Resources.classForName("java.util.logging.Logger"); - Class implClass = Resources.classForName("com.alibaba.druid.support.logging.Jdk14LoggingImpl"); - logConstructor = implClass.getConstructor(new Class[] { String.class }); - } catch (Throwable t) { - } - } -} +/* + * 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.support.logging; + +import java.lang.reflect.Constructor; + +@SuppressWarnings("rawtypes") +public class LogFactory { + + private static Constructor logConstructor; + + static { + // TODO add slf4j logging + + // 优先选择log4j,而非Apache Common Logging. 因为后者无法设置真实Log调用者的信息 + tryImplementation("org.slf4j.Logger", "com.alibaba.druid.support.logging.SLF4JImpl"); + tryImplementation("org.apache.log4j.Logger", "com.alibaba.druid.support.logging.Log4jImpl"); + tryImplementation("java.util.logging.Logger", "com.alibaba.druid.support.logging.Jdk14LoggingImpl"); + tryImplementation("org.apache.commons.logging.LogFactory", + "com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl"); + + if (logConstructor == null) { + try { + logConstructor = NoLoggingImpl.class.getConstructor(String.class); + } catch (Exception e) { + throw new IllegalStateException(e.getMessage(), e); + } + } + } + + @SuppressWarnings("unchecked") + private static void tryImplementation(String testClassName, String implClassName) { + if (logConstructor != null) { + return; + } + + try { + Resources.classForName(testClassName); + Class implClass = Resources.classForName(implClassName); + logConstructor = implClass.getConstructor(new Class[] { String.class }); + + Class declareClass = logConstructor.getDeclaringClass(); + if (!Log.class.isAssignableFrom(declareClass)) { + logConstructor = null; + } + + try { + logConstructor.newInstance(LogFactory.class.getName()); + } catch (Throwable t) { + logConstructor = null; + } + } catch (Throwable t) { + // skip + } + } + + public static Log getLog(Class clazz) { + return getLog(clazz.getName()); + } + + public static Log getLog(String loggerName) { + try { + return (Log) logConstructor.newInstance(new Object[] { loggerName }); + } catch (Throwable t) { + throw new RuntimeException("Error creating logger for logger '" + loggerName + "'. Cause: " + t, t); + } + } + + @SuppressWarnings("unchecked") + public static synchronized void selectLog4JLogging() { + try { + Resources.classForName("org.apache.log4j.Logger"); + Class implClass = Resources.classForName("com.alibaba.druid.support.logging.Log4jImpl"); + logConstructor = implClass.getConstructor(new Class[] { String.class }); + } catch (Throwable t) { + } + } + + @SuppressWarnings("unchecked") + public static synchronized void selectJavaLogging() { + try { + Resources.classForName("java.util.logging.Logger"); + Class implClass = Resources.classForName("com.alibaba.druid.support.logging.Jdk14LoggingImpl"); + logConstructor = implClass.getConstructor(new Class[] { String.class }); + } catch (Throwable t) { + } + } +} From 53515c940111807c39fda311c600d3969db75cb1 Mon Sep 17 00:00:00 2001 From: melin Date: Fri, 26 Jul 2013 16:29:39 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E6=AD=A3pagerutils=20oracle=20lim?= =?UTF-8?q?it=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/alibaba/druid/sql/PagerUtils.java | 738 +++++++++--------- 1 file changed, 369 insertions(+), 369 deletions(-) diff --git a/src/main/java/com/alibaba/druid/sql/PagerUtils.java b/src/main/java/com/alibaba/druid/sql/PagerUtils.java index 5205ce6190..f2b313a9b6 100644 --- a/src/main/java/com/alibaba/druid/sql/PagerUtils.java +++ b/src/main/java/com/alibaba/druid/sql/PagerUtils.java @@ -1,369 +1,369 @@ -/* - * 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; - -import java.util.List; - -import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.ast.SQLOrderBy; -import com.alibaba.druid.sql.ast.SQLOver; -import com.alibaba.druid.sql.ast.SQLStatement; -import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr; -import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr; -import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; -import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; -import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; -import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; -import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; -import com.alibaba.druid.sql.ast.statement.SQLSelect; -import com.alibaba.druid.sql.ast.statement.SQLSelectItem; -import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; -import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; -import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; -import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; -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.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; -import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr; -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.util.JdbcConstants; - -public class PagerUtils { - - public static String count(String sql, String dbType) { - List stmtList = SQLUtils.parseStatements(sql, dbType); - - if (stmtList.size() != 1) { - throw new IllegalArgumentException("sql not support count : " + sql); - } - - SQLStatement stmt = stmtList.get(0); - - if (!(stmt instanceof SQLSelectStatement)) { - throw new IllegalArgumentException("sql not support count : " + sql); - } - - SQLSelectStatement selectStmt = (SQLSelectStatement) stmt; - return count(selectStmt.getSelect(), dbType); - } - - public static String limit(String sql, String dbType, int offset, int count) { - List stmtList = SQLUtils.parseStatements(sql, dbType); - - if (stmtList.size() != 1) { - throw new IllegalArgumentException("sql not support count : " + sql); - } - - SQLStatement stmt = stmtList.get(0); - - if (!(stmt instanceof SQLSelectStatement)) { - throw new IllegalArgumentException("sql not support count : " + sql); - } - - SQLSelectStatement selectStmt = (SQLSelectStatement) stmt; - - return limit(selectStmt.getSelect(), dbType, offset, count); - } - - public static String limit(SQLSelect select, String dbType, int offset, int count) { - SQLSelectQuery query = select.getQuery(); - - if (JdbcConstants.ORACLE.equals(dbType)) { - return limitOracle(select, dbType, offset, count); - } - - if (JdbcConstants.DB2.equals(dbType)) { - return limitDB2(select, dbType, offset, count); - } - - if (JdbcConstants.SQL_SERVER.equals(dbType)) { - return limitSQLServer(select, dbType, offset, count); - } - - if (query instanceof SQLSelectQueryBlock) { - return limitQueryBlock(select, dbType, offset, count); - } - - throw new UnsupportedOperationException(); - } - - private static String limitQueryBlock(SQLSelect select, String dbType, int offset, int count) { - SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) select.getQuery(); - if (JdbcConstants.MYSQL.equals(dbType) || // - JdbcConstants.MARIADB.equals(dbType) || // - JdbcConstants.H2.equals(dbType)) { - return limitMySqlQueryBlock((MySqlSelectQueryBlock) queryBlock, dbType, offset, count); - } - - throw new UnsupportedOperationException(); - } - - private static String limitDB2(SQLSelect select, String dbType, int offset, int count) { - SQLSelectQuery query = select.getQuery(); - - if (query instanceof SQLSelectQueryBlock) { - DB2SelectQueryBlock queryBlock = (DB2SelectQueryBlock) query; - if (offset <= 0) { - queryBlock.setFirst(new SQLNumberExpr(count)); - return SQLUtils.toSQLString(select, dbType); - } - - SQLAggregateExpr aggregateExpr = new SQLAggregateExpr("ROW_NUMBER"); - SQLOrderBy orderBy = select.getOrderBy(); - if (orderBy != null) { - aggregateExpr.setOver(new SQLOver(orderBy)); - select.setOrderBy(null); - } - - queryBlock.getSelectList().add(new SQLSelectItem(aggregateExpr, "ROWNUM")); - - DB2SelectQueryBlock countQueryBlock = new DB2SelectQueryBlock(); - countQueryBlock.getSelectList().add(new SQLSelectItem(new SQLAllColumnExpr())); - - countQueryBlock.setFrom(new SQLSubqueryTableSource(select, "XX")); - - SQLBinaryOpExpr gt = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // - SQLBinaryOperator.GreaterThan, // - new SQLNumberExpr(offset)); - SQLBinaryOpExpr lteq = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // - SQLBinaryOperator.LessThanOrEqual, // - new SQLNumberExpr(count + offset)); - SQLBinaryOpExpr pageCondition = new SQLBinaryOpExpr(gt, SQLBinaryOperator.BooleanAnd, lteq); - - countQueryBlock.setWhere(pageCondition); - - return SQLUtils.toSQLString(countQueryBlock, dbType); - } - - return SQLUtils.toSQLString(select, dbType); - } - - private static String limitSQLServer(SQLSelect select, String dbType, int offset, int count) { - SQLSelectQuery query = select.getQuery(); - - if (query instanceof SQLSelectQueryBlock) { - SQLServerSelectQueryBlock queryBlock = (SQLServerSelectQueryBlock) query; - if (offset <= 0) { - queryBlock.setTop(new SQLServerTop(new SQLNumberExpr(count))); - return SQLUtils.toSQLString(select, dbType); - } - - SQLAggregateExpr aggregateExpr = new SQLAggregateExpr("ROW_NUMBER"); - SQLOrderBy orderBy = select.getOrderBy(); - if (orderBy != null) { - aggregateExpr.setOver(new SQLOver(orderBy)); - select.setOrderBy(null); - } - - queryBlock.getSelectList().add(new SQLSelectItem(aggregateExpr, "ROWNUM")); - - DB2SelectQueryBlock countQueryBlock = new DB2SelectQueryBlock(); - countQueryBlock.getSelectList().add(new SQLSelectItem(new SQLAllColumnExpr())); - - countQueryBlock.setFrom(new SQLSubqueryTableSource(select, "XX")); - - SQLBinaryOpExpr gt = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // - SQLBinaryOperator.GreaterThan, // - new SQLNumberExpr(offset)); - SQLBinaryOpExpr lteq = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // - SQLBinaryOperator.LessThanOrEqual, // - new SQLNumberExpr(count + offset)); - SQLBinaryOpExpr pageCondition = new SQLBinaryOpExpr(gt, SQLBinaryOperator.BooleanAnd, lteq); - - countQueryBlock.setWhere(pageCondition); - - return SQLUtils.toSQLString(countQueryBlock, dbType); - } - - return SQLUtils.toSQLString(select, dbType); - } - - private static String limitOracle(SQLSelect select, String dbType, int offset, int count) { - SQLSelectQuery query = select.getQuery(); - - if (query instanceof SQLSelectQueryBlock) { - OracleSelectQueryBlock queryBlock = (OracleSelectQueryBlock) query; - if (select.getOrderBy() == null && offset <= 0) { - SQLExpr condition = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // - SQLBinaryOperator.LessThanOrEqual, // - new SQLNumberExpr(count)); - if (queryBlock.getWhere() == null) { - queryBlock.setWhere(condition); - } else { - queryBlock.setWhere(new SQLBinaryOpExpr(queryBlock.getWhere(), // - SQLBinaryOperator.BooleanAnd, // - condition)); - } - - return SQLUtils.toSQLString(select, dbType); - } - } - - OracleSelectQueryBlock countQueryBlock = new OracleSelectQueryBlock(); - countQueryBlock.getSelectList().add(new SQLSelectItem(new SQLPropertyExpr(new SQLIdentifierExpr("XX"), "*"))); - countQueryBlock.getSelectList().add(new SQLSelectItem(new SQLIdentifierExpr("ROWNUM"), "RN")); - - countQueryBlock.setFrom(new SQLSubqueryTableSource(select, "XX")); - countQueryBlock.setWhere(new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // - SQLBinaryOperator.LessThanOrEqual, // - new SQLNumberExpr(count + offset))); - if (offset <= 0) { - return SQLUtils.toSQLString(countQueryBlock, dbType); - } - - OracleSelectQueryBlock offsetQueryBlock = new OracleSelectQueryBlock(); - offsetQueryBlock.getSelectList().add(new SQLSelectItem(new SQLAllColumnExpr())); - offsetQueryBlock.setFrom(new SQLSubqueryTableSource(new SQLSelect(countQueryBlock), "XXX")); - offsetQueryBlock.setWhere(new SQLBinaryOpExpr(new SQLIdentifierExpr("RN"), // - SQLBinaryOperator.GreaterThan, // - new SQLNumberExpr(offset))); - - return SQLUtils.toSQLString(offsetQueryBlock, dbType); - } - - private static String limitMySqlQueryBlock(MySqlSelectQueryBlock queryBlock, String dbType, int offset, int count) { - if (queryBlock.getLimit() != null) { - throw new IllegalArgumentException("limit already exists."); - } - - Limit limit = new Limit(); - if (offset > 0) { - limit.setOffset(new SQLNumberExpr(offset)); - } - limit.setRowCount(new SQLNumberExpr(count)); - queryBlock.setLimit(limit); - - return SQLUtils.toSQLString(queryBlock, dbType); - } - - private static String count(SQLSelect select, String dbType) { - if (select.getOrderBy() != null) { - select.setOrderBy(null); - } - - SQLSelectQuery query = select.getQuery(); - clearOrderBy(query); - - if (query instanceof SQLSelectQueryBlock) { - SQLSelectItem countItem = createCountItem(dbType); - - SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query; - - if (queryBlock.getGroupBy() != null && queryBlock.getGroupBy().getItems().size() > 0) { - return createCountUseSubQuery(select, dbType); - } - - queryBlock.getSelectList().clear(); - queryBlock.getSelectList().add(countItem); - return SQLUtils.toSQLString(select, dbType); - } else if (query instanceof SQLUnionQuery) { - return createCountUseSubQuery(select, dbType); - } - - throw new IllegalStateException(); - } - - private static String createCountUseSubQuery(SQLSelect select, String dbType) { - SQLSelectQueryBlock countSelectQuery = createQueryBlock(dbType); - - SQLSelectItem countItem = createCountItem(dbType); - countSelectQuery.getSelectList().add(countItem); - - countSelectQuery.setFrom(new SQLSubqueryTableSource(select)); - - SQLSelect countSelect = new SQLSelect(countSelectQuery); - SQLSelectStatement countStmt = new SQLSelectStatement(countSelect); - - return SQLUtils.toSQLString(countStmt, dbType); - } - - private static SQLSelectQueryBlock createQueryBlock(String dbType) { - if (JdbcConstants.MYSQL.equals(dbType)) { - return new MySqlSelectQueryBlock(); - } - - if (JdbcConstants.MARIADB.equals(dbType)) { - return new MySqlSelectQueryBlock(); - } - - if (JdbcConstants.H2.equals(dbType)) { - return new MySqlSelectQueryBlock(); - } - - if (JdbcConstants.ORACLE.equals(dbType)) { - return new OracleSelectQueryBlock(); - } - - if (JdbcConstants.POSTGRESQL.equals(dbType)) { - return new PGSelectQueryBlock(); - } - - if (JdbcConstants.SQL_SERVER.equals(dbType)) { - return new SQLServerSelectQueryBlock(); - } - - if (JdbcConstants.DB2.equals(dbType)) { - return new DB2SelectQueryBlock(); - } - - return new SQLSelectQueryBlock(); - } - - private static SQLSelectItem createCountItem(String dbType) { - SQLAggregateExpr countExpr; - - if (JdbcConstants.ORACLE.equals(dbType)) { - countExpr = new OracleAggregateExpr("COUNT"); - } else { - countExpr = new SQLAggregateExpr("COUNT"); - } - countExpr.getArguments().add(new SQLAllColumnExpr()); - - SQLSelectItem countItem = new SQLSelectItem(countExpr); - return countItem; - } - - private static void clearOrderBy(SQLSelectQuery query) { - if (query instanceof SQLSelectQueryBlock) { - SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query; - if (queryBlock instanceof MySqlSelectQueryBlock) { - MySqlSelectQueryBlock mysqlQueryBlock = (MySqlSelectQueryBlock) queryBlock; - if (mysqlQueryBlock.getOrderBy() != null) { - mysqlQueryBlock.setOrderBy(null); - } - } else if (queryBlock instanceof PGSelectQueryBlock) { - PGSelectQueryBlock pgQueryBlock = (PGSelectQueryBlock) queryBlock; - if (pgQueryBlock.getOrderBy() != null) { - pgQueryBlock.setOrderBy(null); - } - } - return; - } - - if (query instanceof SQLUnionQuery) { - SQLUnionQuery union = (SQLUnionQuery) query; - if (union.getOrderBy() != null) { - union.setOrderBy(null); - } - clearOrderBy(union.getLeft()); - clearOrderBy(union.getRight()); - } - } -} +/* + * 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; + +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLOrderBy; +import com.alibaba.druid.sql.ast.SQLOver; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr; +import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; +import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; +import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; +import com.alibaba.druid.sql.ast.statement.SQLSelect; +import com.alibaba.druid.sql.ast.statement.SQLSelectItem; +import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; +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.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr; +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.util.JdbcConstants; + +public class PagerUtils { + + public static String count(String sql, String dbType) { + List stmtList = SQLUtils.parseStatements(sql, dbType); + + if (stmtList.size() != 1) { + throw new IllegalArgumentException("sql not support count : " + sql); + } + + SQLStatement stmt = stmtList.get(0); + + if (!(stmt instanceof SQLSelectStatement)) { + throw new IllegalArgumentException("sql not support count : " + sql); + } + + SQLSelectStatement selectStmt = (SQLSelectStatement) stmt; + return count(selectStmt.getSelect(), dbType); + } + + public static String limit(String sql, String dbType, int offset, int count) { + List stmtList = SQLUtils.parseStatements(sql, dbType); + + if (stmtList.size() != 1) { + throw new IllegalArgumentException("sql not support count : " + sql); + } + + SQLStatement stmt = stmtList.get(0); + + if (!(stmt instanceof SQLSelectStatement)) { + throw new IllegalArgumentException("sql not support count : " + sql); + } + + SQLSelectStatement selectStmt = (SQLSelectStatement) stmt; + + return limit(selectStmt.getSelect(), dbType, offset, count); + } + + public static String limit(SQLSelect select, String dbType, int offset, int count) { + SQLSelectQuery query = select.getQuery(); + + if (JdbcConstants.ORACLE.equals(dbType)) { + return limitOracle(select, dbType, offset, count); + } + + if (JdbcConstants.DB2.equals(dbType)) { + return limitDB2(select, dbType, offset, count); + } + + if (JdbcConstants.SQL_SERVER.equals(dbType)) { + return limitSQLServer(select, dbType, offset, count); + } + + if (query instanceof SQLSelectQueryBlock) { + return limitQueryBlock(select, dbType, offset, count); + } + + throw new UnsupportedOperationException(); + } + + private static String limitQueryBlock(SQLSelect select, String dbType, int offset, int count) { + SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) select.getQuery(); + if (JdbcConstants.MYSQL.equals(dbType) || // + JdbcConstants.MARIADB.equals(dbType) || // + JdbcConstants.H2.equals(dbType)) { + return limitMySqlQueryBlock((MySqlSelectQueryBlock) queryBlock, dbType, offset, count); + } + + throw new UnsupportedOperationException(); + } + + private static String limitDB2(SQLSelect select, String dbType, int offset, int count) { + SQLSelectQuery query = select.getQuery(); + + if (query instanceof SQLSelectQueryBlock) { + DB2SelectQueryBlock queryBlock = (DB2SelectQueryBlock) query; + if (offset <= 0) { + queryBlock.setFirst(new SQLNumberExpr(count)); + return SQLUtils.toSQLString(select, dbType); + } + + SQLAggregateExpr aggregateExpr = new SQLAggregateExpr("ROW_NUMBER"); + SQLOrderBy orderBy = select.getOrderBy(); + if (orderBy != null) { + aggregateExpr.setOver(new SQLOver(orderBy)); + select.setOrderBy(null); + } + + queryBlock.getSelectList().add(new SQLSelectItem(aggregateExpr, "ROWNUM")); + + DB2SelectQueryBlock countQueryBlock = new DB2SelectQueryBlock(); + countQueryBlock.getSelectList().add(new SQLSelectItem(new SQLAllColumnExpr())); + + countQueryBlock.setFrom(new SQLSubqueryTableSource(select, "XX")); + + SQLBinaryOpExpr gt = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // + SQLBinaryOperator.GreaterThan, // + new SQLNumberExpr(offset)); + SQLBinaryOpExpr lteq = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // + SQLBinaryOperator.LessThanOrEqual, // + new SQLNumberExpr(count + offset)); + SQLBinaryOpExpr pageCondition = new SQLBinaryOpExpr(gt, SQLBinaryOperator.BooleanAnd, lteq); + + countQueryBlock.setWhere(pageCondition); + + return SQLUtils.toSQLString(countQueryBlock, dbType); + } + + return SQLUtils.toSQLString(select, dbType); + } + + private static String limitSQLServer(SQLSelect select, String dbType, int offset, int count) { + SQLSelectQuery query = select.getQuery(); + + if (query instanceof SQLSelectQueryBlock) { + SQLServerSelectQueryBlock queryBlock = (SQLServerSelectQueryBlock) query; + if (offset <= 0) { + queryBlock.setTop(new SQLServerTop(new SQLNumberExpr(count))); + return SQLUtils.toSQLString(select, dbType); + } + + SQLAggregateExpr aggregateExpr = new SQLAggregateExpr("ROW_NUMBER"); + SQLOrderBy orderBy = select.getOrderBy(); + if (orderBy != null) { + aggregateExpr.setOver(new SQLOver(orderBy)); + select.setOrderBy(null); + } + + queryBlock.getSelectList().add(new SQLSelectItem(aggregateExpr, "ROWNUM")); + + DB2SelectQueryBlock countQueryBlock = new DB2SelectQueryBlock(); + countQueryBlock.getSelectList().add(new SQLSelectItem(new SQLAllColumnExpr())); + + countQueryBlock.setFrom(new SQLSubqueryTableSource(select, "XX")); + + SQLBinaryOpExpr gt = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // + SQLBinaryOperator.GreaterThan, // + new SQLNumberExpr(offset)); + SQLBinaryOpExpr lteq = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // + SQLBinaryOperator.LessThanOrEqual, // + new SQLNumberExpr(count + offset)); + SQLBinaryOpExpr pageCondition = new SQLBinaryOpExpr(gt, SQLBinaryOperator.BooleanAnd, lteq); + + countQueryBlock.setWhere(pageCondition); + + return SQLUtils.toSQLString(countQueryBlock, dbType); + } + + return SQLUtils.toSQLString(select, dbType); + } + + private static String limitOracle(SQLSelect select, String dbType, int offset, int count) { + SQLSelectQuery query = select.getQuery(); + + if (query instanceof SQLSelectQueryBlock) { + OracleSelectQueryBlock queryBlock = (OracleSelectQueryBlock) query; + if (queryBlock.getGroupBy() == null && select.getOrderBy() == null && offset <= 0) { + SQLExpr condition = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // + SQLBinaryOperator.LessThanOrEqual, // + new SQLNumberExpr(count)); + if (queryBlock.getWhere() == null) { + queryBlock.setWhere(condition); + } else { + queryBlock.setWhere(new SQLBinaryOpExpr(queryBlock.getWhere(), // + SQLBinaryOperator.BooleanAnd, // + condition)); + } + + return SQLUtils.toSQLString(select, dbType); + } + } + + OracleSelectQueryBlock countQueryBlock = new OracleSelectQueryBlock(); + countQueryBlock.getSelectList().add(new SQLSelectItem(new SQLPropertyExpr(new SQLIdentifierExpr("XX"), "*"))); + countQueryBlock.getSelectList().add(new SQLSelectItem(new SQLIdentifierExpr("ROWNUM"), "RN")); + + countQueryBlock.setFrom(new SQLSubqueryTableSource(select, "XX")); + countQueryBlock.setWhere(new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // + SQLBinaryOperator.LessThanOrEqual, // + new SQLNumberExpr(count + offset))); + if (offset <= 0) { + return SQLUtils.toSQLString(countQueryBlock, dbType); + } + + OracleSelectQueryBlock offsetQueryBlock = new OracleSelectQueryBlock(); + offsetQueryBlock.getSelectList().add(new SQLSelectItem(new SQLAllColumnExpr())); + offsetQueryBlock.setFrom(new SQLSubqueryTableSource(new SQLSelect(countQueryBlock), "XXX")); + offsetQueryBlock.setWhere(new SQLBinaryOpExpr(new SQLIdentifierExpr("RN"), // + SQLBinaryOperator.GreaterThan, // + new SQLNumberExpr(offset))); + + return SQLUtils.toSQLString(offsetQueryBlock, dbType); + } + + private static String limitMySqlQueryBlock(MySqlSelectQueryBlock queryBlock, String dbType, int offset, int count) { + if (queryBlock.getLimit() != null) { + throw new IllegalArgumentException("limit already exists."); + } + + Limit limit = new Limit(); + if (offset > 0) { + limit.setOffset(new SQLNumberExpr(offset)); + } + limit.setRowCount(new SQLNumberExpr(count)); + queryBlock.setLimit(limit); + + return SQLUtils.toSQLString(queryBlock, dbType); + } + + private static String count(SQLSelect select, String dbType) { + if (select.getOrderBy() != null) { + select.setOrderBy(null); + } + + SQLSelectQuery query = select.getQuery(); + clearOrderBy(query); + + if (query instanceof SQLSelectQueryBlock) { + SQLSelectItem countItem = createCountItem(dbType); + + SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query; + + if (queryBlock.getGroupBy() != null && queryBlock.getGroupBy().getItems().size() > 0) { + return createCountUseSubQuery(select, dbType); + } + + queryBlock.getSelectList().clear(); + queryBlock.getSelectList().add(countItem); + return SQLUtils.toSQLString(select, dbType); + } else if (query instanceof SQLUnionQuery) { + return createCountUseSubQuery(select, dbType); + } + + throw new IllegalStateException(); + } + + private static String createCountUseSubQuery(SQLSelect select, String dbType) { + SQLSelectQueryBlock countSelectQuery = createQueryBlock(dbType); + + SQLSelectItem countItem = createCountItem(dbType); + countSelectQuery.getSelectList().add(countItem); + + countSelectQuery.setFrom(new SQLSubqueryTableSource(select)); + + SQLSelect countSelect = new SQLSelect(countSelectQuery); + SQLSelectStatement countStmt = new SQLSelectStatement(countSelect); + + return SQLUtils.toSQLString(countStmt, dbType); + } + + private static SQLSelectQueryBlock createQueryBlock(String dbType) { + if (JdbcConstants.MYSQL.equals(dbType)) { + return new MySqlSelectQueryBlock(); + } + + if (JdbcConstants.MARIADB.equals(dbType)) { + return new MySqlSelectQueryBlock(); + } + + if (JdbcConstants.H2.equals(dbType)) { + return new MySqlSelectQueryBlock(); + } + + if (JdbcConstants.ORACLE.equals(dbType)) { + return new OracleSelectQueryBlock(); + } + + if (JdbcConstants.POSTGRESQL.equals(dbType)) { + return new PGSelectQueryBlock(); + } + + if (JdbcConstants.SQL_SERVER.equals(dbType)) { + return new SQLServerSelectQueryBlock(); + } + + if (JdbcConstants.DB2.equals(dbType)) { + return new DB2SelectQueryBlock(); + } + + return new SQLSelectQueryBlock(); + } + + private static SQLSelectItem createCountItem(String dbType) { + SQLAggregateExpr countExpr; + + if (JdbcConstants.ORACLE.equals(dbType)) { + countExpr = new OracleAggregateExpr("COUNT"); + } else { + countExpr = new SQLAggregateExpr("COUNT"); + } + countExpr.getArguments().add(new SQLAllColumnExpr()); + + SQLSelectItem countItem = new SQLSelectItem(countExpr); + return countItem; + } + + private static void clearOrderBy(SQLSelectQuery query) { + if (query instanceof SQLSelectQueryBlock) { + SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query; + if (queryBlock instanceof MySqlSelectQueryBlock) { + MySqlSelectQueryBlock mysqlQueryBlock = (MySqlSelectQueryBlock) queryBlock; + if (mysqlQueryBlock.getOrderBy() != null) { + mysqlQueryBlock.setOrderBy(null); + } + } else if (queryBlock instanceof PGSelectQueryBlock) { + PGSelectQueryBlock pgQueryBlock = (PGSelectQueryBlock) queryBlock; + if (pgQueryBlock.getOrderBy() != null) { + pgQueryBlock.setOrderBy(null); + } + } + return; + } + + if (query instanceof SQLUnionQuery) { + SQLUnionQuery union = (SQLUnionQuery) query; + if (union.getOrderBy() != null) { + union.setOrderBy(null); + } + clearOrderBy(union.getLeft()); + clearOrderBy(union.getRight()); + } + } +} From 0d7ff82c7b52f10dc0ad31565b67c8821892f0fa Mon Sep 17 00:00:00 2001 From: melin Date: Fri, 26 Jul 2013 17:15:37 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=AD=A3db2=20limit=E8=AF=AD?= =?UTF-8?q?=E5=8F=A5=20bug=20#401?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/alibaba/druid/sql/PagerUtils.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/alibaba/druid/sql/PagerUtils.java b/src/main/java/com/alibaba/druid/sql/PagerUtils.java index f2b313a9b6..89e429c4b8 100644 --- a/src/main/java/com/alibaba/druid/sql/PagerUtils.java +++ b/src/main/java/com/alibaba/druid/sql/PagerUtils.java @@ -127,10 +127,8 @@ public class PagerUtils { SQLAggregateExpr aggregateExpr = new SQLAggregateExpr("ROW_NUMBER"); SQLOrderBy orderBy = select.getOrderBy(); - if (orderBy != null) { - aggregateExpr.setOver(new SQLOver(orderBy)); - select.setOrderBy(null); - } + aggregateExpr.setOver(new SQLOver(orderBy)); + select.setOrderBy(null); queryBlock.getSelectList().add(new SQLSelectItem(aggregateExpr, "ROWNUM"));