You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
CREATETABLEfoo (bar TEXT);
-- name: SetBar :execUPDATE foo
SET bar = $1::TEXT;
Casting $1 to TEXT avoids a sql.NullString in the parameter of SetBar, but the parameter doesn't infer the name bar. It would be convenient if I could set it explicitly.
I played around with this a bit today. I don't think the :param approach is going to work. The PostgreSQL parser barfs on those queries. I attempted to use the sqlx named parameter code, but it operates on single queries, not an entire file. It also failed to handle comments.
Instead, I think it's better if we create a psuedo-function and map it to an operator. Here's what it would look like:
-- name: GetAuthor :oneSELECT*FROM authors
WHERE id =sqlc.arg(id) LIMIT1;
-- name: CreateAuthor :oneINSERT INTO authors (
name, bio
) VALUES (
sqlc.arg(name), sqlc.arg(bio)
)
RETURNING *;
-- name: DeleteAuthor :execDELETEFROM authors
WHERE id =sqlc.arg(id);
In this case, sqlc is a psuedo-schema, arg is a function that takes an identifier as the first argument. sqlc.arg is a bit cumbersome to write, so we could map it to the @ operator, which surprisingly works for both PostgreSQL and MySQL.
-- name: GetAuthor :oneSELECT*FROM authors
WHERE id = @id LIMIT1;
-- name: CreateAuthor :oneINSERT INTO authors (
name, bio
) VALUES (
@name, @bio
)
RETURNING *;
-- name: DeleteAuthor :execDELETEFROM authors
WHERE id = @id;
I think this approach is much better than relying on a syntax that doesn't parse. There are also a bunch of different ways to approach the arg function (sqlc.arg.name, sqlc_arg(name), _$.arg), etc. We just want to pick an approach that won't likely cause issues for existing queries.
I tested a few of these out on the mysql parser to see what works best. It looks like :param parses great for mysql. I realize it's not ideal to have different solutions between engines, but this would be very natural for mysql users.
I was having trouble getting @param to parse properly... unless you were thinking of replacing those before parsing.
I realize it's not ideal to have different solutions between engines, but this would be very natural for mysql users.
In an ideal world we'd use the same operator for all engines. We should make sure the long-form solution (e.g sqlc.arg(name)) works the same across all engines. This should be much easier, since it's a SQL function.
Activity
maxhawkins commentedon Dec 14, 2019
+1 this would be helpful.
I encountered this situation:
Casting
$1toTEXTavoids asql.NullStringin the parameter ofSetBar, but the parameter doesn't infer the namebar. It would be convenient if I could set it explicitly.maxhawkins commentedon Dec 16, 2019
Adding named parameters a la HugSQL could solve this problem too:
kyleconroy commentedon Dec 17, 2019
@maxhawkins I've avoided adding support for the HugSQL syntax because it's nonstandard. Passing that query to the PostgreSQL parser returns an error.
maxhawkins commentedon Dec 17, 2019
OK, agreed. Avoiding nonstandard syntax makes sense to me.
I want to add automatic SQL formatting to my query files and nonstandard syntax would break it.
kyleconroy commentedon Jan 8, 2020
SQLAlchemy supports named parameters in the form
:param:Sequel, a Ruby database toolkit, supports the same format:
While this format isn't part of the SQL standard, I think it solves the problem nicely.
maxhawkins commentedon Jan 8, 2020
psql uses a similar format for its \set command:
kyleconroy commentedon Jan 15, 2020
I played around with this a bit today. I don't think the
:paramapproach is going to work. The PostgreSQL parser barfs on those queries. I attempted to use the sqlx named parameter code, but it operates on single queries, not an entire file. It also failed to handle comments.Instead, I think it's better if we create a psuedo-function and map it to an operator. Here's what it would look like:
In this case,
sqlcis a psuedo-schema,argis a function that takes an identifier as the first argument.sqlc.argis a bit cumbersome to write, so we could map it to the@operator, which surprisingly works for both PostgreSQL and MySQL.I think this approach is much better than relying on a syntax that doesn't parse. There are also a bunch of different ways to approach the arg function (
sqlc.arg.name,sqlc_arg(name),_$.arg), etc. We just want to pick an approach that won't likely cause issues for existing queries.cmoog commentedon Jan 16, 2020
I tested a few of these out on the
mysqlparser to see what works best. It looks like:paramparses great formysql. I realize it's not ideal to have different solutions between engines, but this would be very natural formysqlusers.I was having trouble getting
@paramto parse properly... unless you were thinking of replacing those before parsing.kyleconroy commentedon Jan 16, 2020
In an ideal world we'd use the same operator for all engines. We should make sure the long-form solution (e.g
sqlc.arg(name)) works the same across all engines. This should be much easier, since it's a SQL function.