Skip to content

Conversation

@dimitris-athanasiou
Copy link
Contributor

This correctly handles aggregations on null values.

Aggregations on constants do not work as per #100634.

However, we can do better in terms of handling null.

We achieve this by 2 changes:

  • we do not fold aggregate functions as AggregateMapper does not handle Literal values.
  • we reuse the existing ReplaceStatsFilteredAggWithEval rule to replace aggs on null with an eval.

I have renamed ReplaceStatsFilteredAggWithEval to ReplaceStatsFilteredOrNullAggWithEval to capture the new scenario where we apply the rule.

Closes #137544

This correctly handles aggregations on null values.

Aggregations on constants do not work as per elastic#100634.

However, we can do better in terms of handling null.

We achieve this by 2 changes:

  - we do not fold aggregate functions as `AggregateMapper` does not handle `Literal` values.
  - we reuse the existing `ReplaceStatsFilteredAggWithEval` rule to replace aggs on null with an eval.

I have renamed `ReplaceStatsFilteredAggWithEval` to `ReplaceStatsFilteredOrNullAggWithEval` to capture
the new scenario where we apply the rule.

Closes elastic#137544
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-analytical-engine (Team:Analytics)

@elasticsearchmachine elasticsearchmachine added Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) v9.4.0 labels Dec 19, 2025
@elasticsearchmachine
Copy link
Collaborator

Hi @dimitris-athanasiou, I've created a changelog YAML for you.

@dimitris-athanasiou dimitris-athanasiou added auto-backport Automatically create backport pull requests when merged v9.2.4 labels Dec 19, 2025
Copy link
Contributor

@alex-spies alex-spies left a comment

Choose a reason for hiding this comment

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

Thank you @dimitris-athanasiou !

Sorry for the drive-by, but this got my attention as we've had issues with aggs on consts in the past. Not a full review, but I wanted to understand the main mechanism.

We're performing the same optimization as for STATS some_agg(...) WHERE false - which is semantically the same, as the WHERE false filter is the same as having no rows, or a single null row, being fed into the agg function. This looks correct to me.

Copy link
Contributor

Choose a reason for hiding this comment

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

It'd be lovely if we could add a couple more tests, as we're adding something pretty new here:

  • tests with different agg functions, esp. the special ones from ReplaceStatsFilteredAggWithEval#mapNullToValue
  • tests with more than 1 agg function where 1 or more get null literals, and some where another agg function does not get a null value.
  • tests with BY
  • tests with INLINE STATS
  • tests with per-agg WHERE clauses

Copy link
Contributor Author

Choose a reason for hiding this comment

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

tests with different agg functions, esp. the special ones from ReplaceStatsFilteredAggWithEval#mapNullToValue

There are already tests for count/count_distinct:

  • stats.countNull
  • stats.countDistinctNull

Those were both working because those two functions are not nullable and they were escaping null-folding because of that.

I'll definitely add tests for all other points you bring up!

import static org.hamcrest.Matchers.startsWith;

//@TestLogging(value = "org.elasticsearch.xpack.esql:TRACE", reason = "debug")
@TestLogging(value = "org.elasticsearch.xpack.esql:TRACE", reason = "debug")
Copy link
Contributor

Choose a reason for hiding this comment

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

Leftover?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, since this closes #137544, let's add the repro queries from the issue to the spec tests?

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

Labels

:Analytics/ES|QL AKA ESQL auto-backport Automatically create backport pull requests when merged >bug Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) v9.2.4 v9.3.1 v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ES|QL] FUSE command fails when a column contains NULL

3 participants