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
Accepts a single argument, which is expected to evaluate to
a sequence, and produces `ARRAY[?, ?, ..]` for the elements
of that sequence (as SQL parameters):
Accepts a single argument, which is expected to evaluate to a sequence,
with an optional second argument specifying the type of the array,
and produces `ARRAY[?, ?, ..]` for the elements of that sequence (as SQL parameters):
```clojure
(require '[honey.sql :as sql])
(sql/format-expr [:array (range 5)])
;;=> ["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:

View file

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

View file

@ -278,7 +278,12 @@
:columns [:baz]
:values [[[:array :?vals]]]}
{: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
;; UNION and INTERSECT subexpressions should not be parenthesized.