Skip to content

Commit

Permalink
fix #527 by adding tests for composite and documenting its use in mor…
Browse files Browse the repository at this point in the history
…e detail

both from clause and composite special syntax have examples now

Signed-off-by: Sean Corfield <[email protected]>
  • Loading branch information
seancorfield committed Mar 29, 2024
1 parent 04e7e5b commit f69ee7e
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 1 deletion.
11 changes: 11 additions & 0 deletions doc/clause-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
17 changes: 17 additions & 0 deletions doc/special-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `:
Expand Down
2 changes: 1 addition & 1 deletion src/honey/sql.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -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))))
Expand Down
16 changes: 16 additions & 0 deletions test/honey/sql_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -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}))
)

0 comments on commit f69ee7e

Please sign in to comment.