Skip to content

feat(optimize): push filter through Distinct nodes - #26

Merged
protosphinx merged 1 commit into
mainfrom
bot/distinct-filter-pushdown
Aug 19, 2026
Merged

protosphinx merged 1 commit into
mainfrom
bot/distinct-filter-pushdown

Conversation

@protosphinx

Copy link
Copy Markdown
Member

Why

Predicate pushdown skips Distinct nodes today, leaving a Filter
sitting above a Distinct after optimization. This is suboptimal: since
predicates are pure, filter(distinct(X), pred) = distinct(filter(X, pred)).
Moving the filter below the dedup step shrinks the row set before the
Distinct operator sees it, reducing both the cardinality it must process
and the overall cost.

The motivating case is WITH DISTINCT ... WHERE ...: the WHERE lands
above the Distinct in the plan, and previously the optimizer could not
push it further.

What

  • src/optimize.rs: add a Plan::Distinct arm to try_push_filter
    that recurses through the Distinct node, pushing the filter into its
    input (6 lines).
  • tests/distinct_optimize.rs: 7 new integration tests covering
    passthrough-var push, renamed-alias push, plan-shape position check,
    optimizer idempotence for RETURN DISTINCT and WITH DISTINCT + WHERE,
    cost improvement, and descend-into-RETURN-DISTINCT-input.

Tests

  • cargo test - 213 tests pass (206 existing + 7 new)
  • cargo clippy --all-targets -- -D warnings - clean
  • cargo fmt --check - clean

Self-merge gate

  • all CI checks pass
  • LOC delta < 250 (152 lines: 6 in src/optimize.rs, 146 in tests/)
  • no public-API surface change (src/lib.rs not modified)
  • no runtime-dependency additions
  • no workflow file changes
  • tests added (tests/distinct_optimize.rs, 7 tests)

Generated by Claude Code

Predicates are pure, so filter(distinct(X), pred) = distinct(filter(X, pred)).
Adding a Distinct arm to try_push_filter lets the optimizer move a WHERE
clause below a WITH DISTINCT, shrinking the row set before dedup rather than
after.

Adds tests/distinct_optimize.rs with 7 tests covering passthrough vars,
renamed aliases, plan-shape assertions, idempotence, and cost verification.
@protosphinx protosphinx added the automated Opened by the daily bot label Aug 19, 2026 — with Claude
@protosphinx
protosphinx merged commit d746d4f into main Aug 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automated Opened by the daily bot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant