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 6560b1956a..8c98390f97 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 @@ -59,7 +59,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS if (x.getTableNames().size() == 1) { String ident = ((SQLIdentifierExpr) x.getTableNames().get(0)).getName(); - setCurrentTable(ident); + setCurrentTable(x, ident); } for (SQLName tableName : x.getTableNames()) { @@ -96,12 +96,9 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS setAliasMap(); - String originalTable = currentTableLocal.get(); - if (x.getTableName() instanceof SQLIdentifierExpr) { String ident = ((SQLIdentifierExpr) x.getTableName()).getName(); - setCurrentTable(ident); - x.putAttribute("_old_local_", originalTable); + setCurrentTable(x, ident); TableStat stat = tableStats.get(ident); if (stat == null) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java index 38ad53338e..b82537342e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java @@ -288,6 +288,10 @@ public class OracleStatementParser extends SQLStatementParser { if (lexer.token() == Token.COMMIT) { lexer.nextToken(); + + if (identifierEquals("WORK")) { + lexer.nextToken(); + } OracleCommitStatement stmt = new OracleCommitStatement(); statementList.add(stmt); continue; 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 5b0cc0c8cd..d348bd3e3b 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 @@ -231,19 +231,15 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle accept(x.getFactoring()); accept(x.getQuery()); - String originalTable = currentTableLocal.get(); - - setCurrentTable((String) x.getQuery().getAttribute("table")); - x.putAttribute("_old_local_", originalTable); + setCurrentTable(x, (String) x.getQuery().getAttribute("table")); accept(x.getOrderBy()); - setCurrentTable(originalTable); - return false; } public void endVisit(SQLSelect x) { + restoreCurrentTable(x); } public boolean visit(OracleUpdateStatement x) { @@ -941,12 +937,12 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle setMode(x, Mode.Merge); - String originalTable = currentTableLocal.get(); + String originalTable = getCurrentTable(); x.getUsing().accept(this); String ident = x.getInto().toString(); - setCurrentTable(ident); + setCurrentTable(x, ident); x.putAttribute("_old_local_", originalTable); TableStat stat = tableStats.get(ident); @@ -1034,12 +1030,10 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public boolean visit(InsertIntoClause x) { - String originalTable = currentTableLocal.get(); if (x.getTableName() instanceof SQLName) { String ident = ((SQLName) x.getTableName()).toString(); - setCurrentTable(ident); - x.putAttribute("_old_local_", originalTable); + setCurrentTable(x, ident); TableStat stat = tableStats.get(ident); if (stat == null) { @@ -1111,7 +1105,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public boolean visit(ConditionalInsertClauseItem x) { - String originalTable = currentTableLocal.get(); SQLObject parent = x.getParent(); if (parent instanceof ConditionalInsertClause) { parent = parent.getParent(); @@ -1120,12 +1113,12 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle SQLSelect subQuery = ((OracleMultiInsertStatement) parent).getSubQuery(); if (subQuery != null) { String table = (String) subQuery.getAttribute("_table_"); - setCurrentTable(table); + setCurrentTable(x, table); } } x.getWhen().accept(this); x.getThen().accept(this); - setCurrentTable(originalTable); + restoreCurrentTable(x); return false; } @@ -1136,6 +1129,12 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public boolean visit(OracleBlockStatement x) { + for (OracleParameter param : x.getParameters()) { + param.setParent(x); + + SQLExpr name = param.getName(); + this.variants.put(name.toString(), name); + } return true; } @@ -1388,7 +1387,9 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle public boolean visit(OracleForStatement x) { x.getRange().setParent(x); - x.getIndex().accept(this); + SQLName index = x.getIndex(); + this.getVariants().put(index.toString(), x); + x.getRange().accept(this); accept(x.getStatements()); 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 aefa87ca0a..5f112276e0 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 @@ -193,7 +193,7 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit x.putAttribute("_original_use_mode", getMode()); setMode(x, Mode.Insert); - String originalTable = currentTableLocal.get(); + String originalTable = getCurrentTable(); if (x.getTableName() instanceof SQLName) { String ident = ((SQLName) x.getTableName()).toString(); 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 2f63a3dace..6f87852904 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -47,42 +47,62 @@ import com.alibaba.druid.stat.TableStat.Relationship; public class SchemaStatVisitor extends SQLASTVisitorAdapter { - protected final HashMap tableStats = new LinkedHashMap(); - protected final Set columns = new LinkedHashSet(); - protected final Set conditions = new LinkedHashSet(); - protected final Set relationships = new LinkedHashSet(); - protected final Set orderByColumns = new LinkedHashSet(); - protected final Set groupByColumns = new LinkedHashSet(); + protected final HashMap tableStats = new LinkedHashMap(); + protected final Set columns = new LinkedHashSet(); + protected final Set conditions = new LinkedHashSet(); + protected final Set relationships = new LinkedHashSet(); + protected final Set orderByColumns = new LinkedHashSet(); + protected final Set groupByColumns = new LinkedHashSet(); - protected final Map subQueryMap = new LinkedHashMap(); - - protected Map aliasLocal = new HashMap(); - - protected final static ThreadLocal currentTableLocal = new ThreadLocal(); + protected final Map subQueryMap = new LinkedHashMap(); - public final static String ATTR_TABLE = "_table_"; - public final static String ATTR_COLUMN = "_column_"; + protected final Map variants = new LinkedHashMap(); + + protected Map aliasMap = new HashMap(); + + protected String currentTable; + + public final static String ATTR_TABLE = "_table_"; + public final static String ATTR_COLUMN = "_column_"; private Mode mode; - + + public Map getVariants() { + return variants; + } + public void setAliasMap() { this.setAliasMap(new HashMap()); } - + public void clearAliasMap() { - this.aliasLocal = null; + this.aliasMap = null; } - + public void setAliasMap(Map aliasMap) { - this.aliasLocal = aliasMap; + this.aliasMap = aliasMap; } public Map getAliasMap() { - return aliasLocal; + return aliasMap; } - + public void setCurrentTable(String table) { - currentTableLocal.set(table); + this.currentTable = table; + } + + 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() { @@ -114,7 +134,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } public boolean visit(SQLIdentifierExpr x) { - String currentTable = currentTableLocal.get(); + String currentTable = getCurrentTable(); if (subQueryMap.containsKey(currentTable)) { return false; @@ -277,7 +297,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } String column = ((SQLIdentifierExpr) expr).getName(); - String table = currentTableLocal.get(); + String table = getCurrentTable(); if (table != null) { if (aliasMap.containsKey(table)) { table = aliasMap.get(table); @@ -303,7 +323,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { setAliasMap(); - String originalTable = currentTableLocal.get(); + String originalTable = getCurrentTable(); for (SQLName name : x.getTableNames()) { String ident = name.toString(); @@ -332,7 +352,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { setAliasMap(); - String originalTable = currentTableLocal.get(); + String originalTable = getCurrentTable(); for (SQLName name : x.getTableNames()) { String ident = name.toString(); @@ -361,7 +381,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { setAliasMap(); - String originalTable = currentTableLocal.get(); + String originalTable = getCurrentTable(); if (x.getTableName() instanceof SQLName) { String ident = ((SQLName) x.getTableName()).toString(); @@ -410,7 +430,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { return false; } - String originalTable = currentTableLocal.get(); + String originalTable = getCurrentTable(); if (x.getFrom() instanceof SQLExprTableSource) { SQLExprTableSource tableSource = (SQLExprTableSource) x.getFrom(); @@ -439,7 +459,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { public void endVisit(SQLSelectQueryBlock x) { String originalTable = (String) x.getAttribute("_old_local_"); - x.putAttribute("table", currentTableLocal.get()); + x.putAttribute("table", getCurrentTable()); setCurrentTable(originalTable); setModeOrigin(x); @@ -513,18 +533,24 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } public boolean visit(SQLIdentifierExpr x) { - String currentTable = currentTableLocal.get(); + String currentTable = getCurrentTable(); if (subQueryMap.containsKey(currentTable)) { return false; } + String ident = x.toString(); + + if (variants.containsKey(ident)) { + return false; + } + if (currentTable != null) { - Column column = new Column(currentTable, x.getName()); + Column column = new Column(currentTable, ident); columns.add(column); x.putAttribute(ATTR_COLUMN, column); } else { - Column column = handleUnkownColumn(x.getName()); + Column column = handleUnkownColumn(ident); if (column != null) { x.putAttribute(ATTR_COLUMN, column); } @@ -539,7 +565,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } public boolean visit(SQLAllColumnExpr x) { - String currentTable = currentTableLocal.get(); + String currentTable = getCurrentTable(); if (subQueryMap.containsKey(currentTable)) { return false; @@ -654,7 +680,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { accept(x.getQuery()); - String originalTable = currentTableLocal.get(); + String originalTable = getCurrentTable(); setCurrentTable((String) x.getQuery().getAttribute("table")); x.putAttribute("_old_local_", originalTable);