diff --git a/src/main/java/com/alibaba/druid/sql/PagerUtils.java b/src/main/java/com/alibaba/druid/sql/PagerUtils.java index 9e53e1a601..c651acb5fc 100644 --- a/src/main/java/com/alibaba/druid/sql/PagerUtils.java +++ b/src/main/java/com/alibaba/druid/sql/PagerUtils.java @@ -444,7 +444,9 @@ public class PagerUtils { } private static SQLSelectQueryBlock createQueryBlock(String dbType) { - if (JdbcConstants.MYSQL.equals(dbType)) { + if (JdbcConstants.MYSQL.equals(dbType) + || JdbcConstants.MARIADB.equals(dbType) + || JdbcConstants.ALIYUN_ADS.equals(dbType)) { return new MySqlSelectQueryBlock(); } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLMethodInvokeExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLMethodInvokeExpr.java index d85cc54dd9..995a63c371 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLMethodInvokeExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLMethodInvokeExpr.java @@ -48,6 +48,14 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable, setOwner(owner); } + public SQLMethodInvokeExpr(String methodName, SQLExpr owner, SQLExpr... params){ + this.methodName = methodName; + setOwner(owner); + for (SQLExpr param : params) { + this.addParameter(param); + } + } + public String getMethodName() { return this.methodName; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCharacterDataType.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCharacterDataType.java index 9a2861221d..f6e0ee0c34 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCharacterDataType.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCharacterDataType.java @@ -15,6 +15,7 @@ */ package com.alibaba.druid.sql.ast.statement; +import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLCommentHint; import com.alibaba.druid.sql.ast.SQLDataTypeImpl; import com.alibaba.druid.sql.ast.SQLExpr; @@ -99,4 +100,9 @@ public class SQLCharacterDataType extends SQLDataTypeImpl { visitor.endVisit(this); } + + @Override + public String toString() { + return SQLUtils.toSQLString(this); + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLColumnDefinition.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLColumnDefinition.java index 33f6f6fd9c..172bc35b1e 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLColumnDefinition.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLColumnDefinition.java @@ -103,6 +103,9 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen } public void setDataType(SQLDataType dataType) { + if (dataType != null) { + dataType.setParent(this); + } this.dataType = dataType; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java index c1f13e5900..0465978be0 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java @@ -227,4 +227,14 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS } } } + + public SQLPrimaryKey findPrimaryKey() { + for (SQLTableElement element : this.tableElementList) { + if (element instanceof SQLPrimaryKey) { + return (SQLPrimaryKey) element; + } + } + + return null; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java index 1531b249d2..66dda452c6 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java @@ -22,6 +22,7 @@ import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.*; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery, SQLReplaceable { @@ -89,6 +90,18 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery } this.where = where; } + + public void addWhere(SQLExpr condition) { + if (condition == null) { + return; + } + + if (where == null) { + where = condition; + } else { + where = SQLBinaryOpExpr.and(where, condition); + } + } public SQLOrderBy getOrderBy() { return orderBy; @@ -448,4 +461,14 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery this.setWhere(SQLBinaryOpExpr.and(where, expr)); } + + public void limit(int rowCount, int offset) { + SQLLimit limit = new SQLLimit(); + limit.setRowCount(new SQLIntegerExpr(rowCount)); + if (offset > 0) { + limit.setOffset(new SQLIntegerExpr(offset)); + } + + setLimit(limit); + } } diff --git a/src/main/java/com/alibaba/druid/sql/builder/FunctionBuilder.java b/src/main/java/com/alibaba/druid/sql/builder/FunctionBuilder.java new file mode 100644 index 0000000000..5c17276dc6 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/builder/FunctionBuilder.java @@ -0,0 +1,78 @@ +/* + * Copyright 1999-2017 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.builder; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; +import com.alibaba.druid.util.JdbcConstants; + +/** + * Created by wenshao on 09/07/2017. + */ +public class FunctionBuilder { + private final String dbType; + + public FunctionBuilder(String dbType) { + this.dbType = dbType; + } + + // for character function + public SQLMethodInvokeExpr length(SQLExpr expr) { + return new SQLMethodInvokeExpr("length", null, expr); + } + + public SQLMethodInvokeExpr lower(SQLExpr expr) { + return new SQLMethodInvokeExpr("lower", null, expr); + } + + public SQLMethodInvokeExpr upper(SQLExpr expr) { + return new SQLMethodInvokeExpr("upper", null, expr); + } + + public SQLMethodInvokeExpr substr(SQLExpr expr) { + return new SQLMethodInvokeExpr("substr", null, expr); + } + + public SQLMethodInvokeExpr ltrim(SQLExpr expr) { + return new SQLMethodInvokeExpr("ltrim", null, expr); + } + + public SQLMethodInvokeExpr rtrim(SQLExpr expr) { + return new SQLMethodInvokeExpr("rtrim", null, expr); + } + + public SQLMethodInvokeExpr trim(SQLExpr expr) { + return new SQLMethodInvokeExpr("trim", null, expr); + } + + public SQLMethodInvokeExpr ifnull(SQLExpr expr1, SQLExpr expr2) { + if (JdbcConstants.ALIYUN_ADS.equals(dbType) + || JdbcConstants.PRESTO.equals(dbType) + || JdbcConstants.ODPS.equals(dbType)) { + return new SQLMethodInvokeExpr("coalesce", null, expr1, expr2); + } + + if (JdbcConstants.ORACLE.equals(dbType)) { + return new SQLMethodInvokeExpr("nvl", null, expr1, expr2); + } + + if (JdbcConstants.SQL_SERVER.equals(dbType)) { + return new SQLMethodInvokeExpr("isnull", null, expr1, expr2); + } + + return new SQLMethodInvokeExpr("ifnull", null, expr1, expr2); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/builder/impl/SQLSelectBuilderImpl.java b/src/main/java/com/alibaba/druid/sql/builder/impl/SQLSelectBuilderImpl.java index 3a09568ff6..014c20a3a0 100644 --- a/src/main/java/com/alibaba/druid/sql/builder/impl/SQLSelectBuilderImpl.java +++ b/src/main/java/com/alibaba/druid/sql/builder/impl/SQLSelectBuilderImpl.java @@ -194,11 +194,7 @@ public class SQLSelectBuilderImpl implements SQLSelectBuilder { @Override public SQLSelectBuilderImpl whereAnd(String expr) { SQLSelectQueryBlock queryBlock = getQueryBlock(); - - SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType); - SQLExpr newCondition = SQLUtils.buildCondition(SQLBinaryOperator.BooleanAnd, exprObj, false, - queryBlock.getWhere()); - queryBlock.setWhere(newCondition); + queryBlock.addWhere(SQLUtils.toSQLExpr(expr, dbType)); return this; } @@ -222,86 +218,9 @@ public class SQLSelectBuilderImpl implements SQLSelectBuilder { @Override public SQLSelectBuilderImpl limit(int rowCount, int offset) { - SQLSelectQueryBlock queryBlock = getQueryBlock(); - - if (queryBlock instanceof MySqlSelectQueryBlock) { - MySqlSelectQueryBlock mySqlQueryBlock = (MySqlSelectQueryBlock) queryBlock; - - SQLLimit limit = new SQLLimit(); - limit.setRowCount(new SQLIntegerExpr(rowCount)); - if (offset > 0) { - limit.setOffset(new SQLIntegerExpr(offset)); - } - - mySqlQueryBlock.setLimit(limit); - - return this; - } - - if (queryBlock instanceof SQLServerSelectQueryBlock) { - SQLServerSelectQueryBlock sqlserverQueryBlock = (SQLServerSelectQueryBlock) queryBlock; - if (offset <= 0) { - SQLServerTop top = new SQLServerTop(); - top.setExpr(new SQLIntegerExpr(rowCount)); - sqlserverQueryBlock.setTop(top); - } else { - throw new UnsupportedOperationException("not support offset"); - } - - return this; - } - - if (queryBlock instanceof PGSelectQueryBlock) { - PGSelectQueryBlock pgQueryBlock = (PGSelectQueryBlock) queryBlock; - SQLLimit limit = new SQLLimit(); - if (offset > 0) { - limit.setOffset(new SQLIntegerExpr(offset)); - } - limit.setRowCount(new SQLIntegerExpr(rowCount)); - pgQueryBlock.setLimit(limit); - - return this; - } - - if (queryBlock instanceof DB2SelectQueryBlock) { - DB2SelectQueryBlock db2QueryBlock = (DB2SelectQueryBlock) queryBlock; - if (offset <= 0) { - SQLExpr rowCountExpr = new SQLIntegerExpr(rowCount); - db2QueryBlock.setFirst(rowCountExpr); - } else { - throw new UnsupportedOperationException("not support offset"); - } - - return this; - } - - if (queryBlock instanceof OracleSelectQueryBlock) { - OracleSelectQueryBlock oracleQueryBlock = (OracleSelectQueryBlock) queryBlock; - if (offset <= 0) { - SQLExpr rowCountExpr = new SQLIntegerExpr(rowCount); - SQLExpr newCondition = SQLUtils.buildCondition(SQLBinaryOperator.BooleanAnd, rowCountExpr, false, - oracleQueryBlock.getWhere()); - queryBlock.setWhere(newCondition); - } else { - throw new UnsupportedOperationException("not support offset"); - } - - return this; - } - - if (queryBlock instanceof OdpsSelectQueryBlock) { - OdpsSelectQueryBlock odpsQueryBlock = (OdpsSelectQueryBlock) queryBlock; - - if (offset > 0) { - throw new UnsupportedOperationException("not support offset"); - } - - odpsQueryBlock.setLimit(new SQLLimit(new SQLIntegerExpr(rowCount))); - - return this; - } - - throw new UnsupportedOperationException(); + getQueryBlock() + .limit(rowCount, offset); + return this; } protected SQLSelectQueryBlock getQueryBlock() { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2SelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2SelectQueryBlock.java index 8540fb74a6..3c355033a8 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2SelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2SelectQueryBlock.java @@ -16,6 +16,7 @@ package com.alibaba.druid.sql.dialect.db2.ast.stmt; import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.dialect.db2.ast.DB2Object; import com.alibaba.druid.sql.dialect.db2.visitor.DB2ASTVisitor; @@ -80,4 +81,12 @@ public class DB2SelectQueryBlock extends SQLSelectQueryBlock implements DB2Objec public static enum Isolation { RR, RS, CS, UR } + + public void limit(int rowCount, int offset) { + if (offset <= 0) { + setFirst(new SQLIntegerExpr(rowCount)); + } else { + throw new UnsupportedOperationException("not support offset"); + } + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index 65c74b48a8..b80af123f6 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -328,9 +328,10 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV dataType.accept(this); } - if (x.getCharsetExpr() != null) { + final SQLExpr charsetExpr = x.getCharsetExpr(); + if (charsetExpr != null) { print0(ucase ? " CHARSET " : " charset "); - x.getCharsetExpr().accept(this); + charsetExpr.accept(this); } for (SQLColumnConstraint item : x.getConstraints()) { @@ -338,20 +339,23 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV item.accept(this); } - if (x.getDefaultExpr() != null) { + final SQLExpr defaultExpr = x.getDefaultExpr(); + if (defaultExpr != null) { print0(ucase ? " DEFAULT " : " default "); - x.getDefaultExpr().accept(this); + defaultExpr.accept(this); } - if (x.getStorage() != null) { + final SQLExpr storage = x.getStorage(); + if (storage != null) { print0(ucase ? " STORAGE " : " storage "); - x.getStorage().accept(this); + storage.accept(this); } - if (x.getOnUpdate() != null) { + SQLExpr onUpdate = x.getOnUpdate(); + if (onUpdate != null) { print0(ucase ? " ON UPDATE " : " on update "); - x.getOnUpdate().accept(this); + onUpdate.accept(this); } if (x.isAutoIncrement()) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsSelectQueryBlock.java index 67909aaa59..a8c7bffbb0 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsSelectQueryBlock.java @@ -21,7 +21,9 @@ import java.util.List; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLHint; +import com.alibaba.druid.sql.ast.SQLLimit; import com.alibaba.druid.sql.ast.SQLOrderBy; +import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor; @@ -122,4 +124,12 @@ public class OdpsSelectQueryBlock extends SQLSelectQueryBlock { public String toString() { return SQLUtils.toOdpsString(this); } + + public void limit(int rowCount, int offset) { + if (offset > 0) { + throw new UnsupportedOperationException("not support offset"); + } + + setLimit(new SQLLimit(new SQLIntegerExpr(rowCount))); + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectQueryBlock.java index aea0b58b7b..1d263b64c6 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectQueryBlock.java @@ -21,6 +21,9 @@ import java.util.List; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLCommentHint; import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLLimit; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; +import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; @@ -147,4 +150,15 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock { public String toString() { return SQLUtils.toOracleString(this); } + + public void limit(int rowCount, int offset) { + if (offset <= 0) { + SQLExpr rowCountExpr = new SQLIntegerExpr(rowCount); + SQLExpr newCondition = SQLUtils.buildCondition(SQLBinaryOperator.BooleanAnd, rowCountExpr, false, + where); + setWhere(newCondition); + } else { + throw new UnsupportedOperationException("not support offset"); + } + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/SQLServerSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/SQLServerSelectQueryBlock.java index 1bcf600750..b4b8ecbcb1 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/SQLServerSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/SQLServerSelectQueryBlock.java @@ -15,6 +15,8 @@ */ package com.alibaba.druid.sql.dialect.sqlserver.ast; +import com.alibaba.druid.sql.ast.SQLLimit; +import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; @@ -34,6 +36,10 @@ public class SQLServerSelectQueryBlock extends SQLSelectQueryBlock { this.top = top; } + public void setTop(int rowCount) { + setTop(new SQLServerTop(new SQLIntegerExpr(rowCount))); + } + @Override protected void accept0(SQLASTVisitor visitor) { accept0((SQLServerASTVisitor) visitor); @@ -49,4 +55,12 @@ public class SQLServerSelectQueryBlock extends SQLSelectQueryBlock { } visitor.endVisit(this); } + + public void limit(int rowCount, int offset) { + if (offset <= 0) { + setTop(rowCount); + } else { + throw new UnsupportedOperationException("not support offset"); + } + } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java index 930d1b4740..869f77cdc4 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -343,6 +343,16 @@ public class Lexer { } if (isFirstIdentifierChar(ch)) { + if (ch == '(') { + scanChar(); + token = LPAREN; + return; + } else if (ch == ')') { + scanChar(); + token = RPAREN; + return; + } + if (ch == 'N') { if (charAt(pos + 1) == '\'') { ++pos; diff --git a/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java b/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java index e4b0150e8c..85ed6428ee 100644 --- a/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java +++ b/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java @@ -110,7 +110,11 @@ public class SchemaRepository { String name = x.computeName(); SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Table, x); - objects.put(name.toLowerCase(), object); + String name_lower = name.toLowerCase(); + if (objects.containsKey(name_lower)) { + return false; + } + objects.put(name_lower, object); return false; } diff --git a/src/main/java/com/alibaba/druid/util/JdbcConstants.java b/src/main/java/com/alibaba/druid/util/JdbcConstants.java index 2325fc5e03..414297028e 100644 --- a/src/main/java/com/alibaba/druid/util/JdbcConstants.java +++ b/src/main/java/com/alibaba/druid/util/JdbcConstants.java @@ -99,4 +99,9 @@ public interface JdbcConstants { public static final String SQLITE = "sqlite"; public static final String SQLITE_DRIVER = "org.sqlite.JDBC"; + + public static final String ALIYUN_ADS = "aliyun_ads"; + public static final String ALIYUN_DRDS = "aliyun_drds"; + + public static final String PRESTO = "presto"; } diff --git a/src/test/java/com/alibaba/druid/bvt/ApacheDBUtilsTest.java b/src/test/java/com/alibaba/druid/bvt/ApacheDBUtilsTest.java new file mode 100644 index 0000000000..7f8e6d5d37 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/ApacheDBUtilsTest.java @@ -0,0 +1,78 @@ +package com.alibaba.druid.bvt; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.util.JdbcUtils; +import junit.framework.TestCase; +import org.apache.commons.dbutils.DbUtils; +import org.apache.commons.dbutils.QueryRunner; +import org.apache.commons.dbutils.handlers.MapHandler; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; + +/** + * Created by wenshao on 06/07/2017. + */ +public class ApacheDBUtilsTest extends TestCase { + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mysql://rm-bp1n325y4m6h78xt3.mysql.rds.aliyuncs.com:3306/oracle_info?allowMultiQueries=true&characterEncoding=UTF8"); + dataSource.setUsername("user1"); + dataSource.setPassword("ADAM2d3fb107bcda629fc"); + +// druid.url=jdbc:mysql://rm-bp1n325y4m6h78xt3.mysql.rds.aliyuncs.com:3306/oracle_info?allowMultiQueries=true&characterEncoding=UTF8 +// druid.username=user1 +// druid.password=ADAM2d3fb107bcda629fc + } + + public void test_txn() throws Exception { + Connection conn = dataSource.getConnection(); + Connection conn3 = dataSource.getConnection(); + + System.out.println("1:" + conn); + QueryRunner runner = new QueryRunner(); + String sql = "select task_ida from worker limit 1"; + try { + runner.query(conn, sql, new MapHandler()); + //Long count = new PgCopy().pipeline(conn, sql, conn3, "worker_0607", "task_id"); + } catch (Exception e) { + e.printStackTrace(); + //DbUtils.closeQuietly(conn);//直接关闭close + DbUtils.rollbackAndCloseQuietly(conn); + DbUtils.commitAndCloseQuietly(conn); + } + + + //会抛sql.SQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block Query: + try { + Connection conn1 = dataSource.getConnection(); +// conn1.setAutoCommit(true); + System.out.println("2:" + conn1); + String sql1 = "select * from worker limit 1"; + QueryRunner runner1 = new QueryRunner(); + runner1.query(conn1, sql1, new MapHandler()); + } catch (Exception e) { + e.printStackTrace(); + } + + + + //恢复正常 + try { + Connection conn1 = dataSource.getConnection(); + System.out.println("3:" + conn1); + String sql1 = "select * from worker limit 2"; + QueryRunner runner1 = new QueryRunner(); + runner1.query(conn1, sql1, new MapHandler()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + protected void tearDown() throws Exception { + JdbcUtils.close(dataSource); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest67.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest67.java new file mode 100644 index 0000000000..efc1a284a1 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest67.java @@ -0,0 +1,85 @@ +/* + * Copyright 1999-2017 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.select; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; +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 org.junit.Assert; + +import java.util.List; + +public class OracleSelectTest67 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "SELECT NVL(B.KYSLRQ, A.HZDJRQ) HZDJRQ FROM DJ_NSRXX A" + + ", (SELECT B.NSRDZDAH, MIN(B.KYSLRQ) KYSLRQ FROM DJ_PZJGXX B WHERE B.NSRDZDAH = :B1 GROUP BY B.NSRDZDAH) B WHERE A.NSRDZDAH = :B1 AND A.NSRDZDAH = B.NSRDZDAH(+)"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.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()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertEquals(4, visitor.getColumns().size()); + + { + String text = SQLUtils.toOracleString(stmt); + + assertEquals("SELECT NVL(B.KYSLRQ, A.HZDJRQ) AS HZDJRQ\n" + + "FROM DJ_NSRXX A, (\n" + + "\tSELECT B.NSRDZDAH, MIN(B.KYSLRQ) AS KYSLRQ\n" + + "\tFROM DJ_PZJGXX B\n" + + "\tWHERE B.NSRDZDAH = :B1\n" + + "\tGROUP BY B.NSRDZDAH\n" + + ") B\n" + + "WHERE A.NSRDZDAH = :B1\n" + + "\tAND A.NSRDZDAH = B.NSRDZDAH(+)", text); + } + + { + String text = SQLUtils.toOracleString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); + + Assert.assertEquals("select NVL(B.KYSLRQ, A.HZDJRQ) as HZDJRQ\n" + + "from DJ_NSRXX A, (\n" + + "\tselect B.NSRDZDAH, min(B.KYSLRQ) as KYSLRQ\n" + + "\tfrom DJ_PZJGXX B\n" + + "\twhere B.NSRDZDAH = :B1\n" + + "\tgroup by B.NSRDZDAH\n" + + ") B\n" + + "where A.NSRDZDAH = :B1\n" + + "\tand A.NSRDZDAH = B.NSRDZDAH(+)", text); + } + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("acduser.vw_acd_info", "xzqh"))); + + // Assert.assertTrue(visitor.getOrderByColumns().contains(new TableStat.Column("employees", "last_name"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest68.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest68.java new file mode 100644 index 0000000000..69f7d3fca0 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest68.java @@ -0,0 +1,162 @@ +/* + * Copyright 1999-2017 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.select; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; +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 org.junit.Assert; + +import java.util.List; + +public class OracleSelectTest68 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "INSERT INTO SB_ZZS_LDSK_2016 SELECT DJXH, :B1 , NVL(SUM(CASE WHEN ZZSLX = '2' AND LDLX = '1' THEN LDSE END), 0) SQLDSE_BQ, NVL(SUM(CASE WHEN ZZSLX = '1' AND LDLX = '1' THEN LDSE END), 0) SQLDSE_LJ, NVL(SUM(CASE WHEN LDLX = '2' THEN LDSE END), 0) SQLDSE_JZ, 0, 0, 0,SYSDATE FROM (SELECT ZZSLX, LDLX, DJXH, SUM(BCLDBHS) LDSE FROM (SELECT ZZSLX, LDLX, DJXH, SUM(T.BCLDBHS) BCLDBHS FROM HX_SB.SB_ZZS_LDSKLSZ@JSCX T WHERE T.SKSSQZ < ADD_MONTHS(:B1 ,-1)+1 AND DJXH IN (SELECT NSRDZDAH FROM DJ_NSRXX_JS_GZSB) AND T.CZLX_DM IN ('10', '66', '68', '53', '56', '61', '64') GROUP BY ZZSLX, LDLX, DJXH UNION ALL SELECT ZZSLX, LDLX, DJXH, -SUM(T.BCLDBHS) BCLDBHS FROM HX_SB.SB_ZZS_LDSKLSZ@JSCX T WHERE T.SKSSQZ = ADD_MONTHS(:B1 ,-1) AND DJXH IN (SELECT NSRDZDAH FROM DJ_NSRXX_JS_GZSB) AND T.CZLX_DM IN ('53', '56', '61', '64') GROUP BY ZZSLX, LDLX, DJXH) GROUP BY ZZSLX, LDLX, DJXH) A GROUP BY DJXH"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.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()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(3, visitor.getTables().size()); + + Assert.assertEquals(10, visitor.getColumns().size()); + + { + String text = SQLUtils.toOracleString(stmt); + + assertEquals("INSERT INTO SB_ZZS_LDSK_2016\n" + + "SELECT DJXH, :B1\n" + + "\t, NVL(SUM(CASE \n" + + "\t\tWHEN ZZSLX = '2'\n" + + "\t\tAND LDLX = '1' THEN LDSE\n" + + "\tEND), 0) AS SQLDSE_BQ\n" + + "\t, NVL(SUM(CASE \n" + + "\t\tWHEN ZZSLX = '1'\n" + + "\t\tAND LDLX = '1' THEN LDSE\n" + + "\tEND), 0) AS SQLDSE_LJ\n" + + "\t, NVL(SUM(CASE \n" + + "\t\tWHEN LDLX = '2' THEN LDSE\n" + + "\tEND), 0) AS SQLDSE_JZ\n" + + "\t, 0, 0, 0, SYSDATE\n" + + "FROM (\n" + + "\tSELECT ZZSLX, LDLX, DJXH, SUM(BCLDBHS) AS LDSE\n" + + "\tFROM (\n" + + "\t\tSELECT ZZSLX, LDLX, DJXH, SUM(T.BCLDBHS) AS BCLDBHS\n" + + "\t\tFROM HX_SB.SB_ZZS_LDSKLSZ@JSCX T\n" + + "\t\tWHERE T.SKSSQZ < ADD_MONTHS(:B1, -1) + 1\n" + + "\t\t\tAND DJXH IN (\n" + + "\t\t\t\tSELECT NSRDZDAH\n" + + "\t\t\t\tFROM DJ_NSRXX_JS_GZSB\n" + + "\t\t\t)\n" + + "\t\t\tAND T.CZLX_DM IN (\n" + + "\t\t\t\t'10', \n" + + "\t\t\t\t'66', \n" + + "\t\t\t\t'68', \n" + + "\t\t\t\t'53', \n" + + "\t\t\t\t'56', \n" + + "\t\t\t\t'61', \n" + + "\t\t\t\t'64'\n" + + "\t\t\t)\n" + + "\t\tGROUP BY ZZSLX, LDLX, DJXH\n" + + "\t\tUNION ALL\n" + + "\t\tSELECT ZZSLX, LDLX, DJXH, -SUM(T.BCLDBHS) AS BCLDBHS\n" + + "\t\tFROM HX_SB.SB_ZZS_LDSKLSZ@JSCX T\n" + + "\t\tWHERE T.SKSSQZ = ADD_MONTHS(:B1, -1)\n" + + "\t\t\tAND DJXH IN (\n" + + "\t\t\t\tSELECT NSRDZDAH\n" + + "\t\t\t\tFROM DJ_NSRXX_JS_GZSB\n" + + "\t\t\t)\n" + + "\t\t\tAND T.CZLX_DM IN ('53', '56', '61', '64')\n" + + "\t\tGROUP BY ZZSLX, LDLX, DJXH\n" + + "\t)\n" + + "\tGROUP BY ZZSLX, LDLX, DJXH\n" + + ") A\n" + + "GROUP BY DJXH", text); + } + + { + String text = SQLUtils.toOracleString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); + + Assert.assertEquals("insert into SB_ZZS_LDSK_2016\n" + + "select DJXH, :B1\n" + + "\t, NVL(sum(case \n" + + "\t\twhen ZZSLX = '2'\n" + + "\t\tand LDLX = '1' then LDSE\n" + + "\tend), 0) as SQLDSE_BQ\n" + + "\t, NVL(sum(case \n" + + "\t\twhen ZZSLX = '1'\n" + + "\t\tand LDLX = '1' then LDSE\n" + + "\tend), 0) as SQLDSE_LJ\n" + + "\t, NVL(sum(case \n" + + "\t\twhen LDLX = '2' then LDSE\n" + + "\tend), 0) as SQLDSE_JZ\n" + + "\t, 0, 0, 0, sysdate\n" + + "from (\n" + + "\tselect ZZSLX, LDLX, DJXH, sum(BCLDBHS) as LDSE\n" + + "\tfrom (\n" + + "\t\tselect ZZSLX, LDLX, DJXH, sum(T.BCLDBHS) as BCLDBHS\n" + + "\t\tfrom HX_SB.SB_ZZS_LDSKLSZ@JSCX T\n" + + "\t\twhere T.SKSSQZ < ADD_MONTHS(:B1, -1) + 1\n" + + "\t\t\tand DJXH in (\n" + + "\t\t\t\tselect NSRDZDAH\n" + + "\t\t\t\tfrom DJ_NSRXX_JS_GZSB\n" + + "\t\t\t)\n" + + "\t\t\tand T.CZLX_DM in (\n" + + "\t\t\t\t'10', \n" + + "\t\t\t\t'66', \n" + + "\t\t\t\t'68', \n" + + "\t\t\t\t'53', \n" + + "\t\t\t\t'56', \n" + + "\t\t\t\t'61', \n" + + "\t\t\t\t'64'\n" + + "\t\t\t)\n" + + "\t\tgroup by ZZSLX, LDLX, DJXH\n" + + "\t\tunion all\n" + + "\t\tselect ZZSLX, LDLX, DJXH, -sum(T.BCLDBHS) as BCLDBHS\n" + + "\t\tfrom HX_SB.SB_ZZS_LDSKLSZ@JSCX T\n" + + "\t\twhere T.SKSSQZ = ADD_MONTHS(:B1, -1)\n" + + "\t\t\tand DJXH in (\n" + + "\t\t\t\tselect NSRDZDAH\n" + + "\t\t\t\tfrom DJ_NSRXX_JS_GZSB\n" + + "\t\t\t)\n" + + "\t\t\tand T.CZLX_DM in ('53', '56', '61', '64')\n" + + "\t\tgroup by ZZSLX, LDLX, DJXH\n" + + "\t)\n" + + "\tgroup by ZZSLX, LDLX, DJXH\n" + + ") A\n" + + "group by DJXH", text); + } + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("acduser.vw_acd_info", "xzqh"))); + + // Assert.assertTrue(visitor.getOrderByColumns().contains(new TableStat.Column("employees", "last_name"))); + } +} diff --git a/src/test/java/com/alibaba/druid/sql/calcite/CalciteTest.java b/src/test/java/com/alibaba/druid/sql/calcite/CalciteTest.java new file mode 100644 index 0000000000..241830731c --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/calcite/CalciteTest.java @@ -0,0 +1,25 @@ +package com.alibaba.druid.sql.calcite; + +import junit.framework.TestCase; +import org.apache.calcite.plan.RelOptUtil; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.tools.FrameworkConfig; +import org.apache.calcite.tools.Frameworks; +import org.apache.calcite.tools.RelBuilder; + +/** + * Created by wenshao on 03/07/2017. + */ +public class CalciteTest extends TestCase { + public void test_calcite() throws Exception { + final FrameworkConfig config = Frameworks + .newConfigBuilder() + .build(); + final RelBuilder builder = RelBuilder.create(config); + final RelNode node = builder + .scan("EMP") + .build(); + System.out.println(RelOptUtil.toString(node)); + + } +}