fix #494 by supporting expressions in on conflict
This commit is contained in:
parent
3ec884f881
commit
290537c581
4 changed files with 23 additions and 18 deletions
|
|
@ -1,6 +1,7 @@
|
|||
# Changes
|
||||
|
||||
* 2.4.next in progress
|
||||
* Fix [#494](https://github.com/seancorfield/honeysql/issues/494) by supporting expressions in `:on-conflict` instead of just entities.
|
||||
* Address [#493](https://github.com/seancorfield/honeysql/issues/493) by clarifying use of `:values` in CTEs (using `:with`).
|
||||
* Address [#489](https://github.com/seancorfield/honeysql/issues/489) by adding more examples around `:update`.
|
||||
* Update dev/test dependencies.
|
||||
|
|
|
|||
|
|
@ -1099,10 +1099,11 @@ as if they are separate clauses but they will appear
|
|||
in pairs: `ON ... DO ...`.
|
||||
|
||||
`:on-conflict` accepts a sequence of zero or more
|
||||
SQL entities (keywords or symbols), optionally
|
||||
SQL expressions, optionally
|
||||
followed by a single SQL clause (hash map). It can also
|
||||
accept either a single SQL entity or a single SQL clause.
|
||||
The SQL entities are column names and the SQL clause can be an
|
||||
The SQL expressions can be just column names or function calls etc,
|
||||
and the SQL clause can be an
|
||||
`:on-constraint` clause or a`:where` clause.
|
||||
|
||||
_[For convenience of use with the `on-conflict` helper, this clause can also accept any of those arguments, wrapped in a sequence; it can also accept an empty sequence, and just produce `ON CONFLICT`, so that it can be combined with other clauses directly]_
|
||||
|
|
|
|||
|
|
@ -881,23 +881,26 @@
|
|||
|
||||
(defn- format-on-conflict [k x]
|
||||
(if (sequential? x)
|
||||
(let [entities (take-while ident? x)
|
||||
n (count entities)
|
||||
(let [exprs (take-while (complement map?) x)
|
||||
n (count exprs)
|
||||
[clause & more] (drop n x)
|
||||
_ (when (or (seq more)
|
||||
(and clause (not (map? clause))))
|
||||
_ (when (seq more)
|
||||
(throw (ex-info "unsupported :on-conflict format"
|
||||
{:clause x})))
|
||||
[sql & params] (when clause
|
||||
[sqls expr-params]
|
||||
(when (seq exprs)
|
||||
(format-expr-list exprs))
|
||||
[sql & clause-params]
|
||||
(when clause
|
||||
(format-dsl clause))]
|
||||
(into [(str (sql-kw k)
|
||||
|
||||
(-> [(str (sql-kw k)
|
||||
(when (pos? n)
|
||||
(str " ("
|
||||
(str/join ", " (map #'format-entity entities))
|
||||
")"))
|
||||
(str " (" (str/join ", " sqls) ")"))
|
||||
(when sql
|
||||
(str " " sql)))]
|
||||
params))
|
||||
(into expr-params)
|
||||
(into clause-params)))
|
||||
(format-on-conflict k [x])))
|
||||
|
||||
(defn- format-do-update-set [k x]
|
||||
|
|
|
|||
|
|
@ -772,13 +772,13 @@ DO NOTHING
|
|||
INSERT INTO customers
|
||||
(name, email)
|
||||
VALUES ('Microsoft', 'hotline@microsoft.com')
|
||||
ON CONFLICT (name, email)
|
||||
ON CONFLICT (name, TRIM(email))
|
||||
DO NOTHING
|
||||
"]
|
||||
(format {:insert-into :customers
|
||||
:columns [:name :email]
|
||||
:values [[[:inline "Microsoft"], [:inline "hotline@microsoft.com"]]]
|
||||
:on-conflict [:name :email]
|
||||
:on-conflict [:name [:trim :email]]
|
||||
:do-nothing true}
|
||||
{:pretty true})))
|
||||
(is (= ["
|
||||
|
|
|
|||
Loading…
Reference in a new issue