juji-io / datalevin

A simple, fast and versatile Datalog database
https://github.com/juji-io/datalevin
Eclipse Public License 1.0
1.07k stars 60 forks source link

Staged entity transactions broken for refs #244

Closed den1k closed 2 months ago

den1k commented 2 months ago

repro:

(def schema
  {:dev-id {:db/valueType :db.type/string
            :db/unique    :db.unique/identity}
   :a-ref  {:db/valueType   :db.type/ref
            :db/cardinality :db.cardinality/many}})

(def test-conn
  (d/create-conn "data/test-conn" schema))

(d/transact! test-conn [{:dev-id "foo"}])

(d/transact! test-conn [{:dev-id "bar"}])

(d/entity @test-conn [:dev-id "foo"])
; => #:db{:id 1}

(assoc (d/entity @test-conn [:dev-id "foo"])
  :a-ref [:dev-id "bar"])
; => {:db/id 1, :<STAGED> {:a-ref [{:op :assoc} [:dev-id "bar"]]}}

; transact staged value
(d/transact! test-conn [(assoc (d/entity @test-conn [:dev-id "foo"])
                          :a-ref [:dev-id "bar"])])

(:a-ref (d/entity @test-conn [:dev-id "foo"]))
; (:a-ref (d/entity @test-conn [:dev-id "foo"]))
; => nil
; πŸ‘† BROKEN: ref is missing, staged value did not transact

; transact directly
(d/transact! test-conn [{:dev-id "foo"
                         :a-ref  [:dev-id "bar"]}])

(:a-ref (d/entity @test-conn [:dev-id "foo"]))
; works!
; => #{#:db{:id 2}}
den1k commented 2 months ago

Tried debugging this as best as I could but was not able to run the repo properly. I did not resolve the issue but found this redundant invocation:

https://github.com/juji-io/datalevin/blob/master/src/datalevin/db.clj#L963-L964

den1k commented 2 months ago

found the issue. it was a regression introduced here: https://github.com/juji-io/datalevin/commit/638c764e7d1ac3c5ac790f1d38ff19155bc921b9#diff-8513cf5705e7d10c2e9192048c770be6723efc995496e7d7be307fb5ceec51dfL1047