diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleUpdateSetListSingleColumnItem.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleUpdateSetListSingleColumnItem.java index 879a5fc918..b85d0938fb 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleUpdateSetListSingleColumnItem.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleUpdateSetListSingleColumnItem.java @@ -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); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java index 70ba0d10b7..3820bbbb08 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java @@ -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()); 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 51248f9426..7854597ecf 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 @@ -296,6 +296,7 @@ public class OracleStatementParser extends SQLStatementParser { parseInsert0(insertInto, false); clause.setElseItem(insertInto); } + stmt.getEntries().add(clause); } SQLSelect subQuery = this.createSQLSelectParser().select(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVIsitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVIsitorAdapter.java index 6a67a14d59..89a64d4827 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVIsitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVIsitorAdapter.java @@ -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) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java index 2232de37e5..d9389bec95 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java @@ -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); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java index f97651eb71..0acc53cb1b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java @@ -1602,4 +1602,9 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS public void endVisit(ConditionalInsertClauseItem x) { } + + @Override + public void endVisit(OracleSelectQueryBlock x) { + + } } 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 78501db171..b44e62abf5 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 @@ -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 aliasMap = aliasLocal.get(); + if (expr instanceof SQLName) { - String ident = ((SQLName) expr).toString(); - - Map 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); 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 360519b1be..82542c7ca6 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 @@ -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); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java index 0b9e5dccf8..a3b5689092 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java @@ -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); 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 bf2e016705..7631a2a86b 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -52,11 +52,14 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { protected final Set orderByColumns = new LinkedHashSet(); protected final Set groupByColumns = new LinkedHashSet(); - private final Map subQueryMap = new LinkedHashMap(); + protected final Map subQueryMap = new LinkedHashMap(); protected final static ThreadLocal> aliasLocal = new ThreadLocal>(); protected final static ThreadLocal currentTableLocal = new ThreadLocal(); protected final static ThreadLocal modeLocal = new ThreadLocal(); + 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 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 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 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 aliasMap = aliasLocal.get(); - - if (aliasMap.containsKey(ident) && aliasMap.get(ident) == null) { + + if (subQueryMap.containsKey(ident)) { return false; } + Map 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; } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest1.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest1.java new file mode 100644 index 0000000000..1778589f69 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest1.java @@ -0,0 +1,41 @@ +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 OracleSelectTest1 extends OracleTest { + + public void test_0() throws Exception { + String sql = "SELECT employees_seq.currval FROM DUAL; "; + + 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()); + System.out.println("relationships : " + visitor.getRelationships()); + +// Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("orders"))); + + Assert.assertEquals(0, visitor.getTables().size()); + Assert.assertEquals(0, visitor.getColumns().size()); + +// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "employee_id"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest3.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest3.java new file mode 100644 index 0000000000..5cd6e51b41 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest3.java @@ -0,0 +1,49 @@ +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 OracleSelectTest3 extends OracleTest { + + public void test_0() throws Exception { + String sql = "SELECT department_id, last_name, salary " + // + " FROM employees x " + // + " WHERE salary > (SELECT AVG(salary) " + // + " FROM employees " + // + " WHERE x.department_id = department_id) " + // + " ORDER BY department_id; "; + + 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()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + + Assert.assertEquals(3, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "last_name"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest4.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest4.java new file mode 100644 index 0000000000..4b1f47d8ad --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest4.java @@ -0,0 +1,49 @@ +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 OracleSelectTest4 extends OracleTest { + + public void test_0() throws Exception { + String sql = "SELECT LPAD(' ',2*(LEVEL-1)) || last_name org_chart, " + // + "employee_id, manager_id, job_id " + // + " FROM employees" + // + " START WITH job_id = 'AD_PRES' " + // + " CONNECT BY PRIOR employee_id = manager_id AND LEVEL <= 2;"; + + 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()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + + Assert.assertEquals(4, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "job_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "last_name"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "manager_id"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest5.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest5.java new file mode 100644 index 0000000000..6bc8a9432b --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest5.java @@ -0,0 +1,45 @@ +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 OracleSelectTest5 extends OracleTest { + + public void test_0() throws Exception { + String sql = "SELECT t1.department_id, t2.* FROM hr_info t1, TABLE(t1.people) t2" + // + " WHERE t2.department_id = t1.department_id;"; + + 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()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("hr_info"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("hr_info.people"))); + + Assert.assertEquals(3, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("hr_info", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("hr_info.people", "*"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("hr_info.people", "department_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest6.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest6.java new file mode 100644 index 0000000000..b6d9b94a94 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest6.java @@ -0,0 +1,53 @@ +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 OracleSelectTest6 extends OracleTest { + + public void test_0() throws Exception { + String sql = "SELECT * FROM departments " + // + " WHERE EXISTS " + // + " (SELECT * FROM employees " + // + " WHERE departments.department_id = employees.department_id " + // + " AND employees.salary > 2500)" + // + " 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()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("departments"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + + Assert.assertEquals(6, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "*"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "department_name"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "*"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest7.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest7.java new file mode 100644 index 0000000000..053f6277ed --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest7.java @@ -0,0 +1,51 @@ +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 OracleSelectTest7 extends OracleTest { + + public void test_0() throws Exception { + String sql = "SELECT * FROM employees " + // + " WHERE department_id NOT IN " + // + " (SELECT department_id FROM departments " + // + " WHERE location_id = 1700)" + // + " ORDER BY last_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()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("departments"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + + Assert.assertEquals(5, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "last_name"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "location_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "*"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest8.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest8.java new file mode 100644 index 0000000000..4e084247a3 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest8.java @@ -0,0 +1,48 @@ +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 OracleSelectTest8 extends OracleTest { + + public void test_0() throws Exception { + String sql = "SELECT d.department_id, e.last_name" + // + " FROM departments d, employees e" + // + " WHERE d.department_id = e.department_id(+)" + // + " ORDER BY d.department_id, e.last_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()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("departments"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + + Assert.assertEquals(3, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "last_name"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest9.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest9.java new file mode 100644 index 0000000000..100f376e8b --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest9.java @@ -0,0 +1,55 @@ +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 OracleSelectTest9 extends OracleTest { + + public void test_0() throws Exception { + String sql = "SELECT e.employee_id, e.salary, e.commission_pct" + // + " FROM employees e JOIN departments d" + // + " USING (department_id)" + // + " WHERE job_id = 'SA_REP'" + // + " AND location_id = 2500" + // + " ORDER BY e.employee_id" + // + " FOR UPDATE OF e.salary;"; + + 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()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("departments"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + + Assert.assertEquals(7, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "commission_pct"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("UNKNOWN", "job_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("UNKNOWN", "location_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleUpdateTest1.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleUpdateTest1.java new file mode 100644 index 0000000000..69c41561e6 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleUpdateTest1.java @@ -0,0 +1,48 @@ +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 OracleUpdateTest1 extends OracleTest { + + public void test_0() throws Exception { + String sql = "UPDATE table1 t_alias1 " + // + " SET column = " + // + " (SELECT expr " + // + " FROM table2 t_alias2 " + // + " WHERE t_alias1.column = t_alias2.column); "; + + 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()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("table1"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("table2"))); + + Assert.assertEquals(2, visitor.getTables().size()); + Assert.assertEquals(3, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("table1", "column"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("table2", "expr"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("table2", "column"))); + } + +}