Skip to content

Wrong results: a filter on a constant column keeps the row of an aggregate without GROUP BY #26545

Open

Description

@ameyypawar

Describe the bug

A filter on a constant column, such as k in SELECT 'all' AS k, count(*) ..., is applied below an aggregate without GROUP BY, so it no longer removes the aggregate's row. An aggregate without GROUP BY returns one row even for an empty input, so the query returns that row (count(*) = 0, max(v) = NULL) where it should return none.

To Reproduce

datafusion-cli -c "
CREATE TABLE t(a INT, v INT) AS VALUES (1, 10), (2, 20), (2, 30);
SELECT c FROM (SELECT 'all' AS k, count(*) AS c FROM t) WHERE k = 'none';
"

This currently gives:

+---+
| c |
+---+
| 0 |
+---+

The same happens with other aggregates, with an empty grouping set (ROLLUP, CUBE, GROUPING SETS (..., ())), and in a UNION ALL that labels its branches:

query DataFusion expected
SELECT m FROM (SELECT 'all' AS k, max(v) AS m FROM t) WHERE k = 'none' one row, NULL no rows
SELECT a, c FROM (SELECT 'all' AS k, a, count(*) AS c FROM t GROUP BY ROLLUP(a)) WHERE k = 'none' one row, (NULL, 0) no rows
SELECT c FROM (SELECT 'one' AS k, count(*) AS c FROM t WHERE a = 1 UNION ALL SELECT 'all' AS k, count(*) AS c FROM t) WHERE k = 'all' 0, 3 3

With a true filter (WHERE k = 'all'), or with a grouped aggregate (GROUP BY a), the results are right.

Expected behavior

No rows: the subquery's only row has k = 'all', so k = 'none' is false for it. SQLite 3.51 returns no rows for the count(*) and max(v) queries, and 3 for the UNION ALL (it has no ROLLUP).

Additional context

PushDownFilter moves the filter below the aggregate. In its Aggregate arm, a predicate is pushed when all of its columns are group keys, which holds for a predicate with no columns. EXPLAIN VERBOSE shows logical_plan after push_down_filter with Filter: Utf8("all") = Utf8("none") between the Aggregate and the TableScan.

#22926 made the physical filter pushdown keep filters above aggregates that return a row for an empty input. PushDownFilter has no such check.

Unlike #26503, #26505 and #26508, no correlated subquery is involved, and fixing PushDownFilter does not change their results.

Found with DataFusion CLI v55.1.0, main at d89a85d.

Willingness to contribute

I plan to contribute a fix for this bug independently

Activity

  1. ameyypawar commented on Oct 20, 2026

    @ameyypawar
    Author

    If this is a valid bug, I'd fix it in the Aggregate arm of PushDownFilter: push no predicate below an aggregate that returns a row for an empty input (no GROUP BY, or an empty grouping set), the same check #22926 added on the physical side. I have it ready with tests and can open a PR.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions