Skip to content

Commit b3afed9

Browse files
authored
datalog: Always set table in Cursor.bind_table (#3692)
The `bind_table` function is used to bind a reference used in a rule or query to the appropriate value from a database (by loading the table with a given ID from the database). The `bind_table` function returns a boolean indicating if the table was empty, which is used by semi-naive evaluation to skip components where the `diff` is empty. As a misguided optimization for this specific use case, the `bind_table` function does not actually set the reference if the table is empty, which makes the semantics dubious in other settings. In fact, it causes a bug where evaluating a rule in different databases would cause the table of the old database to leak into the evaluation of in the new database if the table is empty in the new database. Fix the issue by always setting the reference in `bind_table`, which is the sane behavior.
1 parent dd57ab2 commit b3afed9

File tree

1 file changed

+2
-5
lines changed

1 file changed

+2
-5
lines changed

middle_end/flambda2/datalog/cursor.ml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,11 +292,8 @@ let create ?(calls = []) ?output context =
292292

293293
let bind_table (Bind_table (id, handler)) database =
294294
let table = Table.Map.get id database in
295-
if Trie.is_empty (Table.Id.is_trie id) table
296-
then false
297-
else (
298-
handler.contents <- Table.Map.get id database;
299-
true)
295+
handler := table;
296+
not (Trie.is_empty (Table.Id.is_trie id) table)
300297

301298
let bind_table_list binders database =
302299
List.iter (fun binder -> ignore @@ bind_table binder database) binders

0 commit comments

Comments
 (0)