Repository navigation
feat(cypher): multi-alias scalar RETURN and edge alias properties (#981, #982) - #986
Merged
Merged
Conversation
Remove the hard rejection of multi-alias RETURN projections in _active_match_alias_for_stage() and _build_projection_plan(). Add all_source_aliases tracking to _ProjectionPlan. The bindings-table merge approach is proven but not yet wired into execution. Saving progress. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
MATCH (a)-[:R]->(b) RETURN a.id AS a_id, b.id AS b_id now works. Implementation: when multiple MATCH aliases appear in a scalar RETURN, build a bindings table by joining edges with node properties for each alias endpoint (src/dst). The joined table has columns prefixed with alias names (a.id, b.id, etc.) that the existing row pipeline can project from directly. Key changes: - lowering.py: _build_alias_endpoints() maps node aliases to src/dst edge endpoints; catch multi-alias rejection and use bindings path - pipeline.py: rows(alias_endpoints=...) builds the bindings table via vectorized merge (pandas/cudf compatible) - validation.py: allow alias_endpoints param on rows() safelist - ast.py: rows() accepts optional alias_endpoints dict - _ProjectionPlan: track all_source_aliases for multi-alias detection Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…982) Add 4 end-to-end tests for multi-alias RETURN: - basic a.id + b.id projection - multiple bindings (2 edges → 2 rows) - empty match → empty result - edge alias property access (r.creationDate) — validates #982 fix DRY: remove duplicated projection/distinct/order_by/page logic from try/except fallback path in _lower_projection_chain; both single and multi-alias now share the same downstream code. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Only allow multi-alias RETURN for scalar projections (a.id, b.name). Whole-row projections (RETURN n, x) with multiple aliases still raise the unsupported error, as the bindings table approach doesn't handle entity-valued outputs. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Only use bindings-table path for pure scalar alias.prop projections. Reject multi-alias when whole-row outputs or expression-based outputs (type(), count(), etc.) are present. Fix mypy: use Optional[GFQLValidationError] for the caught exception. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Tighten multi-alias guard: only use bindings path when at least one referenced alias is a node (not when all are edge aliases like r1, r2). Fix both compilation entry point and _lower_projection_chain to use consistent all_are_edges check. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Add 3 edge-case tests: star graph (1->N bindings), bidirectional edges (correct src/dst swap), duplicate edges (one binding per edge). GPU validation: all tests pass on both pandas and cudf (dgx-spark, graphistry/test-gpu:latest container). The bindings table merge works correctly with cudf DataFrames. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…#982) Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Document that WITH multi-alias scalar projections are not yet supported (goes through a different code path than RETURN). 12 total multi-alias tests now. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
This was referenced Mar 31, 2026
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
Support multi-alias scalar
RETURNprojections and edge alias property access in direct Cypher queries (#981, #982).Before
After
Implementation
When multiple MATCH aliases appear in a scalar RETURN, builds a bindings table by joining edges with alias-prefixed node properties via vectorized merge. Each edge row becomes one result row. Pure columnar operations — works on both pandas and cudf.
Guard rails: Only enabled for scalar
alias.propprojections from node aliases. Whole-row projections (RETURN n, x), expression-based outputs (RETURN type(r1)), and all-edge-alias patterns are correctly rejected.Changes
lowering.py_build_alias_endpoints()maps aliases to src/dst; catch multi-alias rejection → bindings path;_ProjectionPlan.all_source_aliasespipeline.pyrows(alias_endpoints=...)builds bindings table via mergevalidation.pyalias_endpointsparam onrows()safelistast.pyrows()accepts optionalalias_endpointsdicttest_lowering.pyTest coverage (11 new tests)
cypher_to_gfqlhelper worksGPU validation
All tests pass on both pandas and cudf (dgx-spark,
graphistry/test-gpu:latest).Test plan
🤖 Generated with Claude Code