Describe the bug
AggregateExec reports a row count of Exact(0) when its input has no rows, even when the
group-by contains an empty grouping set. GROUPING SETS(()), ROLLUP and CUBE each emit a
grand-total row for such an input, so the row count contradicts execution.
The row count is claimed as Exact, so rules answering a query from statistics (rather than by executing) return an incorrect result.
To Reproduce
CREATE TABLE t(v1 INT) AS VALUES (1), (2);
SELECT SUM(v1) FROM t WHERE false GROUP BY ROLLUP(v1);
-- NULL, one row, correct
SELECT COUNT(*) FROM (SELECT SUM(v1) FROM t WHERE false GROUP BY ROLLUP(v1));
-- 0, expected 1
CUBE(v1) and GROUPING SETS((), (v1)) behave the same way. The aggregate_statistics rule
replaces the outer COUNT(*) with a literal taken from the inner row count.
Expected behavior
1 should be returned, matching what the inner aggregate emits in practice.
Additional context
The column statistics suffer from the same issue, as AggregateExec copies the child's min_value,
max_value and distinct_count for its grouping columns, but a grand-total row holds NULL in
every grouping column, so those values describe rows the aggregate does not emit.
If we fix the number of row count without fixing the column stats too, they could be used to reply to MIN/MAX instead of execution, falling into the same type of problem of COUNT(*).
Related: #21570 reported the execution side of the same query shape, fixed by #22039. This issue
is about the statistics, which still disagree with execution.
Describe the bug
AggregateExecreports a row count ofExact(0)when its input has no rows, even when thegroup-by contains an empty grouping set.
GROUPING SETS(()),ROLLUPandCUBEeach emit agrand-total row for such an input, so the row count contradicts execution.
The row count is claimed as
Exact, so rules answering a query from statistics (rather than by executing) return an incorrect result.To Reproduce
CUBE(v1)andGROUPING SETS((), (v1))behave the same way. Theaggregate_statisticsrulereplaces the outer
COUNT(*)with a literal taken from the inner row count.Expected behavior
1should be returned, matching what the inner aggregate emits in practice.Additional context
The column statistics suffer from the same issue, as
AggregateExeccopies the child'smin_value,max_valueanddistinct_countfor its grouping columns, but a grand-total row holdsNULLinevery grouping column, so those values describe rows the aggregate does not emit.
If we fix the number of row count without fixing the column stats too, they could be used to reply to
MIN/MAXinstead of execution, falling into the same type of problem ofCOUNT(*).Related: #21570 reported the execution side of the same query shape, fixed by #22039. This issue
is about the statistics, which still disagree with execution.