fix #527 by adding tests for composite and documenting its use in more detail

both from clause and composite special syntax have examples now

Signed-off-by: Sean Corfield <sean@corfield.org>
This commit is contained in:
Sean Corfield 2024-03-29 15:15:12 -07:00
parent 04e7e5b3ab
commit f69ee7e8de
No known key found for this signature in database
4 changed files with 45 additions and 1 deletions

View file

@ -815,6 +815,17 @@ user=> (sql/format {:select [:u.username :s.name]
["SELECT u.username, s.name FROM user AS u, status AS s WHERE (u.statusid = s.id) AND (u.id = ?)" 9]
```
`:from` can also accept a `:values` clause:
```clojure
user=> (sql/format {:update :table :set {:a :v.a}
:from [[{:values [[1 2 3]
[4 5 6]]}
[:v [:composite :a :b :c]]]]
:where [:and [:= :x :v.b] [:> :y :v.c]]})
["UPDATE table SET a = v.a FROM (VALUES (?, ?, ?), (?, ?, ?)) AS v (a, b, c) WHERE (x = v.b) AND (y > v.c)" 1 2 3 4 5 6]
```
As of 2.4.1066, HoneySQL supports a temporal clause that starts with `:for`,
followed by the time reference
(e.g., `:system-time` or `:business-time`), followed by a temporal qualifier,

View file

@ -174,6 +174,23 @@ expression (comma-separated, wrapped in parentheses):
;;=> ["(a, b, ?, x + ?)" "red" 1]
```
This can be useful in a number of situations where you want a composite
value, as above, or a composite based on or declaring columns names:
```clojure
(sql/format {:select [[[:composite :a :b] :c]] :from :table})
;;=> ["SELECT (a, b) AS c FROM table"]
```
```clojure
(sql/format {:update :table :set {:a :v.a}
:from [[{:values [[1 2 3]
[4 5 6]]}
[:v [:composite :a :b :c]]]]
:where [:and [:= :x :v.b] [:> :y :v.c]]})
;;=> ["UPDATE table FROM (VALUES (?, ?, ?), (?, ?, ?)) AS v (a, b, c) SET a = v.a WHERE (x = v.b) AND (y > v.c)" 1 2 3 4 5 6]
```
## distinct
Accepts a single expression and prefixes it with `DISTINCT `:

View file

@ -341,7 +341,7 @@
(when k
(let [n (str/replace (name k) "?" "??")]
(if (= \' (first n))
(let [ident (subs n 1 (count n))
(let [ident (subs n 1)
ident-l (str/lower-case ident)]
(binding [*quoted* (when-not (contains? #{"array"} ident-l) *quoted*)]
(format-entity (keyword ident))))

View file

@ -1341,10 +1341,26 @@ ORDER BY id = ? DESC
(= ["SELECT * FROM table WITH (DEF, ABC)"]
(sut/format {:select [:*] :from [^{:abc true :def true} [:table]]}))))))
(deftest issue-527-composite
(is (= ["SELECT (a, b) AS c FROM table"]
(sut/format {:select [[[:composite :a :b] :c]] :from [:table]})))
(is (= ["SELECT a FROM table WHERE (b, c) = (?, ?)" 1 2]
(sut/format {:select :a :from :table :where [:= [:composite :b :c] [:composite 1 2]]})))
(is (= ["SELECT a, b, c FROM (VALUES (?, ?, ?), (?, ?, ?)) AS t (a, b, c)" 1 2 3 4 5 6]
(sut/format {:select [:a :b :c]
:from [[{:values [[1 2 3] [4 5 6]]}
[:t [:composite :a :b :c]]]]}))))
(comment
;; partial (incorrect!) workaround for #407:
(sut/format {:select :f.* :from [[:foo [:f :for :system-time]]] :where [:= :f.id 1]})
;; correct version:
(sut/format {:select :f.* :from [[:foo :f :for :system-time]] :where [:= :f.id 1]})
(sut/format {:where [:= :x [:inline :DATE "2019-01-01"]]})
;; https://github.com/seancorfield/honeysql/issues/526
(->
{:create-table-as [:a-b.b-c.c-d]
:select [:*]
:from [:a-b.b-c.c-d]}
(sut/format {:dialect :nrql}))
)