From 431e080bdfea4e1a1115fdf585350b1a22af5942 Mon Sep 17 00:00:00 2001 From: wenshao Date: Fri, 20 May 2011 16:05:38 +0000 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=BF=90=E7=AE=97=E7=AC=A6?= =?UTF-8?q?=E4=BC=98=E5=85=88=E7=BA=A7=E5=88=AB=E5=A4=84=E7=90=86=E4=B8=8D?= =?UTF-8?q?=E5=BD=93=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://code.alibabatech.com/svn/druid/trunk@160 b9813039-fb51-4c41-a8b9-e21c2acb5095 --- .../sql/ast/statement/SQLInsertStatement.java | 9 ++ .../ast/statement/SQLSubqueryTableSource.java | 5 +- .../sql/ast/statement/SQLUnionOperator.java | 18 +++ .../sql/ast/statement/SQLUnionQuery.java | 18 +-- .../dialect/mysql/parser/MySqlExprParser.java | 4 + .../sql/dialect/mysql/parser/MySqlLexer.java | 2 + .../mysql/parser/MySqlSelectParser.java | 37 +++++- .../mysql/parser/MySqlStatementParser.java | 9 +- .../mysql/visitor/MySqlOutputVisitor.java | 2 +- .../oracle/ast/expr/OraclePriorExpr.java | 41 +++++++ .../ast/stmt/OracleSelectOrderByItem.java | 17 ++- .../oracle/ast/visitor/OracleASTVisitor.java | 5 + .../ast/visitor/OracleOutputVisitor.java | 13 +++ .../OracleParameterizedOutputVisitor.java | 56 ++++++++++ .../oracle/parser/OracleExprParser.java | 17 ++- .../oracle/parser/OracleSelectParser.java | 60 +++++++--- .../com/alibaba/druid/sql/parser/Lexer.java | 15 ++- .../druid/sql/parser/SQLExprParser.java | 48 +++++--- .../alibaba/druid/sql/parser/SQLParser.java | 28 +++-- .../druid/sql/parser/SQLSelectParser.java | 43 +++++-- .../druid/sql/parser/SQLStatementParser.java | 5 + .../com/alibaba/druid/sql/parser/Token.java | 1 + .../sql/visitor/SQLASTOutputVisitor.java | 17 ++- .../druid/sql/visitor/SQLASTVisitor.java | 5 + .../sql/visitor/SQLASTVisitorAdapter.java | 13 ++- .../com/alibaba/druid/sql/OnlineSQLTest.java | 105 ++++++++++++++---- .../bvt/parser/MySqlParserResourceTest.java | 10 +- .../bvt/OracleSQLParserResourceTest.java | 44 +++++--- src/test/resources/bvt/parser/mysql-1.txt | 14 +++ src/test/resources/bvt/parser/mysql-2.txt | 9 ++ src/test/resources/bvt/parser/mysql-3.txt | 11 ++ src/test/resources/bvt/parser/mysql-4.txt | 9 ++ src/test/resources/bvt/parser/mysql-5.txt | 14 +++ src/test/resources/bvt/parser/mysql-6.txt | 43 +++++++ src/test/resources/bvt/parser/mysql-7.txt | 13 +++ src/test/resources/bvt/parser/mysql-8.txt | 20 ++++ src/test/resources/bvt/parser/mysql-9.txt | 42 +++++++ src/test/resources/bvt/parser/oracle-13.txt | 2 +- src/test/resources/bvt/parser/oracle-15.txt | 35 ++++++ src/test/resources/bvt/parser/oracle-16.txt | 19 ++++ src/test/resources/bvt/parser/oracle-17.txt | 31 ++++++ src/test/resources/bvt/parser/oracle-18.txt | 14 +++ src/test/resources/bvt/parser/oracle-19.txt | 20 ++++ src/test/resources/bvt/parser/oracle-20.txt | 16 +++ src/test/resources/bvt/parser/oracle-21.txt | 29 +++++ src/test/resources/bvt/parser/oracle-22.txt | 39 +++++++ src/test/resources/bvt/parser/oracle-23.txt | 17 +++ src/test/resources/bvt/parser/oracle-24.txt | 22 ++++ src/test/resources/bvt/parser/oracle-25.txt | 62 +++++++++++ src/test/resources/bvt/parser/oracle-26.txt | 21 ++++ src/test/resources/bvt/parser/oracle-27.txt | 14 +++ src/test/resources/bvt/parser/oracle-28.txt | 16 +++ src/test/resources/bvt/parser/oracle-29.txt | 18 +++ src/test/resources/bvt/parser/oracle-5.txt | 2 +- 54 files changed, 1085 insertions(+), 114 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionOperator.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OraclePriorExpr.java create mode 100644 src/test/resources/bvt/parser/mysql-1.txt create mode 100644 src/test/resources/bvt/parser/mysql-2.txt create mode 100644 src/test/resources/bvt/parser/mysql-3.txt create mode 100644 src/test/resources/bvt/parser/mysql-4.txt create mode 100644 src/test/resources/bvt/parser/mysql-5.txt create mode 100644 src/test/resources/bvt/parser/mysql-6.txt create mode 100644 src/test/resources/bvt/parser/mysql-7.txt create mode 100644 src/test/resources/bvt/parser/mysql-8.txt create mode 100644 src/test/resources/bvt/parser/mysql-9.txt create mode 100644 src/test/resources/bvt/parser/oracle-15.txt create mode 100644 src/test/resources/bvt/parser/oracle-16.txt create mode 100644 src/test/resources/bvt/parser/oracle-17.txt create mode 100644 src/test/resources/bvt/parser/oracle-18.txt create mode 100644 src/test/resources/bvt/parser/oracle-19.txt create mode 100644 src/test/resources/bvt/parser/oracle-20.txt create mode 100644 src/test/resources/bvt/parser/oracle-21.txt create mode 100644 src/test/resources/bvt/parser/oracle-22.txt create mode 100644 src/test/resources/bvt/parser/oracle-23.txt create mode 100644 src/test/resources/bvt/parser/oracle-24.txt create mode 100644 src/test/resources/bvt/parser/oracle-25.txt create mode 100644 src/test/resources/bvt/parser/oracle-26.txt create mode 100644 src/test/resources/bvt/parser/oracle-27.txt create mode 100644 src/test/resources/bvt/parser/oracle-28.txt create mode 100644 src/test/resources/bvt/parser/oracle-29.txt diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertStatement.java index 0db4a1c50c..a7d557b78e 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertStatement.java @@ -29,6 +29,7 @@ public class SQLInsertStatement extends SQLStatementImpl { private static final long serialVersionUID = 1L; private SQLName tableName; + private String alias; private final List columns = new ArrayList(); private ValuesClause values; @@ -38,6 +39,14 @@ public class SQLInsertStatement extends SQLStatementImpl { } + public String getAlias() { + return alias; + } + + public void setAlias(String alias) { + this.alias = alias; + } + public SQLName getTableName() { return tableName; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSubqueryTableSource.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSubqueryTableSource.java index f9b60cceca..4ea3bd27ba 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSubqueryTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSubqueryTableSource.java @@ -51,7 +51,10 @@ public class SQLSubqueryTableSource extends SQLTableSource { @Override protected void accept0(SQLASTVisitor visitor) { - throw new UnsupportedOperationException(); + if (visitor.visit(this)) { + acceptChild(visitor, select); + } + visitor.endVisit(this); } public void output(StringBuffer buf) { diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionOperator.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionOperator.java new file mode 100644 index 0000000000..b755a8771d --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionOperator.java @@ -0,0 +1,18 @@ +package com.alibaba.druid.sql.ast.statement; + +public enum SQLUnionOperator { + UNION("UNION"), + UNION_ALL("UNION ALL"), + MINUS("MINUS"), + INTERSECT("INTERSECT"); + + public final String name; + + private SQLUnionOperator(String name) { + this.name = name; + } + + public String toString() { + return name; + } +} diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionQuery.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionQuery.java index 918fc2c4e4..0f232eef54 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionQuery.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionQuery.java @@ -23,7 +23,15 @@ public class SQLUnionQuery extends SQLSelectQuery { private SQLSelectQuery left; private SQLSelectQuery right; - private boolean all; + private SQLUnionOperator operator = SQLUnionOperator.UNION; + + public SQLUnionOperator getOperator() { + return operator; + } + + public void setOperator(SQLUnionOperator operator) { + this.operator = operator; + } public SQLUnionQuery(){ @@ -45,14 +53,6 @@ public class SQLUnionQuery extends SQLSelectQuery { this.right = right; } - public boolean isAll() { - return all; - } - - public void setAll(boolean all) { - this.all = all; - } - @Override protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java index cfb0440bfb..1f00287d79 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java @@ -98,6 +98,10 @@ public class MySqlExprParser extends SQLExprParser { case FALSE: lexer.nextToken(); return primaryRest(new MySqlBooleanExpr(false)); + case LITERAL_ALIAS: + String aliasValue = lexer.stringVal(); + lexer.nextToken(); + return primaryRest(new SQLCharExpr(aliasValue)); default: return super.primary(); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java index 8904dfb159..ad2a797073 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java @@ -102,8 +102,10 @@ public class MySqlLexer extends Lexer { map.put("LOCK", Token.LOCK); map.put("SOME", Token.SOME); map.put("ANY", Token.ANY); + map.put("TRUE", Token.TRUE); map.put("FALSE", Token.FALSE); + map.put("LIMIT", Token.LIMIT); DEFAULT_MYSQL_KEYWORDS = new Keywords(map); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java index 704fda7646..37ebc25377 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java @@ -38,6 +38,41 @@ public class MySqlSelectParser extends SQLSelectParser { this(new MySqlLexer(sql)); this.lexer.nextToken(); } + + @Override + protected final String as() throws ParserException { + String rtnValue = null; + + if (lexer.token() == Token.AS) { + lexer.nextToken(); + + if (lexer.token() == Token.LITERAL_ALIAS) { + rtnValue = lexer.stringVal(); + lexer.nextToken(); + return rtnValue; + } + + if (lexer.token() == Token.IDENTIFIER) { + rtnValue = lexer.stringVal(); + lexer.nextToken(); + return rtnValue; + } + + throw new ParserException("Error", 0, 0); + } + + if (lexer.token() == Token.LITERAL_ALIAS) { + rtnValue = lexer.stringVal(); + lexer.nextToken(); + } else if (lexer.token() == Token.IDENTIFIER) { + rtnValue = lexer.stringVal(); + lexer.nextToken(); + } else if (lexer.token() == Token.LITERAL_CHARS) { + rtnValue = "'" + lexer.stringVal() + "'"; + lexer.nextToken(); + } + return rtnValue; + } @Override protected SQLSelectQuery query() throws ParserException { @@ -164,7 +199,7 @@ public class MySqlSelectParser extends SQLSelectParser { queryBlock.setOrderBy(this.createExprParser().parseOrderBy()); - if (identifierEquals("LIMIT")) { + if (lexer.token() == Token.LIMIT) { lexer.nextToken(); MySqlSelectQueryBlock.Limit limit = new MySqlSelectQueryBlock.Limit(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index b2e3ae1ced..321a3a0547 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -129,7 +129,7 @@ public class MySqlStatementParser extends SQLStatementParser { deleteStatement.setOrderBy(orderBy); } - if (identifierEquals("LIMIT")) { + if (lexer.token() == Token.LIMIT) { lexer.nextToken(); MySqlSelectQueryBlock.Limit limit = new MySqlSelectQueryBlock.Limit(); @@ -317,7 +317,7 @@ public class MySqlStatementParser extends SQLStatementParser { private MySqlShowWarningsStatement parseShowWarnings() throws ParserException { MySqlShowWarningsStatement stmt = new MySqlShowWarningsStatement(); - if (identifierEquals("LIMIT")) { + if (lexer.token() == Token.LIMIT) { lexer.nextToken(); MySqlSelectQueryBlock.Limit limit = new MySqlSelectQueryBlock.Limit(); @@ -771,6 +771,11 @@ public class MySqlStatementParser extends SQLStatementParser { SQLName tableName = this.exprParser.name(); insertStatement.setTableName(tableName); + + if (lexer.token() == Token.IDENTIFIER) { + insertStatement.setAlias(lexer.stringVal()); + lexer.nextToken(); + } if (lexer.token() == (Token.LPAREN)) { lexer.nextToken(); 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 511f5c6ca9..fcd0e37217 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 @@ -189,7 +189,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV } if (select.getLimit() != null) { - print(" "); + println(); select.getLimit().accept(this); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OraclePriorExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OraclePriorExpr.java new file mode 100644 index 0000000000..8a65dc3002 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OraclePriorExpr.java @@ -0,0 +1,41 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.expr; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLExprImpl; +import com.alibaba.druid.sql.dialect.oracle.ast.visitor.OracleASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +public class OraclePriorExpr extends SQLExprImpl { + + private static final long serialVersionUID = 1L; + private SQLExpr expr; + + public OraclePriorExpr() { + + } + + public OraclePriorExpr(SQLExpr expr) { + this.expr = expr; + } + + public SQLExpr getExpr() { + return expr; + } + + public void setExpr(SQLExpr expr) { + this.expr = expr; + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + accept0((OracleASTVisitor) visitor); + } + + protected void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, expr); + } + visitor.endVisit(this); + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectOrderByItem.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectOrderByItem.java index 84a67f9c5c..d64f9fa155 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectOrderByItem.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectOrderByItem.java @@ -18,6 +18,7 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; import com.alibaba.druid.sql.ast.SQLOrderingSpecification; import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem; import com.alibaba.druid.sql.dialect.oracle.ast.visitor.OracleASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class OracleSelectOrderByItem extends SQLSelectOrderByItem { @@ -36,6 +37,10 @@ public class OracleSelectOrderByItem extends SQLSelectOrderByItem { public void setNullsOrderType(NullsOrderType nullsOrderType) { this.nullsOrderType = nullsOrderType; } + + protected void accept0(SQLASTVisitor visitor) { + accept0((OracleASTVisitor) visitor); + } protected void accept0(OracleASTVisitor visitor) { if (visitor.visit(this)) { @@ -47,12 +52,16 @@ public class OracleSelectOrderByItem extends SQLSelectOrderByItem { public void output(StringBuffer buf) { this.expr.output(buf); - if (SQLOrderingSpecification.ASC.equals(this.type)) buf.append(" ASC"); - else if (SQLOrderingSpecification.DESC.equals(this.type)) { + if (SQLOrderingSpecification.ASC.equals(this.type)) { + buf.append(" ASC"); + } else if (SQLOrderingSpecification.DESC.equals(this.type)) { buf.append(" DESC"); } - if (NullsOrderType.NullsFirst.equals(this.nullsOrderType)) buf.append(" NULLS FIRST"); - else if (NullsOrderType.NullsLast.equals(this.nullsOrderType)) buf.append(" NULLS LAST"); + if (NullsOrderType.NullsFirst.equals(this.nullsOrderType)) { + buf.append(" NULLS FIRST"); + } else if (NullsOrderType.NullsLast.equals(this.nullsOrderType)) { + buf.append(" NULLS LAST"); + } } public static enum NullsOrderType { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleASTVisitor.java index f4a31c8260..53a54a6224 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleASTVisitor.java @@ -35,6 +35,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleGroupComparisonCondit import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleGroupingSetsExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleOuterExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OraclePriorExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OraclePriorIdentifierExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTableCollectionExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr; @@ -333,4 +334,8 @@ public interface OracleASTVisitor extends SQLASTVisitor { boolean visit(GroupingSetExpr x); void endVisit(GroupingSetExpr x); + + boolean visit(OraclePriorExpr x); + + void endVisit(OraclePriorExpr x); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleOutputVisitor.java index 9997b495c3..3087555737 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleOutputVisitor.java @@ -47,6 +47,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleGroupComparisonCondit import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleGroupingSetsExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleOuterExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OraclePriorExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OraclePriorIdentifierExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTableCollectionExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr; @@ -1576,4 +1577,16 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS } + @Override + public boolean visit(OraclePriorExpr x) { + print("PRIOR "); + x.getExpr().accept(this); + return false; + } + + @Override + public void endVisit(OraclePriorExpr x) { + + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleParameterizedOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleParameterizedOutputVisitor.java index fad5df2778..a3b4df9e1a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleParameterizedOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleParameterizedOutputVisitor.java @@ -2,8 +2,13 @@ package com.alibaba.druid.sql.dialect.oracle.ast.visitor; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; +import com.alibaba.druid.sql.ast.expr.SQLCharExpr; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.expr.SQLInListExpr; +import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; +import com.alibaba.druid.sql.ast.expr.SQLNCharExpr; +import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; public class OracleParameterizedOutputVisitor extends OracleOutputVisitor { @@ -12,6 +17,37 @@ public class OracleParameterizedOutputVisitor extends OracleOutputVisitor { super(appender); } + public void println() { + print(' '); + } + + public boolean visit(SQLInListExpr x) { + x.getExpr().accept(this); + + if (x.isNot()) { + print(" NOT IN (##)"); + } else { + print(" IN (##)"); + } + + return false; + } + + public boolean visit(SQLBinaryOpExpr x) { + if (x.getLeft() instanceof SQLLiteralExpr && x.getRight() instanceof SQLLiteralExpr) { + print(x.getLeft().toString()); + print(' '); + print(x.getOperator().name); + print(' '); + print(x.getRight().toString()); + return false; + } + + x = merge(x); + + return super.visit(x); + } + public SQLBinaryOpExpr merge(SQLBinaryOpExpr x) { if (x.getRight() instanceof SQLLiteralExpr) { x = new SQLBinaryOpExpr(x.getLeft(), x.getOperator(), new SQLVariantRefExpr("?")); @@ -52,5 +88,25 @@ public class OracleParameterizedOutputVisitor extends OracleOutputVisitor { return x; } + + public boolean visit(SQLIntegerExpr x) { + print('?'); + return false; + } + + public boolean visit(SQLNumberExpr x) { + print('?'); + return false; + } + + public boolean visit(SQLCharExpr x) { + print('?'); + return false; + } + + public boolean visit(SQLNCharExpr x) { + print('?'); + return false; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java index 8470dd9f81..670a7694d1 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java @@ -25,6 +25,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalType; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OraclePriorExpr; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectOrderByItem; import com.alibaba.druid.sql.parser.Lexer; import com.alibaba.druid.sql.parser.ParserException; @@ -89,6 +90,13 @@ public class OracleExprParser extends SQLExprParser { } else { throw new ParserException("syntax error : " + lexer.token()); } + case PRIOR: + lexer.nextToken(); + primaryRest(new OraclePriorExpr(expr())); + case LITERAL_ALIAS: + String alias = '"' + lexer.stringVal() + '"'; + lexer.nextToken(); + return primaryRest(new SQLIdentifierExpr(alias)); default: return super.primary(); } @@ -157,7 +165,7 @@ public class OracleExprParser extends SQLExprParser { exprList(over.getPartitionBy()); accept(Token.RPAREN); } else { - over.getPartitionBy().add(expr()); + exprList(over.getPartitionBy()); } } @@ -240,14 +248,15 @@ public class OracleExprParser extends SQLExprParser { } if (identifierEquals("NULLS")) { - if (lexer.stringVal().equalsIgnoreCase("FIRST")) { + lexer.nextToken(); + if (identifierEquals("FIRST")) { lexer.nextToken(); item.setNullsOrderType(OracleSelectOrderByItem.NullsOrderType.NullsFirst); - } else if (lexer.stringVal().equalsIgnoreCase("LAST")) { + } else if (identifierEquals("LAST")) { lexer.nextToken(); item.setNullsOrderType(OracleSelectOrderByItem.NullsOrderType.NullsLast); } else { - throw new ParserException("TODO"); + throw new ParserException("TODO " + lexer.token()); } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java index f7dc0c0d61..2cd23590f2 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java @@ -22,6 +22,7 @@ import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; import com.alibaba.druid.sql.ast.statement.SQLTableSource; +import com.alibaba.druid.sql.ast.statement.SQLUnionOperator; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint; import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause; @@ -145,10 +146,13 @@ public class OracleSelectParser extends SQLSelectParser { if (lexer.token() == (Token.DISTINCT)) { queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT); + lexer.nextToken(); } else if (lexer.token() == (Token.UNIQUE)) { queryBlock.setDistionOption(SQLSetQuantifier.UNIQUE); + lexer.nextToken(); } else if (lexer.token() == (Token.ALL)) { queryBlock.setDistionOption(SQLSetQuantifier.ALL); + lexer.nextToken(); } parseSelectList(queryBlock); @@ -172,7 +176,7 @@ public class OracleSelectParser extends SQLSelectParser { lexer.nextToken(); if (lexer.token() == (Token.ALL)) { - union.setAll(true); + union.setOperator(SQLUnionOperator.UNION_ALL); lexer.nextToken(); } @@ -183,12 +187,32 @@ public class OracleSelectParser extends SQLSelectParser { return queryRest(union); } - if (lexer.token() == (Token.INTERSECT)) { - throw new ParserException("TODO"); + if (lexer.token() == Token.INTERSECT) { + lexer.nextToken(); + + SQLUnionQuery union = new SQLUnionQuery(); + union.setLeft(selectQuery); + + union.setOperator(SQLUnionOperator.INTERSECT); + + SQLSelectQuery right = this.query(); + union.setRight(right); + + return union; } - if (lexer.token() == (Token.MINUS)) { - throw new ParserException("TODO"); + if (lexer.token() == Token.MINUS) { + lexer.nextToken(); + + SQLUnionQuery union = new SQLUnionQuery(); + union.setLeft(selectQuery); + + union.setOperator(SQLUnionOperator.MINUS); + + SQLSelectQuery right = this.query(); + union.setRight(right); + + return union; } return selectQuery; @@ -233,11 +257,16 @@ public class OracleSelectParser extends SQLSelectParser { private void parseHierachical(OracleSelectQueryBlock queryBlock) { OracleSelectHierachicalQueryClause hierachical = null; - if (identifierEquals("CONNECT")) { + if (lexer.token() == Token.CONNECT) { hierachical = new OracleSelectHierachicalQueryClause(); lexer.nextToken(); accept(Token.BY); + if (lexer.token() == Token.PRIOR) { + lexer.nextToken(); + hierachical.setPrior(true); + } + if (identifierEquals("NOCYCLE")) { hierachical.setNoCycle(true); } @@ -283,13 +312,16 @@ public class OracleSelectParser extends SQLSelectParser { if (lexer.token() == (Token.LPAREN)) { lexer.nextToken(); OracleSelectSubqueryTableSource tableSource; - if (lexer.token() == (Token.SELECT)) tableSource = new OracleSelectSubqueryTableSource(select()); - else { - throw new ParserException("TODO"); + if (lexer.token() == Token.SELECT) { + tableSource = new OracleSelectSubqueryTableSource(select()); + } else if (lexer.token() == (Token.LPAREN)) { + tableSource = new OracleSelectSubqueryTableSource(select()); + } else { + throw new ParserException("TODO :" + lexer.token()); } accept(Token.RPAREN); - parsePivot(tableSource); + parsePivot((OracleSelectTableSource) tableSource); return parseTableSourceRest(tableSource); } @@ -442,7 +474,7 @@ public class OracleSelectParser extends SQLSelectParser { OracleSelectJoin.JoinType joinType = null; - if (identifierEquals("LEFT")) { + if (lexer.token() == Token.LEFT) { lexer.nextToken(); if (identifierEquals("OUTER")) { lexer.nextToken(); @@ -451,7 +483,7 @@ public class OracleSelectParser extends SQLSelectParser { joinType = OracleSelectJoin.JoinType.LEFT_OUTER_JOIN; } - if (identifierEquals("RIGHT")) { + if (lexer.token() == Token.RIGHT) { lexer.nextToken(); if (identifierEquals("OUTER")) { lexer.nextToken(); @@ -475,7 +507,7 @@ public class OracleSelectParser extends SQLSelectParser { joinType = OracleSelectJoin.JoinType.INNER_JOIN; } - if (lexer.token() == (Token.JOIN)) { + if (lexer.token() == Token.JOIN) { lexer.nextToken(); joinType = OracleSelectJoin.JoinType.JOIN; } @@ -491,7 +523,7 @@ public class OracleSelectParser extends SQLSelectParser { join.setJoinType(joinType); join.setRight(parseTableSource()); - if (identifierEquals("ON")) { + if (lexer.token() == Token.ON) { lexer.nextToken(); join.setCondition(this.createExprParser().expr()); } else if (identifierEquals("USING")) { 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 fddd364151..1296c7152c 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -446,6 +446,8 @@ public class Lexer { } private final void scanAlias() { + np = bp; + for (;;) { if (bp >= buflen) { lexError(tokenPos, "unclosed.str.lit"); @@ -457,7 +459,7 @@ public class Lexer { if (ch == '\"') { scanChar(); token = LITERAL_ALIAS; - return; + break; } if (sp == sbuf.length) { @@ -466,6 +468,8 @@ public class Lexer { sbuf[sp++] = ch; } } + + stringVal = new String(buf, np + 1, sp); } public void scanVariable() { @@ -480,6 +484,14 @@ public class Lexer { np = bp; sp = 1; char ch; + + if (buf[bp + 1] == '@') { + ch = buf[++bp]; + hash = 31 * hash + ch; + + sp++; + } + for (;;) { ch = buf[++bp]; @@ -522,6 +534,7 @@ public class Lexer { if (ch == '*' && buf[bp + 1] == '/') { sp += 2; scanChar(); + scanChar(); break; } 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 d3fc607221..e38370ef93 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -382,6 +382,14 @@ public class SQLExprParser extends SQLParser { sqlExpr = someExpr; break; + case KEY: + lexer.nextToken(); + sqlExpr = new SQLIdentifierExpr("KEY"); + break; + case DISTINCT: + lexer.nextToken(); + sqlExpr = new SQLIdentifierExpr("DISTINCT"); + break; case ALL: lexer.nextToken(); SQLAllExpr allExpr = new SQLAllExpr(); @@ -422,13 +430,18 @@ public class SQLExprParser extends SQLParser { lexer.nextToken(); expr = new SQLPropertyExpr(expr, "*"); } else { - if (lexer.token() != Token.IDENTIFIER) { - throw new ParserException("error"); + String name; + + if (lexer.token() == Token.KEY) { + name = "KEY"; + lexer.nextToken(); + } else if (lexer.token() != Token.IDENTIFIER) { + throw new ParserException("error : " + lexer.stringVal()); + } else { + name = lexer.stringVal(); + lexer.nextToken(); } - String name = lexer.stringVal(); - lexer.nextToken(); - if (lexer.token() == Token.LPAREN) { lexer.nextToken(); @@ -436,7 +449,12 @@ public class SQLExprParser extends SQLParser { if (lexer.token() == Token.RPAREN) { lexer.nextToken(); } else { - exprList(methodInvokeExpr.getParameters()); + if (lexer.token() == Token.PLUS) { + methodInvokeExpr.getParameters().add(new SQLIdentifierExpr("+")); + lexer.nextToken(); + } else { + exprList(methodInvokeExpr.getParameters()); + } accept(Token.RPAREN); } expr = methodInvokeExpr; @@ -521,14 +539,18 @@ public class SQLExprParser extends SQLParser { } public final SQLName name() throws ParserException { - if (lexer.token() != Token.IDENTIFIER) { + String identName; + if (lexer.token() == Token.LITERAL_ALIAS) { + identName = '"' + lexer.stringVal() + '"'; + lexer.nextToken(); + } else if (lexer.token() == Token.IDENTIFIER) { + identName = lexer.stringVal(); + + lexer.nextToken(); + } else { throw new ParserException("error"); } - String identName = lexer.stringVal(); - - lexer.nextToken(); - SQLName name = new SQLIdentifierExpr(identName); if (lexer.token() == Token.DOT) { @@ -770,13 +792,13 @@ public class SQLExprParser extends SQLParser { public final SQLExpr orRest(SQLExpr expr) throws ParserException { if (lexer.token() == Token.OR) { lexer.nextToken(); - SQLExpr rightExp = relational(); + SQLExpr rightExp = and(); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanOr, rightExp); expr = orRest(expr); } else if (lexer.token() == Token.XOR) { lexer.nextToken(); - SQLExpr rightExp = relational(); + SQLExpr rightExp = and(); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanXor, rightExp); expr = orRest(expr); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java index 806d8afe11..586d1fbf38 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java @@ -41,35 +41,45 @@ public class SQLParser { } } - protected final String as() throws ParserException { - String rtnValue = null; + protected String as() throws ParserException { + String alias = null; if (lexer.token() == Token.AS) { lexer.nextToken(); if (lexer.token() == Token.LITERAL_ALIAS) { - rtnValue = lexer.stringVal(); + alias = '"' + lexer.stringVal() + '"'; lexer.nextToken(); - return rtnValue; + return alias; } if (lexer.token() == Token.IDENTIFIER) { - rtnValue = lexer.stringVal(); + alias = lexer.stringVal(); lexer.nextToken(); - return rtnValue; + return alias; + } + + if (lexer.token() == Token.KEY) { + lexer.nextToken(); + alias = "KEY"; + return alias; } throw new ParserException("Error", 0, 0); } if (lexer.token() == Token.LITERAL_ALIAS) { - rtnValue = lexer.stringVal(); + alias = '"' + lexer.stringVal() + '"'; lexer.nextToken(); } else if (lexer.token() == Token.IDENTIFIER) { - rtnValue = lexer.stringVal(); + alias = lexer.stringVal(); lexer.nextToken(); + } else if (lexer.token() == Token.KEY) { + lexer.nextToken(); + alias = "KEY"; + return alias; } - return rtnValue; + return alias; } public void accept(Token token) { diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java index 121b445636..014a178d02 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java @@ -18,15 +18,16 @@ package com.alibaba.druid.sql.parser; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLOrderBy; import com.alibaba.druid.sql.ast.SQLSetQuantifier; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; -import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; -import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableSource; +import com.alibaba.druid.sql.ast.statement.SQLUnionOperator; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; public class SQLSelectParser extends SQLParser { @@ -60,7 +61,7 @@ public class SQLSelectParser extends SQLParser { union.setLeft(selectQuery); if (lexer.token() == Token.ALL) { - union.setAll(true); + union.setOperator(SQLUnionOperator.UNION_ALL); lexer.nextToken(); } @@ -71,11 +72,31 @@ public class SQLSelectParser extends SQLParser { } if (lexer.token() == Token.INTERSECT) { - throw new ParserException("TODO"); + lexer.nextToken(); + + SQLUnionQuery union = new SQLUnionQuery(); + union.setLeft(selectQuery); + + union.setOperator(SQLUnionOperator.INTERSECT); + + SQLSelectQuery right = this.query(); + union.setRight(right); + + return union; } if (lexer.token() == Token.MINUS) { - throw new ParserException("TODO"); + lexer.nextToken(); + + SQLUnionQuery union = new SQLUnionQuery(); + union.setLeft(selectQuery); + + union.setOperator(SQLUnionOperator.MINUS); + + SQLSelectQuery right = this.query(); + union.setRight(right); + + return union; } return selectQuery; @@ -174,15 +195,17 @@ public class SQLSelectParser extends SQLParser { lexer.nextToken(); SQLTableSource tableSource; if (lexer.token() == Token.SELECT) { - tableSource = new SQLSubqueryTableSource(select()); + SQLSelect select = select(); + accept(Token.RPAREN); + queryRest(select.getQuery()); + tableSource = new SQLSubqueryTableSource(select); } else if (lexer.token() == Token.LPAREN) { tableSource = parseTableSource(); + accept(Token.RPAREN); } else { throw new ParserException("TODO"); } - accept(Token.RPAREN); - return parseTableSourceRest(tableSource); } @@ -258,6 +281,10 @@ public class SQLSelectParser extends SQLParser { return parseTableSourceRest(join); } + if (lexer.token() == Token.UNION) { + throw new SQLParseException("TODO"); + } + return tableSource; } 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 29b096cda4..8407f38101 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -138,6 +138,11 @@ public class SQLStatementParser extends SQLParser { SQLName tableName = this.exprParser.name(); insertStatement.setTableName(tableName); + + if (lexer.token() == Token.IDENTIFIER) { + insertStatement.setAlias(lexer.stringVal()); + lexer.nextToken(); + } if (lexer.token() == (Token.LPAREN)) { lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/parser/Token.java b/src/main/java/com/alibaba/druid/sql/parser/Token.java index 9c7cdf3622..88d201de4c 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -96,6 +96,7 @@ public enum Token { // mysql TRUE("TRUE"), FALSE("FALSE"), + LIMIT("LIMIT"), // oracle START("START"), 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 f519dd74fe..105cffe1db 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -70,6 +70,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLSetStatement; +import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableElement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUniqueConstraint; @@ -664,10 +665,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { public boolean visit(SQLUnionQuery x) { x.getLeft().accept(this); println(); - print("UNION"); - if (x.isAll()) { - print(" ALL"); - } + print(x.getOperator().name); println(); x.getRight().accept(this); return false; @@ -817,4 +815,15 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { return false; } + + @Override + public boolean visit(SQLSubqueryTableSource x) { + print("("); + incrementIndent(); + x.getSelect().accept(this); + decrementIndent(); + print(")"); + + return false; + } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java index 7986c698c1..2d1c584d31 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java @@ -68,6 +68,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLSetStatement; +import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableElement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUniqueConstraint; @@ -324,4 +325,8 @@ public interface SQLASTVisitor { void endVisit(SQLListExpr x); boolean visit(SQLListExpr x); + + void endVisit(SQLSubqueryTableSource x); + + boolean visit(SQLSubqueryTableSource x); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java index 59a7d29f73..a90d685c8b 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java @@ -69,6 +69,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLSetStatement; +import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableElement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUniqueConstraint; @@ -550,6 +551,16 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { @Override public boolean visit(SQLListExpr x) { - return false; + return true; + } + + @Override + public void endVisit(SQLSubqueryTableSource x) { + + } + + @Override + public boolean visit(SQLSubqueryTableSource x) { + return true; } } diff --git a/src/test/java/com/alibaba/druid/sql/OnlineSQLTest.java b/src/test/java/com/alibaba/druid/sql/OnlineSQLTest.java index 76729b30e7..6b3ebdf3a1 100644 --- a/src/test/java/com/alibaba/druid/sql/OnlineSQLTest.java +++ b/src/test/java/com/alibaba/druid/sql/OnlineSQLTest.java @@ -14,6 +14,8 @@ import junit.framework.TestCase; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlParameterizedOutputVisitor; +import com.alibaba.druid.sql.dialect.oracle.ast.visitor.OracleParameterizedOutputVisitor; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; public class OnlineSQLTest extends TestCase { @@ -22,22 +24,50 @@ public class OnlineSQLTest extends TestCase { private String password = "dragoon"; public void test_list_sql() throws Exception { - //reset(); + // reset(); + + // 这些中文括号 + //update(7216, "", 4); + //update(7223, "", 4); + //update(8387, "", 4); + + // 语法错误 +// update(17018, "", 4); //alarm_type&? +// update(17841, "", 4); //alarm_type&? +// update(17845, "", 4); //alarm_type&? +// update(18247, "", 4); //alarm_type&? +// update(19469, "", 4); //alarm_type&? + update(19730, "", 4); //alarm_type&? + update(20164, "", 4); //alarm_type&? + update(20386, "", 4); //alarm_type&? + update(20440, "", 4); //alarm_type&? + update(21208, "", 4); //alarm_type&? + + // IBATIS NAME + update(18035, "", 4); //alarm_type&? + Connection conn = DriverManager.getConnection(url, user, password); int count = 0; - String sql = "SELECT id, value FROM m_sql_const WHERE flag IS NULL LIMIT 1"; + String sql = "SELECT id, value FROM m_sql_const WHERE flag IS NULL LIMIT 100"; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { int id = rs.getInt(1); String value = rs.getString(2); + + if (value.indexOf('(') != -1) { + update(id, "", 4); + continue; + } + System.out.println(value); System.out.println(); try { - validate(id, value); + validateOracle(id, value); } catch (Exception e) { e.printStackTrace(); + System.out.println("id : " + id); continue; } count++; @@ -49,7 +79,7 @@ public class OnlineSQLTest extends TestCase { conn.close(); } - + void reset() throws SQLException { Connection conn = DriverManager.getConnection(url, user, password); @@ -61,13 +91,14 @@ public class OnlineSQLTest extends TestCase { conn.close(); } - void update(int id, String value2) throws SQLException { + void update(int id, String value2, int flag) throws SQLException { Connection conn = DriverManager.getConnection(url, user, password); - String sql = "UPDATE m_sql_const SET flag = 1, value2 = ? WHERE id = ?"; + String sql = "UPDATE m_sql_const SET flag = ?, value2 = ? WHERE id = ?"; PreparedStatement stmt = conn.prepareStatement(sql); - stmt.setString(1, value2); - stmt.setInt(2, id); + stmt.setInt(1, flag); + stmt.setString(2, value2); + stmt.setInt(3, id); stmt.executeUpdate(); stmt.close(); @@ -78,31 +109,57 @@ public class OnlineSQLTest extends TestCase { sql = sql.trim(); boolean sqlFlag = false; String lowerSql = sql.toLowerCase(); - if (lowerSql.startsWith("insert") || lowerSql.startsWith("select") || lowerSql.startsWith("upate") || lowerSql.startsWith("delete") || lowerSql.startsWith("create") || lowerSql.startsWith("drop")) { + if (lowerSql.startsWith("insert") || lowerSql.startsWith("select") || lowerSql.startsWith("upate") || lowerSql.startsWith("delete") + || lowerSql.startsWith("create") || lowerSql.startsWith("drop")) { sqlFlag = true; } - + if (!sqlFlag) { - update(id, sql); + update(id, sql, 2); return; } - try { - MySqlStatementParser parser = new MySqlStatementParser(sql); - List statementList = parser.parseStatementList(); - SQLStatement statemen = statementList.get(0); + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); - Assert.assertEquals(1, statementList.size()); + Assert.assertEquals(1, statementList.size()); - StringBuilder out = new StringBuilder(); - MySqlParameterizedOutputVisitor visitor = new MySqlParameterizedOutputVisitor(out); - statemen.accept(visitor); + StringBuilder out = new StringBuilder(); + MySqlParameterizedOutputVisitor visitor = new MySqlParameterizedOutputVisitor(out); + statemen.accept(visitor); - update(id, out.toString()); - System.out.println(sql); - System.out.println(out.toString()); - } catch (Exception e) { - throw e; + update(id, out.toString(), 1); + System.out.println(sql); + System.out.println(out.toString()); + } + + void validateOracle(int id, String sql) throws Exception { + sql = sql.trim(); + boolean sqlFlag = false; + String lowerSql = sql.toLowerCase(); + if (lowerSql.startsWith("insert") || lowerSql.startsWith("select") || lowerSql.startsWith("upate") || lowerSql.startsWith("delete") + || lowerSql.startsWith("create") || lowerSql.startsWith("drop")) { + sqlFlag = true; } + + if (!sqlFlag) { + update(id, sql, 2); + return; + } + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + + StringBuilder out = new StringBuilder(); + OracleParameterizedOutputVisitor visitor = new OracleParameterizedOutputVisitor(out); + statemen.accept(visitor); + + update(id, out.toString(), 1); + System.out.println(sql); + System.out.println(out.toString()); } } diff --git a/src/test/java/com/alibaba/druid/sql/mysql/bvt/parser/MySqlParserResourceTest.java b/src/test/java/com/alibaba/druid/sql/mysql/bvt/parser/MySqlParserResourceTest.java index 989c116669..213877d54e 100644 --- a/src/test/java/com/alibaba/druid/sql/mysql/bvt/parser/MySqlParserResourceTest.java +++ b/src/test/java/com/alibaba/druid/sql/mysql/bvt/parser/MySqlParserResourceTest.java @@ -16,7 +16,15 @@ import com.alibaba.druid.util.JdbcUtils; public class MySqlParserResourceTest extends TestCase { public void test_0() throws Exception { - exec_test("bvt/parser/mysql-0.txt"); +// exec_test("bvt/parser/mysql-0.txt"); +// exec_test("bvt/parser/mysql-1.txt"); +// exec_test("bvt/parser/mysql-2.txt"); +// exec_test("bvt/parser/mysql-3.txt"); +// exec_test("bvt/parser/mysql-4.txt"); +// exec_test("bvt/parser/mysql-5.txt"); +// exec_test("bvt/parser/mysql-6.txt"); +// exec_test("bvt/parser/mysql-7.txt"); + exec_test("bvt/parser/mysql-8.txt"); } diff --git a/src/test/java/com/alibaba/druid/sql/oracle/bvt/OracleSQLParserResourceTest.java b/src/test/java/com/alibaba/druid/sql/oracle/bvt/OracleSQLParserResourceTest.java index 0d7fbc125d..c2a827d19e 100644 --- a/src/test/java/com/alibaba/druid/sql/oracle/bvt/OracleSQLParserResourceTest.java +++ b/src/test/java/com/alibaba/druid/sql/oracle/bvt/OracleSQLParserResourceTest.java @@ -16,21 +16,35 @@ import com.alibaba.druid.util.JdbcUtils; public class OracleSQLParserResourceTest extends TestCase { public void test_0() throws Exception { - exec_test("bvt/parser/oracle-0.txt"); - exec_test("bvt/parser/oracle-1.txt"); - exec_test("bvt/parser/oracle-2.txt"); - exec_test("bvt/parser/oracle-3.txt"); - exec_test("bvt/parser/oracle-4.txt"); - exec_test("bvt/parser/oracle-5.txt"); - exec_test("bvt/parser/oracle-6.txt"); // PARTITION - exec_test("bvt/parser/oracle-7.txt"); - exec_test("bvt/parser/oracle-8.txt"); - exec_test("bvt/parser/oracle-9.txt"); - exec_test("bvt/parser/oracle-10.txt"); - exec_test("bvt/parser/oracle-11.txt"); - exec_test("bvt/parser/oracle-12.txt"); - exec_test("bvt/parser/oracle-13.txt"); - exec_test("bvt/parser/oracle-14.txt"); +// exec_test("bvt/parser/oracle-0.txt"); +// exec_test("bvt/parser/oracle-1.txt"); +// exec_test("bvt/parser/oracle-2.txt"); +// exec_test("bvt/parser/oracle-3.txt"); +// exec_test("bvt/parser/oracle-4.txt"); +// exec_test("bvt/parser/oracle-5.txt"); +// exec_test("bvt/parser/oracle-6.txt"); // PARTITION +// exec_test("bvt/parser/oracle-7.txt"); +// exec_test("bvt/parser/oracle-8.txt"); +// exec_test("bvt/parser/oracle-9.txt"); +// exec_test("bvt/parser/oracle-10.txt"); +// exec_test("bvt/parser/oracle-11.txt"); +// exec_test("bvt/parser/oracle-12.txt"); +// exec_test("bvt/parser/oracle-13.txt"); +// exec_test("bvt/parser/oracle-14.txt"); +// exec_test("bvt/parser/oracle-15.txt"); +// exec_test("bvt/parser/oracle-16.txt"); +// exec_test("bvt/parser/oracle-17.txt"); +// exec_test("bvt/parser/oracle-18.txt"); +// exec_test("bvt/parser/oracle-19.txt"); +// exec_test("bvt/parser/oracle-20.txt"); +// exec_test("bvt/parser/oracle-21.txt"); +// exec_test("bvt/parser/oracle-22.txt"); +// exec_test("bvt/parser/oracle-23.txt"); +// exec_test("bvt/parser/oracle-24.txt"); +// exec_test("bvt/parser/oracle-25.txt"); +// exec_test("bvt/parser/oracle-26.txt"); +// exec_test("bvt/parser/oracle-27.txt"); + exec_test("bvt/parser/oracle-28.txt"); } diff --git a/src/test/resources/bvt/parser/mysql-1.txt b/src/test/resources/bvt/parser/mysql-1.txt new file mode 100644 index 0000000000..48599d8a7c --- /dev/null +++ b/src/test/resources/bvt/parser/mysql-1.txt @@ -0,0 +1,14 @@ + SELECT id, item_type 'itemType', item_id 'itemId', item_name 'itemName', app_id 'appId' + , sequence, refresh_intv "refreshIntv" + FROM view_portal_info + WHERE 1=1 + AND item_type = ? + AND app_id = ? + ORDER BY sequence desc + LIMIT ?, ? +--------------------------- +SELECT id, item_type AS 'itemType', item_id AS 'itemId', item_name AS 'itemName', app_id AS 'appId', sequence, refresh_intv AS refresh_intv +FROM view_portal_info +WHERE 1 = 1 AND item_type = ? AND app_id = ? +ORDER BY sequence DESC +LIMIT ?, ? \ No newline at end of file diff --git a/src/test/resources/bvt/parser/mysql-2.txt b/src/test/resources/bvt/parser/mysql-2.txt new file mode 100644 index 0000000000..86cc049ecc --- /dev/null +++ b/src/test/resources/bvt/parser/mysql-2.txt @@ -0,0 +1,9 @@ + SELECT id "id", username "username", password "password", name "name", staff_num "staffNumber", + wangwang "wangwang", email "email", mobile "mobile", + is_deleted "isDeleted", is_admin "isAdmin", gmt_create "gmtCreate" + FROM sys_user + LIMIT ?, ? +--------------------------- + SELECT id AS id, username AS username, password AS password, name AS name, staff_num AS staff_num, wangwang AS wangwang, email AS email, mobile AS mobile, is_deleted AS is_deleted, is_admin AS is_admin, gmt_create AS gmt_create +FROM sys_user +LIMIT ?, ? \ No newline at end of file diff --git a/src/test/resources/bvt/parser/mysql-3.txt b/src/test/resources/bvt/parser/mysql-3.txt new file mode 100644 index 0000000000..0dc19860db --- /dev/null +++ b/src/test/resources/bvt/parser/mysql-3.txt @@ -0,0 +1,11 @@ +SELECT COUNT(*) FROM (SELECT COUNT(*) FROM m_web_uri_m5 +WHERE monitor_item_id = ? AND app_num = ? AND inst_num = ? AND service_tag = ? AND monitor_item_id = ? +AND collect_date >= ? AND collect_date < ? +AND (1=0 OR c_URI in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83)) +GROUP BY c_URI) A +--------------------------- +SELECT COUNT(*) +FROM (SELECT COUNT(*) + FROM m_web_uri_m5 + WHERE monitor_item_id = ? AND app_num = ? AND inst_num = ? AND service_tag = ? AND monitor_item_id = ? AND collect_date >= ? AND collect_date < ? AND (1 = 0 OR c_URI IN (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83)) + GROUP BY c_URI) \ No newline at end of file diff --git a/src/test/resources/bvt/parser/mysql-4.txt b/src/test/resources/bvt/parser/mysql-4.txt new file mode 100644 index 0000000000..e399a83dee --- /dev/null +++ b/src/test/resources/bvt/parser/mysql-4.txt @@ -0,0 +1,9 @@ + select s.*,d.* + from server s + left join device_base d on s.device_base_id= d.id + left join logic_site l on l.id = d.logic_site_id + where s.gmt_modify > ? and l.site_name = "开发测试" +--------------------------- +SELECT s.*, d.* +FROM server s LEFT JOIN device_base d ON s.device_base_id = d.id LEFT JOIN logic_site l ON l.id = d.logic_site_id +WHERE s.gmt_modify > ? AND l.site_name = '开发测试' \ No newline at end of file diff --git a/src/test/resources/bvt/parser/mysql-5.txt b/src/test/resources/bvt/parser/mysql-5.txt new file mode 100644 index 0000000000..9cebcdf1be --- /dev/null +++ b/src/test/resources/bvt/parser/mysql-5.txt @@ -0,0 +1,14 @@ +SELECT /*+ use_hash(a b e) index(e)*/Count(*) +FROM q_matchrelation a,q_offerdetail b,q_keyword e , Q_ADCREATIVE f +WHERE a.offerid=b.offerid + AND a.keywordid = e.keywordid + AND a.offerid=f.offerid + AND a.issuspect='1' +ORDER BY e.word_alias,a.createtime DESC + + +--------------------------- +SELECT Count(*) +FROM q_matchrelation a , q_offerdetail b , q_keyword e , Q_ADCREATIVE f +WHERE a.offerid = b.offerid AND a.keywordid = e.keywordid AND a.offerid = f.offerid AND a.issuspect = '1' +ORDER BY e.word_alias, a.createtime DESC \ No newline at end of file diff --git a/src/test/resources/bvt/parser/mysql-6.txt b/src/test/resources/bvt/parser/mysql-6.txt new file mode 100644 index 0000000000..8f40785301 --- /dev/null +++ b/src/test/resources/bvt/parser/mysql-6.txt @@ -0,0 +1,43 @@ +select count(*) +from ( + (select a.activity_offer_id adResourceId, + a.title adResourceName, + a.b2boffer_url adResourceURL, + a.custid, + b.memberid, + c.position_name positionName, + c.charge_setting feeRegulation, + a.priority_weight priorityWeight, + a.audit_state adResourceState, + 0 adResourceType, + a.gmt_create, + a.refuse_remark + from q_activity_offer_enroll a,q_custinfo b,q_activity_position c + where a.custid = b.custid + and a.activity_position_id = c.activity_position_id + and c.activity_id = ?) + union all + (select a.reg_position_id adResourceId, + b.custname adResourceName, + null adResourceURL, + a.custid, + b.memberid, + c.position_name positionName, + c.charge_setting feeRegulation, + null priorityWeight, + a.audit_state adResourceState, + 1 adResourceType, + a.gmt_create, a.refuse_remark + from q_activity_custom_enroll a,q_custinfo b,q_activity_position c + where a.custid = b.custid + and a.activity_position_id = c.activity_position_id + and c.activity_id = ?)) a + + + + +--------------------------- +SELECT count(*) +FROM (SELECT a.activity_offer_id AS adResourceId, a.title AS adResourceName, a.b2boffer_url AS adResourceURL, a.custid, b.memberid, c.position_name AS positionName, c.charge_setting AS feeRegulation, a.priority_weight AS priorityWeight, a.audit_state AS adResourceState, 0 AS adResourceType, a.gmt_create, a.refuse_remark + FROM q_activity_offer_enroll a , q_custinfo b , q_activity_position c + WHERE a.custid = b.custid AND a.activity_position_id = c.activity_position_id AND c.activity_id = ?) \ No newline at end of file diff --git a/src/test/resources/bvt/parser/mysql-7.txt b/src/test/resources/bvt/parser/mysql-7.txt new file mode 100644 index 0000000000..d019c0eb68 --- /dev/null +++ b/src/test/resources/bvt/parser/mysql-7.txt @@ -0,0 +1,13 @@ +insert into accontexchangeinfo a + (a.id,a.sourceid,a.batchno,a.applicant,a.out_uid,a.in_uid,a.moneytype,a.amount,a.remark,a.gmt_create,a.gmt_modified) + values +( + SEQ_ACCONTEXCHANGEINFO.nextval,?,?,?,?,?,?,?,?,SYSDATE,SYSDATE) + + + + + +--------------------------- +INSERT INTO accontexchangeinfo (a.id, a.sourceid, a.batchno, a.applicant, a.out_uid, a.in_uid, a.moneytype, a.amount, a.remark, a.gmt_create, a.gmt_modified) VALUES (SEQ_ACCONTEXCHANGEINFO.nextval, ?, ?, ?, ?, ?, ?, ?, ?, SYSDATE, SYSDATE) + diff --git a/src/test/resources/bvt/parser/mysql-8.txt b/src/test/resources/bvt/parser/mysql-8.txt new file mode 100644 index 0000000000..0af1c567fe --- /dev/null +++ b/src/test/resources/bvt/parser/mysql-8.txt @@ -0,0 +1,20 @@ +SELECT a.examine_id examineId,a.examine_name examineName,a.level_limit levelLimit +FROM c_examinepaper a, + (SELECT examine_id FROM c_examinepaper WHERE level_limit=? AND status=1 + MINUS + SELECT DISTINCT examine_id FROM course) b +WHERE a.examine_id = b.examine_id + + + + + +--------------------------- +SELECT a.examine_id AS examineId, a.examine_name AS examineName, a.level_limit AS levelLimit +FROM c_examinepaper a , (SELECT examine_id + FROM c_examinepaper + WHERE level_limit = ? AND status = 1 + MINUS + SELECT DISTINCT examine_id + FROM course) +WHERE a.examine_id = b.examine_id diff --git a/src/test/resources/bvt/parser/mysql-9.txt b/src/test/resources/bvt/parser/mysql-9.txt new file mode 100644 index 0000000000..6aaf8a103c --- /dev/null +++ b/src/test/resources/bvt/parser/mysql-9.txt @@ -0,0 +1,42 @@ +SELECT * +FROM + (SELECT + records.*, + rownum as row_num + FROM + ( SELECT + re.exchange_record_id as recordId, + re.GOODS_TITLE as goodsTitle, + re.GOODS_ATTRIBUTE as goodsAttribute, + re.GOODS_USAGE as goodsUsage, + re.goods_Id as goodsId, + re.EXPRESS_company as expressCompany, + re.EXPRESS_number as expressNumber, + re.cost_score as costScore, + re.exchange_Status as exchangeStatus, + re.remark as remark, + re.receiver_Name as receiverName, + re.receiver_Address as receiverAddress, + re.receiver_post_code as receiverPostCode, + re.receiver_mobile_phon as receiverMobilePhone, + re.receiver_phone_numer as receiverPhoneNumber, + re.change_date as createDate, accoun.memberid as memberId + FROM JF_EXCHANGE_RECORD re, Q_CUSTINFO accoun + WHERE re.custId = accoun.custId(+) + AND re.exchange_Status = ? + AND (re.goods_Attribute = ? ) + AND re.change_Date >= to_date(? || ' 00:00:00', 'yyyy-mm-dd hh24:mi:ss') + AND re.change_Date <= to_date(? || ' 23:59:59', 'yyyy-mm-dd hh24:mi:ss') + ORDER BY re.exchange_record_id DESC )records + WHERE rownum < ? ) + WHERE row_num > ? + +--------------------------- +SELECT a.examine_id AS examineId, a.examine_name AS examineName, a.level_limit AS levelLimit +FROM c_examinepaper a , (SELECT examine_id + FROM c_examinepaper + WHERE level_limit = ? AND status = 1 + MINUS + SELECT DISTINCT examine_id + FROM course) +WHERE a.examine_id = b.examine_id diff --git a/src/test/resources/bvt/parser/oracle-13.txt b/src/test/resources/bvt/parser/oracle-13.txt index a9f43ca08b..b173206850 100644 --- a/src/test/resources/bvt/parser/oracle-13.txt +++ b/src/test/resources/bvt/parser/oracle-13.txt @@ -7,7 +7,7 @@ SELECT DECODE(GROUPING(department_name), 1, 'All Departments', GROUP BY CUBE (department_name, job_id) ORDER BY department_name, job_id; --------------------------- -SELECT DECODE(GROUPING(department_name), 1, 'All Departments', department_name) AS department_name, DECODE(GROUPING(job_id), 1, 'All Jobs', job_id) AS job_id, COUNT(*) AS COUNT, AVG(salary) * 12 AS salary +SELECT DECODE(GROUPING(department_name), 1, 'All Departments', department_name) AS department_name, DECODE(GROUPING(job_id), 1, 'All Jobs', job_id) AS job_id, COUNT(*) AS "Total Empl", AVG(salary) * 12 AS "Average Sal" FROM employees e , departments d WHERE d.department_id = e.department_id GROUP BY CUBE(department_name, job_id) diff --git a/src/test/resources/bvt/parser/oracle-15.txt b/src/test/resources/bvt/parser/oracle-15.txt new file mode 100644 index 0000000000..919de2e886 --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-15.txt @@ -0,0 +1,35 @@ +SELECT * +FROM (SELECT A.*, rownum cnt + FROM (SELECT + A.CUSTID,A.PAYCOUNT, A.MEMBERID,A.ACCREDITSTATUS,C.CUSTNAME, C.CONTNAME, C.CONTPHONECITYCODE, + C.CONTPHONE, C.CONTMOBPHONE, C.CONTFAXCITYCODE, C.CONTFAX, C.CONTEMAIL, + C.CUSTAREA AS AREANAME, C.CUSTADDR, C.ORGINDUSTRY AS ORGINDUSTRYNAME, + E.DESCRIPTION AS CUSTSTATNAME, F.DESCRIPTION AS B2BCUSTTYPENAME, + null AS CUSTSERVICERNAME, G.DESCRIPTION AS B2BVALIDFLAGNAME, A.VALIDFLAG + FROM Q_CUSTOMERS A, Q_CUSTINFO C, + (SELECT * FROM Q_DOMAINCDSTRING WHERE DOMAINCD = 'CUSTOMERS_CUSTSTAT') E, + (SELECT * FROM Q_DOMAINCDSTRING WHERE DOMAINCD = 'CUSTOMERS_B2BCUSTTYPE') F, + (SELECT * FROM Q_DOMAINCDSTRING WHERE DOMAINCD = 'CUSTOMERS_B2BVALIDFLAG') G + WHERE + A.CUSTID = C.CUSTID + AND A.CUSTSTAT = E.CODE( + ) + AND A.B2BCUSTTYPE = F.CODE( + ) + AND A.b2bValidFlag = G.CODE( + ) + AND A.MEMBERID = ? + ORDER BY A.CUSTID DESC) A +WHERE ROWNUM < ?) WHERE CNT > ? +--------------------------- +SELECT * +FROM (SELECT A.*, rownum AS cnt + FROM (SELECT A.CUSTID, A.PAYCOUNT, A.MEMBERID, A.ACCREDITSTATUS, C.CUSTNAME, C.CONTNAME, C.CONTPHONECITYCODE, C.CONTPHONE, C.CONTMOBPHONE, C.CONTFAXCITYCODE, C.CONTFAX, C.CONTEMAIL, C.CUSTAREA AS AREANAME, C.CUSTADDR, C.ORGINDUSTRY AS ORGINDUSTRYNAME, E.DESCRIPTION AS CUSTSTATNAME, F.DESCRIPTION AS B2BCUSTTYPENAME, NULL AS CUSTSERVICERNAME, G.DESCRIPTION AS B2BVALIDFLAGNAME, A.VALIDFLAG + FROM Q_CUSTOMERS A , Q_CUSTINFO C , (SELECT * + FROM Q_DOMAINCDSTRING + WHERE DOMAINCD = 'CUSTOMERS_CUSTSTAT') E , (SELECT * + FROM Q_DOMAINCDSTRING + WHERE DOMAINCD = 'CUSTOMERS_B2BCUSTTYPE') F , (SELECT * + FROM Q_DOMAINCDSTRING + WHERE DOMAINCD = 'CUSTOMERS_B2BVALIDFLAG') G + WHERE A.CUSTID = C.CUSTID AND A.CUSTSTAT = CODE(+) AND A.B2BCUSTTYPE = CODE(+) AND A.b2bValidFlag = CODE(+) AND A.MEMBERID = ? + ORDER BY A.CUSTID DESC) A + WHERE ROWNUM < ?) +WHERE CNT > ?; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-16.txt b/src/test/resources/bvt/parser/oracle-16.txt new file mode 100644 index 0000000000..25e8909bee --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-16.txt @@ -0,0 +1,19 @@ +SELECT ID,CLASSTYPE,KEY,VALUE +FROM + (SELECT A.*,ROWNUM CNT FROM(SELECT ID,CLASSTYPE,KEY,VALUE + FROM Q_SYSCONSTANTS + WHERE CLASSTYPE = ? + ORDER BY ID DESC) A +WHERE ROWNUM < ? +) +WHERE CNT > ? + +--------------------------- +SELECT ID, CLASSTYPE, KEY, VALUE +FROM (SELECT A.*, ROWNUM AS CNT + FROM (SELECT ID, CLASSTYPE, KEY, VALUE + FROM Q_SYSCONSTANTS + WHERE CLASSTYPE = ? + ORDER BY ID DESC) A + WHERE ROWNUM < ?) +WHERE CNT > ?; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-17.txt b/src/test/resources/bvt/parser/oracle-17.txt new file mode 100644 index 0000000000..2e9aae6bee --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-17.txt @@ -0,0 +1,31 @@ +select custid,memberid, + to_char(createtime,'yyyy-mm-dd hh24:mi:ss') createtime , + planid,auditstate,to_char(modifytime,'yyyy-mm-dd hh24:mi:ss') modifytime,createid , + to_char(custappdate,'yyyy-mm-dd hh24:mi:ss') custappdate,executeState,gmtcreate,custname,planbatchid +from( + select custid,memberid,createtime,planid,auditstate,createid ,custappdate,executeState,custname,gmtcreate ,cnt,planbatchid ,modifytime + from( + select p.custid,p.memberid,p.createtime,p.planid,p.auditstate,p.createid ,p.custappdate,p.modifytime,p.gmtcreate,p.executeState, + c.custname,row_number() over(order by p.memberid asc ,p.createtime DESC ) cnt,p.planbatchid + from q_plan p ,q_custinfo c + where p.custid=c.custid + AND p.applytype = 0 + AND p.createtime BETWEEN to_date(?,'yyyy-mm-dd') + AND to_date(?,'yyyy-mm-dd hh24:mi:ss') + AND (p.auditstate = ? and p.executestate = 1) + AND auditstate != 3 + AND p.memberid in (?) + )t + WHERE t.cnt < ? )k +WHERE k.cnt > ? +ORDER BY memberid ASC, createtime DESC + +--------------------------- +SELECT custid, memberid, to_char(createtime, 'yyyy-mm-dd hh24:mi:ss') AS createtime, planid, auditstate, to_char(modifytime, 'yyyy-mm-dd hh24:mi:ss') AS modifytime, createid, to_char(custappdate, 'yyyy-mm-dd hh24:mi:ss') AS custappdate, executeState, gmtcreate, custname, planbatchid +FROM (SELECT custid, memberid, createtime, planid, auditstate, createid, custappdate, executeState, custname, gmtcreate, cnt, planbatchid, modifytime + FROM (SELECT p.custid, p.memberid, p.createtime, p.planid, p.auditstate, p.createid, p.custappdate, p.modifytime, p.gmtcreate, p.executeState, c.custname, row_number() OVER ( ORDER BY p.memberid ASC, p.createtime DESC) AS cnt, p.planbatchid + FROM q_plan p , q_custinfo c + WHERE p.custid = c.custid AND p.applytype = 0 AND p.createtime BETWEEN to_date(?, 'yyyy-mm-dd') AND to_date(?, 'yyyy-mm-dd hh24:mi:ss') AND (p.auditstate = ? AND p.executestate = 1) AND auditstate != 3 AND p.memberid IN (?)) t + WHERE t.cnt < ?) k +WHERE k.cnt > ? +ORDER BY memberid ASC, createtime DESC; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-18.txt b/src/test/resources/bvt/parser/oracle-18.txt new file mode 100644 index 0000000000..7b50e14779 --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-18.txt @@ -0,0 +1,14 @@ +SELECT /*+ use_hash(a b e) index(e)*/Count(*) +FROM q_matchrelation a,q_offerdetail b,q_keyword e , Q_ADCREATIVE f +WHERE a.offerid=b.offerid + AND a.keywordid = e.keywordid + AND a.offerid=f.offerid + AND a.issuspect='1' +ORDER BY e.word_alias,a.createtime DESC + + +--------------------------- +SELECT /*+use_hash(a b e) index(e)*/ Count(*) +FROM q_matchrelation a , q_offerdetail b , q_keyword e , Q_ADCREATIVE f +WHERE a.offerid = b.offerid AND a.keywordid = e.keywordid AND a.offerid = f.offerid AND a.issuspect = '1' +ORDER BY e.word_alias, a.createtime DESC; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-19.txt b/src/test/resources/bvt/parser/oracle-19.txt new file mode 100644 index 0000000000..c0683488ef --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-19.txt @@ -0,0 +1,20 @@ +select * +from ( + select rownum rnm, z.* + from ( + select name as value,value as key + from app_resource_cae + where is_deleted='n' and type='fuse' order by ordering + ) z +where rownum < ? ) where rnm >= ? + + +--------------------------- +SELECT * +FROM (SELECT rownum AS rnm, z.* + FROM (SELECT name AS value, value AS KEY + FROM app_resource_cae + WHERE is_deleted = 'n' AND type = 'fuse' + ORDER BY ordering) z + WHERE rownum < ?) +WHERE rnm >= ?; diff --git a/src/test/resources/bvt/parser/oracle-20.txt b/src/test/resources/bvt/parser/oracle-20.txt new file mode 100644 index 0000000000..25dbb501d1 --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-20.txt @@ -0,0 +1,16 @@ + SELECT RC_CLOT_INFO_EXT.*, RC_CLOT_TRUNK.NAME AS TRUNK_NAME + FROM RC_CLOT_INFO,RC_CLOT_INFO_EXT, RC_CLOT_TRUNK + WHERE RC_CLOT_INFO.is_deleted='n' and + RC_CLOT_INFO.TRUNK_ID=RC_CLOT_TRUNK.ID + AND RC_CLOT_INFO.ID=RC_CLOT_INFO_EXT.CLOT_ID + AND RC_CLOT_INFO_EXT.GMT_MODIFIED >=? +ORDER BY RC_CLOT_TRUNK.NAME,RC_CLOT_INFO.id NULLS LAST + + + + +--------------------------- +SELECT RC_CLOT_INFO_EXT.*, RC_CLOT_TRUNK.NAME AS TRUNK_NAME +FROM RC_CLOT_INFO , RC_CLOT_INFO_EXT , RC_CLOT_TRUNK +WHERE RC_CLOT_INFO.is_deleted = 'n' AND RC_CLOT_INFO.TRUNK_ID = RC_CLOT_TRUNK.ID AND RC_CLOT_INFO.ID = RC_CLOT_INFO_EXT.CLOT_ID AND RC_CLOT_INFO_EXT.GMT_MODIFIED >= ? +ORDER BY RC_CLOT_TRUNK.NAME, RC_CLOT_INFO.id; diff --git a/src/test/resources/bvt/parser/oracle-21.txt b/src/test/resources/bvt/parser/oracle-21.txt new file mode 100644 index 0000000000..0aa74bab42 --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-21.txt @@ -0,0 +1,29 @@ +select * from ( + select rownum rnm, z.* + from ( + select distinct(tt.id) use_less_id, tt.* + from ( + select t.*, rct.parent_id, RCT.NAME as trunk_name + from rc_clot_info t, rc_clot_trunk rct + where t.is_deleted ='n' and t.trunk_id = rct.id + ) tt + CONNECT BY prior parent_id = trunk_id + start with trunk_name = 'rc.mf.Caesar' + order by load_order nulls last +) z where rownum < ? ) where rnm >= ? + + + + +--------------------------- +SELECT * +FROM (SELECT rownum AS rnm, z.* + FROM (SELECT DISTINCT DISTINCT(tt.id) AS use_less_id, tt.* + FROM (SELECT t.*, rct.parent_id, RCT.NAME AS trunk_name + FROM rc_clot_info t , rc_clot_trunk rct + WHERE t.is_deleted = 'n' AND t.trunk_id = rct.id) tt + START WITH trunk_name = 'rc.mf.Caesar' + CONNECT BY PRIOR parent_id = trunk_id + ORDER BY load_order NULLS LAST) z + WHERE rownum < ?) +WHERE rnm >= ?; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-22.txt b/src/test/resources/bvt/parser/oracle-22.txt new file mode 100644 index 0000000000..6d4be18b18 --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-22.txt @@ -0,0 +1,39 @@ +select * +from + ( select rownum rnm, z.* + from ( + select * + FROM ( + SELECT DISTINCT * + FROM ( + SELECT lower(a.role_name) || '#' || a.permission_id as key, 'y' as value + FROM app_role_permission A + WHERE a.is_deleted = 'n' + UNION ALL + SELECT lower(b.role_name) || '#' || a.permission_id, 'y' + FROM app_role_permission A, app_role_base_role B + WHERE a.is_deleted = 'n' AND b.is_deleted = 'n' AND a.role_name = b.base_role_name + ) + ) c + ORDER BY c.key) z + where rownum < ? + ) +where rnm >= ? + + + +--------------------------- +SELECT * +FROM (SELECT rownum AS rnm, z.* + FROM (SELECT * + FROM (SELECT DISTINCT * + FROM (SELECT lower(a.role_name) || '#' || a.permission_id AS KEY, 'y' AS value + FROM app_role_permission A + WHERE a.is_deleted = 'n' + UNION ALL + SELECT lower(b.role_name) || '#' || a.permission_id, 'y' + FROM app_role_permission A , app_role_base_role B + WHERE a.is_deleted = 'n' AND b.is_deleted = 'n' AND a.role_name = b.base_role_name)) c + ORDER BY c.KEY) z + WHERE rownum < ?) +WHERE rnm >= ?; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-23.txt b/src/test/resources/bvt/parser/oracle-23.txt new file mode 100644 index 0000000000..b6bcffc09d --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-23.txt @@ -0,0 +1,17 @@ +select nodeId,nodeName,taskflowName,taskflowVersion +from ( + select /*+ use_hash(n f) ordered */ n.ID nodeId,n.name nodeName,f.name taskflowName,f.version taskflowVersion + from "HT_TASK_FLOW_NODE_WA_2" n, "HT_TASK_FLOW_WA_2" f + where n.owner = ? and n.STATUS in ( ? ) and n.GMT_MODIFIED < ? and n.IS_AUTO = 'Y' and n.task_flow_id = f.id order by f.priority desc nulls last, f.gmt_create asc ) where rownum < ? + + + + + +--------------------------- +SELECT nodeId, nodeName, taskflowName, taskflowVersion +FROM (SELECT /*+use_hash(n f) ordered*/ n.ID AS nodeId, n.name AS nodeName, f.name AS taskflowName, f.version AS taskflowVersion + FROM "HT_TASK_FLOW_NODE_WA_2" n , "HT_TASK_FLOW_WA_2" f + WHERE n.owner = ? AND (n.STATUS IN (?) AND n.GMT_MODIFIED < ? AND n.IS_AUTO = 'Y' AND n.task_flow_id = f.id) + ORDER BY f.priority DESC NULLS LAST, f.gmt_create ASC) +WHERE rownum < ?; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-24.txt b/src/test/resources/bvt/parser/oracle-24.txt new file mode 100644 index 0000000000..bd487221f7 --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-24.txt @@ -0,0 +1,22 @@ +select INDUSTRY_ID, sale_type, service_type, RISK_TYPE, + to_char(gmt_create, 'yyyy-mm-dd hh24:mi:ss') gmt_create +from ( + select /*+ use_hash(a b c) ordered */ b.service_type, b.RISK_TYPE, + b.sale_type, b.INDUSTRY_ID, b.GMT_CREATE, + row_number() over(partition by b.service_type,b.RISK_TYPE,b.sale_type,b.INDUSTRY_ID order by b.GMT_CREATE) xh + from "HT_TASK_FLOW_WA_2" a, "HT_TASK_FLOW_BIZ_WA_2" b, "HT_TASK_FLOW_NODE_WA_2" c + where a.id = b.task_flow_id + AND a.id = c.task_flow_id AND c.status = 'waiting' and c.IS_AUTO = 'N' + AND a.status = 'running' AND c.name in (?) + ) +where xh=1 + + + + +--------------------------- +SELECT INDUSTRY_ID, sale_type, service_type, RISK_TYPE, to_char(gmt_create, 'yyyy-mm-dd hh24:mi:ss') AS gmt_create +FROM (SELECT /*+use_hash(a b c) ordered*/ b.service_type, b.RISK_TYPE, b.sale_type, b.INDUSTRY_ID, b.GMT_CREATE, row_number() OVER (PARTITION BY (b.service_type, b.RISK_TYPE, b.sale_type, b.INDUSTRY_ID) ORDER BY b.GMT_CREATE) AS xh + FROM "HT_TASK_FLOW_WA_2" a , "HT_TASK_FLOW_BIZ_WA_2" b , "HT_TASK_FLOW_NODE_WA_2" c + WHERE a.id = b.task_flow_id AND a.id = c.task_flow_id AND c.status = 'waiting' AND c.IS_AUTO = 'N' AND a.status = 'running' AND c.name IN (?)) +WHERE xh = 1; diff --git a/src/test/resources/bvt/parser/oracle-25.txt b/src/test/resources/bvt/parser/oracle-25.txt new file mode 100644 index 0000000000..84eb3bf25f --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-25.txt @@ -0,0 +1,62 @@ +select * from ( + select row_.*, rownum rownum_ + from ( + select * + from + ( + select results.*,row_number() over ( partition by results.object_id order by results.gmt_modified desc) rn + from + ( + ( + select sus.ID ID, sus.GMT_CREATE GMT_CREATE, + sus.GMT_MODIFIED GMT_MODIFIED, sus.COMPANY_ID COMPANY_ID, + sus.OBJECT_ID OBJECT_ID, sus.OBJECT_TYPE OBJECT_TYPE, + sus.CONFIRM_TYPE CONFIRM_TYPE, sus.OPERATOR OPERATOR, + sus.FILTER_TYPE FILTER_TYPE, sus.MEMBER_ID MEMBER_ID, + sus.MEMBER_SEQ MEMBER_SEQ, sus.RISK_TYPE RISK_TYPE , 'Y' IS_DRAFT + from bops_sus_posting sus , ws_product_draft p , + member m + where 1=1 and p.company_id = m.company_id + and m.login_id=? + and p.sale_type in( ? ) + and p.id=sus.object_id + ) + union + ( + select sus.ID ID, sus.GMT_CREATE GMT_CREATE, + sus.GMT_MODIFIED GMT_MODIFIED, sus.COMPANY_ID COMPANY_ID, + sus.OBJECT_ID OBJECT_ID, sus.OBJECT_TYPE OBJECT_TYPE, + sus.CONFIRM_TYPE CONFIRM_TYPE, sus.OPERATOR OPERATOR, + sus.FILTER_TYPE FILTER_TYPE, sus.MEMBER_ID MEMBER_ID, + sus.MEMBER_SEQ MEMBER_SEQ, sus.RISK_TYPE RISK_TYPE , 'N' IS_DRAFT + from bops_sus_posting sus , ws_product p ,member m + where 1=1 + and p.company_id = m.company_id + and m.login_id=? + and p.sale_type in( ? ) + and p.id=sus.object_id + ) + ) results + ) where rn = 1 order by gmt_modified desc + )row_ where rownum <= ? + ) +where rownum_ >= ? + + + +--------------------------- +SELECT * +FROM (SELECT row_.*, rownum AS rownum_ + FROM (SELECT * + FROM (SELECT results.*, row_number() OVER (PARTITION BY (results.object_id) ORDER BY results.gmt_modified DESC) AS rn + FROM (SELECT sus.ID AS ID, sus.GMT_CREATE AS GMT_CREATE, sus.GMT_MODIFIED AS GMT_MODIFIED, sus.COMPANY_ID AS COMPANY_ID, sus.OBJECT_ID AS OBJECT_ID, sus.OBJECT_TYPE AS OBJECT_TYPE, sus.CONFIRM_TYPE AS CONFIRM_TYPE, sus.OPERATOR AS OPERATOR, sus.FILTER_TYPE AS FILTER_TYPE, sus.MEMBER_ID AS MEMBER_ID, sus.MEMBER_SEQ AS MEMBER_SEQ, sus.RISK_TYPE AS RISK_TYPE, 'Y' AS IS_DRAFT + FROM bops_sus_posting sus , ws_product_draft p , member m + WHERE 1 = 1 AND p.company_id = m.company_id AND m.login_id = ? AND (p.sale_type IN (?) AND p.id = sus.object_id) + UNION + SELECT sus.ID AS ID, sus.GMT_CREATE AS GMT_CREATE, sus.GMT_MODIFIED AS GMT_MODIFIED, sus.COMPANY_ID AS COMPANY_ID, sus.OBJECT_ID AS OBJECT_ID, sus.OBJECT_TYPE AS OBJECT_TYPE, sus.CONFIRM_TYPE AS CONFIRM_TYPE, sus.OPERATOR AS OPERATOR, sus.FILTER_TYPE AS FILTER_TYPE, sus.MEMBER_ID AS MEMBER_ID, sus.MEMBER_SEQ AS MEMBER_SEQ, sus.RISK_TYPE AS RISK_TYPE, 'N' AS IS_DRAFT + FROM bops_sus_posting sus , ws_product p , member m + WHERE 1 = 1 AND p.company_id = m.company_id AND m.login_id = ? AND (p.sale_type IN (?) AND p.id = sus.object_id)) results) + WHERE rn = 1 + ORDER BY gmt_modified DESC) row_ + WHERE rownum <= ?) +WHERE rownum_ >= ?; diff --git a/src/test/resources/bvt/parser/oracle-26.txt b/src/test/resources/bvt/parser/oracle-26.txt new file mode 100644 index 0000000000..28065ed7df --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-26.txt @@ -0,0 +1,21 @@ +select * +from ( + select rownum rnm, z.* + from ( + select name key,value + from app_resource t + where t.type='VODKA._CTPCLEAN_NIRVANA_URL' and is_deleted='n' order by id + ) z + where rownum < ? ) where rnm >= ? + + + +--------------------------- +SELECT * +FROM (SELECT rownum AS rnm, z.* + FROM (SELECT name AS KEY, value + FROM app_resource t + WHERE t.type = 'VODKA._CTPCLEAN_NIRVANA_URL' AND is_deleted = 'n' + ORDER BY id) z + WHERE rownum < ?) +WHERE rnm >= ?; diff --git a/src/test/resources/bvt/parser/oracle-27.txt b/src/test/resources/bvt/parser/oracle-27.txt new file mode 100644 index 0000000000..7e29316471 --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-27.txt @@ -0,0 +1,14 @@ +select bk.attr_id as attrId, group_concat(distinct(bk.value_id)) as attrValueStr, + group_concat(distinct(pt.name)) as themeNameStr +from price_theme pt + left join tl_spu_attr_value_rel_bk bk on pt.spu_id=bk.spu_id +where pt.status='action' and pt.category_id=? +group by bk.attr_id; + + +--------------------------- +SELECT bk.attr_id AS attrId, group_concat(DISTINCT(bk.value_id)) AS attrValueStr, group_concat(DISTINCT(pt.name)) AS themeNameStr +FROM price_theme pt LEFT JOIN tl_spu_attr_value_rel_bk bk ON pt.spu_id = bk.spu_id +WHERE pt.status = 'action' AND pt.category_id = ? +GROUP BY bk.attr_id; + diff --git a/src/test/resources/bvt/parser/oracle-28.txt b/src/test/resources/bvt/parser/oracle-28.txt new file mode 100644 index 0000000000..cdf7e5218f --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-28.txt @@ -0,0 +1,16 @@ +select count(*) +from CREDIT_CMT_APPLY ,CREDIT_CMT_SHEET +where 1=2 +OR operator = ? + and CREDIT_CMT_APPLY.GMT_CREATE >= ? + and CREDIT_CMT_APPLY.GMT_CREATE <= ? + and CREDIT_CMT_APPLY.ID = CREDIT_CMT_SHEET.cmt_apply_id + and Type = 'denounce' + and (SHEET_STATUS = 'assigned_unresolved') + +--------------------------- +SELECT count(*) +FROM CREDIT_CMT_APPLY , CREDIT_CMT_SHEET +WHERE 1 = 2 OR operator = ? AND CREDIT_CMT_APPLY.GMT_CREATE >= ? AND CREDIT_CMT_APPLY.GMT_CREATE <= ? AND CREDIT_CMT_APPLY.ID = CREDIT_CMT_SHEET.cmt_apply_id AND Type = 'denounce' AND SHEET_STATUS = 'assigned_unresolved'; + + diff --git a/src/test/resources/bvt/parser/oracle-29.txt b/src/test/resources/bvt/parser/oracle-29.txt new file mode 100644 index 0000000000..69c07428f5 --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-29.txt @@ -0,0 +1,18 @@ +select count(*) +from CREDIT_CMT_APPLY ,CREDIT_CMT_SHEET +where 1=2 +OR operator = ? + and CREDIT_CMT_APPLY.GMT_CREATE >= ? + and CREDIT_CMT_APPLY.GMT_CREATE <= ? + and CREDIT_CMT_APPLY.ID = CREDIT_CMT_SHEET.cmt_apply_id + and Type = 'denounce' + and (SHEET_STATUS = 'assigned_unresolved') + + + +--------------------------- +SELECT bk.attr_id AS attrId, group_concat(DISTINCT(bk.value_id)) AS attrValueStr, group_concat(DISTINCT(pt.name)) AS themeNameStr +FROM price_theme pt LEFT JOIN tl_spu_attr_value_rel_bk bk ON pt.spu_id = bk.spu_id +WHERE pt.status = 'action' AND pt.category_id = ? +GROUP BY bk.attr_id; + diff --git a/src/test/resources/bvt/parser/oracle-5.txt b/src/test/resources/bvt/parser/oracle-5.txt index 0d1ea0fafb..e2d247acb5 100644 --- a/src/test/resources/bvt/parser/oracle-5.txt +++ b/src/test/resources/bvt/parser/oracle-5.txt @@ -9,7 +9,7 @@ FROM FROM employees) b ORDER BY a.department_id; --------------------------- -SELECT a.department_id AS department_id, a.num_emp / b.total_count AS total_count, a.sal_sum / b.total_sal AS total_sal +SELECT a.department_id AS "Department", a.num_emp / b.total_count AS "%_Employees", a.sal_sum / b.total_sal AS "%_Salary" FROM (SELECT department_id, COUNT(*) AS num_emp, SUM(salary) AS sal_sum FROM employees GROUP BY department_id) a , (SELECT COUNT(*) AS total_count, SUM(salary) AS total_sal