Fork me on GitHub
#hugsql
<
2022-02-11
>
Victor14:02:02

Hi everyone. I’m fairly new to clojure and am trying to use a JSONB ?| operator with hugsql. What I would like to do is pass a vector through as a param. I’m seeing this error and I’m not sure how to use the vector appropriately in vector.

actual: org.postgresql.util.PSQLException: ERROR: operator does not exist: text < jsonb
  Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Thanks for any help in advance!
(sql/read-all-with-options tx {:org_id "org_test" :exclude_roles ["admin" "org_admin"]})

-- :name read-all-with-options :? :*
-- :doc get all users and filter out excluded roles
select * from users where org_id = :org_id
and (allowed_roles ??| ARRAY[ :exclude_roles ]) is false

lukasz15:02:22

Can't verify but wouldn't :exclude_roles::array work here instead?

Victor15:02:43

Hey lukasz, unfortunately that didn’t work either.

actual: org.postgresql.util.PSQLException: ERROR: syntax error at or near "array"
`

lukasz15:02:40

Let me check - I believe one of our production services does a similar query

Victor15:02:00

thank you so much!

Victor15:02:53

I tried logging what :exclude_roles is being passed as to the sql query by doing SELECT (:exclude_roles); This is the response. Not sure if this is helpful:

({:?column? (apply_applicant ob_anon_primary)})

lukasz15:02:18

Ok, we didn't quite have the same query, but part of our system deals with typed arrays and jsonb so here's how you make it work:

select * from json_test where store->'foo' ??| :ids 

lukasz15:02:56

and in your Clojure code you do: (query-ns/hugsql-query db {:ids (into-array ["qux"])})

lukasz15:02:35

where the table is defined as:

nomnom=# select * from json_test;
          store
-------------------------
 {"foo": ["abc", "def"]}
 {"foo": ["qux", "def"]}
 {"foo": ["abc", "zxc"]}
 {"foo": ["qux", "zxc"]}
(4 rows)

nomnom=# \d json_test ;
              Table "public.json_test"
 Column | Type  | Collation | Nullable |   Default
--------+-------+-----------+----------+-------------
 store  | jsonb |           |          | '{}'::jsonb

lukasz15:02:51

So, in your example, you'd change ARRAY[:exclude_roles] to just :exclude_roles and when calling your query you'd write it as: (sql/read-all-with-options tx {:org_id "org_test" :exclude_roles (into-array ["admin" "org_admin"])})

Victor16:02:27

Thanks so much, sorry I’m new to clojure, where do I put this? (query-ns/hugsql-query db {:ids (into-array ["qux"])})

Victor16:02:08

thank you man! that worked perfectly

Victor16:02:15

appreciate the help 🙂

lukasz16:02:07

np, JSONB and PG arrays are one of the sharper edges in HugSQL - you can make it all work, but some bits are not obvious (like type casting in the query itself vs what type is passed to the PG driver)

🙌 1
😁 1