Repository navigation
feat(cypher): implement shortestPath execution with igraph/cugraph backends #1010
Copy link
Copy link
Closed
Closed
Copy link
Description
Summary
This is the active direct Cypher shortestPath(...) execution lane.
Active implementation PR:
Current branch status on April 3, 2026
#1042 currently adds the narrow scalar shortest-path contract needed by the benchmark lane:
length(path)path IS NULLCASE path IS NULL WHEN true THEN -1 ELSE length(path) END- exact official comma-seeded
interactive-complex-13shape - bounded, reverse-direction, disconnected-null, endpoint/id-projection, staged
WITH, zero-hop, cyclic/bounded duplicate-route, and multi-row shortestPath amplification around that scalar slice
Still intentionally unsupported on the branch:
allShortestPaths(...)RETURN pathrelationships(path)and other generic path-carrier forms
Focused validation so far
Local focused checks:
graphistry/tests/compute/gfql/cypher/test_parser.py -k shortest_path- result:
1 passed, 95 deselected graphistry/tests/compute/gfql/cypher/test_lowering.py -k "shortest_path or allShortestPaths"- result:
40 passed, 660 deselected
Focused dgx-spark host-CPU checks:
- parser:
1 passed, 95 deselected - lowering/execution:
40 passed, 660 deselected
What this branch found while implementing the lane
Two adjacent runtime fixes were needed in the row-binding path:
- fixed-point edges must count as multihop in
graphistry/compute/gfql/same_path/edge_semantics.py - multihop row bindings must preserve hop-labeled node frames into the next node filter in
graphistry/compute/gfql/row/pipeline.py
Seven adjacent scalar/runtime hardening fixes were then needed during amplification:
- shortest-path scalar rewrites now bind onto the endpoint alias hop property, and disconnected empty-row synthesis now carries alias-prefixed seed values so endpoint/id projections survive direct
RETURNnull-extension - disconnected shortest-path rows now also null-extend through staged scalar
WITH ... RETURN ...chains in the supported local subset - unbounded shortestPath self-matches now produce valid zero-hop scalar results instead of
null/-1 - cyclic shortestPath scalar execution now dedupes equal-length revisits instead of erroring or diverging on multiroute graphs
- bounded cyclic and self-loop shortestPath scalar outputs now dedupe identical shortest rows instead of returning duplicates
- multi-row shortestPath pair queries now preserve row-specific endpoint hop values instead of collapsing to
0/1 - multi-row disconnected shortestPath now null-extends per seed pair for direct, staged, bounded, and reverse-direction scalar forms
Recent test-only amplification on top locks:
- multi-row
path IS NULLordering across direct, staged, bounded, and reverse-direction shortestPath queries
So this issue is well past parser recognition: the active branch is executing the shortest-path scalar contract end-to-end in focused tests and has gone through several real amplification passes that kept uncovering product bugs.
Benchmark target
Official query file:
/home/lmeyerov/Work/pyg-bench/third_party/ldbc_snb_interactive_v1_impls/cypher/queries/interactive-complex-13.cypher
Official query text:
MATCH
(person1:Person {id: $person1Id}),
(person2:Person {id: $person2Id}),
path = shortestPath((person1)-[:KNOWS*]-(person2))
RETURN
CASE path IS NULL
WHEN true THEN -1
ELSE length(path)
END AS shortestPathLengthReactions are currently unavailable
Activity
lmeyerov commentedon Apr 2, 2026
Benchmark rerun update from
pyg-benchon refreshed currentmaster14dafaf6b951954d8de840f9236f3e874249ebac.Official SNB lane:
interactive-complex-1/named-shortest-friends/home/lmeyerov/Work/pyg-bench/results/runs/dgx-spark-snb-interactive-ic1-origin-master-14dafaf6b9-fresh-r2uv run python scripts/run_dgx_spark_suite.py --suite snb-interactive --config configs/suites/snb-interactive-ic1-conformance-sf1.yaml --output-dir results/runs/dgx-spark-snb-interactive-ic1-origin-master-14dafaf6b9-fresh-r2 --graphistry-repo-path /tmp/pygraphistry-origin-master-14dafaf6b --host-uvMeasured outcome on
dgx-spark:GFQL:partialvia the benchmark-side bounded-shortest-path plus profile-history workaroundCypher:primitive_gapunder#1010[unsupported-cypher-query] shortestPath() is not yet supported in the local Cypher compiler | field: match | value: 'shortestPath' | suggestion: Use a subset currently supported by the GFQL Cypher compiler.Timing from the same run:
setup_latency_ms = 301.229query_latency_ms = 236.499csv_load = 70.363 msderivation = 150.102 msgraph_bind = 80.764 msTwo useful benchmark-side notes:
core_fastfixture path, so it is no longer blocked by harness setup noisesf1fixture, so this is primarily a support-classification checkpoint rather than a high-cardinality comparison run