Skip to content
This repository was archived by the owner on Sep 12, 2018. It is now read-only.
This repository was archived by the owner on Sep 12, 2018. It is now read-only.

[tx] Accept vector values for :db/cardinality :db.cardinality/many attributes #284

@ncalexan

Description

@ncalexan

Datomic accepts a shorthand for asserting many assertions with the same [e a] values, where the attribute is :db.cardinality :db.cardinality/many. A transaction of the form

[[:db/add ENTITY :many-attribute [V1 V2 V3]]

is equivalent to

[[:db/add ENTITY :many-attribute V1]
 [:db/add ENTITY :many-attribute V2]
 [:db/add ENTITY :many-attribute V3]]

See http://docs.datomic.com/transactions.html, "Cardinality many transactions". (Note that such shorthand is valid for :db/retract as well as :db/add.)

This ticket tracks rewriting terms with vector values into many terms with scalar values. The relevant code is around 23ea4c9#diff-54794907269c3b2d0bebbfd6a8aeab5dR895.

There are a few wrinkles:

  • Vectors could be nested. It stands to reason that [V1 V2 [V3 V4]] would flatten all the way down to [V1 V2 V3 V4] It's almost certainly a mistake in human input, but it's convenient to handles values uniformly in generated input. I have no strong feelings about this and am inclined to flatten vectors entirely. (Lists and sets should be rejected, just for hygiene.) However, this might interact with the next thing...
  • Vectors of length 2 can have special meaning: they can be lookup refs (see http://docs.datomic.com/identity.html#lookup-refs). There's going to be some special work needed to disambiguate lookup refs from vectors of length 2 around 23ea4c9#diff-54794907269c3b2d0bebbfd6a8aeab5dR898, and in general it can't be done: if an assertion is
    [:db/add e :many-ref-attribute [a v]]
    where :many-ref-attribute is :db.valueType :db.type/ref and :db/cardinality :db.cardinality/many, and a and v are given as numeric entids or keyword idents, there's no way to distinguish the two cases.

In neither of the situations above do I know what Datomic does or how they try to disambiguate. In the Clojure implementation, I made callers annotate lookup refs like

[:db/add (lookup-ref a v) :other-atttribute v]

to disambiguate. (We could do that here but I'd like to use Rust's stronger type system to not require this manual disambiguation.) For now, let's assume that vectors of length 2 are always lookup refs if they can be and see where that gets us.

This depends on #283, so it's not ready to work on yet.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions