Skip to content

Commit 999db01

Browse files
Implement GROUP BY () without columns (#1218)
* Implement GROUP BY () without columns * Migrate GroupByElement to ExpressionList Also solves issue #1210 automatically * Solves issue #1168, add a test for it.
1 parent 7c21242 commit 999db01

File tree

5 files changed

+116
-21
lines changed

5 files changed

+116
-21
lines changed

src/main/java/net/sf/jsqlparser/expression/operators/relational/ExpressionList.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,20 @@
2424
public class ExpressionList implements ItemsList {
2525

2626
private List<Expression> expressions;
27-
private boolean withBrackets = true;
27+
private boolean usingBrackets = true;
28+
29+
public boolean isUsingBrackets() {
30+
return usingBrackets;
31+
}
32+
33+
public void setUsingBrackets(boolean usingBrackets) {
34+
this.usingBrackets = usingBrackets;
35+
}
36+
37+
public ExpressionList withUsingBrackets(boolean usingBrackets) {
38+
setUsingBrackets(usingBrackets);
39+
return this;
40+
}
2841

2942
public ExpressionList() {
3043
}
@@ -56,9 +69,9 @@ public void setExpressions(List<Expression> expressions) {
5669
this.expressions = expressions;
5770
}
5871

72+
@Deprecated
5973
public ExpressionList withBrackets(boolean brackets) {
60-
this.withBrackets = brackets;
61-
return this;
74+
return withUsingBrackets(brackets);
6275
}
6376

6477
@Override
@@ -68,7 +81,7 @@ public void accept(ItemsListVisitor itemsListVisitor) {
6881

6982
@Override
7083
public String toString() {
71-
return PlainSelect.getStringList(expressions, true, withBrackets);
84+
return PlainSelect.getStringList(expressions, true, usingBrackets);
7285
}
7386

7487
public ExpressionList addExpressions(Collection<? extends Expression> expressions) {

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

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,51 @@
1818
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
1919

2020
public class GroupByElement {
21-
22-
private List<Expression> groupByExpressions = new ArrayList<>();
21+
// ExpressionList has 'usingBrackets = true' and so we need to switch it off explicitly
22+
private ExpressionList groupByExpressions = new ExpressionList().withUsingBrackets(false);
2323
private List groupingSets = new ArrayList();
2424

25+
public boolean isUsingBrackets() {
26+
return groupByExpressions.isUsingBrackets();
27+
}
28+
29+
public void setUsingBrackets(boolean usingBrackets) {
30+
this.groupByExpressions.setUsingBrackets(usingBrackets);
31+
}
32+
33+
public GroupByElement withUsingBrackets(boolean usingBrackets) {
34+
this.groupByExpressions.setUsingBrackets(usingBrackets);
35+
return this;
36+
}
37+
2538
public void accept(GroupByVisitor groupByVisitor) {
2639
groupByVisitor.visit(this);
2740
}
28-
29-
public List<Expression> getGroupByExpressions() {
41+
42+
public ExpressionList getGroupByExpressionList() {
3043
return groupByExpressions;
3144
}
45+
46+
public void setGroupByExpressionList(ExpressionList groupByExpressions) {
47+
this.groupByExpressions=groupByExpressions;
48+
}
49+
50+
@Deprecated
51+
public List<Expression> getGroupByExpressions() {
52+
return groupByExpressions.getExpressions();
53+
}
3254

55+
@Deprecated
3356
public void setGroupByExpressions(List<Expression> groupByExpressions) {
34-
this.groupByExpressions = groupByExpressions;
57+
this.groupByExpressions.setExpressions(groupByExpressions);
3558
}
3659

60+
@Deprecated
3761
public void addGroupByExpression(Expression groupByExpression) {
38-
groupByExpressions.add(groupByExpression);
62+
if (groupByExpressions.getExpressions()==null) {
63+
groupByExpressions.setExpressions(new ArrayList());
64+
}
65+
groupByExpressions.getExpressions().add(groupByExpression);
3966
}
4067

4168
public List getGroupingSets() {
@@ -60,8 +87,14 @@ public String toString() {
6087
StringBuilder b = new StringBuilder();
6188
b.append("GROUP BY ");
6289

63-
if (groupByExpressions.size() > 0) {
64-
b.append(PlainSelect.getStringList(groupByExpressions));
90+
if (groupByExpressions.getExpressions()!=null && groupByExpressions.getExpressions().size() > 0) {
91+
if (groupByExpressions.isUsingBrackets()) {
92+
b.append("( ");
93+
}
94+
b.append(PlainSelect.getStringList(groupByExpressions.getExpressions()));
95+
if (groupByExpressions.isUsingBrackets()) {
96+
b.append(" )");
97+
}
6598
} else if (groupingSets.size() > 0) {
6699
b.append("GROUPING SETS (");
67100
boolean first = true;
@@ -79,6 +112,10 @@ public String toString() {
79112
}
80113
}
81114
b.append(")");
115+
} else {
116+
if (groupByExpressions.isUsingBrackets()) {
117+
b.append("()");
118+
}
82119
}
83120

84121
return b.toString();
@@ -95,13 +132,15 @@ public GroupByElement withGroupingSets(List groupingSets) {
95132
}
96133

97134
public GroupByElement addGroupByExpressions(Expression... groupByExpressions) {
98-
List<Expression> collection = Optional.ofNullable(getGroupByExpressions()).orElseGet(ArrayList::new);
135+
List<Expression> collection
136+
= Optional.ofNullable(getGroupByExpressions()).orElseGet(ArrayList::new);
99137
Collections.addAll(collection, groupByExpressions);
100138
return this.withGroupByExpressions(collection);
101139
}
102140

103141
public GroupByElement addGroupByExpressions(Collection<? extends Expression> groupByExpressions) {
104-
List<Expression> collection = Optional.ofNullable(getGroupByExpressions()).orElseGet(ArrayList::new);
142+
List<Expression> collection
143+
= Optional.ofNullable(getGroupByExpressions()).orElseGet(ArrayList::new);
105144
collection.addAll(groupByExpressions);
106145
return this.withGroupByExpressions(collection);
107146
}

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
package net.sf.jsqlparser.util.deparser;
1111

1212
import java.util.Iterator;
13+
import java.util.List;
1314

1415
import net.sf.jsqlparser.expression.Expression;
1516
import net.sf.jsqlparser.expression.ExpressionVisitor;
@@ -34,12 +35,21 @@ public GroupByDeParser(ExpressionVisitor expressionVisitor, StringBuilder buffer
3435
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
3536
public void deParse(GroupByElement groupBy) {
3637
buffer.append("GROUP BY ");
37-
for (Iterator<Expression> iter = groupBy.getGroupByExpressions().iterator(); iter.hasNext();) {
38-
iter.next().accept(expressionVisitor);
39-
if (iter.hasNext()) {
40-
buffer.append(", ");
38+
if (groupBy.isUsingBrackets()) {
39+
buffer.append("( ");
40+
}
41+
List<Expression> expressions = groupBy.getGroupByExpressionList().getExpressions();
42+
if (expressions != null) {
43+
for (Iterator<Expression> iter = expressions.iterator(); iter.hasNext();) {
44+
iter.next().accept(expressionVisitor);
45+
if (iter.hasNext()) {
46+
buffer.append(", ");
47+
}
4148
}
4249
}
50+
if (groupBy.isUsingBrackets()) {
51+
buffer.append(" )");
52+
}
4353
if (!groupBy.getGroupingSets().isEmpty()) {
4454
buffer.append("GROUPING SETS (");
4555
boolean first = true;

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2325,9 +2325,15 @@ GroupByElement GroupByColumnReferences():
23252325
}
23262326
{
23272327
<K_GROUP> <K_BY>
2328-
(
2329-
columnReference=SimpleExpression() {groupBy.addGroupByExpression(columnReference); }
2330-
("," columnReference=SimpleExpression() {groupBy.addGroupByExpression(columnReference); } )*
2328+
( LOOKAHEAD(2) (
2329+
"(" ")" { groupBy.withUsingBrackets(true); }
2330+
)
2331+
| LOOKAHEAD(3) (
2332+
"(" list = SimpleExpressionList(true) ")" { groupBy.setGroupByExpressionList(list); }
2333+
)
2334+
|
2335+
( list = SimpleExpressionList(false) { groupBy.setGroupByExpressionList(list); }
2336+
)
23312337
|
23322338
<K_GROUPING> <K_SETS> "("
23332339
( LOOKAHEAD(2) "(" ")" { groupBy.addGroupingSet(new ExpressionList()); }

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4577,4 +4577,31 @@ public void testWithValueListWithOutExtraBrackets1135() throws JSQLParserExcepti
45774577
public void testKeywordSynonymIssue1211() throws JSQLParserException {
45784578
assertSqlCanBeParsedAndDeparsed("select businessDate as \"bd\", synonym as \"synonym\" from sc.tab", true);
45794579
}
4580+
4581+
@Test
4582+
public void testGroupedByIssue1176() throws JSQLParserException {
4583+
assertSqlCanBeParsedAndDeparsed(
4584+
"select id_instrument, count(*)\n" + "from cfe.instrument\n" + "group by (id_instrument)",
4585+
true);
4586+
assertSqlCanBeParsedAndDeparsed("select count(*)\n" + "from cfe.instrument\n" + "group by ()",
4587+
true);
4588+
}
4589+
4590+
@Test
4591+
public void testGroupedByWithExtraBracketsIssue1210() throws JSQLParserException {
4592+
assertSqlCanBeParsedAndDeparsed(
4593+
"select a,b,c from table group by rollup(a,b,c)",
4594+
true);
4595+
assertSqlCanBeParsedAndDeparsed("select a,b,c from table group by rollup((a,b,c))",
4596+
true);
4597+
4598+
4599+
}
4600+
4601+
@Test
4602+
public void testGroupedByWithExtraBracketsIssue1168() throws JSQLParserException {
4603+
assertSqlCanBeParsedAndDeparsed(
4604+
"select sum(a) as amount, b, c from TEST_TABLE group by rollup ((a,b),c)",
4605+
true);
4606+
}
45804607
}

0 commit comments

Comments
 (0)