replikativ / datahike

A fast, immutable, distributed & compositional Datalog engine for everyone.
https://datahike.io
Eclipse Public License 1.0
1.62k stars 95 forks source link

[Bug]: As-of-Databases show wrong values when old datom gets retracted #558

Closed jsmassa closed 1 year ago

jsmassa commented 2 years ago

What version of Datahike are you using?

0.5.1511

What version of Java are you using?

11.0.13 2021-10-19

What operating system are you using?

Ubuntu

What database EDN configuration are you using?

{:store              {:backend :mem}
                                            :keep-history?      true
                                            :schema-flexibility :write
                                            :attribute-refs?    false}

Describe the bug

For cardinality/one attributes, only the last datom gets considered when looking for a current value in as-of-databases. This leads to values being overlooked sometimes when an old value gets retracted after a new value has been added.

What is the expected behaviour?

The last non-retracted value gets found.

How can the behaviour be reproduced?

(let [schema [{:db/ident       :name
                   :db/cardinality :db.cardinality/one
                   :db/unique      :db.unique/identity
                   :db/valueType   :db.type/string}
                  {:db/ident       :aka
                  :db/cardinality :db.cardinality/one
                  :db/valueType   :db.type/string}]
          conn (setup-db cfg)
          _ (d/transact conn schema)
          {:keys [tx-data] :as tx-report} (d/transact conn [{:name "Michal" :aka "Tupen"}])
          _ (println tx-report)
          michal (:e (first (filter #(= "Michal" (:v %)) tx-data)))
          {{:keys [db/current-tx]} :tempids} (d/transact conn [[:db/retract michal :aka "Tupen"]
                                                               [:db/add michal :aka "Devil"]
                                                               [:db/retract michal :aka "Tupen"]])
          _                                  (d/transact conn [[:db/retract michal :aka "Devil"]])
          as-of-db (d/as-of @conn current-tx)]
(d/pull as-of-db [:aka] michal))) ;; Should be {:aka "Devil"} but is nil