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
not-join body reads :db/valid-at as nil on its per-row path #615
A :db/valid-at pattern inside a not-join body binds nil instead of the query's valid time when the body also holds an expression clause (or in any not-join inside an or branch, and in rule bodies). The answer then depends on which executor path runs the body.
Reproduction (v3 8e1f771b; same code on main)
(transact [[:a :n 1] [:b :n 2]])
(query [:find ?e :valid-at "2030-01-01" :where [?e :n _] (not-join [?e] [?e :db/valid-at ?t])])
;; No results found. (correct: both entities have a valid time)
(query [:find ?e :valid-at "2030-01-01" :where [?e :n _] (not-join [?e] [?e :db/valid-at ?t] [(> ?t 0)])])
;; :a and :b (wrong: ?t is nil, (> nil 0) fails, the body never matches)
Cause
evaluate_not_join (src/query/datalog/evaluator.rs) matches the body with PatternMatcher::from_slice, whose :db/valid-at value is Value::Null. The exclusion-set path in apply_not_join_clause uses from_slice_with_valid_at with the query's value. evaluate_not_join is the per-row path used when the body holds an expression or a pseudo-attribute reading an outer source, and the only path for not-join in or branches (evaluate_branch) and rule queries (apply_not_join_clause_derived, StratifiedEvaluator).
Fix
Pass the query's valid-at value into evaluate_not_join and build its matcher with from_slice_with_valid_at, as not_body_matches does. Regression tests: the queries above, the same inside an or branch and in a rule body.
Found while writing the #546 design (docs/superpowers/specs/2026-10-16-negation-disjunction-engine-design.md §3.4). Present since at least v0.13.1.
Fixed on v3 in #616 (98208af) and on main in #618 (228a087). Stays open until the v2.0.x patch is published (data-integrity policy). Rule definitions binding nil for :db/valid-at are tracked separately in #617.
Activity
test(not-join): deferred rule-query and expression-only bodies (#615)
test(not-join): deferred rule-query and expression-only bodies (#615)
Merge pull request #616 from project-minigraf/fix/615-not-join-valid-at
fix(not-join): :db/valid-at binds the query's valid time on the per-r…
adityamukho commentedon Oct 16, 2026
Fixed on
v3in #616 (98208af) and onmainin #618 (228a087). Stays open until the v2.0.x patch is published (data-integrity policy). Rule definitions bindingnilfor:db/valid-atare tracked separately in #617.release: v2.0.8
adityamukho commentedon Oct 20, 2026
Released in v2.0.8 (crates.io 2.0.8, 2026-10-20); also fixed on
v3for v3.0.0. Moved to "Fixed in v2.0.8" in #421.