Skip to content

Commit 495a7f2

Browse files
committed
fixes #91
1 parent d0ce413 commit 495a7f2

File tree

8 files changed

+142
-0
lines changed

8 files changed

+142
-0
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ Also I would like to know about needed examples or documentation stuff.
3232

3333
## Extensions in the latest SNAPSHOT version 0.9.2
3434

35+
* support for within group expressions, e.g. oracls LISTAGG function
36+
37+
```sql
38+
SELECT LISTAGG(col1, '##') WITHIN GROUP (ORDER BY col1) FROM table1
39+
```
40+
3541
* support for inner with statements
3642

3743
```sql

src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ public interface ExpressionVisitor {
136136
void visit(Modulo modulo);
137137

138138
void visit(AnalyticExpression aexpr);
139+
140+
void visit(WithinGroupExpression wgexpr);
139141

140142
void visit(ExtractExpression eexpr);
141143

src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,4 +312,12 @@ public void visit(JsonExpression jsonExpr) {
312312
public void visit(RegExpMySQLOperator expr) {
313313
visitBinaryExpression(expr);
314314
}
315+
316+
@Override
317+
public void visit(WithinGroupExpression wgexpr) {
318+
wgexpr.getExprList().accept(this);
319+
for (OrderByElement element : wgexpr.getOrderByElements()) {
320+
element.getExpression().accept(this);
321+
}
322+
}
315323
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2015 JSQLParser
6+
* %%
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Lesser General Public License as
9+
* published by the Free Software Foundation, either version 2.1 of the
10+
* License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Lesser Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Lesser Public
18+
* License along with this program. If not, see
19+
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
20+
* #L%
21+
*/
22+
package net.sf.jsqlparser.expression;
23+
24+
import java.util.List;
25+
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
26+
import net.sf.jsqlparser.statement.select.OrderByElement;
27+
28+
/**
29+
*
30+
* @author toben
31+
*/
32+
public class WithinGroupExpression implements Expression {
33+
34+
private String name;
35+
36+
public String getName() {
37+
return name;
38+
}
39+
40+
public void setName(String name) {
41+
this.name = name;
42+
}
43+
44+
private List<OrderByElement> orderByElements;
45+
46+
public List<OrderByElement> getOrderByElements() {
47+
return orderByElements;
48+
}
49+
50+
public void setOrderByElements(List<OrderByElement> orderByElements) {
51+
this.orderByElements = orderByElements;
52+
}
53+
54+
private ExpressionList exprList;
55+
56+
public ExpressionList getExprList() {
57+
return exprList;
58+
}
59+
60+
public void setExprList(ExpressionList exprList) {
61+
this.exprList = exprList;
62+
}
63+
64+
@Override
65+
public void accept(ExpressionVisitor visitor) {
66+
visitor.visit(this);
67+
}
68+
69+
@Override
70+
public String toString() {
71+
StringBuilder b = new StringBuilder();
72+
73+
b.append(name);
74+
b.append(exprList.toString());
75+
b.append(" WITHIN GROUP (");
76+
77+
b.append("ORDER BY ");
78+
for (int i = 0; i < orderByElements.size(); i++) {
79+
if (i > 0) {
80+
b.append(", ");
81+
}
82+
b.append(orderByElements.get(i).toString());
83+
}
84+
85+
b.append(")");
86+
87+
return b.toString();
88+
}
89+
90+
}

src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,4 +498,8 @@ public void visit(AllTableColumns allTableColumns) {
498498
public void visit(SelectExpressionItem item) {
499499
item.getExpression().accept(this);
500500
}
501+
502+
@Override
503+
public void visit(WithinGroupExpression wgexpr) {
504+
}
501505
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,4 +515,9 @@ public void visit(JsonExpression jsonExpr) {
515515
buffer.append(jsonExpr.toString());
516516
}
517517

518+
@Override
519+
public void visit(WithinGroupExpression wgexpr) {
520+
buffer.append(wgexpr.toString());
521+
}
522+
518523
}

src/main/javacc/net/sf/jsqlparser/parser/JSqlParserCC.jj

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
206206
| <K_ONLY:"ONLY">
207207
| <K_COMMIT:"COMMIT">
208208
| <K_UNIQUE:"UNIQUE">
209+
| <K_WITHIN:"WITHIN">
209210
}
210211

211212
TOKEN : /* Numeric Constants */
@@ -1733,6 +1734,8 @@ Expression PrimaryExpression():
17331734

17341735
| LOOKAHEAD(AnalyticExpression()) retval=AnalyticExpression()
17351736

1737+
| LOOKAHEAD(WithinGroupExpression()) retval=WithinGroupExpression()
1738+
17361739
| LOOKAHEAD(ExtractExpression()) retval=ExtractExpression()
17371740

17381741
| LOOKAHEAD([sign="+" | sign="-"] JsonExpression()) [sign="+" | sign="-"] retval=JsonExpression()
@@ -1814,6 +1817,26 @@ IntervalExpression IntervalExpression() : {
18141817
}
18151818
}
18161819

1820+
WithinGroupExpression WithinGroupExpression() :
1821+
{
1822+
Token token = null;
1823+
List<OrderByElement> orderByElements = null;
1824+
WithinGroupExpression result = new WithinGroupExpression();
1825+
ExpressionList exprList;
1826+
}
1827+
{
1828+
token = <S_IDENTIFIER> "(" exprList = SimpleExpressionList() ")"
1829+
<K_WITHIN> <K_GROUP>
1830+
"(" orderByElements = OrderByElements() ")"
1831+
1832+
{
1833+
result.setName(token.image);
1834+
result.setExprList(exprList);
1835+
result.setOrderByElements(orderByElements);
1836+
return result;
1837+
}
1838+
}
1839+
18171840
AnalyticExpression AnalyticExpression() :
18181841
{
18191842
AnalyticExpression retval = new AnalyticExpression();

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,4 +1649,8 @@ public void testSelectOracleColl() throws JSQLParserException {
16491649
public void testSelectInnerWith() throws JSQLParserException {
16501650
assertSqlCanBeParsedAndDeparsed("SELECT * FROM (WITH actor AS (SELECT 'a' aid FROM DUAL) SELECT aid FROM actor)");
16511651
}
1652+
1653+
public void testSelectWithinGroup() throws JSQLParserException {
1654+
assertSqlCanBeParsedAndDeparsed("SELECT LISTAGG(col1, '##') WITHIN GROUP (ORDER BY col1) FROM table1");
1655+
}
16521656
}

0 commit comments

Comments
 (0)