Add optional type argument to the :array special

This commit is contained in:
Eugene Pakhomov 2023-02-26 12:59:53 +02:00
parent de0adf56ef
commit 0c7642a357
3 changed files with 17 additions and 7 deletions

View file

@ -8,15 +8,19 @@ The first group are used for SQL expressions. The second (last group) are used p
## array ## array
Accepts a single argument, which is expected to evaluate to Accepts a single argument, which is expected to evaluate to a sequence,
a sequence, and produces `ARRAY[?, ?, ..]` for the elements with an optional second argument specifying the type of the array,
of that sequence (as SQL parameters): and produces `ARRAY[?, ?, ..]` for the elements of that sequence (as SQL parameters):
```clojure ```clojure
(require '[honey.sql :as sql]) (require '[honey.sql :as sql])
(sql/format-expr [:array (range 5)]) (sql/format-expr [:array (range 5)])
;;=> ["ARRAY[?, ?, ?, ?, ?]" 0 1 2 3 4] ;;=> ["ARRAY[?, ?, ?, ?, ?]" 0 1 2 3 4]
(sql/format-expr [:array (range 3) :text])
;;=> ["ARRAY[?, ?, ?]::TEXT[]" 0 1 2]
(sql/format-expr [:array [] :integer])
;;=> ["ARRAY[]::INTEGER[]"]
``` ```
> Note: you cannot provide a named parameter as the argument for `:array` because the generated SQL depends on the number of elements in the sequence, so the following throws an exception: > Note: you cannot provide a named parameter as the argument for `:array` because the generated SQL depends on the number of elements in the sequence, so the following throws an exception:

View file

@ -1437,10 +1437,11 @@
(str/join ", " (map format-single-column spec)) (str/join ", " (map format-single-column spec))
">")]) ">")])
:array :array
(fn [_ [arr]] (fn [_ [arr type]]
;; allow for (unwrap arr) here? ;; allow for (unwrap arr) here?
(let [[sqls params] (format-expr-list arr)] (let [[sqls params] (format-expr-list arr)
(into [(str "ARRAY[" (str/join ", " sqls) "]")] params))) type-str (when type (str "::" (sql-kw type) "[]"))]
(into [(str "ARRAY[" (str/join ", " sqls) "]" type-str)] params)))
:between :between
(fn [_ [x a b]] (fn [_ [x a b]]
(let [[sql-x & params-x] (format-expr x {:nested true}) (let [[sql-x & params-x] (format-expr x {:nested true})

View file

@ -278,7 +278,12 @@
:columns [:baz] :columns [:baz]
:values [[[:array :?vals]]]} :values [[[:array :?vals]]]}
{:params {:vals [1 2 3 4]}}) {:params {:vals [1 2 3 4]}})
["INSERT INTO foo (baz) VALUES (ARRAY[?, ?, ?, ?])" 1 2 3 4]))) ["INSERT INTO foo (baz) VALUES (ARRAY[?, ?, ?, ?])" 1 2 3 4]))
(testing "typed array"
(is (= (format {:select [[[:array [] :integer]]]})
["SELECT ARRAY[]::INTEGER[]"]))
(is (= (format {:select [[[:array [1 2] :text]]]})
["SELECT ARRAY[?, ?]::TEXT[]" 1 2]))))
(deftest union-test (deftest union-test
;; UNION and INTERSECT subexpressions should not be parenthesized. ;; UNION and INTERSECT subexpressions should not be parenthesized.