diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLExprUtils.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLExprUtils.java index d570c12a32..b458a9ec1f 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLExprUtils.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLExprUtils.java @@ -37,7 +37,7 @@ public class SQLExprUtils { if (clazz_a == SQLIdentifierExpr.class) { SQLIdentifierExpr x_a = (SQLIdentifierExpr) a; SQLIdentifierExpr x_b = (SQLIdentifierExpr) b; - return x_a.equals(x_b); + return x_a.hashCode() == x_b.hashCode(); } if (clazz_a == SQLBinaryOpExpr.class) { diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIdentifierExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIdentifierExpr.java index 4c23ee085f..5822f15ac1 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIdentifierExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIdentifierExpr.java @@ -26,14 +26,10 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName { protected String name; private transient String lowerName; - protected transient long hash_lower; - private transient Boolean parameter; + protected transient long hashCode64; - private transient SQLColumnDefinition resolvedColumn; - private transient SQLParameter resolvedParameter; - private transient SQLDeclareItem resolvedDeclareItem; - - private transient SQLObject resolvedOwnerObject; + private transient SQLObject resolvedColumn; + private transient SQLObject resolvedOwnerObject; public SQLIdentifierExpr(){ @@ -45,7 +41,7 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName { public SQLIdentifierExpr(String name, long hash_lower){ this.name = name; - this.hash_lower = hash_lower; + this.hashCode64 = hash_lower; } public String getSimpleName() { @@ -59,7 +55,7 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName { public void setName(String name) { this.name = name; this.lowerName = null; - this.hash_lower = 0L; + this.hashCode64 = 0L; } public String getLowerName() { @@ -75,37 +71,11 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName { @Override public long hashCode64() { - if (hash_lower == 0 + if (hashCode64 == 0 && name != null) { - final int len = name.length(); - - boolean quote = false; - - String name = this.name; - if (len > 2) { - char c0 = name.charAt(0); - char c1 = name.charAt(len - 1); - if ((c0 == '`' && c1 == '`') - || (c0 == '"' && c1 == '"') - || (c0 == '[' && c1 == ']')) { - quote = true; - } - } - if (quote) { - hash_lower = FNVUtils.fnv_64_lower(name, 1, len -1); - } else { - hash_lower = FNVUtils.fnv_64_lower(name); - } + hashCode64 = FNVUtils.fnv_64_lower_normalized(name); } - return hash_lower; - } - - public Boolean isParameter() { - return parameter; - } - - public void setParameter(Boolean parameter) { - this.parameter = parameter; + return hashCode64; } public void output(StringBuffer buf) { @@ -120,66 +90,18 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName { @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; + long value = hashCode64(); + return (int)(value ^ (value >>> 32)); } @Override public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } if (!(obj instanceof SQLIdentifierExpr)) { return false; } + SQLIdentifierExpr other = (SQLIdentifierExpr) obj; - if (name == null) { - if (other.name != null) { - return false; - } - } else if (!name.equals(other.name)) { - return false; - } - return true; - } - - public boolean equals(SQLIdentifierExpr other) { - if (name == other.name) { - return true; - } - - if (name == null || other.name == null) { - return false; - } - - return name.equals(other.name); - } - - public boolean equalsIgnoreCase(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof SQLIdentifierExpr)) { - return false; - } - SQLIdentifierExpr other = (SQLIdentifierExpr) obj; - if (name == null) { - if (other.name != null) { - return false; - } - - } else if (!SQLUtils.normalize(name).equalsIgnoreCase(SQLUtils.normalize(other.name))) { - return false; - } - return true; + return this.hashCode64() == other.hashCode64(); } public String toString() { @@ -187,7 +109,7 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName { } public SQLIdentifierExpr clone() { - SQLIdentifierExpr x = new SQLIdentifierExpr(this.name); + SQLIdentifierExpr x = new SQLIdentifierExpr(this.name, hashCode64); x.resolvedColumn = resolvedColumn; x.resolvedOwnerObject = resolvedOwnerObject; return x; @@ -198,7 +120,11 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName { } public SQLColumnDefinition getResolvedColumn() { - return resolvedColumn; + if (resolvedColumn instanceof SQLColumnDefinition) { + return (SQLColumnDefinition) resolvedColumn; + } + + return null; } public void setResolvedColumn(SQLColumnDefinition resolvedColumn) { @@ -226,22 +152,29 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName { } public SQLParameter getResolvedParameter() { - return resolvedParameter; + if (resolvedColumn instanceof SQLParameter) { + return (SQLParameter) this.resolvedColumn; + } + return null; } public void setResolvedParameter(SQLParameter resolvedParameter) { - this.resolvedParameter = resolvedParameter; + this.resolvedColumn = resolvedParameter; } public SQLDeclareItem getResolvedDeclareItem() { - return resolvedDeclareItem; + if (resolvedColumn instanceof SQLDeclareItem) { + return (SQLDeclareItem) this.resolvedColumn; + } + return null; } public void setResolvedDeclareItem(SQLDeclareItem resolvedDeclareItem) { - this.resolvedDeclareItem = resolvedDeclareItem; + this.resolvedColumn = resolvedDeclareItem; } public SQLDataType computeDataType() { + SQLColumnDefinition resolvedColumn = getResolvedColumn(); if (resolvedColumn != null) { return resolvedColumn.getDataType(); } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLColumnDefinition.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLColumnDefinition.java index 34f6bec677..e2fc571bf7 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLColumnDefinition.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLColumnDefinition.java @@ -380,7 +380,7 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen SQLIdentifierExpr identExpr = (SQLIdentifierExpr) this.name; String columnName = identExpr.getName(); columnName = SQLUtils.normalize(columnName, dbType); - identExpr.setName(columnName); + this.setName(columnName); } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java index b14f03bdf0..10c75315de 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java @@ -584,7 +584,7 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS SQLIdentifierExpr identExpr = (SQLIdentifierExpr) name; String tableName = identExpr.getName(); tableName = SQLUtils.normalize(tableName, dbType); - identExpr.setName(tableName); + setName(tableName); } for (SQLTableElement element : this.tableElementList) { diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java index 39b10f61fd..bd65a5395b 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java @@ -60,6 +60,10 @@ public class SQLExprTableSource extends SQLTableSourceImpl { this.expr = expr; } + public void setExpr(String name) { + this.setExpr(new SQLIdentifierExpr(name)); + } + public SQLName getName() { if (expr instanceof SQLName) { return (SQLName) expr; diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnique.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnique.java index 2066d5aac6..50790d7e38 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnique.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnique.java @@ -98,7 +98,7 @@ public class SQLUnique extends SQLConstraintImpl implements SQLUniqueConstraint, SQLIdentifierExpr identExpr = (SQLIdentifierExpr) column; String columnName = identExpr.getName(); columnName = SQLUtils.normalize(columnName, dbType); - identExpr.setName(columnName); + item.setExpr(new SQLIdentifierExpr(columnName)); } } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index ac46ec5454..303a6272e9 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -1643,7 +1643,7 @@ public class MySqlStatementParser extends SQLStatementParser { lexer.nextToken(); if (database instanceof SQLIdentifierExpr) { SQLIdentifierExpr ident = (SQLIdentifierExpr) database; - ident.setName(ident.getName() + "-" + strVal); + database = new SQLIdentifierExpr(ident.getName() + "-" + strVal); } } stmt.setDatabase(database); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java index 1809b7db3a..8cf9f85500 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java @@ -99,7 +99,6 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS if (x.getTableSource() instanceof SQLExprTableSource) { SQLName tableName = (SQLName) ((SQLExprTableSource) x.getTableSource()).getExpr(); String ident = tableName.toString(); - setCurrentTable(x, ident); TableStat stat = this.getTableStat(ident); stat.incrementDeleteCount(); @@ -146,8 +145,6 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS } if (ident != null) { - setCurrentTable(x, ident); - TableStat stat = getTableStat(ident); stat.incrementInsertCount(); @@ -318,8 +315,6 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS } if (ident != null) { - setCurrentTable(x, ident); - TableStat stat = getTableStat(ident); stat.incrementInsertCount(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/transform/FromSubqueryResolver.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/transform/FromSubqueryResolver.java index 1be1e16fc7..e0d387043e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/transform/FromSubqueryResolver.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/transform/FromSubqueryResolver.java @@ -88,7 +88,7 @@ public class FromSubqueryResolver extends OracleASTVisitorAdapter { String ident = identifierExpr.getName(); String mappingIdent = mappings.get(ident); if (mappingIdent != null) { - identifierExpr.setName(mappingIdent); + x.setExpr(new SQLIdentifierExpr(mappingIdent)); } } return false; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java index 070886bbb3..5c3193ee33 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java @@ -71,7 +71,6 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV if (tableName instanceof SQLName) { String ident = ((SQLName) tableName).toString(); - setCurrentTable(ident); TableStat stat = getTableStat(ident); stat.incrementInsertCount(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleRangeExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleRangeExpr.java index 7a9dde570b..023cbe5524 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleRangeExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleRangeExpr.java @@ -29,8 +29,8 @@ public class OracleRangeExpr extends OracleSQLObjectImpl implements SQLExpr { } public OracleRangeExpr(SQLExpr lowBound, SQLExpr upBound){ - this.lowBound = lowBound; - this.upBound = upBound; + setLowBound(lowBound); + setUpBound(upBound); } @Override @@ -47,6 +47,9 @@ public class OracleRangeExpr extends OracleSQLObjectImpl implements SQLExpr { } public void setLowBound(SQLExpr lowBound) { + if (lowBound != null) { + lowBound.setParent(this); + } this.lowBound = lowBound; } @@ -55,6 +58,9 @@ public class OracleRangeExpr extends OracleSQLObjectImpl implements SQLExpr { } public void setUpBound(SQLExpr upBound) { + if (upBound != null) { + upBound.setParent(this); + } this.upBound = upBound; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java index d62a337756..b0c9d723b8 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java @@ -164,7 +164,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle x.putAttribute(ATTR_TABLE, table); } } - restoreCurrentTable(x); } public boolean visit(OracleUpdateStatement x) { @@ -185,7 +184,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle if (tableExpr instanceof SQLName) { String ident = tableExpr.toString(); - setCurrentTable(ident); TableStat stat = getTableStat(ident); stat.incrementUpdateCount(); @@ -431,7 +429,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle this.aliasMap.put(x.getAlias(), table); } addSubQuery(x.getAlias(), x.getSelect()); - this.setCurrentTable(x.getAlias()); } if (table != null) { @@ -701,7 +698,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle if (x.getTableName() instanceof SQLName) { String ident = ((SQLName) x.getTableName()).toString(); - setCurrentTable(x, ident); TableStat stat = getTableStat(ident); stat.incrementInsertCount(); @@ -769,14 +765,9 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle } if (parent instanceof OracleMultiInsertStatement) { SQLSelect subQuery = ((OracleMultiInsertStatement) parent).getSubQuery(); - if (subQuery != null) { - String table = (String) subQuery.getAttribute("_table_"); - setCurrentTable(x, table); - } } x.getWhen().accept(this); x.getThen().accept(this); - restoreCurrentTable(x); return false; } @@ -935,7 +926,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public void endVisit(SQLAlterTableStatement x) { - restoreCurrentTable(x); } @Override @@ -1004,7 +994,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public void endVisit(OracleCreateIndexStatement x) { - restoreCurrentTable(x); } @Override diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java index 171f48f916..c1abe30383 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java @@ -112,7 +112,6 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit setMode(x, Mode.Delete); String ident = ((SQLIdentifierExpr) x.getTableName()).getName(); - setCurrentTable(ident); TableStat stat = getTableStat(ident, x.getAlias()); stat.incrementDeleteCount(); @@ -143,13 +142,10 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit x.putAttribute("_original_use_mode", getMode()); setMode(x, Mode.Insert); - String originalTable = getCurrentTable(); SQLName tableName = x.getTableName(); { String ident = tableName.toString(); - setCurrentTable(ident); - x.putAttribute("_old_local_", originalTable); TableStat stat = getTableStat(ident); stat.incrementInsertCount(); @@ -204,7 +200,6 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit } String ident = x.getTableName().toString(); - setCurrentTable(ident); TableStat stat = getTableStat(ident); stat.incrementUpdateCount(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java index c710696127..1d61a46eb5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java @@ -87,7 +87,6 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL setAliasMap(); String ident = x.getTableName().toString(); - setCurrentTable(ident); TableStat stat = getTableStat(ident); stat.incrementUpdateCount(); diff --git a/src/main/java/com/alibaba/druid/sql/repository/SchemaResolveVisitorFactory.java b/src/main/java/com/alibaba/druid/sql/repository/SchemaResolveVisitorFactory.java index a9180a6d85..81ab64e009 100644 --- a/src/main/java/com/alibaba/druid/sql/repository/SchemaResolveVisitorFactory.java +++ b/src/main/java/com/alibaba/druid/sql/repository/SchemaResolveVisitorFactory.java @@ -379,6 +379,37 @@ class SchemaResolveVisitorFactory { return false; } + public boolean visit(OracleForStatement x) { + Context ctx = createContext(x); + + SQLExpr index = x.getIndex(); + if (index != null) { + index.accept(this); + } + + SQLExpr range = x.getRange(); + if (range != null) { + range.accept(this); + } + + for (SQLStatement stmt : x.getStatements()) { + stmt.accept(this); + } + + popContext(); + return false; + } + + public boolean visit(SQLIfStatement x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLCreateFunctionStatement x) { + resolve(this, x); + return false; + } + public boolean visit(OracleSelectTableReference x) { resolve(this, x); return false; @@ -1444,17 +1475,11 @@ class SchemaResolveVisitorFactory { tableSource = ((OdpsLateralViewTableSource) ctxTable).getTableSource(); } } else { - SQLDeclareItem declareItem = ctx.findDeclare(hash); - if (declareItem != null) { - x.setResolvedDeclareItem(declareItem); - return; - } - - for (SchemaResolveVisitor.Context parentCtx = ctx.parent; + for (SchemaResolveVisitor.Context parentCtx = ctx; parentCtx != null; parentCtx = parentCtx.parent) { - declareItem = parentCtx.findDeclare(hash); + SQLDeclareItem declareItem = parentCtx.findDeclare(hash); if (declareItem != null) { x.setResolvedDeclareItem(declareItem); return; @@ -1731,7 +1756,7 @@ class SchemaResolveVisitorFactory { SQLExprTableSource into = x.getInto(); if (into != null) { - into.accept(visitor); + visitor.visit(into); } SQLExpr where = x.getWhere(); @@ -1944,6 +1969,8 @@ class SchemaResolveVisitorFactory { } if (identifierExpr != null) { + checkParameter(visitor, identifierExpr); + SQLTableSource tableSource = unwrapAlias(visitor.getContext(), null, identifierExpr.name_hash_lower()); if (tableSource != null) { identifierExpr.setResolvedTableSource(tableSource); @@ -2039,6 +2066,29 @@ class SchemaResolveVisitorFactory { visitor.popContext(); } + static void resolve(SchemaResolveVisitor visitor, SQLCreateFunctionStatement x) { + { + SchemaResolveVisitor.Context parentCtx = visitor.getContext(); + if (parentCtx != null) { + SQLDeclareItem declareItem = new SQLDeclareItem(x.getName().clone(), null); + declareItem.setResolvedObject(x); + parentCtx.declare(declareItem); + } + } + + SchemaResolveVisitor.Context ctx = visitor.createContext(x); + + for (SQLParameter parameter : x.getParameters()) { + parameter.accept(visitor); + } + + SQLStatement block = x.getBlock(); + if (block != null) { + block.accept(visitor); + } + + visitor.popContext(); + } static void resolve(SchemaResolveVisitor visitor, SQLCreateProcedureStatement x) { { SchemaResolveVisitor.Context parentCtx = visitor.getContext(); @@ -2052,7 +2102,7 @@ class SchemaResolveVisitorFactory { SchemaResolveVisitor.Context ctx = visitor.createContext(x); for (SQLParameter parameter : x.getParameters()) { - parameter.accept0(visitor); + parameter.accept(visitor); } SQLStatement block = x.getBlock(); @@ -2063,11 +2113,36 @@ class SchemaResolveVisitorFactory { visitor.popContext(); } + static boolean resolve(SchemaResolveVisitor visitor, SQLIfStatement x) { + SchemaResolveVisitor.Context ctx = visitor.createContext(x); + + SQLExpr condition = x.getCondition(); + if (condition != null) { + condition.accept(visitor); + } + + for (SQLStatement stmt : x.getStatements()) { + stmt.accept(visitor); + } + + for (SQLIfStatement.ElseIf elseIf : x.getElseIfList()) { + elseIf.accept(visitor); + } + + SQLIfStatement.Else e = x.getElseItem(); + if (e != null) { + e.accept(visitor); + } + + visitor.popContext(); + return false; + } + static void resolve(SchemaResolveVisitor visitor, SQLBlockStatement x) { SchemaResolveVisitor.Context ctx = visitor.createContext(x); for (SQLParameter parameter : x.getParameters()) { - parameter.accept0(visitor); + visitor.visit(parameter); } for (SQLStatement stmt : x.getStatementList()) { @@ -2083,6 +2158,11 @@ class SchemaResolveVisitorFactory { } static void resolve(SchemaResolveVisitor visitor, SQLParameter x) { + SQLName name = x.getName(); + if (name instanceof SQLIdentifierExpr) { + ((SQLIdentifierExpr) name).setResolvedParameter(x); + } + SQLExpr expr = x.getDefaultValue(); SchemaResolveVisitor.Context ctx = null; @@ -2116,4 +2196,41 @@ class SchemaResolveVisitorFactory { ((SQLIdentifierExpr) name).setResolvedDeclareItem(x); } } + + + private static boolean checkParameter(SchemaResolveVisitor visitor, SQLIdentifierExpr x) { + if (x.getResolvedParameter() != null) { + return true; + } + + SchemaResolveVisitor.Context ctx = visitor.getContext(); + if (ctx == null) { + return false; + } + + long hash = x.hashCode64(); + for (SchemaResolveVisitor.Context parentCtx = ctx; + parentCtx != null; + parentCtx = parentCtx.parent) { + + if (parentCtx.object instanceof SQLBlockStatement) { + SQLBlockStatement block = (SQLBlockStatement) parentCtx.object; + SQLParameter parameter = block.findParameter(hash); + if (parameter != null) { + x.setResolvedParameter(parameter); + return true; + } + } + + if (parentCtx.object instanceof SQLCreateProcedureStatement) { + SQLCreateProcedureStatement createProc = (SQLCreateProcedureStatement) parentCtx.object; + SQLParameter parameter = createProc.findParameter(hash); + if (parameter != null) { + x.setResolvedParameter(parameter); + return true; + } + } + } + return false; + } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java index 62f2446ae3..2f7c849018 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -214,28 +214,6 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { return aliasMap; } - public void setCurrentTable(String table) { - this.currentTable = table; - } - - public void setCurrentTable(SQLObject x) { - x.putAttribute("_old_local_", this.currentTable); - } - - public void restoreCurrentTable(SQLObject x) { - String table = (String) x.getAttribute("_old_local_"); - this.currentTable = table; - } - - public void setCurrentTable(SQLObject x, String table) { - x.putAttribute("_old_local_", this.currentTable); - this.currentTable = table; - } - - public String getCurrentTable() { - return currentTable; - } - protected Mode getMode() { return mode; } @@ -696,7 +674,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (expr instanceof SQLIdentifierExpr) { SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) expr; - if (isParam(identifierExpr)) { + if (identifierExpr.getResolvedParameter() != null) { return null; } @@ -710,7 +688,16 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } String column = identifierExpr.getName(); - String table = getCurrentTable(); + + String table = null; + SQLTableSource tableSource = identifierExpr.getResolvedTableSource(); + if (tableSource instanceof SQLExprTableSource) { + SQLName tableName = ((SQLExprTableSource) tableSource).getName(); + if (tableName != null) { + table = tableName.toString(); + } + } + if (table != null && aliasMap.containsKey(table)) { table = aliasMap.get(table); if (table == null) { @@ -738,14 +725,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { setAliasMap(); - String originalTable = getCurrentTable(); - for (SQLExprTableSource tableSource : x.getTableSources()) { SQLName name = (SQLName) tableSource.getExpr(); String ident = name.toString(); - setCurrentTable(ident); - x.putAttribute("_old_local_", originalTable); TableStat stat = getTableStat(ident); stat.incrementDeleteCount(); @@ -769,13 +752,9 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { setAliasMap(); - String originalTable = getCurrentTable(); - for (SQLExprTableSource tableSource : x.getTableSources()) { SQLName name = (SQLName) tableSource.getExpr(); String ident = name.toString(); - setCurrentTable(ident); - x.putAttribute("_old_local_", originalTable); TableStat stat = getTableStat(ident); stat.incrementDropCount(); @@ -798,12 +777,8 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { setAliasMap(); - String originalTable = getCurrentTable(); - if (x.getTableName() instanceof SQLName) { String ident = ((SQLName) x.getTableName()).toString(); - setCurrentTable(ident); - x.putAttribute("_old_local_", originalTable); TableStat stat = getTableStat(ident); stat.incrementInsertCount(); @@ -865,19 +840,15 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } } - String originalTable = getCurrentTable(); - if (x.getFrom() instanceof SQLExprTableSource) { SQLExprTableSource tableSource = (SQLExprTableSource) x.getFrom(); if (tableSource.getExpr() instanceof SQLName) { String ident = tableSource.getExpr().toString(); - setCurrentTable(x, ident); x.putAttribute(ATTR_TABLE, ident); if (x.getParent() instanceof SQLSelect) { x.getParent().putAttribute(ATTR_TABLE, ident); } - x.putAttribute("_old_local_", originalTable); } } @@ -903,40 +874,14 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } public static boolean isParam(SQLIdentifierExpr x) { - if (x.isParameter() != null) { - return x.isParameter(); - } - - for (SQLObject parent = x.getParent(); parent != null; parent = parent.getParent()) { - if (parent instanceof SQLCreateProcedureStatement) { - SQLCreateProcedureStatement stmt = (SQLCreateProcedureStatement) parent; - for (SQLParameter parameter : stmt.getParameters()) { - if (x.equals(parameter.getName())) { - x.setParameter(true); - return true; - } - } - break; - } - - if (parent instanceof SQLBlockStatement) { - SQLBlockStatement stmt = (SQLBlockStatement) parent; - for (SQLParameter parameter : stmt.getParameters()) { - if (x.equals(parameter.getName())) { - x.setParameter(true); - return true; - } - } - } + if (x.getResolvedParameter() != null + || x.getResolvedDeclareItem() != null) { + return true; } return false; } public void endVisit(SQLSelectQueryBlock x) { - String originalTable = (String) x.getAttribute("_old_local_"); - x.putAttribute("table", getCurrentTable()); - setCurrentTable(originalTable); - setModeOrigin(x); } @@ -1666,12 +1611,9 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } public void endVisit(SQLSelect x) { - restoreCurrentTable(x); } public boolean visit(SQLSelect x) { - setCurrentTable(x); - if (x.getOrderBy() != null) { x.getOrderBy().setParent(x); } @@ -1679,14 +1621,8 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { accept(x.getWithSubQuery()); accept(x.getQuery()); - String originalTable = getCurrentTable(); - - setCurrentTable((String) x.getQuery().getAttribute("table")); - x.putAttribute("_old_local_", originalTable); - accept(x.getOrderBy()); - setCurrentTable(originalTable); return false; } @@ -1720,7 +1656,6 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (tableSource instanceof SQLExprTableSource) { SQLName identName = ((SQLExprTableSource) tableSource).getName(); String ident = identName.toString(); - setCurrentTable(ident); TableStat stat = getTableStat(ident); stat.incrementUpdateCount(); @@ -1750,7 +1685,6 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { setMode(x, Mode.Delete); String tableName = x.getTableName().toString(); - setCurrentTable(tableName); if (x.getAlias() != null) { putAliasMap(this.aliasMap, x.getAlias(), tableName); @@ -1813,12 +1747,9 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { TableStat stat = getTableStat(tableName); stat.incrementCreateCount(); - setCurrentTable(x, tableName); accept(x.getTableElementList()); - restoreCurrentTable(x); - if (x.getInherits() != null) { x.getInherits().accept(this); } @@ -1942,7 +1873,6 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { TableStat stat = getTableStat(tableName); stat.incrementAlterCount(); - setCurrentTable(x, tableName); for (SQLAlterTableItem item : x.getItems()) { item.setParent(x); @@ -1965,7 +1895,6 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { SQLName name = (SQLName) table.getExpr(); String ident = name.toString(); - setCurrentTable(ident); TableStat stat = getTableStat(ident); stat.incrementDropIndexCount(); @@ -1983,7 +1912,6 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { SQLName name = (SQLName) ((SQLExprTableSource) x.getTable()).getExpr(); String table = name.toString(); - setCurrentTable(table); TableStat stat = getTableStat(table); stat.incrementCreateIndexCount(); @@ -2011,7 +1939,6 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } String table = x.getReferencedTableName().getSimpleName(); - setCurrentTable(table); TableStat stat = getTableStat(table); stat.incrementReferencedCount(); @@ -2303,16 +2230,12 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { setAliasMap(); - String originalTable = getCurrentTable(); - setMode(x.getUsing(), Mode.Select); x.getUsing().accept(this); setMode(x, Mode.Merge); String ident = x.getInto().toString(); - setCurrentTable(x, ident); - x.putAttribute("_old_local_", originalTable); TableStat stat = getTableStat(ident); stat.incrementMergeCount(); @@ -2440,5 +2363,4 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } return true; } - } diff --git a/src/main/java/com/alibaba/druid/stat/TableStat.java b/src/main/java/com/alibaba/druid/stat/TableStat.java index 1f6c01ee4d..3c1764b629 100644 --- a/src/main/java/com/alibaba/druid/stat/TableStat.java +++ b/src/main/java/com/alibaba/druid/stat/TableStat.java @@ -186,13 +186,13 @@ public class TableStat { } public static class Name { + private final String name; - private String name; - - private int hash; + private final long hash; public Name(String name){ this.name = name; + hash = FNVUtils.fnv_64_lower_normalized(name); } public String getName() { @@ -200,11 +200,12 @@ public class TableStat { } public int hashCode() { - int h = hash; - if (h == 0 && name != null && name.length() > 0) { - hash = h = StringUtils.lowerHashCode(name); - } - return h; + long value = hashCode64(); + return (int)(value ^ (value >>> 32)); + } + + public long hashCode64() { + return hash; } public boolean equals(Object o) { @@ -213,16 +214,7 @@ public class TableStat { } Name other = (Name) o; - - if (this.name == other.name) { - return true; - } - - if (this.name == null | other.name == null) { - return false; - } - - return this.name.equalsIgnoreCase(other.name); + return this.hash == other.hash; } public String toString() { @@ -410,6 +402,8 @@ public class TableStat { private final String table; private final String name; + protected final long hashCode64; + private boolean where; private boolean select; private boolean groupBy; @@ -428,11 +422,25 @@ public class TableStat { */ private String dataType; - protected long hashCode64; - public Column(String table, String name){ this.table = table; this.name = name; + + int p = table.indexOf('.'); + if (p != -1) { + String dbType = null; + if (table.indexOf('`') != -1) { + dbType = JdbcConstants.MYSQL; + } else if (table.indexOf('[') != -1) { + dbType = JdbcConstants.SQL_SERVER; + } else if (table.indexOf('@') != -1) { + dbType = JdbcConstants.ORACLE; + } + SQLExpr owner = SQLUtils.toSQLExpr(table, dbType); + hashCode64 = FNVUtils.fnv_64_lower(new SQLPropertyExpr(owner, name)); + } else { + hashCode64 = FNVUtils.fnv_64_lower(table, name); + } } public String getTable() { @@ -452,24 +460,6 @@ public class TableStat { } public long hashCode64() { - if (hashCode64 == 0) { - int p = table.indexOf('.'); - if (p != -1) { - String dbType = null; - if (table.indexOf('`') != -1) { - dbType = JdbcConstants.MYSQL; - } else if (table.indexOf('[') != -1) { - dbType = JdbcConstants.SQL_SERVER; - } else if (table.indexOf('@') != -1) { - dbType = JdbcConstants.ORACLE; - } - SQLExpr owner = SQLUtils.toSQLExpr(table, dbType); - hashCode64 = FNVUtils.fnv_64_lower(new SQLPropertyExpr(owner, name)); - } else { - hashCode64 = FNVUtils.fnv_64_lower(table, name); - } - } - return hashCode64; } @@ -574,8 +564,7 @@ public class TableStat { } Column column = (Column) obj; - - return hashCode64() == column.hashCode64(); + return hashCode64 == column.hashCode64; } } diff --git a/src/test/java/com/alibaba/druid/benckmark/sql/MySqlParameterizedBenchmark.java b/src/test/java/com/alibaba/druid/benckmark/sql/MySqlParameterizedBenchmark.java index e73cd0f74c..cca1897ee6 100644 --- a/src/test/java/com/alibaba/druid/benckmark/sql/MySqlParameterizedBenchmark.java +++ b/src/test/java/com/alibaba/druid/benckmark/sql/MySqlParameterizedBenchmark.java @@ -38,7 +38,7 @@ public class MySqlParameterizedBenchmark extends TestCase { // perf_parse(sql3); // 9174 5875 5805 5536 5717 // perf_parse(sql4); // 2953 2502 - perf_stat(sql); // 11793 13628 13561 13259 + perf_stat(sql); // 11793 13628 13561 13259 9909 // perf_resolve(sql); // 4970 4586 } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/create/MySqlCreateProcedureTest8.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/create/MySqlCreateProcedureTest8.java index 2256dead92..5c7f1ed03a 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/create/MySqlCreateProcedureTest8.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/create/MySqlCreateProcedureTest8.java @@ -65,6 +65,8 @@ public class MySqlCreateProcedureTest8 extends MysqlTest { // print(statementList); assertEquals(1, statementList.size()); + System.out.println(stmt); + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.MYSQL); stmt.accept(visitor); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_29.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_29.java index 63d12e7ca2..93c1c8d754 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_29.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_29.java @@ -38,15 +38,17 @@ public class MySqlSelectTest_29 extends MysqlTest { SQLStatement stmt = statementList.get(0); // print(statementList); + System.out.println(stmt); + Assert.assertEquals(1, statementList.size()); MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); stmt.accept(visitor); -// System.out.println("Tables : " + visitor.getTables()); -// System.out.println("fields : " + visitor.getColumns()); -// System.out.println("coditions : " + visitor.getConditions()); -// System.out.println("orderBy : " + visitor.getOrderByColumns()); + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); Assert.assertEquals(2, visitor.getTables().size()); Assert.assertEquals(6, visitor.getColumns().size()); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/block/OracleBlockTest1.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/block/OracleBlockTest1.java index 95956191d3..6d72cb80fb 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/block/OracleBlockTest1.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/block/OracleBlockTest1.java @@ -31,13 +31,14 @@ public class OracleBlockTest1 extends OracleTest { OracleStatementParser parser = new OracleStatementParser(sql); List statementList = parser.parseStatementList(); - SQLStatement statemen = statementList.get(0); - print(statementList); + SQLStatement stmt = statementList.get(0); Assert.assertEquals(1, statementList.size()); + System.out.println(stmt); + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); - statemen.accept(visitor); + stmt.accept(visitor); System.out.println("Tables : " + visitor.getTables()); System.out.println("fields : " + visitor.getColumns()); diff --git a/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo1.java b/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo1.java index 3e0fbe8703..087b7b87c2 100644 --- a/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo1.java +++ b/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo1.java @@ -123,7 +123,7 @@ public class Demo1 extends TestCase { String tableName = identExpr.getName(); if (tableName.equals("user")) { - identExpr.setName(this.tableName); + x.setExpr(this.tableName); } } else if (expr instanceof SQLPropertyExpr) { SQLPropertyExpr proExpr = (SQLPropertyExpr) expr; @@ -144,7 +144,7 @@ public class Demo1 extends TestCase { String tableName = identExpr.getName(); if (tableName.equals("user")) { - identExpr.setName(this.tableName); + x.setExpr(this.tableName); } } else if (expr instanceof SQLPropertyExpr) { SQLPropertyExpr proExpr = (SQLPropertyExpr) expr; diff --git a/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo2.java b/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo2.java index d43f628ed9..4fb02a8673 100644 --- a/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo2.java +++ b/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo2.java @@ -74,7 +74,7 @@ public class Demo2 extends TestCase { String ident = identExpr.getName(); if (ident.equals("user")) { - identExpr.setName(tableName); + tableSource.setExpr(tableName); } } else if (expr instanceof SQLPropertyExpr) { SQLPropertyExpr proExpr = (SQLPropertyExpr) expr; diff --git a/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo3.java b/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo3.java index 735555c4ef..414c5530ee 100644 --- a/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo3.java +++ b/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo3.java @@ -113,7 +113,7 @@ public class Demo3 extends TestCase { String ident = identExpr.getName(); if (ident.equals("user")) { - identExpr.setName(tableName); + tableSource.setExpr(new SQLIdentifierExpr(tableName)); } } else if (expr instanceof SQLPropertyExpr) { SQLPropertyExpr proExpr = (SQLPropertyExpr) expr;