Skip to content

Commit b804317

Browse files
committed
feat(codegen/go): support emit_pointers_for_null_types for nullable enums
When emit_pointers_for_null_types is enabled, nullable enum columns now generate *EnumType pointers instead of NullEnumType wrapper structs. Previously, this setting only affected built-in types (sql.NullString -> *string), leaving enum types unaffected. Closes #3276
1 parent 07c3808 commit b804317

File tree

17 files changed

+488
-7
lines changed

17 files changed

+488
-7
lines changed

internal/codegen/golang/gen.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ type tmplCtx struct {
4242
OmitSqlcVersion bool
4343
BuildTags string
4444
WrapErrors bool
45+
EmitPointersForNullTypes bool
4546
}
4647

4748
func (t *tmplCtx) OutputQuery(sourceName string) bool {
@@ -140,7 +141,9 @@ func validate(options *opts.Options, enums []Enum, structs []Struct, queries []Q
140141
enumNames := make(map[string]struct{})
141142
for _, enum := range enums {
142143
enumNames[enum.Name] = struct{}{}
143-
enumNames["Null"+enum.Name] = struct{}{}
144+
if !options.EmitPointersForNullTypes {
145+
enumNames["Null"+enum.Name] = struct{}{}
146+
}
144147
}
145148
structNames := make(map[string]struct{})
146149
for _, struckt := range structs {
@@ -192,6 +195,7 @@ func generate(req *plugin.GenerateRequest, options *opts.Options, enums []Enum,
192195
BuildTags: options.BuildTags,
193196
OmitSqlcVersion: options.OmitSqlcVersion,
194197
WrapErrors: options.WrapErrors,
198+
EmitPointersForNullTypes: options.EmitPointersForNullTypes,
195199
}
196200

197201
if tctx.UsesCopyFrom && !tctx.SQLDriver.IsPGX() && options.SqlDriver != opts.SQLDriverGoSQLDriverMySQL {
@@ -396,7 +400,8 @@ func filterUnusedStructs(enums []Enum, structs []Struct, queries []Query) ([]Enu
396400
for _, enum := range enums {
397401
_, keep := keepTypes[enum.Name]
398402
_, keepNull := keepTypes["Null"+enum.Name]
399-
if keep || keepNull {
403+
_, keepPointer := keepTypes["*"+enum.Name]
404+
if keep || keepNull || keepPointer {
400405
keepEnums = append(keepEnums, enum)
401406
}
402407
}

internal/codegen/golang/imports.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,9 @@ func (i *importer) modelImports() fileImports {
276276

277277
if len(i.Enums) > 0 {
278278
std["fmt"] = struct{}{}
279-
std["database/sql/driver"] = struct{}{}
279+
if !i.Options.EmitPointersForNullTypes {
280+
std["database/sql/driver"] = struct{}{}
281+
}
280282
}
281283

282284
return sortedImports(std, pkg)

internal/codegen/golang/mysql_type.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ func mysqlType(req *plugin.GenerateRequest, options *opts.Options, col *plugin.C
1313
columnType := sdk.DataType(col.Type)
1414
notNull := col.NotNull || col.IsArray
1515
unsigned := col.Unsigned
16+
emitPointersForNull := options.EmitPointersForNullTypes
1617

1718
switch columnType {
1819

@@ -127,10 +128,16 @@ func mysqlType(req *plugin.GenerateRequest, options *opts.Options, col *plugin.C
127128
}
128129
return StructName(schema.Name+"_"+enum.Name, options)
129130
} else {
131+
var enumTypeName string
130132
if schema.Name == req.Catalog.DefaultSchema {
131-
return "Null" + StructName(enum.Name, options)
133+
enumTypeName = StructName(enum.Name, options)
134+
} else {
135+
enumTypeName = StructName(schema.Name+"_"+enum.Name, options)
132136
}
133-
return "Null" + StructName(schema.Name+"_"+enum.Name, options)
137+
if emitPointersForNull {
138+
return "*" + enumTypeName
139+
}
140+
return "Null" + enumTypeName
134141
}
135142
}
136143
}

internal/codegen/golang/postgresql_type.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,10 +577,16 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi
577577
}
578578
return StructName(schema.Name+"_"+enum.Name, options)
579579
} else {
580+
var enumTypeName string
580581
if schema.Name == req.Catalog.DefaultSchema {
581-
return "Null" + StructName(enum.Name, options)
582+
enumTypeName = StructName(enum.Name, options)
583+
} else {
584+
enumTypeName = StructName(schema.Name+"_"+enum.Name, options)
582585
}
583-
return "Null" + StructName(schema.Name+"_"+enum.Name, options)
586+
if emitPointersForNull {
587+
return "*" + enumTypeName
588+
}
589+
return "Null" + enumTypeName
584590
}
585591
}
586592
}

internal/codegen/golang/templates/template.tmpl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ func (e *{{.Name}}) Scan(src interface{}) error {
108108
return nil
109109
}
110110

111+
{{ if not $.EmitPointersForNullTypes }}
111112
type Null{{.Name}} struct {
112113
{{.Name}} {{.Name}} {{if .NameTag}}{{$.Q}}{{.NameTag}}{{$.Q}}{{end}}
113114
Valid bool {{if .ValidTag}}{{$.Q}}{{.ValidTag}}{{$.Q}}{{end}} // Valid is true if {{.Name}} is not NULL
@@ -131,6 +132,8 @@ func (ns Null{{.Name}}) Value() (driver.Value, error) {
131132
return string(ns.{{.Name}}), nil
132133
}
133134

135+
{{ end }}
136+
134137

135138
{{ if $.EmitEnumValidMethod }}
136139
func (e {{.Name}}) Valid() bool {

internal/endtoend/testdata/emit_pointers_for_null_types_enum/mysql/go/db.go

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/emit_pointers_for_null_types_enum/mysql/go/models.go

Lines changed: 63 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/emit_pointers_for_null_types_enum/mysql/go/query.sql.go

Lines changed: 107 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
-- name: GetAll :many
2+
SELECT * FROM users;
3+
4+
-- name: NewUser :exec
5+
INSERT INTO users (
6+
first_name,
7+
last_name,
8+
age,
9+
shoe_size,
10+
shirt_size
11+
) VALUES
12+
(?, ?, ?, ?, ?);
13+
14+
-- name: UpdateSizes :exec
15+
UPDATE users
16+
SET shoe_size = ?, shirt_size = ?
17+
WHERE id = ?;
18+
19+
-- name: DeleteBySize :exec
20+
DELETE FROM users
21+
WHERE shoe_size = ? AND shirt_size = ?;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CREATE TABLE users (
2+
id integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
3+
first_name varchar(255) NOT NULL,
4+
last_name varchar(255),
5+
age integer NOT NULL,
6+
shoe_size ENUM('x-small', 'small', 'medium', 'large', 'x-large') NOT NULL,
7+
shirt_size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
8+
);

0 commit comments

Comments
 (0)