feat(gfql): polars-native connected OPTIONAL MATCH (fixes pandas-ism crash + unseeded-arm dispatch + polars join twin)#1736
Conversation
|
Extended beyond the dropna fix — connected OPTIONAL MATCH is now polars-NATIVE end-to-end, not just crash-free:
Probe-verified on dgx: IS7-shaped |
|
Third commit: full LDBC IS7 now runs natively on polars, oracle-exact — the last blocker was the simple-CASE marker |
|
Fourth commit — the noted perf follow-up, measured: polars OPTIONAL MATCH arm pruning via first-alias id-membership injection. The polars arm previously ran unseeded (correct but computed the full pattern before the outer join). The same restriction |
31b07ba to
13d2442
Compare
da41fb1 to
5e6d307
Compare
8df8249 to
11d0bab
Compare
Review of PR #1736 asked for amplification of the 3 IS7-shaped regression tests. Add a 14-test oracle-gated parity matrix for the polars-native connected OPTIONAL MATCH lowering: every behavioral test diffs engine='polars' against the engine='pandas' oracle (normalized sorted row sets) plus hand-derived expected rows on deliberately asymmetric fixtures (unique score/weight per node/edge so mis-joins produce wrong values). Strict-parity (shape runs natively today; regression to NIE or wrong rows fails): partial matched/unmatched seeds, zero-match arm via CASE null flag, arm WHERE keeping rows, duplicate seed ids, empty seed set, arm fan-out multiplicity, null-carrying arm value column, string ids, pruning fallback (arm first op id-constrained), pruning engaged (120-person arm space >> 2 seeds, decoy rows must not leak). Parity-or-honest-NIE (shape declines today by the parity-or-error contract; silent wrong results or pandas-ism crash fails): zero-match arm + property projection (NIE 'select'), two OPTIONAL arms (NIE 'rows'), arm WHERE filtering all rows, float ids/endpoints (dtype-divergent join key). No real polars/pandas divergence found (0 xfails). 17/17 in 4.3s, clean under -W error::FutureWarning; ruff/mypy clean. Round-001 amplification artifacts under plans/gfql-optional-match-polars-amplification/ (local; plans/ is gitignored by repo policy). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
5e6d307 to
e513b8c
Compare
…crash -> works/honest-NIE) _optional_arm_start_nodes applied pandas-only frame ops to the joined binding rows, crashing IS7-shaped MATCH ... OPTIONAL MATCH queries on engine='polars' with AttributeError before the row pipeline could run (or honestly decline). Branch on frame type: polars uses drop_nulls/unique/rename + filter(is_in); pandas/cuDF path unchanged. Validated on dgx: repro fixed, 167 cutover + polars-conformance tests pass, 2 new regression tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
…atch + polars join twin) The optional-arm dispatch passed start_nodes (a pruning hint) which the polars bindings-row path declines by contract (bounded-reentry, pandas-only), forcing an NIE on queries polars can run; and the arm join/alias-synthesis block was pandas-only. Skip seeding on polars engines (semantics preserved by the left-outer join on shared aliases) and add a polars twin for the join block. IS7-shaped MATCH...OPTIONAL MATCH now runs natively on polars, oracle-exact. Validated on dgx: 184 tests pass (cutover/conformance/planner + 3 new). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
… WHEN null -> is_null) The Cypher simple-CASE marker __cypher_case_eq__(x, null) declined on polars, NIE-ing any query with a CASE x WHEN null projection (LDBC IS7's knows-flag). Lower the null-literal forms as the other side's null mask, exactly matching the pandas evaluator; the general form (pandas bool/numeric cross-dtype rules) still declines honestly. Full IS7 now runs natively on polars, oracle-exact (discriminating true/false flag test). Validated dgx: 184 + 2 CASE tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
…ship (9.2x on LDBC IS7) The polars arm ran unseeded (start_nodes declines by contract on the polars bindings-row path), computing the full pattern before the outer join. Express the same pruning as an id-membership filter injected into the arm's first (shared) node op — only when that op has no query and no existing id constraint; falls back to unseeded otherwise. Harness-measured: IS7 message-replies cypher on polars 710.8 -> 77.2 ms. 184 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
Review of PR #1736 asked for amplification of the 3 IS7-shaped regression tests. Add a 14-test oracle-gated parity matrix for the polars-native connected OPTIONAL MATCH lowering: every behavioral test diffs engine='polars' against the engine='pandas' oracle (normalized sorted row sets) plus hand-derived expected rows on deliberately asymmetric fixtures (unique score/weight per node/edge so mis-joins produce wrong values). Strict-parity (shape runs natively today; regression to NIE or wrong rows fails): partial matched/unmatched seeds, zero-match arm via CASE null flag, arm WHERE keeping rows, duplicate seed ids, empty seed set, arm fan-out multiplicity, null-carrying arm value column, string ids, pruning fallback (arm first op id-constrained), pruning engaged (120-person arm space >> 2 seeds, decoy rows must not leak). Parity-or-honest-NIE (shape declines today by the parity-or-error contract; silent wrong results or pandas-ism crash fails): zero-match arm + property projection (NIE 'select'), two OPTIONAL arms (NIE 'rows'), arm WHERE filtering all rows, float ids/endpoints (dtype-divergent join key). No real polars/pandas divergence found (0 xfails). 17/17 in 4.3s, clean under -W error::FutureWarning; ruff/mypy clean. Round-001 amplification artifacts under plans/gfql-optional-match-polars-amplification/ (local; plans/ is gitignored by repo policy). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
…ed-line gate) The PR's gfql_unified.py polars branches were exercised only by its own test file, which no coverage lane ran (changed-line gate saw 28.75%). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
e513b8c to
2da6ba6
Compare
What
Stack PR #3 (base: #1734
feat/gfql-typed-edge-index-coverage-> #1735 -> master). Fixes the first of the two polars blockers found by the 2026-07-19 official-Cypher LDBC baseline (plans/gfql-benchmark-numbers/cypherbase-sf01/):MATCH ... OPTIONAL MATCH ...(LDBC IS7 / message-replies shape) onengine='polars'crashed withAttributeError: 'DataFrame' object has no attribute 'dropna'—_optional_arm_start_nodesingfql_unified.pyran pandas-only frame ops (.dropna()/.drop_duplicates()/.rename(columns=)/boolean-mask indexing) on the joined binding rows, which are polars frames on the polars engine.Fix
Branch on frame type in the seed extraction: polars uses
drop_nulls().unique().rename({...})+filter(col.is_in(...)); the pandas/cuDF path is unchanged. After this the polars row pipeline can still honestly decline the full IS7 query (parity-or-errorrowsNIE — the second blocker, next stack PR), but never crashes with a pandas-ism.Validation (dgx, 26.02-gfql-polars container)
gfql_unified.py:380).test_runtime_physical_cutover.py+test_engine_polars_cypher_conformance.py: 167 passed.test_optional_match_polars_frames.py: pandas oracle (row values + knows-flag) + polars no-pandas-ism contract. 2 passed.Why it matters
LDBC cypher-surface coverage on polars is 6/20 with 5 more queries blocked only by the polars
rowsNIE; this crash was the one dishonest failure (a bug, not a decline). Fixing it is a prerequisite for therowsnative-lowering PR that unlocks the polars Cypher lane.🤖 Generated with Claude Code
https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL