Skip to content

Cypher RETURN * reads the parse-time pattern, not the live scope — duplicate columns, and empty values after WITH #1983

Closed

Description

@CaptainMittens

Version

Built from source at ae5de7fe (main), release line v0.10.8

Platform

macOS (Apple Silicon)

Install channel

Built from source

Binary variant

standard

What happened, and what did you expect?

RETURN * builds its columns from the variables the query pattern named, not from the
bindings it is about to project. One line causes two separate wrong answers, and neither
reports an error — so a caller cannot tell a broken query from an empty graph.

Measured against a real indexed project:

Query Columns Values
MATCH (f:Function) RETURN * 4, correct real
MATCH (f:Function) OPTIONAL MATCH (f)-[:CALLS]->(g) RETURN * 12 — f appears twice real
the same, plus WITH f.name AS caller, g.name AS callee the same 12 all empty

execute_return_star calls collect_pattern_vars(q, ...), which reads the parse-time
pattern. Two consequences follow from that one call:

  1. After a WITH, the pattern variables are out of scope. The WITH replaced them with
    the names it made, and the live bindings are keyed by those names. Asking for f finds
    nothing, so every column is written as "".
  2. collect_pattern_vars appends each pattern in turn with no repeat check, so a variable
    named in two patterns gets its columns emitted twice.

I expected RETURN * to project the live scope — the bindings that actually exist at that
point in the query.

Reproduction

  1. Index any project with functions and CALLS edges.
  2. Run each of the three queries in the table above through query_graph.
  3. Result: query 2 returns 12 columns with f duplicated; query 3 returns 12 columns all
    of which are empty strings, with no error. Expected: query 2 returns 8 distinct
    columns, and query 3 returns the two columns the WITH named, with real values.

Logs

No error is emitted in either failing case — empty columns are returned as if the graph
had no matching data.

Diagnostics trajectory (memory / performance / leak issues)

Not applicable — a correctness issue, not memory or performance.

Project scale (if relevant)

Reproduces on any indexed project with at least one CALLS edge.

Confirmations

  • I searched existing issues and this is not a duplicate.
  • My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.

Activity

  1. added
    cypherCypher query language parser/executor bugs
    parsing/qualityGraph extraction bugs, false positives, missing edges
    on Sep 1, 2026
  2. added
    bugSomething isn't working
    priority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
    on Sep 1, 2026
  3. DeusData commented on Sep 1, 2026

    @DeusData
    Owner

    Thank you for the precise live-scope diagnosis. PR #1918 is the focused implementation for this issue and has completed maintainer review with one remaining request around silently truncating more than sixteen WITH columns. Leaving the issue open until that fix lands so the closing reference stays tied to the final implementation.

  4. DeusData commented on Sep 4, 2026

    @DeusData
    Owner

    Fixed on main by #1918 — merge commit 8f64c36d8575 (fix commits 63b99976 + 426e415f). Thanks again for the report and the fix.

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

    bugSomething isn't workingcypherCypher query language parser/executor bugsparsing/qualityGraph extraction bugs, false positives, missing edgespriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions