Skip to content

fix(plugin): scope diagnostics to the first branch of a set operation - #331

Merged
tiagolauer merged 1 commit into
masterfrom
fix/294-plugin-union-scope
Aug 2, 2026
Merged

fix(plugin): scope diagnostics to the first branch of a set operation#331
tiagolauer merged 1 commit into
masterfrom
fix/294-plugin-union-scope

Conversation

@tiagolauer

Copy link
Copy Markdown
Owner

Fixes #294.

The bug

select id from users union select id from posts
       ^^ ambiguous column: id

Since UNION branches must be column-compatible, sharing column names is the normal case — which makes this a squiggle on nearly every UNION. The shape type-locked in tests/union.test-d.ts reproduces it identically, and the core types the query cleanly (first-branch shape, per the README).

The fix

findSources regex-scans every from/join in the whole statement into one scope, and the select-list check counts the first SELECT's columns against that pooled scope, reporting anything found twice as ambiguous.

The issue offers per-branch scopes or skipping UNION statements entirely. This does the narrower thing that keeps diagnostics working: stop at the first top-level set operator. The first branch is exactly the branch the core takes the row shape from, so what is diagnosed matches what is typed, and later branches fall under the plugin's stated "not reported on, instead of reported wrongly" policy.

Truncating rather than rescoping matters for correctness of the spans: every offset before the cut is unchanged, so no position arithmetic in this file had to move.

The scan is paren-depth aware, so a union inside a subquery does not cut the statement short.

Verification

ts-plugin/tests/diagnostics.test.ts, five new cases (two red on master — PASS (43) FAIL (2) with the src change stashed):

  • select id from users union select id from posts reports nothing
  • same for union all, intersect, except
  • a typo in the first branch is still reported (unknown column: nope)
  • a genuine ambiguity inside the first branch is still reported (users join posts, then a union)
  • a union inside a subquery does not truncate the statement (the outer typo is still found)

Full plugin suite passes; tsc --noEmit -p ts-plugin/tsconfig.json clean.

    select id from users union select id from posts
           ^^ ambiguous column: id

findSources regex-scans every from/join in the whole statement into one
scope, and the select-list check then counts the first SELECT's columns
against that pooled list. UNION branches have to be column-compatible, so
sharing a name is the normal case - this put a squiggle on nearly every
UNION, including the shape type-locked in tests/union.test-d.ts, which the
core types cleanly.

Diagnostics now stop at the first top-level set operator. That matches what
the core does (the row shape comes from the first branch) and the plugin's
own policy: later branches are not reported on, instead of being reported
wrongly. Truncating rather than rescoping keeps every offset before the cut
aligned with the source, so no span arithmetic changes.

The scan is paren-depth aware, so a union inside a subquery does not cut the
statement short.

Fixes #294

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tiagolauer
tiagolauer force-pushed the fix/294-plugin-union-scope branch from caa18e0 to a2472d2 Compare August 2, 2026 13:03
@tiagolauer
tiagolauer merged commit be16def into master Aug 2, 2026
12 checks passed
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.

ts-plugin flags UNION branches as ambiguous column

1 participant