replikativ/datahike

[Bug]: Hitchhiker-tree index repeatedly retracts datom with re-upserted value instead of latest value

Opened this issue · 1 comments

yflim commented

What version of Datahike are you using?

0.4.1502

What version of Java are you using?

java version "16.0.2" 2021-07-20

What operating system are you using?

MacOS

What database EDN configuration are you using?

{:store {:backend :mem},
:keep-history? true,
:schema-flexibility :read,
:attribute-refs? false,
:index :datahike.index/hitchhiker-tree}

Describe the bug

When using a hitchhiker-tree index, after upserting (and retracting) a datom with a prior value, upserts using the same EA (entity and attribute) retract that value instead of the latest value.

What is the expected behaviour?

An upsert should retract the latest value (if any) of the same EA.

How can the behaviour be reproduced?

(require '[datahike.api :as d]
           '[datahike.index :as di]
           '[datahike.test.utils :as tu])
           
  (def conn (tu/setup-db))
  (def schema [{:db/ident       :name
                :db/valueType   :db.type/string
                :db/unique      :db.unique/identity
                :db/index       true
                :db/cardinality :db.cardinality/one}
               {:db/ident       :age
                :db/valueType   :db.type/long
                :db/cardinality :db.cardinality/one}])

  (d/transact conn schema)
  (d/transact conn {:tx-data [{:name "Alice"
                               :age  25}]})
  (d/transact conn [[:db/add [:name "Alice"] :age 30]])
  (d/transact conn [[:db/add [:name "Alice"] :age 35]])
  (d/transact conn [[:db/add [:name "Alice"] :age 25]])
  (d/transact conn [[:db/add [:name "Alice"] :age 40]])
  (d/transact conn [[:db/add [:name "Alice"] :age 30]])

  (= ['(3 :age 25 536870918 false)
       '(3 :age 25 536870915 false)
       '(3 :age 25 536870914 true)
       '(3 :age 25 536870917 true)
       '(3 :age 30 536870916 false)
       '(3 :age 30 536870915 true)
       '(3 :age 30 536870919 true)
       '(3 :age 35 536870917 false)
       '(3 :age 35 536870916 true)
       '(3 :age 40 536870919 false)
       '(3 :age 40 536870918 true)
       '(3 :name "Alice" 536870914 true)]
     (mapv seq (filter #(> (.-e %) 2) (di/-seq (.-temporal-eavt @conn)))))

Might have already a solution in PR #503 and should not be worked on until #503 is merged