Skip to content

Generated code returns nil slice instead of empty slice for zero results #3910

Open
@vdemcak

Description

@vdemcak

What do you want to change?

When generating code for queries that return slices, the generated code initializes the slice as nil instead of an empty slice. When this nil slice is marshaled to JSON, it becomes null instead of [], which can be unexpected for API consumers who expect consistent array responses.

Current Behavior

Currently generated code:

func (q *Queries) ListUserOrganizations(ctx context.Context, userID string) ([]ListUserOrganizationsRow, error) {
    rows, err := q.db.Query(ctx, listUserOrganizations, userID)
    if err != nil {
        return nil, err
    }
    defer rows.Close()
    var items []ListUserOrganizationsRow  // initializes as nil
    for rows.Next() {
        var i ListUserOrganizationsRow
        if err := rows.Scan(&i.ID, &i.Name); err != nil {
            return nil, err
        }
        items = append(items, i)
    }
    return items, nil  // returns nil if no rows found
}

When marshaled to JSON:

{
    "data": null
}

Desired Behavior

Proposed generated code:

func (q *Queries) ListUserOrganizations(ctx context.Context, userID string) ([]ListUserOrganizationsRow, error) {
    rows, err := q.db.Query(ctx, listUserOrganizations, userID)
    if err != nil {
        return nil, err
    }
    defer rows.Close()
    items := []ListUserOrganizationsRow{}  // initialize as empty slice
    for rows.Next() {
        var i ListUserOrganizationsRow
        if err := rows.Scan(&i.ID, &i.Name); err != nil {
            return nil, err
        }
        items = append(items, i)
    }
    return items, nil  // returns empty slice if no rows found
}

When marshaled to JSON:

{
    "data": []
}

Feature Request

Add a configuration option to control whether slice results should be initialized as nil or empty slices. This would allow users to choose between:

  • Current behaviour (nil slices, marshals to null)
  • Empty slices (marshals to [])

Use Case

This is particularly important for REST APIs where consumers expect consistent types in responses. Having an array field sometimes return null and sometimes [] can cause issues with client-side type checking and handling.

However, having this configurable in sqlc would provide a cleaner solution and consistent behavior across generated code.

What database engines need to be changed?

PostgreSQL

What programming language backends need to be changed?

Go

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions