diff --git a/CHANGELOG.md b/CHANGELOG.md index c26edaf..2f79ee1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ * Add `:select` with function call and alias example to README (PR [#502](https://github.com/seancorfield/honeysql/pull/502) [@markbastian](https://github.com/markbastian)). * Address [#501](https://github.com/seancorfield/honeysql/issues/501) by making `INSERT INTO` (and `REPLACE INTO`) use the `:columns` or `:values` clauses to produce column names (which are then omitted from those other clauses). * Address [#497](https://github.com/seancorfield/honeysql/issues/497) by adding `:alias` special syntax. - * Address [#496](https://github.com/seancorfield/honeysql/issues/496) by adding `:overriding-value` option to `:insert` clause. Documentation TBD. + * Address [#496](https://github.com/seancorfield/honeysql/issues/496) by adding `:overriding-value` option to `:insert` clause. * Address [#407](https://github.com/seancorfield/honeysql/issues/407) by adding support for temporal queries (see `FROM` in [SQL Clause Reference](https://cljdoc.org/d/com.github.seancorfield/honeysql/CURRENT/doc/getting-started/sql-clause-reference#from)). * Address [#389](https://github.com/seancorfield/honeysql/issues/389) by adding examples of `[:only :table]` producing `ONLY(table)`. * Add `:create-or-replace-view` to support PostgreSQL's lack of `IF NOT EXISTS` for `CREATE VIEW`. diff --git a/doc/clause-reference.md b/doc/clause-reference.md index 376d2f9..4e04cb0 100644 --- a/doc/clause-reference.md +++ b/doc/clause-reference.md @@ -642,7 +642,33 @@ user=> (sql/format '{insert-into (((transport t) (id, name)) {select (*) from (c ["INSERT INTO transport AS t (id, name) SELECT * FROM cars"] ``` -> Note: if you specify `:columns` for an `:insert-into` that also includes column names, you will get invalid SQL. Similarly, if you specify `:columns` when `:values` is based on hash maps, you will get invalid SQL. Since clauses are generated independently, there is no cross-checking performed if you provide an illegal combination of clauses. +Some databases do not let you override (insert) values that would override +generated column values, unless your SQL specifies `OVERRIDING SYSTEM VALUE` +or `OVERRIDING USER VALUE`. In HoneySQL, you can use `:overriding-value` as +an option to `:insert-into` to specify this, with either `:system` or `:user` +as the option's value. The options can be specified as a hash map in the +first position of the `:insert-into` clause, prior to the table specifier. + +```clojure +user=> (sql/format {:insert-into [{:overriding-value :system} + [:transport :t] [:id :name]] + :values [[1 "Car"] [2 "Boat"] [3 "Bike"]]} + {:pretty true}) +[" +INSERT INTO transport AS t (id, name) OVERRIDING SYSTEM VALUE +VALUES (?, ?), (?, ?), (?, ?) +" 1 "Car" 2 "Boat" 3 "Bike"] +user=> (sql/format {:insert-into [{:overriding-value :user} + [:transport :t] [:id :name]] + :values [[1 "Car"] [2 "Boat"] [3 "Bike"]]} + {:pretty true}) +[" +INSERT INTO transport AS t (id, name) OVERRIDING USER VALUE +VALUES (?, ?), (?, ?), (?, ?) +" 1 "Car" 2 "Boat" 3 "Bike"] +``` + +> Note: if you specify `:columns` for an `:insert-into` that also includes column names, or with a `:values` clause based on hash maps (which imply column names), then an order of precedence is applied: the columns specified directly in `:insert-into` take precedence, then the `:columns` clause, then the implied column names from the `:values` clause. ## update diff --git a/src/honey/sql.cljc b/src/honey/sql.cljc index a3f3e18..07c2e8c 100644 --- a/src/honey/sql.cljc +++ b/src/honey/sql.cljc @@ -2259,4 +2259,8 @@ (fn [_ _] ["OVERRIDING SYSTEM VALUE"]) :values) (sql/format {:insert-into :foo :values [{:id 1}] :overriding-system-value true}) + (sql/format {:insert-into [{:overriding-value :system} + [:transport :t] [:id :name]] + :values [[1 "Car"] [2 "Boat"] [3 "Bike"]]} + {:pretty true}) )