Skip to content

Commit

Permalink
feat: Databricks IGNORE/RESPECT NULLS
Browse files Browse the repository at this point in the history
- IGNORE/RESPECT NULLS for aggregate functions
- `VALUES` can have an `Alias`

Signed-off-by: Andreas Reichel <andreas@manticore-projects.com>
  • Loading branch information
manticore-projects committed May 27, 2024
1 parent e07f8d0 commit 544b168
Show file tree
Hide file tree
Showing 20 changed files with 112 additions and 30 deletions.
2 changes: 1 addition & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
* This file was generated by the Gradle 'init' task.
*/

rootProject.name = 'jsqlparser'
rootProject.name = 'JSQLFormatter'
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public AnalyticExpression(Function function) {
}
}
this.havingClause = function.getHavingClause();
this.ignoreNullsOutside = function.isIgnoreNullsOutside();
this.nullHandling = function.getNullHandling();
this.funcOrderBy = function.getOrderByElements();
this.limit = function.getLimit();
Expand Down
23 changes: 22 additions & 1 deletion src/main/java/net/sf/jsqlparser/expression/Function.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public String toString() {
private Column attributeColumn = null;
private List<OrderByElement> orderByElements;
private NullHandling nullHandling = null;
private boolean ignoreNullsOutside = false; // IGNORE NULLS outside function parameters
private Limit limit = null;

private KeepExpression keep = null;
Expand Down Expand Up @@ -148,6 +149,15 @@ public Function setNullHandling(NullHandling nullHandling) {
return this;
}

public boolean isIgnoreNullsOutside() {
return ignoreNullsOutside;
}

public Function setIgnoreNullsOutside(boolean ignoreNullsOutside) {
this.ignoreNullsOutside = ignoreNullsOutside;
return this;
}

public Limit getLimit() {
return limit;
}
Expand Down Expand Up @@ -321,7 +331,7 @@ public String toString() {
havingClause.appendTo(b);
}

if (nullHandling != null) {
if (nullHandling != null && !isIgnoreNullsOutside()) {
switch (nullHandling) {
case IGNORE_NULLS:
b.append(" IGNORE NULLS");
Expand Down Expand Up @@ -357,6 +367,17 @@ public String toString() {

String ans = getName() + params;

if (nullHandling != null && isIgnoreNullsOutside()) {
switch (nullHandling) {
case IGNORE_NULLS:
ans += " IGNORE NULLS";
break;
case RESPECT_NULLS:
ans += " RESPECT NULLS";
break;
}
}

if (attributeExpression != null) {
ans += "." + attributeExpression;
} else if (attributeColumn != null) {
Expand Down
15 changes: 12 additions & 3 deletions src/main/java/net/sf/jsqlparser/statement/select/Values.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,21 @@
public class Values extends Select implements FromItem {

private ExpressionList<Expression> expressions;
private Alias alias;

public Values() {
// empty constructor
this(null, null);
}

public Values(ExpressionList<Expression> expressions) {
this.expressions = expressions;
}

public Values(ExpressionList<Expression> expressions, Alias alias) {
this.expressions = expressions;
this.alias = alias;
}

public ExpressionList<?> getExpressions() {
return expressions;
}
Expand All @@ -42,6 +48,9 @@ public void setExpressions(ExpressionList<Expression> expressions) {
public StringBuilder appendSelectBodyTo(StringBuilder builder) {
builder.append("VALUES ");
builder.append(expressions.toString());
if (alias != null) {
builder.append(" ").append(alias);
}
return builder;
}

Expand Down Expand Up @@ -74,12 +83,12 @@ public void accept(FromItemVisitor fromItemVisitor) {

@Override
public Alias getAlias() {
return null;
return alias;
}

@Override
public void setAlias(Alias alias) {

this.alias = alias;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ public void visit(Function function) {
havingClause.getExpression().accept(this);
}

if (function.getNullHandling() != null) {
if (function.getNullHandling() != null && !function.isIgnoreNullsOutside()) {
switch (function.getNullHandling()) {
case IGNORE_NULLS:
buffer.append(" IGNORE NULLS");
Expand Down Expand Up @@ -643,6 +643,17 @@ public void visit(Function function) {
buffer.append(")");
}

if (function.getNullHandling() != null && function.isIgnoreNullsOutside()) {
switch (function.getNullHandling()) {
case IGNORE_NULLS:
buffer.append(" IGNORE NULLS");
break;
case RESPECT_NULLS:
buffer.append(" RESPECT NULLS");
break;
}
}

if (function.getAttribute() != null) {
buffer.append(".").append(function.getAttribute());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,8 @@ public ValuesStatementDeParser(ExpressionVisitor expressionVisitor, StringBuilde
public void deParse(Values values) {
buffer.append("VALUES ");
values.getExpressions().accept(expressionVisitor);
if (values.getAlias() != null) {
buffer.append(" ").append(values.getAlias());
}
}
}
38 changes: 26 additions & 12 deletions src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -5086,16 +5086,6 @@ void windowFun(AnalyticExpression retval):{
WindowDefinition winDef;
} {
(
[
(
<K_IGNORE> <K_NULLS> { retval.setNullHandling(Function.NullHandling.IGNORE_NULLS); retval.setIgnoreNullsOutside(true); }
)
|
(
<K_RESPECT> <K_NULLS> { retval.setNullHandling(Function.NullHandling.RESPECT_NULLS); retval.setIgnoreNullsOutside(true); }
)
]

<K_OVER> {retval.setType(AnalyticType.OVER);}
|
<K_WITHIN> <K_GROUP> {retval.setType(AnalyticType.WITHIN_GROUP);}
Expand Down Expand Up @@ -5146,8 +5136,13 @@ AnalyticExpression AnalyticExpression(Function function) :
Expression filter = null;
}
{
((<K_FILTER> "(" <K_WHERE> {retval.setType(AnalyticType.FILTER_ONLY);} filter = Expression() ")" [ LOOKAHEAD(2) windowFun(retval) ] )
| windowFun(retval))
(
(
<K_FILTER> "(" <K_WHERE> {retval.setType(AnalyticType.FILTER_ONLY);} filter = Expression() ")"
[ LOOKAHEAD(2) windowFun(retval) ]
)
| windowFun(retval)
)
{
retval.setFilterExpression(filter);
return retval;
Expand Down Expand Up @@ -5610,6 +5605,7 @@ Function InternalFunction(boolean escaped):

")"


[ "." (
// tricky lookahead since we do need to support the following constructs
// schema.f1().f2() - Function with Function Column
Expand All @@ -5620,6 +5616,24 @@ Function InternalFunction(boolean escaped):
)
]

[
(
<K_IGNORE> <K_NULLS>
{
retval.setNullHandling(Function.NullHandling.IGNORE_NULLS);
retval.setIgnoreNullsOutside(true);
}
)
|
(
<K_RESPECT> <K_NULLS>
{
retval.setNullHandling(Function.NullHandling.RESPECT_NULLS);
retval.setIgnoreNullsOutside(true);
}
)
]

[ LOOKAHEAD(2) keep = KeepExpression() ]

{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,15 @@ void testRedshiftApproximate() throws JSQLParserException {

TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
}

@Test
void testDatabricks() throws JSQLParserException {
String sqlStr = "SELECT any_value(col) IGNORE NULLS FROM test;";

TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);

sqlStr = "SELECT any_value(col) IGNORE NULLS FROM VALUES (NULL), (5), (20) AS tab(col);";

TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ select deptno
from emp

--@FAILURE: Encountered unexpected token: "by" "BY" recorded first on Aug 3, 2021, 7:20:08 AM
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Nov 14, 2022, 11:44:23 AM
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Nov 14, 2022, 11:44:23 AM
--@FAILURE: Encountered unexpected token: "group" "GROUP" recorded first on May 27, 2024, 9:38:25 AM
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@


--@FAILURE: Encountered unexpected token: "by" "BY" recorded first on Aug 3, 2021, 7:20:08 AM
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Nov 14, 2022, 11:44:22 AM
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Nov 14, 2022, 11:44:22 AM
--@FAILURE: Encountered unexpected token: "(" "(" recorded first on May 27, 2024, 9:38:28 AM
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ select manager_id, last_name, hire_date,
range numtodsinterval(100, 'day') preceding) as t_count
from employees

--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: Encountered unexpected token: "(" "(" recorded first on May 27, 2024, 9:38:27 AM
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ from
)


--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: Encountered unexpected token: "group" "GROUP" recorded first on May 27, 2024, 9:38:28 AM
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ SELECT STALENESS,
FROM
A

--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:07 AM
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:07 AM
--@FAILURE: Encountered unexpected token: "(" "(" recorded first on May 27, 2024, 9:38:27 AM
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ from T



--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: Encountered unexpected token: "over" "OVER" recorded first on May 27, 2024, 9:38:27 AM
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ select
case when row_number() over (partition by bo# order by staleness, osize, obj#) = 1 then 32 else 0 end + 64 aflags
from f

--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: Encountered unexpected token: "over" "OVER" recorded first on May 27, 2024, 9:38:27 AM
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ select staleness
, part#, bo#
from st0

--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: Encountered unexpected token: "over" "OVER" recorded first on May 27, 2024, 9:38:28 AM
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ level4[any] = case when org_level[cv()] = 4 then ename [cv()] end
)))

--@FAILURE: Encountered unexpected token: "return" <S_IDENTIFIER> recorded first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: Encountered unexpected token: "return" "RETURN" recorded first on 9 Dec 2023, 18:20:44
--@FAILURE: Encountered unexpected token: "return" "RETURN" recorded first on 9 Dec 2023, 18:20:44
--@FAILURE: Encountered unexpected token: "(" "(" recorded first on May 27, 2024, 9:38:28 AM
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@ select spf.*, nvl(a, ddr_a) as a, b, d,
)


--@FAILURE: Encountered unexpected token: "partition" "PARTITION" recorded first on Aug 3, 2021, 7:20:07 AM
--@FAILURE: Encountered unexpected token: "partition" "PARTITION" recorded first on Aug 3, 2021, 7:20:07 AM
--@FAILURE: Encountered unexpected token: "(" "(" recorded first on May 27, 2024, 9:38:28 AM
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,5 @@ select
)

--@FAILURE: Encountered unexpected token: "by" "BY" recorded first on Aug 3, 2021, 7:20:08 AM
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Nov 14, 2022, 11:44:23 AM
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Nov 14, 2022, 11:44:23 AM
--@FAILURE: Encountered unexpected token: "(" "(" recorded first on May 27, 2024, 9:38:28 AM
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,5 @@ select * from (
)
where rownum_ >= ?

--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM
--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: Encountered unexpected token: "(" "(" recorded first on May 27, 2024, 9:38:27 AM

0 comments on commit 544b168

Please sign in to comment.