8000 fix(or): seed an or branch whose expression reads an outer variable (#620) by adityamukho · Pull Request #622 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content

fix(or): seed an or branch whose expression reads an outer variable (#620) - #622

Merged
adityamukho merged 1 commit into
v3from
fix/620-or-outer-expr
Oct 18, 2026
Merged

adityamukho merged 1 commit into
v3from
fix/620-or-outer-expr

Conversation

@adityamukho
Copy link
Copy Markdown
Collaborator

Issue #620: an or / or-join branch whose expression reads a variable only the outer row binds never matched, so the or silently dropped rows, in queries and in rule bodies.

(transact [[:a :n 1] [:b :n 2]])
(query [:find ?v :where [?e :n ?v] (or [(> ?v 1)] [(< ?v 0)])])           ;; was: no rows, now: 2
(query [:find ?v :where [?e :n ?v] (or-join [?v] [(> ?v 1)] [(< ?v 0)])])  ;; was: no rows, now: 2

Cause

apply_or_clauses evaluated each branch on its own, starting with nothing bound, and joined the union back onto the incoming rows. A branch's expression saw the outer variable unbound and dropped every row. or-join was affected the same way, though the issue only names or.

Fix

branch_outer_reads (executor.rs) finds the variables a branch's expressions, including those in nested branches, read but that the branch never binds through a pattern, a rule invocation or an expression output. A branch with any of these now takes the existing seeded path:

Rule bodies go through the same function, so they are fixed too.

Tests

  • tests/plan_independence_test.rs gains 5 tests: the issue's queries, a branch that binds a new variable from an outer one, nested or, or-join, and rule bodies. Each runs through execute and a cursor with reordering on and off. All 5 failed before the fix.
  • Unit test test_branch_outer_reads.
  • cargo test --features test-oracle: 1566 passed, 0 failed. cargo clippy -- -D warnings is clean.
  • Codex review (read-only): no findings.

The v2.x backport to main follows as a separate PR. #620 is a data-integrity issue, so this PR carries no closing keyword.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PtCdzbJMSS1V8qEPaJ4jXz

…620)

apply_or_clauses evaluated plain or / or-join branches from an empty
binding and joined the union back onto the incoming rows. A branch whose
expression reads a variable only the outer row binds -- [(> ?v 1)] after
[?e :n ?v] -- saw it unbound and matched nothing, so the or dropped rows
silently, in queries and in rule bodies.

branch_outer_reads names the variables a branch's expressions (its own
and its nested branches') read but the branch does not bind by a
pattern, rule invocation or expression output. A branch with any now
takes the seeded path: each incoming row seeds a plain or's branches,
and an or-join's join variables seed its branches per row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PtCdzbJMSS1V8qEPaJ4jXz
@codecov
codecov Bot commented Oct 18, 2026
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@adityamukho
adityamukho merged commit b21708a into v3 Oct 18, 2026
25 checks passed
@adityamukho
adityamukho deleted the fix/620-or-outer-expr branch October 18, 2026 08:24
adityamukho added a commit that referenced this pull request Oct 18, 2026
…620) (#623)

Backport of the v3 fix (#622). apply_or_clauses evaluated plain or /
or-join branches from an empty binding and joined the union back onto
the incoming rows. A branch whose expression reads a variable only the
outer row binds -- [(> ?v 1)] after [?e :n ?v] -- saw it unbound and
matched nothing, so the or dropped rows silently, in queries and in
rule bodies.

branch_outer_reads names the variables a branch's expressions (its own
and its nested branches') read but the branch does not bind by a
pattern, rule invocation or expression output. A branch with any now
takes a seeded path: each incoming row seeds a plain or's branches, and
an or-join's join variables seed its branches per row (a new per-row
path on v2, the one v3 uses for metadata reads).


Claude-Session: https://claude.ai/code/session_01PtCdzbJMSS1V8qEPaJ4jXz

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet
3D36

Development

Successfully merging this pull request may close these issues.

1 participant

0