Transaction / Indexing bug
Nobody has claimed this yet.
- Dominant language
- Clojure
- Stars
- 5.8k
- Forks
- 318
- PR merge metrics
- No merged PRs in 30d
Description
In a transaction where a map has refs and reverse-ref attributes, the ref attributes are thrown away.
This works:
(require '[datascript.core :as d])
(def db
(d/empty-db
{:foo/id {:db/unique :db.unique/identity}
:foo/relations {:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many}}))
(def db-with-foo
(d/db-with
db
[{:foo/id "foo1"
:foo/relations [{:foo/id "foo2"}
{:foo/id "foo3"}]}]))
(comment
(d/touch (d/entity db-with-foo [:foo/id "foo3"]))
; works!
; => {:foo/id "foo3", :db/id 3}
)
This fails for :foo/relations [{:foo/id "foo3"}] but works for the reverse :foo/_relations:
(def db-with-foo-backwards
(d/db-with
db
[{:foo/id "foo2"
:foo/_relations [{:foo/id "foo1" :foo/relations [{:foo/id "foo3"}]}]}]))
(comment
(d/touch (d/entity db-with-foo-backwards [:foo/id "foo3"]))
; errors!
; => #object[Error Error: Assert failed: (entity? e)]
; relation between "foo1" and "foo2" exists
(d/touch (d/entity db-with-foo-backwards [:foo/id "foo1"]))
; => {:foo/id "foo1", :foo/relations #{#:db{:id 1}}, :db/id 2}
)
Looking at the indexes of either DB we see that the relations and datoms are missing in db-with-foo-backwards:
(comment
(:aevt db-with-foo)
; =>
;#{#datascript/Datom[1 :foo/id "foo1" 536870913 true]
; #datascript/Datom[2 :foo/id "foo2" 536870913 true]
; #datascript/Datom[3 :foo/id "foo3" 536870913 true] ; <-- foo3 exists!
; #datascript/Datom[1 :foo/relations 2 536870913 true]
; #datascript/Datom[1 :foo/relations 3 536870913 true]}
)
(comment
(:aevt db-with-foo-backwards)
; =>
;#{#datascript/Datom[1 :foo/id "foo2" 536870913 true]
; #datascript/Datom[2 :foo/id "foo1" 536870913 true] ; <-- foo3 and relations missing!
; #datascript/Datom[2 :foo/relations 1 536870913 true]}
)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the reproduction with d/db-with, d/touch, and the :aevt index shown in the issue. Trace how a map containing :foo/relations and reverse refs is processed during the transaction. Done means db-with-foo-backwards retains foo3 and its relation datoms, and touching the related entities no longer asserts on entity?.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- clojure
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100