Skip to content

Improve error message for unsupported window functions in eventstats/streamstats - #5600

Open
gingeekrishna wants to merge 2 commits into
opensearch-project:mainfrom
gingeekrishna:fix/5168-improve-unsupported-window-function-error
Open

Improve error message for unsupported window functions in eventstats/streamstats#5600
gingeekrishna wants to merge 2 commits into
opensearch-project:mainfrom
gingeekrishna:fix/5168-improve-unsupported-window-function-error

Conversation

@gingeekrishna

Copy link
Copy Markdown
Contributor

Description

Fixes #5168

eventstats/streamstats reject window functions outside WINDOW_FUNC_MAPPING (e.g. rank(), dense_rank(), nth_value()) with a bare "Unexpected window function: X" error.

As confirmed in the issue discussion by @songkant-aws, this is expected behavior, not a bug — rank/dense_rank/nth_value require ORDER BY semantics, but eventstats/streamstats only support partition by. The issue was relabeled error-experience: the fix is to make the error message clearer, not to add support for these functions.

Changes

  • CalciteRexNodeVisitor#visitWindowFunction: replaced the generic "Unexpected window function: X" message with one that names the rejected function and lists the functions eventstats/streamstats do support (sourced from WINDOW_FUNC_MAPPING), so users get actionable guidance instead of a bare error.
  • Updated the existing unit test (UnifiedQueryPlannerTest) and integration tests (CalcitePPLEventstatsIT, CalciteStreamstatsCommandIT) to assert against the new message.
  • Added new integration tests covering rank/dense_rank specifically, since the issue's repro queries used those functions.

Note: this PR builds on top of #5587 (already merged), which fixed the same throw site to return a 4xx instead of a 500. This PR only changes the message text, not the exception type or HTTP status.

Test plan

  • Unit test UnifiedQueryPlannerTest#unsupportedWindowFunctionIsRethrownAsSemanticCheckException passes
  • Integration tests added/updated for eventstats and streamstats (require a live cluster to run in CI)

…streamstats

Window functions outside WINDOW_FUNC_MAPPING (e.g. rank, dense_rank,
nth_value) throw a generic "Unexpected window function: X" from
CalciteRexNodeVisitor#visitWindowFunction. These functions require
ORDER BY semantics that eventstats/streamstats don't have (they only
support partition-by), so they are intentionally unsupported, not a
bug -- but the error message gave users no indication of what to use
instead.

Replace the message with one that names the function and lists the
functions eventstats/streamstats do support, so users get actionable
guidance instead of a bare "unexpected" error.

Fixes opensearch-project#5168

Signed-off-by: Radhakrishnan Pachyappan <gingeekrishna@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

(Review updated until commit 99c53f5)

Here are some key observations to aid the review process:

🧪 PR contains tests
🔒 No security concerns identified
✅ No TODO sections
🔀 No multiple PR themes
⚡ Recommended focus areas for review

Hardcoded list

The error message hardcodes the list of supported functions as a string literal. If WINDOW_FUNC_MAPPING is updated to add or remove functions, this message will become stale and misleading. The list should be generated dynamically from WINDOW_FUNC_MAPPING.keySet() to stay in sync.

() ->
    new CalciteUnsupportedException(
        "Window function '"
            + funcName
            + "' is not supported in eventstats/streamstats."
            + " Supported functions: avg, count, dc, distinct_count, earliest,"
            + " latest, max, min, row_number, stddev_pop, stddev_samp, sum,"
            + " var_pop, var_samp."));

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Latest suggestions up to 99c53f5
Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Use String.format for error message

The error message concatenates multiple strings which can impact readability and
maintainability. Consider using String.format() or a text block for better
formatting and easier future modifications of the supported functions list.

core/src/main/java/org/opensearch/sql/calcite/CalciteRexNodeVisitor.java [709-715]

 new CalciteUnsupportedException(
-    "Window function '"
-        + funcName
-        + "' is not supported in eventstats/streamstats."
-        + " Supported functions: avg, count, dc, distinct_count, earliest,"
-        + " latest, max, min, row_number, stddev_pop, stddev_samp, sum,"
-        + " var_pop, var_samp."));
+    String.format(
+        "Window function '%s' is not supported in eventstats/streamstats."
+            + " Supported functions: avg, count, dc, distinct_count, earliest,"
+            + " latest, max, min, row_number, stddev_pop, stddev_samp, sum,"
+            + " var_pop, var_samp.",
+        funcName));
Suggestion importance[1-10]: 4

__

Why: While using String.format() can improve readability, the current string concatenation approach is perfectly valid and readable. This is a minor style improvement that doesn't significantly impact code quality or functionality.

Low

Previous suggestions

Suggestions up to commit c16fc0c
CategorySuggestion                                                                                                                                    Impact
General
Dynamically generate supported functions list

The hardcoded list of supported functions in the error message may become outdated
if new functions are added to WINDOW_FUNC_MAPPING. Consider dynamically generating
this list from the mapping keys to ensure accuracy and maintainability.

core/src/main/java/org/opensearch/sql/calcite/CalciteRexNodeVisitor.java [709-715]

 new CalciteUnsupportedException(
     "Window function '"
         + funcName
         + "' is not supported in eventstats/streamstats."
-        + " Supported functions: avg, count, dc, distinct_count, earliest,"
-        + " latest, max, min, row_number, stddev_pop, stddev_samp, sum,"
-        + " var_pop, var_samp."));
+        + " Supported functions: "
+        + String.join(", ", WINDOW_FUNC_MAPPING.keySet())
+        + "."));
Suggestion importance[1-10]: 7

__

Why: This suggestion improves maintainability by dynamically generating the list of supported functions from WINDOW_FUNC_MAPPING.keySet() instead of hardcoding them. This ensures the error message stays accurate when new functions are added, reducing maintenance burden and preventing outdated documentation.

Medium

Signed-off-by: Radhakrishnan Pachyappan <gingeekrishna@gmail.com>
@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 99c53f5

@dai-chen dai-chen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I'm trying to add support for rank and dense_rank function in Calcite for unified SQL for analytics engine. If we confirm both are not supported by PPL evenstats and streamstats, shall we remove them from PPL grammar directly? I assume that's the only place window function can be used. Otherwise it will be tricky to check language type in Calcite planner.

@gingeekrishna

Copy link
Copy Markdown
Contributor Author

@dai-chen Good question — I dug into this a bit.

Your assumption holds for PPL specifically: in the PPL grammar, windowFunction (the parenthesized call syntax) is only ever invoked from eventstatsAggTerm/streamstatsAggTerm (OpenSearchPPLParser.g4:922-943), so that is the only place a window function can appear in PPL today.

But it's not the only place in the engine overall. SQL has its own windowFunctionClause/overClause grammar (OpenSearchSQLParser.g4:150-159) that already accepts RANK()/DENSE_RANK() in ... OVER (...). Both SQL and PPL build the same WindowFunction AST node and are resolved by the same CalciteRexNodeVisitor#visitWindowFunction — there's even a comment there noting "SQL emits AggregateFunction for aggregate-as-window (e.g., SUM(x) OVER); PPL emits Function." WINDOW_FUNC_MAPPING in BuiltinFunctionName (used by both paths) simply has no rank/dense_rank entries yet, so both languages fail identically right now.

Practical implication: if you add rank/dense_rank to WINDOW_FUNC_MAPPING and implement them in the shared visitor, that enables them for PPL eventstats/streamstats too, since the mapping/visitor is shared — not just SQL.

So yes, I think removing RANK/DENSE_RANK from PPL's scalarWindowFunctionName rule (lines 933-934) is the right move, and it avoids the language-type check you were worried about: PPL's parser would reject the syntax before it ever reaches the AST/Calcite layer, while SQL's grammar (which already accepts it) passes through untouched. That pushes the language separation to parse time instead of planner time.

One side note on this PR itself: the new error message I added ("Window function 'x' is not supported in eventstats/streamstats") is thrown from that same shared visitor, so it would also currently fire — misleadingly — for a plain SQL RANK() OVER (...) query, since the check isn't actually PPL-specific. I may follow up with a tweak to make that message language-agnostic.

@dai-chen

Copy link
Copy Markdown
Collaborator

@gingeekrishna Thanks for digging in! I've put up PR #5720 for the SQL side. As you confirmed, removing them from grammar should make PPL reject at parse time and leaves my change SQL-only. With both PRs merged, I think we get the language separation at parse time rather than in the planner, which is where it belongs as expected. Thanks!

@dai-chen dai-chen added enhancement New feature or request PPL Piped processing language labels Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request PPL Piped processing language

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] eventstats/streamstats reject window functions that grammar accepts

3 participants