Repository: sqlc-dev/sqlc
Pull request #3106 (2024-01-05 04:42:32)

fix(codegen/golang): Use `int16` for MySQL `SMALLINT` and `YEAR`
Resolves https://github.com/sqlc-dev/sqlc/issues/3088


Patch:
diff --git a/docs/tutorials/getting-started-mysql.md b/docs/tutorials/getting-started-mysql.md
index 7cf52972f..882cd75fa 100644
--- a/docs/tutorials/getting-started-mysql.md
+++ b/docs/tutorials/getting-started-mysql.md
@@ -8,6 +8,8 @@ We'll generate Go code here, but other
 naturally need the Go toolchain if you want to build and run a program with the
 code sqlc generates, but sqlc itself has no dependencies.
 
+At the end, you'll push your SQL queries to [sqlc Cloud](https://dashboard.sqlc.dev/) for further insights and analysis.
+
 ## Setting up
 
 Create a new directory called `sqlc-tutorial` and open it up.
@@ -181,3 +183,43 @@ database must have the `authors` table as defined in `schema.sql`.
 
 You should now have a working program using sqlc's generated Go source code,
 and hopefully can see how you'd use sqlc in your own real-world applications.
+
+## Query analysis and managed databases
+
+[sqlc Cloud](https://dashboard.sqlc.dev) provides additional insights into your
+queries, catching subtle bugs and performance issues. To get started, create a
+[dashboard account](https://dashboard.sqlc.dev). Once you've signed in, create a
+project and generate an auth token. Add your project's ID to the `cloud` block
+to your sqlc.yaml.
+
+```yaml
+version: "2"
+cloud:
+  # Replace <PROJECT_ID> with your project ID from the sqlc Cloud dashboard
+  project: "<PROJECT_ID>"
+sql:
+  - engine: "mysql"
+    queries: "query.sql"
+    schema: "schema.sql"
+    gen:
+      go:
+        package: "tutorial"
+        out: "tutorial"
+```
+
+Replace `<PROJECT_ID>` with your project ID from the sqlc Cloud dashboard. It
+will look something like `01HA8SZH31HKYE9RR3N3N3TSJM`.
+
+And finally, set the `SQLC_AUTH_TOKEN` environment variable:
+
+```shell
+export SQLC_AUTH_TOKEN="<your sqlc auth token>"
+```
+
+```shell
+$ sqlc push --tag tutorial
+```
+
+In the sidebar, go to the "Insights" section to run checks against your queries.
+If you need access to a pre-configured MySQL database, check out [managed
+databases](../howtwo/managed-databases.md).
diff --git a/docs/tutorials/getting-started-postgresql.md b/docs/tutorials/getting-started-postgresql.md
index 2f6729896..db2a46d47 100644
--- a/docs/tutorials/getting-started-postgresql.md
+++ b/docs/tutorials/getting-started-postgresql.md
@@ -8,12 +8,8 @@ We'll generate Go code here, but other
 naturally need the Go toolchain if you want to build and run a program with the
 code sqlc generates, but sqlc itself has no dependencies.
 
-We'll also rely on sqlc's [managed databases](../howto/managed-databases.md),
-which require a sqlc Cloud project and auth token. You can get those from
-the [sqlc Cloud dashboard](https://dashboard.sqlc.dev/). Managed databases are
-an optional feature that improves sqlc's query analysis in many cases, but you
-can turn it off simply by removing the `cloud` and `database` sections of your
-configuration.
+At the end, you'll push your SQL queries to [sqlc
+Cloud](https://dashboard.sqlc.dev/) for further insights and analysis.
 
 ## Setting up
 
@@ -31,15 +27,10 @@ following contents:
 
 ```yaml
 version: "2"
-cloud:
-  # Replace <PROJECT_ID> with your project ID from the sqlc Cloud dashboard
-  project: "<PROJECT_ID>"
 sql:
   - engine: "postgresql"
     queries: "query.sql"
     schema: "schema.sql"
-    database:
-      managed: true
     gen:
       go:
         package: "tutorial"
@@ -47,15 +38,6 @@ sql:
         sql_package: "pgx/v5"
 ```
 
-Replace `<PROJECT_ID>` with your project ID from the sqlc Cloud dashboard. It
-will look something like `01HA8SZH31HKYE9RR3N3N3TSJM`.
-
-And finally, set the `SQLC_AUTH_TOKEN` environment variable:
-
-```shell
-export SQLC_AUTH_TOKEN="<your sqlc auth token>"
-```
-
 ## Schema and queries
 
 sqlc needs to know your database schema and queries in order to generate code.
@@ -220,3 +202,44 @@ database must have the `authors` table as defined in `schema.sql`.
 
 You should now have a working program using sqlc's generated Go source code,
 and hopefully can see how you'd use sqlc in your own real-world applications.
+
+## Query analysis and managed databases
+
+[sqlc Cloud](https://dashboard.sqlc.dev) provides additional insights into your
+queries, catching subtle bugs and performance issues. To get started, create a
+[dashboard account](https://dashboard.sqlc.dev). Once you've signed in, create a
+project and generate an auth token. Add your project's ID to the `cloud` block
+to your sqlc.yaml.
+
+```yaml
+version: "2"
+cloud:
+  # Replace <PROJECT_ID> with your project ID from the sqlc Cloud dashboard
+  project: "<PROJECT_ID>"
+sql:
+  - engine: "postgresql"
+    queries: "query.sql"
+    schema: "schema.sql"
+    gen:
+      go:
+        package: "tutorial"
+        out: "tutorial"
+        sql_package: "pgx/v5"
+```
+
+Replace `<PROJECT_ID>` with your project ID from the sqlc Cloud dashboard. It
+will look something like `01HA8SZH31HKYE9RR3N3N3TSJM`.
+
+And finally, set the `SQLC_AUTH_TOKEN` environment variable:
+
+```shell
+export SQLC_AUTH_TOKEN="<your sqlc auth token>"
+```
+
+```shell
+$ sqlc push --tag tutorial
+```
+
+In the sidebar, go to the "Insights" section to run checks against your queries.
+If you need access to a pre-configured PostgreSQL database, check out [managed
+databases](../howtwo/managed-databases.md).
diff --git a/go.mod b/go.mod
index deb0bb98e..c08bff0f9 100644
--- a/go.mod
+++ b/go.mod
@@ -22,7 +22,7 @@ require (
 	github.com/tetratelabs/wazero v1.6.0
 	github.com/wasilibs/go-pgquery v0.0.0-20231208014744-de63626a1e99
 	github.com/xeipuuv/gojsonschema v1.2.0
-	golang.org/x/sync v0.5.0
+	golang.org/x/sync v0.6.0
 	google.golang.org/grpc v1.60.1
 	google.golang.org/protobuf v1.32.0
 	gopkg.in/yaml.v3 v3.0.1
diff --git a/go.sum b/go.sum
index a3b6c5ff3..390c8155c 100644
--- a/go.sum
+++ b/go.sum
@@ -252,8 +252,8 @@ golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
 golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
-golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
diff --git a/internal/codegen/golang/mysql_type.go b/internal/codegen/golang/mysql_type.go
index 32e1df68c..7029ca961 100644
--- a/internal/codegen/golang/mysql_type.go
+++ b/internal/codegen/golang/mysql_type.go
@@ -38,7 +38,16 @@ func mysqlType(req *plugin.GenerateRequest, options *opts.Options, col *plugin.C
 			return "sql.NullInt32"
 		}
 
-	case "int", "integer", "smallint", "mediumint", "year":
+	case "smallint", "year":
+		if notNull {
+			if unsigned {
+				return "uint16"
+			}
+			return "int16"
+		}
+		return "sql.NullInt16"
+
+	case "int", "integer", "mediumint":
 		if notNull {
 			if unsigned {
 				return "uint32"


Test patch:
diff --git a/internal/endtoend/testdata/datatype/mysql/go/models.go b/internal/endtoend/testdata/datatype/mysql/go/models.go
index 5d426f03b..d5ed3a1d5 100644
--- a/internal/endtoend/testdata/datatype/mysql/go/models.go
+++ b/internal/endtoend/testdata/datatype/mysql/go/models.go
@@ -55,7 +55,7 @@ type DtNumeric struct {
 	A sql.NullInt32
 	B sql.NullInt32
 	C sql.NullInt32
-	D sql.NullInt32
+	D sql.NullInt16
 	E sql.NullInt32
 	F sql.NullInt64
 	G interface{}
@@ -70,7 +70,7 @@ type DtNumericNotNull struct {
 	A int32
 	B int32
 	C int32
-	D int32
+	D int16
 	E int32
 	F int64
 	G interface{}
@@ -85,7 +85,7 @@ type DtNumericUnsigned struct {
 	A sql.NullInt32
 	B sql.NullInt32
 	C sql.NullInt32
-	D sql.NullInt32
+	D sql.NullInt16
 	E sql.NullInt32
 	F sql.NullInt64
 }
diff --git a/internal/endtoend/testdata/vet_explain/mysql/db/models.go b/internal/endtoend/testdata/vet_explain/mysql/db/models.go
index bbd6b8fba..9dc6afbad 100644
--- a/internal/endtoend/testdata/vet_explain/mysql/db/models.go
+++ b/internal/endtoend/testdata/vet_explain/mysql/db/models.go
@@ -99,7 +99,7 @@ func (ns NullDebugCset) Value() (driver.Value, error) {
 
 type Debug struct {
 	ID               int64
-	Csmallint        int32
+	Csmallint        int16
 	Cint             int32
 	Cinteger         int32
 	Cdecimal         string
@@ -118,7 +118,7 @@ type Debug struct {
 	Cdatetime        time.Time
 	Ctimestamp       time.Time
 	Ctime            time.Time
-	Cyear            int32
+	Cyear            int16
 	Cchar            string
 	Cvarchar         string
 	Cbinary          []byte
diff --git a/internal/endtoend/testdata/vet_explain/mysql/db/query.sql.go b/internal/endtoend/testdata/vet_explain/mysql/db/query.sql.go
index d14bdff60..14704b9c9 100644
--- a/internal/endtoend/testdata/vet_explain/mysql/db/query.sql.go
+++ b/internal/endtoend/testdata/vet_explain/mysql/db/query.sql.go
@@ -316,7 +316,7 @@ SELECT id FROM debug
 WHERE Csmallint = ? LIMIT 1
 `
 
-func (q *Queries) SelectByCsmallint(ctx context.Context, csmallint int32) (int64, error) {
+func (q *Queries) SelectByCsmallint(ctx context.Context, csmallint int16) (int64, error) {
 	row := q.db.QueryRowContext(ctx, selectByCsmallint, csmallint)
 	var id int64
 	err := row.Scan(&id)
@@ -424,7 +424,7 @@ SELECT id FROM debug
 WHERE Cyear = ? LIMIT 1
 `
 
-func (q *Queries) SelectByCyear(ctx context.Context, cyear int32) (int64, error) {
+func (q *Queries) SelectByCyear(ctx context.Context, cyear int16) (int64, error) {
 	row := q.db.QueryRowContext(ctx, selectByCyear, cyear)
 	var id int64
 	err := row.Scan(&id)