From 4f29345e6a8a418a6eb23e41b62d0e4b23530c54 Mon Sep 17 00:00:00 2001 From: wenshao Date: Tue, 21 Jun 2011 15:26:06 +0000 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0SQL=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E7=BB=9F=E8=AE=A1SQL=E4=B8=AD?= =?UTF-8?q?=E6=89=80=E4=BD=BF=E7=94=A8=E7=9A=84=E8=A1=A8=E5=92=8C=E5=AD=97?= =?UTF-8?q?=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://code.alibabatech.com/svn/druid/trunk@267 b9813039-fb51-4c41-a8b9-e21c2acb5095 --- .../mysql/visitor/MySqlSchemaStatVisitor.java | 32 ++++++++++---- .../MySqlSchemaStatVisitorTest_Subquery2.java | 44 +++++++++++++++++++ 2 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/sql/mysql/bvt/visitor/MySqlSchemaStatVisitorTest_Subquery2.java 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 fd712791c8..28e98bd350 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 @@ -30,6 +30,16 @@ public class MySqlSchemaStatVisitor extends MySqlASTVisitorAdapter { private final static ThreadLocal currentTableLocal = new ThreadLocal(); private final static ThreadLocal modeLocal = new ThreadLocal(); + public boolean visit(SQLSubqueryTableSource x) { + Map aliasMap = aliasLocal.get(); + if (aliasMap != null) { + if (x.getAlias() != null) { + aliasMap.put(x.getAlias(), null); + } + } + return true; + } + public boolean visit(SQLExprTableSource x) { if (x.getExpr() instanceof SQLIdentifierExpr) { String ident = ((SQLIdentifierExpr) x.getExpr()).getName(); @@ -91,10 +101,10 @@ public class MySqlSchemaStatVisitor extends MySqlASTVisitorAdapter { Map aliasMap = aliasLocal.get(); aliasMap.put(ident, ident); - + accept(x.getItems()); accept(x.getWhere()); - + return false; } @@ -240,12 +250,12 @@ public class MySqlSchemaStatVisitor extends MySqlASTVisitorAdapter { } public boolean visit(SQLSelectQueryBlock x) { - + if (x.getFrom() instanceof SQLSubqueryTableSource) { x.getFrom().accept(this); return false; } - + x.putAttribute("_original_use_mode", modeLocal.get()); modeLocal.set(Mode.Select); @@ -281,10 +291,16 @@ public class MySqlSchemaStatVisitor extends MySqlASTVisitorAdapter { if (x.getOwner() instanceof SQLIdentifierExpr) { String owner = ((SQLIdentifierExpr) x.getOwner()).getName(); - Map aliasMap = aliasLocal.get(); - if (aliasMap != null) { - String table = aliasMap.get(owner); - fields.add(new Column(table, x.getName())); + if (owner != null) { + Map aliasMap = aliasLocal.get(); + if (aliasMap != null) { + String table = aliasMap.get(owner); + + // table == null时是SubQuery + if (table != null) { + fields.add(new Column(table, x.getName())); + } + } } } return false; diff --git a/src/test/java/com/alibaba/druid/sql/mysql/bvt/visitor/MySqlSchemaStatVisitorTest_Subquery2.java b/src/test/java/com/alibaba/druid/sql/mysql/bvt/visitor/MySqlSchemaStatVisitorTest_Subquery2.java new file mode 100644 index 0000000000..de765b397d --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/mysql/bvt/visitor/MySqlSchemaStatVisitorTest_Subquery2.java @@ -0,0 +1,44 @@ +package com.alibaba.druid.sql.mysql.bvt.visitor; + +import java.util.List; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor.Column; + +public class MySqlSchemaStatVisitorTest_Subquery2 extends TestCase { + + public void test_0() throws Exception { + String sql = "SELECT a.id, a.name, b.name groupName FROM (select id, name, groupId from users limit 10) a inner join groups b on a.groupId = b.id"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println(sql); + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getFields()); + + Assert.assertEquals(2, visitor.getTables().size()); + Assert.assertEquals(true, visitor.getTables().containsKey("users")); + Assert.assertEquals(true, visitor.getTables().containsKey("groups")); + + Assert.assertEquals(5, visitor.getFields().size()); + Assert.assertEquals(true, visitor.getFields().contains(new Column("users", "id"))); + Assert.assertEquals(true, visitor.getFields().contains(new Column("users", "groupId"))); + Assert.assertEquals(true, visitor.getFields().contains(new Column("users", "name"))); + Assert.assertEquals(true, visitor.getFields().contains(new Column("groups", "id"))); + Assert.assertEquals(true, visitor.getFields().contains(new Column("groups", "name"))); + + } + +}