Repository navigation
Description
Problem
PreparedQuery::execute (and PreparedQuery::query) builds its DatalogExecutor with new_with_rules_and_functions and never calls set_limits (src/query/datalog/prepared.rs, execute_inner on main). Every other read path in db.rs passes the database's OpenOptions::max_derived_facts and max_results.
So a prepared rule query runs with the executor's defaults, whatever the database was opened with:
- a lower limit set to stop a runaway recursive rule early does not apply to prepared queries;
- a higher limit set for a legitimate large derivation does not apply either, and the prepared query fails with
INT-020whereexecuteof the same query succeeds.
Per-query :max-derived-facts / :max-results in the query text still apply, because they travel inside the query.
Repro (main, checked 2026-10-21)
fn run(opts: OpenOptions) {
let db = opts.open_memory().unwrap();
db.execute("(transact [[:a :friend :b] [:b :friend :c] [:c :friend :d] [:d :friend :e]])").unwrap();
db.execute("(rule [(reach ?x ?y) [?x :friend ?y]])").unwrap();
db.execute("(rule [(reach ?x ?z) (reach ?x ?y) [?y :friend ?z]])").unwrap();
// INT-020, as configured
db.execute("(query [:find ?x ?y :where (reach ?x ?y) [?y :friend :e]])").unwrap_err();
// succeeds: the configured limit is ignored
db.prepare("(query [:find ?x ?y :where (reach ?x ?y) [?y :friend $z]])").unwrap()
.execute(&[("z", BindValue::Val(Value::Keyword(":e".into())))]).unwrap();
}
run(OpenOptions::new().max_derived_facts(3)); // v2.x: per iteration (round 1 derives 4)
run(OpenOptions::new().max_results(5)); // total derived facts (10)Fix
Fixed on v3 in #676 (#549): PreparedQuery keeps the database's limits from prepare_query and calls executor.set_limits(…) in bind, with the test prepared_rule_queries_use_the_database_limits in tests/memory_limit_test.rs. The backport to main passes (max_derived_facts, max_results) (v2.x has both limits and its set_limits takes both), with the same test and a max_results variant.
Not a data-integrity issue: no wrong rows, only the wrong limit. Under the support policy (PHILOSOPHY.md §7), v2.0.x still takes bug fixes until v3.0.0.
Activity
fix(prepared): prepared queries use the database's rule limits (#679) (…
release: v2.0.10
adityamukho commentedon Oct 23, 2026
Fixed in v2.0.10, released 2026-10-23 (crates.io, CHANGELOG). Also fixed on
v3for v3.0.0. Moved to "Fixed in v2.0.10" in #421.