Bug in :db/ensure's boolean attr handling?

When I set a boolean attribute to false, :db/ensure thinks the datom isn’t there at all:

(let [db (d/with-db system/conn)
        schema [#:db{:ident :foo,
                     :valueType :db.type/boolean,
                     :cardinality :db.cardinality/one}
                {:db/ident :foo-spec,
                 :db.entity/attrs [:foo]}]
        db (:db-after (d/with db {:tx-data schema}))]
    ; works
    (d/with db {:tx-data [{:foo true, :db/ensure :foo-spec}]})
    ; doesn't work
    (d/with db {:tx-data [{:foo false, :db/ensure :foo-spec}]}))
Execution error (ExceptionInfo) at datomic.client.api.async/ares (async.clj:58).
Entity 27096364554912302 missing attributes clojure.lang.LazySeq@3cd1fc84 of spec :foo-spec
user=> (.printStackTrace *e)
clojure.lang.ExceptionInfo: Entity 27096364554912302 missing attributes clojure.lang.LazySeq@3cd1fc84 of spec :foo-spec {:cognitect.anomalies/category :cognitect.anomalies/incorrect, :cognitect.anomalies/message "Entity 27096364554912302 missing attributes clojure.lang.LazySeq@3cd1fc84 of spec :foo-spec", :db/error :db.error/entity-attr, :dbs [{:database-id "2c6b0702-61bc-4d2d-aa42-c2d2948b6170", :t 171, :next-t 172, :history false}]}
	at datomic.client.api.async$ares.invokeStatic(async.clj:58)
	at datomic.client.api.async$ares.invoke(async.clj:54)
	at datomic.client.api.sync$eval30052$fn__30071.invoke(sync.clj:98)
	at datomic.client.api.protocols$eval511$fn__570$G__502__577.invoke(protocols.clj:126)
	at datomic.client.api$with.invokeStatic(api.clj:304)
	at datomic.client.api$with.invoke(api.clj:294)
	at user$eval30750.invokeStatic(NO_SOURCE_FILE:11)
	at user$eval30750.invoke(NO_SOURCE_FILE:1)
	at clojure.lang.Compiler.eval(Compiler.java:7176)
	at clojure.lang.Compiler.eval(Compiler.java:7131)
	at clojure.core$eval.invokeStatic(core.clj:3214)
	at clojure.core$eval.invoke(core.clj:3210)
	at clojure.main$repl$read_eval_print__9068$fn__9071.invoke(main.clj:414)
	at clojure.main$repl$read_eval_print__9068.invoke(main.clj:414)
	at clojure.main$repl$fn__9077.invoke(main.clj:435)
	at clojure.main$repl.invokeStatic(main.clj:435)
	at clojure.main$repl_opt.invokeStatic(main.clj:499)
	at clojure.main$repl_opt.invoke(main.clj:495)
	at clojure.main$main.invokeStatic(main.clj:598)
	at clojure.main$main.doInvoke(main.clj:561)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:705)
	at clojure.main.main(main.java:37)

There also seems to be a small bug in the error output; the missing attributes aren’t realized (missing attributes clojure.lang.LazySeq@3cd1fc84)

Also, when using a composite tuple, the value is nil instead of false:

(let [db (d/with-db system/conn)
        schema [#:db{:ident :foo,
                     :valueType :db.type/boolean,
                     :cardinality :db.cardinality/one}
                #:db{:ident :bar,
                     :valueType :db.type/boolean,
                     :cardinality :db.cardinality/one}]
        db (:db-after (d/with db {:tx-data schema}))
        more-schema [{:db/ident :some-composite-key
                      :db/cardinality :db.cardinality/one
                      :db/valueType :db.type/tuple
                      :db/tupleAttrs [:foo :bar]}]
        db (:db-after (d/with db {:tx-data more-schema}))]
    (u/pprint (:tx-data (d/with db {:tx-data [{:foo true
                                               :bar false}]}))))
[#datom[13194139533486 50 #inst "2019-07-10T21:34:53.300-00:00" 13194139533486 true]
 #datom[20433324090589741 130 true 13194139533486 true]
 #datom[20433324090589741 131 false 13194139533486 true]
 #datom[20433324090589741 132 [true nil] 13194139533486 true]]

Thanks again for the report. We have identified a bug here and are working on a fix for the next release. I’ll update all related threads once we have more details on the fix/release.

Cross posting. See my response on the other thread: Upsert behavior with composite tuple key

1 Like

@jacob We’ve resolved this issue in Datomic on-prem, see the release announcement. We are currently pending release with AWS for a fix in Datomic Cloud. I’ll update this thread again as soon as we have the templates posted and through AWS’s review.