Repository navigation
Walk every child field of expressions when building subquery scopes - #11
Merged
Merged
Conversation
WalkInScopeIter::get_children hand-listed the child fields of most node types and left some out, so a query inside them got no subquery scope. An aggregate's FILTER, ORDER BY and LIMIT, a window frame bound, a CAST FORMAT or DEFAULT expression and IN UNNEST(...) were all skipped, and every non-typed aggregate parses to AggregateFunction. Only the arms that enforce scope boundaries stay hand-written: Select (FROM and JOIN items are walked as before, CTEs are not), Table, Subquery, Exists, and In, whose query operand still gets its own scope. Every other node takes its children from the canonical AST traversal, so new fields are covered automatically. Stop rules are unchanged, and the existing pointer dedup keeps each query to a single scope. walk_in_scope and find_all_in_scope now also yield the nodes in those previously skipped positions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fa6xBWiFS7JFH5kt1epZ7o
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.
WalkInScopeIter::get_childrenhand-lists the child fields of most node types and leaves some out. A query in one of those fields gets no subquery scope, so its tables and columns are invisible to everything built on the scope tree:AggregateFunctionwalks onlyargs. It skipsfilter,order_byandlimit, and every non-typed aggregate parses to this node.WindowFunctionskips theover.framebounds and thekeepclause.Castskipsformatanddefault.Inskipsunnest.What changes
Select: FROM and JOIN items are walked as before, and CTEs are not.Table,SubqueryandExists: unchanged.In: itsqueryoperand still gets its own scope through the existingInarm, so the walk leaves it out.Expression::children()), so a field added to the AST later is covered automatically.collect_subqueries_in_expr, so each query still gets exactly one scope.walk_in_scopeandfind_all_in_scopenow also yield nodes in the previously skipped positions. The CHANGELOG notes this.Select's own hand-listed fields (prewhere,distinct_on,windowsand others). Subqueries there already got scopes throughcollect_subqueries. Widening whatwalk_in_scopeyields for aSelectwould change what other callers see, so that's left for a separate change.Tests
test_subquery_in_expression_field_is_one_subquery_scopechecks that each position below registers exactly one subquery scope with sourcet, and thattdoesn't leak into the outer scope:FILTER, both a scalar subquery and a bareARRAY(SELECT …);ORDER BY;CAST … FORMAT;CAST … DEFAULT … ON CONVERSION ERROR;IN UNNEST(ARRAY(SELECT …)).No existing expectation changed.
Local checks pass:
cargo fmt --all -- --check,make check-consistency, clippy-D warningson the ffi and wasm crates, andmake test-rust-verify-core.🤖 Generated with Claude Code
Generated by Claude Code