From 6aee04e25c27c3e5b32c9a709793e23d9c334c32 Mon Sep 17 00:00:00 2001 From: Sean Corfield Date: Sun, 3 Oct 2021 22:18:12 -0700 Subject: [PATCH] fixes #365 --- CHANGELOG.md | 1 + README.md | 4 ++-- doc/clause-reference.md | 2 +- src/honey/sql.cljc | 2 +- test/honey/sql/postgres_test.cljc | 8 ++++---- test/honey/sql_test.cljc | 20 ++++++++++---------- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ffeb9d..feb9d15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * 2.0.next in progress * Fix #367 by supporting parameters in subexpressions around `IS NULL` / `IS NOT NULL` tests. + * Fix #365 -- a regression from 1.x -- where subclauses for `UNION`, `EXCEPT`, etc were incorrectly parenthesized. * Update `build-clj` to v0.5.0. * 2.0.813 -- 2021-09-25 diff --git a/README.md b/README.md index eeafa78..6942cee 100644 --- a/README.md +++ b/README.md @@ -471,7 +471,7 @@ Queries may be combined with a `:union`, `:union-all`, `:intersect` or `:except` ```clojure (sql/format {:union [(-> (select :*) (from :foo)) (-> (select :*) (from :bar))]}) -=> ["(SELECT * FROM foo) UNION (SELECT * FROM bar)"] +=> ["SELECT * FROM foo UNION SELECT * FROM bar"] ``` There are also helpers for each of those: @@ -479,7 +479,7 @@ There are also helpers for each of those: ```clojure (sql/format (union (-> (select :*) (from :foo)) (-> (select :*) (from :bar)))) -=> ["(SELECT * FROM foo) UNION (SELECT * FROM bar)"] +=> ["SELECT * FROM foo UNION SELECT * FROM bar"] ``` diff --git a/doc/clause-reference.md b/doc/clause-reference.md index 6468dd5..415c861 100644 --- a/doc/clause-reference.md +++ b/doc/clause-reference.md @@ -298,7 +298,7 @@ between those clauses. ```clojure user=> (sql/format '{union [{select (id,status) from (table-a)} {select (id,(event status) from (table-b))}]}) -["(SELECT id, status FROM table_a) UNION (SELECT id, event AS status, from, table_b)"] +["SELECT id, status FROM table_a UNION SELECT id, event AS status, from, table_b"] ``` ## select, select-distinct diff --git a/src/honey/sql.cljc b/src/honey/sql.cljc index 83b4101..8cf9240 100644 --- a/src/honey/sql.cljc +++ b/src/honey/sql.cljc @@ -338,7 +338,7 @@ (reduce (fn [[sql params] [sql' & params']] [(conj sql sql') (if params' (into params params') params)]) [[] []] - (map #(format-dsl % {:nested true}) xs))] + (map #(format-dsl %) xs))] (into [(str/join (str " " (sql-kw k) " ") sqls)] params))) (defn format-expr-list diff --git a/test/honey/sql/postgres_test.cljc b/test/honey/sql/postgres_test.cljc index ccbcb51..9649a66 100644 --- a/test/honey/sql/postgres_test.cljc +++ b/test/honey/sql/postgres_test.cljc @@ -319,7 +319,7 @@ (deftest values-except-select (testing "select which values are not not present in a table" - (is (= ["(VALUES (?), (?), (?)) EXCEPT (SELECT id FROM images)" 4 5 6] + (is (= ["VALUES (?), (?), (?) EXCEPT SELECT id FROM images" 4 5 6] (sql/format {:except [{:values [[4] [5] [6]]} @@ -327,7 +327,7 @@ (deftest select-except-select (testing "select which rows are not present in another table" - (is (= ["(SELECT ip) EXCEPT (SELECT ip FROM ip_location)"] + (is (= ["SELECT ip EXCEPT SELECT ip FROM ip_location"] (sql/format {:except [{:select [:ip]} @@ -335,7 +335,7 @@ (deftest values-except-all-select (testing "select which values are not not present in a table" - (is (= ["(VALUES (?), (?), (?)) EXCEPT ALL (SELECT id FROM images)" 4 5 6] + (is (= ["VALUES (?), (?), (?) EXCEPT ALL SELECT id FROM images" 4 5 6] (sql/format {:except-all [{:values [[4] [5] [6]]} @@ -343,7 +343,7 @@ (deftest select-except-all-select (testing "select which rows are not present in another table" - (is (= ["(SELECT ip) EXCEPT ALL (SELECT ip FROM ip_location)"] + (is (= ["SELECT ip EXCEPT ALL SELECT ip FROM ip_location"] (sql/format {:except-all [{:select [:ip]} diff --git a/test/honey/sql_test.cljc b/test/honey/sql_test.cljc index bda1edd..17d2a27 100644 --- a/test/honey/sql_test.cljc +++ b/test/honey/sql_test.cljc @@ -184,30 +184,30 @@ ;; ORDER BY foo ASC (is (= (format {:union [{:select [:foo] :from [:bar1]} {:select [:foo] :from [:bar2]}]}) - ["(SELECT foo FROM bar1) UNION (SELECT foo FROM bar2)"])) + ["SELECT foo FROM bar1 UNION SELECT foo FROM bar2"])) (testing "union complex values" (is (= (format {:union [{:select [:foo] :from [:bar1]} {:select [:foo] :from [:bar2]}] :with [[[:bar {:columns [:spam :eggs]}] {:values [[1 2] [3 4] [5 6]]}]]}) - ["WITH bar (spam, eggs) AS (VALUES (?, ?), (?, ?), (?, ?)) (SELECT foo FROM bar1) UNION (SELECT foo FROM bar2)" + ["WITH bar (spam, eggs) AS (VALUES (?, ?), (?, ?), (?, ?)) SELECT foo FROM bar1 UNION SELECT foo FROM bar2" 1 2 3 4 5 6])))) (deftest union-all-test (is (= (format {:union-all [{:select [:foo] :from [:bar1]} {:select [:foo] :from [:bar2]}]}) - ["(SELECT foo FROM bar1) UNION ALL (SELECT foo FROM bar2)"]))) + ["SELECT foo FROM bar1 UNION ALL SELECT foo FROM bar2"]))) (deftest intersect-test (is (= (format {:intersect [{:select [:foo] :from [:bar1]} {:select [:foo] :from [:bar2]}]}) - ["(SELECT foo FROM bar1) INTERSECT (SELECT foo FROM bar2)"]))) + ["SELECT foo FROM bar1 INTERSECT SELECT foo FROM bar2"]))) (deftest except-test (is (= (format {:except [{:select [:foo] :from [:bar1]} {:select [:foo] :from [:bar2]}]}) - ["(SELECT foo FROM bar1) EXCEPT (SELECT foo FROM bar2)"]))) + ["SELECT foo FROM bar1 EXCEPT SELECT foo FROM bar2"]))) (deftest inner-parts-test (testing "The correct way to apply ORDER BY to various parts of a UNION" @@ -221,7 +221,7 @@ :order-by [[:amount :desc]] :limit 5}]}] :order-by [[:amount :asc]]}) - ["(SELECT amount, id, created_on FROM transactions) UNION (SELECT amount, id, created_on FROM (SELECT amount, id, created_on FROM other_transactions ORDER BY amount DESC LIMIT ?)) ORDER BY amount ASC" 5])))) + ["SELECT amount, id, created_on FROM transactions UNION SELECT amount, id, created_on FROM (SELECT amount, id, created_on FROM other_transactions ORDER BY amount DESC LIMIT ?) ORDER BY amount ASC" 5])))) (deftest compare-expressions-test (testing "Sequences should be fns when in value/comparison spots" @@ -253,14 +253,14 @@ {:select [:foo] :from [:bar2]}] :with [[[:bar {:columns [:spam :eggs]}] {:values [[1 2] [3 4] [5 6]]}]]}) - ["WITH bar (spam, eggs) AS (VALUES (?, ?), (?, ?), (?, ?)) (SELECT foo FROM bar1) UNION (SELECT foo FROM bar2)" 1 2 3 4 5 6]))) + ["WITH bar (spam, eggs) AS (VALUES (?, ?), (?, ?), (?, ?)) SELECT foo FROM bar1 UNION SELECT foo FROM bar2" 1 2 3 4 5 6]))) (deftest union-all-with-cte (is (= (format {:union-all [{:select [:foo] :from [:bar1]} {:select [:foo] :from [:bar2]}] :with [[[:bar {:columns [:spam :eggs]}] {:values [[1 2] [3 4] [5 6]]}]]}) - ["WITH bar (spam, eggs) AS (VALUES (?, ?), (?, ?), (?, ?)) (SELECT foo FROM bar1) UNION ALL (SELECT foo FROM bar2)" 1 2 3 4 5 6]))) + ["WITH bar (spam, eggs) AS (VALUES (?, ?), (?, ?), (?, ?)) SELECT foo FROM bar1 UNION ALL SELECT foo FROM bar2" 1 2 3 4 5 6]))) (deftest parameterizer-none (testing "array parameter" @@ -276,7 +276,7 @@ :with [[[:bar {:columns [:spam :eggs]}] {:values [[1 2] [3 4] [5 6]]}]]} {:inline true}) - ["WITH bar (spam, eggs) AS (VALUES (1, 2), (3, 4), (5, 6)) (SELECT foo FROM bar1) UNION (SELECT foo FROM bar2)"])))) + ["WITH bar (spam, eggs) AS (VALUES (1, 2), (3, 4), (5, 6)) SELECT foo FROM bar1 UNION SELECT foo FROM bar2"])))) (deftest inline-was-parameterizer-none (testing "array parameter" @@ -293,7 +293,7 @@ :with [[[:bar {:columns [:spam :eggs]}] {:values (mapv #(mapv vector (repeat :inline) %) [[1 2] [3 4] [5 6]])}]]}) - ["WITH bar (spam, eggs) AS (VALUES (1, 2), (3, 4), (5, 6)) (SELECT foo FROM bar1) UNION (SELECT foo FROM bar2)"])))) + ["WITH bar (spam, eggs) AS (VALUES (1, 2), (3, 4), (5, 6)) SELECT foo FROM bar1 UNION SELECT foo FROM bar2"])))) (deftest similar-regex-tests (testing "basic similar to"