Skip to content

match-where1-11 fails #191

Open
Open

Description

@mj3cheun

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 on master — 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 xfail match-where1-11 until then.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions