Skip to content

docs(pre-asap): capture why resolution uses positional ColumnId, not names - #241

Merged
zzylol merged 1 commit into
mainfrom
docs/column-id-vs-name-rationale
Aug 22, 2026
Merged

zzylol merged 1 commit into
mainfrom
docs/column-id-vs-name-rationale

Conversation

@zzylol

@zzylol zzylol commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Settles the design question raised in #216 ("column index vs column name as ref") by moving its already-conclusive rationale from the issue thread into resolve.rs's module doc, next to the code it explains.

The question: should QueryExpr keep positional ColumnId refs (resolved once by Binder), or could it carry name-based ColumnRefs all the way through, the way DataFusion's own logical plan and Calcite do?

The answer (already worked out in #216, not new analysis): resolving once is the better trade for this codebase's shape — one front-end-facing tree feeding several independent downstream passes (canonicalize, cost model, dag_export, schema/type inference, summary binding). Three reasons, now captured in the doc:

  1. Names collide across joins — not hypothetical, backed by the real join_predicate_disambiguates_shared_column_name test.
  2. A name's meaning shifts as you go up the tree (Project renames, Aggregate collapses/synthesizes columns, Join concatenates schemas).
  3. Resolving once centralizes scoping logic in one place instead of ~6 passes each needing their own qualifier-aware, collision-aware name resolver.

No code change — the conclusion is to keep the current design as-is. This is purely documentation so a future "why not just use names" question finds its answer next to resolve_root instead of requiring someone to dig up issue #216.

Test plan

  • cargo build --workspace --all-targets
  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test -p asap-types --lib

Closes #216

🤖 Generated with Claude Code

…names

Settles the design question raised in #216 ("column index vs column
name as ref"): resolving every ColumnRef to a positional ColumnId once
(rather than carrying qualified names all the way through, the way
DataFusion's and Calcite's logical plans do) is the better trade for
this codebase's shape -- name collisions across joins are real (see
join_predicate_disambiguates_shared_column_name), a name's meaning
shifts as you go up the tree, and resolving once centralizes scoping
logic in one place instead of every downstream pass reimplementing
its own qualifier-aware, collision-aware name resolver.

No code change -- the conclusion is to keep the current design. This
just moves the rationale from the issue thread into the module doc so
a future "why not just use names" question finds its answer next to
the code.

Closes #216

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@zzylol
zzylol merged commit 86670ef into main Aug 22, 2026
3 checks passed
@zzylol
zzylol deleted the docs/column-id-vs-name-rationale branch August 22, 2026 22:01
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.

column index vs column name as ref

1 participant