Skip to content

Commit 8722e61

Browse files
committed
1 parent 0b4fd6e commit 8722e61

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

src/honeysql_postgres/format.cljc

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131

3232
(def ^:private postgres-clause-priorities
3333
"Determines the order that clauses will be placed within generated SQL"
34-
(merge {:with 30
34+
(merge {:explain 20
35+
:with 30
3536
:with-recursive 40
3637
:except 45
3738
:except-all 45
@@ -297,3 +298,33 @@
297298
(-> extension-name
298299
util/get-first
299300
sqlf/to-sql)))
301+
302+
(defmethod format-clause :explain [[_ [params]] _]
303+
(if (empty? params)
304+
"EXPLAIN"
305+
(let [params-string-map
306+
{:costs "COSTS"
307+
:settings "SETTINGS"
308+
:buffers "BUFFERS"
309+
:wal "WAL"
310+
:timing "TIMING"
311+
:summary "SUMMARY"}
312+
313+
format-string-map
314+
{:text "TEXT"
315+
:xml "XML"
316+
:json "JSON"
317+
:yaml "YAML"}
318+
319+
->param-string
320+
(fn [[k v]]
321+
(case k
322+
:analyze "ANALYZE"
323+
:verbose "VERBOSE"
324+
:format (sqlf/paren-wrap (str "FORMAT" " " (format-string-map v)))
325+
(when-let [param-name (params-string-map k)]
326+
(sqlf/paren-wrap
327+
(sqlf/space-join [param-name (if (true? v) "TRUE" "FALSE")])))))]
328+
329+
(sqlf/space-join ["EXPLAIN"
330+
(sqlf/space-join (map ->param-string params))]))))

src/honeysql_postgres/helpers.cljc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,6 @@
8383

8484
(defhelper drop-extension [m extension-name]
8585
(assoc m :drop-extension (sqlh/collify extension-name)))
86+
87+
(defhelper explain [m args]
88+
(assoc m :explain args))

test/honeysql_postgres/postgres_test.cljc

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
drop-column
1919
drop-extension
2020
drop-table
21+
explain
2122
filter
2223
insert-into-as
2324
on-conflict
@@ -354,6 +355,7 @@
354355
(within-group [(sql/call :percentile_disc (hsql-types/array [0.25 0.5 0.75])) (order-by :s.i) :alias])
355356
(from (sql/raw "generate_series(1,10) AS s(i)"))
356357
(sql/format)))))
358+
357359
(deftest create-extension-test
358360
(testing "create extension"
359361
(is (= ["CREATE EXTENSION \"uuid-ossp\""]
@@ -372,3 +374,55 @@
372374
(-> (drop-extension :uuid-ossp)
373375
(sql/format :allow-dashed-names? true
374376
:quoting :ansi))))))
377+
378+
(deftest explain-test
379+
(let [query (-> (select :*)
380+
(from :products))]
381+
(testing "EXPLAIN without any arguments"
382+
(is (= ["EXPLAIN SELECT * FROM products"]
383+
(-> query (explain) (sql/format)))))
384+
(testing "Explain with analyze"
385+
(is (= ["EXPLAIN ANALYZE SELECT * FROM products"]
386+
(-> query (explain {:analyze true}) (sql/format)))))
387+
(testing "Explain with analyze verbose"
388+
(is (= ["EXPLAIN ANALYZE VERBOSE SELECT * FROM products"]
389+
(-> query (explain {:analyze true :verbose true}) (sql/format)))))
390+
(testing "Explain with costs"
391+
(is (= ["EXPLAIN (COSTS TRUE) SELECT * FROM products"]
392+
(-> query (explain {:costs true}) (sql/format))))
393+
(is (= ["EXPLAIN (COSTS FALSE) SELECT * FROM products"]
394+
(-> query (explain {:costs false}) (sql/format)))))
395+
(testing "Explain with settings"
396+
(is (= ["EXPLAIN (SETTINGS TRUE) SELECT * FROM products"]
397+
(-> query (explain {:settings true}) (sql/format))))
398+
(is (= ["EXPLAIN (SETTINGS FALSE) SELECT * FROM products"]
399+
(-> query (explain {:settings false}) (sql/format)))))
400+
(testing "Explain with buffers"
401+
(is (= ["EXPLAIN (BUFFERS TRUE) SELECT * FROM products"]
402+
(-> query (explain {:buffers true}) (sql/format))))
403+
(is (= ["EXPLAIN (BUFFERS FALSE) SELECT * FROM products"]
404+
(-> query (explain {:buffers false}) (sql/format)))))
405+
(testing "Explain with wal"
406+
(is (= ["EXPLAIN (WAL TRUE) SELECT * FROM products"]
407+
(-> query (explain {:wal true}) (sql/format))))
408+
(is (= ["EXPLAIN (WAL FALSE) SELECT * FROM products"]
409+
(-> query (explain {:wal false}) (sql/format)))))
410+
(testing "Explain with timing"
411+
(is (= ["EXPLAIN (TIMING TRUE) SELECT * FROM products"]
412+
(-> query (explain {:timing true}) (sql/format))))
413+
(is (= ["EXPLAIN (TIMING FALSE) SELECT * FROM products"]
414+
(-> query (explain {:timing false}) (sql/format)))))
415+
(testing "Explain with summary"
416+
(is (= ["EXPLAIN (SUMMARY TRUE) SELECT * FROM products"]
417+
(-> query (explain {:summary true}) (sql/format))))
418+
(is (= ["EXPLAIN (SUMMARY FALSE) SELECT * FROM products"]
419+
(-> query (explain {:summary false}) (sql/format)))))
420+
(testing "Explain with format"
421+
(is (= ["EXPLAIN (FORMAT TEXT) SELECT * FROM products"]
422+
(-> query (explain {:format :text}) (sql/format))))
423+
(is (= ["EXPLAIN (FORMAT XML) SELECT * FROM products"]
424+
(-> query (explain {:format :xml}) (sql/format))))
425+
(is (= ["EXPLAIN (FORMAT JSON) SELECT * FROM products"]
426+
(-> query (explain {:format :json}) (sql/format))))
427+
(is (= ["EXPLAIN (FORMAT YAML) SELECT * FROM products"]
428+
(-> query (explain {:format :yaml}) (sql/format)))))))

0 commit comments

Comments
 (0)