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
The documentation for updating rows appears to be incomplete, resulting in an error for Sqlite and a silent-but-incorrect generation for MySQL. It appears that the $1 placeholders used in the documentation are not valid for these two backends (but is valid for PostgreSQL,) and that ? should be used for the Sqlite and MySQL backends.
Suggested resolution
Update the documentation to reflect differences in SQL dialects. As someone unfamiliar with PostgreSQL it wasn't clear if the use of $1 was specific to sqlc or not, so having a note and examples using the other backends would be great.
The silent failure to generate expected MySQL outputs (see code block at bottom) is an issue that isn't as clear to fix. The user will quickly see that the generated functions don't behave as expected, but there's no output or indication as to what went wrong. One place I could see this potentially occurring is a codebase that uses PostgreSQL and then adds the MySQL backend using the same queries - it's possible that they are "compatible" enough to silently pass through. Perhaps sqlc could emit a warning if it detects the $# syntax within a query targeting MySQL?
If possible it might also be helpful to have nicer error messages that catch this case for the Sqlite version too, indicating that the syntax might be using the wrong dialect; I'm not sure how viable such a warning would be to implement.
What I did
sqcl 1.27.0, generating go code
When following the documentation for updating rows, I ran into two issues. When generating for sqlite, the $1 syntax demonstrated in the documentation's UPDATE authors SET bio = $1; results in the error below. When generating for mysql, the syntax does not result in an error but does not generate the expected go code.
Sqlite Reproduction
Using the attached configuration, comment out the mysql portion of the yaml
Run sqlc generate
Note the error output attached below
Edit the query.sql to only include the UpdateExampleGood query
Run sqlc generate
Note no error output
Note that sqlite/query.sql.go contains the expected UpdateExampleParams struct
MySQL Reproduction
Using the attached configuration, comment out the sqlite portion of the yaml
Revert the query.sql to the attached version if it was edited
Run sqlc generate
Note no error output
Note that mysql/query.sql.go contains two Query functions
UpdateExample does not have an associated Params struct
UpdateExampleGood does have the expected Params struct
Example MySQL output with expected and unexpected generated functions
// Code generated by sqlc. DO NOT EDIT.// versions:// sqlc v1.27.0// source: query.sqlpackage example_issue
import (
"context"
)
constupdateExample=`-- name: UpdateExample :execUPDATE Example SET name = $2 WHERE id = $1`// NOTE: NoParamsstructforthe`$`syntax, butthefunctionisgeneratedanywayfunc (q*Queries) UpdateExample(ctxcontext.Context) error {
_, err:=q.db.ExecContext(ctx, updateExample)
returnerr
}
constupdateExampleGood=`-- name: UpdateExampleGood :execUPDATE Example SET name = ? WHERE id = ?`typeUpdateExampleGoodParamsstruct {
NamestringIDint32
}
// NOTE: Params struct is generated with the `?` syntaxfunc (q*Queries) UpdateExampleGood(ctx context.Context, argUpdateExampleGoodParams) error {
_, err:=q.db.ExecContext(ctx, updateExampleGood, arg.Name, arg.ID)
returnerr
}
Relevant log output
** Running `sqlc generate` with sqlite backend:
line 2:26 no viable alternative at input 'UPDATE Example SET name = $'# package example_issue
query.sql:1:1: no viable alternative at input 'UPDATE Example SET name = $'** No log outputs for mysql backend
Database schema
CREATETABLEIF NOT EXISTS Example (
id INTEGERNOT NULL,
name TEXTNOT NULL
);
SQL queries
-- This query fails to generate for sqlite, and doesn't generate Params for mysql-- name: UpdateExample :execUPDATE Example SET name = $2WHERE id = $1;
-- This version produces the expected output for both-- name: UpdateExampleGood :execUPDATE Example SET name = ? WHERE id = ?;
Configuration
version: "2"sql:
- engine: "mysql"queries: "query.sql"schema: "schema.sql"gen:
go:
package: "example_issue"out: "mysql"
- engine: "sqlite"queries: "query.sql"schema: "schema.sql"gen:
go:
package: "example_issue"out: "sqlite"# NOTE: Included for completeness; to use you need to remove the `UpdateExampleGood` query# since it doesn't have compatible syntax but does work with the documented $1, $2 syntax # - engine: "postgresql"# queries: "query.sql"# schema: "schema.sql"# gen:# go:# package: "example_issue"# out: "postgresql"
Playground URL
No response
What operating system are you using?
Linux
What database engines are you using?
MySQL, SQLite
What type of code are you generating?
Go
The text was updated successfully, but these errors were encountered:
Version
1.27.0
What happened?
High Level
The documentation for updating rows appears to be incomplete, resulting in an error for Sqlite and a silent-but-incorrect generation for MySQL. It appears that the
$1
placeholders used in the documentation are not valid for these two backends (but is valid for PostgreSQL,) and that?
should be used for the Sqlite and MySQL backends.Suggested resolution
Update the documentation to reflect differences in SQL dialects. As someone unfamiliar with PostgreSQL it wasn't clear if the use of
$1
was specific to sqlc or not, so having a note and examples using the other backends would be great.The silent failure to generate expected MySQL outputs (see code block at bottom) is an issue that isn't as clear to fix. The user will quickly see that the generated functions don't behave as expected, but there's no output or indication as to what went wrong. One place I could see this potentially occurring is a codebase that uses PostgreSQL and then adds the MySQL backend using the same queries - it's possible that they are "compatible" enough to silently pass through. Perhaps
sqlc
could emit a warning if it detects the$#
syntax within a query targeting MySQL?If possible it might also be helpful to have nicer error messages that catch this case for the Sqlite version too, indicating that the syntax might be using the wrong dialect; I'm not sure how viable such a warning would be to implement.
What I did
sqcl 1.27.0, generating go code
When following the documentation for updating rows, I ran into two issues. When generating for sqlite, the
$1
syntax demonstrated in the documentation'sUPDATE authors SET bio = $1;
results in the error below. When generating for mysql, the syntax does not result in an error but does not generate the expected go code.Sqlite Reproduction
sqlc generate
query.sql
to only include theUpdateExampleGood
querysqlc generate
sqlite/query.sql.go
contains the expected UpdateExampleParams structMySQL Reproduction
query.sql
to the attached version if it was editedsqlc generate
mysql/query.sql.go
contains two Query functionsUpdateExample
does not have an associated Params structUpdateExampleGood
does have the expected Params structExample MySQL output with expected and unexpected generated functions
Relevant log output
Database schema
SQL queries
Configuration
Playground URL
No response
What operating system are you using?
Linux
What database engines are you using?
MySQL, SQLite
What type of code are you generating?
Go
The text was updated successfully, but these errors were encountered: