Skip to content

GFQL Cypher: whole-row carry loses multiplicity + whole-entity carried alias null-row rendering (openCypher 5 vs 3; cuDF renders False) #1935

Open

Description

@lmeyerov

Two strict-xfailed pre-existing silent-wrongs from #1897's amplification, which said both "want one follow-up issue" that was never filed:

  1. Duplicate-carried-prefix multiplicity loss: MATCH (a:P)-->(c) WITH a AS p OPTIONAL MATCH ... — openCypher says 5 rows; all three engines return 3, because the whole-row carry dedups the prefix by node id before the duplicate_carried_node_rows decline can fire. Also makes the E10 duplicate-key guard unreachable on this path.
  2. Whole-entity carried alias dropped from the null-extended row: WITH a AS p, a.id AS pid ... RETURN p, pid, b.id — p stays bound but comes back all-NULL on pandas/cuDF for the unmatched row, and cuDF renders boolean label columns False where pandas renders None; polars declines.

Both are strict-xfailed on master (test names in graphistry/tests/compute/gfql/cypher/reentry/), so they cannot regress silently; this issue tracks serving them.

🤖 Generated with Claude Code
https://claude.ai/code/session_01AjbKuKheqDu78oapRT5AYm

Activity

  1. lmeyerov commented on Aug 20, 2026

    @lmeyerov
    ContributorAuthor

    Split status after a triage pass over the 12 strict xfails that record a runtime wrong answer:

    Item 2 (whole-entity carried alias blanked on the null-extended row, cuDF rendering False) — fixed in #1992. The prefix frame already carries the alias' flat p.<prop> columns under exactly the names the result frame uses; the null-fill copied only the carried scalar columns. It now copies the entity columns too, keys unchanged. Both pandas and cuDF verified.

    Item 1 (duplicate-carried-prefix multiplicity, openCypher 5 vs 3) — deferred, and it is not really a re-entry bug. The prefix never reaches re-entry with duplicates: MATCH (a:P)-->(c) WITH a AS p is a whole-row carry, and the whole-row projection lane dedups it to 2 rows before compiled_query_reentry_state sees it. That is why the duplicate_carried_node_rows guard is unreachable — adding a duplicate probe there is provably vacuous (measured: never fires on any spelling of this shape).

    The actual root cause is the whole-entity projection lane, now filed as #1994 with the measured evidence. Routing a single whole-row output over a relationship to rows(binding_ops=...) fixes this item too — it turns the 3-row wrong answer into a typed decline on all three engines — but it takes graphistry/tests/compute/gfql from green to 60+ failures because the polars whole-entity projector and the reentry lanes cannot render off binding rows. Sequencing is in #1994.

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