Describe the bug
The SingleDistinctToGroupBy optimizer rule rewrites a grouped count(DISTINCT col) into a cheaper nested double aggregate. It fires for plans built by the SQL planner but not for the logically-equivalent plan built by the DataFrame API, so the DataFrame path runs materially slower for the same query.
The divergence is caused by how each front-end places the output alias:
- SQL (count(DISTINCT v) AS n): the alias becomes an outer Projection; Aggregate.aggr_expr holds a bare Expr::AggregateFunction.
- DataFrame API (count(col("v")).distinct().alias("n")): the alias wraps the aggregate directly, so aggr_expr holds Expr::Alias(AggregateFunction).
is_single_distinct_agg only matches a bare Expr::AggregateFunction and returns false for the aliased shape, so the rule never fires for the DataFrame API.
To Reproduce
No response
Expected behavior
No response
Additional context
No response
Describe the bug
The
SingleDistinctToGroupByoptimizer rule rewrites a grouped count(DISTINCT col) into a cheaper nested double aggregate. It fires for plans built by the SQL planner but not for the logically-equivalent plan built by the DataFrame API, so the DataFrame path runs materially slower for the same query.The divergence is caused by how each front-end places the output alias:
is_single_distinct_aggonly matches a bare Expr::AggregateFunction and returns false for the aliased shape, so the rule never fires for the DataFrame API.To Reproduce
No response
Expected behavior
No response
Additional context
No response