refactor sql parser.

This commit is contained in:
wenshao
2017-06-01 09:09:46 +08:00
parent ad452e507d
commit 82d691365a
13 changed files with 163 additions and 138 deletions
@@ -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);
}
}
@@ -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;
}
}
@@ -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"), //
@@ -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;
}
}
@@ -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;
}
}
@@ -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();
@@ -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);
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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);
}
@@ -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);
}
@@ -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);