Skip to content

GFQL Cypher: binding-named variables (e.g. MATCH (src)-[e]->(dst)) should scope, not decline (E108) #2069

Description

@lmeyerov

What

The Cypher route declines a variable whose name equals a binding column of the same frame (node-id, source, destination or edge-id), with typed error E108. Example on g.edges(df, "src", "dst"):

MATCH (src)-[e]->(dst) RETURN src.name

openCypher allows this: variables and property keys/columns are separate namespaces, and RETURN src projects an entity, so nothing collides.

Why we decline today

Lowering passes the variable straight through as the chain alias, and a chain alias is materialized as a marker column named after the alias on the frame that owns the binding. That is the same collision an op-list alias has, and there the decline is the right answer (an op-list alias is an output column, so the marker would be a duplicate output name; openCypher rejects duplicate result columns at RETURN the same way). On the Cypher surface the decline fires at the scoping layer, which is the wrong layer.

Contract (decided 2026-09-06 with the owner, thread on #2056)

One rule on both surfaces: scope shadows, projection declines duplicate output names. Binding columns are structure; the binding stays on the original column values everywhere.

Fix

  • Lowering maps a binding-named variable to an internal marker (generate_safe_column_name) for the chain.
  • The row pipeline resolves alias.prop, whole-entity RETURN alias, WITH alias re-entry and aggregates through that map; the endpoint / id column is never touched.
  • Remove the Cypher-route E108 for this case; keep it on op lists.
  • Pins: pos+neg on both surfaces, all four engines, single-hop / multi-hop / varlen, RETURN src, RETURN src.src, WITH src ... MATCH, count(src); tck-gfql green; route harness parity.

Follow-up to #2056; not a change to #2056.

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