diff --git a/CHANGELOG.md b/CHANGELOG.md index 11caa9c..ced81b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changes * 2.6.next in progress + * Address [#529](https://github.com/seancorfield/honeysql/issues/529) by fixing `:join` special syntax to support aliases and to handle expressions the same way `select` / `from` etc handle them (extra `[...]` nesting). * Address [#527](https://github.com/seancorfield/honeysql/issues/527) by adding tests and more documentation for `:composite`. * Add example of mixed `DO UPDATE SET` with `EXCLUDED` and regular SQL expressions. * Improve exception message when un-`lift`-ed JSON expressions are used in the DSL. diff --git a/doc/special-syntax.md b/doc/special-syntax.md index c910e52..8e5378b 100644 --- a/doc/special-syntax.md +++ b/doc/special-syntax.md @@ -369,6 +369,20 @@ a `JOIN` clause. ;;=> ["INNER JOIN (tbl1 LEFT JOIN tbl2 USING (id))"] ``` +An alias can be provided: + +```clojure +(sql/format {:join [[[:join [:tbl1 :t] {:left-join [:tbl2 [:using :id]]}]]]}) +;;=> ["INNER JOIN (tbl1 AS t LEFT JOIN tbl2 USING (id))"] +``` + +To provide an expression, an extra level of `[...]` is needed: + +```clojure +(sql/format {:join [[[:join [[:make_thing 42] :t] {:left-join [:tbl2 [:using :id]]}]]]}) +;;=> ["INNER JOIN (MAKE_THING(?) AS t LEFT JOIN tbl2 USING (id))" 42] +``` + ## lateral Accepts a single argument that can be a (`SELECT`) clause or diff --git a/src/honey/sql.cljc b/src/honey/sql.cljc index d528fe6..95af3ee 100644 --- a/src/honey/sql.cljc +++ b/src/honey/sql.cljc @@ -1839,7 +1839,7 @@ :interval format-interval :join (fn [_ [e & js]] - (let [[sqls params] (reduce-sql (cons (format-expr e) + (let [[sqls params] (reduce-sql (cons (format-selectable-dsl e {:as true}) (map format-dsl js)))] (into [(str "(" (str/join " " sqls) ")")] params))) :lateral diff --git a/test/honey/sql/helpers_test.cljc b/test/honey/sql/helpers_test.cljc index b551a6e..b48d153 100644 --- a/test/honey/sql/helpers_test.cljc +++ b/test/honey/sql/helpers_test.cljc @@ -1,4 +1,4 @@ -;; copyright (c) 2020-2022 sean corfield, all rights reserved +;; copyright (c) 2020-2024 sean corfield, all rights reserved (ns honey.sql.helpers-test (:refer-clojure :exclude [filter for group-by partition-by set update]) @@ -981,3 +981,14 @@ (sql/format (create-index [:unique :my-column-idx :if-not-exists] [:my-table :my-column])))) (is (= ["CREATE INDEX my_column_idx ON my_table (LOWER(my_column))"] (sql/format (create-index :my-column-idx [:my-table :%lower.my-column])))))) + +(deftest join-with-alias + (is (= ["SELECT * FROM foo LEFT JOIN (populatons AS pm INNER JOIN customers AS pc ON (pm.id = pc.id) AND (pm.other_id = pc.other_id)) ON foo.fk_id = pm.id"] + (sql/format {:select :* + :from :foo + :left-join [[[:join [:populatons :pm] + {:join [[:customers :pc] + [:and + [:= :pm/id :pc/id] + [:= :pm/other-id :pc/other-id]]]}]] + [:= :foo/fk-id :pm/id]]}))))