diff --git a/src/main/java/com/alibaba/druid/sql/SQLUtils.java b/src/main/java/com/alibaba/druid/sql/SQLUtils.java index 3943a5d820..3fd2c6cd86 100644 --- a/src/main/java/com/alibaba/druid/sql/SQLUtils.java +++ b/src/main/java/com/alibaba/druid/sql/SQLUtils.java @@ -23,8 +23,7 @@ import com.alibaba.druid.DruidRuntimeException; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.SQLStatement; -import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; -import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; +import com.alibaba.druid.sql.ast.expr.*; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem; @@ -736,5 +735,59 @@ public class SQLUtils { return buf.hashCode(); } + + public static SQLExpr not(SQLExpr expr) { + if (expr instanceof SQLBinaryOpExpr) { + SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) expr; + SQLBinaryOperator op = binaryOpExpr.getOperator(); + + SQLBinaryOperator notOp = null; + + switch (op){ + case Equality: + notOp = SQLBinaryOperator.LessThanOrEqualOrGreaterThan; + break; + case LessThanOrEqualOrGreaterThan: + notOp = SQLBinaryOperator.Equality; + break; + case LessThan: + notOp = SQLBinaryOperator.GreaterThanOrEqual; + break; + case LessThanOrEqual: + notOp = SQLBinaryOperator.GreaterThan; + break; + case GreaterThan: + notOp = SQLBinaryOperator.LessThanOrEqual; + break; + case GreaterThanOrEqual: + notOp = SQLBinaryOperator.LessThan; + break; + case Is: + notOp = SQLBinaryOperator.IsNot; + break; + case IsNot: + notOp = SQLBinaryOperator.Is; + break; + default: + break; + } + + + if (notOp != null) { + return new SQLBinaryOpExpr(binaryOpExpr.getLeft(), notOp, binaryOpExpr.getRight()); + } + } + + if (expr instanceof SQLInListExpr) { + SQLInListExpr inListExpr = (SQLInListExpr) expr; + + SQLInListExpr newInListExpr = new SQLInListExpr(inListExpr); + newInListExpr.getTargetList().addAll(inListExpr.getTargetList()); + newInListExpr.setNot(!inListExpr.isNot()); + return newInListExpr; + } + + return new SQLUnaryExpr(SQLUnaryOperator.Not, expr); + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java index 2b35208426..b002c474f9 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java @@ -91,23 +91,20 @@ public class SQLExprTableSource extends SQLTableSourceImpl { } @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((expr == null) ? 0 : expr.hashCode()); - return result; + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + SQLExprTableSource that = (SQLExprTableSource) o; + + if (expr != null ? !expr.equals(that.expr) : that.expr != null) return false; + return partitions != null ? partitions.equals(that.partitions) : that.partitions == null; } @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - SQLExprTableSource other = (SQLExprTableSource) obj; - if (expr == null) { - if (other.expr != null) return false; - } else if (!expr.equals(other.expr)) return false; - return true; + public int hashCode() { + int result = expr != null ? expr.hashCode() : 0; + result = 31 * result + (partitions != null ? partitions.hashCode() : 0); + return result; } - } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java index 4894e16864..881c091019 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java @@ -117,6 +117,21 @@ public class SQLJoinTableSource extends SQLTableSourceImpl { } } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + SQLJoinTableSource that = (SQLJoinTableSource) o; + + if (natural != that.natural) return false; + if (left != null ? !left.equals(that.left) : that.left != null) return false; + if (joinType != that.joinType) return false; + if (right != null ? !right.equals(that.right) : that.right != null) return false; + if (condition != null ? !condition.equals(that.condition) : that.condition != null) return false; + return using != null ? using.equals(that.using) : that.using == null; + } + public static enum JoinType { COMMA(","), // JOIN("JOIN"), // diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLRollbackStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLRollbackStatement.java index 4089537c18..7eb3e672c3 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLRollbackStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLRollbackStatement.java @@ -15,6 +15,7 @@ */ package com.alibaba.druid.sql.ast.statement; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLStatementImpl; import com.alibaba.druid.sql.visitor.SQLASTVisitor; @@ -22,6 +23,11 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLRollbackStatement extends SQLStatementImpl { private SQLName to; + + // for mysql + private Boolean chain; + private Boolean release; + private SQLExpr force; public SQLRollbackStatement() { @@ -35,6 +41,8 @@ public class SQLRollbackStatement extends SQLStatementImpl { protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, to); + + acceptChild(visitor, force); } visitor.endVisit(this); } @@ -47,4 +55,28 @@ public class SQLRollbackStatement extends SQLStatementImpl { this.to = to; } + public Boolean getChain() { + return chain; + } + + public void setChain(Boolean chain) { + this.chain = chain; + } + + public Boolean getRelease() { + return release; + } + + public void setRelease(Boolean release) { + this.release = release; + } + + public SQLExpr getForce() { + return force; + } + + public void setForce(SQLExpr force) { + this.force = force; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlRollbackStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlRollbackStatement.java deleted file mode 100644 index af7daeee90..0000000000 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlRollbackStatement.java +++ /dev/null @@ -1,78 +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.mysql.ast.statement; - -import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement; -import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; -import com.alibaba.druid.sql.visitor.SQLASTVisitor; -import com.alibaba.druid.util.JdbcConstants; - -public class MySqlRollbackStatement extends SQLRollbackStatement implements MySqlStatement { - - private Boolean chain; - private Boolean release; - - private SQLExpr force; - - public MySqlRollbackStatement(){ - super (JdbcConstants.MYSQL); - } - - public Boolean getChain() { - return chain; - } - - public void setChain(Boolean chain) { - this.chain = chain; - } - - public Boolean getRelease() { - return release; - } - - public void setRelease(Boolean release) { - this.release = release; - } - - @Override - protected void accept0(SQLASTVisitor visitor) { - if (visitor instanceof MySqlASTVisitor) { - accept0((MySqlASTVisitor) visitor); - } else { - throw new IllegalArgumentException("not support visitor type : " + visitor.getClass().getName()); - } - } - - @Override - public void accept0(MySqlASTVisitor visitor) { - if (visitor.visit(this)) { - acceptChild(visitor, getTo()); - acceptChild(visitor, getForce()); - } - - visitor.endVisit(this); - } - - public SQLExpr getForce() { - return force; - } - - public void setForce(SQLExpr force) { - this.force = force; - } - -} 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 29694535d0..b72b56495f 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 @@ -79,7 +79,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRollbackStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetPasswordStatement; @@ -1644,10 +1643,10 @@ public class MySqlStatementParser extends SQLStatementParser { } @Override - public MySqlRollbackStatement parseRollback() { + public SQLRollbackStatement parseRollback() { acceptIdentifier("ROLLBACK"); - MySqlRollbackStatement stmt = new MySqlRollbackStatement(); + SQLRollbackStatement stmt = new SQLRollbackStatement(); if (identifierEquals("WORK")) { lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java index 1e4791a94f..e56ef34e93 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java @@ -68,7 +68,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRollbackStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; @@ -190,10 +189,6 @@ public interface MySqlASTVisitor extends SQLASTVisitor { boolean visit(MySqlReplaceStatement x); - void endVisit(MySqlRollbackStatement x); - - boolean visit(MySqlRollbackStatement x); - void endVisit(MySqlShowColumnsStatement x); boolean visit(MySqlShowColumnsStatement x); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java index 72e1b86a6b..f7882217dd 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java @@ -70,7 +70,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRollbackStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; @@ -280,17 +279,6 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySq return true; } - @Override - public void endVisit(MySqlRollbackStatement x) { - - } - - @Override - public boolean visit(MySqlRollbackStatement x) { - - return true; - } - @Override public void endVisit(MySqlShowColumnsStatement x) { 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 6c75f97bed..55003751a5 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 @@ -78,7 +78,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRollbackStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; @@ -1222,13 +1221,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV return false; } - @Override - public void endVisit(MySqlRollbackStatement x) { - - } - - @Override - public boolean visit(MySqlRollbackStatement x) { + public boolean visit(SQLRollbackStatement x) { print0(ucase ? "ROLLBACK" : "rollback"); if (x.getChain() != null) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java index b61cc166ac..33dc0e29fd 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java @@ -85,7 +85,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRollbackStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; @@ -409,17 +408,6 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS return true; } - @Override - public void endVisit(MySqlRollbackStatement x) { - - } - - @Override - public boolean visit(MySqlRollbackStatement x) { - - return true; - } - @Override public void endVisit(MySqlShowColumnsStatement x) { 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 00aa4b005b..663e3d52e7 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 @@ -91,6 +91,25 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect } } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + OracleSelectJoin that = (OracleSelectJoin) o; + + if (pivot != null ? !pivot.equals(that.pivot) : that.pivot != null) return false; + return flashback != null ? flashback.equals(that.flashback) : that.flashback == null; + } + + @Override + public int hashCode() { + int result = pivot != null ? pivot.hashCode() : 0; + result = 31 * result + (flashback != null ? flashback.hashCode() : 0); + return result; + } + public String toString () { return SQLUtils.toOracleString(this); } 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 d4497f9515..e01673167c 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 @@ -110,7 +110,33 @@ public class OracleSelectTableReference extends SQLExprTableSource implements Or buf.append(this.alias); } } - + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + OracleSelectTableReference that = (OracleSelectTableReference) o; + + if (only != that.only) return false; + if (pivot != null ? !pivot.equals(that.pivot) : that.pivot != null) return false; + if (partition != null ? !partition.equals(that.partition) : that.partition != null) return false; + if (sampleClause != null ? !sampleClause.equals(that.sampleClause) : that.sampleClause != null) return false; + return flashback != null ? flashback.equals(that.flashback) : that.flashback == null; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (only ? 1 : 0); + result = 31 * result + (pivot != null ? pivot.hashCode() : 0); + result = 31 * result + (partition != null ? partition.hashCode() : 0); + result = 31 * result + (sampleClause != null ? sampleClause.hashCode() : 0); + result = 31 * result + (flashback != null ? flashback.hashCode() : 0); + return result; + } + public String toString () { return SQLUtils.toOracleString(this); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlASTVisitorAdapterTest.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlASTVisitorAdapterTest.java index 70b14fc4ac..c6845766d5 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlASTVisitorAdapterTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlASTVisitorAdapterTest.java @@ -34,7 +34,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRollbackStatement; import com.alibaba.druid.sql.ast.SQLLimit; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; @@ -107,7 +106,6 @@ public class MySqlASTVisitorAdapterTest extends TestCase { new MySqlLoadXmlStatement().accept(adapter); new MySqlReplaceStatement().accept(adapter); new SQLStartTransactionStatement().accept(adapter); - new MySqlRollbackStatement().accept(adapter); new MySqlShowColumnsStatement().accept(adapter); new MySqlShowDatabasesStatement().accept(adapter); new MySqlShowWarningsStatement().accept(adapter);