pgx icon indicating copy to clipboard operation
pgx copied to clipboard

Use array's default scan in a custom type `Scan`

Open zoriya opened this issue 3 weeks ago • 1 comments

Using pq, i had a custom type like so:

type Keyframe struct {
  Keyframes []float64
  IsDone boolean
}

func (kf *Keyframe) Scan(src any) error {
	var arr pq.Float64Array
	err := arr.Scan(src)
	if err != nil {
		return err
	}
	kf.Keyframes = arr
	kf.IsDone = true
	return nil
}

I have trouble converting this to pgx since i don't know how to scan src into a []float64.

Most issues/PR talk about the new ScanColumn or use the pgtype.Array but I couldn't make the scan method work.

I also tried to simply do

func (kf *Keyframe) Scan(src any) error {
	arr, ok := src.([]float64)
	if !ok {
		return errors.New("failure")
	}
	kf.Keyframes = arr
	kf.IsDone = true
	return nil
}

but this didn't work either.

The question is then: how can you use the default scan behavior of an array in a Scan method of a custom type?

zoriya avatar Nov 03 '25 18:11 zoriya

I managed to implement it using:

func (kf *Keyframe) Scan(src any) error {
	var arr []float64

	m := pgtype.NewMap()
	t, ok := m.TypeForValue(&arr)

	if !ok {
		return errors.New("failed to parse keyframes")
	}
	err := m.Scan(t.OID, pgtype.BinaryFormatCode, src.([]byte), &arr)
	if err != nil {
		return err
	}

	kf.Keyframes = arr
	kf.IsDone = true
	return nil
}

is there a new simpler way with the new proposal of ScanColumn?

zoriya avatar Nov 04 '25 08:11 zoriya

Are you using database/sql or pgx directly?

Is this actually a custom type in PostgreSQL?

Also, see the docs for the pgtype package and examine the tests in composite_test.go.

jackc avatar Nov 09 '25 00:11 jackc

i'm using pgx directly. this isn't a custom type on postgres, for postgres it's just a []string

zoriya avatar Nov 09 '25 17:11 zoriya