Skip to content

COUNT(*) over an empty grouping set with empty input returns 0 (should return 1) #24038

Description

@asolimando

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.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions