Skip to content

Commit 1992d0e

Browse files
committed
add join-lateral && case-when clauses
1 parent 024a93a commit 1992d0e

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

src/honeysql_postgres/format.cljc

+39
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
:within-group 55
1818
:over 55
1919
:insert-into-as 60
20+
:join-lateral 153
21+
:left-join-lateral 154
2022
:partition-by 165
2123
:window 195
2224
:upsert 225
@@ -267,3 +269,40 @@
267269
(-> extension-name
268270
util/get-first
269271
sqlf/to-sql)))
272+
273+
(defn- format-join [type table pred]
274+
(str (when type
275+
(str (string/upper-case (name type)) " "))
276+
"JOIN LATERAL " (sqlf/to-sql table)
277+
(when (some? pred)
278+
(str " ON " (sqlf/format-predicate* pred)))))
279+
280+
(defn- make-join [type join-groups]
281+
(sqlf/space-join (map #(apply format-join type %)
282+
(partition 2 join-groups))))
283+
284+
(defmethod format-clause :join-lateral [[_ join-groups] _]
285+
(make-join :inner join-groups))
286+
287+
(defmethod format-clause :left-join-lateral [[_ join-groups] _]
288+
(make-join :left join-groups))
289+
290+
(defn- format-case-preds [pred-thens]
291+
(map (fn [[pred then]]
292+
(str "WHEN " (sqlf/format-predicate* pred)
293+
" THEN " (sqlf/to-sql then)))
294+
(partition 2 pred-thens)))
295+
296+
(defn- format-branches
297+
[branches]
298+
(str "CASE " (sqlf/space-join branches) " END"))
299+
300+
(defmethod format-clause :case-when
301+
[[_ pred-thens] _]
302+
(format-branches (format-case-preds pred-thens)))
303+
304+
(defmethod format-clause :case-when-else
305+
[[_ pred-thens] _]
306+
(let [else (last pred-thens)]
307+
(format-branches (concat (format-case-preds (drop-last pred-thens))
308+
[(str "ELSE " (sqlf/to-sql else))]))))

src/honeysql_postgres/helpers.cljc

+16
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,19 @@
8080

8181
(defhelper drop-extension [m extension-name]
8282
(assoc m :drop-extension (sqlh/collify extension-name)))
83+
84+
(defhelper join-lateral
85+
[m clauses]
86+
(assoc m :join-lateral clauses))
87+
88+
(defhelper left-join-lateral
89+
[m clauses]
90+
(assoc m :left-join-lateral clauses))
91+
92+
(defhelper case-when
93+
[m clauses]
94+
(assoc m :case-when clauses))
95+
96+
(defhelper case-when-else
97+
[m clauses]
98+
(assoc m :case-when-else clauses))

test/honeysql_postgres/postgres_test.cljc

+37
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
:refer
99
[add-column
1010
alter-table
11+
case-when
12+
case-when-else
1113
create-extension
1214
create-table
1315
create-view
@@ -19,6 +21,8 @@
1921
drop-table
2022
filter
2123
insert-into-as
24+
join-lateral
25+
left-join-lateral
2226
on-conflict
2327
on-conflict-constraint
2428
over
@@ -334,3 +338,36 @@
334338
(-> (drop-extension :uuid-ossp)
335339
(sql/format :allow-dashed-names? true
336340
:quoting :ansi))))))
341+
342+
(deftest case-when-test
343+
(is (= ["CASE WHEN x = 1 THEN x WHEN x > 1 THEN y END"]
344+
(-> (case-when [:= :x (sql/inline 1)] :x
345+
[:> :x (sql/inline 1)] :y)
346+
sql/format))))
347+
348+
(deftest case-when-else-test
349+
(is (= ["CASE WHEN x = 1 THEN x WHEN x > 1 THEN y ELSE z END"]
350+
(-> (case-when-else [:= :x (sql/inline 1)] :x
351+
[:> :x (sql/inline 1)] :y
352+
:z)
353+
sql/format))))
354+
355+
(deftest join-lateral-test
356+
(is (= ["SELECT count(x3), count(x0) FROM x_values INNER JOIN LATERAL (SELECT (CASE WHEN x > 3 THEN x END) AS x3, (CASE WHEN x > 0 THEN x END) AS x0) z ON true"]
357+
(-> (select :%count.x3
358+
:%count.x0)
359+
(from :x-values)
360+
(join-lateral [(select
361+
[(case-when [:> :x (sql/inline 3)] :x) :x3]
362+
[(case-when [:> :x (sql/inline 0)] :x) :x0]) :z] :true)
363+
sql/format))))
364+
365+
(deftest left-join-lateral-test
366+
(is (= ["SELECT count(x3), count(x0) FROM x_values LEFT JOIN LATERAL (SELECT (CASE WHEN x > 3 THEN x END) AS x3, (CASE WHEN x > 0 THEN x END) AS x0) z ON true"]
367+
(-> (select :%count.x3
368+
:%count.x0)
369+
(from :x-values)
370+
(left-join-lateral [(select
371+
[(case-when [:> :x (sql/inline 3)] :x) :x3]
372+
[(case-when [:> :x (sql/inline 0)] :x) :x0]) :z] :true)
373+
sql/format))))

0 commit comments

Comments
 (0)