Fix RowToStructByPos on structs with multiple anonymous sub-structs
Fixes #1343
This commit is contained in:
committed by
Jack Christensen
parent
ba100785cc
commit
3e825ec898
@@ -533,9 +533,9 @@ func (rs *positionalStructRowScanner) appendScanTargets(dstElemValue reflect.Val
|
|||||||
for i := 0; i < dstElemType.NumField(); i++ {
|
for i := 0; i < dstElemType.NumField(); i++ {
|
||||||
sf := dstElemType.Field(i)
|
sf := dstElemType.Field(i)
|
||||||
if sf.PkgPath == "" {
|
if sf.PkgPath == "" {
|
||||||
// Handle anoymous struct embedding, but do not try to handle embedded pointers.
|
// Handle anonymous struct embedding, but do not try to handle embedded pointers.
|
||||||
if sf.Anonymous && sf.Type.Kind() == reflect.Struct {
|
if sf.Anonymous && sf.Type.Kind() == reflect.Struct {
|
||||||
scanTargets = append(scanTargets, rs.appendScanTargets(dstElemValue.Field(i), scanTargets)...)
|
scanTargets = rs.appendScanTargets(dstElemValue.Field(i), scanTargets)
|
||||||
} else {
|
} else {
|
||||||
scanTargets = append(scanTargets, dstElemValue.Field(i).Addr().Interface())
|
scanTargets = append(scanTargets, dstElemValue.Field(i).Addr().Interface())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -383,6 +383,34 @@ func TestRowToStructByPosEmbeddedStruct(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRowToStructByPosMultipleEmbeddedStruct(t *testing.T) {
|
||||||
|
type Sandwich struct {
|
||||||
|
Bread string
|
||||||
|
Salad string
|
||||||
|
}
|
||||||
|
type Drink struct {
|
||||||
|
Ml int
|
||||||
|
}
|
||||||
|
|
||||||
|
type meal struct {
|
||||||
|
Sandwich
|
||||||
|
Drink
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConnTestRunner.RunTest(context.Background(), t, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
|
rows, _ := conn.Query(ctx, `select 'Baguette' as bread, 'Lettuce' as salad, drink_ml from generate_series(0, 9) drink_ml`)
|
||||||
|
slice, err := pgx.CollectRows(rows, pgx.RowToStructByPos[meal])
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Len(t, slice, 10)
|
||||||
|
for i := range slice {
|
||||||
|
assert.Equal(t, "Baguette", slice[i].Sandwich.Bread)
|
||||||
|
assert.Equal(t, "Lettuce", slice[i].Sandwich.Salad)
|
||||||
|
assert.EqualValues(t, i, slice[i].Drink.Ml)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Pointer to struct is not supported. But check that we don't panic.
|
// Pointer to struct is not supported. But check that we don't panic.
|
||||||
func TestRowToStructByPosEmbeddedPointerToStruct(t *testing.T) {
|
func TestRowToStructByPosEmbeddedPointerToStruct(t *testing.T) {
|
||||||
type Name struct {
|
type Name struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user