Summary (P0 correctness — silent wrong answer)
A multi-part Cypher query that filters in the first MATCH, carries a node via WITH, then re-references it in a second MATCH does not restrict the second MATCH to the filtered set — it re-matches the alias from the whole graph. The query runs without error and returns a wrong count. Affects pandas and cuDF (polars NIEs the projection separately).
Repro
import pandas as pd, graphistry
nodes = pd.DataFrame({'node_id':[0,1,2,10,20],
'node_type':['Person','Person','Person','City','Interest'],
'city':[None,None,None,'NYC',None], 'interest':[None,None,None,None,'Books']})
edges = pd.DataFrame({'src':[0,1,2,0], 'dst':[10,10,10,20],
'rel':['LIVES_IN','LIVES_IN','LIVES_IN','HAS_INTEREST']}) # only p0 has interest Books; all live in NYC
g = graphistry.nodes(nodes,'node_id').edges(edges,'src','dst')
# first MATCH alone filters correctly -> 1 ✅
g.gfql("MATCH (p {node_type:'Person'})-[{rel:'HAS_INTEREST'}]->(i {node_type:'Interest'}) WHERE i.interest='Books' RETURN count(p) AS c") # c=1
# carry via WITH into a second MATCH -> should still be 1, returns 3 ❌
g.gfql('''MATCH (p {node_type:'Person'})-[{rel:'HAS_INTEREST'}]->(i {node_type:'Interest'})
WHERE i.interest='Books'
WITH p
MATCH (p)-[{rel:'LIVES_IN'}]->(c {node_type:'City'})
RETURN count(p) AS numPersons''') # numPersons = 3 (WRONG, expected 1) on pandas AND cudf
Impact
This is the canonical shape of graph-benchmark q2/q5/q6/q7 ('users with interest X and gender Y who live in city Z'). It means those queries cannot be run as single-query GFQL Cypher today without producing wrong numbers — they must be orchestrated as multiple GFQL calls (first MATCH → extract filtered node ids → seed the second MATCH). Blocks the #1710 fair benchmark rewrite.
Expected
Either carry the filtered binding correctly (numPersons=1), or — if the bounded-reentry carry isn't supported for this shape — raise NotImplementedError (honest NIE), never a silent wrong count.
Notes
Summary (P0 correctness — silent wrong answer)
A multi-part Cypher query that filters in the first MATCH, carries a node via
WITH, then re-references it in a second MATCH does not restrict the second MATCH to the filtered set — it re-matches the alias from the whole graph. The query runs without error and returns a wrong count. Affects pandas and cuDF (polars NIEs the projection separately).Repro
Impact
This is the canonical shape of graph-benchmark q2/q5/q6/q7 ('users with interest X and gender Y who live in city Z'). It means those queries cannot be run as single-query GFQL Cypher today without producing wrong numbers — they must be orchestrated as multiple GFQL calls (first MATCH → extract filtered node ids → seed the second MATCH). Blocks the #1710 fair benchmark rewrite.
Expected
Either carry the filtered binding correctly (
numPersons=1), or — if the bounded-reentry carry isn't supported for this shape — raiseNotImplementedError(honest NIE), never a silent wrong count.Notes
WITH→second-MATCH re-entry not restricting the alias domain.