Repository navigation
fix(gfql): WITH->MATCH carry restricts every route (#1712 residual); alias-shadowed property reads (#1911 defect-4) - #1950
Merged
Merged
Conversation
…ias-shadowed property reads (#1911 defect-4) Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AjbKuKheqDu78oapRT5AYm
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AjbKuKheqDu78oapRT5AYm
… per hygiene guards Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AjbKuKheqDu78oapRT5AYm
…ead _y coalesce arm untouched Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AjbKuKheqDu78oapRT5AYm
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AjbKuKheqDu78oapRT5AYm
…nged-line coverage) Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AjbKuKheqDu78oapRT5AYm
…L keeps overwrite parity) Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AjbKuKheqDu78oapRT5AYm
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AjbKuKheqDu78oapRT5AYm
…ing base frames The dotted self-name flipped the bindings-alias-prefix heuristic (NA-ing sibling property reads) and an intermediate dispatch base frame's own marker could be misread as user data (comma-pattern r.weight -> NA). Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AjbKuKheqDu78oapRT5AYm
…th serves it) Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AjbKuKheqDu78oapRT5AYm
Same version-skew class as the #1948 pin fix: three alias-scoping pins compared nan == None and failed only on the py3.13 lane. Normalizing once in _rows covers every record assertion in the file. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AjbKuKheqDu78oapRT5AYm
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.
Two verified reentry/carry-family defects, fixed against master
8f4041336with red-at-master pins, anti-vacuity counts, and a killed-mutant check per fix. Partial-scope residuals are pinned and called out on the issues; #1911 and #1712 stay open (refs #1712, refs #1911 — no auto-close).1. #1712 residual — WITH→MATCH re-entry seeds ignored by three execution routes
MATCH (p …) WITH p[, p.x AS t] MATCH (p)-…must restrict the trailing MATCH to the carriedprows. The bare single-pattern shape was fixed earlier; three routes still re-matched from the whole graph:RETURN t, count(p))[{t: Person, n:1}, {t: NaN, n:2}][{t: Person, n:1}]MATCH (p)-→(c), (p)-→(d)), bare AND projection carry[{pid:0,…},{pid:1,…}](also polars)[{pid: 0, pets: 1}](all three engines)MATCH (p)-→(c)-→(x) RETURN count(*))n=3(also polars)n=1Mechanics: the two seed-blind fast paths now decline when a reentry seed is present (
reentry_start_nodes) and fall back to the seeded chain path; the connected join post-filters its joined rows to the carried seed ids via a newrestrict_connected_join_rows_to_reentry_seed(typed E108 decline when the alias binding column cannot be recovered). polars' pre-existing typed NIE for scalar-carry reentry is pinned as a decline.NULL-in-the-carried-column:
WITH p, p.nickname AS twhere the carried person'snicknameis NULL came back as the sentinel string'0000-00-00'— a vacuously-true all-null temporal-constructor probe inentity_props._all_non_null_match. All-null series no longer "prove" any constructor shape; the NULL survives the carry.Remaining on #1712: polars still typed-declines scalar-carry reentry (
WITH p, p.x AS t MATCH …) — pre-existing NIE, pinned; native polars support is future work.2. #1911 defect-4 — alias shadowing a property name reads the marker, not the values
MATCH (name:P) RETURN name.nameanswered[True]×4on pandas + polars and crashed cuDF with a raw mixed-dtypeTypeError. Root cause: the alias flag is stamped as<alias> = True, overwriting the same-named user column that property reads then consume.chain.combine_stepsnow coalesces alias-marker_x/_ypairs as markers (boolean, null→False) instead of.where-merging marker booleans with user values (the cuDF crash, and the pandas empty-match column drop).rows(table=…, source=alias)route restores the user values from the base frame under the dotted self-name (name.name) — index-keyed with a key-merge fallback — keeping the boolean marker intact for every other property read; polars re-keys via id join.alias.aliasproperty columns from the restored dotted column; whole-entity flatten keeps its documented behavior (shadowed column omitted).MATCH (a)-[s:K]->(b)with source bound tos): previously an incidental GFQLSchemaError, and the marker-aware coalesce would have made it silently empty. Scoped to Cypher chains — raw GFQL chains keep their documented overwrite parity (test_fast_path_alias_shadowing_column_matches_full_pathunchanged).RETURN rwith a user column literally named__gfql_edge_ident__keeps omitting dunder-named user columns from the flattened entity (generic internal-name policy) while explicitr.__gfql_edge_ident__projection returns the user's values — no crash, no misattribution.Remaining on #1911: (a) polars edge alias colliding with the very column its own type filter reads (
MATCH (a)-[type:K]->(b) RETURN type.type) stays a typedGFQLSchemaError(honest decline; pandas/cuDF answerK,K); (b) polars multi-hop relationship-alias row over-multiplication (independent of the alias name) — both pinned as residuals; (c)MATCH (id:P) RETURN id.idremains the pre-existing typed decline by design.Verification
8f4041336: 35 failing cells acrosstest_reentry_carry_seed_restriction.py(new) andtest_alias_scoping_semantics.py(extended); all green at head; anti-vacuity via distinct multi-row oracles (a marker leak, an unrestricted count, or an empty frame cannot pass).graphistry/tests/computefailure SET identical to the master baseline; changed-line coverage clean locally (no cuDF-only changed lines); new polars-mentioning test file registered inbin/test-polars.sh(lane-completeness gate green).🤖 Generated with Claude Code
https://claude.ai/code/session_01AjbKuKheqDu78oapRT5AYm