diff --git a/api/src/test/java/org/opensearch/sql/api/UnifiedQueryPlannerTest.java b/api/src/test/java/org/opensearch/sql/api/UnifiedQueryPlannerTest.java index bb2d1e4a53f..008121e8377 100644 --- a/api/src/test/java/org/opensearch/sql/api/UnifiedQueryPlannerTest.java +++ b/api/src/test/java/org/opensearch/sql/api/UnifiedQueryPlannerTest.java @@ -159,6 +159,18 @@ public void unsupportedFeatureIsRethrownAsSemanticCheckException() { .assertErrorMessageContains("unsupported in Calcite"); } + @Test + public void unsupportedWindowFunctionIsRethrownAsSemanticCheckException() { + // Window functions outside WINDOW_FUNC_MAPPING reach + // CalciteRexNodeVisitor#visitWindowFunction's + // orElseThrow. The throw site emits CalciteUnsupportedException so this path normalizes to a + // 4xx SemanticCheckException rather than escaping as a 500. + givenInvalidQuery("source = catalog.employees | eventstats rank()") + .assertErrorType(SemanticCheckException.class) + .assertCauseType(CalciteUnsupportedException.class) + .assertErrorMessageContains("Unexpected window function: rank"); + } + @Test public void assertionErrorIsWrappedAsSemanticCheckException() { // Remove when the underlying Calcite assertion is fixed. diff --git a/core/src/main/java/org/opensearch/sql/calcite/CalciteRexNodeVisitor.java b/core/src/main/java/org/opensearch/sql/calcite/CalciteRexNodeVisitor.java index 3c37a11ba5b..849b615f970 100644 --- a/core/src/main/java/org/opensearch/sql/calcite/CalciteRexNodeVisitor.java +++ b/core/src/main/java/org/opensearch/sql/calcite/CalciteRexNodeVisitor.java @@ -705,7 +705,7 @@ public RexNode visitWindowFunction(WindowFunction node, CalcitePlanContext conte node.getWindowFrame()); }) .orElseThrow( - () -> new UnsupportedOperationException("Unexpected window function: " + funcName)); + () -> new CalciteUnsupportedException("Unexpected window function: " + funcName)); } private List translateOrderKeys(