Merge pull request #470 from p-himik/467-allow-scalar-order-by-et-al
Allow single kw in :order-by and other clauses
This commit is contained in:
commit
fc3397650e
5 changed files with 27 additions and 9 deletions
|
|
@ -209,6 +209,9 @@
|
||||||
{:symbol x
|
{:symbol x
|
||||||
:failure (str t)})))))
|
:failure (str t)})))))
|
||||||
|
|
||||||
|
(defn- ensure-sequential [xs]
|
||||||
|
(if (sequential? xs) xs [xs]))
|
||||||
|
|
||||||
(defn format-entity
|
(defn format-entity
|
||||||
"Given a simple SQL entity (a keyword or symbol -- or string),
|
"Given a simple SQL entity (a keyword or symbol -- or string),
|
||||||
return the equivalent SQL fragment (as a string -- no parameters).
|
return the equivalent SQL fragment (as a string -- no parameters).
|
||||||
|
|
@ -549,7 +552,7 @@
|
||||||
(-> [sql'] (into params) (into params'))))
|
(-> [sql'] (into params) (into params'))))
|
||||||
|
|
||||||
(defn- format-select-into [k xs]
|
(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))]
|
[sql & params] (when e (format-expr e))]
|
||||||
(into [(str (sql-kw k) " " (format-entity v)
|
(into [(str (sql-kw k) " " (format-entity v)
|
||||||
(when sql
|
(when sql
|
||||||
|
|
@ -708,11 +711,12 @@
|
||||||
[]))
|
[]))
|
||||||
|
|
||||||
(defn- format-group-by [k xs]
|
(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)))
|
(into [(str (sql-kw k) " " (str/join ", " sqls))] params)))
|
||||||
|
|
||||||
(defn- format-order-by [k xs]
|
(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]
|
[sqls params]
|
||||||
(format-expr-list (map #(if (sequential? %) (first %) %) xs))]
|
(format-expr-list (map #(if (sequential? %) (first %) %) xs))]
|
||||||
(into [(str (sql-kw k) " "
|
(into [(str (sql-kw k) " "
|
||||||
|
|
@ -722,7 +726,7 @@
|
||||||
dirs)))] params)))
|
dirs)))] params)))
|
||||||
|
|
||||||
(defn- format-lock-strength [k xs]
|
(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)
|
[(str (sql-kw k) " " (sql-kw strength)
|
||||||
(when tables
|
(when tables
|
||||||
(str
|
(str
|
||||||
|
|
@ -946,7 +950,7 @@
|
||||||
(format-ddl-options opts context)))))
|
(format-ddl-options opts context)))))
|
||||||
|
|
||||||
(defn- format-truncate [k xs]
|
(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")]
|
[pre table ine options] (destructure-ddl-item [table options] "truncate")]
|
||||||
(when (seq pre) (throw (ex-info "TRUNCATE syntax error" {:unexpected pre})))
|
(when (seq pre) (throw (ex-info "TRUNCATE syntax error" {:unexpected pre})))
|
||||||
(when (seq ine) (throw (ex-info "TRUNCATE syntax error" {:unexpected ine})))
|
(when (seq ine) (throw (ex-info "TRUNCATE syntax error" {:unexpected ine})))
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,11 @@
|
||||||
;; implementation helpers:
|
;; implementation helpers:
|
||||||
|
|
||||||
(defn- default-merge [current args]
|
(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
|
(defn- sym->kw
|
||||||
"Given a symbol, produce a keyword, retaining the namespace
|
"Given a symbol, produce a keyword, retaining the namespace
|
||||||
|
|
|
||||||
|
|
@ -144,14 +144,14 @@
|
||||||
(deftest select-top-tests
|
(deftest select-top-tests
|
||||||
(testing "Basic TOP syntax"
|
(testing "Basic TOP syntax"
|
||||||
(is (= ["SELECT TOP(?) foo FROM bar ORDER BY quux ASC" 10]
|
(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]
|
(is (= ["SELECT TOP(?) foo FROM bar ORDER BY quux ASC" 10]
|
||||||
(sql/format (-> (select-top 10 :foo)
|
(sql/format (-> (select-top 10 :foo)
|
||||||
(from :bar)
|
(from :bar)
|
||||||
(order-by :quux))))))
|
(order-by :quux))))))
|
||||||
(testing "Expanded TOP syntax"
|
(testing "Expanded TOP syntax"
|
||||||
(is (= ["SELECT TOP(?) PERCENT WITH TIES foo, baz FROM bar ORDER BY quux ASC" 10]
|
(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]
|
(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)
|
(sql/format (-> (select-top [10 :percent :with-ties] :foo :baz)
|
||||||
(from :bar)
|
(from :bar)
|
||||||
|
|
@ -865,7 +865,7 @@
|
||||||
[[:filter ; two pairs -- alias is on last pair
|
[[:filter ; two pairs -- alias is on last pair
|
||||||
[:avg :x [:order-by :y [:a :desc]]] {:where [:< :i 10]}
|
[:avg :x [:order-by :y [:a :desc]]] {:where [:< :i 10]}
|
||||||
[:sum :q] {:where [:= :x nil]}] :b]
|
[: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,"
|
[(str "SELECT COUNT(*) FILTER (WHERE i > ?) AS a,"
|
||||||
" AVG(x, y ORDER BY a DESC) FILTER (WHERE i < ?),"
|
" AVG(x, y ORDER BY a DESC) FILTER (WHERE i < ?),"
|
||||||
" SUM(q) FILTER (WHERE x IS NULL) AS b,"
|
" SUM(q) FILTER (WHERE x IS NULL) AS b,"
|
||||||
|
|
|
||||||
|
|
@ -255,6 +255,12 @@
|
||||||
(sql/format)))))
|
(sql/format)))))
|
||||||
|
|
||||||
(deftest over-test
|
(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"
|
(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)"]
|
(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:
|
;; honeysql treats over as a function:
|
||||||
|
|
|
||||||
|
|
@ -83,10 +83,14 @@
|
||||||
(sut/format {:select [:*] :from [:table] :where (sut/map= {:id 1})} {:quoted true})))
|
(sut/format {:select [:*] :from [:table] :where (sut/map= {:id 1})} {:quoted true})))
|
||||||
(is (= ["SELECT \"t\".* FROM \"table\" AS \"t\" WHERE \"id\" = ?" 1]
|
(is (= ["SELECT \"t\".* FROM \"table\" AS \"t\" WHERE \"id\" = ?" 1]
|
||||||
(sut/format {:select [:t.*] :from [[:table :t]] :where [:= :id 1]} {:quoted true})))
|
(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\""]
|
(is (= ["SELECT * FROM \"table\" GROUP BY \"foo\", \"bar\""]
|
||||||
(sut/format {:select [:*] :from [:table] :group-by [:foo :bar]} {:quoted true})))
|
(sut/format {:select [:*] :from [:table] :group-by [:foo :bar]} {:quoted true})))
|
||||||
(is (= ["SELECT * FROM \"table\" GROUP BY DATE(\"bar\")"]
|
(is (= ["SELECT * FROM \"table\" GROUP BY DATE(\"bar\")"]
|
||||||
(sut/format {:select [:*] :from [:table] :group-by [[:date :bar]]} {:quoted true})))
|
(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"]
|
(is (= ["SELECT * FROM \"table\" ORDER BY \"foo\" DESC, \"bar\" ASC"]
|
||||||
(sut/format {:select [:*] :from [:table] :order-by [[:foo :desc] :bar]} {:quoted true})))
|
(sut/format {:select [:*] :from [:table] :order-by [[:foo :desc] :bar]} {:quoted true})))
|
||||||
(is (= ["SELECT * FROM \"table\" ORDER BY DATE(\"expiry\") DESC, \"bar\" ASC"]
|
(is (= ["SELECT * FROM \"table\" ORDER BY DATE(\"expiry\") DESC, \"bar\" ASC"]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue