Upsert behavior with composite tuple key

Edit: did some more investigating.

  (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.