@@ -120,11 +120,12 @@ type goEmbed struct {
120120 modelType string
121121 modelName string
122122 fields []Field
123+ nullable bool
123124}
124125
125126// look through all the structs and attempt to find a matching one to embed
126127// We need the name of the struct and its field names.
127- func newGoEmbed (embed * plugin.Identifier , structs []Struct , defaultSchema string ) * goEmbed {
128+ func newGoEmbed (embed * plugin.Identifier , structs []Struct , defaultSchema string , nullable bool ) * goEmbed {
128129 if embed == nil {
129130 return nil
130131 }
@@ -147,6 +148,7 @@ func newGoEmbed(embed *plugin.Identifier, structs []Struct, defaultSchema string
147148 modelType : s .Name ,
148149 modelName : s .Name ,
149150 fields : fields ,
151+ nullable : nullable ,
150152 }
151153 }
152154
@@ -304,7 +306,7 @@ func buildQueries(req *plugin.GenerateRequest, options *opts.Options, structs []
304306 columns = append (columns , goColumn {
305307 id : i ,
306308 Column : c ,
307- embed : newGoEmbed (c .EmbedTable , structs , req .Catalog .DefaultSchema ),
309+ embed : newGoEmbed (c .EmbedTable , structs , req .Catalog .DefaultSchema , c . IsNullableEmbed ),
308310 })
309311 }
310312 var err error
@@ -396,6 +398,11 @@ func columnsToStruct(req *plugin.GenerateRequest, options *opts.Options, name st
396398 }
397399 if c .embed == nil {
398400 f .Type = goType (req , options , c .Column )
401+ } else if c .embed .nullable {
402+ f .Type = "*" + c .embed .modelType
403+ f .EmbedFields = c .embed .fields
404+ f .IsNullableEmbed = true
405+ f .NullableEmbedInfo = computeNullableEmbedInfo (c .embed )
399406 } else {
400407 f .Type = c .embed .modelType
401408 f .EmbedFields = c .embed .fields
@@ -435,6 +442,40 @@ func columnsToStruct(req *plugin.GenerateRequest, options *opts.Options, name st
435442 return & gs , nil
436443}
437444
445+ // computeNullableEmbedInfo computes scan metadata for nullable embed fields.
446+ // For each field in the embed, we scan into a pointer-typed temporary variable,
447+ // then check if any temp var is non-nil to construct the struct.
448+ func computeNullableEmbedInfo (embed * goEmbed ) []NullableEmbedFieldInfo {
449+ var infos []NullableEmbedFieldInfo
450+ for _ , f := range embed .fields {
451+ varName := "nembed" + embed .modelName + f .Name
452+ originalType := f .Type
453+ var scanType , validExpr , assignExpr string
454+
455+ if strings .HasPrefix (originalType , "*" ) {
456+ // Already a pointer type (e.g., pgx nullable), scan directly
457+ scanType = originalType
458+ validExpr = varName + " != nil"
459+ assignExpr = varName
460+ } else {
461+ // Wrap in pointer for nullable scan
462+ scanType = "*" + originalType
463+ validExpr = varName + " != nil"
464+ assignExpr = "*" + varName
465+ }
466+
467+ infos = append (infos , NullableEmbedFieldInfo {
468+ TempVarName : varName ,
469+ ScanType : scanType ,
470+ ValidExpr : validExpr ,
471+ AssignExpr : assignExpr ,
472+ StructField : f .Name ,
473+ OriginalType : originalType ,
474+ })
475+ }
476+ return infos
477+ }
478+
438479func checkIncompatibleFieldTypes (fields []Field ) error {
439480 fieldTypes := map [string ]string {}
440481 for _ , field := range fields {
0 commit comments