Skip to content

perf: borrow source column sets in qualification; linear scopes for commented set operations - #33

Merged
kvlonge merged 2 commits into
mainfrom
perf/borrow-column-sets
Oct 3, 2026
Merged

kvlonge merged 2 commits into
mainfrom
perf/borrow-column-sets

Conversation

@kvlonge

@kvlonge kvlonge commented Oct 3, 2026

Copy link
Copy Markdown

Why

  • Column qualification cloned each source's column set for every column reference and built the full scope tree under each SELECT, so wide joins and wide SELECT * subqueries scaled badly (16 wide joins: 93 ms).
  • The linear set-operation scope build missed operands the parser wraps when a line comment precedes the set operator, so commented UNION ALL chains stayed quadratic.

Changes

  • Qualification resolves each source's columns once per resolver and borrows them, builds normalised names lazily, caches outer-scope lookups, builds only the current SELECT's sources, and moves clauses and outputs instead of cloning.
  • Set-operation branch scopes look through the comment wrapper and keep it around the shallow copy.

Verification

  • Microbenchmarks (release): 16 wide joins 93 → 10.2 ms; 400-column star over 4 levels 51 → 34 ms; commented 240-branch chain scope build 54 → 1.6 ms.
  • New allocation-scaling and commented scaling tests fail on the old code.
  • Differential: 3,922 queries × 10 dialects (~493k results, strict comparator); no key stable on base differs on head.
  • Crate suite passes apart from failures that also occur on main.

A line or block comment before UNION, INTERSECT or EXCEPT makes the parser
wrap the preceding operand in a comment annotation. The shallow branch copy
from the linear set-operation scope build did not look through that wrapper,
so every level of a commented chain copied all earlier branches again and
scope building, validation and analysis grew quadratically.

Branch scopes now keep the comment wrapper around the shallow copy, and a
wrapped set-operation operand gets the same NULL placeholder as a bare one.
The scope tree shape and all validation, analysis and lineage results are
unchanged.
Schema-aware column qualification copied work proportional to the whole
query or relation for every column reference and nesting level:

- Each reference copied its source's complete column list, ambiguity checks
  copied and normalized the column lists of every source, and table lookup
  copied the unambiguous-column map. The resolver now normalizes each
  source's columns once and answers these lookups from borrowed sets, and
  caches correlated outer-scope lookups.
- Each SELECT built and copied the complete scope tree of its query, and
  copied that scope again for nested queries. Qualification now builds only
  the selected sources of the SELECT and passes enclosing scopes by
  reference.
- Clauses, nested queries, outputs and GROUP BY projections were copied
  before rewriting; they are now moved, and star expansion returns early
  when no star is projected.

Wide relations and SELECT * over derived tables now qualify in time linear
in their width, and nested derived tables no longer rebuild every nested
scope at each level. Qualified output and all validation, analysis and
lineage results are unchanged.
@kvlonge
kvlonge merged commit 9ff0af2 into main Oct 3, 2026
24 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.

1 participant