Skip to content

Commit

Permalink
Fix: RowToStructByPos with embedded unexported struct
Browse files Browse the repository at this point in the history
  • Loading branch information
jackc committed Apr 28, 2023
1 parent c27b9b4 commit f59e8bf
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
12 changes: 5 additions & 7 deletions rows.go
Original file line number Diff line number Diff line change
Expand Up @@ -533,13 +533,11 @@ func (rs *positionalStructRowScanner) appendScanTargets(dstElemValue reflect.Val

for i := 0; i < dstElemType.NumField(); i++ {
sf := dstElemType.Field(i)
if sf.PkgPath == "" {
// Handle anonymous struct embedding, but do not try to handle embedded pointers.
if sf.Anonymous && sf.Type.Kind() == reflect.Struct {
scanTargets = rs.appendScanTargets(dstElemValue.Field(i), scanTargets)
} else {
scanTargets = append(scanTargets, dstElemValue.Field(i).Addr().Interface())
}
// Handle anonymous struct embedding, but do not try to handle embedded pointers.
if sf.Anonymous && sf.Type.Kind() == reflect.Struct {
scanTargets = rs.appendScanTargets(dstElemValue.Field(i), scanTargets)
} else if sf.PkgPath == "" {
scanTargets = append(scanTargets, dstElemValue.Field(i).Addr().Interface())
}
}

Expand Down
25 changes: 25 additions & 0 deletions rows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,31 @@ func TestRowToStructByPosMultipleEmbeddedStruct(t *testing.T) {
})
}

func TestRowToStructByPosEmbeddedUnexportedStruct(t *testing.T) {
type name struct {
First string
Last string
}

type person struct {
name
Age int32
}

defaultConnTestRunner.RunTest(context.Background(), t, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
rows, _ := conn.Query(ctx, `select 'John' as first_name, 'Smith' as last_name, n as age from generate_series(0, 9) n`)
slice, err := pgx.CollectRows(rows, pgx.RowToStructByPos[person])
require.NoError(t, err)

assert.Len(t, slice, 10)
for i := range slice {
assert.Equal(t, "John", slice[i].name.First)
assert.Equal(t, "Smith", slice[i].name.Last)
assert.EqualValues(t, i, slice[i].Age)
}
})
}

// Pointer to struct is not supported. But check that we don't panic.
func TestRowToStructByPosEmbeddedPointerToStruct(t *testing.T) {
type Name struct {
Expand Down

0 comments on commit f59e8bf

Please sign in to comment.