[go: up one dir, main page]

Skip to content

Commit

Permalink
fix(spanner): support time.Time and other custom types using SelectAll (
Browse files Browse the repository at this point in the history
#9382)

* fix(spanner): support time.Time and other custom types using SelectAll

* add tests
  • Loading branch information
rahul2393 committed Feb 6, 2024
1 parent 2fe67df commit dc21234
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
20 changes: 14 additions & 6 deletions spanner/row.go
Expand Up @@ -480,11 +480,13 @@ func SelectAll(rows rowIterator, destination interface{}, options ...DecodeOptio
}
if !isPrimitive {
e := sliceItem.Elem()
for i, p := range pointers {
idx := 0
for _, p := range pointers {
if p == nil {
continue
}
e.Field(i).Set(reflect.ValueOf(p).Elem())
e.Field(idx).Set(reflect.ValueOf(p).Elem())
idx++
}
}
var elemVal reflect.Value
Expand All @@ -510,7 +512,11 @@ func structPointers(sliceItem reflect.Value, cols []*sppb.StructType_Field, leni
fieldTag := make(map[string]reflect.Value, len(cols))
initFieldTag(sliceItem, &fieldTag)

for _, colName := range cols {
for i, colName := range cols {
if colName.Name == "" {
return nil, errColNotFound(fmt.Sprintf("column %d", i))
}

var fieldVal reflect.Value
if v, ok := fieldTag[colName.GetName()]; ok {
fieldVal = v
Expand Down Expand Up @@ -548,9 +554,11 @@ func initFieldTag(sliceItem reflect.Value, fieldTagMap *map[string]reflect.Value
}
if fieldType.Type.Kind() == reflect.Struct {
// found an embedded struct
sliceItemOfAnonymous := sliceItem.Field(i)
initFieldTag(sliceItemOfAnonymous, fieldTagMap)
continue
if fieldType.Anonymous {
sliceItemOfAnonymous := sliceItem.Field(i)
initFieldTag(sliceItemOfAnonymous, fieldTagMap)
continue
}
}
name, keep, _, _ := spannerTagParser(fieldType.Tag)
if !keep {
Expand Down
18 changes: 11 additions & 7 deletions spanner/row_test.go
Expand Up @@ -2005,6 +2005,7 @@ func TestSelectAll(t *testing.T) {
Col1 int64
Col2 float64
Col3 string
Col4 time.Time
}
tests := []struct {
name string
Expand Down Expand Up @@ -2068,24 +2069,26 @@ func TestSelectAll(t *testing.T) {
{Name: "Col1", Type: intType()},
{Name: "Col2", Type: floatType()},
{Name: "Col3", Type: stringType()},
{Name: "Col4", Type: timeType()},
},
[]*proto3.Value{intProto(1), floatProto(1.1), stringProto("value")},
[]*proto3.Value{intProto(1), floatProto(1.1), stringProto("value"), timeProto(tm)},
}, nil)
mockIterator.On("Next").Once().Return(&Row{
[]*sppb.StructType_Field{
{Name: "Col1", Type: intType()},
{Name: "Col2", Type: floatType()},
{Name: "Col3", Type: stringType()},
{Name: "Col4", Type: timeType()},
},
[]*proto3.Value{intProto(2), floatProto(2.2), stringProto("value2")},
[]*proto3.Value{intProto(2), floatProto(2.2), stringProto("value2"), timeProto(tm.Add(24 * time.Hour))},
}, nil)
mockIterator.On("Next").Once().Return(nil, iterator.Done)
mockIterator.On("Stop").Once().Return(nil)
},
},
want: &[]testStruct{
{Col1: 1, Col2: 1.1, Col3: "value"},
{Col1: 2, Col2: 2.2, Col3: "value2"},
{Col1: 1, Col2: 1.1, Col3: "value", Col4: tm},
{Col1: 2, Col2: 2.2, Col3: "value2", Col4: tm.Add(24 * time.Hour)},
},
},
{
Expand Down Expand Up @@ -2127,9 +2130,10 @@ func TestSelectAll(t *testing.T) {
{Name: "Col1", Type: intType()},
{Name: "Col2", Type: floatType()},
{Name: "Col3", Type: stringType()},
{Name: "Col4", Type: stringType()},
{Name: "Col4", Type: timeType()},
{Name: "Col5", Type: stringType()},
},
[]*proto3.Value{intProto(1), floatProto(1.1), stringProto("value"), stringProto("value4")},
[]*proto3.Value{intProto(1), floatProto(1.1), stringProto("value"), timeProto(tm), stringProto("value2")},
}, nil)
// failure case
mockIterator.On("Next").Once().Return(nil, iterator.Done)
Expand All @@ -2138,7 +2142,7 @@ func TestSelectAll(t *testing.T) {
options: []DecodeOptions{WithLenient()},
},
want: &[]*testStruct{
{Col1: 1, Col2: 1.1, Col3: "value"},
{Col1: 1, Col2: 1.1, Col3: "value", Col4: tm},
},
},
{
Expand Down

0 comments on commit dc21234

Please sign in to comment.