From a2e02c8a0360a96a2b683b770a53cc2067fa70aa Mon Sep 17 00:00:00 2001 From: Sean Corfield Date: Thu, 31 Mar 2022 17:34:51 -0700 Subject: [PATCH] fix #394 by escaping quote chars This matches the HoneySQL 1.x behavior now. --- CHANGELOG.md | 3 ++- src/honey/sql.cljc | 13 +++++++++---- test/honey/sql_test.cljc | 9 +++++++++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bb4988..3d589e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ * 2.2.next in progress * Address [#400](https://github.com/seancorfield/honeysql/issues/400) by adding `:table` clause. * Address [#399](https://github.com/seancorfield/honeysql/issues/399) by correcting multi-column `RETURNING` clauses in docs and tests. - * Address [#398](https://github.com/seancorfield/honeysql/issues/398) by adding `honey.sql.pg-json` namespace that registers PostgreSQL JSON operators and provides symbolic names for "unwritable" operators (that contain `@`). + * Address [#398](https://github.com/seancorfield/honeysql/issues/398) by adding `honey.sql.pg-json` namespace that registers PostgreSQL JSON operators and provides symbolic names for "unwritable" operators (that contain `@` or `#`). + * Fix [#394](https://github.com/seancorfield/honeysql/issues/394) by restoring HoneySQL 1.x's behavior when quoting. * Fix [#387](https://github.com/seancorfield/honeysql/issues/387) again. * Update CI to reflect Clojure 1.11 release (master -> 1.11; new master is 1.12). * Update `build-clj` to v0.8.0. diff --git a/src/honey/sql.cljc b/src/honey/sql.cljc index 1cbad1d..7414e5c 100644 --- a/src/honey/sql.cljc +++ b/src/honey/sql.cljc @@ -87,15 +87,20 @@ order)) (conj order clause)))) +(defn- strop + "Escape any embedded closing strop characters." + [s x e] + (str s (str/replace x (str e) (str e e)) e)) + (def ^:private dialects (reduce-kv (fn [m k v] (assoc m k (assoc v :dialect k))) {} - {:ansi {:quote #(str \" % \")} - :sqlserver {:quote #(str \[ % \])} - :mysql {:quote #(str \` % \`) + {:ansi {:quote #(strop \" % \")} + :sqlserver {:quote #(strop \[ % \])} + :mysql {:quote #(strop \` % \`) :clause-order-fn #(add-clause-before % :set :where)} - :oracle {:quote #(str \" % \") :as false}})) + :oracle {:quote #(strop \" % \") :as false}})) ; should become defonce (def ^:private default-dialect (atom (:ansi dialects))) diff --git a/test/honey/sql_test.cljc b/test/honey/sql_test.cljc index 4fd4859..77287b2 100644 --- a/test/honey/sql_test.cljc +++ b/test/honey/sql_test.cljc @@ -883,3 +883,12 @@ ORDER BY id = ? DESC (is (= "what_is_this" (sut/sql-kw :'what-is-this))) (is (= "fee_fie_foe_fum" (sut/sql-kw :'fee-fie-foe-fum))) (is (= "_what_the_" (sut/sql-kw :'-what-the-)))) + +(deftest issue-394-quoting + (is (= ["SELECT \"A\"\"B\""] (sut/format {:select (keyword "A\"B")} {:quoted true}))) + (is (= ["SELECT \"A\"\"B\""] (sut/format {:select (keyword "A\"B")} {:dialect :ansi}))) + (is (= ["SELECT [A\"B]"] (sut/format {:select (keyword "A\"B")} {:dialect :sqlserver}))) + (is (= ["SELECT [A]]B]"] (sut/format {:select (keyword "A]B")} {:dialect :sqlserver}))) + (is (= ["SELECT `A\"B`"] (sut/format {:select (keyword "A\"B")} {:dialect :mysql}))) + (is (= ["SELECT `A``B`"] (sut/format {:select (keyword "A`B")} {:dialect :mysql}))) + (is (= ["SELECT \"A\"\"B\""] (sut/format {:select (keyword "A\"B")} {:dialect :oracle}))))