From 5fc9acdb4c625b0a20c4b849bb31c3e61cd1d39c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Fri, 24 Feb 2012 14:19:00 +0800 Subject: [PATCH] enhance for schema stat --- .../alibaba/druid/filter/FilterAdapter.java | 5 +- .../encoding/EncodingConvertFilter.java | 29 +- .../sql/dialect/oracle/ast/OracleOrderBy.java | 6 +- .../oracle/ast/stmt/OracleOrderByItem.java | 6 +- .../visitor/OracleSchemaStatVisitor.java | 1042 +++++++++-------- .../druid/sql/visitor/SchemaStatVisitor.java | 13 +- .../bvt/sql/oracle/OracleSelectTest.java | 40 + .../bvt/sql/oracle/OracleSelectTest2.java | 54 + .../com/alibaba/druid/sql/OracleTest.java | 21 + 9 files changed, 691 insertions(+), 525 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest2.java create mode 100644 src/test/java/com/alibaba/druid/sql/OracleTest.java diff --git a/src/main/java/com/alibaba/druid/filter/FilterAdapter.java b/src/main/java/com/alibaba/druid/filter/FilterAdapter.java index bfb97a946a..d6c1c5fa34 100644 --- a/src/main/java/com/alibaba/druid/filter/FilterAdapter.java +++ b/src/main/java/com/alibaba/druid/filter/FilterAdapter.java @@ -57,14 +57,15 @@ import com.alibaba.druid.proxy.jdbc.StatementProxy; * @author wenshao */ public abstract class FilterAdapter extends NotificationBroadcasterSupport implements Filter { + protected DataSourceProxy dataSource; @Override public void loadConfig(AbstractDruidFilterConfig DruidFilterConfig) { } @Override - public void init(DataSourceProxy newDataSource) { - + public void init(DataSourceProxy dataSource) { + this.dataSource = dataSource; } @Override diff --git a/src/main/java/com/alibaba/druid/filter/encoding/EncodingConvertFilter.java b/src/main/java/com/alibaba/druid/filter/encoding/EncodingConvertFilter.java index 1a8ef8d05a..7e77d25e98 100644 --- a/src/main/java/com/alibaba/druid/filter/encoding/EncodingConvertFilter.java +++ b/src/main/java/com/alibaba/druid/filter/encoding/EncodingConvertFilter.java @@ -33,6 +33,7 @@ import com.alibaba.druid.proxy.jdbc.ClobProxy; import com.alibaba.druid.proxy.jdbc.ConnectionProxy; import com.alibaba.druid.proxy.jdbc.PreparedStatementProxy; import com.alibaba.druid.proxy.jdbc.ResultSetProxy; +import com.alibaba.druid.proxy.jdbc.ResultSetProxyImpl; import com.alibaba.druid.proxy.jdbc.StatementProxy; import com.alibaba.druid.util.JdbcUtils; @@ -211,6 +212,26 @@ public class EncodingConvertFilter extends FilterAdapter { String text = JdbcUtils.read(reader); return new StringReader(decode(connection, text)); } + + return object; + } + + public Object decodeObject(CallableStatementProxy stmt, Object object) throws SQLException { + if (object instanceof String) { + return decode(stmt.getConnectionProxy(), (String) object); + } + + if (object instanceof Reader) { + Reader reader = (Reader) object; + String text = JdbcUtils.read(reader); + return new StringReader(decode(stmt.getConnectionProxy(), text)); + } + + if (object instanceof ResultSet) { + ResultSet resultSet = (ResultSet) object; + return new ResultSetProxyImpl(stmt, resultSet, dataSource.createResultSetId(), + stmt.getLastExecuteSql()); + } return object; } @@ -594,21 +615,21 @@ public class EncodingConvertFilter extends FilterAdapter { public Object callableStatement_getObject(FilterChain chain, CallableStatementProxy statement, int parameterIndex) throws SQLException { Object value = chain.callableStatement_getObject(statement, parameterIndex); - return decodeObject(statement.getConnectionProxy(), value); + return decodeObject(statement, value); } @Override public Object callableStatement_getObject(FilterChain chain, CallableStatementProxy statement, int parameterIndex, java.util.Map> map) throws SQLException { Object value = chain.callableStatement_getObject(statement, parameterIndex, map); - return decodeObject(statement.getConnectionProxy(), value); + return decodeObject(statement, value); } @Override public Object callableStatement_getObject(FilterChain chain, CallableStatementProxy statement, String parameterName) throws SQLException { Object value = chain.callableStatement_getObject(statement, parameterName); - return decodeObject(statement.getConnectionProxy(), value); + return decodeObject(statement, value); } @Override @@ -616,7 +637,7 @@ public class EncodingConvertFilter extends FilterAdapter { String parameterName, java.util.Map> map) throws SQLException { Object value = chain.callableStatement_getObject(statement, parameterName, map); - return decodeObject(statement.getConnectionProxy(), value); + return decodeObject(statement, value); } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/OracleOrderBy.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/OracleOrderBy.java index f1c58d300c..6a18e79f50 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/OracleOrderBy.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/OracleOrderBy.java @@ -39,7 +39,11 @@ public class OracleOrderBy extends SQLOrderBy { } protected void accept0(SQLASTVisitor visitor) { - accept0((OracleASTVisitor) visitor); + if (visitor instanceof OracleASTVisitor) { + accept0((OracleASTVisitor) visitor); + } else { + super.accept0(visitor); + } } protected void accept0(OracleASTVisitor visitor) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleOrderByItem.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleOrderByItem.java index 38e7b64dba..160013d81a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleOrderByItem.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleOrderByItem.java @@ -39,7 +39,11 @@ public class OracleOrderByItem extends SQLSelectOrderByItem { } protected void accept0(SQLASTVisitor visitor) { - accept0((OracleASTVisitor) visitor); + if (visitor instanceof OracleASTVisitor) { + accept0((OracleASTVisitor) visitor); + } else { + super.accept0(visitor); + } } protected void accept0(OracleASTVisitor visitor) { 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 0866e0ba01..f4fe3975c7 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 @@ -5,6 +5,7 @@ import java.util.Map; 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.expr.SQLAggregateExpr; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr; @@ -72,732 +73,751 @@ import com.alibaba.druid.stat.TableStat; import com.alibaba.druid.stat.TableStat.Column; import com.alibaba.druid.stat.TableStat.Mode; -public class OracleSchemaStatVisitor extends SchemaStatVisitor implements - OracleASTVisitor { - - public boolean visit(OracleSelectTableReference x) { - SQLExpr expr = x.getExpr(); - if (expr instanceof SQLName) { - String ident = ((SQLName) expr).toString(); - TableStat stat = tableStats.get(ident); - if (stat == null) { - stat = new TableStat(); - tableStats.put(new TableStat.Name(ident), stat); - } - - Mode mode = modeLocal.get(); - switch (mode) { - case Delete: - stat.incrementDeleteCount(); - break; - case Insert: - stat.incrementInsertCount(); - break; - case Update: - stat.incrementUpdateCount(); - break; - case Select: - stat.incrementSelectCount(); - break; - default: - break; - } - - Map aliasMap = aliasLocal.get(); - if (aliasMap != null) { - if (x.getAlias() != null) { - aliasMap.put(x.getAlias(), ident); - } - aliasMap.put(ident, ident); - } - return false; - } - - accept(x.getExpr()); - - return false; - } - - public boolean visit(SQLAggregateExpr x) { - accept(x.getArguments()); - return false; - } - - public boolean visit(OracleAggregateExpr x) { - accept(x.getArguments()); - accept(x.getOver()); - return false; - } - - public void endVisit(OracleSelect x) { - } - - public boolean visit(OracleSelect x) { - accept(x.getFactoring()); - accept(x.getQuery()); - - String originalTable = currentTableLocal.get(); - - currentTableLocal.set((String) x.getQuery().getAttribute("table")); - x.putAttribute("_old_local_", originalTable); - - accept(x.getOrderBy()); - - currentTableLocal.set(originalTable); - - return false; - } - - public void endVisit(SQLSelect x) { - } - - public boolean visit(OracleUpdateStatement x) { - aliasLocal.set(new HashMap()); - - if (x.getTable() instanceof SQLIdentifierExpr) { - String ident = x.getTable().toString(); - currentTableLocal.set(ident); - - TableStat stat = tableStats.get(ident); - if (stat == null) { - stat = new TableStat(); - tableStats.put(new TableStat.Name(ident), stat); - } - stat.incrementUpdateCount(); - - Map aliasMap = aliasLocal.get(); - aliasMap.put(ident, ident); - } else { - accept(x.getTable()); - } - - accept(x.getSetClause()); - accept(x.getWhere()); - - return false; - } - - public void endVisit(OracleUpdateStatement x) { - aliasLocal.set(null); - } +public class OracleSchemaStatVisitor extends SchemaStatVisitor implements OracleASTVisitor { + + public boolean visit(OracleSelectTableReference x) { + SQLExpr expr = x.getExpr(); + if (expr instanceof SQLName) { + String ident = ((SQLName) expr).toString(); + + Map aliasMap = aliasLocal.get(); + + if (aliasMap.containsKey(ident) && aliasMap.get(ident) == null) { + return false; + } + + TableStat stat = tableStats.get(ident); + if (stat == null) { + stat = new TableStat(); + tableStats.put(new TableStat.Name(ident), stat); + } + + Mode mode = modeLocal.get(); + switch (mode) { + case Delete: + stat.incrementDeleteCount(); + break; + case Insert: + stat.incrementInsertCount(); + break; + case Update: + stat.incrementUpdateCount(); + break; + case Select: + stat.incrementSelectCount(); + break; + default: + break; + } + + if (aliasMap != null) { + if (x.getAlias() != null) { + aliasMap.put(x.getAlias(), ident); + } + aliasMap.put(ident, ident); + } + return false; + } + + accept(x.getExpr()); + + return false; + } + + public boolean visit(SQLAggregateExpr x) { + accept(x.getArguments()); + return false; + } + + public boolean visit(OracleAggregateExpr x) { + accept(x.getArguments()); + accept(x.getOver()); + return false; + } + + public void endVisit(OracleSelect x) { + } + + public boolean visit(OracleSelect x) { + if (x.getOrderBy() != null) { + x.getOrderBy().setParent(x); + } + + accept(x.getFactoring()); + accept(x.getQuery()); + + String originalTable = currentTableLocal.get(); + + currentTableLocal.set((String) x.getQuery().getAttribute("table")); + x.putAttribute("_old_local_", originalTable); + + accept(x.getOrderBy()); + + currentTableLocal.set(originalTable); + + return false; + } + + public void endVisit(SQLSelect x) { + } + + public boolean visit(OracleUpdateStatement x) { + aliasLocal.set(new HashMap()); + + if (x.getTable() instanceof SQLIdentifierExpr) { + String ident = x.getTable().toString(); + currentTableLocal.set(ident); + + TableStat stat = tableStats.get(ident); + if (stat == null) { + stat = new TableStat(); + tableStats.put(new TableStat.Name(ident), stat); + } + stat.incrementUpdateCount(); + + Map aliasMap = aliasLocal.get(); + aliasMap.put(ident, ident); + } else { + accept(x.getTable()); + } - public boolean visit(OracleDeleteStatement x) { - return visit((SQLDeleteStatement) x); - } + accept(x.getSetClause()); + accept(x.getWhere()); - public void endVisit(OracleDeleteStatement x) { - aliasLocal.set(null); - } + return false; + } - public boolean visit(OracleSelectQueryBlock x) { - return visit((SQLSelectQueryBlock) x); - } + public void endVisit(OracleUpdateStatement x) { + aliasLocal.set(null); + } - public void endVisit(OracleSelectQueryBlock x) { - endVisit((SQLSelectQueryBlock) x); - } + public boolean visit(OracleDeleteStatement x) { + return visit((SQLDeleteStatement) x); + } - public boolean visit(SQLPropertyExpr x) { - if ("ROWNUM".equalsIgnoreCase(x.getName())) { - return false; - } + public void endVisit(OracleDeleteStatement x) { + aliasLocal.set(null); + } - if (x.getOwner() instanceof SQLIdentifierExpr) { - String owner = ((SQLIdentifierExpr) x.getOwner()).getName(); + public boolean visit(OracleSelectQueryBlock x) { + return visit((SQLSelectQueryBlock) x); + } - if (owner != null) { - Map aliasMap = aliasLocal.get(); - if (aliasMap != null) { - String table = aliasMap.get(owner); + public void endVisit(OracleSelectQueryBlock x) { + endVisit((SQLSelectQueryBlock) x); + } - // table == null时是SubQuery - if (table != null) { - columns.add(new Column(table, x.getName())); - } - } - } - } - return false; - } + public boolean visit(SQLPropertyExpr x) { + if ("ROWNUM".equalsIgnoreCase(x.getName())) { + return false; + } - public boolean visit(SQLIdentifierExpr x) { - if ("ROWNUM".equalsIgnoreCase(x.getName())) { - return false; - } + if (x.getOwner() instanceof SQLIdentifierExpr) { + String owner = ((SQLIdentifierExpr) x.getOwner()).getName(); - if ("SYSDATE".equalsIgnoreCase(x.getName())) { - return false; - } + if (owner != null) { + Map aliasMap = aliasLocal.get(); + if (aliasMap != null) { + String table = aliasMap.get(owner); - if ("+".equalsIgnoreCase(x.getName())) { - return false; - } + // table == null时是SubQuery + if (table != null) { + columns.add(new Column(table, x.getName())); + } + } + } + } + return false; + } - String currentTable = currentTableLocal.get(); + public boolean visit(SQLIdentifierExpr x) { + if ("ROWNUM".equalsIgnoreCase(x.getName())) { + return false; + } - if (currentTable != null) { - columns.add(new Column(currentTable, x.getName())); - } - return false; - } + if ("SYSDATE".equalsIgnoreCase(x.getName())) { + return false; + } - @Override - public void endVisit(OracleAggregateExpr astNode) { + if ("+".equalsIgnoreCase(x.getName())) { + return false; + } - } + String currentTable = currentTableLocal.get(); - @Override - public void endVisit(OracleConstraintState astNode) { + if (currentTable != null) { + columns.add(new Column(currentTable, x.getName())); + } + return false; + } - } + @Override + public void endVisit(OracleAggregateExpr astNode) { - @Override - public void endVisit(OraclePLSQLCommitStatement astNode) { + } - } + @Override + public void endVisit(OracleConstraintState astNode) { - @Override - public void endVisit(OracleAnalytic x) { + } - } + @Override + public void endVisit(OraclePLSQLCommitStatement astNode) { - @Override - public void endVisit(OracleAnalyticWindowing x) { + } - } + @Override + public void endVisit(OracleAnalytic x) { - @Override - public void endVisit(OracleDateExpr x) { + } - } + @Override + public void endVisit(OracleAnalyticWindowing x) { - @Override - public void endVisit(OracleDbLinkExpr x) { + } - } + @Override + public void endVisit(OracleDateExpr x) { - @Override - public void endVisit(OracleExtractExpr x) { + } - } + @Override + public void endVisit(OracleDbLinkExpr x) { - @Override - public void endVisit(OracleHint x) { + } - } + @Override + public void endVisit(OracleExtractExpr x) { - @Override - public void endVisit(OracleIntervalExpr x) { + } - } + @Override + public void endVisit(OracleHint x) { - @Override - public void endVisit(SQLObjectCreateExpr x) { + } - } + @Override + public void endVisit(OracleIntervalExpr x) { - @Override - public void endVisit(OracleOrderBy x) { + } - } + @Override + public void endVisit(SQLObjectCreateExpr x) { - @Override - public void endVisit(OracleOuterExpr x) { + } - } + @Override + public void endVisit(OracleOrderBy x) { - @Override - public void endVisit(OracleSelectForUpdate x) { + } - } + @Override + public void endVisit(OracleOuterExpr x) { - @Override - public void endVisit(OracleSelectHierachicalQueryClause x) { + } - } + @Override + public void endVisit(OracleSelectForUpdate x) { - @Override - public void endVisit(OracleSelectJoin x) { + } - } + @Override + public void endVisit(OracleSelectHierachicalQueryClause x) { - @Override - public void endVisit(OracleOrderByItem x) { + } - } + @Override + public void endVisit(OracleSelectJoin x) { - @Override - public void endVisit(OracleSelectPivot x) { + } - } + @Override + public void endVisit(OracleOrderByItem x) { - @Override - public void endVisit(Item x) { + } - } + @Override + public void endVisit(OracleSelectPivot x) { - @Override - public void endVisit(CheckOption x) { + } - } + @Override + public void endVisit(Item x) { - @Override - public void endVisit(ReadOnly x) { + } - } + @Override + public void endVisit(CheckOption x) { - @Override - public void endVisit(OracleSelectSubqueryTableSource x) { + } - } + @Override + public void endVisit(ReadOnly x) { - @Override - public void endVisit(OracleSelectUnPivot x) { + } - } + @Override + public void endVisit(OracleSelectSubqueryTableSource x) { - @Override - public void endVisit(OracleTableExpr x) { + } - } + @Override + public void endVisit(OracleSelectUnPivot x) { - @Override - public void endVisit(OracleTimestampExpr x) { + } - } + @Override + public void endVisit(OracleTableExpr x) { - @Override - public void endVisit(OracleUpdateSetListClause x) { + } - } + @Override + public void endVisit(OracleTimestampExpr x) { - @Override - public void endVisit(OracleUpdateSetListMultiColumnItem x) { + } - } + @Override + public void endVisit(OracleUpdateSetListClause x) { - @Override - public void endVisit(OracleUpdateSetListSingleColumnItem x) { + } - } + @Override + public void endVisit(OracleUpdateSetListMultiColumnItem x) { - @Override - public void endVisit(OracleUpdateSetValueClause x) { + } - } + @Override + public void endVisit(OracleUpdateSetListSingleColumnItem x) { - @Override - public boolean visit(OracleConstraintState astNode) { + } - return true; - } + @Override + public void endVisit(OracleUpdateSetValueClause x) { - @Override - public boolean visit(OraclePLSQLCommitStatement astNode) { + } - return true; - } + @Override + public boolean visit(OracleConstraintState astNode) { - @Override - public boolean visit(OracleAnalytic x) { + return true; + } - return true; - } + @Override + public boolean visit(OraclePLSQLCommitStatement astNode) { - @Override - public boolean visit(OracleAnalyticWindowing x) { + return true; + } - return true; - } + @Override + public boolean visit(OracleAnalytic x) { - @Override - public boolean visit(OracleDateExpr x) { + return true; + } - return true; - } + @Override + public boolean visit(OracleAnalyticWindowing x) { - @Override - public boolean visit(OracleDbLinkExpr x) { + return true; + } - return true; - } + @Override + public boolean visit(OracleDateExpr x) { - @Override - public boolean visit(OracleExtractExpr x) { + return true; + } - return true; - } + @Override + public boolean visit(OracleDbLinkExpr x) { - @Override - public boolean visit(OracleHint x) { + return true; + } - return true; - } + @Override + public boolean visit(OracleExtractExpr x) { - @Override - public boolean visit(OracleIntervalExpr x) { + return true; + } - return true; - } + @Override + public boolean visit(OracleHint x) { - @Override - public boolean visit(SQLObjectCreateExpr x) { + return true; + } - return true; - } + @Override + public boolean visit(OracleIntervalExpr x) { - @Override - public boolean visit(OracleOrderBy x) { + return true; + } - return true; - } + @Override + public boolean visit(SQLObjectCreateExpr x) { - @Override - public boolean visit(OracleOuterExpr x) { + return true; + } - return true; - } + @Override + public boolean visit(OracleOrderBy x) { + return this.visit((SQLOrderBy) x); + } - @Override - public boolean visit(OracleSelectForUpdate x) { + @Override + public boolean visit(OracleOuterExpr x) { - return true; - } + return true; + } - @Override - public boolean visit(OracleSelectHierachicalQueryClause x) { + @Override + public boolean visit(OracleSelectForUpdate x) { - return true; - } + return true; + } - @Override - public boolean visit(OracleSelectJoin x) { + @Override + public boolean visit(OracleSelectHierachicalQueryClause x) { - return true; - } + return true; + } - @Override - public boolean visit(OracleOrderByItem x) { + @Override + public boolean visit(OracleSelectJoin x) { - return true; - } + return true; + } - @Override - public boolean visit(OracleSelectPivot x) { + @Override + public boolean visit(OracleOrderByItem x) { - return true; - } + return true; + } - @Override - public boolean visit(Item x) { + @Override + public boolean visit(OracleSelectPivot x) { - return true; - } + return true; + } - @Override - public boolean visit(CheckOption x) { + @Override + public boolean visit(Item x) { - return true; - } + return true; + } - @Override - public boolean visit(ReadOnly x) { + @Override + public boolean visit(CheckOption x) { - return true; - } + return true; + } - @Override - public boolean visit(OracleSelectSubqueryTableSource x) { + @Override + public boolean visit(ReadOnly x) { - return true; - } + return true; + } - @Override - public boolean visit(OracleSelectUnPivot x) { + @Override + public boolean visit(OracleSelectSubqueryTableSource x) { - return true; - } + return true; + } - @Override - public boolean visit(OracleTableExpr x) { + @Override + public boolean visit(OracleSelectUnPivot x) { - return true; - } + return true; + } - @Override - public boolean visit(OracleTimestampExpr x) { + @Override + public boolean visit(OracleTableExpr x) { - return true; - } + return true; + } - @Override - public boolean visit(OracleUpdateSetListClause x) { + @Override + public boolean visit(OracleTimestampExpr x) { - return true; - } + return true; + } - @Override - public boolean visit(OracleUpdateSetListMultiColumnItem x) { + @Override + public boolean visit(OracleUpdateSetListClause x) { - return true; - } + return true; + } - @Override - public boolean visit(OracleUpdateSetListSingleColumnItem x) { + @Override + public boolean visit(OracleUpdateSetListMultiColumnItem x) { - return true; - } + return true; + } - @Override - public boolean visit(OracleUpdateSetValueClause x) { + @Override + public boolean visit(OracleUpdateSetListSingleColumnItem x) { - return true; - } + return true; + } - @Override - public boolean visit(SampleClause x) { + @Override + public boolean visit(OracleUpdateSetValueClause x) { - return true; - } + return true; + } - @Override - public void endVisit(SampleClause x) { + @Override + public boolean visit(SampleClause x) { - } + return true; + } - @Override - public void endVisit(OracleSelectTableReference x) { + @Override + public void endVisit(SampleClause x) { - } + } - @Override - public boolean visit(PartitionExtensionClause x) { + @Override + public void endVisit(OracleSelectTableReference x) { - return true; - } + } - @Override - public void endVisit(PartitionExtensionClause x) { + @Override + public boolean visit(PartitionExtensionClause x) { - } + return true; + } - @Override - public boolean visit(VersionsFlashbackQueryClause x) { + @Override + public void endVisit(PartitionExtensionClause x) { - return true; - } + } - @Override - public void endVisit(VersionsFlashbackQueryClause x) { + @Override + public boolean visit(VersionsFlashbackQueryClause x) { - } + return true; + } - @Override - public boolean visit(AsOfFlashbackQueryClause x) { + @Override + public void endVisit(VersionsFlashbackQueryClause x) { - return true; - } + } - @Override - public void endVisit(AsOfFlashbackQueryClause x) { + @Override + public boolean visit(AsOfFlashbackQueryClause x) { - } + return true; + } - @Override - public boolean visit(GroupingSetExpr x) { + @Override + public void endVisit(AsOfFlashbackQueryClause x) { - return true; - } + } - @Override - public void endVisit(GroupingSetExpr x) { + @Override + public boolean visit(GroupingSetExpr x) { - } + return true; + } - @Override - public boolean visit(SubqueryFactoringClause x) { + @Override + public void endVisit(GroupingSetExpr x) { - return true; - } + } - @Override - public void endVisit(SubqueryFactoringClause x) { + @Override + public boolean visit(SubqueryFactoringClause x) { - } + return true; + } - @Override - public boolean visit(Entry x) { + @Override + public void endVisit(SubqueryFactoringClause x) { - return true; - } + } - @Override - public void endVisit(Entry x) { + @Override + public boolean visit(Entry x) { + Map aliasMap = aliasLocal.get(); + if (aliasMap != null) { + String alias = null; + if (x.getName() != null) { + alias = x.getName().toString(); + } - } + if (alias != null) { + aliasMap.put(alias, null); + } + } + x.getSubQuery().accept(this); + return false; + } - @Override - public boolean visit(SearchClause x) { + @Override + public void endVisit(Entry x) { - return true; - } + } - @Override - public void endVisit(SearchClause x) { + @Override + public boolean visit(SearchClause x) { - } + return true; + } - @Override - public boolean visit(CycleClause x) { + @Override + public void endVisit(SearchClause x) { - return true; - } + } - @Override - public void endVisit(CycleClause x) { + @Override + public boolean visit(CycleClause x) { - } + return true; + } - @Override - public boolean visit(OracleBinaryFloatExpr x) { + @Override + public void endVisit(CycleClause x) { - return true; - } + } - @Override - public void endVisit(OracleBinaryFloatExpr x) { + @Override + public boolean visit(OracleBinaryFloatExpr x) { - } + return true; + } - @Override - public boolean visit(OracleBinaryDoubleExpr x) { + @Override + public void endVisit(OracleBinaryFloatExpr x) { - return true; - } + } - @Override - public void endVisit(OracleBinaryDoubleExpr x) { + @Override + public boolean visit(OracleBinaryDoubleExpr x) { - } + return true; + } - @Override - public boolean visit(OracleCursorExpr x) { + @Override + public void endVisit(OracleBinaryDoubleExpr x) { - return true; - } + } - @Override - public void endVisit(OracleCursorExpr x) { + @Override + public boolean visit(OracleCursorExpr x) { - } + return true; + } - @Override - public boolean visit(OracleIsSetExpr x) { + @Override + public void endVisit(OracleCursorExpr x) { - return true; - } + } - @Override - public void endVisit(OracleIsSetExpr x) { + @Override + public boolean visit(OracleIsSetExpr x) { - } + return true; + } - @Override - public boolean visit(ReturnRowsClause x) { + @Override + public void endVisit(OracleIsSetExpr x) { - return true; - } + } - @Override - public void endVisit(ReturnRowsClause x) { + @Override + public boolean visit(ReturnRowsClause x) { - } + return true; + } - @Override - public boolean visit(MainModelClause x) { + @Override + public void endVisit(ReturnRowsClause x) { - return true; - } + } - @Override - public void endVisit(MainModelClause x) { + @Override + public boolean visit(MainModelClause x) { - } + return true; + } - @Override - public boolean visit(ModelColumnClause x) { + @Override + public void endVisit(MainModelClause x) { - return true; - } + } - @Override - public void endVisit(ModelColumnClause x) { + @Override + public boolean visit(ModelColumnClause x) { - } + return true; + } - @Override - public boolean visit(QueryPartitionClause x) { + @Override + public void endVisit(ModelColumnClause x) { - return true; - } + } - @Override - public void endVisit(QueryPartitionClause x) { + @Override + public boolean visit(QueryPartitionClause x) { - } + return true; + } - @Override - public boolean visit(ModelColumn x) { + @Override + public void endVisit(QueryPartitionClause x) { - return true; - } + } - @Override - public void endVisit(ModelColumn x) { + @Override + public boolean visit(ModelColumn x) { - } + return true; + } - @Override - public boolean visit(ModelRulesClause x) { + @Override + public void endVisit(ModelColumn x) { - return true; - } + } - @Override - public void endVisit(ModelRulesClause x) { + @Override + public boolean visit(ModelRulesClause x) { - } + return true; + } - @Override - public boolean visit(CellAssignmentItem x) { + @Override + public void endVisit(ModelRulesClause x) { - return true; - } + } - @Override - public void endVisit(CellAssignmentItem x) { + @Override + public boolean visit(CellAssignmentItem x) { - } + return true; + } - @Override - public boolean visit(CellAssignment x) { + @Override + public void endVisit(CellAssignmentItem x) { - return true; - } + } - @Override - public void endVisit(CellAssignment x) { + @Override + public boolean visit(CellAssignment x) { - } + return true; + } - @Override - public boolean visit(ModelClause x) { - return true; - } + @Override + public void endVisit(CellAssignment x) { - @Override - public void endVisit(ModelClause x) { + } - } + @Override + public boolean visit(ModelClause x) { + return true; + } + + @Override + public void endVisit(ModelClause x) { + + } } 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 acc479e1a2..575334d787 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -1,7 +1,8 @@ package com.alibaba.druid.sql.visitor; import java.util.HashMap; -import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -39,11 +40,11 @@ import com.alibaba.druid.stat.TableStat.Mode; public class SchemaStatVisitor extends SQLASTVisitorAdapter { - protected final HashMap tableStats = new HashMap(); - protected final Set columns = new HashSet(); - protected final Set conditions = new HashSet(); - protected final Set orderByColumns = new HashSet(); - protected final Set groupByColumns = new HashSet(); + protected final HashMap tableStats = new LinkedHashMap(); + protected final Set columns = new LinkedHashSet(); + protected final Set conditions = new LinkedHashSet(); + protected final Set orderByColumns = new LinkedHashSet(); + protected final Set groupByColumns = new LinkedHashSet(); protected final static ThreadLocal> aliasLocal = new ThreadLocal>(); protected final static ThreadLocal currentTableLocal = new ThreadLocal(); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest.java new file mode 100644 index 0000000000..616de6c0d2 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest.java @@ -0,0 +1,40 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest extends OracleTest { + + public void test_0() throws Exception { + String sql = "INSERT INTO films VALUES ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes');"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("films"))); + + Assert.assertEquals(0, visitor.getColumns().size()); + +// Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("films", "producer_id"))); + } + + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest2.java new file mode 100644 index 0000000000..026574cb11 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest2.java @@ -0,0 +1,54 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest2 extends OracleTest { + + public void test_0() throws Exception { + String sql = "WITH " + // + " dept_costs AS (" + // + " SELECT department_name, SUM(salary) dept_total" + // + " FROM employees e, departments d" + // + " WHERE e.department_id = d.department_id" + // + " GROUP BY department_name)," + // + " avg_cost AS (" + // + " SELECT SUM(dept_total)/COUNT(*) avg" + // + " FROM dept_costs)" + // + "SELECT * FROM dept_costs" + // + " WHERE dept_total >" + // + " (SELECT avg FROM avg_cost)" + // + " ORDER BY department_name;"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("departments"))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("films", "producer_id"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/sql/OracleTest.java b/src/test/java/com/alibaba/druid/sql/OracleTest.java new file mode 100644 index 0000000000..6b01739445 --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/OracleTest.java @@ -0,0 +1,21 @@ +package com.alibaba.druid.sql; + +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleOutputVisitor; + +public class OracleTest extends TestCase { + protected String output(List stmtList) { + StringBuilder out = new StringBuilder(); + OracleOutputVisitor visitor = new OracleOutputVisitor(out); + + for (SQLStatement stmt : stmtList) { + stmt.accept(visitor); + } + + return out.toString(); + } +}