address #483 by adding tests & docs for :join
This commit is contained in:
parent
858d157863
commit
8cbb7f3834
3 changed files with 40 additions and 1 deletions
|
|
@ -700,7 +700,7 @@ one or more SQL entities. Each entity can either be a
|
|||
simple table name (keyword or symbol) or a pair of a
|
||||
table name and an alias.
|
||||
|
||||
`:using` is intended to be used as a simple join with a `:delete-from`
|
||||
`:using` is intended to be used as a simple join, for example with a `:delete-from`
|
||||
clause (see [PostgreSQL DELETE statement](https://www.postgresql.org/docs/12/sql-delete.html)
|
||||
for more detail).
|
||||
|
||||
|
|
@ -778,6 +778,9 @@ user=> (sql/format {:select [:t.ref :pp.code]
|
|||
["SELECT t.ref, pp.code FROM transaction AS t LEFT JOIN paypal_tx AS pp USING (id) WHERE ? = pp.status" "settled"]
|
||||
```
|
||||
|
||||
See also the [`:join` special syntax](https://cljdoc.org/d/com.github.seancorfield/honeysql/CURRENT/doc/getting-started/sql-special-syntax-#join)
|
||||
for nested `JOIN` expressions.
|
||||
|
||||
## cross-join
|
||||
|
||||
`:cross-join` accepts a single sequence argument that lists
|
||||
|
|
|
|||
|
|
@ -220,6 +220,17 @@ that represents a time unit. Produces an `INTERVAL` expression:
|
|||
|
||||
> Note: PostgreSQL has an `INTERVAL` data type which is unrelated to this syntax. In PostgreSQL, the closet equivalent would be `[:cast "30 days" :interval]` which will lift `"30 days"` out as a parameter. In DDL, for PostgreSQL, you can use `:interval` to produce the `INTERVAL` data type (without wrapping it in a vector).
|
||||
|
||||
## join
|
||||
|
||||
Accepts a table name (or expression) followed by one or more join clauses.
|
||||
Produces a nested `JOIN` expression, typically used as the table expression of
|
||||
a `JOIN` clause.
|
||||
|
||||
```clojure
|
||||
(sql/format {:join [[[:join :tbl1 {:left-join [:tbl2 [:using :id]]}]]]})
|
||||
;;=> ["INNER JOIN (tbl1 LEFT JOIN tbl2 USING (id))"]
|
||||
```
|
||||
|
||||
## lateral
|
||||
|
||||
Accepts a single argument that can be a (`SELECT`) clause or
|
||||
|
|
|
|||
|
|
@ -1170,3 +1170,28 @@ ORDER BY id = ? DESC
|
|||
(sut/format [:raw "@foo := " [42]])))
|
||||
(is (= ["@foo := MYFUNC(?)" 42]
|
||||
(sut/format [:raw "@foo := " [:myfunc 42]])))))
|
||||
|
||||
(deftest issue-483-join
|
||||
(testing "single nested join"
|
||||
(is (= ["SELECT * FROM tbl1 LEFT JOIN (tbl2 INNER JOIN tbl3 USING (common_column)) ON (tbl2.col2 = tbl1.col2) AND (tbl3.col3 = tbl1.col3)"]
|
||||
(-> {:select :*
|
||||
:from :tbl1
|
||||
:left-join [[[:join :tbl2 {:join [:tbl3 [:using [:common_column]]]}]]
|
||||
[:and
|
||||
[:= :tbl2.col2 :tbl1.col2]
|
||||
[:= :tbl3.col3 :tbl1.col3]]]}
|
||||
(sut/format)))))
|
||||
(testing "multiple nested join"
|
||||
(is (= ["SELECT * FROM tbl1 LEFT JOIN (tbl2 INNER JOIN tbl3 USING (common_column) RIGHT JOIN tbl4 USING (id)) ON (tbl2.col2 = tbl1.col2) AND (tbl3.col3 = tbl1.col3)"]
|
||||
(-> {:select :*
|
||||
:from :tbl1
|
||||
:left-join [[[:join :tbl2
|
||||
{:join [:tbl3 [:using [:common_column]]]}
|
||||
{:right-join [:tbl4 [:using :id]]}]]
|
||||
[:and
|
||||
[:= :tbl2.col2 :tbl1.col2]
|
||||
[:= :tbl3.col3 :tbl1.col3]]]}
|
||||
(sut/format)))))
|
||||
(testing "special syntax example"
|
||||
(is (= ["INNER JOIN (tbl1 LEFT JOIN tbl2 USING (id))"]
|
||||
(sut/format {:join [[[:join :tbl1 {:left-join [:tbl2 [:using :id]]}]]]})))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue