Skip to content

fix(rvlite): finish multi-row MATCH for RETURN columns, SET, DELETE and comma patterns - #1237

Open
aepod wants to merge 1 commit into
ruvnet:mainfrom
weave-logic-ai:fix/rvlite-cypher-match-followups
Open

aepod wants to merge 1 commit into
ruvnet:mainfrom
weave-logic-ai:fix/rvlite-cypher-match-followups

Conversation

@aepod

@aepod aepod commented Oct 20, 2026

Copy link
Copy Markdown

This is a fresh version of #292 on current main, and replaces it. #484 fixed #269, so RETURN now iterates every MATCH row. Thanks for that. This PR builds on it and fixes what was still missing.

I ran the tests from #292 against current main and 2 of them still fail. There are four remaining problems, each reproduced on current main with a new test before the fix:

  1. A MATCH with zero matches makes RETURN n error with VariableNotFound("n") instead of returning 0 rows. RETURN falls back to the outer context when matched_rows is empty.
  2. RETURN n.name gets the column name ?column?, and RETURN n.name, n.city collapses both into one ?column? column.
  3. MATCH ... SET n.x = ... and MATCH ... DETACH DELETE n do nothing, because SET and DELETE read the variable from the outer context, which MATCH no longer fills.
  4. MATCH (p:Person), (c:Company) unions the two pattern results instead of taking a cross product, so RETURN p.name, c.name errors with VariableNotFound("p").

The fix:

  • The executor tracks whether a MATCH ran. This is a private field on Executor, so there is no public API change.
  • RETURN, SET and DELETE share one row_contexts() helper.
  • Property items get var.prop column names. Aliases still win.
  • Comma patterns combine as a cross product, and a variable shared between patterns must bind the same element.
  • DELETE removes each node or edge once, even if it appears in several rows.

Files: crates/rvlite/src/cypher/executor.rs and crates/rvlite/src/cypher/mod.rs.

Tests: with only the new tests applied to current main, 7 of the 13 tests in cypher::tests fail: test_match_no_results, test_match_return_properties, test_match_where_filter (it now checks the n.name values), test_return_multiple_property_columns, test_match_set_updates_every_row, test_match_detach_delete_every_row, test_match_comma_patterns_cross_product. With this change:

  • cargo test -p rvlite --no-fail-fast: lib 72 passed, 0 failed, 2 ignored (the parser ignores that were already there). cypher_integration_test 8 passed.
  • cargo fmt check is clean on the changed files.
  • cargo clippy -p rvlite --all-targets: 0 warnings in rvlite, same as main.
  • cargo check -p rvlite --target wasm32-unknown-unknown passes.

Not fixed here:

  • A second MATCH statement still replaces the first one's rows.
  • MATCH (n:A:B) still gives duplicates.
  • Plain DELETE (without DETACH) still always errors for nodes, as before.

This touches crates/rvlite/src/cypher/mod.rs, like open PR #1084. I checked with git merge-tree and there is no textual conflict.

🤖 Generated with RuFlo

…nd comma patterns

ruvnet#484 made RETURN iterate every MATCH row (ruvnet#269), but the rest of the
executor still reads bindings from the outer context, so:

- MATCH with zero matches fell back to the outer context and RETURN n
  failed with VariableNotFound("n") instead of returning no rows.
- RETURN n.name produced the column "?column?", and RETURN n.name, n.city
  collapsed both items into that one column.
- MATCH ... SET and MATCH ... DETACH DELETE were no-ops, because SET and
  DELETE looked the variable up in the outer context, which MATCH no
  longer fills.
- MATCH (p:Person), (c:Company) unioned the two pattern results instead of
  taking their cross product, so every row was missing a variable.

SET, DELETE and RETURN now share one row_contexts() helper, the executor
records whether a MATCH ran, property items get "var.prop" column names,
and comma patterns combine as a cross product. Adds regression tests for
each case alongside the ruvnet#269 ones.

Co-Authored-By: RuFlo <ruv@ruv.net>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CypherEngine: MATCH RETURN produces single row — context.bind() overwrites previous bindings

1 participant