Repository navigation
v2.0.7 — 2026-10-16
Release Notes
Patch release on the v2.x line under the support policy: one data-integrity fix for prepared queries (#603) and two query fixes for rules with literal arguments (#608) and or clauses that share no variable with the earlier clauses (#610). File format is unchanged (v7). No API changes. Upgrading is recommended for every v2.x user who uses prepared queries with a literal :as-of or :valid-at, rule calls with a literal argument, or or.
Fixed
- Rule queries with a literal argument return every row (#608). Magic-sets rewriting restricts a rule to the facts its callers demand, but it took each rule's bound arguments from the first call it saw and assumed every other call matched. A call that did not — the same rule called with free arguments elsewhere in the query, a call inside
orornot, a call from a rule the query calls with free arguments, or a rule-body call whose argument nothing bound yet — either failed withINT-022((chain ?x :c)with(chain ?x ?y) :- (link ?x ?m) (chain ?m ?y)) or silently returned too few rows ((link ?x :c) (link ?p ?q)returned only the:cedges for?p ?q). A query with both arguments literal next to another rule call also lost its rows. The demand on each rule is now the one every call site supplies, and a rule some call site reads in full is evaluated in full. Present since v1.2.0; also fixed on v3. - An
orthat shares no variable with the earlier clauses returns its cross product (#610). Such anor—[?x :edge ?z] (or [?p :edge :b] [?p :edge :c])— returned no rows when no branch hadnotornot-join, because the incoming rows were replaced by the branch results. Each incoming row now joins every branch row, in queries and rule bodies.or-joinstill refuses a join variable no earlier clause binds (INT-018): it filters, it does not bind. Also fixed on v3. - A prepared query keeps a literal
:as-of,:valid-ator:any-valid-time(#603). Binding a prepared query's slots dropped any:as-ofor:valid-atthat was not itself a slot, soPreparedQuery::executeran at the current transaction time and valid now:(query [:find ?v :as-of 1 :where [:a :n ?v]])prepared returned the current rows, not those at transaction 1, and a prepared per-fact pseudo-attribute query with:any-valid-timefailed withINT-026. Slot forms (:as-of $tx,:valid-at $t) were not affected. Present since 2026-04-04 (v1.x and every v2.x release).
Tests
tests/prepared_statements_test.rschecks that a prepared query with a literal:as-of,:valid-ator:any-valid-timereturns the same rows as the unprepared query (#603);tests/magic_sets_test.rschecks rule calls with a literal argument where some call site cannot carry the demand (#608);tests/disjunction_test.rschecks the cross product of anorthat shares no variable with the earlier clauses, in queries and rule bodies (#610).
Known issues
- Same-transaction multi-valued facts can read back as one value (#371, #287), a fact retracted and re-asserted in one
WriteTransactionis lost at commit (#477), a later assertion does not replace an earlier valid-time window (#435),save()is not crash-atomic (#374), and a.walfrom a later checkpoint is replayed onto an older.graph(#535); all are fixed in v3.0.0. All v2.x known issues, with affected versions and workarounds, are listed in the pinned issue #421.
Download minigraf 2.0.7
| File | Platform | Checksum |
|---|---|---|
| minigraf-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| minigraf-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| minigraf-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| minigraf-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| minigraf-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |