improved sql parser.

This commit is contained in:
wenshao
2017-08-30 21:38:31 +08:00
parent a3e607e6eb
commit ce2daf6b9a
5 changed files with 86 additions and 71 deletions
@@ -23,7 +23,6 @@ import com.alibaba.druid.util.FnvHash;
public class SQLIdentifierExpr extends SQLExprImpl implements SQLName {
protected String name;
private String lowerName;
private long hashCode64;
private SQLObject resolvedColumn;
@@ -52,15 +51,12 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName {
public void setName(String name) {
this.name = name;
this.lowerName = null;
this.hashCode64 = 0L;
}
public String getLowerName() {
if (lowerName == null && name != null) {
lowerName = name.toLowerCase();
if (parent instanceof SQLPropertyExpr) {
SQLPropertyExpr propertyExpr = (SQLPropertyExpr) parent;
propertyExpr.computeHashCode64();
}
return lowerName;
}
public long nameHashCode64() {
@@ -22,14 +22,14 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.FnvHash;
public class SQLPropertyExpr extends SQLExprImpl implements SQLName {
private SQLExpr owner;
private String name;
private SQLExpr owner;
private String name;
private transient long nameHashCod64;
private transient long hashCode64;
protected long nameHashCod64;
protected long hashCode64;
private transient SQLColumnDefinition resolvedColumn;
private transient SQLObject resolvedOwnerObject;
protected SQLColumnDefinition resolvedColumn;
protected SQLObject resolvedOwnerObject;
public SQLPropertyExpr(String owner, String name){
this(new SQLIdentifierExpr(owner), name);
@@ -70,10 +70,35 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName {
if (owner != null) {
owner.setParent(this);
}
if (parent instanceof SQLPropertyExpr) {
SQLPropertyExpr propertyExpr = (SQLPropertyExpr) parent;
propertyExpr.computeHashCode64();
}
this.owner = owner;
this.hashCode64 = 0;
}
protected void computeHashCode64() {
long hash;
if (owner instanceof SQLName) {
hash = ((SQLName) owner).hashCode64();
hash ^= '.';
hash *= FnvHash.PRIME;
} else if (owner == null){
hash = FnvHash.BASIC;
} else {
hash = FnvHash.fnv1a_64_lower(owner.toString());
hash ^= '.';
hash *= FnvHash.PRIME;
}
hash = FnvHash.hashCode64(hash, name);
hashCode64 = hash;
}
public void setOwner(String owner) {
this.setOwner(new SQLIdentifierExpr(owner));
}
@@ -86,6 +111,11 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName {
this.name = name;
this.hashCode64 = 0;
this.nameHashCod64 = 0;
if (parent instanceof SQLPropertyExpr) {
SQLPropertyExpr propertyExpr = (SQLPropertyExpr) parent;
propertyExpr.computeHashCode64();
}
}
public void output(StringBuffer buf) {
@@ -110,22 +140,7 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName {
public long hashCode64() {
if (hashCode64 == 0) {
long hash;
if (owner instanceof SQLName) {
hash = ((SQLName) owner).hashCode64();
hash ^= '.';
hash *= FnvHash.PRIME;
} else if (owner == null){
hash = FnvHash.BASIC;
} else {
hash = FnvHash.fnv1a_64_lower(owner.toString());
hash ^= '.';
hash *= FnvHash.PRIME;
}
hash = FnvHash.hashCode64(hash, name);
hashCode64 = hash;
computeHashCode64();
}
return hashCode64;
@@ -512,6 +512,10 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
}
public boolean selectItemHasAllColumn() {
return selectItemHasAllColumn(true);
}
public boolean selectItemHasAllColumn(boolean recursive) {
for (SQLSelectItem item : this.selectList) {
SQLExpr expr = item.getExpr();
@@ -519,7 +523,7 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
|| (expr instanceof SQLPropertyExpr && ((SQLPropertyExpr) expr).getName().equals("*"));
if (allColumn) {
if (from instanceof SQLSubqueryTableSource) {
if (recursive && from instanceof SQLSubqueryTableSource) {
SQLSelect subSelect = ((SQLSubqueryTableSource) from).select;
SQLSelectQueryBlock queryBlock = subSelect.getQueryBlock();
if (queryBlock != null) {
@@ -576,32 +580,4 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
setLimit(limit);
}
public int selectIndexOf(SQLExpr expr) {
String ident = null;
if (expr instanceof SQLIdentifierExpr) {
ident = ((SQLIdentifierExpr) expr).getName();
}
for (int i = 0; i < selectList.size(); i++) {
SQLSelectItem selectItem = selectList.get(i);
if (ident != null && SQLUtils.nameEquals(ident, selectItem.alias)) {
return i;
}
SQLExpr selectItemExpr = selectItem.getExpr();
if (selectItemExpr instanceof SQLName) {
String name = ((SQLName) selectItemExpr).getSimpleName();
if (SQLUtils.nameEquals(ident, name)) {
return i;
}
}
if (expr.equals(selectItemExpr)) {
return i;
}
}
return -1;
}
}
@@ -16,6 +16,7 @@
package com.alibaba.druid.sql.dialect.mysql.ast.clause;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStatementImpl;
@@ -36,9 +37,16 @@ public class MySqlCursorDeclareStatement extends MySqlStatementImpl{
}
public void setCursorName(SQLName cursorName) {
if (cursorName != null) {
cursorName.setParent(this);
}
this.cursorName = cursorName;
}
public void setCursorName(String cursorName) {
this.setCursorName(new SQLIdentifierExpr(cursorName));
}
public SQLSelect getSelect() {
return select;
}
@@ -16,12 +16,15 @@
package com.alibaba.druid.sql.dialect.mysql.visitor.transform;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitorAdapter;
import com.alibaba.druid.util.FnvHash;
import java.util.ArrayList;
import java.util.List;
@@ -30,6 +33,8 @@ import java.util.List;
* Created by wenshao on 27/07/2017.
*/
public class OrderByResolve extends OracleASTVisitorAdapter {
final static long DBMS_RANDOM_VALUE = FnvHash.hashCode64("DBMS_RANDOM.value");
public boolean visit(SQLSelect x) {
SQLSelectQueryBlock queryBlock = x.getQueryBlock();
if (queryBlock == null) {
@@ -46,23 +51,38 @@ public class OrderByResolve extends OracleASTVisitorAdapter {
return super.visit(x);
}
List<SQLSelectOrderByItem> notContainsOrderBy = new ArrayList<SQLSelectOrderByItem>();
for (SQLSelectOrderByItem orderByItem : orderBy.getItems()) {
SQLExpr orderByExpr = orderByItem.getExpr();
if (queryBlock.selectIndexOf(orderByExpr) == -1) {
notContainsOrderBy.add(orderByItem);
if (!queryBlock.selectItemHasAllColumn(false)) {
List<SQLSelectOrderByItem> notContainsOrderBy = new ArrayList<SQLSelectOrderByItem>();
for (SQLSelectOrderByItem orderByItem : orderBy.getItems()) {
SQLExpr orderByExpr = orderByItem.getExpr();
if (orderByExpr instanceof SQLName) {
if (((SQLName) orderByExpr).hashCode64() == DBMS_RANDOM_VALUE) {
continue;
}
long hashCode64 = ((SQLName) orderByExpr).nameHashCode64();
SQLSelectItem selectItem = queryBlock.findSelectItem(hashCode64);
if (selectItem == null) {
queryBlock.addSelectItem(orderByExpr.clone());
}
}
}
if (notContainsOrderBy.size() > 0) {
for (SQLSelectOrderByItem orderByItem : notContainsOrderBy) {
queryBlock.addSelectItem(orderByItem.getExpr());
}
OracleSelectQueryBlock queryBlock1 = new OracleSelectQueryBlock();
queryBlock1.setFrom(queryBlock, "x");
x.setQuery(queryBlock1);
}
}
if (notContainsOrderBy.size() > 0) {
for (SQLSelectOrderByItem orderByItem : notContainsOrderBy) {
queryBlock.addSelectItem(orderByItem.getExpr());
}
OracleSelectQueryBlock queryBlock1 = new OracleSelectQueryBlock();
queryBlock1.setFrom(queryBlock, "x");
x.setQuery(queryBlock1);
}
return super.visit(x);
}