Skip to content

fix(from): model JOIN ... USING as a merged column - #347

Merged
tiagolauer merged 1 commit into
masterfrom
fix/284-join-using-merged
Aug 2, 2026
Merged

fix(from): model JOIN ... USING as a merged column#347
tiagolauer merged 1 commit into
masterfrom
fix/284-join-using-merged

Conversation

@tiagolauer

Copy link
Copy Markdown
Owner

Fixes #284.

The bug

// DB: a: {id, x}, b: {id, y}
StrictQuery<DB, 'select id from a join b using (id)'>
// QueryTypeError<'ambiguous column: id'>[]

Expected { id: number }[]. USING merges the join column in every dialect that has it; referencing it bare is the whole point of the syntax.

The fix

USING was not modeled at all:

  • AliasOf only special-cased on and as, so the joined table's alias was set to the literal word using — which also broke select b.y from a join b using (id).
  • CountBareMatches counted the column once per source, with no merge exemption.

A Source now carries the columns its join merged (mergedColumns, alongside the existing optional derivedQuery), and a source's copy of one of those columns does not count towards ambiguity. The type still resolves from the first matching source, so nothing about the value changes.

using(id) glued to its paren is deliberately left alone — only the spaced form is read — so that case keeps the report it already gave rather than silently merging.

Verification

tests/join-using-merged.test-d.ts, nine cases. Four red on master:

tests/join-using-merged.test-d.ts(18,3): error TS2344: Type 'false' does not satisfy the constraint 'true'.
tests/join-using-merged.test-d.ts(22,3): ... (29,3), (33,3)
  • the merged column alone, beside other columns, across two USING joins, and through a LEFT JOIN
  • a qualified reference through the joined table (b.y), which the using alias used to break

Controls, all still reporting: an ON join is still ambiguous column: id, a column outside the USING list is still ambiguous, an unknown column is still unknown, and loose mode is unchanged.

tsc --noEmit clean, 192 core + 155 plugin runtime tests pass, budget 194,721 (+2,235).

    StrictQuery<DB, 'select id from a join b using (id)'>
    // was QueryTypeError<'ambiguous column: id'>[]

USING was not modeled at all. AliasOf special-cased only `on` and `as`, so
the joined table's alias was literally set to the word `using`, and
CountBareMatches counted the column once per source with no merge exemption.
But USING produces one column, not two, in every dialect that has it, and
referencing it bare is the entire point of the syntax.

A source now carries the columns its join merged, and its copy of one of
them does not count towards ambiguity. Two things stay exactly as they were:
a column outside the USING list is still ambiguous across the same join, and
an ON join reports ambiguity as before.

`using(id)` glued to its paren is left as it was - the spaced form is what
this reads - so that case errs on the side of the report it already gave
rather than a silent merge.

Fixes #284

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tiagolauer
tiagolauer force-pushed the fix/284-join-using-merged branch from 493c138 to 2703c19 Compare August 2, 2026 13:04
@tiagolauer
tiagolauer merged commit aeac702 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.

JOIN ... USING merged column reported as ambiguous in strict mode

1 participant