Fork me on GitHub

@jarohen @taylor.jeremydavid attached difference in Linux and OS/X indices with some explanation:

πŸ‘ 3

that's great, thanks πŸ™

βž• 3

hello, I'm learning crux those days and just encountered something that I don't quite understand: I am using juxt/crux-core {:mvn/version "20.06-1.9.1-beta"} EDIT: This is working in the last version

(crux/submit-tx node

                  {:crux.db/id :v1
                   :val 4}]

                  {:crux.db/id :v2
                   :val 2}]])

  ;; throws 'Circular dependency between vb and vb'
  (crux/q (crux/db node)
          '{:find [a b]
            :where [[a :val va]
                    [b :val vb]
                    [(/ va 2) vb]]}))

;; this works
(crux/q (crux/db node)
        '{:find [a b]
          :where [[a :val va]
                  [b :val vb]
                  [(/ va 2) half-va]
                  [(= vb half-va)]]})
I was wondering if it is intended, and if yes, why it is. thank you.


Hi! I agree the intermediate lvar shouldn't be strictly necessary in this scenario. The query planner is being too conservative. I'll raise this example with the team and see if we can make it more intuitive πŸ™‚


thank you for your answer, as I said it is no longer necessary in last version of crux

πŸ‘Œ 3

Aha... πŸ˜…


I was also puzzled by something else, trying to implement some sort of get-in rule:

;; i've got a simple nested document
(crux/submit-tx node
                  {:crux.db/id :nested1
                   :a {:b {:c 1}}}]])

;; manually retrieving the value at path [:a :b :c]
(crux/q (crux/db node)
        '{:find [v]
          :where [[x :a xa]
                  [(get xa :b) xab]
                  [(get xab :c) v]]})

;; trying to generalize this with a 'in rule
;; but it throws:
;; Execution error (NullPointerException) at crux.query/build-logic-var-range-constraint-fns$iter$fn$fn (query.clj:568).
(crux/q (crux/db node)
        '{:find [x y]
          :rules [[(in x p v) [(empty? p)] [(= x v)]]
                  [(in x p v) [(first p) fp] [(rest p) rp] [(get x fp) x'] (in x' rp v)]]
          :where [(in x [:a :b :c] y)]})
any help would be much appreciated. thanks


I'm not completely sure how to solve this yet, but one problem is that (in x [:a :b :c] y) won't work because Datalog predicates can't accept a Clojure vector like that. It's also worth noting that queries won't necessarily support this kind of nested lookup efficiently (partly because there are no indexes to inform the join order), so you may well find that a custom predicate will be more effective than a rule


This works:

(c/submit-tx node
               {:crux.db/id :nested1
                :a {:b {:c {:d {:e #{1 4 6 7}}}}}}]])

;; return all roots and leaf value combination tuples for a path

(c/q (c/db node)
     '{:find [x v]
       :rules [
               [(in x d p v)
                [(empty? p)]
                [(identity d) v]
                [(identity x)]]

               [(in x d p v)
                [(not-empty p)]
                [(first p) fp]
                [(rest p) rp]
                [(get d fp) d']
                (in x d' rp v)]

       :where [[(list :b :c :d :e) p]
               [x :a d]
               (in x d p v)]})

; =>  #{[:nested1 1] [:nested1 7] [:nested1 6] [:nested1 4]}


Crucially a Clojure get can't be used on an entity lvar to get the values, you can however retrieve data from within a map when used as an entity id e.g.

(c/submit-tx node
               {:crux.db/id {:nested1 :thing}
                :a {:b {:c {:d {:e #{1 4 6 7}}}}}}]])

(c/q (c/db node)
     '{:find [x]
       :where [[e :a _]
               [(get e :nested1) x]]})


If Clojure's get-in is enough then you can use it simply like so:

(c/q (c/db node)
     {:find '[x v]
      :where '[[(list :b :c :d :e) p]
               [x :a d]
               [(get-in d p) v]]})

; => #{[:nested1 1] [:nested1 7] [:nested1 6] [:nested1 4]}


thank you a lot for those explanations!

πŸ™ 3

And finally a last question πŸ™‚ (sorry), I'm wondering why this is not working

(crux/submit-tx node
                  {:crux.db/id :ab
                   :a 1
                   :b 2}]])

(crux/q (crux/db node)
        '{:find [x]
          :where [[x :a 1]
                  [x :b 2]]})

;;this is throwing
(crux/q (crux/db node)
        '{:find [x]
          :where [(and [x :a 1]
                       [x :b 2])]})
does those two queries should be semantically equivalent ?


in theory yes these two should be identical, in practice though Crux doesn't allow for top-level usage of and because it is implicit. I think we can either relax this or improve the error message though. Thanks for mentioning it!

πŸ‘ 3

Evening all - we've released Crux 1.11.0 πŸš€ Contains new query introspection functions, so that you can see what queries your node's running, slow queries, etc - as well as a handful of bugfixes (thanks @caleb, @keytiong, @foo, @mauricio.szabo and @tolitius for raising issues and PRs πŸ™) This one contains an optional index version bump to fix an issue with Integer entity-ids (`Long`s are unaffected), and a potential race condition in transaction functions - supply :crux.kv-indexer/skip-index-version-bump [12 13] in your node config if you know this one won't affect you. As always, full details in the release notes: - let us know how you get on!

metal 21
parrot 6

No - thank you for answering and fixing these issues so fast! You guys rock! parrot

πŸ™ 3