Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Allow single kw in :order-by and other clauses #470

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/honey/sql.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) " "
Expand All @@ -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
Expand Down Expand Up @@ -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})))
Expand Down
6 changes: 5 additions & 1 deletion src/honey/sql/helpers.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions test/honey/sql/helpers_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,"
Expand Down
6 changes: 6 additions & 0 deletions test/honey/sql/postgres_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 4 additions & 0 deletions test/honey/sql_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down