mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user