Skip to content

Commit

Permalink
fix: make analytic expression visitor null-safe (#1944)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjgoss authored Feb 14, 2024
1 parent b00322e commit 768c63f
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
import net.sf.jsqlparser.statement.select.UnPivot;
import net.sf.jsqlparser.statement.select.WithItem;

import java.util.Optional;

@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.UncommentedEmptyMethodBody"})
public class ExpressionVisitorAdapter
implements ExpressionVisitor, PivotVisitor, SelectItemVisitor {
Expand Down Expand Up @@ -382,11 +384,19 @@ public void visit(AnalyticExpression expr) {
element.getExpression().accept(this);
}
}

if (expr.getWindowElement() != null) {
expr.getWindowElement().getRange().getStart().getExpression().accept(this);
expr.getWindowElement().getRange().getEnd().getExpression().accept(this);
expr.getWindowElement().getOffset().getExpression().accept(this);
/*
* Visit expressions from the range and offset of the window element. Do this using
* optional chains, because several things down the tree can be null e.g. the
* expression. So, null-safe versions of e.g.:
* expr.getWindowElement().getOffset().getExpression().accept(this);
*/
Optional.ofNullable(expr.getWindowElement().getRange()).map(WindowRange::getStart)
.map(WindowOffset::getExpression).ifPresent(e -> e.accept(this));
Optional.ofNullable(expr.getWindowElement().getRange()).map(WindowRange::getEnd)
.map(WindowOffset::getExpression).ifPresent(e -> e.accept(this));
Optional.ofNullable(expr.getWindowElement().getOffset())
.map(WindowOffset::getExpression).ifPresent(e -> e.accept(this));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,4 +259,13 @@ public void visit(AllTableColumns all) {
assertNotNull(holder[0]);
assertEquals("a.*", holder[0].toString());
}

@Test
public void testAnalyticExpressionWithPartialWindowElement() throws JSQLParserException {
ExpressionVisitorAdapter adapter = new ExpressionVisitorAdapter();
Expression expression = CCJSqlParserUtil.parseExpression(
"SUM(\"Spent\") OVER (PARTITION BY \"ID\" ORDER BY \"Name\" ASC ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)");

expression.accept(adapter);
}
}

0 comments on commit 768c63f

Please sign in to comment.