diff --git a/datafusion/optimizer/src/eliminate_group_by_constant.rs b/datafusion/optimizer/src/eliminate_group_by_constant.rs index e21241ba7d993..e3a75b64d5f11 100644 --- a/datafusion/optimizer/src/eliminate_group_by_constant.rs +++ b/datafusion/optimizer/src/eliminate_group_by_constant.rs @@ -64,10 +64,10 @@ impl OptimizerRule for EliminateGroupByConstant { .group_expr .iter() .partition(|expr| is_redundant_group_expr(expr, &group_by_columns)); + // Only eliminate when at least one required group expression remains. A grouping + // aggregate emits 0 rows on empty input; a global aggregate emits 1 NULL row. - if redundant.is_empty() - || (required.is_empty() && aggregate.aggr_expr.is_empty()) - { + if redundant.is_empty() || required.is_empty() { return Ok(Transformed::no(LogicalPlan::Aggregate(aggregate))); } @@ -228,9 +228,8 @@ mod tests { .build()?; assert_optimized_plan_equal!(plan, @r#" - Projection: Utf8("test"), UInt32(123), count(test.c) - Aggregate: groupBy=[[]], aggr=[[count(test.c)]] - TableScan: test + Aggregate: groupBy=[[Utf8("test"), UInt32(123)]], aggr=[[count(test.c)]] + TableScan: test "#) } diff --git a/datafusion/sqllogictest/test_files/aggregate.slt b/datafusion/sqllogictest/test_files/aggregate.slt index 70acff3cb7b9a..fdb4b33e93069 100644 --- a/datafusion/sqllogictest/test_files/aggregate.slt +++ b/datafusion/sqllogictest/test_files/aggregate.slt @@ -7842,6 +7842,23 @@ CREATE TABLE t1(v1 int); statement error DataFusion error: Error during planning: Aggregate functions are not allowed in the WHERE clause. Consider using HAVING instead SELECT v1 FROM t1 WHERE ((count(v1) % 1) << 1) > 0; +# issue: https://github.com/apache/datafusion/issues/11748 +query R +SELECT AVG(v1) FROM t1 GROUP BY false HAVING false; +---- + +query R +SELECT AVG(v1) FROM t1 GROUP BY false; +---- + +statement ok +INSERT INTO t1 VALUES (1), (2), (3); + +query R +SELECT AVG(v1) FROM t1 GROUP BY false; +---- +2 + statement ok DROP TABLE t1; diff --git a/datafusion/sqllogictest/test_files/optimizer_group_by_constant.slt b/datafusion/sqllogictest/test_files/optimizer_group_by_constant.slt index da1e7de22bb7a..9df55512413f3 100644 --- a/datafusion/sqllogictest/test_files/optimizer_group_by_constant.slt +++ b/datafusion/sqllogictest/test_files/optimizer_group_by_constant.slt @@ -60,10 +60,9 @@ FROM test_table t group by 1, 2, 3 ---- logical_plan -01)Projection: Int64(123), Int64(456), Int64(789), count(Int64(1)), avg(t.c12) -02)--Aggregate: groupBy=[[]], aggr=[[count(Int64(1)), avg(t.c12)]] -03)----SubqueryAlias: t -04)------TableScan: test_table projection=[c12] +01)Aggregate: groupBy=[[Int64(123), Int64(456), Int64(789)]], aggr=[[count(Int64(1)), avg(t.c12)]] +02)--SubqueryAlias: t +03)----TableScan: test_table projection=[c12] query TT EXPLAIN @@ -72,8 +71,8 @@ FROM test_table t GROUP BY 1, 2 ---- logical_plan -01)Projection: Date32("2023-05-04") AS dt, Boolean(true) AS today_filter, count(Int64(1)) -02)--Aggregate: groupBy=[[]], aggr=[[count(Int64(1))]] +01)Projection: to_date(Utf8("2023-05-04")) AS dt, date_part(Utf8("DAY"),now()) < Int64(1000) AS today_filter, count(Int64(1)) +02)--Aggregate: groupBy=[[Date32("2023-05-04") AS to_date(Utf8("2023-05-04")), Boolean(true) AS date_part(Utf8("DAY"),now()) < Int64(1000)]], aggr=[[count(Int64(1))]] 03)----SubqueryAlias: t 04)------TableScan: test_table projection=[] @@ -90,10 +89,9 @@ FROM test_table t GROUP BY 1 ---- logical_plan -01)Projection: Boolean(true) AS NOT date_part(Utf8("MONTH"),now()) BETWEEN Int64(50) AND Int64(60), count(Int64(1)) -02)--Aggregate: groupBy=[[]], aggr=[[count(Int64(1))]] -03)----SubqueryAlias: t -04)------TableScan: test_table projection=[] +01)Aggregate: groupBy=[[Boolean(true) AS NOT date_part(Utf8("MONTH"),now()) BETWEEN Int64(50) AND Int64(60)]], aggr=[[count(Int64(1))]] +02)--SubqueryAlias: t +03)----TableScan: test_table projection=[] query TT EXPLAIN @@ -119,7 +117,7 @@ logical_plan # Config reset -# The SLT runner sets `target_partitions` to 4 instead of using the default, so +# The SLT runner sets `target_partitions` to 4 instead of using the default, so # reset it explicitly. statement ok set datafusion.execution.target_partitions = 4;