Handle default bounds correctly in WINDOW clause (#16833)

When a window is defined as WINDOW W AS <DEF> and using a syntax of (PARTITION BY col1 ORDER BY col2 ROWS x PRECEDING), we would need to default the other bound to CURRENT ROW

We already have implemented this earlier, but when defined as WINDOW W AS <DEF>, Calcite takes a different route to validate the window.
This commit is contained in:
Sree Charan Manamala 2024-08-06 13:28:44 +05:30 committed by GitHub
parent aeace28ccb
commit ed6b547481
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 12 deletions

View File

@ -133,6 +133,8 @@ public class DruidSqlValidator extends BaseDruidSqlValidator
throw Util.unexpected(windowOrId.getKind());
}
updateBoundsIfNeeded(targetWindow);
@Nullable
SqlNode lowerBound = targetWindow.getLowerBound();
@Nullable
@ -144,17 +146,6 @@ public class DruidSqlValidator extends BaseDruidSqlValidator
);
}
if (lowerBound != null && upperBound == null) {
if (lowerBound.getKind() == SqlKind.FOLLOWING || SqlWindow.isUnboundedFollowing(lowerBound)) {
upperBound = lowerBound;
lowerBound = SqlWindow.createCurrentRow(SqlParserPos.ZERO);
} else {
upperBound = SqlWindow.createCurrentRow(SqlParserPos.ZERO);
}
targetWindow.setLowerBound(lowerBound);
targetWindow.setUpperBound(upperBound);
}
boolean hasBounds = lowerBound != null || upperBound != null;
if (call.getKind() == SqlKind.NTILE && hasBounds) {
throw buildCalciteContextException(
@ -758,6 +749,28 @@ public class DruidSqlValidator extends BaseDruidSqlValidator
|| SqlWindow.isUnboundedPreceding(bound);
}
/**
* Checks if any bound is null and updates with CURRENT ROW
*/
private void updateBoundsIfNeeded(SqlWindow window)
{
@Nullable
SqlNode lowerBound = window.getLowerBound();
@Nullable
SqlNode upperBound = window.getUpperBound();
if (lowerBound != null && upperBound == null) {
if (lowerBound.getKind() == SqlKind.FOLLOWING || SqlWindow.isUnboundedFollowing(lowerBound)) {
upperBound = lowerBound;
lowerBound = SqlWindow.createCurrentRow(SqlParserPos.ZERO);
} else {
upperBound = SqlWindow.createCurrentRow(SqlParserPos.ZERO);
}
window.setLowerBound(lowerBound);
window.setUpperBound(upperBound);
}
}
@Override
public void validateCall(SqlCall call, SqlValidatorScope scope)
{
@ -812,6 +825,10 @@ public class DruidSqlValidator extends BaseDruidSqlValidator
sqlNode
);
}
if (sqlNode instanceof SqlWindow) {
SqlWindow window = (SqlWindow) sqlNode;
updateBoundsIfNeeded(window);
}
}
super.validateWindowClause(select);
}

View File

@ -7,10 +7,11 @@ sql: |
count(*) OVER (partition by dim2 ORDER BY dim1 ROWS 1 PRECEDING),
count(*) OVER (partition by dim2 ORDER BY dim1 ROWS CURRENT ROW),
count(*) OVER (partition by dim2 ORDER BY dim1 ROWS 1 FOLLOWING),
count(*) OVER (partition by dim2 ORDER BY dim1 ROWS UNBOUNDED FOLLOWING)
count(*) OVER W
FROM numfoo
WHERE dim2 IN ('a', 'abc')
GROUP BY dim2, dim1
WINDOW W AS (partition by dim2 ORDER BY dim1 ROWS UNBOUNDED FOLLOWING)
expectedOperators:
- {"type":"naiveSort","columns":[{"column":"_d1","direction":"ASC"},{"column":"_d0","direction":"ASC"}]}