Fork me on GitHub
#xtdb
<
2022-11-09
>
zeitstein08:11:02

I'm seeing unexpected query results when using a recursive rule on data that forms a loop. Example repro in thread. Am I doing something incorrectly? Another casualty of https://github.com/xtdb/xtdb/issues/1569 🙂

zeitstein08:11:03

(def n (xt/start-node {}))

  (def data
    [;; loop
     {:xt/id 1 :text "1" :child 2}
     {:xt/id 2 :text "2" :child 3}
     {:xt/id 3 :text "3" :child 2}
     ;; non-loop
     {:xt/id 4 :text "4" :child 5}
     {:xt/id 5 :text "5" :child 6}
     {:xt/id 6 :text "6"}])

  (xt/submit-tx n (mapv #(vector ::xt/put %) data))

  (def rules
    '[[(follow p c)
       [p :child c]]
      [(follow p c)
       [p :child i]
       (follow i c)]])

  (defn q [parent]
    (xt/q (xt/db n)
      {:find '[e]
       :in '[p]
       :where '[[e :text] (follow p e)]
       :rules rules}
      parent))

  (q 4) ;; ✔  #{[5] [6]}
  (q 1) ;; ❌ #{[1] [2] [3] [4] [5] [6]}, expected: 2, 3

  ;; same situation with bounded rule (follow [p c])

  ;; this works as expected, returns: 2,3
  (xt/q (xt/db n)
    {:find '[e]
     :where '[(follow 1 e)]
     :rules rules})

refset11:11:45

Hey again 🙂 thanks for raising this. Does the indirection workaround I suggested in the comments resolve it for you?

zeitstein11:11:05

Are you saying hi to me or to your issue nemesis 😁 It works in the above example but didn't work in my system. Maybe because there were more rules in that query – I'll dig into that later.

😄 1
blob_thumbs_up 1
zeitstein07:11:57

https://gist.github.com/zeitstein/6182a270def0baa1c202c70930762d3d expanding on above, trying to repro what I'm seeing in my system (queries with lucene). In the example: • works as expected when recursive rule does not operate on loop data • but also works as expected on loop data when recursive rule has first arg bounded • indirection workaround works, except when recursive rule has both args bounded.

licht1stein11:11:05

If i'm using an xt/id like this {:foo "bar"}, {:foo "spam"}, how do I find all records, where :foo is the key in the xt/id? I tried this, but it doesn't seem to work:

(xt/q db '{:find [?e]
                 :where
                 [[?e :xt/id]
                  [(= :foo (first ?e))]
                  ]})

tatut11:11:24

afaict, that will be inefficient

1
tatut11:11:07

If you want to query by “type”, you would need to encode it in some attribute

1
licht1stein11:11:07

Yeah, that was my next solution. I'll probably just do that and stop playing around 🙂