honeysql 2024-11-19

Hello. I'm new(bie) into SQL/postgres world This query on postgres fails when ids is empty

(let [ids #{}]
  (honey.sql/format {:select [:id]
                     :from   [:users]
                     :where  [:in :id (vec ids)]}))
=> ["SELECT id FROM users WHERE id IN ()"]
is this a know limitation? is this a honeysql issue?

It's expected behaviour. Your map produces something like

where id in ()
which is a broken syntax in terms of Postgres. Always check if your collection of ids is empty before performing such a query.

@igrishaev so it is more like a psql limitation than a honeysql issue?!

As an alternative that doesn't need a check: [:= :id [:any (into-array Integer/TYPE ids)]].

👍 1
👆 1

@souenzzo It's a limitation of the SQL standard - it requires for there to be at least one item in the IN (...) list.

👍 1

@souenzzo Keep in mind that HoneySQL is a builder for raw SQL. But you can easily build an expression which fails when being passed to a database. That's exactly your case.

For things that may need a check, I really enjoy using the honey-sql helper functions.

(cond-> {:select [:id]
         :from [:users]}
 (seq ids) (sql/where [:in :id (vec ids)]))

1

i circumvented this with = ANY, which is much easier to put into honeysql (instead of placeholders for each element it makes one for the array) https://stackoverflow.com/questions/34627026/in-vs-any-operator-in-postgresql

Oops - that's what I meant with my alternative above, but I forgot the actual :any. Fixed.