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
|
simple table name (keyword or symbol) or a pair of a
|
||||||
table name and an alias.
|
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)
|
clause (see [PostgreSQL DELETE statement](https://www.postgresql.org/docs/12/sql-delete.html)
|
||||||
for more detail).
|
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"]
|
["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
|
||||||
|
|
||||||
`:cross-join` accepts a single sequence argument that lists
|
`: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).
|
> 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
|
## lateral
|
||||||
|
|
||||||
Accepts a single argument that can be a (`SELECT`) clause or
|
Accepts a single argument that can be a (`SELECT`) clause or
|
||||||
|
|
|
||||||
|
|
@ -1170,3 +1170,28 @@ ORDER BY id = ? DESC
|
||||||
(sut/format [:raw "@foo := " [42]])))
|
(sut/format [:raw "@foo := " [42]])))
|
||||||
(is (= ["@foo := MYFUNC(?)" 42]
|
(is (= ["@foo := MYFUNC(?)" 42]
|
||||||
(sut/format [:raw "@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