diff --git a/docs/reference/config.md b/docs/reference/config.md index 85e68cf05b..f17e45534d 100644 --- a/docs/reference/config.md +++ b/docs/reference/config.md @@ -157,6 +157,8 @@ The `gen` mapping supports the following keys: - 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, 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`. +- `generic_null_type`: + - A fully qualified name to a Go type that is used to wrap nullable fields; for example, `database/sql.Null` would represent a nullable `string` as `sql.Null[string]`. For more complicated import paths, `generic_null_type` can also be an object with the same keys as `go_type` below. - `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/imports.go b/internal/codegen/golang/imports.go index 9e7819e4b1..4e64d9a832 100644 --- a/internal/codegen/golang/imports.go +++ b/internal/codegen/golang/imports.go @@ -243,6 +243,19 @@ func buildImports(options *opts.Options, queries []Query, uses func(string) bool } } + // Ensure custom null type is imported + if options.GenericNullType != nil { + t := options.GenericNullType.Parsed + + if !(t.BasicType && t.TypeName == "") { + _, alreadyImported := std[t.ImportPath] + hasPackageAlias := t.Package != "" + if (!alreadyImported || hasPackageAlias) && uses(t.TypeName) { + pkg[ImportSpec{Path: t.ImportPath, ID: t.Package}] = struct{}{} + } + } + } + return std, pkg } diff --git a/internal/codegen/golang/mysql_type.go b/internal/codegen/golang/mysql_type.go index 7029ca9615..b83c190d0d 100644 --- a/internal/codegen/golang/mysql_type.go +++ b/internal/codegen/golang/mysql_type.go @@ -14,12 +14,20 @@ func mysqlType(req *plugin.GenerateRequest, options *opts.Options, col *plugin.C notNull := col.NotNull || col.IsArray unsigned := col.Unsigned + var genericNull *opts.ParsedGoType + if options.GenericNullType != nil { + genericNull = &options.GenericNullType.Parsed + } + switch columnType { case "varchar", "text", "char", "tinytext", "mediumtext", "longtext": if notNull { return "string" } + if genericNull != nil { + return genericNull.TypeName + "[string]" + } return "sql.NullString" case "tinyint": @@ -29,39 +37,59 @@ func mysqlType(req *plugin.GenerateRequest, options *opts.Options, col *plugin.C } return "sql.NullBool" } else { + baseType := "int32" + if unsigned { + baseType = "uint32" + } + if notNull { - if unsigned { - return "uint32" - } - return "int32" + return baseType + } + if genericNull != nil { + return genericNull.TypeName + "[" + baseType + "]" } return "sql.NullInt32" } case "smallint", "year": + baseType := "int16" + if unsigned { + baseType = "uint16" + } + if notNull { - if unsigned { - return "uint16" - } - return "int16" + return baseType + } + if genericNull != nil { + return genericNull.TypeName + "[" + baseType + "]" } return "sql.NullInt16" case "int", "integer", "mediumint": + baseType := "int32" + if unsigned { + baseType = "uint32" + } + if notNull { - if unsigned { - return "uint32" - } - return "int32" + return baseType + } + if genericNull != nil { + return genericNull.TypeName + "[" + baseType + "]" } return "sql.NullInt32" case "bigint": + baseType := "int64" + if unsigned { + baseType = "uint64" + } + if notNull { - if unsigned { - return "uint64" - } - return "int64" + return baseType + } + if genericNull != nil { + return genericNull.TypeName + "[" + baseType + "]" } return "sql.NullInt64" @@ -69,18 +97,27 @@ func mysqlType(req *plugin.GenerateRequest, options *opts.Options, col *plugin.C if notNull { return "[]byte" } + if genericNull != nil { + return genericNull.TypeName + "[[]byte]" + } return "sql.NullString" case "double", "double precision", "real", "float": if notNull { return "float64" } + if genericNull != nil { + return genericNull.TypeName + "[float64]" + } return "sql.NullFloat64" case "decimal", "dec", "fixed": if notNull { return "string" } + if genericNull != nil { + return genericNull.TypeName + "[string]" + } return "sql.NullString" case "enum": @@ -91,12 +128,18 @@ func mysqlType(req *plugin.GenerateRequest, options *opts.Options, col *plugin.C if notNull { return "time.Time" } + if genericNull != nil { + return genericNull.TypeName + "[time.Time]" + } return "sql.NullTime" case "boolean", "bool": if notNull { return "bool" } + if genericNull != nil { + return genericNull.TypeName + "[bool]" + } return "sql.NullBool" case "json": diff --git a/internal/codegen/golang/opts/options.go b/internal/codegen/golang/opts/options.go index 0e2a8562e5..58b717b683 100644 --- a/internal/codegen/golang/opts/options.go +++ b/internal/codegen/golang/opts/options.go @@ -10,39 +10,40 @@ import ( ) type Options struct { - EmitInterface bool `json:"emit_interface" yaml:"emit_interface"` - EmitJsonTags bool `json:"emit_json_tags" yaml:"emit_json_tags"` - JsonTagsIdUppercase bool `json:"json_tags_id_uppercase" yaml:"json_tags_id_uppercase"` - EmitDbTags bool `json:"emit_db_tags" yaml:"emit_db_tags"` - EmitPreparedQueries bool `json:"emit_prepared_queries" yaml:"emit_prepared_queries"` - EmitExactTableNames bool `json:"emit_exact_table_names,omitempty" yaml:"emit_exact_table_names"` - EmitEmptySlices bool `json:"emit_empty_slices,omitempty" yaml:"emit_empty_slices"` - EmitExportedQueries bool `json:"emit_exported_queries" yaml:"emit_exported_queries"` - EmitResultStructPointers bool `json:"emit_result_struct_pointers" yaml:"emit_result_struct_pointers"` - EmitParamsStructPointers bool `json:"emit_params_struct_pointers" yaml:"emit_params_struct_pointers"` - EmitMethodsWithDbArgument bool `json:"emit_methods_with_db_argument,omitempty" yaml:"emit_methods_with_db_argument"` - EmitPointersForNullTypes bool `json:"emit_pointers_for_null_types" yaml:"emit_pointers_for_null_types"` - EmitEnumValidMethod bool `json:"emit_enum_valid_method,omitempty" yaml:"emit_enum_valid_method"` - EmitAllEnumValues bool `json:"emit_all_enum_values,omitempty" yaml:"emit_all_enum_values"` - EmitSqlAsComment bool `json:"emit_sql_as_comment,omitempty" yaml:"emit_sql_as_comment"` - JsonTagsCaseStyle string `json:"json_tags_case_style,omitempty" yaml:"json_tags_case_style"` - Package string `json:"package" yaml:"package"` - Out string `json:"out" yaml:"out"` - Overrides []Override `json:"overrides,omitempty" yaml:"overrides"` - Rename map[string]string `json:"rename,omitempty" yaml:"rename"` - SqlPackage string `json:"sql_package" yaml:"sql_package"` - SqlDriver string `json:"sql_driver" yaml:"sql_driver"` - OutputBatchFileName string `json:"output_batch_file_name,omitempty" yaml:"output_batch_file_name"` - OutputDbFileName string `json:"output_db_file_name,omitempty" yaml:"output_db_file_name"` - OutputModelsFileName string `json:"output_models_file_name,omitempty" yaml:"output_models_file_name"` - OutputQuerierFileName string `json:"output_querier_file_name,omitempty" yaml:"output_querier_file_name"` - OutputCopyfromFileName string `json:"output_copyfrom_file_name,omitempty" yaml:"output_copyfrom_file_name"` - OutputFilesSuffix string `json:"output_files_suffix,omitempty" yaml:"output_files_suffix"` - InflectionExcludeTableNames []string `json:"inflection_exclude_table_names,omitempty" yaml:"inflection_exclude_table_names"` - QueryParameterLimit *int32 `json:"query_parameter_limit,omitempty" yaml:"query_parameter_limit"` - OmitSqlcVersion bool `json:"omit_sqlc_version,omitempty" yaml:"omit_sqlc_version"` - OmitUnusedStructs bool `json:"omit_unused_structs,omitempty" yaml:"omit_unused_structs"` - BuildTags string `json:"build_tags,omitempty" yaml:"build_tags"` + EmitInterface bool `json:"emit_interface" yaml:"emit_interface"` + EmitJsonTags bool `json:"emit_json_tags" yaml:"emit_json_tags"` + JsonTagsIdUppercase bool `json:"json_tags_id_uppercase" yaml:"json_tags_id_uppercase"` + EmitDbTags bool `json:"emit_db_tags" yaml:"emit_db_tags"` + EmitPreparedQueries bool `json:"emit_prepared_queries" yaml:"emit_prepared_queries"` + EmitExactTableNames bool `json:"emit_exact_table_names,omitempty" yaml:"emit_exact_table_names"` + EmitEmptySlices bool `json:"emit_empty_slices,omitempty" yaml:"emit_empty_slices"` + EmitExportedQueries bool `json:"emit_exported_queries" yaml:"emit_exported_queries"` + EmitResultStructPointers bool `json:"emit_result_struct_pointers" yaml:"emit_result_struct_pointers"` + EmitParamsStructPointers bool `json:"emit_params_struct_pointers" yaml:"emit_params_struct_pointers"` + EmitMethodsWithDbArgument bool `json:"emit_methods_with_db_argument,omitempty" yaml:"emit_methods_with_db_argument"` + EmitPointersForNullTypes bool `json:"emit_pointers_for_null_types" yaml:"emit_pointers_for_null_types"` + EmitEnumValidMethod bool `json:"emit_enum_valid_method,omitempty" yaml:"emit_enum_valid_method"` + EmitAllEnumValues bool `json:"emit_all_enum_values,omitempty" yaml:"emit_all_enum_values"` + EmitSqlAsComment bool `json:"emit_sql_as_comment,omitempty" yaml:"emit_sql_as_comment"` + JsonTagsCaseStyle string `json:"json_tags_case_style,omitempty" yaml:"json_tags_case_style"` + Package string `json:"package" yaml:"package"` + Out string `json:"out" yaml:"out"` + Overrides []Override `json:"overrides,omitempty" yaml:"overrides"` + Rename map[string]string `json:"rename,omitempty" yaml:"rename"` + SqlPackage string `json:"sql_package" yaml:"sql_package"` + SqlDriver string `json:"sql_driver" yaml:"sql_driver"` + OutputBatchFileName string `json:"output_batch_file_name,omitempty" yaml:"output_batch_file_name"` + OutputDbFileName string `json:"output_db_file_name,omitempty" yaml:"output_db_file_name"` + OutputModelsFileName string `json:"output_models_file_name,omitempty" yaml:"output_models_file_name"` + OutputQuerierFileName string `json:"output_querier_file_name,omitempty" yaml:"output_querier_file_name"` + OutputCopyfromFileName string `json:"output_copyfrom_file_name,omitempty" yaml:"output_copyfrom_file_name"` + OutputFilesSuffix string `json:"output_files_suffix,omitempty" yaml:"output_files_suffix"` + InflectionExcludeTableNames []string `json:"inflection_exclude_table_names,omitempty" yaml:"inflection_exclude_table_names"` + QueryParameterLimit *int32 `json:"query_parameter_limit,omitempty" yaml:"query_parameter_limit"` + OmitSqlcVersion bool `json:"omit_sqlc_version,omitempty" yaml:"omit_sqlc_version"` + OmitUnusedStructs bool `json:"omit_unused_structs,omitempty" yaml:"omit_unused_structs"` + BuildTags string `json:"build_tags,omitempty" yaml:"build_tags"` + GenericNullType *GenericNullOption `json:"generic_null_type" yaml:"generic_null_type"` } type GlobalOptions struct { @@ -50,6 +51,12 @@ type GlobalOptions struct { Rename map[string]string `json:"rename,omitempty" yaml:"rename"` } +type GenericNullOption struct { + GoType + + Parsed ParsedGoType `json:"-"` +} + func Parse(req *plugin.GenerateRequest) (*Options, error) { options, err := parseOpts(req) if err != nil { @@ -106,6 +113,14 @@ func parseOpts(req *plugin.GenerateRequest) (*Options, error) { } } + if options.GenericNullType != nil { + parsed, err := options.GenericNullType.parse() + if err != nil { + return nil, err + } + options.GenericNullType.Parsed = *parsed + } + if options.QueryParameterLimit == nil { options.QueryParameterLimit = new(int32) *options.QueryParameterLimit = 1 @@ -137,6 +152,9 @@ func ValidateOpts(opts *Options) error { if *opts.QueryParameterLimit < 0 { return fmt.Errorf("invalid options: query parameter limit must not be negative") } + if opts.EmitPointersForNullTypes && opts.GenericNullType != nil { + return fmt.Errorf("invalid options: emit_pointers_for_null_types and generic_null_type are mutually exclusive") + } return nil } diff --git a/internal/codegen/golang/postgresql_type.go b/internal/codegen/golang/postgresql_type.go index 563cc09ab9..a3f965e0e1 100644 --- a/internal/codegen/golang/postgresql_type.go +++ b/internal/codegen/golang/postgresql_type.go @@ -40,6 +40,11 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi driver := parseDriver(options.SqlPackage) emitPointersForNull := driver.IsPGX() && options.EmitPointersForNullTypes + var genericNull *opts.ParsedGoType + if options.GenericNullType != nil { + genericNull = &options.GenericNullType.Parsed + } + switch columnType { case "serial", "serial4", "pg_catalog.serial4": if notNull { @@ -48,6 +53,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*int32" } + if genericNull != nil { + return genericNull.TypeName + "[int32]" + } if driver == opts.SQLDriverPGXV5 { return "pgtype.Int4" } @@ -60,6 +68,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*int64" } + if genericNull != nil { + return genericNull.TypeName + "[int64]" + } if driver == opts.SQLDriverPGXV5 { return "pgtype.Int8" } @@ -72,6 +83,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*int16" } + if genericNull != nil { + return genericNull.TypeName + "[int16]" + } if driver == opts.SQLDriverPGXV5 { return "pgtype.Int2" } @@ -84,6 +98,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*int32" } + if genericNull != nil { + return genericNull.TypeName + "[int32]" + } if driver == opts.SQLDriverPGXV5 { return "pgtype.Int4" } @@ -96,6 +113,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*int64" } + if genericNull != nil { + return genericNull.TypeName + "[int64]" + } if driver == opts.SQLDriverPGXV5 { return "pgtype.Int8" } @@ -108,6 +128,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*int16" } + if genericNull != nil { + return genericNull.TypeName + "[int16]" + } if driver == opts.SQLDriverPGXV5 { return "pgtype.Int2" } @@ -120,6 +143,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*float64" } + if genericNull != nil { + return genericNull.TypeName + "[float64]" + } if driver == opts.SQLDriverPGXV5 { return "pgtype.Float8" } @@ -132,6 +158,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*float32" } + if genericNull != nil { + return genericNull.TypeName + "[float32]" + } if driver == opts.SQLDriverPGXV5 { return "pgtype.Float4" } @@ -151,6 +180,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*string" } + if genericNull != nil { + return genericNull.TypeName + "[string]" + } return "sql.NullString" case "boolean", "bool", "pg_catalog.bool": @@ -160,6 +192,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*bool" } + if genericNull != nil { + return genericNull.TypeName + "[bool]" + } if driver == opts.SQLDriverPGXV5 { return "pgtype.Bool" } @@ -210,6 +245,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*time.Time" } + if genericNull != nil { + return genericNull.TypeName + "[time.Time]" + } return "sql.NullTime" case "pg_catalog.time": @@ -222,6 +260,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*time.Time" } + if genericNull != nil { + return genericNull.TypeName + "[time.Time]" + } return "sql.NullTime" case "pg_catalog.timetz": @@ -231,6 +272,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*time.Time" } + if genericNull != nil { + return genericNull.TypeName + "[time.Time]" + } return "sql.NullTime" case "pg_catalog.timestamp": @@ -243,6 +287,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*time.Time" } + if genericNull != nil { + return genericNull.TypeName + "[time.Time]" + } return "sql.NullTime" case "pg_catalog.timestamptz", "timestamptz": @@ -255,6 +302,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*time.Time" } + if genericNull != nil { + return genericNull.TypeName + "[time.Time]" + } return "sql.NullTime" case "text", "pg_catalog.varchar", "pg_catalog.bpchar", "string", "citext", "name": @@ -264,6 +314,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*string" } + if genericNull != nil { + return genericNull.TypeName + "[string]" + } if driver == opts.SQLDriverPGXV5 { return "pgtype.Text" } @@ -279,6 +332,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*uuid.UUID" } + if genericNull != nil { + return genericNull.TypeName + "[uuid.UUID]" + } return "uuid.NullUUID" case "inet": @@ -350,6 +406,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*int64" } + if genericNull != nil { + return genericNull.TypeName + "[int64]" + } return "sql.NullInt64" case "daterange": @@ -593,6 +652,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*string" } + if genericNull != nil { + return genericNull.TypeName + "[string]" + } return "sql.NullString" } } diff --git a/internal/codegen/golang/sqlite_type.go b/internal/codegen/golang/sqlite_type.go index 92c13557f6..49b8d35002 100644 --- a/internal/codegen/golang/sqlite_type.go +++ b/internal/codegen/golang/sqlite_type.go @@ -14,6 +14,11 @@ func sqliteType(req *plugin.GenerateRequest, options *opts.Options, col *plugin. dt := strings.ToLower(sdk.DataType(col.Type)) notNull := col.NotNull || col.IsArray emitPointersForNull := options.EmitPointersForNullTypes + + var genericNull *opts.ParsedGoType + if options.GenericNullType != nil { + genericNull = &options.GenericNullType.Parsed + } switch dt { @@ -24,6 +29,9 @@ func sqliteType(req *plugin.GenerateRequest, options *opts.Options, col *plugin. if emitPointersForNull { return "*int64" } + if genericNull != nil { + return genericNull.TypeName + "[int64]" + } return "sql.NullInt64" case "blob": @@ -36,6 +44,9 @@ func sqliteType(req *plugin.GenerateRequest, options *opts.Options, col *plugin. if emitPointersForNull { return "*float64" } + if genericNull != nil { + return genericNull.TypeName + "[float64]" + } return "sql.NullFloat64" case "boolean", "bool": @@ -45,6 +56,9 @@ func sqliteType(req *plugin.GenerateRequest, options *opts.Options, col *plugin. if emitPointersForNull { return "*bool" } + if genericNull != nil { + return genericNull.TypeName + "[bool]" + } return "sql.NullBool" case "date", "datetime", "timestamp": @@ -54,6 +68,9 @@ func sqliteType(req *plugin.GenerateRequest, options *opts.Options, col *plugin. if emitPointersForNull { return "*time.Time" } + if genericNull != nil { + return genericNull.TypeName + "[time.Time]" + } return "sql.NullTime" case "any": @@ -77,6 +94,9 @@ func sqliteType(req *plugin.GenerateRequest, options *opts.Options, col *plugin. if emitPointersForNull { return "*string" } + if genericNull != nil { + return genericNull.TypeName + "[string]" + } return "sql.NullString" case strings.HasPrefix(dt, "decimal"), dt == "numeric": @@ -86,6 +106,9 @@ func sqliteType(req *plugin.GenerateRequest, options *opts.Options, col *plugin. if emitPointersForNull { return "*float64" } + if genericNull != nil { + return genericNull.TypeName + "[float64]" + } return "sql.NullFloat64" default: diff --git a/internal/endtoend/testdata/codegen_generic_null/mysql/go/db.go b/internal/endtoend/testdata/codegen_generic_null/mysql/go/db.go new file mode 100644 index 0000000000..df0488f428 --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/mysql/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 + +package querytest + +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/codegen_generic_null/mysql/go/models.go b/internal/endtoend/testdata/codegen_generic_null/mysql/go/models.go new file mode 100644 index 0000000000..ad7ddac0b9 --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/mysql/go/models.go @@ -0,0 +1,15 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 + +package querytest + +import ( + "github.com/LukaGiorgadze/gonull" +) + +type Foo struct { + ID uint64 + SometimesBlankText gonull.Nullable[string] + SometimesBlankNumeric gonull.Nullable[int32] +} diff --git a/internal/endtoend/testdata/codegen_generic_null/mysql/go/query.sql.go b/internal/endtoend/testdata/codegen_generic_null/mysql/go/query.sql.go new file mode 100644 index 0000000000..532741df63 --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/mysql/go/query.sql.go @@ -0,0 +1,37 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const getFoos = `-- name: GetFoos :many +SELECT id, sometimes_blank_text, sometimes_blank_numeric FROM foo +` + +func (q *Queries) GetFoos(ctx context.Context) ([]Foo, error) { + rows, err := q.db.QueryContext(ctx, getFoos) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Foo + for rows.Next() { + var i Foo + if err := rows.Scan(&i.ID, &i.SometimesBlankText, &i.SometimesBlankNumeric); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/codegen_generic_null/mysql/query.sql b/internal/endtoend/testdata/codegen_generic_null/mysql/query.sql new file mode 100644 index 0000000000..f0f8901fdd --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/mysql/query.sql @@ -0,0 +1,2 @@ +-- name: GetFoos :many +SELECT * FROM foo; diff --git a/internal/endtoend/testdata/codegen_generic_null/mysql/schema.sql b/internal/endtoend/testdata/codegen_generic_null/mysql/schema.sql new file mode 100644 index 0000000000..8ae33904a8 --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/mysql/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE foo ( + id SERIAL NOT NULL, + sometimes_blank_text VARCHAR(255), + sometimes_blank_numeric INT +); diff --git a/internal/endtoend/testdata/codegen_generic_null/mysql/sqlc.yaml b/internal/endtoend/testdata/codegen_generic_null/mysql/sqlc.yaml new file mode 100644 index 0000000000..e9b1cc4109 --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/mysql/sqlc.yaml @@ -0,0 +1,12 @@ +version: "2" +sql: + - engine: "mysql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + generic_null_type: + import: "github.com/LukaGiorgadze/gonull" + type: "Nullable" diff --git a/internal/endtoend/testdata/codegen_generic_null/postgresql/go/db.go b/internal/endtoend/testdata/codegen_generic_null/postgresql/go/db.go new file mode 100644 index 0000000000..df0488f428 --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/postgresql/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 + +package querytest + +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/codegen_generic_null/postgresql/go/models.go b/internal/endtoend/testdata/codegen_generic_null/postgresql/go/models.go new file mode 100644 index 0000000000..2e14a0022e --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/postgresql/go/models.go @@ -0,0 +1,15 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 + +package querytest + +import ( + "github.com/LukaGiorgadze/gonull" +) + +type Foo struct { + ID int64 + SometimesBlankText gonull.Nullable[string] + SometimesBlankNumeric gonull.Nullable[string] +} diff --git a/internal/endtoend/testdata/codegen_generic_null/postgresql/go/query.sql.go b/internal/endtoend/testdata/codegen_generic_null/postgresql/go/query.sql.go new file mode 100644 index 0000000000..532741df63 --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/postgresql/go/query.sql.go @@ -0,0 +1,37 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const getFoos = `-- name: GetFoos :many +SELECT id, sometimes_blank_text, sometimes_blank_numeric FROM foo +` + +func (q *Queries) GetFoos(ctx context.Context) ([]Foo, error) { + rows, err := q.db.QueryContext(ctx, getFoos) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Foo + for rows.Next() { + var i Foo + if err := rows.Scan(&i.ID, &i.SometimesBlankText, &i.SometimesBlankNumeric); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/codegen_generic_null/postgresql/query.sql b/internal/endtoend/testdata/codegen_generic_null/postgresql/query.sql new file mode 100644 index 0000000000..f0f8901fdd --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/postgresql/query.sql @@ -0,0 +1,2 @@ +-- name: GetFoos :many +SELECT * FROM foo; diff --git a/internal/endtoend/testdata/codegen_generic_null/postgresql/schema.sql b/internal/endtoend/testdata/codegen_generic_null/postgresql/schema.sql new file mode 100644 index 0000000000..73803624b8 --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/postgresql/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE foo ( + id BIGSERIAL PRIMARY KEY, + sometimes_blank_text text, + sometimes_blank_numeric text +); diff --git a/internal/endtoend/testdata/codegen_generic_null/postgresql/sqlc.yaml b/internal/endtoend/testdata/codegen_generic_null/postgresql/sqlc.yaml new file mode 100644 index 0000000000..545ce5458d --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/postgresql/sqlc.yaml @@ -0,0 +1,12 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + generic_null_type: + import: "github.com/LukaGiorgadze/gonull" + type: "Nullable" diff --git a/internal/endtoend/testdata/codegen_generic_null/sqlite/go/db.go b/internal/endtoend/testdata/codegen_generic_null/sqlite/go/db.go new file mode 100644 index 0000000000..df0488f428 --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/sqlite/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 + +package querytest + +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/codegen_generic_null/sqlite/go/models.go b/internal/endtoend/testdata/codegen_generic_null/sqlite/go/models.go new file mode 100644 index 0000000000..031319c565 --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/sqlite/go/models.go @@ -0,0 +1,15 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 + +package querytest + +import ( + "github.com/LukaGiorgadze/gonull" +) + +type Foo struct { + ID int64 + SometimesBlankText gonull.Nullable[string] + SometimesBlankNumeric gonull.Nullable[int64] +} diff --git a/internal/endtoend/testdata/codegen_generic_null/sqlite/go/query.sql.go b/internal/endtoend/testdata/codegen_generic_null/sqlite/go/query.sql.go new file mode 100644 index 0000000000..532741df63 --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/sqlite/go/query.sql.go @@ -0,0 +1,37 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const getFoos = `-- name: GetFoos :many +SELECT id, sometimes_blank_text, sometimes_blank_numeric FROM foo +` + +func (q *Queries) GetFoos(ctx context.Context) ([]Foo, error) { + rows, err := q.db.QueryContext(ctx, getFoos) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Foo + for rows.Next() { + var i Foo + if err := rows.Scan(&i.ID, &i.SometimesBlankText, &i.SometimesBlankNumeric); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/codegen_generic_null/sqlite/query.sql b/internal/endtoend/testdata/codegen_generic_null/sqlite/query.sql new file mode 100644 index 0000000000..f0f8901fdd --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/sqlite/query.sql @@ -0,0 +1,2 @@ +-- name: GetFoos :many +SELECT * FROM foo; diff --git a/internal/endtoend/testdata/codegen_generic_null/sqlite/schema.sql b/internal/endtoend/testdata/codegen_generic_null/sqlite/schema.sql new file mode 100644 index 0000000000..2c9556f90a --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/sqlite/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE foo ( + id INTEGER PRIMARY KEY, + sometimes_blank_text TEXT, + sometimes_blank_numeric INTEGER +); diff --git a/internal/endtoend/testdata/codegen_generic_null/sqlite/sqlc.yaml b/internal/endtoend/testdata/codegen_generic_null/sqlite/sqlc.yaml new file mode 100644 index 0000000000..23e26e56be --- /dev/null +++ b/internal/endtoend/testdata/codegen_generic_null/sqlite/sqlc.yaml @@ -0,0 +1,12 @@ +version: "2" +sql: + - engine: "sqlite" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + generic_null_type: + import: "github.com/LukaGiorgadze/gonull" + type: "Nullable" diff --git a/internal/endtoend/testdata/go.mod b/internal/endtoend/testdata/go.mod index e2a7ea704b..e61659bdd0 100644 --- a/internal/endtoend/testdata/go.mod +++ b/internal/endtoend/testdata/go.mod @@ -1,8 +1,9 @@ module github.com/sqlc-dev/sqlc/endtoend -go 1.18 +go 1.21 require ( + github.com/LukaGiorgadze/gonull v1.2.0 github.com/go-sql-driver/mysql v1.7.0 github.com/gofrs/uuid v4.0.0+incompatible github.com/google/uuid v1.3.0 @@ -12,6 +13,7 @@ require ( github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904 github.com/jackc/pgx/v5 v5.4.3 github.com/lib/pq v1.9.0 + github.com/pgvector/pgvector-go v0.1.1 github.com/sqlc-dev/pqtype v0.2.0 github.com/sqlc-dev/sqlc-testdata v1.0.0 github.com/volatiletech/null/v8 v8.1.2 @@ -25,7 +27,6 @@ require ( github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgproto3/v2 v2.0.1 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect - github.com/pgvector/pgvector-go v0.1.1 // indirect github.com/volatiletech/inflect v0.0.1 // indirect github.com/volatiletech/randomize v0.0.1 // indirect github.com/volatiletech/strmangle v0.0.1 // indirect diff --git a/internal/endtoend/testdata/go.sum b/internal/endtoend/testdata/go.sum index a5819e0a3b..8829002e36 100644 --- a/internal/endtoend/testdata/go.sum +++ b/internal/endtoend/testdata/go.sum @@ -1,4 +1,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/LukaGiorgadze/gonull v1.2.0 h1:I+/pHqr9dySqf6A4agJazrFA8XlrUohqdb10nFIaxJU= +github.com/LukaGiorgadze/gonull v1.2.0/go.mod h1:iGbXOBV6y4VkT14x//F3yZiIxe1ylZYor05pZb0/9TM= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -9,6 +11,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/friendsofgo/errors v0.9.2 h1:X6NYxef4efCBdwI7BgS820zFaN7Cphrmb+Pljdzjtgk= github.com/friendsofgo/errors v0.9.2/go.mod h1:yCvFW5AkDIL9qn7suHVLiI/gH228n7PC4Pn44IGoTOI= +github.com/go-pg/pg/v10 v10.11.0 h1:CMKJqLgTrfpE/aOVeLdybezR2om071Vh38OLZjsyMI0= +github.com/go-pg/pg/v10 v10.11.0/go.mod h1:4BpHRoxE61y4Onpof3x1a2SQvi9c+q1dJnrNdMjsroA= +github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU= +github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo= github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -45,8 +51,6 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1: github.com/jackc/pgproto3/v2 v2.0.1 h1:Rdjp4NFjwHnEslx2b66FfCI2S0LhO4itac3hXz6WX9M= github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= @@ -64,16 +68,14 @@ github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXg github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904 h1:SdGWuGg+Cpxq6Z+ArXt0nafaKeTvtKGEoW+yvycspUU= github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= -github.com/jackc/pgx/v5 v5.0.1 h1:JZu9othr7l8so2JMDAGeDUMXqERAuZpovyfl4H50tdg= -github.com/jackc/pgx/v5 v5.0.1/go.mod h1:JBbvW3Hdw77jKl9uJrEDATUZIFM2VFPzRq4RWIhkF4o= -github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU= -github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -123,7 +125,24 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= +github.com/uptrace/bun v1.1.12 h1:sOjDVHxNTuM6dNGaba0wUuz7KvDE1BmNu9Gqs2gJSXQ= +github.com/uptrace/bun v1.1.12/go.mod h1:NPG6JGULBeQ9IU6yHp7YGELRa5Agmd7ATZdz4tGZ6z0= +github.com/uptrace/bun/dialect/pgdialect v1.1.12 h1:m/CM1UfOkoBTglGO5CUTKnIKKOApOYxkcP2qn0F9tJk= +github.com/uptrace/bun/dialect/pgdialect v1.1.12/go.mod h1:Ij6WIxQILxLlL2frUBxUBOZJtLElD2QQNDcu/PWDHTc= +github.com/uptrace/bun/driver/pgdriver v1.1.12 h1:3rRWB1GK0psTJrHwxzNfEij2MLibggiLdTqjTtfHc1w= +github.com/uptrace/bun/driver/pgdriver v1.1.12/go.mod h1:ssYUP+qwSEgeDDS1xm2XBip9el1y9Mi5mTAvLoiADLM= +github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94= +github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ= +github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= +github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/volatiletech/inflect v0.0.1 h1:2a6FcMQyhmPZcLa+uet3VJ8gLn/9svWhJxJYwvE8KsU= github.com/volatiletech/inflect v0.0.1/go.mod h1:IBti31tG6phkHitLlr5j7shC5SOo//x0AjDzaJU1PLA= github.com/volatiletech/null/v8 v8.1.2 h1:kiTiX1PpwvuugKwfvUNX/SU/5A2KGZMXfGD0DUHdKEI= @@ -147,9 +166,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -169,12 +185,10 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -187,7 +201,6 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -200,4 +213,7 @@ gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:a gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo= +mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw=