diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLFlashbackExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLFlashbackExpr.java new file mode 100644 index 0000000000..1be2f64002 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLFlashbackExpr.java @@ -0,0 +1,80 @@ +package com.alibaba.druid.sql.ast.expr; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLExprImpl; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +/** + * Created by wenshao on 14/06/2017. + */ +public class SQLFlashbackExpr extends SQLExprImpl { + private Type type; + private SQLExpr expr; + + public SQLFlashbackExpr() { + + } + + public SQLFlashbackExpr(Type type, SQLExpr expr) { + this.type = type; + this.setExpr(expr); + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public SQLExpr getExpr() { + return expr; + } + + public void setExpr(SQLExpr expr) { + if (expr != null) { + expr.setParent(this); + } + this.expr = expr; + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, expr); + } + visitor.endVisit(this); + } + + public SQLFlashbackExpr clone() { + SQLFlashbackExpr x = new SQLFlashbackExpr(); + x.type = this.type; + if (expr != null) { + x.setExpr(expr.clone()); + } + return x; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + SQLFlashbackExpr that = (SQLFlashbackExpr) o; + + if (type != that.type) return false; + return expr != null ? expr.equals(that.expr) : that.expr == null; + } + + @Override + public int hashCode() { + int result = type != null ? type.hashCode() : 0; + result = 31 * result + (expr != null ? expr.hashCode() : 0); + return result; + } + + public static enum Type { + SCN, TIMESTAMP + } +} diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTableSourceImpl.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTableSourceImpl.java index 4a91a47265..b61053acee 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTableSourceImpl.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTableSourceImpl.java @@ -18,6 +18,7 @@ package com.alibaba.druid.sql.ast.statement; import java.util.ArrayList; import java.util.List; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLHint; import com.alibaba.druid.sql.ast.SQLObjectImpl; @@ -27,6 +28,8 @@ public abstract class SQLTableSourceImpl extends SQLObjectImpl implements SQLTab protected List hints; + protected SQLExpr flashback; + public SQLTableSourceImpl(){ } @@ -71,4 +74,14 @@ public abstract class SQLTableSourceImpl extends SQLObjectImpl implements SQLTab return alias; } + public SQLExpr getFlashback() { + return flashback; + } + + public void setFlashback(SQLExpr flashback) { + if (flashback != null) { + flashback.setParent(this); + } + this.flashback = flashback; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/FlashbackQueryClause.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/FlashbackQueryClause.java deleted file mode 100644 index 3b5d104fbf..0000000000 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/FlashbackQueryClause.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 1999-2017 Alibaba Group Holding Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.druid.sql.dialect.oracle.ast.clause; - -import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject; -import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; -import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; - -public abstract class FlashbackQueryClause extends OracleSQLObjectImpl { - - private Type type; - - public Type getType() { - return type; - } - - public void setType(Type type) { - this.type = type; - } - - public static enum Type { - SCN, TIMESTAMP - } - - public FlashbackQueryClause clone() { - throw new UnsupportedOperationException(); - } - - public static class VersionsFlashbackQueryClause extends FlashbackQueryClause { - - private SQLExpr begin; - private SQLExpr end; - - public SQLExpr getBegin() { - return begin; - } - - public void setBegin(SQLExpr begin) { - this.begin = begin; - } - - public SQLExpr getEnd() { - return end; - } - - public void setEnd(SQLExpr end) { - this.end = end; - } - - @Override - public void accept0(OracleASTVisitor visitor) { - if (visitor.visit(this)) { - acceptChild(visitor, begin); - acceptChild(visitor, end); - } - visitor.endVisit(this); - } - } - - public static class AsOfFlashbackQueryClause extends FlashbackQueryClause { - - private SQLExpr expr; - - public SQLExpr getExpr() { - return expr; - } - - public void setExpr(SQLExpr expr) { - this.expr = expr; - } - - @Override - public void accept0(OracleASTVisitor visitor) { - if (visitor.visit(this)) { - acceptChild(visitor, expr); - } - visitor.endVisit(this); - } - } - - public static class AsOfSnapshotClause extends FlashbackQueryClause { - - private SQLExpr expr; - - public SQLExpr getExpr() { - return expr; - } - - public void setExpr(SQLExpr expr) { - this.expr = expr; - } - - @Override - public 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/OracleSelectJoin.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectJoin.java index c12cd6a827..dbf984699c 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectJoin.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectJoin.java @@ -18,14 +18,12 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelectTableSource { protected OracleSelectPivotBase pivot; - protected FlashbackQueryClause flashback; public OracleSelectJoin(String alias){ super(alias); @@ -35,13 +33,6 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect } - public FlashbackQueryClause getFlashback() { - return flashback; - } - - public void setFlashback(FlashbackQueryClause flashback) { - this.flashback = flashback; - } public OracleSelectPivotBase getPivot() { return pivot; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectSubqueryTableSource.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectSubqueryTableSource.java index ef1ee80c0c..99ff91bf2f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectSubqueryTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectSubqueryTableSource.java @@ -16,9 +16,9 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; @@ -26,19 +26,10 @@ public class OracleSelectSubqueryTableSource extends SQLSubqueryTableSource impl protected OracleSelectPivotBase pivot; - protected FlashbackQueryClause flashback; public OracleSelectSubqueryTableSource(){ } - public FlashbackQueryClause getFlashback() { - return flashback; - } - - public void setFlashback(FlashbackQueryClause flashback) { - this.flashback = flashback; - } - public OracleSelectSubqueryTableSource(String alias){ super(alias); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableReference.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableReference.java index caa689fac2..2fdedcda5c 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableReference.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableReference.java @@ -17,8 +17,6 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; -import com.alibaba.druid.sql.ast.statement.SQLTableSource; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.PartitionExtensionClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.SampleClause; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; @@ -32,20 +30,10 @@ public class OracleSelectTableReference extends SQLExprTableSource implements Or protected PartitionExtensionClause partition; protected SampleClause sampleClause; - protected FlashbackQueryClause flashback; - public OracleSelectTableReference(){ } - public FlashbackQueryClause getFlashback() { - return flashback; - } - - public void setFlashback(FlashbackQueryClause flashback) { - this.flashback = flashback; - } - public PartitionExtensionClause getPartition() { return partition; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableSource.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableSource.java index f06769a324..687bed0c2d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableSource.java @@ -15,8 +15,8 @@ */ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.statement.SQLTableSource; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause; public interface OracleSelectTableSource extends SQLTableSource { @@ -24,7 +24,7 @@ public interface OracleSelectTableSource extends SQLTableSource { void setPivot(OracleSelectPivotBase pivot); - FlashbackQueryClause getFlashback(); + SQLExpr getFlashback(); - void setFlashback(FlashbackQueryClause flashback); + void setFlashback(SQLExpr flashback); } 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 bbb10d0ec8..0918632a7e 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 @@ -20,17 +20,9 @@ import java.util.List; 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.expr.SQLAggregateExpr; -import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; -import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; -import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; -import com.alibaba.druid.sql.ast.expr.SQLListExpr; +import com.alibaba.druid.sql.ast.expr.*; import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfSnapshotClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.VersionsFlashbackQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.CellAssignment; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.CellAssignmentItem; @@ -695,61 +687,47 @@ public class OracleSelectParser extends SQLSelectParser { } if (identifierEquals("VERSIONS")) { + SQLBetweenExpr betweenExpr = new SQLBetweenExpr(); + betweenExpr.setTestExpr(new SQLIdentifierExpr("VERSIONS")); lexer.nextToken(); - if (lexer.token() == Token.BETWEEN) { + accept(Token.BETWEEN); + + + SQLFlashbackExpr start = new SQLFlashbackExpr(); + if (identifierEquals("SCN")) { lexer.nextToken(); - - VersionsFlashbackQueryClause clause = new VersionsFlashbackQueryClause(); - if (identifierEquals("SCN")) { - clause.setType(AsOfFlashbackQueryClause.Type.SCN); - lexer.nextToken(); - } else { - acceptIdentifier("TIMESTAMP"); - clause.setType(AsOfFlashbackQueryClause.Type.TIMESTAMP); - } - - SQLBinaryOpExpr binaryExpr = (SQLBinaryOpExpr) exprParser.expr(); - if (binaryExpr.getOperator() != SQLBinaryOperator.BooleanAnd) { - throw new ParserException("syntax error : " + binaryExpr.getOperator()); - } - - clause.setBegin(binaryExpr.getLeft()); - clause.setEnd(binaryExpr.getRight()); - - tableReference.setFlashback(clause); + start.setType(SQLFlashbackExpr.Type.SCN); } else { - throw new ParserException("TODO"); + acceptIdentifier("TIMESTAMP"); + start.setType(SQLFlashbackExpr.Type.TIMESTAMP); } + + SQLBinaryOpExpr binaryExpr = (SQLBinaryOpExpr) exprParser.expr(); + if (binaryExpr.getOperator() != SQLBinaryOperator.BooleanAnd) { + throw new ParserException("syntax error : " + binaryExpr.getOperator()); + } + + start.setExpr(binaryExpr.getLeft()); + + betweenExpr.setBeginExpr(start); + betweenExpr.setEndExpr(binaryExpr.getRight()); + + tableReference.setFlashback(betweenExpr); } } - private FlashbackQueryClause flashback() { + private SQLExpr flashback() { accept(Token.OF); - if (identifierEquals("SCN")) { - AsOfFlashbackQueryClause clause = new AsOfFlashbackQueryClause(); - clause.setType(AsOfFlashbackQueryClause.Type.SCN); lexer.nextToken(); - clause.setExpr(exprParser.expr()); - - return clause; + return new SQLFlashbackExpr(SQLFlashbackExpr.Type.SCN, this.expr()); } else if (identifierEquals("SNAPSHOT")) { - lexer.nextToken(); - accept(Token.LPAREN); - AsOfSnapshotClause clause = new AsOfSnapshotClause(); - clause.setExpr(this.expr()); - accept(Token.RPAREN); - - return clause; + return this.expr(); } else { - AsOfFlashbackQueryClause clause = new AsOfFlashbackQueryClause(); - acceptIdentifier("TIMESTAMP"); - clause.setType(AsOfFlashbackQueryClause.Type.TIMESTAMP); - clause.setExpr(exprParser.expr()); - - return clause; + lexer.nextToken(); + return new SQLFlashbackExpr(SQLFlashbackExpr.Type.TIMESTAMP, this.expr()); } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java index ddcf532a47..7005dc684b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java @@ -19,9 +19,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay; import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear; import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp; import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfSnapshotClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.VersionsFlashbackQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleLobStorageClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause; @@ -129,14 +126,6 @@ public interface OracleASTVisitor extends SQLASTVisitor { void endVisit(PartitionExtensionClause x); - boolean visit(VersionsFlashbackQueryClause x); - - void endVisit(VersionsFlashbackQueryClause x); - - boolean visit(AsOfFlashbackQueryClause x); - - void endVisit(AsOfFlashbackQueryClause x); - boolean visit(OracleWithSubqueryEntry x); void endVisit(OracleWithSubqueryEntry x); @@ -353,10 +342,6 @@ public interface OracleASTVisitor extends SQLASTVisitor { void endVisit(OracleAlterViewStatement x); - boolean visit(AsOfSnapshotClause x); - - void endVisit(AsOfSnapshotClause x); - boolean visit(OracleAlterTableMoveTablespace x); void endVisit(OracleAlterTableMoveTablespace x); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitorAdapter.java index 14b1da39f4..221977920e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitorAdapter.java @@ -21,9 +21,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay; import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear; import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp; import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfSnapshotClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.VersionsFlashbackQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.CellAssignment; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.CellAssignmentItem; @@ -263,28 +260,6 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora } - @Override - public boolean visit(VersionsFlashbackQueryClause x) { - - return true; - } - - @Override - public void endVisit(VersionsFlashbackQueryClause x) { - - } - - @Override - public boolean visit(AsOfFlashbackQueryClause x) { - - return true; - } - - @Override - public void endVisit(AsOfFlashbackQueryClause x) { - - } - @Override public boolean visit(OracleWithSubqueryEntry x) { @@ -840,16 +815,6 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora } - @Override - public boolean visit(AsOfSnapshotClause x) { - return true; - } - - @Override - public void endVisit(AsOfSnapshotClause x) { - - } - @Override public boolean visit(OracleAlterViewStatement x) { return true; 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 9ee4376f82..c8a5e6959d 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 @@ -18,20 +18,13 @@ package com.alibaba.druid.sql.dialect.oracle.visitor; import java.util.List; import com.alibaba.druid.sql.ast.*; -import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr; -import com.alibaba.druid.sql.ast.expr.SQLCharExpr; -import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; -import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; -import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; +import com.alibaba.druid.sql.ast.expr.*; import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType; import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay; import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear; import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp; import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfSnapshotClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.VersionsFlashbackQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.CellAssignment; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.CellAssignmentItem; @@ -308,10 +301,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS print(')'); } - if (x.getFlashback() != null) { - println(); - x.getFlashback().accept(this); - } + printFlashback(x.getFlashback()); } return false; @@ -489,10 +479,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS x.getPivot().accept(this); } - if (x.getFlashback() != null) { - println(); - x.getFlashback().accept(this); - } + printFlashback(x.getFlashback()); if ((x.getAlias() != null) && (x.getAlias().length() != 0)) { print(' '); @@ -536,16 +523,28 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS x.getPivot().accept(this); } - if (x.getFlashback() != null) { - println(); - x.getFlashback().accept(this); - } + printFlashback(x.getFlashback()); printAlias(x.getAlias()); return false; } + private void printFlashback(SQLExpr flashback) { + if (flashback == null) { + return; + } + + println(); + + if (flashback instanceof SQLBetweenExpr) { + flashback.accept(this); + } else { + print0(ucase ? "AS OF " : "as of "); + flashback.accept(this); + } + } + public boolean visit(OracleSelectUnPivot x) { print0(ucase ? "UNPIVOT" : "unpivot"); if (x.getNullsIncludeType() != null) { @@ -768,36 +767,36 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS } - @Override - public boolean visit(VersionsFlashbackQueryClause x) { - print0(ucase ? "VERSIONS BETWEEN " : "versions between "); - print0(x.getType().name()); - print(' '); - x.getBegin().accept(this); - print0(ucase ? " AND " : " and "); - x.getEnd().accept(this); - return false; - } - - @Override - public void endVisit(VersionsFlashbackQueryClause x) { - - } - - @Override - public boolean visit(AsOfFlashbackQueryClause x) { - print0(ucase ? "AS OF " : "as of "); - print0(x.getType().name()); - print0(" ("); - x.getExpr().accept(this); - print(')'); - return false; - } - - @Override - public void endVisit(AsOfFlashbackQueryClause x) { - - } +// @Override +// public boolean visit(VersionsFlashbackQueryClause x) { +// print0(ucase ? "VERSIONS BETWEEN " : "versions between "); +// print0(x.getType().name()); +// print(' '); +// x.getBegin().accept(this); +// print0(ucase ? " AND " : " and "); +// x.getEnd().accept(this); +// return false; +// } +// +// @Override +// public void endVisit(VersionsFlashbackQueryClause x) { +// +// } +// +// @Override +// public boolean visit(AsOfFlashbackQueryClause x) { +// print0(ucase ? "AS OF " : "as of "); +// print0(x.getType().name()); +// print0(" ("); +// x.getExpr().accept(this); +// print(')'); +// return false; +// } +// +// @Override +// public void endVisit(AsOfFlashbackQueryClause x) { +// +// } @Override public boolean visit(OracleWithSubqueryEntry x) { @@ -2288,18 +2287,18 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS } - @Override - public boolean visit(AsOfSnapshotClause x) { - print0(ucase ? "AS OF SNAPSHOT(" : "as of snapshot("); - x.getExpr().accept(this); - print(')'); - return false; - } - - @Override - public void endVisit(AsOfSnapshotClause x) { - - } +// @Override +// public boolean visit(AsOfSnapshotClause x) { +// print0(ucase ? "AS OF SNAPSHOT(" : "as of snapshot("); +// x.getExpr().accept(this); +// print(')'); +// return false; +// } +// +// @Override +// public void endVisit(AsOfSnapshotClause x) { +// +// } @Override public boolean visit(OracleAlterViewStatement x) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java index 0b5951be62..7be9ff50d5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java @@ -35,9 +35,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay; import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear; import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp; import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfSnapshotClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.VersionsFlashbackQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.CellAssignment; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.CellAssignmentItem; @@ -492,28 +489,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle } - @Override - public boolean visit(VersionsFlashbackQueryClause x) { - - return true; - } - - @Override - public void endVisit(VersionsFlashbackQueryClause x) { - - } - - @Override - public boolean visit(AsOfFlashbackQueryClause x) { - - return true; - } - - @Override - public void endVisit(AsOfFlashbackQueryClause x) { - - } - @Override public boolean visit(OracleWithSubqueryEntry x) { Map aliasMap = getAliasMap(); @@ -1184,16 +1159,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle } - @Override - public boolean visit(AsOfSnapshotClause x) { - return false; - } - - @Override - public void endVisit(AsOfSnapshotClause x) { - - } - @Override public boolean visit(OracleAlterViewStatement x) { return false; 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 e52532519a..a84acf27ff 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -4485,4 +4485,18 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet return false; } + + public boolean visit(SQLFlashbackExpr x) { + print0(x.getType().name()); + print(' '); + SQLExpr expr = x.getExpr(); + if (expr instanceof SQLBinaryOpExpr) { + print('('); + expr.accept(this); + print(')'); + } else { + expr.accept(this); + } + 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 39820fc3b4..e07265bb7e 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java @@ -726,4 +726,10 @@ public interface SQLASTVisitor { boolean visit(SQLCommitStatement x); void endVisit(SQLCommitStatement x); + + + boolean visit(SQLFlashbackExpr x); + + void endVisit(SQLFlashbackExpr 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 ff312d5ed9..9f85c58393 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java @@ -1643,7 +1643,6 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { } - @Override public boolean visit(SQLCommitStatement x) { return true; @@ -1653,4 +1652,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { public void endVisit(SQLCommitStatement x) { } + + @Override + public boolean visit(SQLFlashbackExpr x) { + return true; + } + + @Override + public void endVisit(SQLFlashbackExpr x) { + + } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSetTest_3.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSetTest_3.java new file mode 100644 index 0000000000..6580c7933f --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSetTest_3.java @@ -0,0 +1,55 @@ +/* + * 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; + +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 junit.framework.TestCase; +import org.junit.Assert; + +import java.util.List; + +public class MySqlSetTest_3 extends TestCase { + + public void test_0() throws Exception { + String sql = "SET sql_mode=?,NAMES ?,CHARACTER SET utf8,CHARACTER_SET_RESULTS=utf8,COLLATION_CONNECTION=?"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List stmtList = parser.parseStatementList(); + SQLStatement stmt = stmtList.get(0); +// print(stmtList); + + Assert.assertEquals(1, stmtList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + 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(0, visitor.getTables().size()); + Assert.assertEquals(0, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + String text = SQLUtils.toMySqlString(stmt); + + Assert.assertEquals("SET sql_mode = ?, NAMES ?, CHARACTER SET utf8, CHARACTER_SET_RESULTS = utf8, COLLATION_CONNECTION = ?", text); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleFlashbackQueryTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleFlashbackQueryTest2.java index 3aef95ee98..3b5708a954 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleFlashbackQueryTest2.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleFlashbackQueryTest2.java @@ -31,7 +31,7 @@ public class OracleFlashbackQueryTest2 extends TestCase { String expect = "SELECT salary\n" + "FROM employees\n" - + "VERSIONS BETWEEN TIMESTAMP SYSTIMESTAMP - INTERVAL '10' MINUTE AND SYSTIMESTAMP - INTERVAL '1' MINUTE\n" + + "VERSIONS BETWEEN TIMESTAMP (SYSTIMESTAMP - INTERVAL '10' MINUTE) AND SYSTIMESTAMP - INTERVAL '1' MINUTE\n" + "WHERE last_name = 'Chung';"; OracleStatementParser parser = new OracleStatementParser(sql); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleFlashbackQueryTest4.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleFlashbackQueryTest4.java new file mode 100644 index 0000000000..08bb271cc5 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleFlashbackQueryTest4.java @@ -0,0 +1,46 @@ +/* + * 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; + +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.test.TestUtils; +import junit.framework.TestCase; +import org.junit.Assert; + +public class OracleFlashbackQueryTest4 extends TestCase { + + public void test_isEmpty() throws Exception { + String sql = "SELECT * FROM employees\n" + + "AS OF TIMESTAMP\n" + + "TO_TIMESTAMP('2004-04-04 09:30:00', 'YYYY-MM-DD HH:MI:SS')\n" + + "WHERE last_name = 'Chung';"; + + String expect = "SELECT *\n" + + "FROM employees\n" + + "AS OF TIMESTAMP TO_TIMESTAMP('2004-04-04 09:30:00', 'YYYY-MM-DD HH:MI:SS')\n" + + "WHERE last_name = 'Chung';"; + + OracleStatementParser parser = new OracleStatementParser(sql); + SQLSelectStatement stmt = (SQLSelectStatement) parser.parseStatementList().get(0); + + String text = TestUtils.outputOracle(stmt); + + Assert.assertEquals(expect, text); + + System.out.println(text); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleASTVisitorAdapterTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleASTVisitorAdapterTest.java index 6503130af2..cd43f2f4c3 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleASTVisitorAdapterTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleASTVisitorAdapterTest.java @@ -10,9 +10,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay; import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear; import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp; import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfSnapshotClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.VersionsFlashbackQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.CellAssignment; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.CellAssignmentItem; @@ -105,9 +102,6 @@ public class OracleASTVisitorAdapterTest extends TestCase { new OracleSelectUnPivot().accept(adapter); new SQLTimestampExpr().accept(adapter); new PartitionExtensionClause().accept(adapter); - new VersionsFlashbackQueryClause().accept(adapter); - new VersionsFlashbackQueryClause().accept(adapter); - new AsOfFlashbackQueryClause().accept(adapter); new SQLGroupingSetExpr().accept(adapter); new OracleWithSubqueryEntry().accept(adapter); new OracleFileSpecification().accept(adapter); @@ -188,7 +182,6 @@ public class OracleASTVisitorAdapterTest extends TestCase { new SQLCommitStatement().accept(adapter); new OracleAlterTriggerStatement().accept(adapter); new OracleAlterSynonymStatement().accept(adapter); - new AsOfSnapshotClause().accept(adapter); new OracleAlterViewStatement().accept(adapter); new OracleAlterTableMoveTablespace().accept(adapter); new OracleSizeExpr().accept(adapter);