fix(gfql): preserve alias property columns through non-final WITH aggregate (#1054)#1057
Merged
fix(gfql): preserve alias property columns through non-final WITH aggregate (#1054)#1057
Conversation
…regate on bindings-row tables (#1054) Three root causes fixed in `_lower_match_alias_aggregate_stage`: 1. Group key used bare `"id"` instead of `"tag.id"` on the bindings-row path (each row had a unique entity blob, making grouping per-row instead of per-alias) 2. Entity blob (`__node_entity__`) was added to `key_names`, serializing all columns and making every row unique; skip entity blob on bindings-row path 3. `projection_fn(visible_projection_items)` dropped `tag.*` property columns after `group_by`; replaced with `group_by(key_prefixes=[f"{alias}."])` + `drop_cols(hidden_keys)` to keep alias-prefixed columns for the next stage New runtime ops: `drop_cols` (ast/pipeline/validation) and `key_prefixes` parameter on `group_by` to dynamically add alias-prefixed columns as group keys. Also fixed a follow-on issue in `_lower_row_column_stage`: alias-prefixed short- circuit expressions (e.g., `"tag.name"`) were being recorded in `next_projected_columns`, causing subsequent RETURN stages to re-inline them via `_rewrite_expr_to_projected_sources` and fail when `_row_expr_arg` tried to parse `tag` as a Cypher identifier. Adds 3 amplification tests: multiple agg functions in non-final WITH, non-final agg + scalar stage accessing alias property, ORDER BY on alias.property after agg. Full lowering suite: 686 passed, 56 skipped. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…d non-final WITH aggregate (#1054) Unit tests (test_row_pipeline_ops.py): - TestDropCols: basic drop, multiple cols, ignore-missing, empty list, dotted column names - TestGroupByKeyPrefixes: prefix expansion, multiple prefixes, key_prefixes=None unchanged - TestRowPipelineSafelist: drop_cols and key_prefixes validation (valid params, type errors) Cypher integration tests (test_lowering.py): - non_final_agg_two_aliases_survive: tag.id accessible alongside tag.name after non-final agg - non_final_agg_where_on_alias_property: alias.property accessible in RETURN after non-final agg 845 passed, 58 skipped. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This was referenced Apr 5, 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.
Fixes #1054.
Problem
When a multi-alias bindings-row query chains a non-final
WITHaggregate stage (e.g.WITH tag, sum(cd) AS total) before aRETURN tag.name, thetag.*property columns are dropped by the post-aggregate projection, makingtag.nameinaccessible in the subsequent stage.Fix
In
_lower_match_alias_aggregate_stage, on the bindings-row path (scope.allowed_match_aliasesnon-empty), preservealias.*property columns through the aggregate stage so the next stage can resolvealias.propertyreferences.Status
🚧 WIP — investigation and implementation in progress.
Test
test_string_cypher_multi_alias_with_four_stage_chain(currently xfail → will pass)🤖 Generated with Claude Code