I sometimes experience transactions failing due to a unique-constraint on an entity containing a tupleAttrs schema
An (anonymized) error message:
Cannot add #datalevin/Datom [17763
:my-entity/parent+location+position [17568 :front-page 9]]
because of unique constraint: 17655
All of my transactions are done using the entity-map syntax, so I originally thought that trying to transact an entity like this (supposing it already exists in the database with the same information) would effectively be a no-op (an upsert with no changes), as that tuple of values should itself act as an identifier
I don't think my schema (below) is the source of the error, but maybe something pops out as odd:
{
:my-entity/parent {:db/valueType :db.type/ref}
:my-entity/location {:db/valueType :db.type/keyword}
:my-entity/position {:db/valueType :db.type/long}
:my-entity/parent+location+position {:db/unique :db.unique/identity,
:db/tupleAttrs
[:my-entity/parent
:my-entity/location
:my-entity/position]}
:my-entity/some-other-val {:db/valueType :db.type/long}
}
I'm having difficulty creating a minimum-reproduction, as so far I only seem to encounter these errors when doing larger/more-nested* transactions, and limiting the transaction to only the 'problem' values often results in an unexpected success.
• To clarify: by 'nested', I'm referring to parent-child :db.type/ref values, not idoc's
Is my expectation of how the upsert behavior works incorrect, or is transacting larger/heavily-nested maps considered undefined?We had an issue where composite attributes are incorrectly encoded. It has now been fixed in master branch. However, it requires a data migration to see the fix. I will be releasing 1.0.0 soon, so hopefully that can get your issue fixed by then.
I appreciate it (and your continued patience with my noise here <3)
I may need to double-check; as I swapped to the master-branch yesterday, I did rm -rf my datalevin directory and began repopulating via transactions from 0, so I'd think I'd be up to date, but maybe I've made an error- if you're talking about issue https://github.com/datalevin/datalevin/issues/299, I do notice a slight difference in error-messages (but that might just be from overall changes to error-msg layout since then); I see a related issue https://github.com/datalevin/datalevin/issues/372 from June, but that one seemed to revolve around retraction-behavior.
I'll append an actual stack-trace below just in case, as I realize I didn't actually do that yesterday~
Definitely looking forward to 1.0 either way!
Ok, I'm getting closer to a minimum reproduction, it seems to only happen when I'm upserting via a reverse-lookup list The following transactions work:
(d/transact! conn
[{:db/id 16661
:rel/_from [{:rel/to 336, :rel/type :alias}]}])
(d/transact! conn
[{:db/id 16661
:rel/_from [{:rel/to 16666 :rel/type :alias}]}])
(d/transact! conn
[{:rel/from 16661, :rel/to 336, :rel/type :alias}
{:rel/from 16661, :rel/to 16666 :rel/type :alias}])
But this one throws the error:
(d/transact! conn
[{:db/id 16661
:rel/_from [{:rel/to 336, :rel/type :alias}
{:rel/to 16666 :rel/type :alias}]}])
The initial insert via the reverse-lookup list does work, its only on the upsert that the error occurs.Alright, this is a min repro for me:
(def tst
(d/get-conn "/var/tmp/datalevin/tst"
{:a/name {:db/valueType :db.type/string, :db/unique :db.unique/identity}
:rel/type+from+to {:db/unique :db.unique/identity,
:db/tupleAttrs [:rel/type :rel/from :rel/to]}
:rel/from {:db/valueType :db.type/ref}
:rel/to {:db/valueType :db.type/ref}
:rel/type {:db/valueType :db.type/keyword}}))
(d/transact! tst
[{:db/id 1 :a/name "A1"}
{:db/id 2 :a/name "A2"}
{:db/id 3 :a/name "A3"}
{:rel/from 1 :rel/to 2 :rel/type :alias}
{:rel/from 1 :rel/to 3 :rel/type :alias}])
(d/transact! tst
[{:rel/from 1 :rel/to 2 :rel/type :alias}
{:rel/from 1 :rel/to 3 :rel/type :alias}]) ;; Succeeds
(d/transact! tst
[{:db/id 1
:rel/_from [{:rel/to 2 :rel/type :alias}
{:rel/to 3 :rel/type :alias}]}]) ;; Fails
This should be on the current master-branch commit: 1f4fce0bfb03042f14880b042c9dba477c70e9b0Confirmed as a bug. Thank you for the isolated case. Fixed in master.
Incredible, grateful for all your work on this project 🌟