Skip to content

Commit c41c3ca

Browse files
fix: let sqlc output nullable array
This allow postgres to output nullable array. Co-authored-by: Conrad Hoffmann <ch@bitfehler.net>
1 parent 47bcc02 commit c41c3ca

27 files changed

Lines changed: 545 additions & 10 deletions

File tree

docs/reference/config.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ sql:
1414
queries: "postgresql/query.sql"
1515
engine: "postgresql"
1616
gen:
17-
go:
17+
go:
1818
package: "authors"
1919
out: "postgresql"
2020
database:
@@ -122,7 +122,7 @@ The `analyzer` mapping supports the following keys:
122122

123123
- `database`:
124124
- If false, do not use the configured database for query analysis. Defaults to `true`.
125-
125+
126126
### gen
127127

128128
The `gen` mapping supports the following keys:
@@ -161,6 +161,8 @@ The `gen` mapping supports the following keys:
161161
- 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`. Nullable enum columns also follow this setting unless `emit_pointers_for_null_enum_types` is set.
162162
- `emit_pointers_for_null_enum_types`:
163163
- Overrides `emit_pointers_for_null_types` for nullable enum columns only. When `true`, nullable enum columns are emitted as pointers (ie. `*UserRole`). When `false`, nullable enum columns use the generated `NullUserRole` wrapper struct even if `emit_pointers_for_null_types` is true. Set this to `false` to keep the pre-v1.31 behavior when upgrading. Only applies to PostgreSQL with `sql_package` `pgx/v4` or `pgx/v5`.
164+
- `emit_nullable_for_null_arrays`:
165+
- If true, generated types for nullable columns with array types are emitted as list of nullable instead of a list of non-nullable. For example, `bool[]` SQL type is emitted as `[]sql.NullBool` instead of `[]bool` when the flag is set. Defaults to `false`.
164166
- `emit_enum_valid_method`:
165167
- If true, generate a Valid method on enum types,
166168
indicating whether a string is a valid enum value.
@@ -257,18 +259,18 @@ Each mapping in the `plugins` collection has the following keys:
257259
- The URL to fetch the WASM file. Supports the `https://` or `file://` schemes.
258260
- `sha256`
259261
- The SHA256 checksum for the downloaded file.
260-
262+
261263
```yaml
262264
version: "2"
263265
plugins:
264266
- name: "py"
265-
wasm:
267+
wasm:
266268
url: "https://github.com/sqlc-dev/sqlc-gen-python/releases/download/v0.16.0-alpha/sqlc-gen-python.wasm"
267269
sha256: "428476c7408fd4c032da4ec74e8a7344f4fa75e0f98a5a3302f238283b9b95f2"
268270
- name: "js"
269271
env:
270272
- PATH
271-
process:
273+
process:
272274
cmd: "sqlc-gen-json"
273275
```
274276

@@ -285,7 +287,7 @@ Each mapping in the `rules` collection has the following keys:
285287

286288
See the [vet](../howto/vet.md) documentation for a list of built-in rules and
287289
help writing custom rules.
288-
290+
289291
```yaml
290292
version: "2"
291293
sql:
@@ -319,7 +321,7 @@ rules:
319321
rule: |
320322
query.cmd == "exec"
321323
```
322-
324+
323325
### Global overrides
324326

325327
Sometimes, the same configuration must be done across various specifications of

internal/codegen/golang/mysql_type.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111

1212
func mysqlType(req *plugin.GenerateRequest, options *opts.Options, col *plugin.Column) string {
1313
columnType := sdk.DataType(col.Type)
14-
notNull := col.NotNull || col.IsArray
14+
notNull := col.NotNull || (col.IsArray && !options.EmitNullableForNullArrays)
1515
unsigned := col.Unsigned
1616

1717
switch columnType {

internal/codegen/golang/opts/options.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type Options struct {
2424
EmitPointersForNullTypes bool `json:"emit_pointers_for_null_types" yaml:"emit_pointers_for_null_types"`
2525
// nil inherits EmitPointersForNullTypes; non-nil overrides for enums only.
2626
EmitPointersForNullEnumTypes *bool `json:"emit_pointers_for_null_enum_types,omitempty" yaml:"emit_pointers_for_null_enum_types"`
27+
EmitNullableForNullArrays bool `json:"emit_nullable_for_null_arrays" yaml:"emit_nullable_for_null_arrays"`
2728
EmitEnumValidMethod bool `json:"emit_enum_valid_method,omitempty" yaml:"emit_enum_valid_method"`
2829
EmitAllEnumValues bool `json:"emit_all_enum_values,omitempty" yaml:"emit_all_enum_values"`
2930
EmitSqlAsComment bool `json:"emit_sql_as_comment,omitempty" yaml:"emit_sql_as_comment"`

internal/codegen/golang/postgresql_type.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func parseIdentifierString(name string) (*plugin.Identifier, error) {
3636

3737
func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugin.Column) string {
3838
columnType := sdk.DataType(col.Type)
39-
notNull := col.NotNull || col.IsArray
39+
notNull := col.NotNull || (col.IsArray && !options.EmitNullableForNullArrays)
4040
driver := parseDriver(options.SqlPackage)
4141
emitPointersForNull := driver.IsPGX() && options.EmitPointersForNullTypes
4242
emitPointersForNullEnums := emitPointersForNull

internal/codegen/golang/sqlite_type.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212

1313
func sqliteType(req *plugin.GenerateRequest, options *opts.Options, col *plugin.Column) string {
1414
dt := strings.ToLower(sdk.DataType(col.Type))
15-
notNull := col.NotNull || col.IsArray
15+
notNull := col.NotNull || (col.IsArray && !options.EmitNullableForNullArrays)
1616
emitPointersForNull := options.EmitPointersForNullTypes
1717

1818
switch dt {

internal/config/v_one.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type v1PackageSettings struct {
4040
EmitMethodsWithDBArgument bool `json:"emit_methods_with_db_argument" yaml:"emit_methods_with_db_argument"`
4141
EmitPointersForNullTypes bool `json:"emit_pointers_for_null_types" yaml:"emit_pointers_for_null_types"`
4242
EmitPointersForNullEnumTypes *bool `json:"emit_pointers_for_null_enum_types,omitempty" yaml:"emit_pointers_for_null_enum_types"`
43+
EmitNullableForNullArrays bool `json:"emit_nullable_for_null_arrays" yaml:"emit_nullable_for_null_arrays"`
4344
EmitEnumValidMethod bool `json:"emit_enum_valid_method,omitempty" yaml:"emit_enum_valid_method"`
4445
EmitAllEnumValues bool `json:"emit_all_enum_values,omitempty" yaml:"emit_all_enum_values"`
4546
EmitSqlAsComment bool `json:"emit_sql_as_comment,omitempty" yaml:"emit_sql_as_comment"`
@@ -155,6 +156,7 @@ func (c *V1GenerateSettings) Translate() Config {
155156
EmitMethodsWithDbArgument: pkg.EmitMethodsWithDBArgument,
156157
EmitPointersForNullTypes: pkg.EmitPointersForNullTypes,
157158
EmitPointersForNullEnumTypes: pkg.EmitPointersForNullEnumTypes,
159+
EmitNullableForNullArrays: pkg.EmitNullableForNullArrays,
158160
EmitEnumValidMethod: pkg.EmitEnumValidMethod,
159161
EmitAllEnumValues: pkg.EmitAllEnumValues,
160162
EmitSqlAsComment: pkg.EmitSqlAsComment,

internal/endtoend/testdata/unnest_null/postgresql/pgx/v4/go/db.go

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

internal/endtoend/testdata/unnest_null/postgresql/pgx/v4/go/models.go

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

internal/endtoend/testdata/unnest_null/postgresql/pgx/v4/go/querier.go

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

internal/endtoend/testdata/unnest_null/postgresql/pgx/v4/go/query.sql.go

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

0 commit comments

Comments
 (0)