Repository navigation
match-where1-11 fails #191
Description
Bug: match-where1-11 fails — harness decomposes edge-return entities but expects the bare alias
Repo: tck-gfql (conformance harness)
Scenario: match-where1-11 — tck/features/clauses/match-where/MatchWhere1.feature
Tags: match-where, or, edge-return, cypher-string, cypher-string-pure
Severity: low (harness-side row representation; GFQL output is correct)
Summary
For a scenario that returns a whole edge (RETURN r), _rows_from_result decomposes the edge entity into r.edge_id / r.type columns, but _normalize_rows is given expected_keys=['r'] and asserts the bare alias is present → fails. Node-return scenarios pass because the harness keeps node entities whole under a single alias key. The edge-return path is not handled symmetrically.
Environment
- pygraphistry:
dev/cypher-lalr-parser-switch(also reproduces onmaster— not version-specific) - engine: pandas (and cuDF)
- cuDF 26.02.01 / numpy 2.2
Steps to reproduce
Run test_cypher_tck_scenario[match-where1-11].
Expected
The edge-return row compares against the scenario's expected r and passes, as the analogous node-return scenarios do.
Actual
tests/cypher_tck/test_tck_runner.py:_assert_expected_rows -> _normalize_rows
AssertionError: missing expected row columns: ['r']; row={'r.edge_id': 'rel_1', 'r.type': 'KNOWS'}
_rows_from_result returned [{'r.edge_id': 'rel_1', 'r.type': 'KNOWS'}, {'r.edge_id': 'rel_2', 'r.type': 'HATES'}]; expected_keys=['r'].
Root cause (harness, not GFQL)
GFQL returns the edge entity correctly and symmetrically with nodes — a single rendered r column plus projection metadata. Verified directly against pygraphistry (graph binds edge_id as the edge id, as _build_graph does):
RETURN r -> _nodes['r'] == ['[:KNOWS]', '[:HATES]']
_cypher_entity_projection_meta == {'r': {'table':'edges','alias':'r',
'id_column':'edge_id','ids':['rel_1','rel_2']}}
_rows_from_result uses that meta to decompose the edge into r.<col> keys, but keeps node entities whole under n. _normalize_rows expects the bare alias, so edge-return fails while node-return passes. The asymmetry is entirely in the harness.
GFQL-side confirmed correct: result_postprocess.py _format_node_entities / _format_edge_entities both render properties; the projection meta is built for edges identically to nodes; [:KNOWS] correctly omits edge_id because it is the edge id (topology), not a user property — same as a node id.
Not a pygraphistry / parser-switch regression
The scenario uses OR, which routes to where_rows on both base and the parser-switch branch (OR never lifts). Base-vs-branch results are byte-identical:
master: _edges.cols=['r','edge_id','type','src','dst'], _nodes['r']==['[:KNOWS]','[:HATES]']
branch: _edges.cols=['r','edge_id','type','src','dst'], _nodes['r']==['[:KNOWS]','[:HATES]'] (identical)
The pygraphistry diff touches only generic_where_clause + the WHERE lift; nothing in RETURN/edge projection. Surfaced because match-where1-11 (tagged edge-return) was newly enabled — its sibling match-where1-10 was previously added to the xfail contract.
Proposed fix
Make _rows_from_result treat edge whole-entity returns the same as nodes — emit the single rendered value under the bare alias instead of expanding to alias.<col>:
# whole-entity column `alias` with projection meta:
# BEFORE (edge branch): row[f"{alias}.{id_column}"] = ...; row[f"{alias}.type"] = ...
# AFTER: keep the single rendered entity under the bare alias (as node-return already does)
row[alias] = result._nodes[alias] # e.g. '[:KNOWS]'Alternative: if the harness intentionally decomposes both nodes and edges (node scenarios passing because the expected side is expanded), fix the expected-keys derivation to expand edge aliases (r → r.<prop>) the same way it expands nodes.
Which applies depends on how the node-return path is handled — needs _rows_from_result, _normalize_rows, and the expected-keys derivation to finalize a line-accurate patch.
Workaround
xfail until fixed, mirroring match-where1-10:
"match-where1-11": xfail("edge whole-entity RETURN: harness decomposes `r` into "
"`r.<prop>` columns but expects bare alias `r`; node-return keeps "
"the entity whole. Harness-side; GFQL output is correct.")Bottom line
- pygraphistry: no change required — edge whole-entity return is implemented and symmetric with node return.
- tck-gfql: fix
_rows_from_result(or the expected-keys derivation) to handle edge-return symmetrically with node-return, or xfailmatch-where1-11until then.
Activity