Skip to content

Add failing repro of filter leaks across a self-joined dimension - #2452

Draft
shangyian wants to merge 2 commits into
DataJunction:mainfrom
shangyian:bug/self-join-anchor-filter-pushdown
Draft

Add failing repro of filter leaks across a self-joined dimension#2452
shangyian wants to merge 2 commits into
DataJunction:mainfrom
shangyian:bug/self-join-anchor-filter-pushdown

Conversation

@shangyian

Copy link
Copy Markdown
Collaborator

Summary

Reproducing #2451

Test Plan

  • PR has an associated issue: #
  • make check passes
  • make test shows 100% unit test coverage

Deployment Plan

A dimension whose own query self-joins one table gets a filter applied to
every alias of that table, not just the one producing the filtered column.

The repro is a month-to-date bridge: `a` supplies the anchor date, `b`
enumerates the dates from the start of that month through the anchor. Orders
join the bridge on the period side and expose the anchor side, so each order
appears once per window containing it. Filtering on the anchor emits

    WHERE a.date_int IN (20180208, 20180210)
      AND b.date_int IN (20180208, 20180210)

and the second predicate collapses every window to just the filtered dates,
so a metric over the bridged rows returns a plausible but wrong average for
anchors that survive the filter, and drops anchors whose window becomes empty.
No error is raised.

Filter resolution is by bare column name, and both output columns trace back
to `date_int` on the same table, so nothing distinguishes the two sides. The
alias-substitution step in _resolve_pushdown_filters_for_cte then copies the
rewritten predicate onto sibling references to the same physical table, which
is deliberate for disambiguating unrelated tables that share a column name but
wrong when the siblings are two roles of one self-join.

The second test is a control: the same bridge over two different tables filters
correctly, so the trigger is the shared physical table rather than the join
shape. It passes today and should keep passing.
@netlify

netlify Bot commented Aug 24, 2026

Copy link
Copy Markdown

Deploy Preview for thriving-cassata-78ae72 canceled.

Name Link
🔨 Latest commit 9fe0713
🔍 Latest deploy log https://app.netlify.com/projects/thriving-cassata-78ae72/deploys/6a8e32b487b9c8000855c654

Filter pushdown into a CTE rewrites the predicate once for the CTE's own
Select, then clones it onto sibling references to the same physical table so
nested subqueries and set-op arms scanning that table get the predicate too.
The skip guard only excluded the primary reference itself, so a self-join --
where a second alias of the same table sits in the same Select -- received a
cloned predicate on the wrong side of the join.

Skip every reference in the primary Select instead. The primary rewrite
resolves the filtered column through the Select's projection map, so it
already constrains the side the column projects from; the other side has to
stay free. Retargeting keeps reaching other scopes, which is what it was for.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant