diff --git a/CHANGELOG.md b/CHANGELOG.md index b153302..ae35890 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changes * 2.6.next in progress + * Fix [#528](https://github.com/seancorfield/honeysql/issues/528) by preventing the `?` -> `??` escaping in SQL keywords just for operators. * Address [#527](https://github.com/seancorfield/honeysql/issues/527) by adding tests and more documentation for `:composite`. * Update Clojure versions (to 1.11.2 and 1.12.0-alpha9). diff --git a/src/honey/sql.cljc b/src/honey/sql.cljc index 1d09d33..88a9b81 100644 --- a/src/honey/sql.cljc +++ b/src/honey/sql.cljc @@ -326,6 +326,27 @@ [v a d (format-entity v {:aliased a :drop-ns d})]))) ) +(defn sql-op-kw + "Given a keyword for an operator, return a SQL representation of it as a string. + + A keyword whose name begins with a single quote is left exactly as-is + (with the `:` and `'` removed), otherwise a `:kebab-case` keyword + becomes a `KEBAB CASE` (uppercase) string with hyphens replaced + by spaces, e.g., `:insert-into` => `INSERT INTO`. + + Any namespace qualifier is ignored. + + Unlike sql-kw below, ? is NOT escaped to ??." + [k] + (when k + (let [n (name k)] + (if (= \' (first n)) + (let [ident (subs n 1) + ident-l (str/lower-case ident)] + (binding [*quoted* (when-not (contains? #{"array"} ident-l) *quoted*)] + (format-entity (keyword ident)))) + (-> n (dehyphen) (upper-case)))))) + (defn sql-kw "Given a keyword, return a SQL representation of it as a string. @@ -1943,10 +1964,10 @@ (when-not (pos? (count sqls)) (throw (ex-info (str "no operands found for " op') {:expr expr}))) - (into [(cond-> (str/join (str " " (sql-kw op) " ") sqls) + (into [(cond-> (str/join (str " " (sql-op-kw op) " ") sqls) (and (contains? @op-can-be-unary op) (= 1 (count sqls))) - (as-> s (str (sql-kw op) " " s)) + (as-> s (str (sql-op-kw op) " " s)) nested (as-> s (str "(" s ")")))] params))) diff --git a/test/honey/sql/pg_ops_test.cljc b/test/honey/sql/pg_ops_test.cljc index a310b79..e030a80 100644 --- a/test/honey/sql/pg_ops_test.cljc +++ b/test/honey/sql/pg_ops_test.cljc @@ -20,11 +20,11 @@ (sql/format {:select [[[:#> :a :b] :x]]}))) (is (= ["SELECT a #>> b AS x"] (sql/format {:select [[[:#>> :a :b] :x]]}))) - (is (= ["SELECT a ?? b AS x"] + (is (= ["SELECT a ? b AS x"] (sql/format {:select [[[:? :a :b] :x]]}))) - (is (= ["SELECT a ??| b AS x"] + (is (= ["SELECT a ?| b AS x"] (sql/format {:select [[[:?| :a :b] :x]]}))) - (is (= ["SELECT a ??& b AS x"] + (is (= ["SELECT a ?& b AS x"] (sql/format {:select [[[:?& :a :b] :x]]}))) (is (= ["SELECT a #- b AS x"] (sql/format {:select [[[:#- :a :b] :x]]})))) @@ -33,7 +33,7 @@ (sql/format {:select [[[sut/at> :a :b] :x]]}))) (is (= ["SELECT a <@ b AS x"] (sql/format {:select [[[sut/