From 2f6e406e33f19ff0142d8cc2231fe09f63f495da Mon Sep 17 00:00:00 2001 From: wenshao Date: Wed, 28 Jun 2017 15:34:43 +0800 Subject: [PATCH] improved sql parser. --- .../druid/sql/ast/expr/SQLBinaryOpExpr.java | 10 ++ .../druid/sql/ast/expr/SQLQueryExpr.java | 10 ++ .../dialect/db2/visitor/DB2OutputVisitor.java | 3 - .../oracle/parser/OracleStatementParser.java | 2 +- .../oracle/visitor/OracleOutputVisitor.java | 7 +- .../druid/sql/parser/SQLExprParser.java | 4 + .../druid/sql/parser/SQLStatementParser.java | 9 ++ .../sql/visitor/SQLASTOutputVisitor.java | 25 ++- .../MySqlCreateTableTest78_json.java | 54 +++++++ .../select/MySqlSelectTest_42_with_cte.java | 105 +++++++++++++ .../select/MySqlSelectTest_43_with_cte.java | 105 +++++++++++++ .../select/MySqlSelectTest_44_with_cte.java | 98 ++++++++++++ ...SelectTest_45_subquery_scalar_operand.java | 80 ++++++++++ .../druid/bvt/sql/odps/OdpsSelectTest22.java | 147 ++++++++++++++++++ .../druid/bvt/sql/odps/OdpsSelectTest23.java | 68 ++++++++ .../sql/oracle/block/OracleBlockTest21.java | 82 ++++++++++ .../block/OracleBlockTest22_comment.java | 81 ++++++++++ .../oracle/create/OracleCreateViewTest1.java | 4 +- .../insert/OracleInsertTest20_first.java | 91 +++++++++++ 19 files changed, 971 insertions(+), 14 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/createTable/MySqlCreateTableTest78_json.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_42_with_cte.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_43_with_cte.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_44_with_cte.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_45_subquery_scalar_operand.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest22.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest23.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/block/OracleBlockTest21.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/block/OracleBlockTest22_comment.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/insert/OracleInsertTest20_first.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOpExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOpExpr.java index 947daf2785..85ee174eee 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOpExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOpExpr.java @@ -35,6 +35,8 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements SQLReplaceable, Seri private SQLBinaryOperator operator; private String dbType; + private boolean bracket = false; + public SQLBinaryOpExpr(){ } @@ -99,6 +101,14 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements SQLReplaceable, Seri this.operator = operator; } + public boolean isBracket() { + return bracket; + } + + public void setBracket(boolean bracket) { + this.bracket = bracket; + } + protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, this.left); diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLQueryExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLQueryExpr.java index 0c6effe323..688ddfcd0c 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLQueryExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLQueryExpr.java @@ -87,4 +87,14 @@ public class SQLQueryExpr extends SQLExprImpl implements Serializable { } return true; } + + public SQLQueryExpr clone() { + SQLQueryExpr x = new SQLQueryExpr(); + + if (subQuery != null) { + x.setSubQuery(subQuery.clone()); + } + + return x; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java index 0b79bdb808..b21cc58c78 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java @@ -43,9 +43,6 @@ public class DB2OutputVisitor extends SQLASTOutputVisitor implements DB2ASTVisit if (x.isForReadOnly()) { println(); print0(ucase ? "FOR READ ONLY" : "for read only"); - } else if (x.isForUpdate()) { - println(); - print0(ucase ? "FOR UPDATE" : "for update"); } if (x.getIsolation() != null) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java index 8f8d05e802..aa13f832d3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java @@ -1695,7 +1695,7 @@ public class OracleStatementParser extends SQLStatementParser { if (lexer.token() == Token.ALL) { lexer.nextToken(); stmt.setOption(OracleMultiInsertStatement.Option.ALL); - } else if (lexer.token() == Token.FIRST) { + } else if (lexer.token() == Token.FIRST || identifierEquals("FIRST")) { lexer.nextToken(); stmt.setOption(OracleMultiInsertStatement.Option.FIRST); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java index c8a5e6959d..068694f7ea 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java @@ -144,8 +144,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS } public boolean visit(OracleDbLinkExpr x) { - x.getExpr().accept(this); - print('@'); + SQLExpr expr = x.getExpr(); + if (expr != null) { + expr.accept(this); + print('@'); + } print0(x.getDbLink()); return false; } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index 33de0fa50c..0bc967f360 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -228,6 +228,10 @@ public class SQLExprParser extends SQLParser { sqlExpr = listExpr; } + + if (sqlExpr instanceof SQLBinaryOpExpr) { + ((SQLBinaryOpExpr) sqlExpr).setBracket(true); + } accept(Token.RPAREN); break; diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index ecd123b849..ebadf8aee8 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -33,6 +33,7 @@ import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerEven import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerType; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlRepeatStatement; import com.alibaba.druid.util.JdbcConstants; +import com.alibaba.druid.util.JdbcUtils; public class SQLStatementParser extends SQLParser { @@ -129,6 +130,14 @@ public class SQLStatementParser extends SQLParser { continue; } + case WITH: + if (!JdbcConstants.POSTGRESQL.equals(dbType)){ + SQLStatement stmt = parseSelect(); + stmt.setParent(parent); + statementList.add(stmt); + continue; + } + break; case SELECT: { SQLStatement stmt = parseSelect(); stmt.setParent(parent); diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 4a537adafe..cddddc3506 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -476,10 +476,17 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet if (x.getRight() instanceof SQLBinaryOpExpr) { SQLBinaryOpExpr right = (SQLBinaryOpExpr) x.getRight(); - boolean rightRational = right.getOperator() == SQLBinaryOperator.BooleanAnd - || right.getOperator() == SQLBinaryOperator.BooleanOr; + SQLBinaryOperator rightOp = right.getOperator(); + SQLBinaryOperator op = x.getOperator(); + boolean rightRational = rightOp == SQLBinaryOperator.BooleanAnd + || rightOp == SQLBinaryOperator.BooleanOr; - if (right.getOperator().priority >= x.getOperator().priority) { + if (rightOp.priority >= op.priority + || (right.isBracket() + && rightOp != op + && rightOp.isLogical() + && op.isLogical() + )) { if (rightRational) { incrementIndent(); } @@ -507,10 +514,16 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet private void visitBinaryLeft(SQLExpr left, SQLBinaryOperator op) { if (left instanceof SQLBinaryOpExpr) { SQLBinaryOpExpr binaryLeft = (SQLBinaryOpExpr) left; - boolean leftRational = binaryLeft.getOperator() == SQLBinaryOperator.BooleanAnd - || binaryLeft.getOperator() == SQLBinaryOperator.BooleanOr; + SQLBinaryOperator leftOp = binaryLeft.getOperator(); + boolean leftRational = leftOp == SQLBinaryOperator.BooleanAnd + || leftOp == SQLBinaryOperator.BooleanOr; - if (binaryLeft.getOperator().priority > op.priority) { + if (leftOp.priority > op.priority + || (binaryLeft.isBracket() + && leftOp != op + && leftOp.isLogical() + && op.isLogical() + )) { if (leftRational) { incrementIndent(); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/createTable/MySqlCreateTableTest78_json.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/createTable/MySqlCreateTableTest78_json.java new file mode 100644 index 0000000000..1571a3a389 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/createTable/MySqlCreateTableTest78_json.java @@ -0,0 +1,54 @@ +/* + * 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.mysql.createTable; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat.Column; + +public class MySqlCreateTableTest78_json extends MysqlTest { + + public void test_one() throws Exception { + String sql = "CREATE TABLE t1 (jdoc JSON);"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseCreateTable(); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmt.accept(visitor); + + Column column = visitor.getColumn("t1", "jdoc"); + assertNotNull(column); + assertEquals("JSON", column.getDataType()); + + { + String output = SQLUtils.toMySqlString(stmt); + assertEquals("CREATE TABLE t1 (\n" + + "\tjdoc JSON\n" + + ")", output); + } + + { + String output = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); + assertEquals("create table t1 (\n" + + "\tjdoc JSON\n" + + ")", output); + } + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_42_with_cte.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_42_with_cte.java new file mode 100644 index 0000000000..a7bfcb1550 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_42_with_cte.java @@ -0,0 +1,105 @@ +/* + * 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.mysql.select; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import org.junit.Assert; + +import java.util.List; + +public class MySqlSelectTest_42_with_cte extends MysqlTest { + + public void test_0() throws Exception { + String sql = "WITH\n" + + " cte1 AS (SELECT a, b FROM table1),\n" + + " cte2 AS (SELECT c, d FROM table2)\n" + + "SELECT b, d FROM cte1 JOIN cte2\n" + + "WHERE cte1.a = cte2.c;"; + + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL, true); + SQLStatement stmt = statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.MYSQL); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + +// Assert.assertEquals(1, visitor.getTables().size()); +// Assert.assertEquals(1, visitor.getColumns().size()); +// Assert.assertEquals(0, visitor.getConditions().size()); +// Assert.assertEquals(0, visitor.getOrderByColumns().size()); + + { + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("WITH cte1 AS (\n" + + "\t\tSELECT a, b\n" + + "\t\tFROM table1\n" + + "\t), \n" + + "\tcte2 AS (\n" + + "\t\tSELECT c, d\n" + + "\t\tFROM table2\n" + + "\t)\n" + + "SELECT b, d\n" + + "FROM cte1\n" + + "\tJOIN cte2\n" + + "WHERE cte1.a = cte2.c;", // + output); + } + { + String output = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); + Assert.assertEquals("with cte1 as (\n" + + "\t\tselect a, b\n" + + "\t\tfrom table1\n" + + "\t), \n" + + "\tcte2 as (\n" + + "\t\tselect c, d\n" + + "\t\tfrom table2\n" + + "\t)\n" + + "select b, d\n" + + "from cte1\n" + + "\tjoin cte2\n" + + "where cte1.a = cte2.c;", // + output); + } + + { + String output = SQLUtils.toMySqlString(stmt, new SQLUtils.FormatOption(true, true, true)); + Assert.assertEquals("WITH cte1 AS (\n" + + "\t\tSELECT a, b\n" + + "\t\tFROM table1\n" + + "\t), \n" + + "\tcte2 AS (\n" + + "\t\tSELECT c, d\n" + + "\t\tFROM table2\n" + + "\t)\n" + + "SELECT b, d\n" + + "FROM cte1\n" + + "\tJOIN cte2\n" + + "WHERE cte1.a = cte2.c;", // + output); + } + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_43_with_cte.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_43_with_cte.java new file mode 100644 index 0000000000..a8d9b0e2e7 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_43_with_cte.java @@ -0,0 +1,105 @@ +/* + * 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.mysql.select; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import org.junit.Assert; + +import java.util.List; + +public class MySqlSelectTest_43_with_cte extends MysqlTest { + + public void test_0() throws Exception { + String sql = "WITH\n" + + " cte1 AS (SELECT a, b FROM table1),\n" + + " cte2 AS (SELECT c, d FROM table2)\n" + + "SELECT b, d FROM cte1 JOIN cte2\n" + + "WHERE cte1.a = cte2.c;"; + + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL, true); + SQLStatement stmt = statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.MYSQL); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + +// Assert.assertEquals(1, visitor.getTables().size()); +// Assert.assertEquals(1, visitor.getColumns().size()); +// Assert.assertEquals(0, visitor.getConditions().size()); +// Assert.assertEquals(0, visitor.getOrderByColumns().size()); + + { + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("WITH cte1 AS (\n" + + "\t\tSELECT a, b\n" + + "\t\tFROM table1\n" + + "\t), \n" + + "\tcte2 AS (\n" + + "\t\tSELECT c, d\n" + + "\t\tFROM table2\n" + + "\t)\n" + + "SELECT b, d\n" + + "FROM cte1\n" + + "\tJOIN cte2\n" + + "WHERE cte1.a = cte2.c;", // + output); + } + { + String output = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); + Assert.assertEquals("with cte1 as (\n" + + "\t\tselect a, b\n" + + "\t\tfrom table1\n" + + "\t), \n" + + "\tcte2 as (\n" + + "\t\tselect c, d\n" + + "\t\tfrom table2\n" + + "\t)\n" + + "select b, d\n" + + "from cte1\n" + + "\tjoin cte2\n" + + "where cte1.a = cte2.c;", // + output); + } + + { + String output = SQLUtils.toMySqlString(stmt, new SQLUtils.FormatOption(true, true, true)); + Assert.assertEquals("WITH cte1 AS (\n" + + "\t\tSELECT a, b\n" + + "\t\tFROM table1\n" + + "\t), \n" + + "\tcte2 AS (\n" + + "\t\tSELECT c, d\n" + + "\t\tFROM table2\n" + + "\t)\n" + + "SELECT b, d\n" + + "FROM cte1\n" + + "\tJOIN cte2\n" + + "WHERE cte1.a = cte2.c;", // + output); + } + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_44_with_cte.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_44_with_cte.java new file mode 100644 index 0000000000..e77bc876ed --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_44_with_cte.java @@ -0,0 +1,98 @@ +/* + * 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.mysql.select; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import org.junit.Assert; + +import java.util.List; + +public class MySqlSelectTest_44_with_cte extends MysqlTest { + + public void test_0() throws Exception { + String sql = "WITH RECURSIVE cte AS\n" + + "(\n" + + " SELECT 1 AS n, 1 AS p, -1 AS q\n" + + " UNION ALL\n" + + " SELECT n + 1, q * 2, p * 2 FROM cte WHERE n < 5\n" + + ")\n" + + "SELECT * FROM cte;"; + + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL, true); + SQLStatement stmt = statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.MYSQL); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + +// Assert.assertEquals(1, visitor.getTables().size()); +// Assert.assertEquals(1, visitor.getColumns().size()); +// Assert.assertEquals(0, visitor.getConditions().size()); +// Assert.assertEquals(0, visitor.getOrderByColumns().size()); + + { + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("WITH RECURSIVE cte AS (\n" + + "\t\tSELECT 1 AS n, 1 AS p, -1 AS q\n" + + "\t\tUNION ALL\n" + + "\t\tSELECT n + 1, q * 2, p * 2\n" + + "\t\tFROM cte\n" + + "\t\tWHERE n < 5\n" + + "\t)\n" + + "SELECT *\n" + + "FROM cte;", // + output); + } + { + String output = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); + Assert.assertEquals("with recursive cte as (\n" + + "\t\tselect 1 as n, 1 as p, -1 as q\n" + + "\t\tunion all\n" + + "\t\tselect n + 1, q * 2, p * 2\n" + + "\t\tfrom cte\n" + + "\t\twhere n < 5\n" + + "\t)\n" + + "select *\n" + + "from cte;", // + output); + } + + { + String output = SQLUtils.toMySqlString(stmt, new SQLUtils.FormatOption(true, true, true)); + Assert.assertEquals("WITH RECURSIVE cte AS (\n" + + "\t\tSELECT ? AS n, ? AS p, ? AS q\n" + + "\t\tUNION ALL\n" + + "\t\tSELECT n + ?, q * ?, p * ?\n" + + "\t\tFROM cte\n" + + "\t\tWHERE n < ?\n" + + "\t)\n" + + "SELECT *\n" + + "FROM cte;", // + output); + } + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_45_subquery_scalar_operand.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_45_subquery_scalar_operand.java new file mode 100644 index 0000000000..4d1d963dd5 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_45_subquery_scalar_operand.java @@ -0,0 +1,80 @@ +/* + * 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.mysql.select; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import org.junit.Assert; + +import java.util.List; + +public class MySqlSelectTest_45_subquery_scalar_operand extends MysqlTest { + + public void test_0() throws Exception { + String sql = "SELECT (SELECT s1 FROM t2) FROM t1;"; + + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL, true); + SQLStatement stmt = statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.MYSQL); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + +// Assert.assertEquals(1, visitor.getTables().size()); +// Assert.assertEquals(1, visitor.getColumns().size()); +// Assert.assertEquals(0, visitor.getConditions().size()); +// Assert.assertEquals(0, visitor.getOrderByColumns().size()); + + { + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("SELECT (\n" + + "\t\tSELECT s1\n" + + "\t\tFROM t2\n" + + "\t)\n" + + "FROM t1;", // + output); + } + { + String output = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); + Assert.assertEquals("select (\n" + + "\t\tselect s1\n" + + "\t\tfrom t2\n" + + "\t)\n" + + "from t1;", // + output); + } + + { + String output = SQLUtils.toMySqlString(stmt, new SQLUtils.FormatOption(true, true, true)); + Assert.assertEquals("SELECT (\n" + + "\t\tSELECT s1\n" + + "\t\tFROM t2\n" + + "\t)\n" + + "FROM t1;", // + output); + } + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest22.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest22.java new file mode 100644 index 0000000000..5a317205d9 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest22.java @@ -0,0 +1,147 @@ +/* + * 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.odps; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.List; + +public class OdpsSelectTest22 extends TestCase { + + public void test_select() throws Exception { + // 1095288847322 + String sql = "select bucket_id,sum(pv) as pv, sum(clk) as clk,sum(clk)/(sum(pv)+1e-10) as ctr,sum(ut_ad_clk) as ut_ad_clk,sum(ad_clk) as ad_clk,sum(cost) as cost\n" + + ", sum(cost)*1000/(sum(pv)+1e-10)/100 as rpm\n" + + "from (\n" + + "select bucket_id,UT.pv as pv, UT.clk as clk, UT.ad_clk as ut_ad_clk, CLK.clk as ad_clk,CLK.cost as cost\n" + + "from (\n" + + "\tselect item_id,pv_id,sum(pv) as pv,sum(clk) as clk, sum(if(str_to_map(args,',','=')['sid'] is not null,clk,0)) as ad_clk\n" + + "\t,str_to_map(args,',','=')['sid'] as ad_session,split_part(str_to_map(args,',','=')['scm'],'.',2) as bucket_id\n" + + "\tfrom alimama_algo.fund_mlr_n_chicago_user_track_distinct_shark\n" + + "\twhere ds=20170627 and hh=00 and mm=00 \n" + + "\tgroup by item_id,str_to_map(args,',','=')['sid'],pv_id, split_part(str_to_map(args,',','=')['scm'],'.',2)\n" + + ") UT\n" + + "left outer join \n" + + "(\n" + + "SELECT pv_id AS ad_session\n" + + "\t, item_it AS item_id\n" + + "\t, SUM(click_price) AS cost\n" + + "\t, COUNT(*) AS clk\n" + + "FROM alimama_algo.fund_mlr_n_chicago_offline_click\n" + + "WHERE ds = 20170627\n" + + "\tAND hh = 0\n" + + "\tAND mm = 0\n" + + "GROUP BY pv_id, \n" + + "\titem_it\n" + + ") CLK on UT.ad_session = CLK.ad_session and UT.item_id = CLK.item_id\n" + + "where UT.ad_clk > 0 or CLK.clk > 0\n" + + ") A\n" + + "group by bucket_id;";// + assertEquals("SELECT bucket_id, SUM(pv) AS pv, SUM(clk) AS clk, SUM(clk) / (SUM(pv) + 1E-10) AS ctr, SUM(ut_ad_clk) AS ut_ad_clk\n" + + "\t, SUM(ad_clk) AS ad_clk, SUM(cost) AS cost, SUM(cost) * 1000 / (SUM(pv) + 1E-10) / 100 AS rpm\n" + + "FROM (\n" + + "\tSELECT bucket_id, UT.pv AS pv, UT.clk AS clk, UT.ad_clk AS ut_ad_clk, CLK.clk AS ad_clk\n" + + "\t\t, CLK.cost AS cost\n" + + "\tFROM (\n" + + "\t\tSELECT item_id, pv_id, SUM(pv) AS pv, SUM(clk) AS clk, SUM(IF(str_to_map(args, ',', '=')['sid'] IS NOT NULL, clk, 0)) AS ad_clk\n" + + "\t\t\t, str_to_map(args, ',', '=')['sid'] AS ad_session, split_part(str_to_map(args, ',', '=')['scm'], '.', 2) AS bucket_id\n" + + "\t\tFROM alimama_algo.fund_mlr_n_chicago_user_track_distinct_shark\n" + + "\t\tWHERE ds = 20170627\n" + + "\t\t\tAND hh = 0\n" + + "\t\t\tAND mm = 0\n" + + "\t\tGROUP BY item_id, \n" + + "\t\t\tstr_to_map(args, ',', '=')['sid'], \n" + + "\t\t\tpv_id, \n" + + "\t\t\tsplit_part(str_to_map(args, ',', '=')['scm'], '.', 2)\n" + + "\t) UT\n" + + "\tLEFT OUTER JOIN (\n" + + "\t\tSELECT pv_id AS ad_session, item_it AS item_id, SUM(click_price) AS cost, COUNT(*) AS clk\n" + + "\t\tFROM alimama_algo.fund_mlr_n_chicago_offline_click\n" + + "\t\tWHERE ds = 20170627\n" + + "\t\t\tAND hh = 0\n" + + "\t\t\tAND mm = 0\n" + + "\t\tGROUP BY pv_id, \n" + + "\t\t\titem_it\n" + + "\t) CLK\n" + + "\tON UT.ad_session = CLK.ad_session\n" + + "\t\tAND UT.item_id = CLK.item_id\n" + + "\tWHERE UT.ad_clk > 0\n" + + "\t\tOR CLK.clk > 0\n" + + ") A\n" + + "GROUP BY bucket_id;", SQLUtils.formatOdps(sql)); + + assertEquals("select bucket_id, sum(pv) as pv, sum(clk) as clk, sum(clk) / (sum(pv) + 1E-10) as ctr, sum(ut_ad_clk) as ut_ad_clk\n" + + "\t, sum(ad_clk) as ad_clk, sum(cost) as cost, sum(cost) * 1000 / (sum(pv) + 1E-10) / 100 as rpm\n" + + "from (\n" + + "\tselect bucket_id, UT.pv as pv, UT.clk as clk, UT.ad_clk as ut_ad_clk, CLK.clk as ad_clk\n" + + "\t\t, CLK.cost as cost\n" + + "\tfrom (\n" + + "\t\tselect item_id, pv_id, sum(pv) as pv, sum(clk) as clk, sum(if(str_to_map(args, ',', '=')['sid'] is not null, clk, 0)) as ad_clk\n" + + "\t\t\t, str_to_map(args, ',', '=')['sid'] as ad_session, split_part(str_to_map(args, ',', '=')['scm'], '.', 2) as bucket_id\n" + + "\t\tfrom alimama_algo.fund_mlr_n_chicago_user_track_distinct_shark\n" + + "\t\twhere ds = 20170627\n" + + "\t\t\tand hh = 0\n" + + "\t\t\tand mm = 0\n" + + "\t\tgroup by item_id, \n" + + "\t\t\tstr_to_map(args, ',', '=')['sid'], \n" + + "\t\t\tpv_id, \n" + + "\t\t\tsplit_part(str_to_map(args, ',', '=')['scm'], '.', 2)\n" + + "\t) UT\n" + + "\tleft outer join (\n" + + "\t\tselect pv_id as ad_session, item_it as item_id, sum(click_price) as cost, count(*) as clk\n" + + "\t\tfrom alimama_algo.fund_mlr_n_chicago_offline_click\n" + + "\t\twhere ds = 20170627\n" + + "\t\t\tand hh = 0\n" + + "\t\t\tand mm = 0\n" + + "\t\tgroup by pv_id, \n" + + "\t\t\titem_it\n" + + "\t) CLK\n" + + "\ton UT.ad_session = CLK.ad_session\n" + + "\t\tand UT.item_id = CLK.item_id\n" + + "\twhere UT.ad_clk > 0\n" + + "\t\tor CLK.clk > 0\n" + + ") A\n" + + "group by bucket_id;", SQLUtils.formatOdps(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ODPS); + SQLStatement stmt = statementList.get(0); + + assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ODPS); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + + assertEquals(2, visitor.getTables().size()); + assertEquals(17, visitor.getColumns().size()); + assertEquals(6, visitor.getConditions().size()); + + System.out.println(SQLUtils.formatOdps(sql)); + +// assertTrue(visitor.getColumns().contains(new Column("abc", "name"))); + } + + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest23.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest23.java new file mode 100644 index 0000000000..adbcaf6931 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest23.java @@ -0,0 +1,68 @@ +/* + * 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.odps; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class OdpsSelectTest23 extends TestCase { + + public void test_select() throws Exception { + // 1095288847322 + String sql = "select * FROM dual where 1 = 1 and (2 = 2 or ( 3 = 3 and 4 = 4));";// + assertEquals("SELECT *\n" + + "FROM dual\n" + + "WHERE 1 = 1\n" + + "\tAND (2 = 2\n" + + "\t\tOR (3 = 3\n" + + "\t\t\tAND 4 = 4));", SQLUtils.formatOdps(sql)); + + assertEquals("select *\n" + + "from dual\n" + + "where 1 = 1\n" + + "\tand (2 = 2\n" + + "\t\tor (3 = 3\n" + + "\t\t\tand 4 = 4));", SQLUtils.formatOdps(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ODPS); + SQLStatement stmt = statementList.get(0); + + assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ODPS); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + + assertEquals(1, visitor.getTables().size()); + assertEquals(1, visitor.getColumns().size()); + assertEquals(0, visitor.getConditions().size()); + + System.out.println(SQLUtils.formatOdps(sql)); + +// assertTrue(visitor.getColumns().contains(new Column("abc", "name"))); + } + + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/block/OracleBlockTest21.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/block/OracleBlockTest21.java new file mode 100644 index 0000000000..5ab090b6ac --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/block/OracleBlockTest21.java @@ -0,0 +1,82 @@ +/* + * 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.block; + +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.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; + +import java.util.List; + +public class OracleBlockTest21 extends OracleTest { + + public void test_0() throws Exception { + String sql = "BEGIN\n" + + " FOR someone IN (\n" + + " SELECT * FROM employees\n" + + " WHERE employee_id < 120\n" + + " ORDER BY employee_id\n" + + " )\n" + + " LOOP\n" + + " DBMS_OUTPUT.PUT_LINE('First name = ' || someone.first_name ||\n" + + " ', Last name = ' || someone.last_name);\n" + + " END LOOP;\n" + + "END;"; // + + List stmtList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); + assertEquals(1, stmtList.size()); + + String result = SQLUtils.toOracleString(stmtList.get(0)); + System.out.println(result); + assertEquals("BEGIN\n" + + "\tFOR someone IN (\n" + + "\t\tSELECT *\n" + + "\t\tFROM employees\n" + + "\t\tWHERE employee_id < 120\n" + + "\t\tORDER BY employee_id\n" + + "\t)\n" + + "\tLOOP\n" + + "\t\tDBMS_OUTPUT.PUT_LINE('First name = ' || someone.first_name || ', Last name = ' || someone.last_name);\n" + + "\tEND LOOP;\n" + + "END;", result); + + assertEquals(1, stmtList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + for (SQLStatement statement : stmtList) { + statement.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()); + + assertEquals(1, visitor.getTables().size()); + + assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + + assertEquals(2, visitor.getColumns().size()); + assertEquals(1, visitor.getConditions().size()); + assertEquals(0, visitor.getRelationships().size()); + + assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/block/OracleBlockTest22_comment.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/block/OracleBlockTest22_comment.java new file mode 100644 index 0000000000..b19c5b99ec --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/block/OracleBlockTest22_comment.java @@ -0,0 +1,81 @@ +/* + * 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.block; + +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.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; + +import java.util.List; + +public class OracleBlockTest22_comment extends OracleTest { + + public void test_0() throws Exception { + String sql = "DECLARE\n" + + " howmany NUMBER;\n" + + " num_tables NUMBER;\n" + + "BEGIN\n" + + " -- Begin processing\n" + + " SELECT COUNT(*) INTO howmany\n" + + " FROM USER_OBJECTS\n" + + " WHERE OBJECT_TYPE = 'TABLE'; -- Check number of tables\n" + + " num_tables := howmany; -- Compute another value\n" + + "END;"; // + + List stmtList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); + assertEquals(1, stmtList.size()); + + String result = SQLUtils.toOracleString(stmtList.get(0)); + System.out.println(result); + assertEquals("DECLARE\n" + + "\thowmany NUMBER;\n" + + "\tnum_tables NUMBER;\n" + + "BEGIN\n" + + "\t-- Begin processing\n" + + "\tSELECT COUNT(*)\n" + + "\tINTO howmany\n" + + "\tFROM USER_OBJECTS\n" + + "\tWHERE OBJECT_TYPE = 'TABLE';\n" + + "\tnum_tables := howmany;\n" + + "END;", result); + + assertEquals(1, stmtList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + for (SQLStatement statement : stmtList) { + statement.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()); + + assertEquals(1, visitor.getTables().size()); + + assertTrue(visitor.getTables().containsKey(new TableStat.Name("USER_OBJECTS"))); + + assertEquals(1, visitor.getColumns().size()); + assertEquals(1, visitor.getConditions().size()); + assertEquals(0, visitor.getRelationships().size()); + + assertTrue(visitor.getColumns().contains(new TableStat.Column("USER_OBJECTS", "OBJECT_TYPE"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateViewTest1.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateViewTest1.java index 9c56c1e734..c8cd479dec 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateViewTest1.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateViewTest1.java @@ -160,8 +160,8 @@ public class OracleCreateViewTest1 extends OracleTest { "\t, c.aboutus_image_path, c.aboutus_image_title, c.chinese_name, c.rowid AS c_rid, v.rowid AS v_rid\n" + "FROM tb_001 v, tb_002 c\n" + "WHERE (v.service_type IN ('gs', 'cgs', 'hkgs', 'twgs')\n" + - "\t\tOR v.service_type = 'cnfm'\n" + - "\t\tAND v.stage = 'new_order')\n" + + "\t\tOR (v.service_type = 'cnfm'\n" + + "\t\t\tAND v.stage = 'new_order'))\n" + "\tAND v.id = c.id",// SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/insert/OracleInsertTest20_first.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/insert/OracleInsertTest20_first.java new file mode 100644 index 0000000000..b39153f164 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/insert/OracleInsertTest20_first.java @@ -0,0 +1,91 @@ +/* + * 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.insert; + +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 com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; +import org.junit.Assert; + +import java.util.List; + +public class OracleInsertTest20_first extends OracleTest { + + public void test_0() throws Exception { + String sql = "INSERT FIRST\n" + + " WHEN ottl < 100000 THEN\n" + + " INTO small_orders\n" + + " VALUES(oid, ottl, sid, cid)\n" + + " WHEN ottl > 100000 and ottl < 200000 THEN\n" + + " INTO medium_orders\n" + + " VALUES(oid, ottl, sid, cid)\n" + + " WHEN ottl > 290000 THEN\n" + + " INTO special_orders\n" + + " WHEN ottl > 200000 THEN\n" + + " INTO large_orders\n" + + " VALUES(oid, ottl, sid, cid)\n" + + " SELECT o.order_id oid, o.customer_id cid, o.order_total ottl,\n" + + " o.sales_rep_id sid, c.credit_limit cl, c.cust_email cem\n" + + " FROM orders o, customers c\n" + + " WHERE o.customer_id = c.customer_id;"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + assertEquals("INSERT FIRST \n" + + "\tWHEN ottl < 100000 THEN\n" + + "\t\tINTO small_orders\n" + + "\t\tVALUES (oid, ottl, sid, cid)\n" + + "\tWHEN ottl > 100000\n" + + "\tAND ottl < 200000 THEN\n" + + "\t\tINTO medium_orders\n" + + "\t\tVALUES (oid, ottl, sid, cid)\n" + + "\tWHEN ottl > 290000 THEN\n" + + "\t\tINTO special_orders\n" + + "\tWHEN ottl > 200000 THEN\n" + + "\t\tINTO large_orders\n" + + "\t\tVALUES (oid, ottl, sid, cid)\n" + + "SELECT o.order_id AS oid, o.customer_id AS cid, o.order_total AS ottl, o.sales_rep_id AS sid, c.credit_limit AS cl\n" + + "\t, c.cust_email AS cem\n" + + "FROM orders o, customers c\n" + + "WHERE o.customer_id = c.customer_id;",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + 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()); + + assertEquals(6, visitor.getTables().size()); + assertEquals(8, visitor.getColumns().size()); + + assertTrue(visitor.getTables().containsKey(new TableStat.Name("orders"))); + + assertTrue(visitor.getColumns().contains(new TableStat.Column("orders", "customer_id"))); + } + +}