Fix issue with optional param in update stmt#267
Fix issue with optional param in update stmt#267tatchi wants to merge 2 commits intoygrek:ahrefsfrom
Conversation
| > stock INT NOT NULL | ||
| > ); | ||
| > | ||
| > UPDATE products SET stock = { @stock }? WHERE id = @id; |
There was a problem hiding this comment.
I don't quite understand. Why are you using the { @stock }? syntax if your stock column is NOT NULL?
There was a problem hiding this comment.
So the idea is to be able to optionally update a column. i.e if you provide None them the column is not updated (keep the current value).
I tried using the syntax suggested in your comment below, and while it compiles fine, the generated OCaml type seems wrong, see the SetValue of 'a & float & 'b
Error: This expression has type
x:[< `OrDefault | `SetValue of 'a & float & 'b ] ->
Conn.execute_response Sql.IO.future
but an expression was expected of type 'c Sql.IO.future
Had 1 error, waiting for filesystem changes... There was a problem hiding this comment.
Isn't this what you need?
again, given this sql:
CREATE TABLE products (
id INT PRIMARY KEY,
stock INT NOT NULL
);
UPDATE products SET stock = @stock { SetValue { @x } | OrDefault { `stock` } } WHERE id = @id;
we get
let update_products_1 db ~stock ~id =
let set_params stmt =
let p = T.start_params stmt (1 + (match stock with `SetValue _ -> 1 | `OrDefault -> 0)) in
begin match stock with
| `OrDefault -> ()
| `SetValue (x) ->
T.set_param_Int p x;
end;
T.set_param_Int p id;
T.finish_params p
in
T.execute db ("UPDATE products SET stock = " ^ (match stock with `SetValue _ -> " " ^ "?" ^ " " | `OrDefault -> " `stock` ") ^ " WHERE id = ?") set_params
end (* module Sqlgg *)that is called this way:
let _ = Db.update_products_1 c ~stock:(`SetValue 100L) ~id:42L in
let _ = Db.update_products_1 c ~stock:`OrDefault ~id:42L inwe see that if the value is OrDefault we return the current column stock.
Please fix me if I misunderstood you.
There was a problem hiding this comment.
About
the generated OCaml type seems wrong, see the SetValue of 'a & float & 'b
When sqlgg generates the code, it cannot know the concrete OCaml type carried by SetValue in advance.
This depends on the concrete implementation of the Sqlgg_traits module, in particular on which set_param_* function is used.
The setter (e.g. set_param_Int) is what ultimately fixes the actual OCaml type of the value.
|
I don't think it's a good idea to try to reuse the syntax for anything else. Maybe I'm wrong @ygrek cc |
When using the optional parameter syntax
?in anUPDATEstatement, it replaces the column with the valueTRUE. Maybe I misunderstood something but it feels wrong to me.See the test added in the first commit.
Instead, this PR makes it so the current column value stays the same
See second commit