Skip to content

Commit

Permalink
[CALCITE-6569] RelToSqlConverter missing IGNORE NULLS for window func…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
JiajunBernoulli authored and mihaibudiu committed Sep 15, 2024
1 parent 6593f26 commit 644e29f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1045,7 +1045,10 @@ public List<SqlNode> toSql(Window.Group group, ImmutableList<RexLiteral> constan
};
RexCall aggCall = (RexCall) winAggCall.accept(replaceConstants);
List<SqlNode> operands = toSql(null, aggCall.operands);
rexOvers.add(createOverCall(aggFunction, operands, sqlWindow, winAggCall.distinct));
final SqlCall overCall =
createOverCall(aggFunction, operands, sqlWindow,
winAggCall.distinct, winAggCall.ignoreNulls);
rexOvers.add(overCall);
}
return rexOvers;
}
Expand Down Expand Up @@ -1092,15 +1095,16 @@ private SqlCall toSql(@Nullable RexProgram program, RexOver rexOver) {
orderList, isRows, lowerBound, upperBound, allowPartial, exclude, POS);

final List<SqlNode> nodeList = toSql(program, rexOver.getOperands());
return createOverCall(sqlAggregateFunction, nodeList, sqlWindow, rexOver.isDistinct());
return createOverCall(sqlAggregateFunction, nodeList, sqlWindow,
rexOver.isDistinct(), rexOver.ignoreNulls());
}

private static SqlCall createOverCall(SqlAggFunction op, List<SqlNode> operands,
SqlWindow window, boolean isDistinct) {
SqlWindow window, boolean isDistinct, boolean ignoreNulls) {
if (op instanceof SqlSumEmptyIsZeroAggFunction) {
// Rewrite "SUM0(x) OVER w" to "COALESCE(SUM(x) OVER w, 0)"
final SqlCall node =
createOverCall(SqlStdOperatorTable.SUM, operands, window, isDistinct);
createOverCall(SqlStdOperatorTable.SUM, operands, window, isDistinct, ignoreNulls);
return SqlStdOperatorTable.COALESCE.createCall(POS, node, ZERO);
}
SqlCall aggFunctionCall;
Expand All @@ -1110,6 +1114,10 @@ private static SqlCall createOverCall(SqlAggFunction op, List<SqlNode> operands,
} else {
aggFunctionCall = op.createCall(POS, operands);
}
if (ignoreNulls) {
aggFunctionCall =
SqlStdOperatorTable.IGNORE_NULLS.createCall(null, POS, aggFunctionCall);
}
return SqlStdOperatorTable.OVER.createCall(POS, aggFunctionCall,
window);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4584,6 +4584,32 @@ private void checkLiteral2(String expression, String expected) {
sql(query).ok(expected);
}

/** Test case for
* <a href="https://issues.apache.org/jira/browse/CALCITE-6569">[CALCITE-6569]
* RelToSqlConverter support IGNORE NULLS for window functions</a>. */
@Test void testIgnoreNullsWindow() {
final String query0 = "SELECT LEAD(\"employee_id\", 2) IGNORE NULLS "
+ "OVER (ORDER BY \"hire_date\") FROM \"employee\"";
final String expected0 = "SELECT LEAD(\"employee_id\", 2) IGNORE NULLS OVER (ORDER BY "
+ "\"hire_date\")\n"
+ "FROM \"foodmart\".\"employee\"";
sql(query0).ok(expected0);

final String query1 = "SELECT "
+ "LAG(\"employee_id\", 1) IGNORE NULLS OVER (ORDER BY \"hire_date\"),"
+ "FIRST_VALUE(\"employee_id\") IGNORE NULLS OVER (ORDER BY \"hire_date\"),"
+ "LAST_VALUE(\"employee_id\") IGNORE NULLS OVER (ORDER BY \"hire_date\")"
+ "FROM \"employee\"";
final String expected1 = "SELECT "
+ "LAG(\"employee_id\", 1) IGNORE NULLS OVER (ORDER BY \"hire_date\"), "
+ "FIRST_VALUE(\"employee_id\") IGNORE NULLS OVER (ORDER BY \"hire_date\""
+ " RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), "
+ "LAST_VALUE(\"employee_id\") IGNORE NULLS OVER (ORDER BY \"hire_date\""
+ " RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)\n"
+ "FROM \"foodmart\".\"employee\"";
sql(query1).ok(expected1);
}

/** Test case for
* <a href="https://issues.apache.org/jira/browse/CALCITE-3112">[CALCITE-3112]
* Support Window in RelToSqlConverter</a>. */
Expand Down

0 comments on commit 644e29f

Please sign in to comment.