fix(parse): let a shadowing name replace the table it hides - #316
Merged
Conversation
tiagolauer
force-pushed
the
fix/285-286-shadowing
branch
from
August 1, 2026 15:17
c1f9b3c to
0aa076d
Compare
Object intersection is additive, so `DB['users'] & { id: number }` still
exposes `name`. Two places relied on it where SQL says the name is hidden:
- a CTE was omitted from the schema only for the outer query, so a later CTE
body still saw the real table's other columns (#285)
- a derived table whose alias reuses a real table name was intersected with
that table instead of hiding it (#286)
Both let strict mode accept a query the database rejects, and type a column
the query cannot produce - `select name from (select id from users) users`
came back as `{ name: string }[]`.
ShadowedBy pairs the existing OmitShadowedTables with the intersection, and
both sites use it. It is gated on the overlay being non-empty: the omit is a
mapped type over every table in the schema, and running it for the empty
overlay a plain query carries measured 10% of the whole type budget. With
the gate the budget lands slightly under master's, since the intersection it
replaces used to run on every query.
Under VERSIONING.md this is a minor: strict mode reports a mistake it
previously let through.
Fixes #285
Fixes #286
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
tiagolauer
force-pushed
the
fix/285-286-shadowing
branch
from
August 2, 2026 13:05
0aa076d to
e1fc1d3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #285. Fixes #286.
Two issues, one root cause and one helper, which is why they are together here rather than in two PRs that would each need half of it.
The bug
Object intersection is additive:
DB['users'] & { id: number }still exposesname. Two places relied on it where SQL says the name is hidden.A CTE was omitted from the schema only for the outer query, so a later CTE body still saw the real table:
And a derived table whose alias reuses a real table name was intersected with it:
Both cases have strict mode accepting a query the database rejects, and typing a column the query cannot produce. The comment at
ResolveCteContextalready described the first gap.The fix
ShadowedBypairs the existingOmitShadowedTableswith the intersection, and both sites use it.It is gated on the overlay being non-empty. That matters: the omit is a mapped type over every table in the schema, and running it for the empty overlay a plain query carries measured +18,744 instantiations, 10% of the whole budget and blew the ceiling. With the gate the budget lands at 192,086, slightly under master's 192,486, because the intersection it replaces used to run on every query.
Versioning
Minor: strict mode reports a mistake it previously let through.
Verification
tests/shadowing.test-d.ts, two cases red on master (one per issue), seven controls green throughout:tsc --noEmitclean, 192 unit tests pass.Found during an audit pass; fix and tests written with Claude Code.