You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
10BC8
Expression binding a variable a pattern also binds depends on plan order #596
An expression binding ([(f …) ?x]) overwrites ?x at the point where optimizer::plan places it. When a pattern also binds ?x, the answer depends on whether that pattern runs before the expression or after it, so native (which reorders by selectivity) and --features wasm (which keeps source order) disagree:
Native runs [:p1 :score ?x] first, then the expression overwrites ?x: [30 31] [40 41]. The score constraint is lost.
Wasm runs the expression first, then the pattern joins on it: [40 41].
Both the executor and the streaming engine do this; the engine reproduces the executor (decision 2 of the #545 plan).
Rule (settled with the maintainer, 2026-10-14)
Every plan must return the same rows the same number of times; only the order of rows may differ, and only when the query sets none.
An expression whose output variable is bound by another clause unifies: it keeps the rows where its result equals the bound value (standard Datalog), wherever it runs. So [(+ ?v 1) ?v] never matches, and two expressions binding the same variable must agree. This is a breaking change for v3.0.0: queries that relied on overwriting change (CHANGELOG, Breaking changes). Equality follows the join rules (#545): floats by IEEE ==, and a keyword equals a ref to the entity it names.
Also
A test that runs the engine's query matrix with reordering on and off in one build, and requires the same rows, so plan-dependent answers fail CI. Related: #594 (pseudo-attributes), #546 (substituted floats in not bodies).
Fixed on v3 by #601 (3a5fdac): an expression binding a variable another clause binds now unifies (keeps the rows where the values are join-equal), on the executor, evaluator and streaming engine; the first binder in :where text gives the value. tests/plan_independence_test.rs checks a query matrix with reordering on and off. Docs: project-minigraf/minigraf-docs#18. Ships in v3.0.0.
Activity
Merge pull request #598 from project-minigraf/docs/594-596-spec
Merge pull request #601 from project-minigraf/feat/596-unify
adityamukho commentedon Oct 15, 2026
Fixed on
v3by #601 (3a5fdac): an expression binding a variable another clause binds now unifies (keeps the rows where the values are join-equal), on the executor, evaluator and streaming engine; the first binder in:wheretext gives the value.tests/plan_independence_test.rschecks a query matrix with reordering on and off. Docs: project-minigraf/minigraf-docs#18. Ships in v3.0.0.