You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Cypher engine hardcodes id as the node-identity column #1490
The GFQL Cypher lowering assumes the node-identity column is literally named id. It does not respect the node-id column bound via g.nodes(df, node_col),
and it cannot distinguish a node's identity from a Cypher property that
happens to be named id.
Surfaced while working graphistry/tck-gfql#126 (the TCK harness wanted to model
a node with an id property distinct from its synthetic identity, per the
openCypher with2-1 setup CREATE (a:End {num: 42, id: 0}), ...).
L1427 — connected-join alias identity: prop = "id" if isinstance(target, ASTNode) else ...
L6549, L6623 — aggregate / alias identity helpers: return "id" for ASTNode.
When the bound node-id column is not named id, repeated-variable patterns
(e.g. MATCH (n)-[]->(n)) fail validation:
GFQLValidationError: [unsupported-cypher-query] WHERE references missing
column 'id' on alias 'n' (node, step=2). Available columns: __node_id__, ...
Impact / two facets
Bound node-id column ignored.g.nodes(df, "__node_id__").gfql("<cypher>")
with a repeated node variable raises E108 even though the graph is valid.
Identity vs. id property conflated. Because identity is the id
column, a node that genuinely has a Cypher property named id (distinct
from identity) cannot be represented — the renderer only surfaces id as a
property via a numeric-dtype heuristic
(row/entity_props.py::_include_numeric_id_as_property), which breaks on
mixed-dtype id columns.
Suggested fix
Thread the graph's bound node-id column name through Cypher lowering instead of
the "id" string literal (and likewise for edges, which already use __gfql_edge_index_0__). Longer term, model node identity as an internal
column separate from user-visible properties so a Cypher id property is
representable.
Seven scenarios returned from direct-Cypher promotion to xfail because graph_fixture_from_create no longer exposes synthetic node identity as data column id: match7-24, return-orderby2-6, expr-graph3-5, expr-graph7-1, usecase-countingsubgraphmatches1-6, usecase-countingsubgraphmatches1-7, usecase-countingsubgraphmatches1-9.
This is the expected evidence for this pygraphistry issue: tck-gfql can now model Cypher id separately from fixture identity, and the remaining failures are direct-Cypher lowering/runtime assumptions about identity column name. No pygraphistry runtime changes were made in the tck-gfql PR.
No pygraphistry runtime changes landed in that PR; this issue remains the upstream follow-up for direct-Cypher lowering honoring the bound node-id column separately from a Cypher id property.
Issue is closed by #1504. Remaining direct-Cypher/TCK work should be recalculated from pygraphistry master plus tck-gfql main, not the pre-#1490 drift snapshot.
Activity
lmeyerov commentedon May 17, 2026
tck-gfql #126 now has an implementation PR that adopts reserved harness-side node identity and records the resulting direct-Cypher fallout:
testspassed in 5m35s)4011 passed, 724 xfailedRelevant count changes from the corrected fixture:
933 (rows 794, errors 139)->926 (rows 787, errors 139)2893 / 3627 (79.8%)->2886 / 3627 (79.6%)supported 2910, xfail 717->supported 2903, xfail 724Seven scenarios returned from direct-Cypher promotion to xfail because
graph_fixture_from_createno longer exposes synthetic node identity as data columnid:match7-24,return-orderby2-6,expr-graph3-5,expr-graph7-1,usecase-countingsubgraphmatches1-6,usecase-countingsubgraphmatches1-7,usecase-countingsubgraphmatches1-9.This is the expected evidence for this pygraphistry issue: tck-gfql can now model Cypher
idseparately from fixture identity, and the remaining failures are direct-Cypher lowering/runtime assumptions about identity column name. No pygraphistry runtime changes were made in the tck-gfql PR.lmeyerov commentedon May 17, 2026
tck-gfql #126 is now merged via PR #131:
b0e1b59673eb6b3654ed1b8e45c51d861b07b2b8testspassed in 5m32sThe merged tck-gfql baseline keeps the corrected harness fixture model and records the pygraphistry fallout here:
926 (rows 787, errors 139)2886 / 3627 (79.6%)supported 2903, xfail 724match7-24,return-orderby2-6,expr-graph3-5,expr-graph7-1,usecase-countingsubgraphmatches1-6,usecase-countingsubgraphmatches1-7,usecase-countingsubgraphmatches1-9No pygraphistry runtime changes landed in that PR; this issue remains the upstream follow-up for direct-Cypher lowering honoring the bound node-id column separately from a Cypher
idproperty.lmeyerov commentedon May 17, 2026
Closeout after conflict resolution/merge:
origin/masterand resolving theCHANGELOG.mdconflict.python3 bin/ci_cypher_surface_guard.py: passed (lowering.py9045/9045).idas the node-identity column #1490 regressions:3 passed, 1 skipped, 4 warnings.mainmoved, keeping Bug: Spigo demo in Python3 #129 promotions (match5-8,with5-2) promoted and tracking only the Cypher engine hardcodesidas the node-identity column #1490 residual drift.1 passed.2 passed.722 passed.tests: passed in 5m41s.Issue is closed by #1504. Remaining direct-Cypher/TCK work should be recalculated from pygraphistry
masterplus tck-gfqlmain, not the pre-#1490 drift snapshot.perf(gfql): projection-pushdown for binding tables — skip unused prop…
perf(gfql): projection-pushdown for binding tables — skip unused prop…
perf(gfql): projection-pushdown for binding tables — skip unused prop…
perf(gfql): projection-pushdown for binding tables — skip unused prop…
perf(gfql): projection-pushdown for binding tables — skip unused prop…
perf(gfql): projection-pushdown for binding tables — skip unused prop…
perf(gfql): projection-pushdown for binding tables — skip unused prop…
perf(gfql): projection-pushdown for binding tables — skip unused prop…