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:
- 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 "".
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
- Index any project with functions and
CALLS edges.
- Run each of the three queries in the table above through
query_graph.
- 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
Version
Built from source at
ae5de7fe(main), release line v0.10.8Platform
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 thebindings 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:
MATCH (f:Function) RETURN *MATCH (f:Function) OPTIONAL MATCH (f)-[:CALLS]->(g) RETURN *fappears twiceWITH f.name AS caller, g.name AS calleeexecute_return_starcallscollect_pattern_vars(q, ...), which reads the parse-timepattern. Two consequences follow from that one call:
WITH, the pattern variables are out of scope. TheWITHreplaced them withthe names it made, and the live bindings are keyed by those names. Asking for
ffindsnothing, so every column is written as
"".collect_pattern_varsappends each pattern in turn with no repeat check, so a variablenamed in two patterns gets its columns emitted twice.
I expected
RETURN *to project the live scope — the bindings that actually exist at thatpoint in the query.
Reproduction
CALLSedges.query_graph.fduplicated; query 3 returns 12 columns allof which are empty strings, with no error. Expected: query 2 returns 8 distinct
columns, and query 3 returns the two columns the
WITHnamed, with real values.Logs
Diagnostics trajectory (memory / performance / leak issues)
Project scale (if relevant)
Reproduces on any indexed project with at least one CALLS edge.
Confirmations