sqlc icon indicating copy to clipboard operation
sqlc copied to clipboard

Support emit_pointers_for_null_types for lib/pq

Open slarse opened this issue 2 months ago • 1 comments

What do you want to change?

Short version: I don't understand why emit_pointers_for_null_types is not enabled when using lib/pq as the driver. It seems like it should work just fine.

Longer version: Currently, when generating PostgreSQL code for Go, you need to use a pgx driver for the emit_pointers_for_null_types to have any effect. I don't really understand why, as the only other significant driver for PostgreSQL in Go is lib/pq, and scanning null columns into pointer types works fine for that driver as well.

This https://github.com/sqlc-dev/sqlc/issues/3221#issuecomment-1975527962 claims that lib/pq does not support scanning into pointer types, but that does not reflect my experience. To the best of my understanding it's not really the responsibility of the driver to "scan into a type" at all when using the database/sql package.

When reading a data row, lib/pq handles null (indicated by -1) by setting the value to nil. That's afaik where lib/pqs responsibility ends, and database/sql takes over to handle the nil value when you call Rows.Scan(), where you eventually end up in convertAssignRows(). This does handle pointer types in the destinations.

On a more practical note, the following works just fine for me:

package main

import (
	"database/sql"
	"fmt"

	_ "github.com/lib/pq"
)

func main() {
	db, err := sql.Open("postgres", "user=postgres password=postgres sslmode=disable")
	if err != nil {
		panic(err)
	}

	var a *int
	var b *int
	rows, err := db.Query("SELECT 42, NULL;")
	if err != nil {
		panic(err)
	}

	rows.Next()
	if err := rows.Scan(&a, &b); err != nil {
		panic(err)
	}

	fmt.Printf("%v, %v\n", *a, b) // 42, <nil>
}

Am I missing something significant here? Or would it be feasible to respect the emit_pointers_for_null_types for the lib/pq driver as well?

What database engines need to be changed?

PostgreSQL

What programming language backends need to be changed?

Go

slarse avatar Oct 18 '25 13:10 slarse

I've forked sqlc-gen-go and have enabled pointer types for lib/pq. Yet to encounter any issues, it seems to be working fine.

I'd still love to hear if someone has any input on why this might be a bad idea. I'm unable to find any incompatibilities.

slarse avatar Oct 23 '25 18:10 slarse