Skip to content

Commit

Permalink
fix #520
Browse files Browse the repository at this point in the history
Signed-off-by: Sean Corfield <sean@corfield.org>
  • Loading branch information
seancorfield committed Jan 6, 2024
1 parent 2e34a9f commit 9b9ec47
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changes

* 2.5.next in progress
* Address [#520](https://github.com/seancorfield/honeysql/issues/520) by expanding how `:inline` works, to support a sequence of arguments.
* Fix [#518](https://github.com/seancorfield/honeysql/issues/518) by moving temporal clause before alias.
* Implemented `CREATE INDEX` [#348](https://github.com/seancorfield/honeysql/issues/348) via PR [#517](https://github.com/seancorfield/honeysql/pull/517) [@dancek](https://github.com/dancek).

Expand Down
32 changes: 30 additions & 2 deletions doc/special-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,8 @@ renders that expression followed by `IGNORE NULLS` or `RESPECT NULLS`:
## inline
Accepts a single argument and tries to render it as a
SQL value directly in the formatted SQL string rather
Accepts one or more arguments and tries to render them as a
SQL values directly in the formatted SQL string rather
than turning it into a positional parameter:
* `nil` becomes `NULL`
* keywords and symbols become upper case entities (with `-` replaced by space)
Expand All @@ -298,6 +298,34 @@ than turning it into a positional parameter:
;;=> ["WHERE x = 'foo'"]
```
If multiple arguments are provided, they are individually formatted as above
and joined into a single SQL string with spaces:
```clojure
(sql/format {:where [:= :x [:inline :DATE "2019-01-01"]]})
;;=> ["WHERE x = DATE '2019-01-01'"]
```
This is convenient for rendering DATE/TIME/TIMESTAMP literals in SQL.
If an argument is an expression, it is formatted as a regular SQL expression
except that any parameters are inlined:
```clojure
(sql/format {:where [:= :x [:inline [:date_add [:now] [:interval 30 :days]]]]})
;;=> ["WHERE x = DATE_ADD(NOW(), INTERVAL 30 DAYS)"]
```
In particular, that means that you can use `:inline` to inline a parameter
value:
```clojure
(sql/format {:where [:= :x [:inline :?foo]]} {:params {:foo "bar"}})
;;=> ["WHERE x = 'bar'"]
(sql/format {:where [:= :x [:inline [:param :foo]]]} {:params {:foo "bar"}})
;;=> ["WHERE x = 'bar'"]
```
## interval
Accepts one or two arguments: either a string or an expression and
Expand Down
6 changes: 4 additions & 2 deletions src/honey/sql.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -1821,9 +1821,10 @@
:filter expr-clause-pairs
:ignore-nulls ignore-respect-nulls
:inline
(fn [_ [x]]
(fn [_ xs]
(binding [*inline* true]
(format-expr x)))
(let [sqls (mapcat format-expr xs)]
[(str/join " " sqls)])))
:interval format-interval
:join
(fn [_ [e & js]]
Expand Down Expand Up @@ -2443,4 +2444,5 @@
:limit 2000}
{:dialect :nrql :pretty true})
(sql/format {:select [[[:array {:select :* :from :table}] :arr]]})
(sql/format [:inline :DATE "2020-01-01"])
)
19 changes: 19 additions & 0 deletions test/honey/sql_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -1309,9 +1309,28 @@ ORDER BY id = ? DESC
{:quoted-always #"^(foo)$"
:quoted false})))))

(deftest issue-520
(testing ":inline with a single argument"
(is (= ["SELECT 42 AS x"]
(sut/format '{select [[[inline 42] x]]}))))
(testing ":inline with multiple arguments"
(is (= ["SELECT DATE '2024-01-06' AS x"]
(sut/format '{select [[[inline DATE "2024-01-06"] x]]}))))
(testing ":inline with a parameter"
(is (= ["SELECT 42 AS x"]
(sut/format '{select [[[inline [param foo]] x]]}
{:params {'foo 42}}))))
(testing ":inline with a sequence"
(is (= ["SELECT ('a', 'b', 'c') AS x"]
(sut/format '{select [[[inline ["a" "b" "c"]] x]]}))))
(testing ":inline with a lifted sequence"
(is (= ["SELECT ['a', 'b', 'c'] AS x"]
(sut/format '{select [[[inline [lift ["a" "b" "c"]]] x]]})))))

(comment
;; partial (incorrect!) workaround for #407:
(sut/format {:select :f.* :from [[:foo [:f :for :system-time]]] :where [:= :f.id 1]})
;; correct version:
(sut/format {:select :f.* :from [[:foo :f :for :system-time]] :where [:= :f.id 1]})
(sut/format {:where [:= :x [:inline :DATE "2019-01-01"]]})
)

0 comments on commit 9b9ec47

Please sign in to comment.