Skip to content

gfql: an edge alias that collides with the column its own filter uses breaks multi-hop steps (pandas/cuDF raise, polars mis-names) #2049

Description

@lmeyerov

Summary

Follow-up to #2039 / #2046 (single-hop polars). The same marker-before-filter defect exists on the multi-hop paths, on every engine:

  • pandas and cuDF: e_forward({"type": "HAS_CREATOR"}, hops=2, name="type") and the to_fixed_point=True form raise GFQLSchemaError [incompatible-column-type]: column "type" is numeric but filter value is string. The alias marker is written onto the edge frame after hop 1 and hop 2's edge_match then filters the boolean marker.
  • polars: serves the same rows; the shadowed column keeps the user values and the marker lands beside it (<name>_right). That is the pinned polars alias-scoping contract (test_alias_scoping_semantics.py: a shadowed alias reads the user value), not a defect — the two engines differ by design in what the colliding column holds, and agree on rows.

Single-hop steps (hops=1, also multi-step chains where each step is single-hop) are correct on every engine after #2046.

Repro

import pandas as pd, graphistry
from graphistry.compute.ast import n, e_forward
nodes = pd.DataFrame({"key": [1, 2, 3, 4], "id": [10, 20, 30, 40], "type": ["p", "p", "m", "m"]})
edges = pd.DataFrame({"s": [3, 3, 4, 1], "d": [1, 2, 1, 4], "type": ["HAS_CREATOR", "OTHER", "HAS_CREATOR", "OTHER"]})
g = graphistry.nodes(nodes, "key").edges(edges, "s", "d")
g.gfql([n({"id": 30}, name="m"), e_forward({"type": "HAS_CREATOR"}, hops=2, name="type"), n(name="p")])  # raises
g.gfql([n({"id": 30}, name="m"), e_forward({"type": "HAS_CREATOR"}, hops=2, name="e"), n(name="p")])     # control: served

Same with to_fixed_point=True. Found by the alias/column collision probe run for the #2046 review (22 collision shapes × 3 engines × index policy).

Expected

The eager engines serve the multi-hop step like the single-hop one: the step's own edge_match sees the graph's column values on the backward re-execution, and the rows match polars.

Pins

Strict-xfail pins for these shapes live in graphistry/tests/compute/test_chain_alias_column_collision.py (every engine) and flip when this is fixed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions