Skip to content

Commit 82f3da8

Browse files
committed
refactored group by expressions into separate class, first step to support grouping sets
1 parent 749ad55 commit 82f3da8

File tree

7 files changed

+152
-33
lines changed

7 files changed

+152
-33
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2019 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.statement.select;
11+
12+
import java.util.ArrayList;
13+
import java.util.List;
14+
import net.sf.jsqlparser.expression.Expression;
15+
16+
public class GroupByElement {
17+
18+
private List<Expression> groupByExpressions = new ArrayList<>();
19+
20+
public void accept(GroupByVisitor groupByVisitor) {
21+
groupByVisitor.visit(this);
22+
}
23+
24+
public List<Expression> getGroupByExpressions() {
25+
return groupByExpressions;
26+
}
27+
28+
public void setGroupByExpressions(List<Expression> groupByExpressions) {
29+
this.groupByExpressions = groupByExpressions;
30+
}
31+
32+
public void addGroupByExpression(Expression groupByExpression) {
33+
groupByExpressions.add(groupByExpression);
34+
}
35+
36+
@Override
37+
public String toString() {
38+
StringBuilder b = new StringBuilder();
39+
b.append("GROUP BY ");
40+
41+
b.append(PlainSelect.getStringList(groupByExpressions));
42+
43+
return b.toString();
44+
}
45+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2019 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.statement.select;
11+
12+
public interface GroupByVisitor {
13+
14+
void visit(GroupByElement groupBy);
15+
}

src/main/java/net/sf/jsqlparser/statement/select/PlainSelect.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class PlainSelect extends ASTNodeAccessImpl implements SelectBody {
2727
private FromItem fromItem;
2828
private List<Join> joins;
2929
private Expression where;
30-
private List<Expression> groupByColumnReferences;
30+
private GroupByElement groupBy;
3131
private List<OrderByElement> orderByElements;
3232
private Expression having;
3333
private Limit limit;
@@ -199,19 +199,19 @@ public void setHaving(Expression expression) {
199199
*
200200
* @return a list of {@link Expression}s
201201
*/
202-
public List<Expression> getGroupByColumnReferences() {
203-
return groupByColumnReferences;
202+
public GroupByElement getGroupBy() {
203+
return this.groupBy;
204204
}
205205

206-
public void setGroupByColumnReferences(List<Expression> list) {
207-
groupByColumnReferences = list;
206+
public void setGroupByElement(GroupByElement groupBy) {
207+
this.groupBy = groupBy;
208208
}
209209

210210
public void addGroupByColumnReference(Expression expr) {
211-
if (groupByColumnReferences == null) {
212-
groupByColumnReferences = new ArrayList<Expression>();
211+
if (groupBy == null) {
212+
groupBy = new GroupByElement();
213213
}
214-
groupByColumnReferences.add(expr);
214+
groupBy.addGroupByExpression(expr);
215215
}
216216

217217
public OracleHierarchicalExpression getOracleHierarchical() {
@@ -343,7 +343,9 @@ public String toString() {
343343
if (oracleHierarchical != null) {
344344
sql.append(oracleHierarchical.toString());
345345
}
346-
sql.append(getFormatedList(groupByColumnReferences, "GROUP BY"));
346+
if (groupBy != null) {
347+
sql.append(" ").append(groupBy.toString());
348+
}
347349
if (having != null) {
348350
sql.append(" HAVING ").append(having);
349351
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2019 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.util.deparser;
11+
12+
import java.util.Iterator;
13+
import net.sf.jsqlparser.expression.Expression;
14+
import net.sf.jsqlparser.expression.ExpressionVisitor;
15+
import net.sf.jsqlparser.statement.select.GroupByElement;
16+
17+
public class GroupByDeParser {
18+
19+
protected StringBuilder buffer;
20+
private ExpressionVisitor expressionVisitor;
21+
22+
GroupByDeParser() {
23+
}
24+
25+
public GroupByDeParser(ExpressionVisitor expressionVisitor, StringBuilder buffer) {
26+
this.expressionVisitor = expressionVisitor;
27+
this.buffer = buffer;
28+
}
29+
30+
public void deParse(GroupByElement groupBy) {
31+
buffer.append("GROUP BY ");
32+
for (Iterator<Expression> iter = groupBy.getGroupByExpressions().iterator(); iter.hasNext();) {
33+
iter.next().accept(expressionVisitor);
34+
if (iter.hasNext()) {
35+
buffer.append(", ");
36+
}
37+
}
38+
}
39+
40+
void setExpressionVisitor(ExpressionVisitor expressionVisitor) {
41+
this.expressionVisitor = expressionVisitor;
42+
}
43+
44+
void setBuffer(StringBuilder buffer) {
45+
this.buffer = buffer;
46+
}
47+
}

src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,9 @@ public void visit(PlainSelect plainSelect) {
123123
plainSelect.getOracleHierarchical().accept(expressionVisitor);
124124
}
125125

126-
if (plainSelect.getGroupByColumnReferences() != null) {
127-
buffer.append(" GROUP BY ");
128-
for (Iterator<Expression> iter = plainSelect.getGroupByColumnReferences().iterator(); iter.
129-
hasNext();) {
130-
Expression columnReference = iter.next();
131-
columnReference.accept(expressionVisitor);
132-
if (iter.hasNext()) {
133-
buffer.append(", ");
134-
}
135-
}
126+
if (plainSelect.getGroupBy() != null) {
127+
buffer.append(" ");
128+
new GroupByDeParser(expressionVisitor, buffer).deParse(plainSelect.getGroupBy());
136129
}
137130

138131
if (plainSelect.getHaving() != null) {
@@ -168,7 +161,7 @@ public void visit(PlainSelect plainSelect) {
168161
deparseOptimizeFor(plainSelect.getOptimizeFor());
169162
}
170163
if (plainSelect.getForXmlPath() != null) {
171-
buffer.append(" FOR XML PATH(" + plainSelect.getForXmlPath() + ")");
164+
buffer.append(" FOR XML PATH(").append(plainSelect.getForXmlPath()).append(")");
172165
}
173166
if (plainSelect.isUseBrackets()) {
174167
buffer.append(")");

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,7 @@ PlainSelect PlainSelect() #PlainSelect:
11551155
List<SelectItem> distinctOn = null;
11561156
Expression where = null;
11571157
List<OrderByElement> orderByElements;
1158-
List<Expression> groupByColumnReferences = null;
1158+
GroupByElement groupBy = null;
11591159
Expression having = null;
11601160
Limit limit = null;
11611161
Offset offset = null;
@@ -1212,7 +1212,7 @@ PlainSelect PlainSelect() #PlainSelect:
12121212

12131213
[ where=WhereClause() { plainSelect.setWhere(where); }]
12141214
[ oracleHierarchicalQueryClause=OracleHierarchicalQueryClause() { plainSelect.setOracleHierarchical(oracleHierarchicalQueryClause); } ]
1215-
[ groupByColumnReferences=GroupByColumnReferences() { plainSelect.setGroupByColumnReferences(groupByColumnReferences); }]
1215+
[ groupBy=GroupByColumnReferences() { plainSelect.setGroupByElement(groupBy); }]
12161216
[ having=Having() { plainSelect.setHaving(having); }]
12171217
[LOOKAHEAD(<K_ORDER> <K_SIBLINGS> <K_BY>) orderByElements = OrderByElements() { plainSelect.setOracleSiblings(true); plainSelect.setOrderByElements(orderByElements); } ]
12181218
[LOOKAHEAD(<K_ORDER> <K_BY>) orderByElements = OrderByElements() { plainSelect.setOrderByElements(orderByElements); } ]
@@ -1795,16 +1795,16 @@ OracleHierarchicalExpression OracleHierarchicalQueryClause():
17951795
}
17961796
}
17971797

1798-
List<Expression> GroupByColumnReferences():
1798+
GroupByElement GroupByColumnReferences():
17991799
{
1800-
Expression columnReference = null;
1801-
List<Expression> columnReferences = new ArrayList<Expression>();
1800+
Expression columnReference;
1801+
GroupByElement groupBy = new GroupByElement();
18021802
}
18031803
{
1804-
<K_GROUP> <K_BY> columnReference=SimpleExpression() {columnReferences.add(columnReference); }
1805-
("," columnReference=SimpleExpression() {columnReferences.add(columnReference); } )*
1804+
<K_GROUP> <K_BY> columnReference=SimpleExpression() {groupBy.addGroupByExpression(columnReference); }
1805+
("," columnReference=SimpleExpression() {groupBy.addGroupByExpression(columnReference); } )*
18061806
{
1807-
return columnReferences;
1807+
return groupBy;
18081808
}
18091809
}
18101810

src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,17 +1130,17 @@ public void testGroupBy() throws JSQLParserException {
11301130
String statement = "SELECT * FROM tab1 WHERE a > 34 GROUP BY tab1.b";
11311131
Select select = (Select) parserManager.parse(new StringReader(statement));
11321132
PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
1133-
assertEquals(1, plainSelect.getGroupByColumnReferences().size());
1134-
assertEquals("tab1.b", ((Column) plainSelect.getGroupByColumnReferences().get(0)).
1133+
assertEquals(1, plainSelect.getGroupBy().getGroupByExpressions().size());
1134+
assertEquals("tab1.b", ((Column) plainSelect.getGroupBy().getGroupByExpressions().get(0)).
11351135
getFullyQualifiedName());
11361136
assertStatementCanBeDeparsedAs(select, statement);
11371137

11381138
statement = "SELECT * FROM tab1 WHERE a > 34 GROUP BY 2, 3";
11391139
select = (Select) parserManager.parse(new StringReader(statement));
11401140
plainSelect = (PlainSelect) select.getSelectBody();
1141-
assertEquals(2, plainSelect.getGroupByColumnReferences().size());
1142-
assertEquals(2, ((LongValue) plainSelect.getGroupByColumnReferences().get(0)).getValue());
1143-
assertEquals(3, ((LongValue) plainSelect.getGroupByColumnReferences().get(1)).getValue());
1141+
assertEquals(2, plainSelect.getGroupBy().getGroupByExpressions().size());
1142+
assertEquals(2, ((LongValue) plainSelect.getGroupBy().getGroupByExpressions().get(0)).getValue());
1143+
assertEquals(3, ((LongValue) plainSelect.getGroupBy().getGroupByExpressions().get(1)).getValue());
11441144
assertStatementCanBeDeparsedAs(select, statement);
11451145
}
11461146

@@ -3591,4 +3591,21 @@ public void visit(PlainSelect plainSelect) {
35913591
});
35923592
}
35933593
}
3594+
3595+
@Test
3596+
public void testGroupingSets1() throws JSQLParserException {
3597+
assertSqlCanBeParsedAndDeparsed("SELECT COL_1, COL_2, COL_3, COL_4, COL_5, COL_6 FROM TABLE_1 "
3598+
+ "GROUP BY "
3599+
+ " GROUPING SETS( (COL_1, COL_2, COL_3, COL_4), (COL_5, COL_6))");
3600+
}
3601+
3602+
@Test
3603+
public void testGroupingSets2() throws JSQLParserException {
3604+
assertSqlCanBeParsedAndDeparsed("SELECT COL_1 FROM TABLE_1 GROUP BY GROUPING SETS( COL_1 )");
3605+
}
3606+
3607+
@Test
3608+
public void testGroupingSets3() throws JSQLParserException {
3609+
assertSqlCanBeParsedAndDeparsed("SELECT COL_1 FROM TABLE_1 GROUP BY GROUPING SETS( COL_1, () )");
3610+
}
35943611
}

0 commit comments

Comments
 (0)