# Upsert behavior with composite tuple key

**URL:** <https://forum.datomic.com/t/upsert-behavior-with-composite-tuple-key/1075>\
**Category:** Datomic Cloud\
**Created:** [July 11, 2019, 4:51pm UTC](https://forum.datomic.com/t/upsert-behavior-with-composite-tuple-key/1075 "2019-07-11T16:51:59Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![jacob](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.datomic.com/jacob/32/302_2.png) [@jacob](https://forum.datomic.com/u/jacob)\
**Post date:** [July 12, 2019, 7:23pm UTC](https://forum.datomic.com/t/upsert-behavior-with-composite-tuple-key/1075/3 "2019-07-12T19:23:12Z")

</div>

Edit: did some more investigating.

```clojure
  (d/create-database client {:db-name "test"})
  (let [conn (d/connect client {:db-name "test"})
        txes [[#:db{:ident :foo,
                    :valueType :db.type/string,
                    :cardinality :db.cardinality/one}
               #:db{:ident :bar,
                    :valueType :db.type/boolean,
                    :cardinality :db.cardinality/one}
               #:db{:ident :baz,
                    :valueType :db.type/string,
                    :cardinality :db.cardinality/one}
               {:db/ident :foo+bar,
                :db/cardinality :db.cardinality/one
                :db/unique :db.unique/identity
                :db/valueType :db.type/tuple
                :db/tupleAttrs [:foo :bar]}]

              ; The value of :foo+bar after this transaction will be ["a" nil]:
              [{:foo "a"
                :bar false}]

              ; And somehow that causes this to fail:
              [{:foo "a"
                :bar false}]

              ; Upsert will work on the first time if we set :foo+bar explicitly.
              ; Also notice that :foo+bar is actually set to ["a" false] after this transaction.
              [{:foo "a"
                :bar false
                :foo+bar ["a" false]}]

              ; But on the second time, it'll create a new entity with :foo+bar set to ["a" nil]
              [{:foo "a"
                :bar false
                :foo+bar ["a" false]}]

              ; If we now try to do it again, changing the second entity to ["a" false] will fail
              ; because one already exists:
              [{:foo "a"
                :bar false
                :foo+bar ["a" false]}]]]
    (doseq [tx txes]
      (try
        (let [db (:db-after (d/transact conn {:tx-data tx}))]
          (println "transaction:")
          (pprint tx)
          (println "result:")
          (pprint
            (d/q '[:find (pull ?e [*]) :where [?e :foo]]
                 db))
          (println))
        (catch Exception e
          (println "transaction failed:" (.getMessage e))
          (println)))))
transaction:                                                                                                                                                                                                                         
[#:db{:ident :foo,
      :valueType :db.type/string,
      :cardinality :db.cardinality/one}
 #:db{:ident :bar,
      :valueType :db.type/boolean,
      :cardinality :db.cardinality/one}
 #:db{:ident :baz,
      :valueType :db.type/string,
      :cardinality :db.cardinality/one}
 #:db{:ident :foo+bar,
      :cardinality :db.cardinality/one,
      :unique :db.unique/identity,
      :valueType :db.type/tuple,
      :tupleAttrs [:foo :bar]}]
result:
[]

transaction:
[{:foo "a", :bar false}]
result:
[[{:db/id 53137197947158605, :foo "a", :bar false, :foo+bar ["a" nil]}]]

transaction failed: Unique conflict: :foo+bar, value: ["a" nil] already held by: 53137197947158605 asserted for: 69475940735909966

transaction:
[{:foo "a", :bar false, :foo+bar ["a" false]}]
result:
[[{:db/id 53137197947158605,
   :foo "a",
   :bar false,
   :foo+bar ["a" false]}]]

transaction:
[{:foo "a", :bar false, :foo+bar ["a" false]}]
result:
[[{:db/id 53137197947158605,
   :foo "a",
   :bar false,
   :foo+bar ["a" false]}]
 [{:db/id 19624083532546126, :foo "a", :bar false, :foo+bar ["a" nil]}]]

transaction failed: Unique conflict: :foo+bar, value: ["a" false] already held by: 53137197947158605 asserted for: 19624083532546126

```

So, in any case, it does seem that composite tuple handling of false values is badly broken and they (i.e., composite tuples with boolean values) shouldn’t be used until this is fixed.

---

_[View the full topic](https://forum.datomic.com/t/upsert-behavior-with-composite-tuple-key/1075)._
