Skip to content

docs: clean up and add to docs regarding type overrides #4060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 104 additions & 16 deletions docs/howto/overrides.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
# Overriding types

.. note:: Type overrides and field renaming are only fully-supported for Go.

In many cases it's useful to tell `sqlc` explicitly what Go type you want it to
use for a query input or output. For instance, a PostgreSQL UUID type will map
to `UUID` from `github.com/jackc/pgx/pgtype` by default when you use
`pgx/v5`, but you may want `sqlc` to use `UUID` from `github.com/google/uuid`
instead.
use for a query input or output. For instance, by default when you use
`pgx/v5`, `sqlc` will map a PostgreSQL UUID type to `UUID` from `github.com/jackc/pgx/pgtype`.
But you may want `sqlc` to use `UUID` from `github.com/google/uuid` instead.

To tell `sqlc` to use a different Go type, add an entry to the `overrides` list in your
configuration.

If you'd like `sqlc` to use a different Go type, specify the package import
path and type in the `overrides` list.
`sqlc` offers two kinds of Go type overrides:
* `db_type` overrides, which override the Go type for a specific database type.
* `column` overrides, which override the Go type for a column or columns by name.

Here's an example including one of each kind:

```yaml
version: "2"
Expand All @@ -22,11 +29,19 @@ sql:
sql_package: "pgx/v5"
overrides:
- db_type: "uuid"
nullable: true
go_type:
import: "github.com/google/uuid"
type: "UUID"
- column: "users.birthday"
go_type: "time.Time"
```

.. tip::
A single `db_type` override configuration applies to either nullable or non-nullable
columns, but not both. If you want the same Go type to override regardless of
nullability, you'll need to configure two overrides: one with `nullable: true` and one without.

## The `overrides` list

Each element in the `overrides` list has the following keys:
Expand All @@ -39,21 +54,23 @@ Each element in the `overrides` list has the following keys:
- The fully-qualified name of a Go type to use in generated code. This is usually a string but can also be [a map](#the-go-type-map) for more complex configurations.
- `go_struct_tag`:
- A reflect-style struct tag to use in generated code, e.g. `a:"b" x:"y,z"`.
If you want `json` or `db` tags for all fields, use `emit_json_tags` or `emit_db_tags` instead.
If you want `json` or `db` tags for all fields, configure `emit_json_tags` or `emit_db_tags` instead.
- `unsigned`:
- If `true`, sqlc will apply this override when a numeric db_type is unsigned.
Note that this has no effect on `column` overrides. Defaults to `false`.
- If `true`, sqlc will apply this override when a numeric column is unsigned.
Note that this only applies to `db_type` overrides and has no effect on `column` overrides.
Defaults to `false`.
- `nullable`:
- If `true`, sqlc will apply this override when a column is nullable.
Otherwise `sqlc` will apply this override when a column is non-nullable.
Note that this has no effect on `column` overrides. Defaults to `false`.
Note that this only applies to `db_type` overrides and has no effect on `column` overrides.
Defaults to `false`.

Note that a single `db_type` override configuration applies to either nullable or non-nullable
columns, but not both. If you want the same Go type to override in both cases, you'll
need to configure two overrides.
.. tip::
A single `db_type` override configuration applies to either nullable or non-nullable
columns, but not both. If you want the same Go type to override regardless of nullability, you'll
need to configure two overrides: one with `nullable: true` and one without.

When generating code, entries using the `column` key will always take precedence over
entries using the `db_type` key.
.. note:: When generating code, `column` override configurations take precedence over `db_type` configurations.

### The `go_type` map

Expand All @@ -80,7 +97,7 @@ sql:
queries: "postgresql/query.sql"
engine: "postgresql"
gen:
go:
go:
package: "authors"
out: "db"
sql_package: "pgx/v5"
Expand All @@ -92,3 +109,74 @@ sql:
type: "MyType"
pointer: true
```

## Global overrides

To override types in all packages that `sqlc` generates, add an override
configuration to the top-level `overrides` section of your `sqlc` config:

```yaml
version: "2"
overrides:
go:
overrides:
- db_type: "pg_catalog.timestamptz"
nullable: true
engine: "postgresql"
go_type:
import: "gopkg.in/guregu/null.v4"
package: "null"
type: "Time"
sql:
- schema: "service1/schema.sql"
queries: "service1/query.sql"
engine: "postgresql"
gen:
go:
package: "service1"
out: "service1"
- schema: "service2/schema.sql"
queries: "service2/query.sql"
engine: "postgresql"
gen:
go:
package: "service2"
out: "service2"
```

Using this configuration, whenever there is a nullable `timestamp with time zone`
column in a Postgres table, `sqlc` will generate Go code using `null.Time`.

Note that the mapping for global type overrides has a field called `engine` that
is absent in per-package type overrides. This field is only used when there are
multiple `sql` sections using different engines. If you're only generating code
for a single database engine you can omit it.

#### Version 1 configuration

If you are using the older version 1 of the `sqlc` configuration format, override
configurations themselves are unchanged but are nested differently.

Per-package configurations are nested under the `overrides` key within an item
in the `packages` list:

```yaml
version: "1"
packages:
- name: "db"
path: "internal/db"
queries: "./sql/query/"
schema: "./sql/schema/"
engine: "postgresql"
overrides: [...]
```

And global configurations are nested under the top-level `overrides` key:

```yaml
version: "1"
packages: [...]
overrides:
- db_type: "uuid"
go_type: "github.com/gofrs/uuid.UUID"
```
108 changes: 7 additions & 101 deletions docs/reference/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,36 +194,11 @@ The `gen` mapping supports the following keys:
- `rename`:
- Customize the name of generated struct fields. See [Renaming fields](../howto/rename.md) for usage information.
- `overrides`:
- It is a collection of definitions that dictates which types are used to map a database types.
- A collection of configurations to override sqlc's default Go type choices. See [Overriding types](../howto/overrides.md) for usage information.

##### overrides

See [Overriding types](../howto/overrides.md) for an in-depth guide to using type overrides. Each mapping of the `overrides` collection has the following keys:

- `db_type`:
- The PostgreSQL or MySQL type to override. Find the full list of supported types in [postgresql_type.go](https://github.com/sqlc-dev/sqlc/blob/main/internal/codegen/golang/postgresql_type.go#L12) or [mysql_type.go](https://github.com/sqlc-dev/sqlc/blob/main/internal/codegen/golang/mysql_type.go#L12). Note that for Postgres you must use the pg_catalog prefixed names where available. Can't be used if the `column` key is defined.
- `column`:
- In case the type overriding should be done on specific a column of a table instead of a type. `column` should be of the form `table.column` but you can be even more specific by specifying `schema.table.column` or `catalog.schema.table.column`. Can't be used if the `db_type` key is defined.
- `go_type`:
- A fully qualified name to a Go type to use in the generated code.
- `go_struct_tag`:
- A reflect-style struct tag to use in the generated code, e.g. `a:"b" x:"y,z"`.
If you want general json/db tags for all fields, use `emit_db_tags` and/or `emit_json_tags` instead.
- `nullable`:
- If `true`, use this type when a column is nullable. Defaults to `false`.

For more complicated import paths, the `go_type` can also be an object with the following keys:

- `import`:
- The import path for the package where the type is defined.
- `package`:
- The package name where the type is defined. This should only be necessary when your import path doesn't end with the desired package name.
- `type`:
- The type name itself, without any package prefix.
- `pointer`:
- If set to `true`, generated code will use pointers to the type rather than the type itself.
- `slice`:
- If set to `true`, generated code will use a slice of the type rather than the type itself.
See [Overriding types](../howto/overrides.md) for an in-depth guide to using type overrides.

#### kotlin

Expand Down Expand Up @@ -356,7 +331,7 @@ overrides:
rename:
id: "Identifier"
overrides:
- db_type: "timestamptz"
- db_type: "pg_catalog.timestamptz"
nullable: true
engine: "postgresql"
go_type:
Expand All @@ -368,7 +343,7 @@ sql:
queries: "postgresql/query.sql"
engine: "postgresql"
gen:
go:
go:
package: "authors"
out: "postgresql"
- schema: "mysql/schema.sql"
Expand Down Expand Up @@ -443,6 +418,8 @@ Each mapping in the `packages` collection has the following keys:
- Either `postgresql` or `mysql`. Defaults to `postgresql`.
- `sql_package`:
- Either `pgx/v4`, `pgx/v5` or `database/sql`. Defaults to `database/sql`.
- `overrides`:
- A list of type override configurations. See the [Overriding types](../howto/overrides.md) guide for details.
- `emit_db_tags`:
- If true, add DB tags to generated structs. Defaults to `false`.
- `emit_prepared_queries`:
Expand Down Expand Up @@ -494,78 +471,7 @@ Each mapping in the `packages` collection has the following keys:

### overrides

The default mapping of PostgreSQL/MySQL types to Go types only uses packages outside
the standard library when it must.

For example, the `uuid` PostgreSQL type is mapped to `github.com/google/uuid`.
If a different Go package for UUIDs is required, specify the package in the
`overrides` array. In this case, I'm going to use the `github.com/gofrs/uuid`
instead.

```yaml
version: "1"
packages: [...]
overrides:
- go_type: "github.com/gofrs/uuid.UUID"
db_type: "uuid"
```

Each override document has the following keys:

- `db_type`:
- The PostgreSQL or MySQL type to override. Find the full list of supported types in [postgresql_type.go](https://github.com/sqlc-dev/sqlc/blob/main/internal/codegen/golang/postgresql_type.go#L12) or [mysql_type.go](https://github.com/sqlc-dev/sqlc/blob/main/internal/codegen/golang/mysql_type.go#L12). Note that for Postgres you must use the pg_catalog prefixed names where available.
- `go_type`:
- A fully qualified name to a Go type to use in the generated code.
- `go_struct_tag`:
- A reflect-style struct tag to use in the generated code, e.g. `a:"b" x:"y,z"`.
If you want general json/db tags for all fields, use `emit_db_tags` and/or `emit_json_tags` instead.
- `nullable`:
- If true, use this type when a column is nullable. Defaults to `false`.

Note that a single `db_type` override configuration applies to either nullable or non-nullable
columns, but not both. If you want a single `go_type` to override in both cases, you'll
need to specify two overrides.

For more complicated import paths, the `go_type` can also be an object.

```yaml
version: "1"
packages: [...]
overrides:
- db_type: "uuid"
go_type:
import: "a/b/v2"
package: "b"
type: "MyType"
```

#### Per-Column Type Overrides

Sometimes you would like to override the Go type used in model or query generation for
a specific field of a table and not on a type basis as described in the previous section.

This may be configured by specifying the `column` property in the override definition. `column`
should be of the form `table.column` but you can be even more specific by specifying `schema.table.column`
or `catalog.schema.table.column`.

```yaml
version: "1"
packages: [...]
overrides:
- column: "authors.id"
go_type: "github.com/segmentio/ksuid.KSUID"
```

#### Package Level Overrides

Overrides can be configured globally, as demonstrated in the previous sections, or they can be configured per-package which
scopes the override behavior to just a single package:

```yaml
version: "1"
packages:
- overrides: [...]
```
See the version 1 configuration section of the [Overriding types](../howto/overrides.md#version-1-configuration) guide for details.

### rename

Expand Down
15 changes: 9 additions & 6 deletions docs/reference/datatypes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
database types to Go types. Choices for more complex types are described below.

If you're unsatisfied with the default, you can override any type using the
[overrides list](config.md#type-overriding) in your `sqlc` config file.
[overrides list](config.md#overrides) in your `sqlc` config file.

## Arrays

Expand Down Expand Up @@ -143,7 +143,9 @@ type Author struct {
}
```

For MySQL, there is no native `uuid` data type. When using `UUID_TO_BIN` to store a `UUID()`, the underlying field type is `BINARY(16)` which by default sqlc would interpret this to `sql.NullString`. To have sqlc automatically convert these fields to a `uuid.UUID` type, use an overide on the column storing the `uuid`.
For MySQL, there is no native `uuid` data type. When using `UUID_TO_BIN` to store a `UUID()`, the underlying field type is `BINARY(16)` which by default sqlc would map to `sql.NullString`. To have sqlc automatically convert these fields to a `uuid.UUID` type, use an overide on the column storing the `uuid`
(see [Overriding types](../howto/overrides.md) for details).

```json
{
"overrides": [
Expand All @@ -158,7 +160,8 @@ For MySQL, there is no native `uuid` data type. When using `UUID_TO_BIN` to stor
## JSON

By default, sqlc will generate the `[]byte`, `pgtype.JSON` or `json.RawMessage` for JSON column type.
But if you use the `pgx/v5` sql package then you can specify a struct instead of default type.
But if you use the `pgx/v5` sql package then you can specify a struct instead of the default type
(see [Overriding types](../howto/overrides.md) for details).
The `pgx` implementation will marshal/unmarshal the struct automatically.

```go
Expand Down Expand Up @@ -209,7 +212,7 @@ type Book struct {

In PostgreSQL, when you have a column with the TEXT type, sqlc will map it to a Go string by default. This default mapping applies to `TEXT` columns that are not nullable. However, for nullable `TEXT` columns, sqlc maps them to `pgtype.Text` when using the pgx/v5 driver. This distinction is crucial for developers looking to handle null values appropriately in their Go applications.

To accommodate nullable strings and map them to `*string` in Go, you can use the `emit_pointers_for_null_types` option in your sqlc configuration. This option ensures that nullable SQL columns are represented as pointer types in Go, allowing for a clear distinction between null and non-null values. Another way to do this is by passing the option `pointer: true` when you are overriding the `TEXT` datatype in you sqlc config file.
To accommodate nullable strings and map them to `*string` in Go, you can use the `emit_pointers_for_null_types` option in your sqlc configuration. This option ensures that nullable SQL columns are represented as pointer types in Go, allowing for a clear distinction between null and non-null values. Another way to do this is by passing the option `pointer: true` when you are overriding the `TEXT` datatype in your sqlc config file (see [Overriding types](../howto/overrides.md) for details).

## Geometry

Expand All @@ -222,7 +225,7 @@ package for working with PostGIS geometry types in [GEOS](https://libgeos.org/).

There are three steps:

1. Configure sqlc to use `*github.com/twpayne/go-geos.Geom` for geometry types.
1. Configure sqlc to use `*github.com/twpayne/go-geos.Geom` for geometry types (see [Overriding types](../howto/overrides.md) for details).
2. Call `github.com/twpayne/pgx-geos.Register` on each
`*github.com/jackc/pgx/v5.Conn`.
3. Annotate your SQL with `::geometry` typecasts, if needed.
Expand Down Expand Up @@ -281,7 +284,7 @@ config.AfterConnect = func(ctx context.Context, conn *pgx.Conn) error {
#### Using `github.com/twpayne/go-geom`

sqlc can be configured to use the [geom](https://github.com/twpayne/go-geom)
package for working with PostGIS geometry types.
package for working with PostGIS geometry types. See [Overriding types](../howto/overrides.md) for more information.

```sql
-- Multipolygons in British National Grid (epsg:27700)
Expand Down
Loading