improved sql parser.

This commit is contained in:
wenshao
2017-06-06 10:13:48 +08:00
parent d9a0cae840
commit 3165a86e3c
16 changed files with 461 additions and 57 deletions
@@ -0,0 +1,23 @@
/*
* 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.ast;
/**
* Created by wenshao on 06/06/2017.
*/
public interface SQLReplaceable {
boolean replace(SQLExpr expr, SQLExpr target);
}
@@ -22,10 +22,12 @@ import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLExprImpl;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.Utils;
public class SQLBinaryOpExpr extends SQLExprImpl implements Serializable {
public class SQLBinaryOpExpr extends SQLExprImpl implements SQLReplaceable, Serializable {
private static final long serialVersionUID = 1L;
private SQLExpr left;
@@ -310,6 +312,39 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements Serializable {
return new SQLBinaryOpExpr(a, SQLBinaryOperator.BooleanAnd, b);
}
public static SQLExpr andIfNotExists(SQLExpr a, SQLExpr b) {
if (a == null) {
return b;
}
if (b == null) {
return a;
}
List<SQLExpr> groupListA = new ArrayList<SQLExpr>();
List<SQLExpr> groupListB = new ArrayList<SQLExpr>();
split(groupListA, a, SQLBinaryOperator.BooleanAnd);
split(groupListB, a, SQLBinaryOperator.BooleanAnd);
for (SQLExpr itemB : groupListB) {
boolean exist = false;
for (SQLExpr itemA : groupListA) {
if (itemA.equals(itemB)) {
exist = true;
} else if (itemA instanceof SQLBinaryOpExpr
&& itemB instanceof SQLBinaryOpExpr) {
if (((SQLBinaryOpExpr) itemA).equalsIgoreOrder((SQLBinaryOpExpr) itemB)) {
exist = true;
}
}
}
if (!exist) {
groupListA.add(itemB);
}
}
return combine(groupListA, SQLBinaryOperator.BooleanAnd);
}
public static SQLBinaryOpExpr isNotNull(SQLExpr expr) {
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.IsNot, new SQLNullExpr());
}
@@ -317,4 +352,34 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements Serializable {
public static SQLBinaryOpExpr isNull(SQLExpr expr) {
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.Is, new SQLNullExpr());
}
public boolean replace(SQLExpr expr, SQLExpr taget) {
SQLObject parent = getParent();
if (left == expr) {
if (taget == null) {
if (parent instanceof SQLReplaceable) {
return ((SQLReplaceable) parent).replace(this, right);
} else {
return false;
}
}
this.setLeft(taget);
return true;
}
if (right == expr) {
if (taget == null) {
if (parent instanceof SQLReplaceable) {
return ((SQLReplaceable) parent).replace(this, left);
} else {
return false;
}
}
this.setRight(taget);
return true;
}
return false;
}
}
@@ -22,9 +22,10 @@ import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLExprImpl;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLCaseExpr extends SQLExprImpl implements Serializable {
public class SQLCaseExpr extends SQLExprImpl implements SQLReplaceable, Serializable {
private static final long serialVersionUID = 1L;
private final List<Item> items = new ArrayList<Item>();
@@ -77,7 +78,22 @@ public class SQLCaseExpr extends SQLExprImpl implements Serializable {
visitor.endVisit(this);
}
public static class Item extends SQLObjectImpl implements Serializable {
@Override
public boolean replace(SQLExpr expr, SQLExpr target) {
if (valueExpr == expr) {
setValueExpr(target);
return true;
}
if (elseExpr == expr) {
setElseExpr(target);
return true;
}
return false;
}
public static class Item extends SQLObjectImpl implements SQLReplaceable, Serializable {
private static final long serialVersionUID = 1L;
private SQLExpr conditionExpr;
@@ -158,6 +174,21 @@ public class SQLCaseExpr extends SQLExprImpl implements Serializable {
}
return x;
}
@Override
public boolean replace(SQLExpr expr, SQLExpr target) {
if (valueExpr == expr) {
setValueExpr(target);
return true;
}
if (conditionExpr == expr) {
setConditionExpr(target);
return true;
}
return false;
}
}
@Override
@@ -21,10 +21,11 @@ import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLExprImpl;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLMethodInvokeExpr extends SQLExprImpl implements Serializable {
public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable, Serializable {
private static final long serialVersionUID = 1L;
private String methodName;
@@ -164,4 +165,16 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements Serializable {
return x;
}
@Override
public boolean replace(SQLExpr expr, SQLExpr target) {
for (int i = 0; i < parameters.size(); ++i) {
if (parameters.get(i) == expr) {
parameters.set(i, target);
target.setParent(this);
return true;
}
}
return false;
}
}
@@ -17,9 +17,10 @@ package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLAssignItem extends SQLObjectImpl {
public class SQLAssignItem extends SQLObjectImpl implements SQLReplaceable {
private SQLExpr target;
private SQLExpr value;
@@ -69,4 +70,17 @@ public class SQLAssignItem extends SQLObjectImpl {
visitor.endVisit(this);
}
@Override
public boolean replace(SQLExpr expr, SQLExpr target) {
if (this.target == expr) {
setTarget(target);
return true;
}
if (this.value == expr) {
setValue(target);
return true;
}
return false;
}
}
@@ -186,7 +186,7 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
return null;
}
public SQLTableElement findKey(String columnName) {
public SQLTableElement findIndex(String columnName) {
for (SQLTableElement element : tableElementList) {
List<SQLExpr> keyColumns = null;
if (element instanceof SQLUniqueConstraint) {
@@ -17,11 +17,12 @@ 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.SQLReplaceable;
import com.alibaba.druid.sql.ast.SQLStatementImpl;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLDeleteStatement extends SQLStatementImpl {
public class SQLDeleteStatement extends SQLStatementImpl implements SQLReplaceable {
protected SQLTableSource tableSource;
protected SQLExpr where;
@@ -121,4 +122,13 @@ public class SQLDeleteStatement extends SQLStatementImpl {
}
this.from = from;
}
@Override
public boolean replace(SQLExpr expr, SQLExpr target) {
if (where == expr) {
setWhere(target);
return true;
}
return false;
}
}
@@ -19,9 +19,10 @@ import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLJoinTableSource extends SQLTableSourceImpl {
public class SQLJoinTableSource extends SQLTableSourceImpl implements SQLReplaceable {
protected SQLTableSource left;
protected JoinType joinType;
@@ -139,6 +140,16 @@ public class SQLJoinTableSource extends SQLTableSourceImpl {
return using != null ? using.equals(that.using) : that.using == null;
}
@Override
public boolean replace(SQLExpr expr, SQLExpr target) {
if (condition == expr) {
setCondition(target);
return true;
}
return false;
}
public static enum JoinType {
COMMA(","), //
JOIN("JOIN"), //
@@ -18,11 +18,12 @@ package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLSelectItem extends SQLObjectImpl {
public class SQLSelectItem extends SQLObjectImpl implements SQLReplaceable {
protected SQLExpr expr;
protected String alias;
@@ -146,4 +147,14 @@ public class SQLSelectItem extends SQLObjectImpl {
x.connectByRoot = connectByRoot;
return x;
}
@Override
public boolean replace(SQLExpr expr, SQLExpr target) {
if (expr == expr) {
setExpr(target);
return true;
}
return false;
}
}
@@ -18,9 +18,10 @@ package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.SQLOrderingSpecification;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLSelectOrderByItem extends SQLObjectImpl {
public class SQLSelectOrderByItem extends SQLObjectImpl implements SQLReplaceable {
protected SQLExpr expr;
protected String collate;
@@ -104,6 +105,15 @@ public class SQLSelectOrderByItem extends SQLObjectImpl {
return true;
}
@Override
public boolean replace(SQLExpr expr, SQLExpr target) {
if (this.expr == expr) {
this.setExpr(target);
return true;
}
return false;
}
public static enum NullsOrderType {
NullsFirst, NullsLast;
@@ -18,13 +18,10 @@ 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.SQLLimit;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery {
public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery, SQLReplaceable {
private boolean bracket = false;
protected int distionOption;
protected final List<SQLSelectItem> selectList = new ArrayList<SQLSelectItem>();
@@ -415,4 +412,13 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
return null;
}
@Override
public boolean replace(SQLExpr expr, SQLExpr target) {
if (where == expr) {
setWhere(target);
return true;
}
return false;
}
}
@@ -20,10 +20,11 @@ import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.ast.SQLStatementImpl;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLUpdateStatement extends SQLStatementImpl {
public class SQLUpdateStatement extends SQLStatementImpl implements SQLReplaceable {
protected final List<SQLUpdateSetItem> items = new ArrayList<SQLUpdateSetItem>();
protected SQLExpr where;
@@ -131,4 +132,13 @@ public class SQLUpdateStatement extends SQLStatementImpl {
}
visitor.endVisit(this);
}
@Override
public boolean replace(SQLExpr expr, SQLExpr target) {
if (where == expr) {
setWhere(target);
return true;
}
return false;
}
}