Fork me on GitHub
#xtdb
<
2021-09-30
>
ozimos13:09:44

I want to run parameterized queries like the one below. 

(xt/q (xt/db node) '{:find [(pull e [:bios.provider/id :xt/id])]
           :where [[e :hud/entity :hud.calendar/team]
                   (or-join
                    [e ?name ?abbr]
                    (and
                     [fid :hud/provider "gizmo"]
                     [e :gizmo.provider/id fid]
                     [(text-search :gizmo/abbreviation ?abbr) [[fid]]]
                     [fid :xt/id]
                     [(any? ?name)])
                    (and
                     [e :hud/provider "hud"]
                     [(text-search :hud/name ?name) [[e]]]
                     [e :xt/id])
                    (and
                     [fid :hud/provider "gizmo"]
                     [e :gizmo.provider/id fid]
                     [(text-search :gizmo/name ?name) [[fid]]]
                     [fid :xt/id]
                     [(any? ?abbr)]))]
           :in [[?name ?abbr]]}
      [name abbr])
But sometimes the `abbr` var is nil and causes lucene to throw ParseException errors. Changing nil values to empty string does not work. One solution is to check if `abbr` is nil then use a different query
(xt/q (xt/db node) '{:find [(pull e [:bios.provider/id :xt/id])]
           :where [[e :hud/entity :hud.calendar/team]
                   (or-join
                    [e ?name]
                    (and
                     [e :hud/provider "hud"]
                     [(text-search :hud/name ?name) [[e]]]
                     [e :xt/id])
                    (and
                     [fid :hud/provider "gizmo"]
                     [e :gizmo.provider/id fid]
                     [(text-search :gizmo/name ?name) [[fid]]]
                     [fid :xt/id]))]
           :in [[?name ?abbr]]}
      [name])
Is there a way to disable an or leg with nil parameters

refset13:09:30

Hi, I think you could try adding a predicate in the relevant leg(s) to guard against that, i.e. [(some? abbr)]

refset13:09:53

> Changing nil values to empty string does not work I'd be curious to see what you attempted for this, as I would expect it to be another valid approach. Was it converting nil -> "" before passing into :in and running the actual query? EDIT: Ah I see, text-search accepts "" fine but Lucene itself will throw a parsing error. Hmm. Maybe that's a sensible default and should be left alone, I'm not sure :thinking_face:

ozimos14:09:58

Yes I check if abbr is nil and if so change it to "" before using it in the query

ozimos14:09:02

I tried with the predicate [(some? ?abbr)] in all legs. I still get an Exception

refset14:09:37

ah, I suppose there's no way (currently) for the query planner to know to prioritise the some? clause ahead of the text-search

refset14:09:05

something else I think you could try as a fairly hacky workaround (while I think of something better) - instead of replacing nil with "", replace it with "averyveryveryverylongstringthatdefinitelywontreturnanyresults"

ozimos14:09:14

This works. I'll go with the hacky solution for now. Better than writing a separate query for every combination of nil parameter values

tatut15:09:47

with the hacky workaround you'll still be hitting the lucene search, you could avoid that with the dynamic query approach

✔️ 1
tatut16:09:51

I would've thought that and would short circuit as it does in clojure, but it makes sense that the planner reorders things

✔️ 1
tatut16:09:12

I wonder if some variant of andthat works as a planner fence would be possible, like (and-short-circuit clause1 ... clauseN) (with a better name perhaps)

tatut16:09:53

:thinking_face: or even a guard in a predicate form like [(text-search :name ?name) [[e]] :when ?name]

refset10:10:42

sorry for the delayed response (blame the Slack DNS outage last night!)... A key idea of Datalog (and XT's Datalog included), is that it is declarative, which isn't really compatible with traditional notions of conditionals & control flow. I agree though that and is counter-intuitive when you're used to clojure.core/and

tatut10:10:09

datomic doesn't have a planner that rearranges forms, so datalog doesn't preclude that imo

2
tatut10:10:35

but yeah, nothing wrong with dynamically building queries

💯 3
tatut15:09:16

is there documentation what are valid types for values? also what values can be compared with > (and similar)

refset16:09:49

XT will happily store and index anything which can be serialised via https://github.com/ptaoussanis/nippy (including many funky Java object types), however you are right to ask about byte-comparable types. The list as it stands today is only defined in the codec.clj namespace, e.g. https://github.com/xtdb/xtdb/blob/a7907f35d55ce8935da0b93c7f6752e0a615010c/core/src/xtdb/codec.clj#L82-L100

refset16:09:12

We haven't documented this much mainly because the exact supported schema is still subject to roadmap changes. Also note that there are edge cases when using the range predicates (`>` etc.) where value type boundaries are not necessarily intuitive, e.g. comparing across numbers https://github.com/xtdb/xtdb/issues/1298

refset16:09:04

You can also handle your own userspace byte encodings and store byte-arrays, since https://github.com/xtdb/xtdb/pull/1168

tatut04:10:32

yeah, I was mainly concerned about the comparability... because I had tried ju.Date, jt.LocalDate and Time and those seemed to work, those seem to be supported specifically

tatut04:10:57

thanks for the pointers

🙏 3
tatut06:10:39

if the comparison can't be done by just pulling from the index, will it revert to deserializing all and calling compare on them, or fail?

refset07:10:40

The byte-wise comparison will still be done, since bytes are always available, but it will be ~meaningless. You can always replace > with clojure.core/> though to get the more familiar semantics (and comparison failures!) with the cost of deserialising each value and comparing every possible entry in the index one by one

tatut07:10:09

yeah, definitely don't want that if it can be avoided

tatut07:10:20

so it's good to know what the byte comparable value types are

👍 3
Steven Deobald19:10:18

Clear datatype docs have been on the ol' todo list for quite some time. There will be a bit of hardening around datatypes with xtdb v2 so it's likely we won't publish strict formal docs until that point. Apologies for sending you to the source for now.