improved sql parser.

This commit is contained in:
wenshao
2017-06-04 21:30:23 +08:00
parent de4bfb0ae3
commit 21ae9b5722
63 changed files with 1049 additions and 350 deletions
@@ -26,6 +26,6 @@ public abstract class SQLExprImpl extends SQLObjectImpl implements SQLExpr {
public abstract int hashCode();
public SQLExpr clone() {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException(this.getClass().getName());
}
}
@@ -71,7 +71,17 @@ public class SQLLimit extends SQLObjectImpl {
}
public SQLLimit clone() {
throw new UnsupportedOperationException();
SQLLimit x = new SQLLimit();
if (offset != null) {
x.setOffset(offset.clone());
}
if (rowCount != null) {
x.setRowCount(rowCount.clone());
}
return x;
}
}
@@ -209,6 +209,6 @@ public abstract class SQLObjectImpl implements SQLObject {
}
public SQLObject clone() {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException(this.getClass().getName());
}
}
@@ -98,6 +98,16 @@ public class SQLOrderBy extends SQLObjectImpl {
}
public SQLOrderBy clone() {
throw new UnsupportedOperationException();
SQLOrderBy x = new SQLOrderBy();
for (SQLSelectOrderByItem item : items) {
SQLSelectOrderByItem item1 = item.clone();
item1.setParent(x);
x.items.add(item1);
}
x.sibings = sibings;
return x;
}
}
@@ -40,4 +40,8 @@ public class SQLAllColumnExpr extends SQLExprImpl {
public boolean equals(Object o) {
return o instanceof SQLAllColumnExpr;
}
public SQLAllColumnExpr clone() {
return new SQLAllColumnExpr();
}
}
@@ -16,6 +16,8 @@
package com.alibaba.druid.sql.ast.expr;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
@@ -152,4 +154,139 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements Serializable {
public String toString() {
return SQLUtils.toSQLString(this, getDbType());
}
public static SQLExpr combine(List<SQLExpr> items, SQLBinaryOperator op) {
if (items == null || op == null) {
return null;
}
int size = items.size();
if (size == 0) {
return null;
}
if (size == 1) {
return items.get(0);
}
SQLBinaryOpExpr expr = new SQLBinaryOpExpr(items.get(0), op, items.get(1));
for (int i = 2; i < size; ++i) {
SQLExpr item = items.get(i);
expr = new SQLBinaryOpExpr(expr, op, item);
}
return expr;
}
public static List<SQLExpr> split(SQLBinaryOpExpr x) {
return split(x, x.getOperator());
}
public static List<SQLExpr> split(SQLBinaryOpExpr x, SQLBinaryOperator op) {
if (x.getOperator() != op) {
List<SQLExpr> groupList = new ArrayList<SQLExpr>(1);
groupList.add(x);
return groupList;
}
List<SQLExpr> groupList = new ArrayList<SQLExpr>();
split(groupList, x, op);
return groupList;
}
public static void split(List<SQLExpr> outList, SQLExpr expr, SQLBinaryOperator op) {
if (expr == null) {
return;
}
if (!(expr instanceof SQLBinaryOpExpr)) {
outList.add(expr);
return;
}
SQLBinaryOpExpr binaryExpr = (SQLBinaryOpExpr) expr;
if (binaryExpr.getOperator() != op) {
outList.add(binaryExpr);
return;
}
List<SQLExpr> rightList = new ArrayList<SQLExpr>();
rightList.add(binaryExpr.getRight());
for (SQLExpr left = binaryExpr.getLeft();;) {
if (left instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr leftBinary = (SQLBinaryOpExpr) left;
if (leftBinary.operator == op) {
left = ((SQLBinaryOpExpr) leftBinary).getLeft();
rightList.add(leftBinary.getRight());
} else {
outList.add(leftBinary);
break;
}
} else {
outList.add(left);
break;
}
}
for (int i = rightList.size() - 1; i >= 0; --i) {
SQLExpr right = rightList.get(i);
if (right instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryRight = (SQLBinaryOpExpr) right;
if (binaryRight.operator == op) {
{
SQLExpr rightLeft = binaryRight.getLeft();
if (rightLeft instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr rightLeftBinary = (SQLBinaryOpExpr) rightLeft;
if (rightLeftBinary.operator == op) {
split(outList, rightLeftBinary, op);
} else {
outList.add(rightLeftBinary);
}
} else {
outList.add(rightLeft);
}
}
{
SQLExpr rightRight = binaryRight.getRight();
if (rightRight instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr rightRightBinary = (SQLBinaryOpExpr) rightRight;
if (rightRightBinary.operator == op) {
split(outList, rightRightBinary, op);
} else {
outList.add(rightRightBinary);
}
} else {
outList.add(rightRight);
}
}
} else {
outList.add(binaryRight);
}
} else {
outList.add(right);
}
}
}
public static SQLExpr and(SQLExpr a, SQLExpr b) {
if (a == null) {
return b;
}
if (b == null) {
return a;
}
if (b instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr bb = (SQLBinaryOpExpr) b;
if (bb.operator == SQLBinaryOperator.BooleanAnd) {
return and(and(a, bb.left), bb.right);
}
}
return new SQLBinaryOpExpr(a, SQLBinaryOperator.BooleanAnd, b);
}
}
@@ -147,6 +147,17 @@ public class SQLCaseExpr extends SQLExprImpl implements Serializable {
return true;
}
public Item clone() {
Item x = new Item();
if (conditionExpr != null) {
x.setConditionExpr(conditionExpr.clone());
}
if (valueExpr != null) {
x.setValueExpr(valueExpr.clone());
}
return x;
}
}
@Override
@@ -195,4 +206,22 @@ public class SQLCaseExpr extends SQLExprImpl implements Serializable {
return true;
}
public SQLCaseExpr clone() {
SQLCaseExpr x = new SQLCaseExpr();
for (Item item : items) {
x.addItem(item.clone());
}
if (valueExpr != null) {
x.setValueExpr(valueExpr.clone());
}
if (elseExpr != null) {
x.setElseExpr(elseExpr.clone());
}
return x;
}
}
@@ -42,4 +42,8 @@ public class SQLNCharExpr extends SQLTextLiteralExpr {
visitor.visit(this);
visitor.endVisit(this);
}
public SQLNCharExpr clone() {
return new SQLNCharExpr(text);
}
}
@@ -86,4 +86,12 @@ public class SQLNotExpr extends SQLExprImpl implements Serializable {
}
return true;
}
public SQLNotExpr clone() {
SQLNotExpr x = new SQLNotExpr();
if (expr != null) {
x.setExpr(expr.clone());
}
return x;
}
}
@@ -48,4 +48,8 @@ public class SQLNullExpr extends SQLExprImpl implements SQLLiteralExpr, SQLValua
public Object getValue() {
return EVAL_VALUE_NULL;
}
public SQLNullExpr clone() {
return new SQLNullExpr();
}
}
@@ -76,4 +76,8 @@ public class SQLNumberExpr extends SQLNumericLiteralExpr {
}
return true;
}
public SQLNumberExpr clone() {
return new SQLNumberExpr(number);
}
}
@@ -47,6 +47,14 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName {
return this.owner;
}
public String getOwnernName() {
if (owner instanceof SQLIdentifierExpr) {
return ((SQLIdentifierExpr) owner).getName();
}
return null;
}
public void setOwner(SQLExpr owner) {
if (owner != null) {
owner.setParent(this);
@@ -123,4 +131,11 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName {
return propertyExpr;
}
public boolean matchOwner(String alias) {
if (owner instanceof SQLIdentifierExpr) {
return ((SQLIdentifierExpr) owner).getName().equalsIgnoreCase(alias);
}
return false;
}
}
@@ -18,6 +18,7 @@ package com.alibaba.druid.sql.ast.statement;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
@@ -271,14 +272,6 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen
alias = ((SQLPropertyExpr) name).getName();
}
if (alias.length() > 2) {
char c0 = alias.charAt(0);
char x0 = alias.charAt(alias.length() - 1);
if ((c0 == '"' && x0 == '"') || (c0 == '`' && x0 == '`')) {
alias = alias.substring(1, alias.length() - 1);
}
}
return alias;
return SQLUtils.normalize(alias);
}
}
@@ -19,9 +19,14 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
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.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.stat.TableStat;
public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLStatement {
@@ -152,5 +157,60 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
return !comments.isEmpty();
}
public String computeName() {
if (tableSource == null) {
return null;
}
SQLExpr expr = tableSource.getExpr();
if (expr instanceof SQLName) {
String name = ((SQLName) expr).getSimpleName();
return SQLUtils.normalize(name);
}
return null;
}
public SQLColumnDefinition findColumn(String columName) {
for (SQLTableElement element : tableElementList) {
if (element instanceof SQLColumnDefinition) {
SQLColumnDefinition column = (SQLColumnDefinition) element;
String name = column.computeAlias();
if (columName.equalsIgnoreCase(name)) {
return column;
}
}
}
return null;
}
public SQLTableElement findKey(String columnName) {
for (SQLTableElement element : tableElementList) {
List<SQLExpr> keyColumns = null;
if (element instanceof SQLUniqueConstraint) {
SQLUniqueConstraint unique = (SQLUniqueConstraint) element;
keyColumns = unique.getColumns();
} else if (element instanceof MySqlTableIndex) {
keyColumns = ((MySqlTableIndex) element).getColumns();
}
if (keyColumns == null) {
continue;
}
for (SQLExpr columnExpr : keyColumns) {
if (columnExpr instanceof SQLIdentifierExpr) {
String keyColumName = ((SQLIdentifierExpr) columnExpr).getName();
keyColumName = SQLUtils.normalize(keyColumName);
if (keyColumName.equalsIgnoreCase(columnName)) {
return element;
}
}
}
}
return null;
}
}
@@ -18,6 +18,7 @@ package com.alibaba.druid.sql.ast.statement;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -117,15 +118,7 @@ public class SQLExprTableSource extends SQLTableSourceImpl {
}
}
if (alias.length() > 2) {
char c0 = alias.charAt(0);
char x0 = alias.charAt(alias.length() - 1);
if ((c0 == '"' && x0 == '"') || (c0 == '`' && x0 == '`')) {
alias = alias.substring(1, alias.length() - 1);
}
}
return alias;
return SQLUtils.normalize(alias);
}
public SQLExprTableSource clone() {
@@ -135,6 +128,8 @@ public class SQLExprTableSource extends SQLTableSourceImpl {
}
public void cloneTo(SQLExprTableSource x) {
x.alias = alias;
if (expr != null) {
x.expr = expr.clone();
}
@@ -165,4 +165,33 @@ public class SQLJoinTableSource extends SQLTableSourceImpl {
return joinType.name;
}
}
public void cloneTo(SQLJoinTableSource x) {
x.alias = alias;
if (left != null) {
x.setLeft(left.clone());
}
x.joinType = joinType;
if (right != null) {
x.setRight(right.clone());
}
for (SQLExpr item : using) {
SQLExpr item2 = item.clone();
item2.setParent(x);
x.using.add(item2);
}
x.natural = natural;
}
public SQLJoinTableSource clone() {
SQLJoinTableSource x = new SQLJoinTableSource();
cloneTo(x);
return x;
}
}
@@ -33,7 +33,7 @@ public class SQLSelect extends SQLObjectImpl {
protected SQLObject restriction;
protected boolean forBrowse;
protected List<String> forXmlOptions = new ArrayList<String>(4);
protected List<String> forXmlOptions = null;
protected SQLExpr xmlPath;
protected SQLExpr rowCount;
@@ -148,7 +148,7 @@ public class SQLSelect extends SQLObjectImpl {
x.withSubQuery = this.withSubQuery;
x.query = this.query;
if (orderBy != null) {
x.setOrderBy(this.orderBy);
x.setOrderBy(this.orderBy.clone());
}
if (restriction != null) {
x.setRestriction(restriction.clone());
@@ -160,9 +160,39 @@ public class SQLSelect extends SQLObjectImpl {
}
}
x.forBrowse = forBrowse;
if (forXmlOptions != null) {
x.forXmlOptions = new ArrayList<String>(forXmlOptions);
}
if (xmlPath != null) {
x.setXmlPath(xmlPath.clone());
}
if (rowCount != null) {
x.setRowCount(rowCount.clone());
}
if (offset != null) {
x.setOffset(offset.clone());
}
return x;
}
public boolean isSimple() {
return withSubQuery == null
&& orderBy == null
&& (hints == null || hints.size() == 0)
&& restriction == null
&& (!forBrowse)
&& (forXmlOptions == null || forXmlOptions.size() == 0)
&& xmlPath == null
&& rowCount == null
&& offset == null;
}
public SQLObject getRestriction() {
return this.restriction;
}
@@ -183,11 +213,18 @@ public class SQLSelect extends SQLObjectImpl {
}
public List<String> getForXmlOptions() {
if (forXmlOptions == null) {
forXmlOptions = new ArrayList<String>(4);
}
return forXmlOptions;
}
public void setForXmlOptions(List<String> forXmlOptions) {
this.forXmlOptions = forXmlOptions;
public int getForXmlOptionsSize() {
if (forXmlOptions == null) {
return 0;
}
return forXmlOptions.size();
}
public SQLExpr getRowCount() {
@@ -15,6 +15,7 @@
*/
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.expr.SQLIdentifierExpr;
@@ -75,15 +76,7 @@ public class SQLSelectItem extends SQLObjectImpl {
}
}
if (alias.length() > 2) {
char c0 = alias.charAt(0);
char x0 = alias.charAt(alias.length() - 1);
if ((c0 == '"' && x0 == '"') || (c0 == '`' && x0 == '`')) {
alias = alias.substring(1, alias.length() - 1);
}
}
return alias;
return SQLUtils.normalize(alias);
}
public String getAlias() {
@@ -119,4 +119,15 @@ public class SQLSelectOrderByItem extends SQLObjectImpl {
throw new IllegalArgumentException();
}
}
public SQLSelectOrderByItem clone() {
SQLSelectOrderByItem x = new SQLSelectOrderByItem();
if (expr != null) {
x.setExpr(expr.clone());
}
x.collate = collate;
x.type = type;
x.nullsOrderType = nullsOrderType;
return x;
}
}
@@ -318,11 +318,11 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
public SQLSelectQueryBlock clone() {
SQLSelectQueryBlock x = new SQLSelectQueryBlock();
clone(x);
cloneTo(x);
return x;
}
public void clone(SQLSelectQueryBlock x) {
public void cloneTo(SQLSelectQueryBlock x) {
x.distionOption = distionOption;
@@ -69,6 +69,9 @@ public class SQLSubqueryTableSource extends SQLTableSourceImpl {
public SQLSubqueryTableSource clone() {
SQLSubqueryTableSource x = new SQLSubqueryTableSource();
x.alias = alias;
if (select != null) {
x.select = select.clone();
}
@@ -29,4 +29,6 @@ public interface SQLTableSource extends SQLObject {
List<SQLHint> getHints();
SQLTableSource clone();
String computeAlias();
}
@@ -64,7 +64,11 @@ public abstract class SQLTableSourceImpl extends SQLObjectImpl implements SQLTab
}
public SQLTableSource clone() {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException(this.getClass().getName());
}
public String computeAlias() {
return alias;
}
}