feat(unwind): add UNWIND clause (v0.13) - #18
Open
protosphinx wants to merge 2 commits into
Open
protosphinx wants to merge 2 commits into
protosphinx wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5b677eab14
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Member
Author
|
auto-deferred for human review: LOC delta 298 (295 added + 3 removed) exceeds the 250-line self-merge gate. All CI checks are green; the implementation looks correct. A human reviewer should sanity-check the UNWIND planner/optimizer arms and then merge. Generated by Claude Code |
protosphinx
force-pushed
the
bot/unwind-clause
branch
from
July 3, 2026 16:07
8b24341 to
351b1e1
Compare
protosphinx
force-pushed
the
bot/unwind-clause
branch
from
August 7, 2026 16:09
351b1e1 to
739c146
Compare
Implements UNWIND as a lateral unnest operator: each input row is cross-applied against the list expression, producing one output row per list element bound to the named variable. Covers grammar (kw_unwind, case-insensitive), AST (Clause::Unwind), plan lowering (Plan::Unwind), cost estimation (literal-length or 10x default), projection pruning, predicate-pushdown optimizer, and semantic analysis. 14 new tests.
The two-pass approach (collect all bindings, then check all clauses) pre-collected the UNWIND alias into the binding set before checking the list expression. This caused UNWIND [x] AS x to be silently accepted when x had no prior binding, because x was already in scope at expression-check time. Replace collect_bindings + global-bindings-pass with a single ordered pass: check each clause against the scope accumulated so far, then call extend_scope to add the bindings that clause produces. The UNWIND alias is now added to scope only after its list expression is validated. Three new tests in tests/sema.rs cover the self-shadow error case, a valid MATCH-then-UNWIND-same-name case, and a chained UNWIND case.
protosphinx
force-pushed
the
bot/unwind-clause
branch
from
August 26, 2026 16:06
739c146 to
60d2703
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.
Summary
UNWIND expr AS varclause to the grammar, AST, planner, cost model, projection pruner, predicate-pushdown optimizer, and semantic analyzer.UNWINDturns a list expression into one output row per element; the element is bound tovar. Case-insensitive keyword, blocked from use as an identifier.sema.rscollects the UNWIND binding and checks the list expression against current scope.tests/unwind.rscovering parse, plan, cost, and pruning.Files changed
src/cypher.pestkw_unwind,unwind_clause, added toreserved_kwandclausesrc/ast.rsClause::Unwind { expr, var }src/parser.rswalk_unwind,kw_unwindinis_kwsrc/plan.rsPlan::Unwind, lowering arm, Display armsrc/cost.rsestimatearm forPlan::Unwindsrc/prune.rswalk_outputandrequired_input_columnsarmssrc/optimize.rsdescendandwalk_boundarmssrc/sema.rscollect_bindingsandcheck_clausearmstests/unwind.rsTest plan
cargo test-- all 200 tests pass (186 existing + 14 new)cargo clippy --all-targets -- -D warnings-- cleancargo fmt --check-- cleansrc/lib.rs.github/workflowschanges🤖 Daily bot
Generated by Claude Code