@@ -2241,6 +2241,25 @@ func BenchmarkColumn(b *testing.B) {
22412241 }
22422242}
22432243
2244+ type CustomType [T any ] struct {
2245+ Val T
2246+ }
2247+
2248+ func (n * CustomType [T ]) DecodeSpanner (input any ) error {
2249+ switch val := input .(type ) {
2250+ case T :
2251+ n .Val = val
2252+ return nil
2253+ case * T :
2254+ if val == nil {
2255+ return nil
2256+ }
2257+ n .Val = * val
2258+ return nil
2259+ }
2260+ panic ("n/a" )
2261+ }
2262+
22442263func TestSelectAll (t * testing.T ) {
22452264 skipUnsupportedPGTest (t )
22462265 type args struct {
@@ -2255,6 +2274,13 @@ func TestSelectAll(t *testing.T) {
22552274 Col3 string
22562275 Col4 time.Time
22572276 }
2277+
2278+ type testStructWithCustom struct {
2279+ Col1 int64
2280+ COL2 float64
2281+ Col3 CustomType [string ]
2282+ }
2283+
22582284 type testStructWithTag struct {
22592285 Col1 int64 `spanner:"tag1"`
22602286 Col2 float64 `spanner:"Tag2"`
@@ -2424,6 +2450,44 @@ func TestSelectAll(t *testing.T) {
24242450 {Col1 : 2 , COL2 : 2.2 , Col3 : "value2" },
24252451 },
24262452 },
2453+ {
2454+ name : "success: using destination with custom type with custom decoder with some null columns" ,
2455+ args : args {
2456+ destination : & []* testStructWithCustom {},
2457+ mock : newMockIterator (
2458+ & Row {
2459+ []* sppb.StructType_Field {
2460+ {Name : "Col1" , Type : intType ()},
2461+ {Name : "Col2" , Type : floatType ()},
2462+ {Name : "Col3" , Type : stringType ()},
2463+ },
2464+ []* proto3.Value {intProto (3 ), floatProto (3.3 ), stringProto ("value3" )},
2465+ },
2466+ & Row {
2467+ []* sppb.StructType_Field {
2468+ {Name : "Col1" , Type : intType ()},
2469+ {Name : "Col2" , Type : floatType ()},
2470+ {Name : "Col3" , Type : stringType ()},
2471+ },
2472+ []* proto3.Value {intProto (1 ), floatProto (1.1 ), nullProto ()},
2473+ },
2474+ & Row {
2475+ []* sppb.StructType_Field {
2476+ {Name : "Col1" , Type : intType ()},
2477+ {Name : "Col2" , Type : floatType ()},
2478+ {Name : "Col3" , Type : stringType ()},
2479+ },
2480+ []* proto3.Value {intProto (2 ), floatProto (2.2 ), stringProto ("value2" )},
2481+ },
2482+ iterator .Done ,
2483+ ),
2484+ },
2485+ want : & []* testStructWithCustom {
2486+ {Col1 : 3 , COL2 : 3.3 , Col3 : CustomType [string ]{"value3" }},
2487+ {Col1 : 1 , COL2 : 1.1 , Col3 : CustomType [string ]{}},
2488+ {Col1 : 2 , COL2 : 2.2 , Col3 : CustomType [string ]{"value2" }},
2489+ },
2490+ },
24272491 {
24282492 name : "success: using slice of structs with spanner tag annotations" ,
24292493 args : args {
0 commit comments