From aa41581ce2916ce6870e34b85ff20b254d80383c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AB=98=E9=93=81?= Date: Sat, 9 Jan 2016 17:58:43 +0800 Subject: [PATCH] bug fixed sql parser grouping sets --- .../sql/ast/expr/SQLGroupingSetExpr.java | 5 -- .../ast/statement/MySqlSelectGroupBy.java | 56 ------------------- .../odps/visitor/OdpsOutputVisitor.java | 25 +-------- .../druid/sql/parser/SQLExprParser.java | 26 +++++++++ .../sql/visitor/SQLASTOutputVisitor.java | 16 +++++- .../druid/bvt/sql/GroupingSetsTest.java | 19 +++++++ 6 files changed, 60 insertions(+), 87 deletions(-) delete mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectGroupBy.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/GroupingSetsTest.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLGroupingSetExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLGroupingSetExpr.java index 49e71c3ad7..10e03ebc11 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLGroupingSetExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLGroupingSetExpr.java @@ -20,7 +20,6 @@ import java.util.List; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLExprImpl; -import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLGroupingSetExpr extends SQLExprImpl { @@ -33,10 +32,6 @@ public class SQLGroupingSetExpr extends SQLExprImpl { @Override protected void accept0(SQLASTVisitor visitor) { - accept0((OracleASTVisitor) visitor); - } - - protected void accept0(OracleASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, parameters); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectGroupBy.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectGroupBy.java deleted file mode 100644 index 419c470f1b..0000000000 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectGroupBy.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 1999-2101 Alibaba Group Holding Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.druid.sql.dialect.mysql.ast.statement; - -import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; -import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; -import com.alibaba.druid.sql.visitor.SQLASTVisitor; - -public class MySqlSelectGroupBy extends SQLSelectGroupByClause { - - private boolean rollUp = false; - - public boolean isRollUp() { - return rollUp; - } - - public void setRollUp(boolean rollUp) { - this.rollUp = rollUp; - } - - @Override - protected void accept0(SQLASTVisitor visitor) { - if (visitor instanceof MySqlASTVisitor) { - accept0((MySqlASTVisitor) visitor); - } else { - if (visitor.visit(this)) { - acceptChild(visitor, this.getItems()); - acceptChild(visitor, this.getHaving()); - } - - visitor.endVisit(this); - } - } - - protected void accept0(MySqlASTVisitor visitor) { - if (visitor.visit(this)) { - acceptChild(visitor, this.getItems()); - acceptChild(visitor, this.getHaving()); - } - - visitor.endVisit(this); - } -} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java index add24fc9b7..96134f46dc 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java @@ -31,7 +31,6 @@ import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType; -import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableElement; @@ -71,6 +70,8 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis builtInFunctions.add("EXPLODE"); builtInFunctions.add("LEAST"); builtInFunctions.add("GREATEST"); + + groupItemSingleLine = true; } public OdpsOutputVisitor(Appendable appender){ @@ -274,28 +275,6 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis return false; } - public boolean visit(SQLSelectGroupByClause x) { - int itemSize = x.getItems().size(); - if (itemSize > 0) { - print0(ucase ? "GROUP BY " : "group by "); - incrementIndent(); - for (int i = 0; i < itemSize; ++i) { - if (i != 0) { - println(", "); - } - x.getItems().get(i).accept(this); - } - decrementIndent(); - } - - if (x.getHaving() != null) { - println(); - print0(ucase ? "HAVING " : "having "); - x.getHaving().accept(this); - } - return false; - } - protected void printSelectList(List selectList) { incrementIndent(); for (int i = 0, size = selectList.size(); i < size; ++i) { diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index 186902b4f1..00abe07fda 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -198,6 +198,7 @@ public class SQLExprParser extends SQLParser { switch (tok) { case LPAREN: lexer.nextToken(); + sqlExpr = expr(); if (lexer.token() == Token.COMMA) { SQLListExpr listExpr = new SQLListExpr(); @@ -209,6 +210,7 @@ public class SQLExprParser extends SQLParser { sqlExpr = listExpr; } + accept(Token.RPAREN); break; case INSERT: @@ -683,6 +685,30 @@ public class SQLExprParser extends SQLParser { lexer.nextToken(); accept(Token.LPAREN); + + for (;;) { + SQLExpr item; + if (lexer.token() == Token.LPAREN) { + lexer.nextToken(); + + SQLListExpr listExpr = new SQLListExpr(); + this.exprList(listExpr.getItems(), listExpr); + item = listExpr; + + accept(Token.RPAREN); + } else { + item = this.expr(); + } + + item.setParent(groupingSets); + groupingSets.getParameters().add(item); + + if (lexer.token() == Token.RPAREN) { + break; + } + + accept(Token.COMMA); + } this.exprList(groupingSets.getParameters(), groupingSets); 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 decf6d524e..e5e607d861 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -169,9 +169,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab private String indent = "\t"; private int indentCount = 0; private boolean prettyFormat = true; - protected boolean ucase = true; + protected boolean ucase = true; protected int selectListNumberOfLine = 5; + protected boolean groupItemSingleLine = false; + private List parameters; public SQLASTOutputVisitor(Appendable appender){ @@ -734,9 +736,17 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab } public boolean visit(SQLSelectGroupByClause x) { - if (x.getItems().size() > 0) { + int itemSize = x.getItems().size(); + if (itemSize > 0) { print0(ucase ? "GROUP BY " : "group by "); - printAndAccept(x.getItems(), ", "); + incrementIndent(); + for (int i = 0; i < itemSize; ++i) { + if (i != 0) { + println(", "); + } + x.getItems().get(i).accept(this); + } + decrementIndent(); } if (x.getHaving() != null) { diff --git a/src/test/java/com/alibaba/druid/bvt/sql/GroupingSetsTest.java b/src/test/java/com/alibaba/druid/bvt/sql/GroupingSetsTest.java new file mode 100644 index 0000000000..b4612ade69 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/GroupingSetsTest.java @@ -0,0 +1,19 @@ +package com.alibaba.druid.bvt.sql; + +import org.junit.Assert; + +import com.alibaba.druid.sql.SQLUtils; + +import junit.framework.TestCase; + +public class GroupingSetsTest extends TestCase { + public void test_groupingSets() throws Exception { + String sql = "SELECT brand, size, sum(sales) FROM items_sold GROUP BY GROUPING SETS ((brand), (size), ());"; + + String result = SQLUtils.format(sql, null); + + Assert.assertEquals("SELECT brand, size, SUM(sales)" + + "\nFROM items_sold" + + "\nGROUP BY GROUPING SETS ((brand), (size), ());", result); + } +}