-
Notifications
You must be signed in to change notification settings - Fork 947
Description
π Problem
When using sqlc v1.30.0
with a PostgreSQL function that returns a nullable scalar type like TEXT
, sqlc
generates non-pointer types (e.g. string
), which causes runtime errors when the function returns NULL
.
π₯ Example
Given the function:
CREATE FUNCTION mark_email_as_verified(p_user_id UUID)
RETURNS TEXT AS $$
BEGIN
RETURN NULL; -- success
END;
$$ LANGUAGE plpgsql;
And the query:
-- name: MarkEmailAsVerified :one
SELECT mark_email_as_verified($1) AS result;
sqlc
generates:
func (q *Queries) MarkEmailAsVerified(ctx context.Context, pUserID uuid.UUID) (string, error)
If the function returns NULL
, this causes:
can't scan into dest[0] (col: result): cannot scan NULL into *string
Or similar runtime panic from Go's database/sql or pgx drivers.
β Expected Behavior
The generated Go function should be:
func (q *Queries) MarkEmailAsVerified(ctx context.Context, pUserID uuid.UUID) (*string, error)
Since PostgreSQL functions returning TEXT
, UUID
, INT
, etc. can return NULL, sqlc should always generate pointer types for these cases.
β Workaround
Set the following in sqlc.yaml
(v1.30.0 supports this):
version: "2"
sql:
- engine: "postgresql"
schema: "schema.sql"
queries: "queries.sql"
emit_pointers_for_null_types: true
This ensures nullable scalar types like TEXT
are correctly mapped to Go pointers (e.g. *string
), avoiding scan errors.
π‘ Suggested Improvements
-
Default Behavior:
- Treat function return values as nullable unless explicitly known to be non-null.
- Generate Go pointer types (
*string
,*uuid.UUID
, etc.) for any scalar-returning function.
-
Optional per-query override, e.g.:
-- name: MarkEmailAsVerified :one -- nullable: true SELECT mark_email_as_verified($1);
-
Better error message:
- When the generated code causes a scan error due to NULL, sqlc should suggest enabling
emit_pointers_for_null_types
.
- When the generated code causes a scan error due to NULL, sqlc should suggest enabling
π¦ Version Info
sqlc
version:v1.30.0
- SQL engine: PostgreSQL
- Go driver: pgx (via
pgx/v5
)
β Summary
This bug leads to runtime error that are non-obvious and difficult to trace, especially for newer users.
Since PostgreSQL functions can always return NULL
, sqlc should default to generating nullable Go types (*T
) or offer a safer default behavior to avoid silent breakage.