Skip to content

polars chain: forward/reverse varlen with min_hops>1 returns nodes outside the hop window (silent wrong) #1748

Description

@lmeyerov

Summary

On the polars chain engine, a forward or reverse variable-length pattern with min_hops > 1 returns nodes whose hop distance is outside the requested window. No error is raised — the answer is silently wrong.

Undirected *2..3 correctly declines with a NotImplementedError. Only fwd/rev silently mis-answer.

Repro

import pandas as pd, polars as pl, graphistry
e = pd.DataFrame({"s": ["p0","p1","p2","p1"], "d": ["p1","p2","p4","p0"]})
q = "MATCH (a {id:'p0'})-[*2..3]->(b) RETURN b"

graphistry.edges(e, "s", "d").gfql(q, engine="pandas")
# -> p2, p4                      (correct: distances 2 and 3)

graphistry.edges(pl.from_pandas(e), "s", "d").gfql(q, engine="polars")
# -> p0, p1, p2, p4              (WRONG: p0 is distance 0, p1 is distance 1)

Cause

The polars chain gates a node alias by hop distance only when the auto hop-label column is present. For min_hops > 1 the label is deliberately not requested (those labels come from pandas' layered backward walk, which is not ported), so the alias ends up ungated and every reachable node passes.

Undirected happens to escape because it declines the whole shape earlier.

Scope — measured, not inferred

4-engine differential sweep against pandas as oracle, 144 cases (4 hand graphs + 12 random graphs x 9 patterns), run on dgx-spark under safe_run.sh, RAPIDS 26.02 image.

build pandas cudf polars polars-gpu
master c355660a 144/144 144/144 79 ok / 49 wrong / 16 NIE 79 / 49 / 16
master + #1746 + #1747 144/144 144/144 114 ok / 14 wrong / 16 NIE 114 / 14 / 16

Set-diff of the mismatch sets: 0 regressions, 70 of 98 fixed. All 28 residual mismatches (14 per polars engine) are this one shape, -[*2..3]->.

So this bug is pre-existing on master and is not introduced by the #1741 stack — that stack removes 71% of the silent-wrong surface and leaves exactly this hole.

Fix direction

Either port the layered backward walk that produces min_hops > 1 labels, or — cheaper and strictly better than today — decline (NIE) the fwd/rev min_hops > 1 + node-alias shape the same way undirected already does, so a wrong answer becomes an honest error.

Related: #1741, #1746, #1747.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions