Skip to content

[SQL] Support the MODE aggregate function by desugaring into GROUP BY + COUNT + ARG_MAX - #6806

Open
mihaibudiu wants to merge 1 commit into
feldera:mainfrom
mihaibudiu:mode
Open

[SQL] Support the MODE aggregate function by desugaring into GROUP BY + COUNT + ARG_MAX#6806
mihaibudiu wants to merge 1 commit into
feldera:mainfrom
mihaibudiu:mode

Conversation

@mihaibudiu

Copy link
Copy Markdown
Contributor

Checklist

  • Unit tests added/updated
  • Documentation updated

… COUNT + ARG_MAX

Signed-off-by: Mihai Budiu <mbudiu@feldera.com>
@mihaibudiu

Copy link
Copy Markdown
Contributor Author

We reject MODE(DISTINCT) because it doesn't make any sense.

@mythical-fred mythical-fred 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.

APPROVE.

Nice desugaring: MODE(v) → inner Aggregate(G∪{v}, COUNT(v)) → outer Aggregate(G, ARG_MAX(v, cnt)), joined back with other aggregates via IS NOT DISTINCT FROM on the group keys. Using COUNT(v) rather than COUNT(*) is what makes the NULL semantics fall out naturally — the all-NULL sub-group gets cnt=0 and only wins when it is the only candidate, so MODE of an all-NULL group is NULL and NULLs never beat a real value. The FILTER case is handled by wrapping the value in CASE(cnt > 0, value, NULL) so groups whose rows are all filtered out survive with a NULL mode. Repeated MODE calls with the same (arg, filterArg) share one branch; the final projection reassembles the original column order. Tests cover the happy path, FILTER (including a group with only NULLs passing the filter and a group with no passing rows), interleaved aggregates with a shared MODE branch, empty input, and DISTINCT rejection.

A couple of small observations, none blocking:

  • RejectUnsupportedPlans is a good pattern — worth reusing for other Calcite-accepted-but-unsupported constructs later. Consider giving it its own file once a second case appears.
  • The rule silently returns for GROUPING SETS / CUBE / ROLLUP (non-SIMPLE group type). That will fall through to whatever the backend does with a raw MODE, which today is nothing. If you want a clean error rather than a mysterious backend failure, RejectUnsupportedPlans is the natural place to also reject MODE under non-SIMPLE groupings.
  • Minor: docs say "The rule for selecting the value is not specified if multiple values are tied for the highest frequency" — worth noting that ties in practice depend on ARG_MAX's ordering (which for MODE is a count, and for equal counts is effectively arbitrary). Not a change request, just a doc-precision thought for future.

LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants