Skip to content

Stack overflow when transacting :db.type/tupleAttrs with a :db.type/ref attr through :db.fn/call #483

@seepel

Description

@seepel

It seems I've run into a stack overflow somewhere deep inside some internals. I'm hoping this might be obvious to someone familiar with the code.

This is the smallest scenariot I've been able to isolate this bug to.

I am modeling an api repository. Providers have a unique name, each provider has a set of services each with a unique name to the provider.

(def conn (d/create-conn {:provider/name {:db/unique :db.unique/identity}
                           :service/provider {:db/cardinality :db.cardinality/one
                                              :db/valueType :db.type/ref}
                           :service/name {:db/cardinality :db.cardinality/one}
                           :service/pk {:db/valueType :db.type/tuple
                                        :db/tupleAttrs [:service/provider :service/name]
                                        :db/unique :db.unique/identity}}))

We'll choose gmail for our test data

(def tx [{:provider/name "googleapis.com"}
          {:service/provider [:provider/name "googleapis.com"]
           :service/name "gmail/v1"}])

I have another transaction that abstracts this through a :db.fn/call

(def tx-call [[:db.fn/call (fn [_db tx] tx) tx]])

Transacting with the call abstraction works against an empty db

(clojure.pprint/pprint (:tx-data (d/transact! conn tx-call)))
; (out) [#datascript/Datom [1 :provider/name "googleapis.com" 536870913 true]
; (out)  #datascript/Datom [2 :service/provider 1 536870913 true]
; (out)  #datascript/Datom [2 :service/name "gmail/v1" 536870913 true]
; (out)  #datascript/Datom [2 :service/pk [1 "gmail/v1"] 536870913 true]]

Transacting against a non-empty db with duplicate data seems to go fine

  (clojure.pprint/pprint (:tx-data (d/transact! conn tx)))
  ; (out) []

Transacting against a non-empty db with duplicate data overflows

  (clojure.pprint/pprint (:tx-data (d/transact! conn tx-call)))
  ; (err) Execution error (StackOverflowError) at datascript.db/is-attr? (db.cljc:1161).
  ; (err) null

Transacting against a non-empty db with duplicate data overflows in random spots

  (clojure.pprint/pprint (:tx-data (d/transact! conn tx-call)))
  ; (err) Execution error (StackOverflowError) at datascript.db$reify__3146/compare (db.cljc:543).
  ; (err) null
  (clojure.pprint/pprint (:tx-data (d/transact! conn tx-call)))
  ; (err) Execution error (StackOverflowError) at datascript.db$reify__3146/compare (db.cljc:543).
  ; (err) null
  (clojure.pprint/pprint (:tx-data (d/transact! conn tx-call)))
  ; (err) Execution error (StackOverflowError) at datascript.db$reify__3158/compare (db.cljc:558).
  ; (err) null
  (clojure.pprint/pprint (:tx-data (d/transact! conn tx-call)))
  ; (err) Execution error (StackOverflowError) at datascript.db/is-attr? (db.cljc:1161).
  ; (err) null
  (clojure.pprint/pprint (:tx-data (d/transact! conn tx-call)))
  ; (err) Execution error (StackOverflowError) at datascript.db.DB/_search (db.cljc:671).
  ; (err) null

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions