Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

or-join join variables check broken #121

Closed
xificurC opened this issue Feb 7, 2020 · 2 comments
Closed

or-join join variables check broken #121

xificurC opened this issue Feb 7, 2020 · 2 comments

Comments

@xificurC
Copy link
Contributor

xificurC commented Feb 7, 2020

This works in datomic. Even reading the exception one can see it's lying :)

Take this with some doubt but I was quickly trying to find the issue and it seemed the code was validating the joined variables against all branches of the or-join one by one, so it dies on the first one with the not clause. This seems to be proven with the second attempt below where a dummy clause is entered and the check passes.

Also, I'm using the or-join very often because I have cases where the attribute is either not present or when it is present it should pass some check. I haven't found a simpler way to write this but feel free to point me to better solutions :)

(require '[datahike.api :as db])
(def c (db/connect (doto "datahike:mem://foo" db/create-database)))
(db/transact c [#:db{:ident :id,
                     :valueType :db.type/keyword,
                     :cardinality :db.cardinality/one,
                     :unique :db.unique/identity}
                #:db{:ident :n, :valueType :db.type/long, :cardinality :db.cardinality/one}])
(db/transact c [{:id :a :n 1} {:id :b}])
(db/q '[:find (pull ?e [*])
        :in $ ?max
        :where
        [?e :id ?id]
        (or-join [?e ?max]
                 (not [?e :n _])
                 (and [?e :n ?n] [(< ?n ?max)]))]
      (db/db c) 1000)
;; =>
1. Unhandled clojure.lang.ExceptionInfo
   Join variable not declared inside clauses: [?max]
   {:error :parser/where,
    :form (or-join [?e ?max] (not [?e :n _]) (and [?e :n ?n] [(< ?n ?max)]))}
                 impl.cljc:  325  datalog.parser.impl/validate-join-vars
                 impl.cljc:  321  datalog.parser.impl/validate-join-vars
                 impl.cljc:  364  datalog.parser.impl$validate_or/invokeStatic
                 impl.cljc:  359  datalog.parser.impl$validate_or/invoke
                 impl.cljc:  395  datalog.parser.impl$parse_or_join/invokeStatic
                 impl.cljc:  386  datalog.parser.impl$parse_or_join/invoke
                 impl.cljc:  403  datalog.parser.impl$parse_clause/invokeStatic
                 impl.cljc:  399  datalog.parser.impl$parse_clause/invoke
                 impl.cljc:   27  datalog.parser.impl$parse_seq$item_parser__40584/invoke
     PersistentVector.java:  343  clojure.lang.PersistentVector/reduce
                  core.clj: 6827  clojure.core/reduce
                  core.clj: 6810  clojure.core/reduce
                 impl.cljc:   25  datalog.parser.impl$parse_seq/invokeStatic
                 impl.cljc:   23  datalog.parser.impl$parse_seq/invoke
                 impl.cljc:  414  datalog.parser.impl$parse_clauses/invokeStatic
                 impl.cljc:  413  datalog.parser.impl$parse_clauses/invoke
                 impl.cljc:  417  datalog.parser.impl$parse_where/invokeStatic
                 impl.cljc:  416  datalog.parser.impl$parse_where/invoke
               parser.cljc:   18  datalog.parser$parse/invokeStatic
               parser.cljc:    9  datalog.parser$parse/invoke
                query.cljc:  921  datahike.query$memoized_parse_query/invokeStatic
                query.cljc:  918  datahike.query$memoized_parse_query/invoke
                query.cljc:  926  datahike.query$q/invokeStatic
                query.cljc:  925  datahike.query$q/doInvoke
               RestFn.java:  139  clojure.lang.RestFn/applyTo
                  core.clj:  667  clojure.core/apply
                  core.clj:  660  clojure.core/apply
                  api.cljc:  208  datahike.api$eval49317$fn__49318/doInvoke
               RestFn.java:  439  clojure.lang.RestFn/invoke
              MultiFn.java:  239  clojure.lang.MultiFn/invoke
                      REPL: 1185  bus.scheduler/eval92056
                      REPL: 1185  bus.scheduler/eval92056
             Compiler.java: 7176  clojure.lang.Compiler/eval
             Compiler.java: 7131  clojure.lang.Compiler/eval
                  core.clj: 3214  clojure.core/eval
                  core.clj: 3210  clojure.core/eval
                  main.clj:  414  clojure.main/repl/read-eval-print/fn
                  main.clj:  414  clojure.main/repl/read-eval-print
                  main.clj:  435  clojure.main/repl/fn
                  main.clj:  435  clojure.main/repl
                  main.clj:  345  clojure.main/repl
               RestFn.java: 1523  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   79  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:   55  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:  142  nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
                  AFn.java:   22  clojure.lang.AFn/run
               session.clj:  171  nrepl.middleware.session/session-exec/main-loop/fn
               session.clj:  170  nrepl.middleware.session/session-exec/main-loop
                  AFn.java:   22  clojure.lang.AFn/run
               Thread.java:  834  java.lang.Thread/run
(db/q '[:find (pull ?e [*])
        :in $ ?max
        :where
        [?e :id ?id]
        (or-join [?e ?max]
                 (and (not [?e :n _]) [(= ?max ?max)])
                 (and [?e :n ?n] [(< ?n ?max)]))]
      (db/db c) 1000)
;; =>
([{:db/id 4, :id :b}] [{:db/id 3, :id :a, :n 1}])
@kordano
Copy link
Member

kordano commented Feb 7, 2020

That is weird behaviour indeed. I'll have a look at it.

@whilo
Copy link
Member

whilo commented Apr 22, 2020

This is fixed in datalog-parser 0.1.3 with replikativ/datalog-parser@85a3ca1 now.

@whilo whilo closed this as completed Apr 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants