clarify :values clause behavior with columns

also add more examples to the RCF at the bottom of honey.sql.
This commit is contained in:
Sean Corfield 2023-08-10 19:31:17 -07:00
parent c2088bff6c
commit ba336f2884
3 changed files with 47 additions and 4 deletions

View file

@ -1,5 +1,8 @@
# Changes # Changes
* 2.4.next in progress
* Attempt to clarify the formatting behavior of the `:values` clause when used to produce column names.
* 2.4.1045 -- 2023-06-25 * 2.4.1045 -- 2023-06-25
* Address [#495](https://github.com/seancorfield/honeysql/issues/495) by adding (experimental) `formatf` function -- purely for discussion: may be removed in a subsequent release! * Address [#495](https://github.com/seancorfield/honeysql/issues/495) by adding (experimental) `formatf` function -- purely for discussion: may be removed in a subsequent release!
* Fix [#494](https://github.com/seancorfield/honeysql/issues/494) by supporting expressions in `:on-conflict` instead of just entities. * Fix [#494](https://github.com/seancorfield/honeysql/issues/494) by supporting expressions in `:on-conflict` instead of just entities.

View file

@ -564,7 +564,8 @@ The third case takes a pair of either a table specifier
or a table/column specifier and a SQL query. or a table/column specifier and a SQL query.
For the first and second cases, you'll use the `:values` clause For the first and second cases, you'll use the `:values` clause
to specify rows of values to insert. to specify rows of values to insert. See [**values**](#values) below
for more detail on the `:values` clause.
`:replace-into` is only supported by MySQL and SQLite but is `:replace-into` is only supported by MySQL and SQLite but is
part of HoneySQL's "core" dialect anyway. It produces a `REPLACE INTO` part of HoneySQL's "core" dialect anyway. It produces a `REPLACE INTO`
@ -1037,16 +1038,40 @@ same as the `:for` clause above.
row values or a sequence of sequences, also representing row row values or a sequence of sequences, also representing row
values. values.
In the former case, all of the rows are augmented to have ### values with hash maps
If you provide a sequence of hash maps, the `:values` clause
will generate a `VALUES` clause with the column names preceding
and the row values following.
```clojure
user=> (sql/format {:values [{:col-a 1 :col-b 2}]})
["(col_a, col_b) VALUES (?, ?)" 1 2]
```
In addition, all of the rows are augmented to have
either `NULL` or `DEFAULT` values for any missing keys (columns). either `NULL` or `DEFAULT` values for any missing keys (columns).
By default, `NULL` is used but you can specify a set of columns By default, `NULL` is used but you can specify a set of columns
to get `DEFAULT` values, via the `:values-default-columns` option. to get `DEFAULT` values, via the `:values-default-columns` option.
You can also be explicit and use `[:default]` as a value to generate `DEFAULT`. You can also be explicit and use `[:default]` as a value to generate `DEFAULT`.
In the latter case -- a sequence of sequences --
all of the rows are padded to the same length by adding `nil` ### values with sequences
If you provide a sequence of sequences, the `:values` clause
will generate a `VALUES` clause with no column names and the
row values following.
```clojure
user=> (sql/format {:values [[1 2]]})
["VALUES (?, ?)" 1 2]
```
In addition, all of the rows are padded to the same length by adding `nil`
values if needed (since `:values` does not know how or if column values if needed (since `:values` does not know how or if column
names are being used in this case). names are being used in this case).
### values examples
```clojure ```clojure
user=> (sql/format {:insert-into :table user=> (sql/format {:insert-into :table
:values [[1 2] [2 3 4 5] [3 4 5]]}) :values [[1 2] [2 3 4 5] [3 4 5]]})

View file

@ -2083,4 +2083,19 @@
(sql/format {:select [:*], :from [:table], :where [:foo [:+ :a 1]]}) (sql/format {:select [:*], :from [:table], :where [:foo [:+ :a 1]]})
(sql/formatf '{select * from table where (foo (+ a 1))}) (sql/formatf '{select * from table where (foo (+ a 1))})
(sql/formatf '{select * from table where (foo (+ a ?1))} 42) (sql/formatf '{select * from table where (foo (+ a ?1))} 42)
(sql/format {:update [:user :u]
:set {:email :u2.email
:first_name :u2.first_name
:last_name :u2.last_name}
:from [[[:values [1 "hollis@weiman.biz" "Hollis" "Connell"]
[2 "robert@duncan.info" "Robert" "Duncan"]]
[[:'u2 :id :email :first_name :last_name]]]]
:where [:= :u.id :u2.id]}
{:inline true})
(sql/register-clause! :output :select :values)
(sql/format {:insert-into :foo :output [:inserted.*] :values [{:bar 1}]})
(sql/format {:insert-into :foo :columns [:bar] :output [:inserted.*] :values [[1]]})
) )