diff --git a/docs/reference/config.md b/docs/reference/config.md index 6308c901bc..6dd39bf114 100644 --- a/docs/reference/config.md +++ b/docs/reference/config.md @@ -154,7 +154,7 @@ The `gen` mapping supports the following keys: - `emit_methods_with_db_argument`: - If true, generated methods will accept a DBTX argument instead of storing a DBTX on the `*Queries` struct. Defaults to `false`. - `emit_pointers_for_null_types`: - - If true and `sql_package` is set to `pgx/v4` or `pgx/v5`, generated types for nullable columns are emitted as pointers (ie. `*string`) instead of `database/sql` null types (ie. `NullString`). Defaults to `false`. + - If true, generated types for nullable columns are emitted as pointers (ie. `*string`) instead of `database/sql` null types (ie. `NullString`). Currently only supported for PostgreSQL if `sql_package` is `pgx/v4` or `pgx/v5`, and for SQLite. Defaults to `false`. - `emit_enum_valid_method`: - If true, generate a Valid method on enum types, indicating whether a string is a valid enum value. diff --git a/internal/codegen/golang/go_type.go b/internal/codegen/golang/go_type.go index 4c491cba5a..0d72621efe 100644 --- a/internal/codegen/golang/go_type.go +++ b/internal/codegen/golang/go_type.go @@ -85,7 +85,7 @@ func goInnerType(req *plugin.GenerateRequest, options *opts.Options, col *plugin case "postgresql": return postgresType(req, options, col) case "sqlite": - return sqliteType(req, col) + return sqliteType(req, options, col) default: return "interface{}" } diff --git a/internal/codegen/golang/sqlite_type.go b/internal/codegen/golang/sqlite_type.go index a0117e69e4..92c13557f6 100644 --- a/internal/codegen/golang/sqlite_type.go +++ b/internal/codegen/golang/sqlite_type.go @@ -4,14 +4,16 @@ import ( "log" "strings" + "github.com/sqlc-dev/sqlc/internal/codegen/golang/opts" "github.com/sqlc-dev/sqlc/internal/codegen/sdk" "github.com/sqlc-dev/sqlc/internal/debug" "github.com/sqlc-dev/sqlc/internal/plugin" ) -func sqliteType(req *plugin.GenerateRequest, col *plugin.Column) string { +func sqliteType(req *plugin.GenerateRequest, options *opts.Options, col *plugin.Column) string { dt := strings.ToLower(sdk.DataType(col.Type)) notNull := col.NotNull || col.IsArray + emitPointersForNull := options.EmitPointersForNullTypes switch dt { @@ -19,6 +21,9 @@ func sqliteType(req *plugin.GenerateRequest, col *plugin.Column) string { if notNull { return "int64" } + if emitPointersForNull { + return "*int64" + } return "sql.NullInt64" case "blob": @@ -28,18 +33,27 @@ func sqliteType(req *plugin.GenerateRequest, col *plugin.Column) string { if notNull { return "float64" } + if emitPointersForNull { + return "*float64" + } return "sql.NullFloat64" case "boolean", "bool": if notNull { return "bool" } + if emitPointersForNull { + return "*bool" + } return "sql.NullBool" case "date", "datetime", "timestamp": if notNull { return "time.Time" } + if emitPointersForNull { + return "*time.Time" + } return "sql.NullTime" case "any": @@ -60,12 +74,18 @@ func sqliteType(req *plugin.GenerateRequest, col *plugin.Column) string { if notNull { return "string" } + if emitPointersForNull { + return "*string" + } return "sql.NullString" case strings.HasPrefix(dt, "decimal"), dt == "numeric": if notNull { return "float64" } + if emitPointersForNull { + return "*float64" + } return "sql.NullFloat64" default: diff --git a/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/go/db.go b/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/go/db.go new file mode 100644 index 0000000000..b2523a3c90 --- /dev/null +++ b/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.24.0 + +package datatype + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/go/models.go b/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/go/models.go new file mode 100644 index 0000000000..0a9117e062 --- /dev/null +++ b/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/go/models.go @@ -0,0 +1,27 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.24.0 + +package datatype + +import ( + "time" +) + +type DtType struct { + A *int64 + B *float64 + C *bool + D *time.Time + E *string + F *float64 +} + +type DtTypesNotNull struct { + A int64 + B float64 + C bool + D time.Time + E string + F float64 +} diff --git a/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/sql/query.sql b/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/sql/query.sql new file mode 100644 index 0000000000..e0ac49d1ec --- /dev/null +++ b/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/sql/query.sql @@ -0,0 +1 @@ +SELECT 1; diff --git a/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/sql/types.sql b/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/sql/types.sql new file mode 100644 index 0000000000..eb55c80eda --- /dev/null +++ b/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/sql/types.sql @@ -0,0 +1,18 @@ + +CREATE TABLE dt_types ( + a int, + b real, + c bool, + d date, + e text, + f numeric +); + +CREATE TABLE dt_types_not_null ( + a int NOT NULL, + b real NOT NULL, + c bool NOT NULL, + d date NOT NULL, + e text NOT NULL, + f numeric NOT NULL +); diff --git a/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/sqlc.json b/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/sqlc.json new file mode 100644 index 0000000000..e62c271419 --- /dev/null +++ b/internal/endtoend/testdata/emit_pointers_for_null_types/sqlite/sqlc.json @@ -0,0 +1,13 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "sqlite", + "name": "datatype", + "schema": "sql/", + "queries": "sql/", + "emit_pointers_for_null_types": true + } + ] +}