xtdb 2025-05-17

Question about the inline XTQL stuff in Beta 8 @jarohen :

FROM (XTDB $$ (-> (from :my-table [x]) (where (<= x 100))) $$) AS my_table
that's based on an example from the docs -- are the parens required here? Is the following valid?
FROM XTDB $$ (-> (from :my-table [x]) (where (<= x 100))) $$ AS my_table

I'm implementing this in HoneySQL, which is why I'm asking...

I've implemented like this for now:

user=> (sql/format [:xtql '(-> (from :my-table [x]) (where (<= x 100)))])
["XTQL $$ (-> (from :my-table [x]) (where (<= x 100))) $$"]
user=> (sql/format {:from [[[:xtql '(-> (from :my-table [x]) (where (<= x 100)))] :my_table]]})
["FROM (XTQL $$ (-> (from :my-table [x]) (where (<= x 100))) $$) AS my_table"]

you don't waste your time 😄🙏

yes, parens required when it's being used within a wider SQL query, optional at top-level

this is mainly just following the syntax for SQL subqueries, I can see whether we can unambiguously remove them for XTQL specifically if that would make things easier

No, it's fine, I just wanted to figure out the implementation. Seems I guessed right 🙂

also you may run into https://github.com/xtdb/xtdb/pull/4443 when you start testing with params - it's ugly, I'm ashamed of it, and any better suggestions welcome 😬

Nasty indeed. I'll have to give that some thought.

I created a HoneySQL issue to think about it...

I guess HoneySQL could look at the XTQL form and see (fn [a b c] ..) and add 3 ? parameters...

fwiw in the Clojure API we've done a relatively simple parse of the XTQL and ... yep, that

One thing to be aware of here is how '#(...) behaves for that pr-str call:

{:from [[[:xtql '#(-> (from :my-table [x]) (where (<= x %))) :my_table]]]}
;;=>
["FROM (XTQL $$ (fn* [p1__32122#] (-> (from :my-table [x]) (where (<= x p1__32122#)))) $$) AS my_table"]

And I suspect you don't support fn* there? 🙂

How are the actual parameters passed in this case?

As in, how would HoneySQL know to lift values out and provide ? placeholders?

yep, we deliberately do support fn* 🙂

so we check first is fn or fn*, then count second

OK... so maybe [:xtsql '(fn [v] (-> (from :my_table [x]) (where (<= x v))) 42] as the HoneySQL format?

To produce ["XTQL ($$ .. $$, ?)" 42]

that seems good, yeah - :xtql I guess?

Yeah... I have a hard time typing that correctly.

ah, there's some good real user feedback 😄

I either type :xtdb or :xtsql 🙂

😄 1

Even in the tests I was just writing for HoneySQL, I repeatedly got it wrong and the tests failed 😞

Per https://github.com/xtdb/xtdb/pull/4443, parameters can be provided to :xtql after the XTQL form, which must either use (fn [..] ..) or the #(..) shorthand syntax to parameterize the query:

clojure
user=> (sql/format {:from [[[:xtql '(fn [v] (-> (from :my-table [x]) (where (<= x v)))) 42] :my_table]]})
["FROM (XTQL ($$ (fn [v] (-> (from :my-table [x]) (where (<= x v)))) $$, ?)) AS my_table" 42]
The shorthand form would be [:xtql '#(-> (from :my-table [x]) (where (<= x %)) 42].

> which must either use the fn or #() syntax > this is the only way to do params in XTQL after beta8. tbh I'm hoping that it's only ever you and us that need to worry about the extra ?s 🙂 - anyone going through the xtdb-api should have it handled transparently on their behalf

thanks ever so much Sean 🙏 gratitude

➕ 1