bug fixed for schema stat visitor

This commit is contained in:
温少
2012-02-26 12:21:05 +08:00
19 changed files with 631 additions and 50 deletions
@@ -32,6 +32,7 @@ public class OracleUpdateSetListSingleColumnItem extends OracleUpdateSetListItem
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.column);
acceptChild(visitor, this.value);
}
visitor.endVisit(this);
@@ -845,7 +845,7 @@ public class OracleSelectParser extends SQLSelectParser {
if (lexer.token() == Token.ON) {
lexer.nextToken();
join.setCondition(this.createExprParser().expr());
} else if (identifierEquals("USING")) {
} else if (lexer.token() == Token.USING) {
lexer.nextToken();
accept(Token.LPAREN);
this.createExprParser().exprList(join.getUsing());
@@ -296,6 +296,7 @@ public class OracleStatementParser extends SQLStatementParser {
parseInsert0(insertInto, false);
clause.setElseItem(insertInto);
}
stmt.getEntries().add(clause);
}
SQLSelect subQuery = this.createSQLSelectParser().select();
@@ -54,6 +54,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectHierachicalQuer
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectJoin;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot.Item;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.CheckOption;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.ReadOnly;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource;
@@ -757,5 +758,15 @@ public class OracleASTVIsitorAdapter extends SQLASTVisitorAdapter implements Ora
public void endVisit(ConditionalInsertClauseItem x) {
}
@Override
public boolean visit(OracleSelectQueryBlock x) {
return true;
}
@Override
public void endVisit(OracleSelectQueryBlock x) {
}
}
@@ -57,6 +57,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectForUpdate;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectHierachicalQueryClause;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectJoin;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
@@ -330,4 +331,8 @@ public interface OracleASTVisitor extends SQLASTVisitor {
boolean visit(ConditionalInsertClauseItem x);
void endVisit(ConditionalInsertClauseItem x);
boolean visit(OracleSelectQueryBlock x);
void endVisit(OracleSelectQueryBlock x);
}
@@ -1602,4 +1602,9 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public void endVisit(ConditionalInsertClauseItem x) {
}
@Override
public void endVisit(OracleSelectQueryBlock x) {
}
}
@@ -9,6 +9,7 @@ import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
@@ -82,18 +83,51 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetValueClause;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateStatement;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.stat.TableStat.Column;
import com.alibaba.druid.stat.TableStat.Mode;
import com.alibaba.druid.stat.TableStat.Relationship;
public class OracleSchemaStatVisitor extends SchemaStatVisitor implements OracleASTVisitor {
protected Column getColumn(SQLExpr expr) {
if (expr instanceof OracleOuterExpr) {
expr = ((OracleOuterExpr) expr).getExpr();
}
return super.getColumn(expr);
}
public boolean visit(OracleSelectTableReference x) {
SQLExpr expr = x.getExpr();
if (expr instanceof SQLMethodInvokeExpr) {
SQLMethodInvokeExpr methodInvoke = (SQLMethodInvokeExpr) expr;
if ("TABLE".equalsIgnoreCase(methodInvoke.getMethodName()) && methodInvoke.getParameters().size() == 1) {
expr = methodInvoke.getParameters().get(0);
}
}
Map<String, String> aliasMap = aliasLocal.get();
if (expr instanceof SQLName) {
String ident = ((SQLName) expr).toString();
Map<String, String> aliasMap = aliasLocal.get();
if (aliasMap.containsKey(ident) && aliasMap.get(ident) == null) {
String ident;
if (expr instanceof SQLPropertyExpr) {
String owner = ((SQLPropertyExpr) expr).getOwner().toString();
String name = ((SQLPropertyExpr) expr).getName();
if (aliasMap.containsKey(owner)) {
owner = aliasMap.get(owner);
}
ident = owner + "." + name;
} else {
ident = expr.toString();
}
if (subQueryMap.containsKey(ident)) {
return false;
}
if ("DUAL".equalsIgnoreCase(ident)) {
return false;
}
@@ -101,6 +135,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
if (stat == null) {
stat = new TableStat();
tableStats.put(new TableStat.Name(ident), stat);
x.putAttribute(ATTR_TABLE, ident);
}
Mode mode = modeLocal.get();
@@ -214,6 +249,10 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
}
public boolean visit(OracleSelectQueryBlock x) {
if (x.getWhere() != null) {
x.getWhere().setParent(x);
}
return visit((SQLSelectQueryBlock) x);
}
@@ -228,6 +267,11 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
return super.visit(x);
}
public boolean visit(SQLMethodInvokeExpr x) {
accept(x.getParameters());
return false;
}
public boolean visit(SQLIdentifierExpr x) {
if ("ROWNUM".equalsIgnoreCase(x.getName())) {
@@ -241,6 +285,10 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
if ("+".equalsIgnoreCase(x.getName())) {
return false;
}
if ("LEVEL".equals(x.getName())) {
return false;
}
return super.visit(x);
}
@@ -475,8 +523,36 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
@Override
public boolean visit(OracleSelectJoin x) {
return true;
x.getLeft().accept(this);
x.getRight().accept(this);
if (x.getCondition() != null) {
x.getCondition().accept(this);
}
for (SQLExpr item : x.getUsing()) {
if (item instanceof SQLIdentifierExpr) {
String columnName = ((SQLIdentifierExpr) item).getName();
String leftTable = (String) x.getLeft().getAttribute(ATTR_TABLE);
String rightTable = (String) x.getRight().getAttribute(ATTR_TABLE);
if (leftTable != null && rightTable != null) {
Relationship relationship = new Relationship();
relationship.setLeft(new Column(leftTable, columnName));
relationship.setRight(new Column(rightTable, columnName));
relationship.setOperator("USING");
relationships.add(relationship);
}
if (leftTable != null) {
columns.add(new Column(leftTable, columnName));
}
if (rightTable != null) {
columns.add(new Column(rightTable, columnName));
}
}
}
return false;
}
@Override
@@ -639,6 +715,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
if (alias != null) {
aliasMap.put(alias, null);
subQueryMap.put(alias, x.getSubQuery());
}
}
x.getSubQuery().accept(this);
@@ -72,6 +72,7 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit
if (alias != null) {
aliasMap.put(alias, null);
subQueryMap.put(alias, x.getQuery());
}
}
x.getQuery().accept(this);
@@ -16,6 +16,7 @@
package com.alibaba.druid.sql.dialect.sqlserver.parser;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.SQLSelectParser;
import com.alibaba.druid.sql.parser.SQLStatementParser;
public class SQLServerStatementParser extends SQLStatementParser {
@@ -24,6 +25,10 @@ public class SQLServerStatementParser extends SQLStatementParser {
super(new SQLServerLexer(sql));
this.lexer.nextToken();
}
public SQLSelectParser createSQLSelectParser() {
return new SQLServerSelectParser(this.lexer);
}
public SQLServerStatementParser(Lexer lexer){
super(lexer);
@@ -52,11 +52,14 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
protected final Set<Column> orderByColumns = new LinkedHashSet<Column>();
protected final Set<Column> groupByColumns = new LinkedHashSet<Column>();
private final Map<String, SQLSelectQuery> subQueryMap = new LinkedHashMap<String, SQLSelectQuery>();
protected final Map<String, SQLObject> subQueryMap = new LinkedHashMap<String, SQLObject>();
protected final static ThreadLocal<Map<String, String>> aliasLocal = new ThreadLocal<Map<String, String>>();
protected final static ThreadLocal<String> currentTableLocal = new ThreadLocal<String>();
protected final static ThreadLocal<Mode> modeLocal = new ThreadLocal<Mode>();
public final static String ATTR_TABLE = "_table_";
public final static String ATTR_COLUMN = "_column_";
public class OrderByStatVisitor extends SQLASTVisitorAdapter {
private final SQLOrderBy orderBy;
@@ -72,8 +75,14 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public boolean visit(SQLIdentifierExpr x) {
String currentTable = currentTableLocal.get();
if (subQueryMap.containsKey(currentTable)) {
return false;
}
if (currentTable != null) {
orderByColumns.add(new Column(currentTable, x.getName()));
} else {
orderByColumns.add(new Column("UNKOWN", x.getName()));
}
return false;
}
@@ -82,16 +91,12 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
if (x.getOwner() instanceof SQLIdentifierExpr) {
String owner = ((SQLIdentifierExpr) x.getOwner()).getName();
if (owner != null) {
Map<String, String> aliasMap = aliasLocal.get();
if (aliasMap != null) {
String table = aliasMap.get(owner);
if (subQueryMap.containsKey(owner)) {
return false;
}
// table == null时是SubQuery
if (table != null) {
orderByColumns.add(new Column(table, x.getName()));
}
}
if (owner != null) {
orderByColumns.add(new Column(owner, x.getName()));
}
}
@@ -138,6 +143,9 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
}
public boolean visit(SQLBinaryOpExpr x) {
x.getLeft().setParent(x);
x.getRight().setParent(x);
switch (x.getOperator()) {
case Equality:
case NotEqual:
@@ -220,17 +228,27 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
}
if (expr instanceof SQLIdentifierExpr) {
Column attrColumn = (Column) expr.getAttribute(ATTR_COLUMN);
if (attrColumn != null) {
return attrColumn;
}
String column = ((SQLIdentifierExpr) expr).getName();
String table = currentTableLocal.get();
if (table != null) {
if (aliasMap.containsKey(table)) {
table = aliasMap.get(table);
if (table == null) {
return null;
}
}
}
if (table != null) {
return new Column(table, column);
}
return new Column("UNKNOWN", column);
}
return null;
@@ -361,15 +379,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
if (tableSource.getExpr() instanceof SQLName) {
String ident = tableSource.getExpr().toString();
Map<String, String> aliasMap = aliasLocal.get();
if (aliasMap.containsKey(ident) && aliasMap.get(ident) == null) {
currentTableLocal.set(null);
} else {
currentTableLocal.set(ident);
x.putAttribute("_table_", ident);
if (x.getParent() instanceof SQLSelect) {
x.getParent().putAttribute("_table_", ident);
}
currentTableLocal.set(ident);
x.putAttribute(ATTR_TABLE, ident);
if (x.getParent() instanceof SQLSelect) {
x.getParent().putAttribute(ATTR_TABLE, ident);
}
x.putAttribute("_old_local_", originalTable);
}
@@ -377,6 +390,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
x.getFrom().accept(this); // 提前执行,获得aliasMap
if (x.getWhere() != null) {
x.getWhere().setParent(x);
}
return true;
}
@@ -396,26 +413,22 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public boolean visit(SQLPropertyExpr x) {
if (x.getOwner() instanceof SQLIdentifierExpr) {
String owner = ((SQLIdentifierExpr) x.getOwner()).getName();
if (subQueryMap.containsKey(owner)) {
return false;
}
if (owner != null) {
Map<String, String> aliasMap = aliasLocal.get();
if (aliasMap != null) {
String table = aliasMap.get(owner);
// table == null时是SubQuery
if (table != null) {
Column column = new Column(table, x.getName());
columns.add(column);
x.putAttribute("_column_", column);
}
}
Column column = new Column(owner, x.getName());
columns.add(column);
x.putAttribute(ATTR_COLUMN, column);
}
}
return false;
}
protected Column handleSubQueryColumn(String owner, String alias) {
SQLSelectQuery query = subQueryMap.get(owner);
SQLObject query = subQueryMap.get(owner);
if (query == null) {
return null;
@@ -439,7 +452,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
}
if (alias.equalsIgnoreCase(itemAlias)) {
Column column = (Column) itemExpr.getAttribute("_column_");
Column column = (Column) itemExpr.getAttribute(ATTR_COLUMN);
return column;
}
@@ -452,16 +465,35 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public boolean visit(SQLIdentifierExpr x) {
String currentTable = currentTableLocal.get();
if (subQueryMap.containsKey(currentTable)) {
return false;
}
if (currentTable != null) {
Column column = new Column(currentTable, x.getName());
columns.add(column);
x.putAttribute("_column_", column);
x.putAttribute(ATTR_COLUMN, column);
} else {
Column column = handleUnkownColumn(x.getName());
if (column != null) {
x.putAttribute(ATTR_COLUMN, column);
}
}
return false;
}
protected Column handleUnkownColumn(String columnName) {
Column column = new Column("UNKNOWN", columnName);
columns.add(column);
return column;
}
public boolean visit(SQLAllColumnExpr x) {
String currentTable = currentTableLocal.get();
if (subQueryMap.containsKey(currentTable)) {
return false;
}
if (currentTable != null) {
columns.add(new Column(currentTable, "*"));
@@ -512,17 +544,18 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public boolean visit(SQLExprTableSource x) {
if (isSimpleExprTableSource(x)) {
String ident = x.getExpr().toString();
Map<String, String> aliasMap = aliasLocal.get();
if (aliasMap.containsKey(ident) && aliasMap.get(ident) == null) {
if (subQueryMap.containsKey(ident)) {
return false;
}
Map<String, String> aliasMap = aliasLocal.get();
TableStat stat = tableStats.get(ident);
if (stat == null) {
stat = new TableStat();
tableStats.put(new TableStat.Name(ident), stat);
x.putAttribute(ATTR_TABLE, ident);
}
Mode mode = modeLocal.get();
@@ -673,7 +706,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
TableStat stat = new TableStat();
stat.incrementCreateCount();
tableStats.put(new TableStat.Name(tableName), stat);
return true;
accept(x.getTableElementList());
return false;
}
public boolean visit(SQLColumnDefinition x) {
@@ -684,14 +720,14 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
tableName = ((SQLCreateTableStatement) parent).getName().toString();
}
}
if (tableName == null) {
return true;
}
String columnName = x.getName().toString();
columns.add(new Column(tableName, columnName));
return true;
return false;
}
}