From 69b6a40e569b7ea77784fc9c1cbaee30156a3937 Mon Sep 17 00:00:00 2001 From: yakolee Date: Thu, 12 Jun 2014 17:20:23 +0800 Subject: [PATCH] =?UTF-8?q?bugfix:union=E5=AD=90=E6=9F=A5=E8=AF=A2bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statement/SQLUnionQueryTableSource.java | 50 +++++++++++++++++++ .../druid/sql/parser/SQLSelectParser.java | 9 +++- .../sql/visitor/SQLASTOutputVisitor.java | 18 +++++++ .../druid/sql/visitor/SQLASTVisitor.java | 5 ++ .../sql/visitor/SQLASTVisitorAdapter.java | 11 ++++ .../druid/bvt/sql/mysql/SQLSelectTest.java | 9 ++++ 6 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionQueryTableSource.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionQueryTableSource.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionQueryTableSource.java new file mode 100644 index 0000000000..4c5398abdc --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionQueryTableSource.java @@ -0,0 +1,50 @@ +package com.alibaba.druid.sql.ast.statement; + +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +public class SQLUnionQueryTableSource extends SQLTableSourceImpl { + + private SQLUnionQuery union; + + public SQLUnionQueryTableSource(){ + + } + + public SQLUnionQueryTableSource(String alias){ + super(alias); + } + + public SQLUnionQueryTableSource(SQLUnionQuery union, String alias){ + super(alias); + this.setUnion(union); + } + + public SQLUnionQueryTableSource(SQLUnionQuery union){ + this.setUnion(union); + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, union); + } + visitor.endVisit(this); + } + + public void output(StringBuffer buf) { + buf.append("("); + this.union.output(buf); + buf.append(")"); + } + + public SQLUnionQuery getUnion() { + return union; + } + + public void setUnion(SQLUnionQuery union) { + if (union != null) { + union.setParent(this); + } + this.union = union; + } +} diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java index 8f874563e7..dc4e67b2f9 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java @@ -32,6 +32,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableSource; import com.alibaba.druid.sql.ast.statement.SQLUnionOperator; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; +import com.alibaba.druid.sql.ast.statement.SQLUnionQueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause; public class SQLSelectParser extends SQLParser { @@ -316,8 +317,12 @@ public class SQLSelectParser extends SQLParser { if (lexer.token() == Token.SELECT || lexer.token() == Token.WITH) { SQLSelect select = select(); accept(Token.RPAREN); - queryRest(select.getQuery()); - tableSource = new SQLSubqueryTableSource(select); + SQLSelectQuery query = queryRest(select.getQuery()); + if (query instanceof SQLUnionQuery) { + tableSource = new SQLUnionQueryTableSource((SQLUnionQuery) query); + } else { + tableSource = new SQLSubqueryTableSource(select); + } } else if (lexer.token() == Token.LPAREN) { tableSource = parseTableSource(); accept(Token.RPAREN); diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index c3705408b6..dc0e29b553 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -136,6 +136,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableElement; import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; +import com.alibaba.druid.sql.ast.statement.SQLUnionQueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLUnique; import com.alibaba.druid.sql.ast.statement.SQLUniqueConstraint; import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem; @@ -1975,4 +1976,21 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab public void endVisit(SQLBooleanExpr x) { } + + @Override + public boolean visit(SQLUnionQueryTableSource x) { + print("("); + incrementIndent(); + x.getUnion().accept(this); + println(); + decrementIndent(); + print(")"); + + if (x.getAlias() != null) { + print(' '); + print(x.getAlias()); + } + + return false; + } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java index e2b8f59ae8..d3e81f5445 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java @@ -112,6 +112,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSetStatement; import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; +import com.alibaba.druid.sql.ast.statement.SQLUnionQueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLUnique; import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; @@ -540,4 +541,8 @@ public interface SQLASTVisitor { boolean visit(SQLBooleanExpr x); + void endVisit(SQLUnionQueryTableSource x); + + boolean visit(SQLUnionQueryTableSource x); + } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java index 72376edd54..0cbe8de94f 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java @@ -114,6 +114,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSetStatement; import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; +import com.alibaba.druid.sql.ast.statement.SQLUnionQueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLUnique; import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; @@ -1053,4 +1054,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { return true; } + @Override + public void endVisit(SQLUnionQueryTableSource x) { + + } + + @Override + public boolean visit(SQLUnionQueryTableSource x) { + return true; + } + } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/SQLSelectTest.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/SQLSelectTest.java index 4d2e04a367..b796a6f44e 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/SQLSelectTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/SQLSelectTest.java @@ -88,6 +88,15 @@ public class SQLSelectTest extends TestCase { output(stmtList); } + + public void test_select_7() throws Exception { + String sql = "select * from ((select * from test1) UNION (select * from test2) UNION (select * from test3)) where t1='温高铁';"; + + SQLStatementParser parser = new MySqlStatementParser(sql); + List stmtList = parser.parseStatementList(); + + output(stmtList); + } private void output(List stmtList) { for (SQLStatement stmt : stmtList) {