Fix scan pointer to pointer to nil slice

https://github.com/jackc/pgx/issues/1263
pull/1281/head
Jack Christensen 2022-07-30 09:10:50 -05:00
parent 7f382f5190
commit c3258b7f52
2 changed files with 18 additions and 0 deletions

View File

@ -6,6 +6,7 @@ import (
"fmt"
"reflect"
"github.com/jackc/pgx/v5/internal/anynil"
"github.com/jackc/pgx/v5/internal/pgio"
)
@ -216,6 +217,12 @@ func (c *ArrayCodec) PlanScan(m *Map, oid uint32, format int16, target any) Scan
return nil
}
// target / arrayScanner might be a pointer to a nil. If it is create one so we can call ScanIndexType to plan the
// scan of the elements.
if anynil.Is(target) {
arrayScanner = reflect.New(reflect.TypeOf(target).Elem()).Interface().(ArraySetter)
}
elementType := arrayScanner.ScanIndexType()
elementScanPlan := m.PlanScan(c.ElementType.OID, format, elementType)

View File

@ -254,6 +254,17 @@ func TestScanPlanInterface(t *testing.T) {
assert.Error(t, err)
}
// https://github.com/jackc/pgx/issues/1263
func TestMapScanPtrToPtrToSlice(t *testing.T) {
m := pgtype.NewMap()
src := []byte("{foo,bar}")
var v *[]string
plan := m.PlanScan(pgtype.TextArrayOID, pgtype.TextFormatCode, &v)
err := plan.Scan(src, &v)
require.NoError(t, err)
require.Equal(t, []string{"foo", "bar"}, *v)
}
func BenchmarkTypeMapScanInt4IntoBinaryDecoder(b *testing.B) {
m := pgtype.NewMap()
src := []byte{0, 0, 0, 42}