Skip to content

fix: TableNode FILTERS section shows duplicate predicates when same table is referenced multiple times in one statement #44

@cooker-code

Description

@cooker-code

Bug Description

When the same table is referenced multiple times within a single SQL statement (e.g., a table appearing in two separate subqueries in the same CTE), the FILTERS section of the corresponding TableNode in the lineage graph shows every predicate twice (or N times for N references).

Root Cause

The Rust core appends each subquery occurrence's WHERE predicates to the flat node.filters array. For a table referenced twice in the same statement with identical filters, this produces 8 entries instead of 4:

"filters": [
  { "expression": "dt = '\${date}'" },
  { "expression": "device_id IS NOT NULL" },
  { "expression": "device_id <> ''" },
  { "expression": "device_id <> '00000000-0000-0000-0000-000000000000'" },
  { "expression": "dt = '\${date}'" },         // duplicate
  { "expression": "device_id IS NOT NULL" },   // duplicate
  { "expression": "device_id <> ''" },         // duplicate
  { "expression": "device_id <> '00000000-0000-0000-0000-000000000000'" }  // duplicate
]

The frontend had no deduplication before displaying node.filters, so all 8 entries were rendered.

Reproduction

SQL with the same physical table used in two subqueries within one CTE:

with new_device as (
  select a.device_id, ...
  from (
    select * from dw_dwd.dwd_eng_device_active_da  -- occurrence 1
    where dt = '${date}' and device_id is not null ...
  ) a
  left join (
    select device_id, ...
    from dw_dwd.dwd_eng_device_active_da            -- occurrence 2
    where dt = '${date}' and device_id is not null ...
  ) t1 on a.device_id = t1.device_id
)

The OccurrenceCycler correctly shows ◀ 1/2 ▶, but the FILTERS section listed 8 predicates instead of 4.

Fix (this commit)

  • Added deduplicateFilters() in graphBuilders.ts and graphBuilder.worker.ts to collapse node.filters to unique expressions (preserving insertion order) before populating TableNodeData.
  • Added per-occurrence filter storage (occurrenceFilters[][] in node metadata via mergeNodesForNavigation) for the cross-statement multi-occurrence path, so TableNode can display per-occurrence filters when cycling occurrences.
  • TableNodeData gains occurrenceFilters?: FilterPredicate[][].
  • TableNode subscribes to focusedOccurrenceIndex and picks the appropriate occurrence's filters when occurrenceFilters is populated.

Files Changed

  • packages/react/src/utils/graphBuilders.ts
  • packages/react/src/workers/graphBuilder.worker.ts
  • packages/react/src/utils/nodeOccurrences.ts
  • packages/react/src/components/TableNode.tsx
  • packages/react/src/types.ts

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions