Skip to content

Commit bff268a

Browse files
Assorted fixes (#1666)
* fix: add missing public Getter Add public Getter for `updateSets` Fixes #1630 * feat: LISTAGG() with OVER() clause fixes issue #1652 fixes 3 more Special Oracle Tests * fix: White-list CURRENT_DATE and CURRENT_TIMESTAMP tokens allows CURRENT_DATE(3) and CURRENT_TIMESTAMP(3) as regular functions fixes #1507 fixes #1607 * feat: Deparser for Expression Lists Visit each Expression of a List instead ExpressionList.toString() fixes #1608 * fix: Lookahead needed
1 parent e186588 commit bff268a

File tree

20 files changed

+250
-58
lines changed

20 files changed

+250
-58
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,20 @@ public String toString() {
253253
case WITHIN_GROUP:
254254
b.append("WITHIN GROUP");
255255
break;
256+
case WITHIN_GROUP_OVER:
257+
b.append("WITHIN GROUP (");
258+
windowDef.orderBy.toStringOrderByElements(b);
259+
b.append(") OVER (");
260+
windowDef.partitionBy.toStringPartitionBy(b);
261+
b.append(")");
262+
break;
256263
default:
257264
b.append("OVER");
258265
}
259266

260267
if (windowName != null) {
261268
b.append(" ").append(windowName);
262-
} else {
269+
} else if (type!=AnalyticType.WITHIN_GROUP_OVER) {
263270
b.append(" ");
264271
b.append(windowDef.toString());
265272
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@
1212
public enum AnalyticType {
1313
OVER,
1414
WITHIN_GROUP,
15+
16+
WITHIN_GROUP_OVER,
1517
FILTER_ONLY
1618
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public void setOrderByElements(List<OrderByElement> orderByElements) {
2727
this.orderByElements = orderByElements;
2828
}
2929

30-
void toStringOrderByElements(StringBuilder b) {
30+
public void toStringOrderByElements(StringBuilder b) {
3131
if (orderByElements != null && !orderByElements.isEmpty()) {
3232
b.append("ORDER BY ");
3333
for (int i = 0; i < orderByElements.size(); i++) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public void setPartitionExpressionList(ExpressionList partitionExpressionList, b
2929
this.brackets = brackets;
3030
}
3131

32-
void toStringPartitionBy(StringBuilder b) {
32+
public void toStringPartitionBy(StringBuilder b) {
3333
if (partitionExpressionList != null && !partitionExpressionList.getExpressions().isEmpty()) {
3434
b.append("PARTITION BY ");
3535
b.append(PlainSelect.

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,20 @@
1515

1616
public class WindowDefinition {
1717

18+
1819
final OrderByClause orderBy = new OrderByClause();
1920
final PartitionByClause partitionBy = new PartitionByClause();
2021
WindowElement windowElement = null;
2122
private String windowName;
2223

24+
public OrderByClause getOrderBy() {
25+
return orderBy;
26+
}
27+
28+
public PartitionByClause getPartitionBy() {
29+
return partitionBy;
30+
}
31+
2332
public WindowElement getWindowElement() {
2433
return windowElement;
2534
}

src/main/java/net/sf/jsqlparser/parser/ParserKeywordsUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ public static void buildGrammarForRelObjectNameWithoutValue(File file) throws Ex
365365
+ "{ Token tk = null; }\n"
366366
+ "{\n"
367367
//@todo: find a way to avoid those hardcoded compound tokens
368-
+ " ( tk=<S_IDENTIFIER> | tk=<S_QUOTED_IDENTIFIER> | tk=<K_DATE_LITERAL> | tk=<K_DATETIMELITERAL> | tk=<K_STRING_FUNCTION_NAME> | tk=<K_ISOLATION> \n"
368+
+ " ( tk=<S_IDENTIFIER> | tk=<S_QUOTED_IDENTIFIER> | tk=<K_DATE_LITERAL> | tk=<K_DATETIMELITERAL> | tk=<K_STRING_FUNCTION_NAME> | tk=<K_ISOLATION> | tk=<K_TIME_KEY_EXPR> \n"
369369
+ " ");
370370

371371
for (String keyword: allKeywords) {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ public static String getStringList(List<?> list, boolean useComma, boolean useBr
572572
*/
573573
public static StringBuilder appendStringListTo(StringBuilder builder, List<?> list, boolean useComma, boolean useBrackets) {
574574
if (list != null) {
575-
String comma = useComma ? "," : "";
575+
String comma = useComma ? ", " : " ";
576576

577577
if (useBrackets) {
578578
builder.append("(");
@@ -581,7 +581,7 @@ public static StringBuilder appendStringListTo(StringBuilder builder, List<?> li
581581
int size = list.size();
582582
for (int i = 0; i < size; i++) {
583583
builder.append(list.get(i)).append(i < size - 1
584-
? comma + " "
584+
? comma
585585
: "");
586586
}
587587

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public String toString() {
8888
StringBuilder b = new StringBuilder();
8989

9090
b.append("(VALUES ");
91-
for (Iterator<ExpressionList> it = getMultiExpressionList().getExprList().iterator(); it.
91+
for (Iterator<ExpressionList> it = getMultiExpressionList().getExpressionLists().iterator(); it.
9292
hasNext();) {
9393
b.append(PlainSelect.getStringList(it.next().getExpressions(), true, !isNoBrackets()));
9494
if (it.hasNext()) {
@@ -97,7 +97,7 @@ public String toString() {
9797
}
9898
b.append(")");
9999
if (alias != null) {
100-
b.append(alias.toString());
100+
b.append(alias);
101101

102102
if (columnNames != null) {
103103
b.append("(");

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

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -465,19 +465,7 @@ public void visit(Function function) {
465465

466466
@Override
467467
public void visit(ExpressionList expressionList) {
468-
if (expressionList.isUsingBrackets()) {
469-
buffer.append("(");
470-
}
471-
for (Iterator<Expression> iter = expressionList.getExpressions().iterator(); iter.hasNext();) {
472-
Expression expression = iter.next();
473-
expression.accept(this);
474-
if (iter.hasNext()) {
475-
buffer.append(", ");
476-
}
477-
}
478-
if (expressionList.isUsingBrackets()) {
479-
buffer.append(")");
480-
}
468+
new ExpressionListDeParser(this, buffer, expressionList.isUsingBrackets(), true).deParse(expressionList.getExpressions());
481469
}
482470

483471
@Override
@@ -709,13 +697,20 @@ public void visit(AnalyticExpression aexpr) {
709697
case WITHIN_GROUP:
710698
buffer.append("WITHIN GROUP");
711699
break;
700+
case WITHIN_GROUP_OVER:
701+
buffer.append("WITHIN GROUP (");
702+
aexpr.getWindowDefinition().getOrderBy().toStringOrderByElements(buffer);
703+
buffer.append(") OVER (");
704+
aexpr.getWindowDefinition().getPartitionBy().toStringPartitionBy(buffer);
705+
buffer.append(")");
706+
break;
712707
default:
713708
buffer.append("OVER");
714709
}
715710

716711
if (aexpr.getWindowName() != null) {
717712
buffer.append(" ").append(aexpr.getWindowName());
718-
} else {
713+
} else if (aexpr.getType()!=AnalyticType.WITHIN_GROUP_OVER) {
719714
buffer.append(" (");
720715

721716
if (partitionExpressionList != null && !partitionExpressionList.getExpressions().isEmpty()) {
@@ -833,7 +828,8 @@ public void visit(MySQLGroupConcat groupConcat) {
833828

834829
@Override
835830
public void visit(ValueListExpression valueList) {
836-
buffer.append(valueList.toString());
831+
ExpressionList expressionList = valueList.getExpressionList();
832+
expressionList.accept(this);
837833
}
838834

839835
@Override
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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 net.sf.jsqlparser.expression.Expression;
13+
import net.sf.jsqlparser.expression.ExpressionVisitor;
14+
15+
import java.util.Collection;
16+
17+
public class ExpressionListDeParser extends AbstractDeParser<Collection<Expression>> {
18+
19+
private final ExpressionVisitor expressionVisitor;
20+
private final boolean useBrackets;
21+
private final boolean useComma;
22+
23+
public ExpressionListDeParser(ExpressionVisitor expressionVisitor, StringBuilder builder, boolean useBrackets, boolean useComma) {
24+
super(builder);
25+
this.expressionVisitor = expressionVisitor;
26+
this.useBrackets = useBrackets;
27+
this.useComma = useComma;
28+
}
29+
30+
@Override
31+
public void deParse(Collection<Expression> expressions) {
32+
if (expressions != null) {
33+
String comma = useComma ? ", " : " ";
34+
if (useBrackets) {
35+
buffer.append("(");
36+
}
37+
int i=0;
38+
int size = expressions.size() - 1;
39+
for (Expression expression: expressions) {
40+
expression.accept(expressionVisitor);
41+
if (i<size) {
42+
buffer.append(comma);
43+
}
44+
i++;
45+
}
46+
47+
if (useBrackets) {
48+
buffer.append(")");
49+
}
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)