Skip to content

Commit 43d97ea

Browse files
committed
backported analytic expressions from fork
1 parent ce45fbc commit 43d97ea

File tree

6 files changed

+284
-2
lines changed

6 files changed

+284
-2
lines changed

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

100755100644
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public class AnalyticExpression implements Expression {
4343
private Expression offset;
4444
private Expression defaultValue;
4545
private boolean allColumns = false;
46+
private WindowElement windowElement;
4647

4748
@Override
4849
public void accept(ExpressionVisitor expressionVisitor) {
@@ -97,6 +98,14 @@ public void setDefaultValue(Expression defaultValue) {
9798
this.defaultValue = defaultValue;
9899
}
99100

101+
public WindowElement getWindowElement() {
102+
return windowElement;
103+
}
104+
105+
public void setWindowElement(WindowElement windowElement) {
106+
this.windowElement = windowElement;
107+
}
108+
100109
@Override
101110
public String toString() {
102111
StringBuilder b = new StringBuilder();
@@ -153,6 +162,11 @@ private void toStringOrderByElements(StringBuilder b) {
153162
}
154163
b.append(orderByElements.get(i).toString());
155164
}
165+
166+
if(windowElement != null){
167+
b.append(' ');
168+
b.append(windowElement);
169+
}
156170
}
157171
}
158172
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2014 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+
public class WindowElement {
25+
26+
public enum Type {
27+
28+
ROWS,
29+
RANGE
30+
}
31+
32+
private Type type;
33+
private WindowOffset offset;
34+
private WindowRange range;
35+
36+
public Type getType() {
37+
return type;
38+
}
39+
40+
public void setType(Type type) {
41+
this.type = type;
42+
}
43+
44+
public WindowOffset getOffset() {
45+
return offset;
46+
}
47+
48+
public void setOffset(WindowOffset offset) {
49+
this.offset = offset;
50+
}
51+
52+
public WindowRange getRange() {
53+
return range;
54+
}
55+
56+
public void setRange(WindowRange range) {
57+
this.range = range;
58+
}
59+
60+
@Override
61+
public String toString() {
62+
StringBuilder buffer = new StringBuilder(type.toString());
63+
64+
if (offset != null) {
65+
buffer.append(offset.toString());
66+
} else if (range != null) {
67+
buffer.append(range.toString());
68+
}
69+
70+
return buffer.toString();
71+
}
72+
73+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2014 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+
public class WindowOffset {
25+
26+
public enum Type {
27+
28+
PRECEDING,
29+
FOLLOWING,
30+
CURRENT,
31+
EXPR
32+
}
33+
34+
private Expression expression;
35+
private Type type;
36+
37+
public Expression getExpression() {
38+
return expression;
39+
}
40+
41+
public void setExpression(Expression expression) {
42+
this.expression = expression;
43+
}
44+
45+
public Type getType() {
46+
return type;
47+
}
48+
49+
public void setType(Type type) {
50+
this.type = type;
51+
}
52+
53+
@Override
54+
public String toString() {
55+
StringBuilder buffer = new StringBuilder();
56+
if (expression != null) {
57+
buffer.append(' ');
58+
buffer.append(expression);
59+
if (type != null) {
60+
buffer.append(' ');
61+
buffer.append(type);
62+
}
63+
buffer.append(' ');
64+
} else {
65+
switch (type) {
66+
case PRECEDING:
67+
buffer.append(" UNBOUNDED PRECEDING");
68+
break;
69+
case FOLLOWING:
70+
buffer.append(" UNBOUNDED FOLLOWING");
71+
break;
72+
case CURRENT:
73+
buffer.append(" CURRENT ROW ");
74+
break;
75+
default:
76+
break;
77+
}
78+
79+
}
80+
81+
return buffer.toString();
82+
}
83+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2014 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+
public class WindowRange {
25+
26+
private WindowOffset start;
27+
private WindowOffset end;
28+
29+
public WindowOffset getEnd() {
30+
return end;
31+
}
32+
33+
public void setEnd(WindowOffset end) {
34+
this.end = end;
35+
}
36+
37+
public WindowOffset getStart() {
38+
return start;
39+
}
40+
41+
public void setStart(WindowOffset start) {
42+
this.start = start;
43+
}
44+
45+
@Override
46+
public String toString() {
47+
StringBuilder buffer = new StringBuilder();
48+
buffer.append(" BETWEEN");
49+
buffer.append(start);
50+
buffer.append(" AND ");
51+
buffer.append(end);
52+
return buffer.toString();
53+
}
54+
}

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

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,13 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
187187
| <K_NULLS: "NULLS">
188188
| <K_FIRST: "FIRST">
189189
| <K_LAST: "LAST">
190+
| <K_ROWS: "ROWS">
191+
| <K_RANGE: "RANGE">
192+
| <K_UNBOUNDED: "UNBOUNDED">
193+
| <K_PRECEDING: "PRECEDING">
194+
| <K_FOLLOWING: "FOLLOWING">
195+
| <K_CURRENT: "CURRENT">
196+
| <K_ROW: "ROW">
190197
}
191198

192199
TOKEN : /* Numeric Constants */
@@ -1679,25 +1686,76 @@ AnalyticExpression AnalyticExpression() :
16791686
Expression expr = null;
16801687
Expression offset = null;
16811688
Expression defaultValue = null;
1689+
WindowElement windowElement = null;
16821690
}
16831691
{
16841692
token=<S_IDENTIFIER> { retval.setName(token.image); }
16851693
"(" [ expr=SimpleExpression() ["," offset=SimpleExpression() ["," defaultValue=SimpleExpression() ]] | "*" { retval.setAllColumns(true); } ] ")" <K_OVER> "("
16861694
[<K_PARTITION> <K_BY> column=Column() {plist.add(column);} ("," column=Column() {plist.add(column);} )* ]
1687-
[olist=OrderByElements() ]
1695+
[olist=OrderByElements() [windowElement = WindowElement() ] ]
1696+
16881697
{
16891698
retval.setExpression(expr);
16901699
retval.setOffset(offset);
16911700
retval.setDefaultValue(defaultValue);
16921701
retval.setPartitionByColumns(plist);
16931702
retval.setOrderByElements(olist);
1703+
retval.setWindowElement(windowElement);
16941704
}
16951705
")"
16961706
{
16971707
return retval;
16981708
}
16991709
}
17001710

1711+
WindowElement WindowElement():
1712+
{
1713+
WindowElement windowElement = new WindowElement();
1714+
WindowRange range = new WindowRange();
1715+
WindowOffset offset = null;
1716+
}
1717+
{
1718+
(<K_ROWS> { windowElement.setType(WindowElement.Type.ROWS); } | <K_RANGE> { windowElement.setType(WindowElement.Type.RANGE); } )
1719+
( (
1720+
<K_BETWEEN> { windowElement.setRange(range); }
1721+
offset = WindowOffset() { range.setStart(offset); }
1722+
<K_AND> offset = WindowOffset() { range.setEnd(offset); }
1723+
)
1724+
|
1725+
offset = WindowOffset() { windowElement.setOffset(offset); }
1726+
)
1727+
1728+
{
1729+
return windowElement;
1730+
}
1731+
}
1732+
1733+
WindowOffset WindowOffset():
1734+
{
1735+
WindowOffset offset = new WindowOffset();
1736+
Expression expr = null;
1737+
}
1738+
{
1739+
(
1740+
1741+
<K_UNBOUNDED> (<K_PRECEDING> { offset.setType(WindowOffset.Type.PRECEDING); return offset; } |
1742+
<K_FOLLOWING> { offset.setType(WindowOffset.Type.FOLLOWING); return offset; } )
1743+
)
1744+
|
1745+
( <K_CURRENT> <K_ROW> { offset.setType(WindowOffset.Type.CURRENT); return offset;} )
1746+
|
1747+
( expr = SimpleExpression() {
1748+
offset.setType(WindowOffset.Type.EXPR);
1749+
offset.setExpression(expr);
1750+
}
1751+
(<K_PRECEDING> { offset.setType(WindowOffset.Type.PRECEDING); } | <K_FOLLOWING> { offset.setType(WindowOffset.Type.FOLLOWING); } )
1752+
)
1753+
1754+
{
1755+
return offset;
1756+
}
1757+
}
1758+
17011759
ExtractExpression ExtractExpression() :
17021760
{
17031761
ExtractExpression retval = new ExtractExpression();

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ public void testProblemSqlAnalytic7Count() throws JSQLParserException {
980980
}
981981

982982
public void testProblemSqlAnalytic8Complex() throws JSQLParserException {
983-
String stmt = "SELECT ID, NAME, SALARY, SUM(SALARY) OVER () AS SUM_SAL, AVG(SALARY) OVER () AS AVG_SAL, MIN(SALARY) OVER () AS MIN_SAL, MAX(SALARY) OVER () AS MAX_SAL, COUNT(*) OVER () AS ROWS FROM STAFF WHERE ID < 60 ORDER BY ID";
983+
String stmt = "SELECT ID, NAME, SALARY, SUM(SALARY) OVER () AS SUM_SAL, AVG(SALARY) OVER () AS AVG_SAL, MIN(SALARY) OVER () AS MIN_SAL, MAX(SALARY) OVER () AS MAX_SAL, COUNT(*) OVER () AS ROWS2 FROM STAFF WHERE ID < 60 ORDER BY ID";
984984
assertSqlCanBeParsedAndDeparsed(stmt);
985985
}
986986

0 commit comments

Comments
 (0)