From 11e1a93c596515aef6a07a34acf9fc848c7bf6fa Mon Sep 17 00:00:00 2001 From: Sean Corfield Date: Wed, 27 Sep 2023 23:13:16 -0700 Subject: [PATCH] fix #505 by rewriting helper-merge --- CHANGELOG.md | 1 + src/honey/sql/helpers.cljc | 35 +++++++++++++++++++++++++++----- test/honey/sql/helpers_test.cljc | 21 +++++++++++++++++++ 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3671c2e..b36ded5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changes * 2.4.next in progress + * Fix [#505](https://github.com/seancorfield/honeysql/issues/505) by rewriting the helper merge function to handle both keywords and symbols properly. * Address [#503](https://github.com/seancorfield/honeysql/issues/503) by adding `:at-time-zone` special syntax. * Address [#504](https://github.com/seancorfield/honeysql/issues/504) for BigQuery support, by adding special syntax for ignore/respect nulls, as well as new `:distinct` and `:expr` clauses to allow expressions to be qualified with SQL clauses. The latter will probably be useful for other dialects too. diff --git a/src/honey/sql/helpers.cljc b/src/honey/sql/helpers.cljc index ab1ce34..3e0cf60 100644 --- a/src/honey/sql/helpers.cljc +++ b/src/honey/sql/helpers.cljc @@ -71,6 +71,16 @@ (keyword (name s))) s)) +(defn- kw->sym + "Given a keyword, produce a symbol, retaining the namespace + qualifier, if any." + [k] + (if (keyword? k) + (if-let [n (namespace k)] + (symbol n (name k)) + (symbol (name k))) + k)) + (defn- conjunction? [e] (and (ident? e) @@ -134,11 +144,26 @@ :having #'conjunction-merge}) (defn- helper-merge [data k args] - (if-let [merge-fn (special-merges k)] - (if-some [clause (merge-fn (get data k) args)] - (assoc data k clause) - data) - (clojure.core/update data k default-merge args))) + (let [k' (sym->kw k) + k (kw->sym k) + d (get data k) + d' (get data k') + mf (special-merges k') + mf' (or mf default-merge)] + (cond (some? d) + (if-some [clause (mf' d args)] + (assoc data k clause) + data) + (some? d') + (if-some [clause (mf' d' args)] + (assoc data k' clause) + data) + mf + (if-some [clause (mf nil args)] + (assoc data k' clause) + data) + :else + (clojure.core/update data k' default-merge args)))) (defn- generic [k args] (if (map? (first args)) diff --git a/test/honey/sql/helpers_test.cljc b/test/honey/sql/helpers_test.cljc index b1b4a75..e2e75d4 100644 --- a/test/honey/sql/helpers_test.cljc +++ b/test/honey/sql/helpers_test.cljc @@ -913,3 +913,24 @@ (where false))) (is (= ["SELECT * FROM table WHERE FALSE"] (sql/format {:select [:*] :from [:table] :where false}))))) + +(deftest issue-505 + (testing "where should merge symbols/keywords correctly" + (is (= '{where [:and (= a 1) [:= :b 2]]} + (-> '{where (= a 1)} + (where [:= :b 2])))) + (is (= '{where (= a 1)} + (-> '{where (= a 1)} + (where)))) + (is (= '{:where [:and (= a 1) [:= :b 2]]} + (-> '{:where (= a 1)} + (where [:= :b 2])))) + (is (= '{:where (= a 1)} + (-> '{:where (= a 1)} + (where)))) + (is (= '{:where [:= :b 2]} + (-> '{} + (where [:= :b 2])))) + (is (= '{} + (-> '{} + (where))))))