Skip to content

Commit 8e46e7a

Browse files
committed
fix: make analytic expression visitor null-safe
1 parent b00322e commit 8e46e7a

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

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

+14-4
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@
6464
import net.sf.jsqlparser.statement.select.UnPivot;
6565
import net.sf.jsqlparser.statement.select.WithItem;
6666

67+
import java.util.Optional;
68+
6769
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.UncommentedEmptyMethodBody"})
6870
public class ExpressionVisitorAdapter
6971
implements ExpressionVisitor, PivotVisitor, SelectItemVisitor {
@@ -382,11 +384,19 @@ public void visit(AnalyticExpression expr) {
382384
element.getExpression().accept(this);
383385
}
384386
}
385-
386387
if (expr.getWindowElement() != null) {
387-
expr.getWindowElement().getRange().getStart().getExpression().accept(this);
388-
expr.getWindowElement().getRange().getEnd().getExpression().accept(this);
389-
expr.getWindowElement().getOffset().getExpression().accept(this);
388+
/*
389+
Visit expressions from the range and offset of the window element.
390+
Do this using optional chains, because several things down the tree
391+
can be null e.g. the expression. So, null-safe versions of e.g.:
392+
expr.getWindowElement().getOffset().getExpression().accept(this);
393+
*/
394+
Optional.ofNullable(expr.getWindowElement().getRange()).map(WindowRange::getStart)
395+
.map(WindowOffset::getExpression).ifPresent(e -> e.accept(this));
396+
Optional.ofNullable(expr.getWindowElement().getRange()).map(WindowRange::getEnd)
397+
.map(WindowOffset::getExpression).ifPresent(e -> e.accept(this));
398+
Optional.ofNullable(expr.getWindowElement().getOffset())
399+
.map(WindowOffset::getExpression).ifPresent(e -> e.accept(this));
390400
}
391401
}
392402

src/test/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapterTest.java

+9
Original file line numberDiff line numberDiff line change
@@ -259,4 +259,13 @@ public void visit(AllTableColumns all) {
259259
assertNotNull(holder[0]);
260260
assertEquals("a.*", holder[0].toString());
261261
}
262+
263+
@Test
264+
public void testAnalyticExpressionWithPartialWindowElement() throws JSQLParserException {
265+
ExpressionVisitorAdapter adapter = new ExpressionVisitorAdapter();
266+
Expression expression = CCJSqlParserUtil.parseExpression(
267+
"SUM(\"Spent\") OVER (PARTITION BY \"ID\" ORDER BY \"Name\" ASC ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)");
268+
269+
expression.accept(adapter);
270+
}
262271
}

0 commit comments

Comments
 (0)