1/*
2Copyright 2017 Google LLC
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package spanner
18
19import (
20	"encoding/base64"
21	"fmt"
22	"reflect"
23	"strconv"
24	"strings"
25	"testing"
26	"time"
27
28	"cloud.google.com/go/civil"
29	"cloud.google.com/go/internal/testutil"
30	proto "github.com/golang/protobuf/proto"
31	proto3 "github.com/golang/protobuf/ptypes/struct"
32	"github.com/google/go-cmp/cmp"
33	sppb "google.golang.org/genproto/googleapis/spanner/v1"
34)
35
36var (
37	tm    = time.Date(2016, 11, 15, 0, 0, 0, 0, time.UTC)
38	dt, _ = civil.ParseDate("2016-11-15")
39	// row contains a column for each unique Cloud Spanner type.
40	row = Row{
41		[]*sppb.StructType_Field{
42			// STRING / STRING ARRAY
43			{Name: "STRING", Type: stringType()},
44			{Name: "NULL_STRING", Type: stringType()},
45			{Name: "STRING_ARRAY", Type: listType(stringType())},
46			{Name: "NULL_STRING_ARRAY", Type: listType(stringType())},
47			// BYTES / BYTES ARRAY
48			{Name: "BYTES", Type: bytesType()},
49			{Name: "NULL_BYTES", Type: bytesType()},
50			{Name: "BYTES_ARRAY", Type: listType(bytesType())},
51			{Name: "NULL_BYTES_ARRAY", Type: listType(bytesType())},
52			// INT64 / INT64 ARRAY
53			{Name: "INT64", Type: intType()},
54			{Name: "NULL_INT64", Type: intType()},
55			{Name: "INT64_ARRAY", Type: listType(intType())},
56			{Name: "NULL_INT64_ARRAY", Type: listType(intType())},
57			// BOOL / BOOL ARRAY
58			{Name: "BOOL", Type: boolType()},
59			{Name: "NULL_BOOL", Type: boolType()},
60			{Name: "BOOL_ARRAY", Type: listType(boolType())},
61			{Name: "NULL_BOOL_ARRAY", Type: listType(boolType())},
62			// FLOAT64 / FLOAT64 ARRAY
63			{Name: "FLOAT64", Type: floatType()},
64			{Name: "NULL_FLOAT64", Type: floatType()},
65			{Name: "FLOAT64_ARRAY", Type: listType(floatType())},
66			{Name: "NULL_FLOAT64_ARRAY", Type: listType(floatType())},
67			// TIMESTAMP / TIMESTAMP ARRAY
68			{Name: "TIMESTAMP", Type: timeType()},
69			{Name: "NULL_TIMESTAMP", Type: timeType()},
70			{Name: "TIMESTAMP_ARRAY", Type: listType(timeType())},
71			{Name: "NULL_TIMESTAMP_ARRAY", Type: listType(timeType())},
72			// DATE / DATE ARRAY
73			{Name: "DATE", Type: dateType()},
74			{Name: "NULL_DATE", Type: dateType()},
75			{Name: "DATE_ARRAY", Type: listType(dateType())},
76			{Name: "NULL_DATE_ARRAY", Type: listType(dateType())},
77
78			// STRUCT ARRAY
79			{
80				Name: "STRUCT_ARRAY",
81				Type: listType(
82					structType(
83						mkField("Col1", intType()),
84						mkField("Col2", floatType()),
85						mkField("Col3", stringType()),
86					),
87				),
88			},
89			{
90				Name: "NULL_STRUCT_ARRAY",
91				Type: listType(
92					structType(
93						mkField("Col1", intType()),
94						mkField("Col2", floatType()),
95						mkField("Col3", stringType()),
96					),
97				),
98			},
99		},
100		[]*proto3.Value{
101			// STRING / STRING ARRAY
102			stringProto("value"),
103			nullProto(),
104			listProto(stringProto("value1"), nullProto(), stringProto("value3")),
105			nullProto(),
106			// BYTES / BYTES ARRAY
107			bytesProto([]byte("value")),
108			nullProto(),
109			listProto(bytesProto([]byte("value1")), nullProto(), bytesProto([]byte("value3"))),
110			nullProto(),
111			// INT64 / INT64 ARRAY
112			intProto(17),
113			nullProto(),
114			listProto(intProto(1), intProto(2), nullProto()),
115			nullProto(),
116			// BOOL / BOOL ARRAY
117			boolProto(true),
118			nullProto(),
119			listProto(nullProto(), boolProto(true), boolProto(false)),
120			nullProto(),
121			// FLOAT64 / FLOAT64 ARRAY
122			floatProto(1.7),
123			nullProto(),
124			listProto(nullProto(), nullProto(), floatProto(1.7)),
125			nullProto(),
126			// TIMESTAMP / TIMESTAMP ARRAY
127			timeProto(tm),
128			nullProto(),
129			listProto(nullProto(), timeProto(tm)),
130			nullProto(),
131			// DATE / DATE ARRAY
132			dateProto(dt),
133			nullProto(),
134			listProto(nullProto(), dateProto(dt)),
135			nullProto(),
136			// STRUCT ARRAY
137			listProto(
138				nullProto(),
139				listProto(intProto(3), floatProto(33.3), stringProto("three")),
140				nullProto(),
141			),
142			nullProto(),
143		},
144	}
145)
146
147// Test helpers for getting column values.
148func TestColumnValues(t *testing.T) {
149	vals := []interface{}{}
150	wantVals := []interface{}{}
151	// Test getting column values.
152	for i, wants := range [][]interface{}{
153		// STRING / STRING ARRAY
154		{"value", NullString{"value", true}},
155		{NullString{}},
156		{[]NullString{{"value1", true}, {}, {"value3", true}}},
157		{[]NullString(nil)},
158		// BYTES / BYTES ARRAY
159		{[]byte("value")},
160		{[]byte(nil)},
161		{[][]byte{[]byte("value1"), nil, []byte("value3")}},
162		{[][]byte(nil)},
163		// INT64 / INT64 ARRAY
164		{int64(17), NullInt64{17, true}},
165		{NullInt64{}},
166		{[]NullInt64{{1, true}, {2, true}, {}}},
167		{[]NullInt64(nil)},
168		// BOOL / BOOL ARRAY
169		{true, NullBool{true, true}},
170		{NullBool{}},
171		{[]NullBool{{}, {true, true}, {false, true}}},
172		{[]NullBool(nil)},
173		// FLOAT64 / FLOAT64 ARRAY
174		{1.7, NullFloat64{1.7, true}},
175		{NullFloat64{}},
176		{[]NullFloat64{{}, {}, {1.7, true}}},
177		{[]NullFloat64(nil)},
178		// TIMESTAMP / TIMESTAMP ARRAY
179		{tm, NullTime{tm, true}},
180		{NullTime{}},
181		{[]NullTime{{}, {tm, true}}},
182		{[]NullTime(nil)},
183		// DATE / DATE ARRAY
184		{dt, NullDate{dt, true}},
185		{NullDate{}},
186		{[]NullDate{{}, {dt, true}}},
187		{[]NullDate(nil)},
188		// STRUCT ARRAY
189		{
190			[]*struct {
191				Col1 NullInt64
192				Col2 NullFloat64
193				Col3 string
194			}{
195				nil,
196
197				{
198					NullInt64{3, true},
199					NullFloat64{33.3, true},
200					"three",
201				},
202				nil,
203			},
204			[]NullRow{
205				{},
206				{
207					Row: Row{
208						fields: []*sppb.StructType_Field{
209							mkField("Col1", intType()),
210							mkField("Col2", floatType()),
211							mkField("Col3", stringType()),
212						},
213						vals: []*proto3.Value{
214							intProto(3),
215							floatProto(33.3),
216							stringProto("three"),
217						},
218					},
219					Valid: true,
220				},
221				{},
222			},
223		},
224		{
225			[]*struct {
226				Col1 NullInt64
227				Col2 NullFloat64
228				Col3 string
229			}(nil),
230			[]NullRow(nil),
231		},
232	} {
233		for j, want := range wants {
234			// Prepare Value vector to test Row.Columns.
235			if j == 0 {
236				vals = append(vals, reflect.New(reflect.TypeOf(want)).Interface())
237				wantVals = append(wantVals, want)
238			}
239			// Column
240			gotp := reflect.New(reflect.TypeOf(want))
241			err := row.Column(i, gotp.Interface())
242			if err != nil {
243				t.Errorf("\t row.Column(%v, %T) returns error: %v, want nil", i, gotp.Interface(), err)
244			}
245			if got := reflect.Indirect(gotp).Interface(); !testEqual(got, want) {
246				t.Errorf("\t row.Column(%v, %T) retrives %v, want %v", i, gotp.Interface(), got, want)
247			}
248			// ColumnByName
249			gotp = reflect.New(reflect.TypeOf(want))
250			err = row.ColumnByName(row.fields[i].Name, gotp.Interface())
251			if err != nil {
252				t.Errorf("\t row.ColumnByName(%v, %T) returns error: %v, want nil", row.fields[i].Name, gotp.Interface(), err)
253			}
254			if got := reflect.Indirect(gotp).Interface(); !testEqual(got, want) {
255				t.Errorf("\t row.ColumnByName(%v, %T) retrives %v, want %v", row.fields[i].Name, gotp.Interface(), got, want)
256			}
257		}
258	}
259	// Test Row.Columns.
260	if err := row.Columns(vals...); err != nil {
261		t.Errorf("row.Columns() returns error: %v, want nil", err)
262	}
263	for i, want := range wantVals {
264		if got := reflect.Indirect(reflect.ValueOf(vals[i])).Interface(); !testEqual(got, want) {
265			t.Errorf("\t got %v(%T) for column[%v], want %v(%T)", got, got, row.fields[i].Name, want, want)
266		}
267	}
268}
269
270// Test decoding into nil destination.
271func TestNilDst(t *testing.T) {
272	for i, test := range []struct {
273		r               *Row
274		dst             interface{}
275		wantErr         error
276		structDst       interface{}
277		wantToStructErr error
278	}{
279		{
280			&Row{
281				[]*sppb.StructType_Field{
282					{Name: "Col0", Type: stringType()},
283				},
284				[]*proto3.Value{stringProto("value")},
285			},
286			nil,
287			errDecodeColumn(0, errNilDst(nil)),
288			nil,
289			errToStructArgType(nil),
290		},
291		{
292			&Row{
293				[]*sppb.StructType_Field{
294					{Name: "Col0", Type: stringType()},
295				},
296				[]*proto3.Value{stringProto("value")},
297			},
298			(*string)(nil),
299			errDecodeColumn(0, errNilDst((*string)(nil))),
300			(*struct{ STRING string })(nil),
301			errNilDst((*struct{ STRING string })(nil)),
302		},
303		{
304			&Row{
305				[]*sppb.StructType_Field{
306					{
307						Name: "Col0",
308						Type: listType(
309							structType(
310								mkField("Col1", intType()),
311								mkField("Col2", floatType()),
312							),
313						),
314					},
315				},
316				[]*proto3.Value{listProto(
317					listProto(intProto(3), floatProto(33.3)),
318				)},
319			},
320			(*[]*struct {
321				Col1 int
322				Col2 float64
323			})(nil),
324			errDecodeColumn(0, errNilDst((*[]*struct {
325				Col1 int
326				Col2 float64
327			})(nil))),
328			(*struct {
329				StructArray []*struct {
330					Col1 int
331					Col2 float64
332				} `spanner:"STRUCT_ARRAY"`
333			})(nil),
334			errNilDst((*struct {
335				StructArray []*struct {
336					Col1 int
337					Col2 float64
338				} `spanner:"STRUCT_ARRAY"`
339			})(nil)),
340		},
341	} {
342		if gotErr := test.r.Column(0, test.dst); !testEqual(gotErr, test.wantErr) {
343			t.Errorf("%v: test.r.Column() returns error %v, want %v", i, gotErr, test.wantErr)
344		}
345		if gotErr := test.r.ColumnByName("Col0", test.dst); !testEqual(gotErr, test.wantErr) {
346			t.Errorf("%v: test.r.ColumnByName() returns error %v, want %v", i, gotErr, test.wantErr)
347		}
348		// Row.Columns(T) should return nil on T == nil, otherwise, it should return test.wantErr.
349		wantColumnsErr := test.wantErr
350		if test.dst == nil {
351			wantColumnsErr = nil
352		}
353		if gotErr := test.r.Columns(test.dst); !testEqual(gotErr, wantColumnsErr) {
354			t.Errorf("%v: test.r.Columns() returns error %v, want %v", i, gotErr, wantColumnsErr)
355		}
356		if gotErr := test.r.ToStruct(test.structDst); !testEqual(gotErr, test.wantToStructErr) {
357			t.Errorf("%v: test.r.ToStruct() returns error %v, want %v", i, gotErr, test.wantToStructErr)
358		}
359	}
360}
361
362// Test decoding NULL columns using Go types that don't support NULL.
363func TestNullTypeErr(t *testing.T) {
364	var tm time.Time
365	ntoi := func(n string) int {
366		for i, f := range row.fields {
367			if f.Name == n {
368				return i
369			}
370		}
371		t.Errorf("cannot find column name %q in row", n)
372		return 0
373	}
374	for _, test := range []struct {
375		colName string
376		dst     interface{}
377	}{
378		{
379			"NULL_STRING",
380			proto.String(""),
381		},
382		{
383			"NULL_INT64",
384			proto.Int64(0),
385		},
386		{
387			"NULL_BOOL",
388			proto.Bool(false),
389		},
390		{
391			"NULL_FLOAT64",
392			proto.Float64(0.0),
393		},
394		{
395			"NULL_TIMESTAMP",
396			&tm,
397		},
398		{
399			"NULL_DATE",
400			&dt,
401		},
402	} {
403		wantErr := errDecodeColumn(ntoi(test.colName), errDstNotForNull(test.dst))
404		if gotErr := row.ColumnByName(test.colName, test.dst); !testEqual(gotErr, wantErr) {
405			t.Errorf("row.ColumnByName(%v) returns error %v, want %v", test.colName, gotErr, wantErr)
406		}
407	}
408}
409
410// Test using wrong destination type in column decoders.
411func TestColumnTypeErr(t *testing.T) {
412	// badDst cannot hold any of the column values.
413	badDst := &struct{}{}
414	for i, f := range row.fields { // For each of the columns, try to decode it into badDst.
415		tc := f.Type.Code
416		var etc sppb.TypeCode
417		if strings.Contains(f.Name, "ARRAY") {
418			etc = f.Type.ArrayElementType.Code
419		}
420		wantErr := errDecodeColumn(i, errTypeMismatch(tc, etc, badDst))
421		if strings.Contains(f.Name, "STRUCT_ARRAY") {
422			wantErr = errDecodeColumn(i, fmt.Errorf("the container is not a slice of struct pointers: %v", errTypeMismatch(tc, etc, badDst)))
423		}
424		if gotErr := row.Column(i, badDst); !testEqual(gotErr, wantErr) {
425			t.Errorf("Column(%v): decoding into destination with wrong type %T returns error %v, want %v",
426				i, badDst, gotErr, wantErr)
427		}
428		if gotErr := row.ColumnByName(f.Name, badDst); !testEqual(gotErr, wantErr) {
429			t.Errorf("ColumnByName(%v): decoding into destination with wrong type %T returns error %v, want %v",
430				f.Name, badDst, gotErr, wantErr)
431		}
432	}
433	wantErr := errDecodeColumn(1, errTypeMismatch(sppb.TypeCode_STRING, sppb.TypeCode_TYPE_CODE_UNSPECIFIED, badDst))
434	// badDst is used to receive column 1.
435	vals := []interface{}{nil, badDst} // Row.Column() is expected to fail at column 1.
436	// Skip decoding the rest columns by providing nils as the destinations.
437	for i := 2; i < len(row.fields); i++ {
438		vals = append(vals, nil)
439	}
440	if gotErr := row.Columns(vals...); !testEqual(gotErr, wantErr) {
441		t.Errorf("Columns(): decoding column 1 with wrong type %T returns error %v, want %v",
442			badDst, gotErr, wantErr)
443	}
444}
445
446// Test the handling of invalid column decoding requests which cannot be mapped to correct column(s).
447func TestInvalidColumnRequest(t *testing.T) {
448	for _, test := range []struct {
449		desc    string
450		f       func() error
451		wantErr error
452	}{
453		{
454			"Request column index is out of range",
455			func() error {
456				return row.Column(10000, &struct{}{})
457			},
458			errColIdxOutOfRange(10000, &row),
459		},
460		{
461			"Cannot find the named column",
462			func() error {
463				return row.ColumnByName("string", &struct{}{})
464			},
465			errColNotFound("string"),
466		},
467		{
468			"Not enough arguments to call row.Columns()",
469			func() error {
470				return row.Columns(nil, nil)
471			},
472			errNumOfColValue(2, &row),
473		},
474		{
475			"Call ColumnByName on row with duplicated column names",
476			func() error {
477				var s string
478				r := &Row{
479					[]*sppb.StructType_Field{
480						{Name: "Val", Type: stringType()},
481						{Name: "Val", Type: stringType()},
482					},
483					[]*proto3.Value{stringProto("value1"), stringProto("value2")},
484				}
485				return r.ColumnByName("Val", &s)
486			},
487			errDupColName("Val"),
488		},
489		{
490			"Call ToStruct on row with duplicated column names",
491			func() error {
492				s := &struct {
493					Val string
494				}{}
495				r := &Row{
496					[]*sppb.StructType_Field{
497						{Name: "Val", Type: stringType()},
498						{Name: "Val", Type: stringType()},
499					},
500					[]*proto3.Value{stringProto("value1"), stringProto("value2")},
501				}
502				return r.ToStruct(s)
503			},
504			errDupSpannerField("Val", &sppb.StructType{
505				Fields: []*sppb.StructType_Field{
506					{Name: "Val", Type: stringType()},
507					{Name: "Val", Type: stringType()},
508				},
509			}),
510		},
511		{
512			"Call ToStruct on a row with unnamed field",
513			func() error {
514				s := &struct {
515					Val string
516				}{}
517				r := &Row{
518					[]*sppb.StructType_Field{
519						{Name: "", Type: stringType()},
520					},
521					[]*proto3.Value{stringProto("value1")},
522				}
523				return r.ToStruct(s)
524			},
525			errUnnamedField(&sppb.StructType{Fields: []*sppb.StructType_Field{
526				{Name: "", Type: stringType()},
527			}}, 0),
528		},
529	} {
530		if gotErr := test.f(); !testEqual(gotErr, test.wantErr) {
531			t.Errorf("%v: test.f() returns error %v, want %v", test.desc, gotErr, test.wantErr)
532		}
533	}
534}
535
536// Test decoding the row with row.ToStruct into an invalid destination.
537func TestToStructInvalidDst(t *testing.T) {
538	for _, test := range []struct {
539		desc    string
540		dst     interface{}
541		wantErr error
542	}{
543		{
544			"Decode row as STRUCT into int32",
545			proto.Int(1),
546			errToStructArgType(proto.Int(1)),
547		},
548		{
549			"Decode row as STRUCT to nil Go struct",
550			(*struct{})(nil),
551			errNilDst((*struct{})(nil)),
552		},
553		{
554			"Decode row as STRUCT to Go struct with duplicated fields for the PK column",
555			&struct {
556				PK1 string `spanner:"STRING"`
557				PK2 string `spanner:"STRING"`
558			}{},
559			errNoOrDupGoField(&struct {
560				PK1 string `spanner:"STRING"`
561				PK2 string `spanner:"STRING"`
562			}{}, "STRING"),
563		},
564		{
565			"Decode row as STRUCT to Go struct with no field for the PK column",
566			&struct {
567				PK1 string `spanner:"_STRING"`
568			}{},
569			errNoOrDupGoField(&struct {
570				PK1 string `spanner:"_STRING"`
571			}{}, "STRING"),
572		},
573		{
574			"Decode row as STRUCT to Go struct with wrong type for the PK column",
575			&struct {
576				PK1 int64 `spanner:"STRING"`
577			}{},
578			errDecodeStructField(&sppb.StructType{Fields: row.fields}, "STRING",
579				errTypeMismatch(sppb.TypeCode_STRING, sppb.TypeCode_TYPE_CODE_UNSPECIFIED, proto.Int64(0))),
580		},
581	} {
582		if gotErr := row.ToStruct(test.dst); !testEqual(gotErr, test.wantErr) {
583			t.Errorf("%v: decoding:\ngot  %v\nwant %v", test.desc, gotErr, test.wantErr)
584		}
585	}
586}
587
588// Test decoding a broken row.
589func TestBrokenRow(t *testing.T) {
590	for i, test := range []struct {
591		row     *Row
592		dst     interface{}
593		wantErr error
594	}{
595		{
596			// A row with no field.
597			&Row{
598				[]*sppb.StructType_Field{},
599				[]*proto3.Value{stringProto("value")},
600			},
601			&NullString{"value", true},
602			errFieldsMismatchVals(&Row{
603				[]*sppb.StructType_Field{},
604				[]*proto3.Value{stringProto("value")},
605			}),
606		},
607		{
608			// A row with nil field.
609			&Row{
610				[]*sppb.StructType_Field{nil},
611				[]*proto3.Value{stringProto("value")},
612			},
613			&NullString{"value", true},
614			errNilColType(0),
615		},
616		{
617			// Field is not nil, but its type is nil.
618			&Row{
619				[]*sppb.StructType_Field{
620					{Name: "Col0", Type: nil},
621				},
622				[]*proto3.Value{listProto(stringProto("value1"), stringProto("value2"))},
623			},
624			&[]NullString{},
625			errDecodeColumn(0, errNilSpannerType()),
626		},
627		{
628			// Field is not nil, field type is not nil, but it is an array and its array element type is nil.
629			&Row{
630				[]*sppb.StructType_Field{
631					{Name: "Col0", Type: &sppb.Type{Code: sppb.TypeCode_ARRAY}},
632				},
633				[]*proto3.Value{listProto(stringProto("value1"), stringProto("value2"))},
634			},
635			&[]NullString{},
636			errDecodeColumn(0, errNilArrElemType(&sppb.Type{Code: sppb.TypeCode_ARRAY})),
637		},
638		{
639			// Field specifies valid type, value is nil.
640			&Row{
641				[]*sppb.StructType_Field{
642					{Name: "Col0", Type: intType()},
643				},
644				[]*proto3.Value{nil},
645			},
646			&NullInt64{1, true},
647			errDecodeColumn(0, errNilSrc()),
648		},
649		{
650			// Field specifies INT64 type, value is having a nil Kind.
651			&Row{
652				[]*sppb.StructType_Field{
653					{Name: "Col0", Type: intType()},
654				},
655				[]*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}},
656			},
657			&NullInt64{1, true},
658			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")),
659		},
660		{
661			// Field specifies INT64 type, but value is for Number type.
662			&Row{
663				[]*sppb.StructType_Field{
664					{Name: "Col0", Type: intType()},
665				},
666				[]*proto3.Value{floatProto(1.0)},
667			},
668			&NullInt64{1, true},
669			errDecodeColumn(0, errSrcVal(floatProto(1.0), "String")),
670		},
671		{
672			// Field specifies INT64 type, but value is wrongly encoded.
673			&Row{
674				[]*sppb.StructType_Field{
675					{Name: "Col0", Type: intType()},
676				},
677				[]*proto3.Value{stringProto("&1")},
678			},
679			proto.Int64(0),
680			errDecodeColumn(0, errBadEncoding(stringProto("&1"), func() error {
681				_, err := strconv.ParseInt("&1", 10, 64)
682				return err
683			}())),
684		},
685		{
686			// Field specifies INT64 type, but value is wrongly encoded.
687			&Row{
688				[]*sppb.StructType_Field{
689					{Name: "Col0", Type: intType()},
690				},
691				[]*proto3.Value{stringProto("&1")},
692			},
693			&NullInt64{},
694			errDecodeColumn(0, errBadEncoding(stringProto("&1"), func() error {
695				_, err := strconv.ParseInt("&1", 10, 64)
696				return err
697			}())),
698		},
699		{
700			// Field specifies STRING type, but value is having a nil Kind.
701			&Row{
702				[]*sppb.StructType_Field{
703					{Name: "Col0", Type: stringType()},
704				},
705				[]*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}},
706			},
707			&NullString{"value", true},
708			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")),
709		},
710		{
711			// Field specifies STRING type, but value is for ARRAY type.
712			&Row{
713				[]*sppb.StructType_Field{
714					{Name: "Col0", Type: stringType()},
715				},
716				[]*proto3.Value{listProto(stringProto("value"))},
717			},
718			&NullString{"value", true},
719			errDecodeColumn(0, errSrcVal(listProto(stringProto("value")), "String")),
720		},
721		{
722			// Field specifies FLOAT64 type, value is having a nil Kind.
723			&Row{
724				[]*sppb.StructType_Field{
725					{Name: "Col0", Type: floatType()},
726				},
727				[]*proto3.Value{{Kind: (*proto3.Value_NumberValue)(nil)}},
728			},
729			&NullFloat64{1.0, true},
730			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_NumberValue)(nil)}, "Number")),
731		},
732		{
733			// Field specifies FLOAT64 type, but value is for BOOL type.
734			&Row{
735				[]*sppb.StructType_Field{
736					{Name: "Col0", Type: floatType()},
737				},
738				[]*proto3.Value{boolProto(true)},
739			},
740			&NullFloat64{1.0, true},
741			errDecodeColumn(0, errSrcVal(boolProto(true), "Number")),
742		},
743		{
744			// Field specifies FLOAT64 type, but value is wrongly encoded.
745			&Row{
746				[]*sppb.StructType_Field{
747					{Name: "Col0", Type: floatType()},
748				},
749				[]*proto3.Value{stringProto("nan")},
750			},
751			&NullFloat64{},
752			errDecodeColumn(0, errUnexpectedFloat64Str("nan")),
753		},
754		{
755			// Field specifies FLOAT64 type, but value is wrongly encoded.
756			&Row{
757				[]*sppb.StructType_Field{
758					{Name: "Col0", Type: floatType()},
759				},
760				[]*proto3.Value{stringProto("nan")},
761			},
762			proto.Float64(0),
763			errDecodeColumn(0, errUnexpectedFloat64Str("nan")),
764		},
765		{
766			// Field specifies BYTES type, value is having a nil Kind.
767			&Row{
768				[]*sppb.StructType_Field{
769					{Name: "Col0", Type: bytesType()},
770				},
771				[]*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}},
772			},
773			&[]byte{},
774			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")),
775		},
776		{
777			// Field specifies BYTES type, but value is for BOOL type.
778			&Row{
779				[]*sppb.StructType_Field{
780					{Name: "Col0", Type: bytesType()},
781				},
782				[]*proto3.Value{boolProto(false)},
783			},
784			&[]byte{},
785			errDecodeColumn(0, errSrcVal(boolProto(false), "String")),
786		},
787		{
788			// Field specifies BYTES type, but value is wrongly encoded.
789			&Row{
790				[]*sppb.StructType_Field{
791					{Name: "Col0", Type: bytesType()},
792				},
793				[]*proto3.Value{stringProto("&&")},
794			},
795			&[]byte{},
796			errDecodeColumn(0, errBadEncoding(stringProto("&&"), func() error {
797				_, err := base64.StdEncoding.DecodeString("&&")
798				return err
799			}())),
800		},
801		{
802			// Field specifies BOOL type, value is having a nil Kind.
803			&Row{
804				[]*sppb.StructType_Field{
805					{Name: "Col0", Type: boolType()},
806				},
807				[]*proto3.Value{{Kind: (*proto3.Value_BoolValue)(nil)}},
808			},
809			&NullBool{false, true},
810			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_BoolValue)(nil)}, "Bool")),
811		},
812		{
813			// Field specifies BOOL type, but value is for STRING type.
814			&Row{
815				[]*sppb.StructType_Field{
816					{Name: "Col0", Type: boolType()},
817				},
818				[]*proto3.Value{stringProto("false")},
819			},
820			&NullBool{false, true},
821			errDecodeColumn(0, errSrcVal(stringProto("false"), "Bool")),
822		},
823		{
824			// Field specifies TIMESTAMP type, value is having a nil Kind.
825			&Row{
826				[]*sppb.StructType_Field{
827					{Name: "Col0", Type: timeType()},
828				},
829				[]*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}},
830			},
831			&NullTime{time.Now(), true},
832			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")),
833		},
834		{
835			// Field specifies TIMESTAMP type, but value is for BOOL type.
836			&Row{
837				[]*sppb.StructType_Field{
838					{Name: "Col0", Type: timeType()},
839				},
840				[]*proto3.Value{boolProto(false)},
841			},
842			&NullTime{time.Now(), true},
843			errDecodeColumn(0, errSrcVal(boolProto(false), "String")),
844		},
845		{
846			// Field specifies TIMESTAMP type, but value is invalid timestamp.
847			&Row{
848				[]*sppb.StructType_Field{
849					{Name: "Col0", Type: timeType()},
850				},
851				[]*proto3.Value{stringProto("junk")},
852			},
853			&NullTime{time.Now(), true},
854			errDecodeColumn(0, errBadEncoding(stringProto("junk"), func() error {
855				_, err := time.Parse(time.RFC3339Nano, "junk")
856				return err
857			}())),
858		},
859		{
860			// Field specifies DATE type, value is having a nil Kind.
861			&Row{
862				[]*sppb.StructType_Field{
863					{Name: "Col0", Type: dateType()},
864				},
865				[]*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}},
866			},
867			&NullDate{civil.Date{}, true},
868			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")),
869		},
870		{
871			// Field specifies DATE type, but value is for BOOL type.
872			&Row{
873				[]*sppb.StructType_Field{
874					{Name: "Col0", Type: dateType()},
875				},
876				[]*proto3.Value{boolProto(false)},
877			},
878			&NullDate{civil.Date{}, true},
879			errDecodeColumn(0, errSrcVal(boolProto(false), "String")),
880		},
881		{
882			// Field specifies DATE type, but value is invalid timestamp.
883			&Row{
884				[]*sppb.StructType_Field{
885					{Name: "Col0", Type: dateType()},
886				},
887				[]*proto3.Value{stringProto("junk")},
888			},
889			&NullDate{civil.Date{}, true},
890			errDecodeColumn(0, errBadEncoding(stringProto("junk"), func() error {
891				_, err := civil.ParseDate("junk")
892				return err
893			}())),
894		},
895
896		{
897			// Field specifies ARRAY<INT64> type, value is having a nil Kind.
898			&Row{
899				[]*sppb.StructType_Field{
900					{Name: "Col0", Type: listType(intType())},
901				},
902				[]*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
903			},
904			&[]NullInt64{},
905			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
906		},
907		{
908			// Field specifies ARRAY<INT64> type, value is having a nil ListValue.
909			&Row{
910				[]*sppb.StructType_Field{
911					{Name: "Col0", Type: listType(intType())},
912				},
913				[]*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
914			},
915			&[]NullInt64{},
916			errDecodeColumn(0, errNilListValue("INT64")),
917		},
918		{
919			// Field specifies ARRAY<INT64> type, but value is for BYTES type.
920			&Row{
921				[]*sppb.StructType_Field{
922					{Name: "Col0", Type: listType(intType())},
923				},
924				[]*proto3.Value{bytesProto([]byte("value"))},
925			},
926			&[]NullInt64{},
927			errDecodeColumn(0, errSrcVal(bytesProto([]byte("value")), "List")),
928		},
929		{
930			// Field specifies ARRAY<INT64> type, but value is for ARRAY<BOOL> type.
931			&Row{
932				[]*sppb.StructType_Field{
933					{Name: "Col0", Type: listType(intType())},
934				},
935				[]*proto3.Value{listProto(boolProto(true))},
936			},
937			&[]NullInt64{},
938			errDecodeColumn(0, errDecodeArrayElement(0, boolProto(true),
939				"INT64", errSrcVal(boolProto(true), "String"))),
940		},
941		{
942			// Field specifies ARRAY<STRING> type, value is having a nil Kind.
943			&Row{
944				[]*sppb.StructType_Field{
945					{Name: "Col0", Type: listType(stringType())},
946				},
947				[]*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
948			},
949			&[]NullString{},
950			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
951		},
952		{
953			// Field specifies ARRAY<STRING> type, value is having a nil ListValue.
954			&Row{
955				[]*sppb.StructType_Field{
956					{Name: "Col0", Type: listType(stringType())},
957				},
958				[]*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
959			},
960			&[]NullString{},
961			errDecodeColumn(0, errNilListValue("STRING")),
962		},
963		{
964			// Field specifies ARRAY<STRING> type, but value is for BOOL type.
965			&Row{
966				[]*sppb.StructType_Field{
967					{Name: "Col0", Type: listType(stringType())},
968				},
969				[]*proto3.Value{boolProto(true)},
970			},
971			&[]NullString{},
972			errDecodeColumn(0, errSrcVal(boolProto(true), "List")),
973		},
974		{
975			// Field specifies ARRAY<STRING> type, but value is for ARRAY<BOOL> type.
976			&Row{
977				[]*sppb.StructType_Field{
978					{Name: "Col0", Type: listType(stringType())},
979				},
980				[]*proto3.Value{listProto(boolProto(true))},
981			},
982			&[]NullString{},
983			errDecodeColumn(0, errDecodeArrayElement(0, boolProto(true),
984				"STRING", errSrcVal(boolProto(true), "String"))),
985		},
986		{
987			// Field specifies ARRAY<FLOAT64> type, value is having a nil Kind.
988			&Row{
989				[]*sppb.StructType_Field{
990					{Name: "Col0", Type: listType(floatType())},
991				},
992				[]*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
993			},
994			&[]NullFloat64{},
995			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
996		},
997		{
998			// Field specifies ARRAY<FLOAT64> type, value is having a nil ListValue.
999			&Row{
1000				[]*sppb.StructType_Field{
1001					{Name: "Col0", Type: listType(floatType())},
1002				},
1003				[]*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
1004			},
1005			&[]NullFloat64{},
1006			errDecodeColumn(0, errNilListValue("FLOAT64")),
1007		},
1008		{
1009			// Field specifies ARRAY<FLOAT64> type, but value is for STRING type.
1010			&Row{
1011				[]*sppb.StructType_Field{
1012					{Name: "Col0", Type: listType(floatType())},
1013				},
1014				[]*proto3.Value{stringProto("value")},
1015			},
1016			&[]NullFloat64{},
1017			errDecodeColumn(0, errSrcVal(stringProto("value"), "List")),
1018		},
1019		{
1020			// Field specifies ARRAY<FLOAT64> type, but value is for ARRAY<BOOL> type.
1021			&Row{
1022				[]*sppb.StructType_Field{
1023					{Name: "Col0", Type: listType(floatType())},
1024				},
1025				[]*proto3.Value{listProto(boolProto(true))},
1026			},
1027			&[]NullFloat64{},
1028			errDecodeColumn(0, errDecodeArrayElement(0, boolProto(true),
1029				"FLOAT64", errSrcVal(boolProto(true), "Number"))),
1030		},
1031		{
1032			// Field specifies ARRAY<BYTES> type, value is having a nil Kind.
1033			&Row{
1034				[]*sppb.StructType_Field{
1035					{Name: "Col0", Type: listType(bytesType())},
1036				},
1037				[]*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
1038			},
1039			&[][]byte{},
1040			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
1041		},
1042		{
1043			// Field specifies ARRAY<BYTES> type, value is having a nil ListValue.
1044			&Row{
1045				[]*sppb.StructType_Field{
1046					{Name: "Col0", Type: listType(bytesType())},
1047				},
1048				[]*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
1049			},
1050			&[][]byte{},
1051			errDecodeColumn(0, errNilListValue("BYTES")),
1052		},
1053		{
1054			// Field specifies ARRAY<BYTES> type, but value is for FLOAT64 type.
1055			&Row{
1056				[]*sppb.StructType_Field{
1057					{Name: "Col0", Type: listType(bytesType())},
1058				},
1059				[]*proto3.Value{floatProto(1.0)},
1060			},
1061			&[][]byte{},
1062			errDecodeColumn(0, errSrcVal(floatProto(1.0), "List")),
1063		},
1064		{
1065			// Field specifies ARRAY<BYTES> type, but value is for ARRAY<FLOAT64> type.
1066			&Row{
1067				[]*sppb.StructType_Field{
1068					{Name: "Col0", Type: listType(bytesType())},
1069				},
1070				[]*proto3.Value{listProto(floatProto(1.0))},
1071			},
1072			&[][]byte{},
1073			errDecodeColumn(0, errDecodeArrayElement(0, floatProto(1.0),
1074				"BYTES", errSrcVal(floatProto(1.0), "String"))),
1075		},
1076		{
1077			// Field specifies ARRAY<BOOL> type, value is having a nil Kind.
1078			&Row{
1079				[]*sppb.StructType_Field{
1080					{Name: "Col0", Type: listType(boolType())},
1081				},
1082				[]*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
1083			},
1084			&[]NullBool{},
1085			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
1086		},
1087		{
1088			// Field specifies ARRAY<BOOL> type, value is having a nil ListValue.
1089			&Row{
1090				[]*sppb.StructType_Field{
1091					{Name: "Col0", Type: listType(boolType())},
1092				},
1093				[]*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
1094			},
1095			&[]NullBool{},
1096			errDecodeColumn(0, errNilListValue("BOOL")),
1097		},
1098		{
1099			// Field specifies ARRAY<BOOL> type, but value is for FLOAT64 type.
1100			&Row{
1101				[]*sppb.StructType_Field{
1102					{Name: "Col0", Type: listType(boolType())},
1103				},
1104				[]*proto3.Value{floatProto(1.0)},
1105			},
1106			&[]NullBool{},
1107			errDecodeColumn(0, errSrcVal(floatProto(1.0), "List")),
1108		},
1109		{
1110			// Field specifies ARRAY<BOOL> type, but value is for ARRAY<FLOAT64> type.
1111			&Row{
1112				[]*sppb.StructType_Field{
1113					{Name: "Col0", Type: listType(boolType())},
1114				},
1115				[]*proto3.Value{listProto(floatProto(1.0))},
1116			},
1117			&[]NullBool{},
1118			errDecodeColumn(0, errDecodeArrayElement(0, floatProto(1.0),
1119				"BOOL", errSrcVal(floatProto(1.0), "Bool"))),
1120		},
1121		{
1122			// Field specifies ARRAY<TIMESTAMP> type, value is having a nil Kind.
1123			&Row{
1124				[]*sppb.StructType_Field{
1125					{Name: "Col0", Type: listType(timeType())},
1126				},
1127				[]*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
1128			},
1129			&[]NullTime{},
1130			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
1131		},
1132		{
1133			// Field specifies ARRAY<TIMESTAMP> type, value is having a nil ListValue.
1134			&Row{
1135				[]*sppb.StructType_Field{
1136					{Name: "Col0", Type: listType(timeType())},
1137				},
1138				[]*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
1139			},
1140			&[]NullTime{},
1141			errDecodeColumn(0, errNilListValue("TIMESTAMP")),
1142		},
1143		{
1144			// Field specifies ARRAY<TIMESTAMP> type, but value is for FLOAT64 type.
1145			&Row{
1146				[]*sppb.StructType_Field{
1147					{Name: "Col0", Type: listType(timeType())},
1148				},
1149				[]*proto3.Value{floatProto(1.0)},
1150			},
1151			&[]NullTime{},
1152			errDecodeColumn(0, errSrcVal(floatProto(1.0), "List")),
1153		},
1154		{
1155			// Field specifies ARRAY<TIMESTAMP> type, but value is for ARRAY<FLOAT64> type.
1156			&Row{
1157				[]*sppb.StructType_Field{
1158					{Name: "Col0", Type: listType(timeType())},
1159				},
1160				[]*proto3.Value{listProto(floatProto(1.0))},
1161			},
1162			&[]NullTime{},
1163			errDecodeColumn(0, errDecodeArrayElement(0, floatProto(1.0),
1164				"TIMESTAMP", errSrcVal(floatProto(1.0), "String"))),
1165		},
1166		{
1167			// Field specifies ARRAY<DATE> type, value is having a nil Kind.
1168			&Row{
1169				[]*sppb.StructType_Field{
1170					{Name: "Col0", Type: listType(dateType())},
1171				},
1172				[]*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
1173			},
1174			&[]NullDate{},
1175			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
1176		},
1177		{
1178			// Field specifies ARRAY<DATE> type, value is having a nil ListValue.
1179			&Row{
1180				[]*sppb.StructType_Field{
1181					{Name: "Col0", Type: listType(dateType())},
1182				},
1183				[]*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
1184			},
1185			&[]NullDate{},
1186			errDecodeColumn(0, errNilListValue("DATE")),
1187		},
1188		{
1189			// Field specifies ARRAY<DATE> type, but value is for FLOAT64 type.
1190			&Row{
1191				[]*sppb.StructType_Field{
1192					{Name: "Col0", Type: listType(dateType())},
1193				},
1194				[]*proto3.Value{floatProto(1.0)},
1195			},
1196			&[]NullDate{},
1197			errDecodeColumn(0, errSrcVal(floatProto(1.0), "List")),
1198		},
1199		{
1200			// Field specifies ARRAY<DATE> type, but value is for ARRAY<FLOAT64> type.
1201			&Row{
1202				[]*sppb.StructType_Field{
1203					{Name: "Col0", Type: listType(dateType())},
1204				},
1205				[]*proto3.Value{listProto(floatProto(1.0))},
1206			},
1207			&[]NullDate{},
1208			errDecodeColumn(0, errDecodeArrayElement(0, floatProto(1.0),
1209				"DATE", errSrcVal(floatProto(1.0), "String"))),
1210		},
1211		{
1212			// Field specifies ARRAY<STRUCT> type, value is having a nil Kind.
1213			&Row{
1214				[]*sppb.StructType_Field{
1215					{Name: "Col0", Type: listType(structType(
1216						mkField("Col1", intType()),
1217						mkField("Col2", floatType()),
1218						mkField("Col3", stringType()),
1219					))},
1220				},
1221				[]*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}},
1222			},
1223			&[]*struct {
1224				Col1 int64
1225				Col2 float64
1226				Col3 string
1227			}{},
1228			errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")),
1229		},
1230		{
1231			// Field specifies ARRAY<STRUCT> type, value is having a nil ListValue.
1232			&Row{
1233				[]*sppb.StructType_Field{
1234					{Name: "Col0", Type: listType(structType(
1235						mkField("Col1", intType()),
1236						mkField("Col2", floatType()),
1237						mkField("Col3", stringType()),
1238					))},
1239				},
1240				[]*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
1241			},
1242			&[]*struct {
1243				Col1 int64
1244				Col2 float64
1245				Col3 string
1246			}{},
1247			errDecodeColumn(0, errNilListValue("STRUCT")),
1248		},
1249		{
1250			// Field specifies ARRAY<STRUCT> type, value is having a nil ListValue.
1251			&Row{
1252				[]*sppb.StructType_Field{
1253					{
1254						Name: "Col0",
1255						Type: listType(
1256							structType(
1257								mkField("Col1", intType()),
1258								mkField("Col2", floatType()),
1259								mkField("Col3", stringType()),
1260							),
1261						),
1262					},
1263				},
1264				[]*proto3.Value{{Kind: &proto3.Value_ListValue{}}},
1265			},
1266			&[]NullRow{},
1267			errDecodeColumn(0, errNilListValue("STRUCT")),
1268		},
1269		{
1270			// Field specifies ARRAY<STRUCT> type, value is for BYTES type.
1271			&Row{
1272				[]*sppb.StructType_Field{
1273					{
1274						Name: "Col0",
1275						Type: listType(
1276							structType(
1277								mkField("Col1", intType()),
1278								mkField("Col2", floatType()),
1279								mkField("Col3", stringType()),
1280							),
1281						),
1282					},
1283				},
1284				[]*proto3.Value{bytesProto([]byte("value"))},
1285			},
1286			&[]*struct {
1287				Col1 int64
1288				Col2 float64
1289				Col3 string
1290			}{},
1291			errDecodeColumn(0, errSrcVal(bytesProto([]byte("value")), "List")),
1292		},
1293		{
1294			// Field specifies ARRAY<STRUCT> type, value is for BYTES type.
1295			&Row{
1296				[]*sppb.StructType_Field{
1297					{
1298						Name: "Col0",
1299						Type: listType(
1300							structType(
1301								mkField("Col1", intType()),
1302								mkField("Col2", floatType()),
1303								mkField("Col3", stringType()),
1304							),
1305						),
1306					},
1307				},
1308				[]*proto3.Value{listProto(bytesProto([]byte("value")))},
1309			},
1310			&[]NullRow{},
1311			errDecodeColumn(0, errNotStructElement(0, bytesProto([]byte("value")))),
1312		},
1313		{
1314			// Field specifies ARRAY<STRUCT> type, value is for ARRAY<BYTES> type.
1315			&Row{
1316				[]*sppb.StructType_Field{
1317					{
1318						Name: "Col0",
1319						Type: listType(
1320							structType(
1321								mkField("Col1", intType()),
1322								mkField("Col2", floatType()),
1323								mkField("Col3", stringType()),
1324							),
1325						),
1326					},
1327				},
1328				[]*proto3.Value{listProto(bytesProto([]byte("value")))},
1329			},
1330			&[]*struct {
1331				Col1 int64
1332				Col2 float64
1333				Col3 string
1334			}{},
1335			errDecodeColumn(0, errDecodeArrayElement(0, bytesProto([]byte("value")),
1336				"STRUCT", errSrcVal(bytesProto([]byte("value")), "List"))),
1337		},
1338		{
1339			// Field specifies ARRAY<STRUCT>, but is having nil StructType.
1340			&Row{
1341				[]*sppb.StructType_Field{
1342					{
1343						Name: "Col0", Type: listType(&sppb.Type{Code: sppb.TypeCode_STRUCT}),
1344					},
1345				},
1346				[]*proto3.Value{listProto(listProto(intProto(1), floatProto(2.0), stringProto("3")))},
1347			},
1348			&[]*struct {
1349				Col1 int64
1350				Col2 float64
1351				Col3 string
1352			}{},
1353			errDecodeColumn(0, errDecodeArrayElement(0, listProto(intProto(1), floatProto(2.0), stringProto("3")),
1354				"STRUCT", errNilSpannerStructType())),
1355		},
1356		{
1357			// Field specifies ARRAY<STRUCT>, but the second struct value is for BOOL type instead of FLOAT64.
1358			&Row{
1359				[]*sppb.StructType_Field{
1360					{
1361						Name: "Col0",
1362						Type: listType(
1363							structType(
1364								mkField("Col1", intType()),
1365								mkField("Col2", floatType()),
1366								mkField("Col3", stringType()),
1367							),
1368						),
1369					},
1370				},
1371				[]*proto3.Value{listProto(listProto(intProto(1), boolProto(true), stringProto("3")))},
1372			},
1373			&[]*struct {
1374				Col1 int64
1375				Col2 float64
1376				Col3 string
1377			}{},
1378			errDecodeColumn(
1379				0,
1380				errDecodeArrayElement(
1381					0, listProto(intProto(1), boolProto(true), stringProto("3")), "STRUCT",
1382					errDecodeStructField(
1383						&sppb.StructType{
1384							Fields: []*sppb.StructType_Field{
1385								mkField("Col1", intType()),
1386								mkField("Col2", floatType()),
1387								mkField("Col3", stringType()),
1388							},
1389						},
1390						"Col2",
1391						errSrcVal(boolProto(true), "Number"),
1392					),
1393				),
1394			),
1395		},
1396	} {
1397		if gotErr := test.row.Column(0, test.dst); !testEqual(gotErr, test.wantErr) {
1398			t.Errorf("%v: test.row.Column(0) got error %v, want %v", i, gotErr, test.wantErr)
1399		}
1400		if gotErr := test.row.ColumnByName("Col0", test.dst); !testEqual(gotErr, test.wantErr) {
1401			t.Errorf("%v: test.row.ColumnByName(%q) got error %v, want %v", i, "Col0", gotErr, test.wantErr)
1402		}
1403		if gotErr := test.row.Columns(test.dst); !testEqual(gotErr, test.wantErr) {
1404			t.Errorf("%v: test.row.Columns(%T) got error %v, want %v", i, test.dst, gotErr, test.wantErr)
1405		}
1406	}
1407}
1408
1409// Test Row.ToStruct().
1410func TestToStruct(t *testing.T) {
1411	s := []struct {
1412		// STRING / STRING ARRAY
1413		PrimaryKey      string       `spanner:"STRING"`
1414		NullString      NullString   `spanner:"NULL_STRING"`
1415		StringArray     []NullString `spanner:"STRING_ARRAY"`
1416		NullStringArray []NullString `spanner:"NULL_STRING_ARRAY"`
1417		// BYTES / BYTES ARRAY
1418		Bytes          []byte   `spanner:"BYTES"`
1419		NullBytes      []byte   `spanner:"NULL_BYTES"`
1420		BytesArray     [][]byte `spanner:"BYTES_ARRAY"`
1421		NullBytesArray [][]byte `spanner:"NULL_BYTES_ARRAY"`
1422		// INT64 / INT64 ARRAY
1423		Int64          int64       `spanner:"INT64"`
1424		NullInt64      NullInt64   `spanner:"NULL_INT64"`
1425		Int64Array     []NullInt64 `spanner:"INT64_ARRAY"`
1426		NullInt64Array []NullInt64 `spanner:"NULL_INT64_ARRAY"`
1427		// BOOL / BOOL ARRAY
1428		Bool          bool       `spanner:"BOOL"`
1429		NullBool      NullBool   `spanner:"NULL_BOOL"`
1430		BoolArray     []NullBool `spanner:"BOOL_ARRAY"`
1431		NullBoolArray []NullBool `spanner:"NULL_BOOL_ARRAY"`
1432		// FLOAT64 / FLOAT64 ARRAY
1433		Float64          float64       `spanner:"FLOAT64"`
1434		NullFloat64      NullFloat64   `spanner:"NULL_FLOAT64"`
1435		Float64Array     []NullFloat64 `spanner:"FLOAT64_ARRAY"`
1436		NullFloat64Array []NullFloat64 `spanner:"NULL_FLOAT64_ARRAY"`
1437		// TIMESTAMP / TIMESTAMP ARRAY
1438		Timestamp          time.Time  `spanner:"TIMESTAMP"`
1439		NullTimestamp      NullTime   `spanner:"NULL_TIMESTAMP"`
1440		TimestampArray     []NullTime `spanner:"TIMESTAMP_ARRAY"`
1441		NullTimestampArray []NullTime `spanner:"NULL_TIMESTAMP_ARRAY"`
1442		// DATE / DATE ARRAY
1443		Date          civil.Date `spanner:"DATE"`
1444		NullDate      NullDate   `spanner:"NULL_DATE"`
1445		DateArray     []NullDate `spanner:"DATE_ARRAY"`
1446		NullDateArray []NullDate `spanner:"NULL_DATE_ARRAY"`
1447
1448		// STRUCT ARRAY
1449		StructArray []*struct {
1450			Col1 int64
1451			Col2 float64
1452			Col3 string
1453		} `spanner:"STRUCT_ARRAY"`
1454		NullStructArray []*struct {
1455			Col1 int64
1456			Col2 float64
1457			Col3 string
1458		} `spanner:"NULL_STRUCT_ARRAY"`
1459	}{
1460		{}, // got
1461		{
1462			// STRING / STRING ARRAY
1463			"value",
1464			NullString{},
1465			[]NullString{{"value1", true}, {}, {"value3", true}},
1466			[]NullString(nil),
1467			// BYTES / BYTES ARRAY
1468			[]byte("value"),
1469			[]byte(nil),
1470			[][]byte{[]byte("value1"), nil, []byte("value3")},
1471			[][]byte(nil),
1472			// INT64 / INT64 ARRAY
1473			int64(17),
1474			NullInt64{},
1475			[]NullInt64{{int64(1), true}, {int64(2), true}, {}},
1476			[]NullInt64(nil),
1477			// BOOL / BOOL ARRAY
1478			true,
1479			NullBool{},
1480			[]NullBool{{}, {true, true}, {false, true}},
1481			[]NullBool(nil),
1482			// FLOAT64 / FLOAT64 ARRAY
1483			1.7,
1484			NullFloat64{},
1485			[]NullFloat64{{}, {}, {1.7, true}},
1486			[]NullFloat64(nil),
1487			// TIMESTAMP / TIMESTAMP ARRAY
1488			tm,
1489			NullTime{},
1490			[]NullTime{{}, {tm, true}},
1491			[]NullTime(nil),
1492			// DATE / DATE ARRAY
1493			dt,
1494			NullDate{},
1495			[]NullDate{{}, {dt, true}},
1496			[]NullDate(nil),
1497			// STRUCT ARRAY
1498			[]*struct {
1499				Col1 int64
1500				Col2 float64
1501				Col3 string
1502			}{
1503				nil,
1504
1505				{3, 33.3, "three"},
1506				nil,
1507			},
1508			[]*struct {
1509				Col1 int64
1510				Col2 float64
1511				Col3 string
1512			}(nil),
1513		}, // want
1514	}
1515	err := row.ToStruct(&s[0])
1516	if err != nil {
1517		t.Errorf("row.ToStruct() returns error: %v, want nil", err)
1518	} else if !testEqual(s[0], s[1]) {
1519		t.Errorf("row.ToStruct() fetches struct %v, want %v", s[0], s[1])
1520	}
1521}
1522
1523// Test Row.ToStruct() with custom types.
1524func TestToStructWithCustomTypes(t *testing.T) {
1525	type CustomString string
1526	type CustomNullString NullString
1527	type CustomBytes []byte
1528	type CustomInt64 int64
1529	type CustomNullInt64 NullInt64
1530	type CustomBool bool
1531	type CustomNullBool NullBool
1532	type CustomFloat64 float64
1533	type CustomNullFloat64 NullFloat64
1534	type CustomTime time.Time
1535	type CustomNullTime NullTime
1536	type CustomDate civil.Date
1537	type CustomNullDate NullDate
1538
1539	s := []struct {
1540		// STRING / STRING ARRAY
1541		PrimaryKey      CustomString       `spanner:"STRING"`
1542		NullString      CustomNullString   `spanner:"NULL_STRING"`
1543		StringArray     []CustomNullString `spanner:"STRING_ARRAY"`
1544		NullStringArray []CustomNullString `spanner:"NULL_STRING_ARRAY"`
1545		// BYTES / BYTES ARRAY
1546		Bytes          CustomBytes   `spanner:"BYTES"`
1547		NullBytes      CustomBytes   `spanner:"NULL_BYTES"`
1548		BytesArray     []CustomBytes `spanner:"BYTES_ARRAY"`
1549		NullBytesArray []CustomBytes `spanner:"NULL_BYTES_ARRAY"`
1550		// INT64 / INT64 ARRAY
1551		Int64          CustomInt64       `spanner:"INT64"`
1552		NullInt64      CustomNullInt64   `spanner:"NULL_INT64"`
1553		Int64Array     []CustomNullInt64 `spanner:"INT64_ARRAY"`
1554		NullInt64Array []CustomNullInt64 `spanner:"NULL_INT64_ARRAY"`
1555		// BOOL / BOOL ARRAY
1556		Bool          CustomBool       `spanner:"BOOL"`
1557		NullBool      CustomNullBool   `spanner:"NULL_BOOL"`
1558		BoolArray     []CustomNullBool `spanner:"BOOL_ARRAY"`
1559		NullBoolArray []CustomNullBool `spanner:"NULL_BOOL_ARRAY"`
1560		// FLOAT64 / FLOAT64 ARRAY
1561		Float64          CustomFloat64       `spanner:"FLOAT64"`
1562		NullFloat64      CustomNullFloat64   `spanner:"NULL_FLOAT64"`
1563		Float64Array     []CustomNullFloat64 `spanner:"FLOAT64_ARRAY"`
1564		NullFloat64Array []CustomNullFloat64 `spanner:"NULL_FLOAT64_ARRAY"`
1565		// TIMESTAMP / TIMESTAMP ARRAY
1566		Timestamp          CustomTime       `spanner:"TIMESTAMP"`
1567		NullTimestamp      CustomNullTime   `spanner:"NULL_TIMESTAMP"`
1568		TimestampArray     []CustomNullTime `spanner:"TIMESTAMP_ARRAY"`
1569		NullTimestampArray []CustomNullTime `spanner:"NULL_TIMESTAMP_ARRAY"`
1570		// DATE / DATE ARRAY
1571		Date          CustomDate       `spanner:"DATE"`
1572		NullDate      CustomNullDate   `spanner:"NULL_DATE"`
1573		DateArray     []CustomNullDate `spanner:"DATE_ARRAY"`
1574		NullDateArray []CustomNullDate `spanner:"NULL_DATE_ARRAY"`
1575
1576		// STRUCT ARRAY
1577		StructArray []*struct {
1578			Col1 CustomInt64
1579			Col2 CustomFloat64
1580			Col3 CustomString
1581		} `spanner:"STRUCT_ARRAY"`
1582		NullStructArray []*struct {
1583			Col1 CustomInt64
1584			Col2 CustomFloat64
1585			Col3 CustomString
1586		} `spanner:"NULL_STRUCT_ARRAY"`
1587	}{
1588		{}, // got
1589		{
1590			// STRING / STRING ARRAY
1591			"value",
1592			CustomNullString{},
1593			[]CustomNullString{{"value1", true}, {}, {"value3", true}},
1594			[]CustomNullString(nil),
1595			// BYTES / BYTES ARRAY
1596			CustomBytes("value"),
1597			CustomBytes(nil),
1598			[]CustomBytes{[]byte("value1"), nil, []byte("value3")},
1599			[]CustomBytes(nil),
1600			// INT64 / INT64 ARRAY
1601			CustomInt64(17),
1602			CustomNullInt64{},
1603			[]CustomNullInt64{{int64(1), true}, {int64(2), true}, {}},
1604			[]CustomNullInt64(nil),
1605			// BOOL / BOOL ARRAY
1606			true,
1607			CustomNullBool{},
1608			[]CustomNullBool{{}, {true, true}, {false, true}},
1609			[]CustomNullBool(nil),
1610			// FLOAT64 / FLOAT64 ARRAY
1611			1.7,
1612			CustomNullFloat64{},
1613			[]CustomNullFloat64{{}, {}, {1.7, true}},
1614			[]CustomNullFloat64(nil),
1615			// TIMESTAMP / TIMESTAMP ARRAY
1616			CustomTime(tm),
1617			CustomNullTime{},
1618			[]CustomNullTime{{}, {tm, true}},
1619			[]CustomNullTime(nil),
1620			// DATE / DATE ARRAY
1621			CustomDate(dt),
1622			CustomNullDate{},
1623			[]CustomNullDate{{}, {dt, true}},
1624			[]CustomNullDate(nil),
1625			// STRUCT ARRAY
1626			[]*struct {
1627				Col1 CustomInt64
1628				Col2 CustomFloat64
1629				Col3 CustomString
1630			}{
1631				nil,
1632
1633				{3, 33.3, "three"},
1634				nil,
1635			},
1636			[]*struct {
1637				Col1 CustomInt64
1638				Col2 CustomFloat64
1639				Col3 CustomString
1640			}(nil),
1641		}, // want
1642	}
1643	err := row.ToStruct(&s[0])
1644	if err != nil {
1645		t.Errorf("row.ToStruct() returns error: %v, want nil", err)
1646	} else if !testutil.Equal(s[0], s[1], cmp.AllowUnexported(CustomTime{})) {
1647		t.Errorf("row.ToStruct() fetches struct %v, want %v", s[0], s[1])
1648	}
1649}
1650
1651func TestToStructEmbedded(t *testing.T) {
1652	type (
1653		S1 struct{ F1 string }
1654		S2 struct {
1655			S1
1656			F2 string
1657		}
1658	)
1659	r := Row{
1660		[]*sppb.StructType_Field{
1661			{Name: "F1", Type: stringType()},
1662			{Name: "F2", Type: stringType()},
1663		},
1664		[]*proto3.Value{
1665			stringProto("v1"),
1666			stringProto("v2"),
1667		},
1668	}
1669	var got S2
1670	if err := r.ToStruct(&got); err != nil {
1671		t.Fatal(err)
1672	}
1673	want := S2{S1: S1{F1: "v1"}, F2: "v2"}
1674	if !testEqual(got, want) {
1675		t.Errorf("got %+v, want %+v", got, want)
1676	}
1677}
1678
1679func TestRowToString(t *testing.T) {
1680	r := Row{
1681		[]*sppb.StructType_Field{
1682			{Name: "F1", Type: stringType()},
1683			{Name: "F2", Type: stringType()},
1684		},
1685		[]*proto3.Value{
1686			stringProto("v1"),
1687			stringProto("v2"),
1688		},
1689	}
1690	got := r.String()
1691	want := `{fields: [name:"F1" type:{code:STRING} name:"F2" type:{code:STRING}], values: [string_value:"v1" string_value:"v2"]}`
1692	// In protobuf-go, the encoder will add an additional space based on a
1693	// deterministically random boolean value.
1694	wantWithTwoSpaces := `{fields: [name:"F1"  type:{code:STRING} name:"F2"  type:{code:STRING}], values: [string_value:"v1" string_value:"v2"]}`
1695
1696	if !testEqual(r.String(), want) && !testEqual(r.String(), wantWithTwoSpaces) {
1697		t.Errorf("got %+v, want %+v", got, want)
1698	}
1699}
1700
1701// Test helpers for getting column names.
1702func TestColumnNameAndIndex(t *testing.T) {
1703	// Test Row.Size().
1704	if rs := row.Size(); rs != len(row.fields) {
1705		t.Errorf("row.Size() returns %v, want %v", rs, len(row.fields))
1706	}
1707	// Test Row.Size() on empty Row.
1708	if rs := (&Row{}).Size(); rs != 0 {
1709		t.Errorf("empty_row.Size() returns %v, want %v", rs, 0)
1710	}
1711	// Test Row.ColumnName()
1712	for i, col := range row.fields {
1713		if cn := row.ColumnName(i); cn != col.Name {
1714			t.Errorf("row.ColumnName(%v) returns %q, want %q", i, cn, col.Name)
1715		}
1716		goti, err := row.ColumnIndex(col.Name)
1717		if err != nil {
1718			t.Errorf("ColumnIndex(%q) error %v", col.Name, err)
1719			continue
1720		}
1721		if goti != i {
1722			t.Errorf("ColumnIndex(%q) = %d, want %d", col.Name, goti, i)
1723		}
1724	}
1725	// Test Row.ColumnName on empty Row.
1726	if cn := (&Row{}).ColumnName(0); cn != "" {
1727		t.Errorf("empty_row.ColumnName(%v) returns %q, want %q", 0, cn, "")
1728	}
1729	// Test Row.ColumnIndex on empty Row.
1730	if _, err := (&Row{}).ColumnIndex(""); err == nil {
1731		t.Error("empty_row.ColumnIndex returns nil, want error")
1732	}
1733}
1734
1735func TestNewRow(t *testing.T) {
1736	for _, test := range []struct {
1737		names   []string
1738		values  []interface{}
1739		want    *Row
1740		wantErr error
1741	}{
1742		{
1743			want: &Row{fields: []*sppb.StructType_Field{}, vals: []*proto3.Value{}},
1744		},
1745		{
1746			names:  []string{},
1747			values: []interface{}{},
1748			want:   &Row{fields: []*sppb.StructType_Field{}, vals: []*proto3.Value{}},
1749		},
1750		{
1751			names:   []string{"a", "b"},
1752			values:  []interface{}{},
1753			want:    nil,
1754			wantErr: errNamesValuesMismatch([]string{"a", "b"}, []interface{}{}),
1755		},
1756		{
1757			names:  []string{"a", "b", "c"},
1758			values: []interface{}{5, "abc", GenericColumnValue{listType(intType()), listProto(intProto(91), nullProto(), intProto(87))}},
1759			want: &Row{
1760				[]*sppb.StructType_Field{
1761					{Name: "a", Type: intType()},
1762					{Name: "b", Type: stringType()},
1763					{Name: "c", Type: listType(intType())},
1764				},
1765				[]*proto3.Value{
1766					intProto(5),
1767					stringProto("abc"),
1768					listProto(intProto(91), nullProto(), intProto(87)),
1769				},
1770			},
1771		},
1772	} {
1773		got, err := NewRow(test.names, test.values)
1774		if !testEqual(err, test.wantErr) {
1775			t.Errorf("NewRow(%v,%v).err = %s, want %s", test.names, test.values, err, test.wantErr)
1776			continue
1777		}
1778		if !testEqual(got, test.want) {
1779			t.Errorf("NewRow(%v,%v) = %s, want %s", test.names, test.values, got, test.want)
1780			continue
1781		}
1782	}
1783}
1784
1785func BenchmarkColumn(b *testing.B) {
1786	var s string
1787	for i := 0; i < b.N; i++ {
1788		if err := row.Column(0, &s); err != nil {
1789			b.Fatal(err)
1790		}
1791	}
1792}
1793