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:
@@ -22,17 +22,10 @@ import java.util.Map;
|
||||
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.SQLReplaceable;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
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;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.db2.visitor.DB2OutputVisitor;
|
||||
import com.alibaba.druid.sql.dialect.db2.visitor.DB2SchemaStatVisitor;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
|
||||
@@ -871,38 +864,8 @@ public class SQLUtils {
|
||||
|
||||
SQLObject parent = expr.getParent();
|
||||
|
||||
if (parent instanceof SQLBinaryOpExpr) {
|
||||
SQLBinaryOpExpr binaryParent = (SQLBinaryOpExpr) expr.getParent();
|
||||
if (binaryParent.getLeft() == expr) {
|
||||
binaryParent.setLeft(target);
|
||||
return true;
|
||||
} else if (binaryParent.getRight() == expr) {
|
||||
binaryParent.setRight(target);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (parent instanceof SQLSelectOrderByItem){
|
||||
SQLSelectOrderByItem orderByItem = (SQLSelectOrderByItem) parent;
|
||||
if (orderByItem.getExpr() == expr) {
|
||||
orderByItem.setExpr(target);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parent instanceof SQLMethodInvokeExpr) {
|
||||
SQLMethodInvokeExpr methodInvokeExpr = (SQLMethodInvokeExpr) parent;
|
||||
List<SQLExpr> parameters = methodInvokeExpr.getParameters();
|
||||
for (int i = 0; i < parameters.size(); ++i) {
|
||||
if (parameters.get(i) == expr) {
|
||||
parameters.set(i, target);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if (parent instanceof SQLReplaceable) {
|
||||
return ((SQLReplaceable) parent).replace(expr, target);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.repository;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUniqueConstraint;
|
||||
|
||||
/**
|
||||
* Created by wenshao on 03/06/2017.
|
||||
*/
|
||||
public class SchemaObject {
|
||||
public final String name;
|
||||
public final Type type;
|
||||
private SQLStatement statement;
|
||||
|
||||
public long rowCount = -1;
|
||||
|
||||
public SchemaObject(String name, Type type) {
|
||||
this(name, type, null);
|
||||
}
|
||||
|
||||
public SchemaObject(String name, Type type, SQLStatement statement) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.statement = statement;
|
||||
}
|
||||
|
||||
public static enum Type {
|
||||
Sequence, Table, Index
|
||||
}
|
||||
|
||||
public SQLStatement getStatement() {
|
||||
return statement;
|
||||
}
|
||||
|
||||
public SQLColumnDefinition findColumn(String columName) {
|
||||
if (statement == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (statement instanceof SQLCreateTableStatement) {
|
||||
return ((SQLCreateTableStatement) statement).findColumn(columName);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean matchIndex(String columnName) {
|
||||
if (statement == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (statement instanceof SQLCreateTableStatement) {
|
||||
SQLTableElement index = ((SQLCreateTableStatement) statement).findIndex(columnName);
|
||||
return index != null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean matchKey(String columnName) {
|
||||
if (statement == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (statement instanceof SQLCreateTableStatement) {
|
||||
SQLTableElement index = ((SQLCreateTableStatement) statement).findIndex(columnName);
|
||||
return index instanceof SQLUniqueConstraint;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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.repository;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitorAdapter;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
|
||||
/**
|
||||
* Created by wenshao on 03/06/2017.
|
||||
*/
|
||||
public class SchemaRepository {
|
||||
public Map<String, SchemaObject> objects = new ConcurrentSkipListMap<String, SchemaObject>();
|
||||
|
||||
public final SchemaVisitor visitor = new SchemaVisitor();
|
||||
|
||||
public SchemaObject findTable(String tableName) {
|
||||
String lowerName = tableName.toLowerCase();
|
||||
SchemaObject object = objects.get(lowerName);
|
||||
|
||||
if (object != null && object.type == SchemaObject.Type.Table) {
|
||||
return object;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void acceptDDL(String ddl, String dbType) {
|
||||
List<SQLStatement> stmtList = SQLUtils.parseStatements(ddl, dbType);
|
||||
for (SQLStatement stmt : stmtList) {
|
||||
accept(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
public void accept(SQLStatement stmt) {
|
||||
stmt.accept(visitor);
|
||||
}
|
||||
|
||||
public boolean isSequence(String name) {
|
||||
SchemaObject object = objects.get(name);
|
||||
return object != null
|
||||
&& object.type == SchemaObject.Type.Sequence;
|
||||
}
|
||||
|
||||
public class SchemaVisitor extends OracleASTVisitorAdapter {
|
||||
|
||||
public boolean visit(SQLDropSequenceStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
objects.remove(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateSequenceStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObject(name, SchemaObject.Type.Sequence);
|
||||
|
||||
objects.put(name.toLowerCase(), object);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(OracleCreateTableStatement x) {
|
||||
visit((SQLCreateTableStatement) x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateTableStatement x) {
|
||||
String name = x.computeName();
|
||||
SchemaObject object = new SchemaObject(name, SchemaObject.Type.Table, x);
|
||||
|
||||
objects.put(name.toLowerCase(), object);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateIndexStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObject(name, SchemaObject.Type.Index);
|
||||
|
||||
objects.put(name.toLowerCase(), object);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public SchemaObject findTable(SQLTableSource tableSource, String alias) {
|
||||
if (tableSource instanceof SQLExprTableSource) {
|
||||
if (alias.equalsIgnoreCase(tableSource.computeAlias())) {
|
||||
SQLExpr expr = ((SQLExprTableSource) tableSource).getExpr();
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
String tableName = ((SQLIdentifierExpr) expr).getName();
|
||||
SchemaObject tableObject = findTable(tableName);
|
||||
return tableObject;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (tableSource instanceof SQLJoinTableSource) {
|
||||
SQLJoinTableSource join = (SQLJoinTableSource) tableSource;
|
||||
SQLTableSource left = join.getLeft();
|
||||
|
||||
SchemaObject tableObject = findTable(left, alias);
|
||||
if (tableObject != null) {
|
||||
return tableObject;
|
||||
}
|
||||
|
||||
SQLTableSource right = join.getRight();
|
||||
tableObject = findTable(right, alias);
|
||||
return tableObject;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -924,6 +924,17 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
}
|
||||
|
||||
if (param instanceof SQLBinaryOpExpr) {
|
||||
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) param;
|
||||
SQLBinaryOperator op = binaryOpExpr.getOperator();
|
||||
if (op == SQLBinaryOperator.BooleanAnd || op == SQLBinaryOperator.BooleanOr) {
|
||||
incrementIndent();
|
||||
param.accept(this);
|
||||
decrementIndent();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
param.accept(this);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user