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	"math"
21	"reflect"
22	"testing"
23	"time"
24
25	"cloud.google.com/go/civil"
26	proto3 "github.com/golang/protobuf/ptypes/struct"
27	sppb "google.golang.org/genproto/googleapis/spanner/v1"
28)
29
30var (
31	t1 = mustParseTime("2016-11-15T15:04:05.999999999Z")
32	// Boundaries
33	t2 = mustParseTime("0000-01-01T00:00:00.000000000Z")
34	t3 = mustParseTime("9999-12-31T23:59:59.999999999Z")
35	// Local timezone
36	t4 = time.Now()
37	d1 = mustParseDate("2016-11-15")
38	d2 = mustParseDate("1678-01-01")
39)
40
41func mustParseTime(s string) time.Time {
42	t, err := time.Parse(time.RFC3339Nano, s)
43	if err != nil {
44		panic(err)
45	}
46	return t
47}
48
49func mustParseDate(s string) civil.Date {
50	d, err := civil.ParseDate(s)
51	if err != nil {
52		panic(err)
53	}
54	return d
55}
56
57// Test encoding Values.
58func TestEncodeValue(t *testing.T) {
59	var (
60		tString = stringType()
61		tInt    = intType()
62		tBool   = boolType()
63		tFloat  = floatType()
64		tBytes  = bytesType()
65		tTime   = timeType()
66		tDate   = dateType()
67	)
68	for i, test := range []struct {
69		in       interface{}
70		want     *proto3.Value
71		wantType *sppb.Type
72	}{
73		// STRING / STRING ARRAY
74		{"abc", stringProto("abc"), tString},
75		{NullString{"abc", true}, stringProto("abc"), tString},
76		{NullString{"abc", false}, nullProto(), tString},
77		{[]string(nil), nullProto(), listType(tString)},
78		{[]string{"abc", "bcd"}, listProto(stringProto("abc"), stringProto("bcd")), listType(tString)},
79		{[]NullString{{"abcd", true}, {"xyz", false}}, listProto(stringProto("abcd"), nullProto()), listType(tString)},
80		// BYTES / BYTES ARRAY
81		{[]byte("foo"), bytesProto([]byte("foo")), tBytes},
82		{[]byte(nil), nullProto(), tBytes},
83		{[][]byte{nil, []byte("ab")}, listProto(nullProto(), bytesProto([]byte("ab"))), listType(tBytes)},
84		{[][]byte(nil), nullProto(), listType(tBytes)},
85		// INT64 / INT64 ARRAY
86		{7, intProto(7), tInt},
87		{[]int(nil), nullProto(), listType(tInt)},
88		{[]int{31, 127}, listProto(intProto(31), intProto(127)), listType(tInt)},
89		{int64(81), intProto(81), tInt},
90		{[]int64(nil), nullProto(), listType(tInt)},
91		{[]int64{33, 129}, listProto(intProto(33), intProto(129)), listType(tInt)},
92		{NullInt64{11, true}, intProto(11), tInt},
93		{NullInt64{11, false}, nullProto(), tInt},
94		{[]NullInt64{{35, true}, {131, false}}, listProto(intProto(35), nullProto()), listType(tInt)},
95		// BOOL / BOOL ARRAY
96		{true, boolProto(true), tBool},
97		{NullBool{true, true}, boolProto(true), tBool},
98		{NullBool{true, false}, nullProto(), tBool},
99		{[]bool{true, false}, listProto(boolProto(true), boolProto(false)), listType(tBool)},
100		{[]NullBool{{true, true}, {true, false}}, listProto(boolProto(true), nullProto()), listType(tBool)},
101		// FLOAT64 / FLOAT64 ARRAY
102		{3.14, floatProto(3.14), tFloat},
103		{NullFloat64{3.1415, true}, floatProto(3.1415), tFloat},
104		{NullFloat64{math.Inf(1), true}, floatProto(math.Inf(1)), tFloat},
105		{NullFloat64{3.14159, false}, nullProto(), tFloat},
106		{[]float64(nil), nullProto(), listType(tFloat)},
107		{[]float64{3.141, 0.618, math.Inf(-1)}, listProto(floatProto(3.141), floatProto(0.618), floatProto(math.Inf(-1))), listType(tFloat)},
108		{[]NullFloat64{{3.141, true}, {0.618, false}}, listProto(floatProto(3.141), nullProto()), listType(tFloat)},
109		// TIMESTAMP / TIMESTAMP ARRAY
110		{t1, timeProto(t1), tTime},
111		{NullTime{t1, true}, timeProto(t1), tTime},
112		{NullTime{t1, false}, nullProto(), tTime},
113		{[]time.Time(nil), nullProto(), listType(tTime)},
114		{[]time.Time{t1, t2, t3, t4}, listProto(timeProto(t1), timeProto(t2), timeProto(t3), timeProto(t4)), listType(tTime)},
115		{[]NullTime{{t1, true}, {t1, false}}, listProto(timeProto(t1), nullProto()), listType(tTime)},
116		// DATE / DATE ARRAY
117		{d1, dateProto(d1), tDate},
118		{NullDate{d1, true}, dateProto(d1), tDate},
119		{NullDate{civil.Date{}, false}, nullProto(), tDate},
120		{[]civil.Date(nil), nullProto(), listType(tDate)},
121		{[]civil.Date{d1, d2}, listProto(dateProto(d1), dateProto(d2)), listType(tDate)},
122		{[]NullDate{{d1, true}, {civil.Date{}, false}}, listProto(dateProto(d1), nullProto()), listType(tDate)},
123		// GenericColumnValue
124		{GenericColumnValue{tString, stringProto("abc")}, stringProto("abc"), tString},
125		{GenericColumnValue{tString, nullProto()}, nullProto(), tString},
126		// not actually valid (stringProto inside int list), but demonstrates pass-through.
127		{
128			GenericColumnValue{
129				Type:  listType(tInt),
130				Value: listProto(intProto(5), nullProto(), stringProto("bcd")),
131			},
132			listProto(intProto(5), nullProto(), stringProto("bcd")),
133			listType(tInt),
134		},
135		// placeholder
136		{CommitTimestamp, stringProto(commitTimestampPlaceholderString), tTime},
137	} {
138		got, gotType, err := encodeValue(test.in)
139		if err != nil {
140			t.Fatalf("#%d: got error during encoding: %v, want nil", i, err)
141		}
142		if !testEqual(got, test.want) {
143			t.Errorf("#%d: got encode result: %v, want %v", i, got, test.want)
144		}
145		if !testEqual(gotType, test.wantType) {
146			t.Errorf("#%d: got encode type: %v, want %v", i, gotType, test.wantType)
147		}
148	}
149}
150
151type encodeTest struct {
152	desc     string
153	in       interface{}
154	want     *proto3.Value
155	wantType *sppb.Type
156}
157
158func checkStructEncoding(desc string, got *proto3.Value, gotType *sppb.Type,
159	want *proto3.Value, wantType *sppb.Type, t *testing.T) {
160	if !testEqual(got, want) {
161		t.Errorf("Test %s: got encode result: %v, want %v", desc, got, want)
162	}
163	if !testEqual(gotType, wantType) {
164		t.Errorf("Test %s: got encode type: %v, want %v", desc, gotType, wantType)
165	}
166}
167
168// Testcase code
169func encodeStructValue(test encodeTest, t *testing.T) {
170	got, gotType, err := encodeValue(test.in)
171	if err != nil {
172		t.Fatalf("Test %s: got error during encoding: %v, want nil", test.desc, err)
173	}
174	checkStructEncoding(test.desc, got, gotType, test.want, test.wantType, t)
175}
176
177func TestEncodeStructValuePointers(t *testing.T) {
178	type structf struct {
179		F int `spanner:"ff2"`
180	}
181	nestedStructProto := structType(mkField("ff2", intType()))
182
183	type testType struct {
184		Stringf    string
185		Structf    *structf
186		ArrStructf []*structf
187	}
188	testTypeProto := structType(
189		mkField("Stringf", stringType()),
190		mkField("Structf", nestedStructProto),
191		mkField("ArrStructf", listType(nestedStructProto)))
192
193	for _, test := range []encodeTest{
194		{
195			"Pointer to Go struct with pointers-to-(array)-struct fields.",
196			&testType{"hello", &structf{50}, []*structf{&structf{30}, &structf{40}}},
197			listProto(
198				stringProto("hello"),
199				listProto(intProto(50)),
200				listProto(
201					listProto(intProto(30)),
202					listProto(intProto(40)))),
203			testTypeProto,
204		},
205		{
206			"Nil pointer to Go struct representing a NULL struct value.",
207			(*testType)(nil),
208			nullProto(),
209			testTypeProto,
210		},
211		{
212			"Slice of pointers to Go structs with NULL and non-NULL elements.",
213			[]*testType{
214				(*testType)(nil),
215				&testType{"hello", nil, []*structf{nil, &structf{40}}},
216				&testType{"world", &structf{70}, nil},
217			},
218			listProto(
219				nullProto(),
220				listProto(
221					stringProto("hello"),
222					nullProto(),
223					listProto(nullProto(), listProto(intProto(40)))),
224				listProto(
225					stringProto("world"),
226					listProto(intProto(70)),
227					nullProto())),
228			listType(testTypeProto),
229		},
230		{
231			"Nil slice of pointers to structs representing a NULL array of structs.",
232			[]*testType(nil),
233			nullProto(),
234			listType(testTypeProto),
235		},
236		{
237			"Empty slice of pointers to structs representing an empty array of structs.",
238			[]*testType{},
239			listProto(),
240			listType(testTypeProto),
241		},
242	} {
243		encodeStructValue(test, t)
244	}
245}
246
247func TestEncodeStructValueErrors(t *testing.T) {
248	type Embedded struct {
249		A int
250	}
251	type embedded struct {
252		B bool
253	}
254	x := 0
255
256	for _, test := range []struct {
257		desc    string
258		in      interface{}
259		wantErr error
260	}{
261		{
262			"Unsupported embedded fields.",
263			struct{ Embedded }{Embedded{10}},
264			errUnsupportedEmbeddedStructFields("Embedded"),
265		},
266		{
267			"Unsupported pointer to embedded fields.",
268			struct{ *Embedded }{&Embedded{10}},
269			errUnsupportedEmbeddedStructFields("Embedded"),
270		},
271		{
272			"Unsupported embedded + unexported fields.",
273			struct {
274				int
275				*bool
276				embedded
277			}{10, nil, embedded{false}},
278			errUnsupportedEmbeddedStructFields("int"),
279		},
280		{
281			"Unsupported type.",
282			(**struct{})(nil),
283			errEncoderUnsupportedType((**struct{})(nil)),
284		},
285		{
286			"Unsupported type.",
287			3,
288			errEncoderUnsupportedType(3),
289		},
290		{
291			"Unsupported type.",
292			&x,
293			errEncoderUnsupportedType(&x),
294		},
295	} {
296		_, _, got := encodeStruct(test.in)
297		if got == nil || !testEqual(test.wantErr, got) {
298			t.Errorf("Test: %s, expected error %v during decoding, got %v", test.desc, test.wantErr, got)
299		}
300	}
301}
302
303func TestEncodeStructValueArrayStructFields(t *testing.T) {
304	type structf struct {
305		Intff int
306	}
307
308	structfType := structType(mkField("Intff", intType()))
309	for _, test := range []encodeTest{
310		{
311			"Unnamed array-of-struct-typed field.",
312			struct {
313				Intf       int
314				ArrStructf []structf `spanner:""`
315			}{10, []structf{structf{1}, structf{2}}},
316			listProto(
317				intProto(10),
318				listProto(
319					listProto(intProto(1)),
320					listProto(intProto(2)))),
321			structType(
322				mkField("Intf", intType()),
323				mkField("", listType(structfType))),
324		},
325		{
326			"Null array-of-struct-typed field.",
327			struct {
328				Intf       int
329				ArrStructf []structf
330			}{10, []structf(nil)},
331			listProto(intProto(10), nullProto()),
332			structType(
333				mkField("Intf", intType()),
334				mkField("ArrStructf", listType(structfType))),
335		},
336		{
337			"Array-of-struct-typed field representing empty array.",
338			struct {
339				Intf       int
340				ArrStructf []structf
341			}{10, []structf{}},
342			listProto(intProto(10), listProto([]*proto3.Value{}...)),
343			structType(
344				mkField("Intf", intType()),
345				mkField("ArrStructf", listType(structfType))),
346		},
347		{
348			"Array-of-struct-typed field with nullable struct elements.",
349			struct {
350				Intf       int
351				ArrStructf []*structf
352			}{
353				10,
354				[]*structf{(*structf)(nil), &structf{1}},
355			},
356			listProto(
357				intProto(10),
358				listProto(
359					nullProto(),
360					listProto(intProto(1)))),
361			structType(
362				mkField("Intf", intType()),
363				mkField("ArrStructf", listType(structfType))),
364		},
365	} {
366		encodeStructValue(test, t)
367	}
368}
369
370func TestEncodeStructValueStructFields(t *testing.T) {
371	type structf struct {
372		Intff int
373	}
374	structfType := structType(mkField("Intff", intType()))
375	for _, test := range []encodeTest{
376		{
377			"Named struct-type field.",
378			struct {
379				Intf    int
380				Structf structf
381			}{10, structf{10}},
382			listProto(intProto(10), listProto(intProto(10))),
383			structType(
384				mkField("Intf", intType()),
385				mkField("Structf", structfType)),
386		},
387		{
388			"Unnamed struct-type field.",
389			struct {
390				Intf    int
391				Structf structf `spanner:""`
392			}{10, structf{10}},
393			listProto(intProto(10), listProto(intProto(10))),
394			structType(
395				mkField("Intf", intType()),
396				mkField("", structfType)),
397		},
398		{
399			"Duplicate struct-typed field.",
400			struct {
401				Structf1 structf `spanner:""`
402				Structf2 structf `spanner:""`
403			}{structf{10}, structf{20}},
404			listProto(listProto(intProto(10)), listProto(intProto(20))),
405			structType(
406				mkField("", structfType),
407				mkField("", structfType)),
408		},
409		{
410			"Null struct-typed field.",
411			struct {
412				Intf    int
413				Structf *structf
414			}{10, nil},
415			listProto(intProto(10), nullProto()),
416			structType(
417				mkField("Intf", intType()),
418				mkField("Structf", structfType)),
419		},
420		{
421			"Empty struct-typed field.",
422			struct {
423				Intf    int
424				Structf struct{}
425			}{10, struct{}{}},
426			listProto(intProto(10), listProto([]*proto3.Value{}...)),
427			structType(
428				mkField("Intf", intType()),
429				mkField("Structf", structType([]*sppb.StructType_Field{}...))),
430		},
431	} {
432		encodeStructValue(test, t)
433	}
434}
435
436func TestEncodeStructValueFieldNames(t *testing.T) {
437	type embedded struct {
438		B bool
439	}
440
441	for _, test := range []encodeTest{
442		{
443			"Duplicate fields.",
444			struct {
445				Field1    int `spanner:"field"`
446				DupField1 int `spanner:"field"`
447			}{10, 20},
448			listProto(intProto(10), intProto(20)),
449			structType(
450				mkField("field", intType()),
451				mkField("field", intType())),
452		},
453		{
454			"Duplicate Fields (different types).",
455			struct {
456				IntField    int    `spanner:"field"`
457				StringField string `spanner:"field"`
458			}{10, "abc"},
459			listProto(intProto(10), stringProto("abc")),
460			structType(
461				mkField("field", intType()),
462				mkField("field", stringType())),
463		},
464		{
465			"Duplicate unnamed fields.",
466			struct {
467				Dup  int `spanner:""`
468				Dup1 int `spanner:""`
469			}{10, 20},
470			listProto(intProto(10), intProto(20)),
471			structType(
472				mkField("", intType()),
473				mkField("", intType())),
474		},
475		{
476			"Named and unnamed fields.",
477			struct {
478				Field  string
479				Field1 int    `spanner:""`
480				Field2 string `spanner:"field"`
481			}{"abc", 10, "def"},
482			listProto(stringProto("abc"), intProto(10), stringProto("def")),
483			structType(
484				mkField("Field", stringType()),
485				mkField("", intType()),
486				mkField("field", stringType())),
487		},
488		{
489			"Ignored unexported fields.",
490			struct {
491				Field  int
492				field  bool
493				Field1 string `spanner:"field"`
494			}{10, false, "abc"},
495			listProto(intProto(10), stringProto("abc")),
496			structType(
497				mkField("Field", intType()),
498				mkField("field", stringType())),
499		},
500		{
501			"Ignored unexported struct/slice fields.",
502			struct {
503				a      []*embedded
504				b      []embedded
505				c      embedded
506				d      *embedded
507				Field1 string `spanner:"field"`
508			}{nil, nil, embedded{}, nil, "def"},
509			listProto(stringProto("def")),
510			structType(
511				mkField("field", stringType())),
512		},
513	} {
514		encodeStructValue(test, t)
515	}
516}
517
518func TestEncodeStructValueBasicFields(t *testing.T) {
519	StructTypeProto := structType(
520		mkField("Stringf", stringType()),
521		mkField("Intf", intType()),
522		mkField("Boolf", boolType()),
523		mkField("Floatf", floatType()),
524		mkField("Bytef", bytesType()),
525		mkField("Timef", timeType()),
526		mkField("Datef", dateType()))
527
528	for _, test := range []encodeTest{
529		{
530			"Basic types.",
531			struct {
532				Stringf string
533				Intf    int
534				Boolf   bool
535				Floatf  float64
536				Bytef   []byte
537				Timef   time.Time
538				Datef   civil.Date
539			}{"abc", 300, false, 3.45, []byte("foo"), t1, d1},
540			listProto(
541				stringProto("abc"),
542				intProto(300),
543				boolProto(false),
544				floatProto(3.45),
545				bytesProto([]byte("foo")),
546				timeProto(t1),
547				dateProto(d1)),
548			StructTypeProto,
549		},
550		{
551			"Basic types null values.",
552			struct {
553				Stringf NullString
554				Intf    NullInt64
555				Boolf   NullBool
556				Floatf  NullFloat64
557				Bytef   []byte
558				Timef   NullTime
559				Datef   NullDate
560			}{
561				NullString{"abc", false},
562				NullInt64{4, false},
563				NullBool{false, false},
564				NullFloat64{5.6, false},
565				nil,
566				NullTime{t1, false},
567				NullDate{d1, false},
568			},
569			listProto(
570				nullProto(),
571				nullProto(),
572				nullProto(),
573				nullProto(),
574				nullProto(),
575				nullProto(),
576				nullProto()),
577			StructTypeProto,
578		},
579	} {
580		encodeStructValue(test, t)
581	}
582}
583
584func TestEncodeStructValueArrayFields(t *testing.T) {
585	StructTypeProto := structType(
586		mkField("Stringf", listType(stringType())),
587		mkField("Intf", listType(intType())),
588		mkField("Int64f", listType(intType())),
589		mkField("Boolf", listType(boolType())),
590		mkField("Floatf", listType(floatType())),
591		mkField("Bytef", listType(bytesType())),
592		mkField("Timef", listType(timeType())),
593		mkField("Datef", listType(dateType())))
594
595	for _, test := range []encodeTest{
596		{
597			"Arrays of basic types with non-nullable elements",
598			struct {
599				Stringf []string
600				Intf    []int
601				Int64f  []int64
602				Boolf   []bool
603				Floatf  []float64
604				Bytef   [][]byte
605				Timef   []time.Time
606				Datef   []civil.Date
607			}{
608				[]string{"abc", "def"},
609				[]int{4, 67},
610				[]int64{5, 68},
611				[]bool{false, true},
612				[]float64{3.45, 0.93},
613				[][]byte{[]byte("foo"), nil},
614				[]time.Time{t1, t2},
615				[]civil.Date{d1, d2},
616			},
617			listProto(
618				listProto(stringProto("abc"), stringProto("def")),
619				listProto(intProto(4), intProto(67)),
620				listProto(intProto(5), intProto(68)),
621				listProto(boolProto(false), boolProto(true)),
622				listProto(floatProto(3.45), floatProto(0.93)),
623				listProto(bytesProto([]byte("foo")), nullProto()),
624				listProto(timeProto(t1), timeProto(t2)),
625				listProto(dateProto(d1), dateProto(d2))),
626			StructTypeProto,
627		},
628		{
629			"Arrays of basic types with nullable elements.",
630			struct {
631				Stringf []NullString
632				Intf    []NullInt64
633				Int64f  []NullInt64
634				Boolf   []NullBool
635				Floatf  []NullFloat64
636				Bytef   [][]byte
637				Timef   []NullTime
638				Datef   []NullDate
639			}{
640				[]NullString{NullString{"abc", false}, NullString{"def", true}},
641				[]NullInt64{NullInt64{4, false}, NullInt64{67, true}},
642				[]NullInt64{NullInt64{5, false}, NullInt64{68, true}},
643				[]NullBool{NullBool{true, false}, NullBool{false, true}},
644				[]NullFloat64{NullFloat64{3.45, false}, NullFloat64{0.93, true}},
645				[][]byte{[]byte("foo"), nil},
646				[]NullTime{NullTime{t1, false}, NullTime{t2, true}},
647				[]NullDate{NullDate{d1, false}, NullDate{d2, true}},
648			},
649			listProto(
650				listProto(nullProto(), stringProto("def")),
651				listProto(nullProto(), intProto(67)),
652				listProto(nullProto(), intProto(68)),
653				listProto(nullProto(), boolProto(false)),
654				listProto(nullProto(), floatProto(0.93)),
655				listProto(bytesProto([]byte("foo")), nullProto()),
656				listProto(nullProto(), timeProto(t2)),
657				listProto(nullProto(), dateProto(d2))),
658			StructTypeProto,
659		},
660		{
661			"Null arrays of basic types.",
662			struct {
663				Stringf []NullString
664				Intf    []NullInt64
665				Int64f  []NullInt64
666				Boolf   []NullBool
667				Floatf  []NullFloat64
668				Bytef   [][]byte
669				Timef   []NullTime
670				Datef   []NullDate
671			}{
672				nil,
673				nil,
674				nil,
675				nil,
676				nil,
677				nil,
678				nil,
679				nil,
680			},
681			listProto(
682				nullProto(),
683				nullProto(),
684				nullProto(),
685				nullProto(),
686				nullProto(),
687				nullProto(),
688				nullProto(),
689				nullProto()),
690			StructTypeProto,
691		},
692	} {
693		encodeStructValue(test, t)
694	}
695}
696
697// Test decoding Values.
698func TestDecodeValue(t *testing.T) {
699	for i, test := range []struct {
700		in   *proto3.Value
701		t    *sppb.Type
702		want interface{}
703		fail bool
704	}{
705		// STRING
706		{stringProto("abc"), stringType(), "abc", false},
707		{nullProto(), stringType(), "abc", true},
708		{stringProto("abc"), stringType(), NullString{"abc", true}, false},
709		{nullProto(), stringType(), NullString{}, false},
710		// STRING ARRAY with []NullString
711		{
712			listProto(stringProto("abc"), nullProto(), stringProto("bcd")),
713			listType(stringType()),
714			[]NullString{{"abc", true}, {}, {"bcd", true}},
715			false,
716		},
717		{nullProto(), listType(stringType()), []NullString(nil), false},
718		// STRING ARRAY with []string
719		{
720			listProto(stringProto("abc"), stringProto("bcd")),
721			listType(stringType()),
722			[]string{"abc", "bcd"},
723			false,
724		},
725		// BYTES
726		{bytesProto([]byte("ab")), bytesType(), []byte("ab"), false},
727		{nullProto(), bytesType(), []byte(nil), false},
728		// BYTES ARRAY
729		{listProto(bytesProto([]byte("ab")), nullProto()), listType(bytesType()), [][]byte{[]byte("ab"), nil}, false},
730		{nullProto(), listType(bytesType()), [][]byte(nil), false},
731		//INT64
732		{intProto(15), intType(), int64(15), false},
733		{nullProto(), intType(), int64(0), true},
734		{intProto(15), intType(), NullInt64{15, true}, false},
735		{nullProto(), intType(), NullInt64{}, false},
736		// INT64 ARRAY with []NullInt64
737		{listProto(intProto(91), nullProto(), intProto(87)), listType(intType()), []NullInt64{{91, true}, {}, {87, true}}, false},
738		{nullProto(), listType(intType()), []NullInt64(nil), false},
739		// INT64 ARRAY with []int64
740		{listProto(intProto(91), intProto(87)), listType(intType()), []int64{91, 87}, false},
741		// BOOL
742		{boolProto(true), boolType(), true, false},
743		{nullProto(), boolType(), true, true},
744		{boolProto(true), boolType(), NullBool{true, true}, false},
745		{nullProto(), boolType(), NullBool{}, false},
746		// BOOL ARRAY with []NullBool
747		{listProto(boolProto(true), boolProto(false), nullProto()), listType(boolType()), []NullBool{{true, true}, {false, true}, {}}, false},
748		{nullProto(), listType(boolType()), []NullBool(nil), false},
749		// BOOL ARRAY with []bool
750		{listProto(boolProto(true), boolProto(false)), listType(boolType()), []bool{true, false}, false},
751		// FLOAT64
752		{floatProto(3.14), floatType(), 3.14, false},
753		{nullProto(), floatType(), 0.00, true},
754		{floatProto(3.14), floatType(), NullFloat64{3.14, true}, false},
755		{nullProto(), floatType(), NullFloat64{}, false},
756		// FLOAT64 ARRAY with []NullFloat64
757		{
758			listProto(floatProto(math.Inf(1)), floatProto(math.Inf(-1)), nullProto(), floatProto(3.1)),
759			listType(floatType()),
760			[]NullFloat64{{math.Inf(1), true}, {math.Inf(-1), true}, {}, {3.1, true}},
761			false,
762		},
763		{nullProto(), listType(floatType()), []NullFloat64(nil), false},
764		// FLOAT64 ARRAY with []float64
765		{
766			listProto(floatProto(math.Inf(1)), floatProto(math.Inf(-1)), floatProto(3.1)),
767			listType(floatType()),
768			[]float64{math.Inf(1), math.Inf(-1), 3.1},
769			false,
770		},
771		// TIMESTAMP
772		{timeProto(t1), timeType(), t1, false},
773		{timeProto(t1), timeType(), NullTime{t1, true}, false},
774		{nullProto(), timeType(), NullTime{}, false},
775		// TIMESTAMP ARRAY with []NullTime
776		{listProto(timeProto(t1), timeProto(t2), timeProto(t3), nullProto()), listType(timeType()), []NullTime{{t1, true}, {t2, true}, {t3, true}, {}}, false},
777		{nullProto(), listType(timeType()), []NullTime(nil), false},
778		// TIMESTAMP ARRAY with []time.Time
779		{listProto(timeProto(t1), timeProto(t2), timeProto(t3)), listType(timeType()), []time.Time{t1, t2, t3}, false},
780		// DATE
781		{dateProto(d1), dateType(), d1, false},
782		{dateProto(d1), dateType(), NullDate{d1, true}, false},
783		{nullProto(), dateType(), NullDate{}, false},
784		// DATE ARRAY with []NullDate
785		{listProto(dateProto(d1), dateProto(d2), nullProto()), listType(dateType()), []NullDate{{d1, true}, {d2, true}, {}}, false},
786		{nullProto(), listType(dateType()), []NullDate(nil), false},
787		// DATE ARRAY with []civil.Date
788		{listProto(dateProto(d1), dateProto(d2)), listType(dateType()), []civil.Date{d1, d2}, false},
789		// STRUCT ARRAY
790		// STRUCT schema is equal to the following Go struct:
791		// type s struct {
792		//     Col1 NullInt64
793		//     Col2 []struct {
794		//         SubCol1 float64
795		//         SubCol2 string
796		//     }
797		// }
798		{
799			in: listProto(
800				listProto(
801					intProto(3),
802					listProto(
803						listProto(floatProto(3.14), stringProto("this")),
804						listProto(floatProto(0.57), stringProto("siht")),
805					),
806				),
807				listProto(
808					nullProto(),
809					nullProto(),
810				),
811				nullProto(),
812			),
813			t: listType(
814				structType(
815					mkField("Col1", intType()),
816					mkField(
817						"Col2",
818						listType(
819							structType(
820								mkField("SubCol1", floatType()),
821								mkField("SubCol2", stringType()),
822							),
823						),
824					),
825				),
826			),
827			want: []NullRow{
828				{
829					Row: Row{
830						fields: []*sppb.StructType_Field{
831							mkField("Col1", intType()),
832							mkField(
833								"Col2",
834								listType(
835									structType(
836										mkField("SubCol1", floatType()),
837										mkField("SubCol2", stringType()),
838									),
839								),
840							),
841						},
842						vals: []*proto3.Value{
843							intProto(3),
844							listProto(
845								listProto(floatProto(3.14), stringProto("this")),
846								listProto(floatProto(0.57), stringProto("siht")),
847							),
848						},
849					},
850					Valid: true,
851				},
852				{
853					Row: Row{
854						fields: []*sppb.StructType_Field{
855							mkField("Col1", intType()),
856							mkField(
857								"Col2",
858								listType(
859									structType(
860										mkField("SubCol1", floatType()),
861										mkField("SubCol2", stringType()),
862									),
863								),
864							),
865						},
866						vals: []*proto3.Value{
867							nullProto(),
868							nullProto(),
869						},
870					},
871					Valid: true,
872				},
873				{},
874			},
875			fail: false,
876		},
877		{
878			in: listProto(
879				listProto(
880					intProto(3),
881					listProto(
882						listProto(floatProto(3.14), stringProto("this")),
883						listProto(floatProto(0.57), stringProto("siht")),
884					),
885				),
886				listProto(
887					nullProto(),
888					nullProto(),
889				),
890				nullProto(),
891			),
892			t: listType(
893				structType(
894					mkField("Col1", intType()),
895					mkField(
896						"Col2",
897						listType(
898							structType(
899								mkField("SubCol1", floatType()),
900								mkField("SubCol2", stringType()),
901							),
902						),
903					),
904				),
905			),
906			want: []*struct {
907				Col1      NullInt64
908				StructCol []*struct {
909					SubCol1 NullFloat64
910					SubCol2 string
911				} `spanner:"Col2"`
912			}{
913				{
914					Col1: NullInt64{3, true},
915					StructCol: []*struct {
916						SubCol1 NullFloat64
917						SubCol2 string
918					}{
919						{
920							SubCol1: NullFloat64{3.14, true},
921							SubCol2: "this",
922						},
923						{
924							SubCol1: NullFloat64{0.57, true},
925							SubCol2: "siht",
926						},
927					},
928				},
929				{
930					Col1: NullInt64{},
931					StructCol: []*struct {
932						SubCol1 NullFloat64
933						SubCol2 string
934					}(nil),
935				},
936				nil,
937			},
938			fail: false,
939		},
940		// GenericColumnValue
941		{stringProto("abc"), stringType(), GenericColumnValue{stringType(), stringProto("abc")}, false},
942		{nullProto(), stringType(), GenericColumnValue{stringType(), nullProto()}, false},
943		// not actually valid (stringProto inside int list), but demonstrates pass-through.
944		{
945			in: listProto(intProto(5), nullProto(), stringProto("bcd")),
946			t:  listType(intType()),
947			want: GenericColumnValue{
948				Type:  listType(intType()),
949				Value: listProto(intProto(5), nullProto(), stringProto("bcd")),
950			},
951			fail: false,
952		},
953	} {
954		gotp := reflect.New(reflect.TypeOf(test.want))
955		if err := decodeValue(test.in, test.t, gotp.Interface()); err != nil {
956			if !test.fail {
957				t.Errorf("%d: cannot decode %v(%v): %v", i, test.in, test.t, err)
958			}
959			continue
960		}
961		if test.fail {
962			t.Errorf("%d: decoding %v(%v) succeeds unexpectedly, want error", i, test.in, test.t)
963			continue
964		}
965		got := reflect.Indirect(gotp).Interface()
966		if !testEqual(got, test.want) {
967			t.Errorf("%d: unexpected decoding result - got %v, want %v", i, got, test.want)
968			continue
969		}
970	}
971}
972
973// Test error cases for decodeValue.
974func TestDecodeValueErrors(t *testing.T) {
975	var s string
976	for i, test := range []struct {
977		in *proto3.Value
978		t  *sppb.Type
979		v  interface{}
980	}{
981		{nullProto(), stringType(), nil},
982		{nullProto(), stringType(), 1},
983		{timeProto(t1), timeType(), &s},
984	} {
985		err := decodeValue(test.in, test.t, test.v)
986		if err == nil {
987			t.Errorf("#%d: want error, got nil", i)
988		}
989	}
990}
991
992// Test NaN encoding/decoding.
993func TestNaN(t *testing.T) {
994	// Decode NaN value.
995	f := 0.0
996	nf := NullFloat64{}
997	// To float64
998	if err := decodeValue(floatProto(math.NaN()), floatType(), &f); err != nil {
999		t.Errorf("decodeValue returns %q for %v, want nil", err, floatProto(math.NaN()))
1000	}
1001	if !math.IsNaN(f) {
1002		t.Errorf("f = %v, want %v", f, math.NaN())
1003	}
1004	// To NullFloat64
1005	if err := decodeValue(floatProto(math.NaN()), floatType(), &nf); err != nil {
1006		t.Errorf("decodeValue returns %q for %v, want nil", err, floatProto(math.NaN()))
1007	}
1008	if !math.IsNaN(nf.Float64) || !nf.Valid {
1009		t.Errorf("f = %v, want %v", f, NullFloat64{math.NaN(), true})
1010	}
1011	// Encode NaN value
1012	// From float64
1013	v, _, err := encodeValue(math.NaN())
1014	if err != nil {
1015		t.Errorf("encodeValue returns %q for NaN, want nil", err)
1016	}
1017	x, ok := v.GetKind().(*proto3.Value_NumberValue)
1018	if !ok {
1019		t.Errorf("incorrect type for v.GetKind(): %T, want *proto3.Value_NumberValue", v.GetKind())
1020	}
1021	if !math.IsNaN(x.NumberValue) {
1022		t.Errorf("x.NumberValue = %v, want %v", x.NumberValue, math.NaN())
1023	}
1024	// From NullFloat64
1025	v, _, err = encodeValue(NullFloat64{math.NaN(), true})
1026	if err != nil {
1027		t.Errorf("encodeValue returns %q for NaN, want nil", err)
1028	}
1029	x, ok = v.GetKind().(*proto3.Value_NumberValue)
1030	if !ok {
1031		t.Errorf("incorrect type for v.GetKind(): %T, want *proto3.Value_NumberValue", v.GetKind())
1032	}
1033	if !math.IsNaN(x.NumberValue) {
1034		t.Errorf("x.NumberValue = %v, want %v", x.NumberValue, math.NaN())
1035	}
1036}
1037
1038func TestGenericColumnValue(t *testing.T) {
1039	for _, test := range []struct {
1040		in   GenericColumnValue
1041		want interface{}
1042		fail bool
1043	}{
1044		{GenericColumnValue{stringType(), stringProto("abc")}, "abc", false},
1045		{GenericColumnValue{stringType(), stringProto("abc")}, 5, true},
1046		{GenericColumnValue{listType(intType()), listProto(intProto(91), nullProto(), intProto(87))}, []NullInt64{{91, true}, {}, {87, true}}, false},
1047		{GenericColumnValue{intType(), intProto(42)}, GenericColumnValue{intType(), intProto(42)}, false}, // trippy! :-)
1048	} {
1049		gotp := reflect.New(reflect.TypeOf(test.want))
1050		if err := test.in.Decode(gotp.Interface()); err != nil {
1051			if !test.fail {
1052				t.Errorf("cannot decode %v to %v: %v", test.in, test.want, err)
1053			}
1054			continue
1055		}
1056		if test.fail {
1057			t.Errorf("decoding %v to %v succeeds unexpectedly", test.in, test.want)
1058		}
1059
1060		// Test we can go backwards as well.
1061		v, err := newGenericColumnValue(test.want)
1062		if err != nil {
1063			t.Errorf("NewGenericColumnValue failed: %v", err)
1064			continue
1065		}
1066		if !testEqual(*v, test.in) {
1067			t.Errorf("unexpected encode result - got %v, want %v", v, test.in)
1068		}
1069	}
1070}
1071
1072func TestDecodeStruct(t *testing.T) {
1073	stype := &sppb.StructType{Fields: []*sppb.StructType_Field{
1074		{Name: "Id", Type: stringType()},
1075		{Name: "Time", Type: timeType()},
1076	}}
1077	lv := listValueProto(stringProto("id"), timeProto(t1))
1078
1079	type (
1080		S1 struct {
1081			Id   string
1082			Time time.Time
1083		}
1084		S2 struct {
1085			Id   string
1086			Time string
1087		}
1088	)
1089	var (
1090		s1 S1
1091		s2 S2
1092	)
1093
1094	for i, test := range []struct {
1095		ptr  interface{}
1096		want interface{}
1097		fail bool
1098	}{
1099		{
1100			ptr:  &s1,
1101			want: &S1{Id: "id", Time: t1},
1102		},
1103		{
1104			ptr:  &s2,
1105			fail: true,
1106		},
1107	} {
1108		err := decodeStruct(stype, lv, test.ptr)
1109		if (err != nil) != test.fail {
1110			t.Errorf("#%d: got error %v, wanted fail: %v", i, err, test.fail)
1111		}
1112		if err == nil && !testEqual(test.ptr, test.want) {
1113			t.Errorf("#%d: got %+v, want %+v", i, test.ptr, test.want)
1114		}
1115	}
1116}
1117