Приведение нескольких значений в HugSQL или YesQL с помощью Postgres

Я пытаюсь составить список IP-адресов ::inet но только последний элемент в списке конвертируется.

Я попробовал следующее, но ничего не работает.

select * from ip_addresses where address in (:addresses::inet)

select * from ip_addresses where address in (:addresses)::inet

select * from ip_addresses where address in CAST (:addresses AS inet)

Я не могу просто бросить address::text поскольку совпадения могут быть неудачными, если во входных адресах не указана подсеть.

2 ответа

Решение

Похоже, HugSQL заменяет :addresses со списком через запятую, так что ваш (:addresses::inet) в конечном итоге выглядит как (addr, addr, addr, ..., addr::inet), Если это так, то вы могли бы заменить in (list) с = any(array)используйте синтаксис конструктора массива и примените приведение к этому массиву в целом:

select * from ip_addresses where address = any(array[:addresses]::inet[])

Я думаю, что ответ от @mu-is-too-short - лучший обходной путь для этого - использование возможностей Postgresql для решения проблемы.

Тем не менее, если вы не хотите использовать для этого массивы Postgresql, вы можете сгенерировать приведение для каждого значения вашего вектора в HugSQL, используя выражение Clojure:

-- :name x 
-- :require [clojure.string :as string]
select * from test where id in (
/*~
(clojure.string/join 
  ","
  (map-indexed (fn [i v] (str ":values." i "::int")) (:values params)))
~*/
)

Что в итоге даст вам что-то вроде этого:

(x-sqlvec {:values ["1" "2"]})
;=> ["select * from test where id in (?::int,?::int)" "1" "2"]

Таким образом, вышеприведенное берет вектор значений и использует синтаксис глубокого получения HugSQL для извлечения каждого из значений в отдельности и добавления приведения типов к каждому из них. Итак, вы эффективно создаете новый набор параметров HugSQL на лету, который выглядит следующим образом:

in (:values.0::int, :values.1::int, :values.2::int)

Другие вопросы по тегам