Allow single kw in :order-by and other clauses

This commit is contained in:
Eugene Pakhomov 2023-02-26 14:20:09 +02:00
parent de0adf56ef
commit 3fba12fbcc
5 changed files with 27 additions and 9 deletions

View file

@ -209,6 +209,9 @@
{:symbol x
:failure (str t)})))))
(defn- ensure-sequential [xs]
(if (sequential? xs) xs [xs]))
(defn format-entity
"Given a simple SQL entity (a keyword or symbol -- or string),
return the equivalent SQL fragment (as a string -- no parameters).
@ -549,7 +552,7 @@
(-> [sql'] (into params) (into params'))))
(defn- format-select-into [k xs]
(let [[v e] (if (sequential? xs) xs [xs])
(let [[v e] (ensure-sequential xs)
[sql & params] (when e (format-expr e))]
(into [(str (sql-kw k) " " (format-entity v)
(when sql
@ -708,11 +711,12 @@
[]))
(defn- format-group-by [k xs]
(let [[sqls params] (format-expr-list xs)]
(let [[sqls params] (format-expr-list (ensure-sequential xs))]
(into [(str (sql-kw k) " " (str/join ", " sqls))] params)))
(defn- format-order-by [k xs]
(let [dirs (map #(when (sequential? %) (second %)) xs)
(let [xs (ensure-sequential xs)
dirs (map #(when (sequential? %) (second %)) xs)
[sqls params]
(format-expr-list (map #(if (sequential? %) (first %) %) xs))]
(into [(str (sql-kw k) " "
@ -722,7 +726,7 @@
dirs)))] params)))
(defn- format-lock-strength [k xs]
(let [[strength tables nowait] (if (sequential? xs) xs [xs])]
(let [[strength tables nowait] (ensure-sequential xs)]
[(str (sql-kw k) " " (sql-kw strength)
(when tables
(str
@ -946,7 +950,7 @@
(format-ddl-options opts context)))))
(defn- format-truncate [k xs]
(let [[table & options] (if (sequential? xs) xs [xs])
(let [[table & options] (ensure-sequential xs)
[pre table ine options] (destructure-ddl-item [table options] "truncate")]
(when (seq pre) (throw (ex-info "TRUNCATE syntax error" {:unexpected pre})))
(when (seq ine) (throw (ex-info "TRUNCATE syntax error" {:unexpected ine})))

View file

@ -51,7 +51,11 @@
;; implementation helpers:
(defn- default-merge [current args]
(c/into (vec current) args))
(let [current (cond
(nil? current) []
(sequential? current) (vec current)
:else [current])]
(c/into current args)))
(defn- sym->kw
"Given a symbol, produce a keyword, retaining the namespace

View file

@ -144,14 +144,14 @@
(deftest select-top-tests
(testing "Basic TOP syntax"
(is (= ["SELECT TOP(?) foo FROM bar ORDER BY quux ASC" 10]
(sql/format {:select-top [10 :foo] :from :bar :order-by [:quux]})))
(sql/format {:select-top [10 :foo] :from :bar :order-by :quux})))
(is (= ["SELECT TOP(?) foo FROM bar ORDER BY quux ASC" 10]
(sql/format (-> (select-top 10 :foo)
(from :bar)
(order-by :quux))))))
(testing "Expanded TOP syntax"
(is (= ["SELECT TOP(?) PERCENT WITH TIES foo, baz FROM bar ORDER BY quux ASC" 10]
(sql/format {:select-top [[10 :percent :with-ties] :foo :baz] :from :bar :order-by [:quux]})))
(sql/format {:select-top [[10 :percent :with-ties] :foo :baz] :from :bar :order-by :quux})))
(is (= ["SELECT TOP(?) PERCENT WITH TIES foo, baz FROM bar ORDER BY quux ASC" 10]
(sql/format (-> (select-top [10 :percent :with-ties] :foo :baz)
(from :bar)
@ -865,7 +865,7 @@
[[:filter ; two pairs -- alias is on last pair
[:avg :x [:order-by :y [:a :desc]]] {:where [:< :i 10]}
[:sum :q] {:where [:= :x nil]}] :b]
[[:within-group [:foo :y] {:order-by [:x]}]]]})
[[:within-group [:foo :y] {:order-by :x}]]]})
[(str "SELECT COUNT(*) FILTER (WHERE i > ?) AS a,"
" AVG(x, y ORDER BY a DESC) FILTER (WHERE i < ?),"
" SUM(q) FILTER (WHERE x IS NULL) AS b,"

View file

@ -255,6 +255,12 @@
(sql/format)))))
(deftest over-test
(testing "simple window statement"
(is (= ["SELECT AVG(salary) OVER w FROM employee WINDOW w AS (PARTITION BY department ORDER BY salary ASC)"]
(sql/format {:select [[[:over [[:avg :salary] :w]]]]
:from :employee
:window [:w {:partition-by :department
:order-by :salary}]}))))
(testing "window function over on select statemt"
(is (= ["SELECT id, AVG(salary) OVER (PARTITION BY department ORDER BY designation ASC) AS Average, MAX(salary) OVER w AS MaxSalary FROM employee WINDOW w AS (PARTITION BY department)"]
;; honeysql treats over as a function:

View file

@ -83,10 +83,14 @@
(sut/format {:select [:*] :from [:table] :where (sut/map= {:id 1})} {:quoted true})))
(is (= ["SELECT \"t\".* FROM \"table\" AS \"t\" WHERE \"id\" = ?" 1]
(sut/format {:select [:t.*] :from [[:table :t]] :where [:= :id 1]} {:quoted true})))
(is (= ["SELECT * FROM \"table\" GROUP BY \"foo\""]
(sut/format {:select [:*] :from [:table] :group-by :foo} {:quoted true})))
(is (= ["SELECT * FROM \"table\" GROUP BY \"foo\", \"bar\""]
(sut/format {:select [:*] :from [:table] :group-by [:foo :bar]} {:quoted true})))
(is (= ["SELECT * FROM \"table\" GROUP BY DATE(\"bar\")"]
(sut/format {:select [:*] :from [:table] :group-by [[:date :bar]]} {:quoted true})))
(is (= ["SELECT * FROM \"table\" ORDER BY \"foo\" ASC"]
(sut/format {:select [:*] :from [:table] :order-by :foo} {:quoted true})))
(is (= ["SELECT * FROM \"table\" ORDER BY \"foo\" DESC, \"bar\" ASC"]
(sut/format {:select [:*] :from [:table] :order-by [[:foo :desc] :bar]} {:quoted true})))
(is (= ["SELECT * FROM \"table\" ORDER BY DATE(\"expiry\") DESC, \"bar\" ASC"]