hugsql

mengu 2023-07-21T20:51:34.737799Z

hi all. in postgresql the following statement will append an element to an array.

update table set array_column = array_column || '{element}'
how can i translate the '{}' part to hugsql? the only workaround i have so far is to use a clojure expression to concatenate the value:
update table set array_column = array_column || /*~ (str "'{" (:element params) "}'") ~*/
if i use a value param, that is embedded directly instead of getting substituted:
update table set array_column = array_column || '{:element}'

lukasz 2023-07-21T21:14:51.313129Z

Assuming you're using next.jdbc, you need to instruct it how to deal with arrays and Clojure types, from there you should be able to just pass them in and read them out, it's been a while though so there might be some adjustments required. https://github.com/nomnom-insights/nomnom.utility-belt.sql/blob/2a4cac52ecb5224f3ebbb6a59c5e9148c68ca8b2/src/utility_belt/sql/conv.clj#L33-L72

seancorfield 2023-07-21T21:21:42.712399Z

@lukaszkorecki Isn't this a Q about HugSQL parameter substitution?

lukasz 2023-07-21T21:24:01.133889Z

Yeah, it is but from what I remember once you set it up I think It Just Works ™️

lukasz 2023-07-21T21:27:01.921609Z

What I do remember that it wasn't entirely working in all cases, moving off array types to jsonb was easier, more flexible and worked better with HugSQL, I use HoneySQL now so there's also that

mengu 2023-07-21T23:30:37.721089Z

what I’m looking for is indeed the inline functionality of honeysql

mengu 2023-07-21T23:32:21.429429Z

(sql/format {:update :table, :set {:array_column, [:|| :array_column [:inline :?value]]}}, {:params {:value "{m}"}})

mengu 2023-07-21T23:45:21.651459Z

^^ that generates the exact statement that I want:

["UPDATE table SET array_column = array_column || '{m}'"]

curtis.summers 2023-07-22T13:49:02.926209Z

You can use PG array[] syntax:

update table set array_column = array_column || array[:element]

curtis.summers 2023-07-22T13:51:39.173539Z

which also works if you have multiple elements in a seq/vec and want to use the value list parameter type:

update table set array_column = array_column || array[:v*:elements]

curtis.summers 2023-07-22T13:54:22.289039Z

sqlvec examples of this:

(hug/sqlvec "select '{\"a\",\"b\"}' || array[:element]" {:element "c"})

["select '{\"a\",\"b\"}' || array[?]" "c"]

(hug/sqlvec "select '{\"a\",\"b\"}' || array[:v*:elements]" {:elements ["c","d"]})

["select '{\"a\",\"b\"}' || array[?,?]" "c" "d"]

mengu 2023-07-22T18:21:25.031859Z

thanks @curtis.summers - i’ve also tried that, i just couldn’t figure out how to pass a single char

mengu 2023-07-22T18:22:07.217079Z

but maybe array[:element::char] would work

mengu 2023-07-22T18:23:42.437009Z

it actually did 😄

update table set array_column = array_column || array[:element::"char"]

mengu 2023-07-22T18:29:08.389829Z

thanks @lukaszkorecki @seancorfield @curtis.summers