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	"github.com/golang/protobuf/proto"
27	proto3 "github.com/golang/protobuf/ptypes/struct"
28	sppb "google.golang.org/genproto/googleapis/spanner/v1"
29)
30
31var (
32	t1 = mustParseTime("2016-11-15T15:04:05.999999999Z")
33	// Boundaries
34	t2 = mustParseTime("0000-01-01T00:00:00.000000000Z")
35	t3 = mustParseTime("9999-12-31T23:59:59.999999999Z")
36	// Local timezone
37	t4 = time.Now()
38	d1 = mustParseDate("2016-11-15")
39	d2 = mustParseDate("1678-01-01")
40)
41
42func mustParseTime(s string) time.Time {
43	t, err := time.Parse(time.RFC3339Nano, s)
44	if err != nil {
45		panic(err)
46	}
47	return t
48}
49
50func mustParseDate(s string) civil.Date {
51	d, err := civil.ParseDate(s)
52	if err != nil {
53		panic(err)
54	}
55	return d
56}
57
58// Test encoding Values.
59func TestEncodeValue(t *testing.T) {
60	var (
61		tString = stringType()
62		tInt    = intType()
63		tBool   = boolType()
64		tFloat  = floatType()
65		tBytes  = bytesType()
66		tTime   = timeType()
67		tDate   = dateType()
68	)
69	for i, test := range []struct {
70		in       interface{}
71		want     *proto3.Value
72		wantType *sppb.Type
73	}{
74		// STRING / STRING ARRAY
75		{"abc", stringProto("abc"), tString},
76		{NullString{"abc", true}, stringProto("abc"), tString},
77		{NullString{"abc", false}, nullProto(), tString},
78		{[]string(nil), nullProto(), listType(tString)},
79		{[]string{"abc", "bcd"}, listProto(stringProto("abc"), stringProto("bcd")), listType(tString)},
80		{[]NullString{{"abcd", true}, {"xyz", false}}, listProto(stringProto("abcd"), nullProto()), listType(tString)},
81		// BYTES / BYTES ARRAY
82		{[]byte("foo"), bytesProto([]byte("foo")), tBytes},
83		{[]byte(nil), nullProto(), tBytes},
84		{[][]byte{nil, []byte("ab")}, listProto(nullProto(), bytesProto([]byte("ab"))), listType(tBytes)},
85		{[][]byte(nil), nullProto(), listType(tBytes)},
86		// INT64 / INT64 ARRAY
87		{7, intProto(7), tInt},
88		{[]int(nil), nullProto(), listType(tInt)},
89		{[]int{31, 127}, listProto(intProto(31), intProto(127)), listType(tInt)},
90		{int64(81), intProto(81), tInt},
91		{[]int64(nil), nullProto(), listType(tInt)},
92		{[]int64{33, 129}, listProto(intProto(33), intProto(129)), listType(tInt)},
93		{NullInt64{11, true}, intProto(11), tInt},
94		{NullInt64{11, false}, nullProto(), tInt},
95		{[]NullInt64{{35, true}, {131, false}}, listProto(intProto(35), nullProto()), listType(tInt)},
96		// BOOL / BOOL ARRAY
97		{true, boolProto(true), tBool},
98		{NullBool{true, true}, boolProto(true), tBool},
99		{NullBool{true, false}, nullProto(), tBool},
100		{[]bool{true, false}, listProto(boolProto(true), boolProto(false)), listType(tBool)},
101		{[]NullBool{{true, true}, {true, false}}, listProto(boolProto(true), nullProto()), listType(tBool)},
102		// FLOAT64 / FLOAT64 ARRAY
103		{3.14, floatProto(3.14), tFloat},
104		{NullFloat64{3.1415, true}, floatProto(3.1415), tFloat},
105		{NullFloat64{math.Inf(1), true}, floatProto(math.Inf(1)), tFloat},
106		{NullFloat64{3.14159, false}, nullProto(), tFloat},
107		{[]float64(nil), nullProto(), listType(tFloat)},
108		{[]float64{3.141, 0.618, math.Inf(-1)}, listProto(floatProto(3.141), floatProto(0.618), floatProto(math.Inf(-1))), listType(tFloat)},
109		{[]NullFloat64{{3.141, true}, {0.618, false}}, listProto(floatProto(3.141), nullProto()), listType(tFloat)},
110		// TIMESTAMP / TIMESTAMP ARRAY
111		{t1, timeProto(t1), tTime},
112		{NullTime{t1, true}, timeProto(t1), tTime},
113		{NullTime{t1, false}, nullProto(), tTime},
114		{[]time.Time(nil), nullProto(), listType(tTime)},
115		{[]time.Time{t1, t2, t3, t4}, listProto(timeProto(t1), timeProto(t2), timeProto(t3), timeProto(t4)), listType(tTime)},
116		{[]NullTime{{t1, true}, {t1, false}}, listProto(timeProto(t1), nullProto()), listType(tTime)},
117		// DATE / DATE ARRAY
118		{d1, dateProto(d1), tDate},
119		{NullDate{d1, true}, dateProto(d1), tDate},
120		{NullDate{civil.Date{}, false}, nullProto(), tDate},
121		{[]civil.Date(nil), nullProto(), listType(tDate)},
122		{[]civil.Date{d1, d2}, listProto(dateProto(d1), dateProto(d2)), listType(tDate)},
123		{[]NullDate{{d1, true}, {civil.Date{}, false}}, listProto(dateProto(d1), nullProto()), listType(tDate)},
124		// GenericColumnValue
125		{GenericColumnValue{tString, stringProto("abc")}, stringProto("abc"), tString},
126		{GenericColumnValue{tString, nullProto()}, nullProto(), tString},
127		// not actually valid (stringProto inside int list), but demonstrates pass-through.
128		{
129			GenericColumnValue{
130				Type:  listType(tInt),
131				Value: listProto(intProto(5), nullProto(), stringProto("bcd")),
132			},
133			listProto(intProto(5), nullProto(), stringProto("bcd")),
134			listType(tInt),
135		},
136		// placeholder
137		{CommitTimestamp, stringProto(commitTimestampPlaceholderString), tTime},
138	} {
139		got, gotType, err := encodeValue(test.in)
140		if err != nil {
141			t.Fatalf("#%d: got error during encoding: %v, want nil", i, err)
142		}
143		if !testEqual(got, test.want) {
144			t.Errorf("#%d: got encode result: %v, want %v", i, got, test.want)
145		}
146		if !testEqual(gotType, test.wantType) {
147			t.Errorf("#%d: got encode type: %v, want %v", i, gotType, test.wantType)
148		}
149	}
150}
151
152type encodeTest struct {
153	desc     string
154	in       interface{}
155	want     *proto3.Value
156	wantType *sppb.Type
157}
158
159func checkStructEncoding(desc string, got *proto3.Value, gotType *sppb.Type,
160	want *proto3.Value, wantType *sppb.Type, t *testing.T) {
161	if !testEqual(got, want) {
162		t.Errorf("Test %s: got encode result: %v, want %v", desc, got, want)
163	}
164	if !testEqual(gotType, wantType) {
165		t.Errorf("Test %s: got encode type: %v, want %v", desc, gotType, wantType)
166	}
167}
168
169// Testcase code
170func encodeStructValue(test encodeTest, t *testing.T) {
171	got, gotType, err := encodeValue(test.in)
172	if err != nil {
173		t.Fatalf("Test %s: got error during encoding: %v, want nil", test.desc, err)
174	}
175	checkStructEncoding(test.desc, got, gotType, test.want, test.wantType, t)
176}
177
178func TestEncodeStructValuePointers(t *testing.T) {
179	type structf struct {
180		F int `spanner:"ff2"`
181	}
182	nestedStructProto := structType(mkField("ff2", intType()))
183
184	type testType struct {
185		Stringf    string
186		Structf    *structf
187		ArrStructf []*structf
188	}
189	testTypeProto := structType(
190		mkField("Stringf", stringType()),
191		mkField("Structf", nestedStructProto),
192		mkField("ArrStructf", listType(nestedStructProto)))
193
194	for _, test := range []encodeTest{
195		{
196			"Pointer to Go struct with pointers-to-(array)-struct fields.",
197			&testType{"hello", &structf{50}, []*structf{{30}, {40}}},
198			listProto(
199				stringProto("hello"),
200				listProto(intProto(50)),
201				listProto(
202					listProto(intProto(30)),
203					listProto(intProto(40)))),
204			testTypeProto,
205		},
206		{
207			"Nil pointer to Go struct representing a NULL struct value.",
208			(*testType)(nil),
209			nullProto(),
210			testTypeProto,
211		},
212		{
213			"Slice of pointers to Go structs with NULL and non-NULL elements.",
214			[]*testType{
215				(*testType)(nil),
216				{"hello", nil, []*structf{nil, {40}}},
217				{"world", &structf{70}, nil},
218			},
219			listProto(
220				nullProto(),
221				listProto(
222					stringProto("hello"),
223					nullProto(),
224					listProto(nullProto(), listProto(intProto(40)))),
225				listProto(
226					stringProto("world"),
227					listProto(intProto(70)),
228					nullProto())),
229			listType(testTypeProto),
230		},
231		{
232			"Nil slice of pointers to structs representing a NULL array of structs.",
233			[]*testType(nil),
234			nullProto(),
235			listType(testTypeProto),
236		},
237		{
238			"Empty slice of pointers to structs representing an empty array of structs.",
239			[]*testType{},
240			listProto(),
241			listType(testTypeProto),
242		},
243	} {
244		encodeStructValue(test, t)
245	}
246}
247
248func TestEncodeStructValueErrors(t *testing.T) {
249	type Embedded struct {
250		A int
251	}
252	type embedded struct {
253		B bool
254	}
255	x := 0
256
257	for _, test := range []struct {
258		desc    string
259		in      interface{}
260		wantErr error
261	}{
262		{
263			"Unsupported embedded fields.",
264			struct{ Embedded }{Embedded{10}},
265			errUnsupportedEmbeddedStructFields("Embedded"),
266		},
267		{
268			"Unsupported pointer to embedded fields.",
269			struct{ *Embedded }{&Embedded{10}},
270			errUnsupportedEmbeddedStructFields("Embedded"),
271		},
272		{
273			"Unsupported embedded + unexported fields.",
274			struct {
275				int
276				*bool
277				embedded
278			}{10, nil, embedded{false}},
279			errUnsupportedEmbeddedStructFields("int"),
280		},
281		{
282			"Unsupported type.",
283			(**struct{})(nil),
284			errEncoderUnsupportedType((**struct{})(nil)),
285		},
286		{
287			"Unsupported type.",
288			3,
289			errEncoderUnsupportedType(3),
290		},
291		{
292			"Unsupported type.",
293			&x,
294			errEncoderUnsupportedType(&x),
295		},
296	} {
297		_, _, got := encodeStruct(test.in)
298		if got == nil || !testEqual(test.wantErr, got) {
299			t.Errorf("Test: %s, expected error %v during decoding, got %v", test.desc, test.wantErr, got)
300		}
301	}
302}
303
304func TestEncodeStructValueArrayStructFields(t *testing.T) {
305	type structf struct {
306		Intff int
307	}
308
309	structfType := structType(mkField("Intff", intType()))
310	for _, test := range []encodeTest{
311		{
312			"Unnamed array-of-struct-typed field.",
313			struct {
314				Intf       int
315				ArrStructf []structf `spanner:""`
316			}{10, []structf{{1}, {2}}},
317			listProto(
318				intProto(10),
319				listProto(
320					listProto(intProto(1)),
321					listProto(intProto(2)))),
322			structType(
323				mkField("Intf", intType()),
324				mkField("", listType(structfType))),
325		},
326		{
327			"Null array-of-struct-typed field.",
328			struct {
329				Intf       int
330				ArrStructf []structf
331			}{10, []structf(nil)},
332			listProto(intProto(10), nullProto()),
333			structType(
334				mkField("Intf", intType()),
335				mkField("ArrStructf", listType(structfType))),
336		},
337		{
338			"Array-of-struct-typed field representing empty array.",
339			struct {
340				Intf       int
341				ArrStructf []structf
342			}{10, []structf{}},
343			listProto(intProto(10), listProto([]*proto3.Value{}...)),
344			structType(
345				mkField("Intf", intType()),
346				mkField("ArrStructf", listType(structfType))),
347		},
348		{
349			"Array-of-struct-typed field with nullable struct elements.",
350			struct {
351				Intf       int
352				ArrStructf []*structf
353			}{
354				10,
355				[]*structf{(*structf)(nil), {1}},
356			},
357			listProto(
358				intProto(10),
359				listProto(
360					nullProto(),
361					listProto(intProto(1)))),
362			structType(
363				mkField("Intf", intType()),
364				mkField("ArrStructf", listType(structfType))),
365		},
366	} {
367		encodeStructValue(test, t)
368	}
369}
370
371func TestEncodeStructValueStructFields(t *testing.T) {
372	type structf struct {
373		Intff int
374	}
375	structfType := structType(mkField("Intff", intType()))
376	for _, test := range []encodeTest{
377		{
378			"Named struct-type field.",
379			struct {
380				Intf    int
381				Structf structf
382			}{10, structf{10}},
383			listProto(intProto(10), listProto(intProto(10))),
384			structType(
385				mkField("Intf", intType()),
386				mkField("Structf", structfType)),
387		},
388		{
389			"Unnamed struct-type field.",
390			struct {
391				Intf    int
392				Structf structf `spanner:""`
393			}{10, structf{10}},
394			listProto(intProto(10), listProto(intProto(10))),
395			structType(
396				mkField("Intf", intType()),
397				mkField("", structfType)),
398		},
399		{
400			"Duplicate struct-typed field.",
401			struct {
402				Structf1 structf `spanner:""`
403				Structf2 structf `spanner:""`
404			}{structf{10}, structf{20}},
405			listProto(listProto(intProto(10)), listProto(intProto(20))),
406			structType(
407				mkField("", structfType),
408				mkField("", structfType)),
409		},
410		{
411			"Null struct-typed field.",
412			struct {
413				Intf    int
414				Structf *structf
415			}{10, nil},
416			listProto(intProto(10), nullProto()),
417			structType(
418				mkField("Intf", intType()),
419				mkField("Structf", structfType)),
420		},
421		{
422			"Empty struct-typed field.",
423			struct {
424				Intf    int
425				Structf struct{}
426			}{10, struct{}{}},
427			listProto(intProto(10), listProto([]*proto3.Value{}...)),
428			structType(
429				mkField("Intf", intType()),
430				mkField("Structf", structType([]*sppb.StructType_Field{}...))),
431		},
432	} {
433		encodeStructValue(test, t)
434	}
435}
436
437func TestEncodeStructValueFieldNames(t *testing.T) {
438	type embedded struct {
439		B bool
440	}
441
442	for _, test := range []encodeTest{
443		{
444			"Duplicate fields.",
445			struct {
446				Field1    int `spanner:"field"`
447				DupField1 int `spanner:"field"`
448			}{10, 20},
449			listProto(intProto(10), intProto(20)),
450			structType(
451				mkField("field", intType()),
452				mkField("field", intType())),
453		},
454		{
455			"Duplicate Fields (different types).",
456			struct {
457				IntField    int    `spanner:"field"`
458				StringField string `spanner:"field"`
459			}{10, "abc"},
460			listProto(intProto(10), stringProto("abc")),
461			structType(
462				mkField("field", intType()),
463				mkField("field", stringType())),
464		},
465		{
466			"Duplicate unnamed fields.",
467			struct {
468				Dup  int `spanner:""`
469				Dup1 int `spanner:""`
470			}{10, 20},
471			listProto(intProto(10), intProto(20)),
472			structType(
473				mkField("", intType()),
474				mkField("", intType())),
475		},
476		{
477			"Named and unnamed fields.",
478			struct {
479				Field  string
480				Field1 int    `spanner:""`
481				Field2 string `spanner:"field"`
482			}{"abc", 10, "def"},
483			listProto(stringProto("abc"), intProto(10), stringProto("def")),
484			structType(
485				mkField("Field", stringType()),
486				mkField("", intType()),
487				mkField("field", stringType())),
488		},
489		{
490			"Ignored unexported fields.",
491			struct {
492				Field  int
493				field  bool
494				Field1 string `spanner:"field"`
495			}{10, false, "abc"},
496			listProto(intProto(10), stringProto("abc")),
497			structType(
498				mkField("Field", intType()),
499				mkField("field", stringType())),
500		},
501		{
502			"Ignored unexported struct/slice fields.",
503			struct {
504				a      []*embedded
505				b      []embedded
506				c      embedded
507				d      *embedded
508				Field1 string `spanner:"field"`
509			}{nil, nil, embedded{}, nil, "def"},
510			listProto(stringProto("def")),
511			structType(
512				mkField("field", stringType())),
513		},
514	} {
515		encodeStructValue(test, t)
516	}
517}
518
519func TestEncodeStructValueBasicFields(t *testing.T) {
520	StructTypeProto := structType(
521		mkField("Stringf", stringType()),
522		mkField("Intf", intType()),
523		mkField("Boolf", boolType()),
524		mkField("Floatf", floatType()),
525		mkField("Bytef", bytesType()),
526		mkField("Timef", timeType()),
527		mkField("Datef", dateType()))
528
529	for _, test := range []encodeTest{
530		{
531			"Basic types.",
532			struct {
533				Stringf string
534				Intf    int
535				Boolf   bool
536				Floatf  float64
537				Bytef   []byte
538				Timef   time.Time
539				Datef   civil.Date
540			}{"abc", 300, false, 3.45, []byte("foo"), t1, d1},
541			listProto(
542				stringProto("abc"),
543				intProto(300),
544				boolProto(false),
545				floatProto(3.45),
546				bytesProto([]byte("foo")),
547				timeProto(t1),
548				dateProto(d1)),
549			StructTypeProto,
550		},
551		{
552			"Basic types null values.",
553			struct {
554				Stringf NullString
555				Intf    NullInt64
556				Boolf   NullBool
557				Floatf  NullFloat64
558				Bytef   []byte
559				Timef   NullTime
560				Datef   NullDate
561			}{
562				NullString{"abc", false},
563				NullInt64{4, false},
564				NullBool{false, false},
565				NullFloat64{5.6, false},
566				nil,
567				NullTime{t1, false},
568				NullDate{d1, false},
569			},
570			listProto(
571				nullProto(),
572				nullProto(),
573				nullProto(),
574				nullProto(),
575				nullProto(),
576				nullProto(),
577				nullProto()),
578			StructTypeProto,
579		},
580	} {
581		encodeStructValue(test, t)
582	}
583}
584
585func TestEncodeStructValueArrayFields(t *testing.T) {
586	StructTypeProto := structType(
587		mkField("Stringf", listType(stringType())),
588		mkField("Intf", listType(intType())),
589		mkField("Int64f", listType(intType())),
590		mkField("Boolf", listType(boolType())),
591		mkField("Floatf", listType(floatType())),
592		mkField("Bytef", listType(bytesType())),
593		mkField("Timef", listType(timeType())),
594		mkField("Datef", listType(dateType())))
595
596	for _, test := range []encodeTest{
597		{
598			"Arrays of basic types with non-nullable elements",
599			struct {
600				Stringf []string
601				Intf    []int
602				Int64f  []int64
603				Boolf   []bool
604				Floatf  []float64
605				Bytef   [][]byte
606				Timef   []time.Time
607				Datef   []civil.Date
608			}{
609				[]string{"abc", "def"},
610				[]int{4, 67},
611				[]int64{5, 68},
612				[]bool{false, true},
613				[]float64{3.45, 0.93},
614				[][]byte{[]byte("foo"), nil},
615				[]time.Time{t1, t2},
616				[]civil.Date{d1, d2},
617			},
618			listProto(
619				listProto(stringProto("abc"), stringProto("def")),
620				listProto(intProto(4), intProto(67)),
621				listProto(intProto(5), intProto(68)),
622				listProto(boolProto(false), boolProto(true)),
623				listProto(floatProto(3.45), floatProto(0.93)),
624				listProto(bytesProto([]byte("foo")), nullProto()),
625				listProto(timeProto(t1), timeProto(t2)),
626				listProto(dateProto(d1), dateProto(d2))),
627			StructTypeProto,
628		},
629		{
630			"Arrays of basic types with nullable elements.",
631			struct {
632				Stringf []NullString
633				Intf    []NullInt64
634				Int64f  []NullInt64
635				Boolf   []NullBool
636				Floatf  []NullFloat64
637				Bytef   [][]byte
638				Timef   []NullTime
639				Datef   []NullDate
640			}{
641				[]NullString{{"abc", false}, {"def", true}},
642				[]NullInt64{{4, false}, {67, true}},
643				[]NullInt64{{5, false}, {68, true}},
644				[]NullBool{{true, false}, {false, true}},
645				[]NullFloat64{{3.45, false}, {0.93, true}},
646				[][]byte{[]byte("foo"), nil},
647				[]NullTime{{t1, false}, {t2, true}},
648				[]NullDate{{d1, false}, {d2, true}},
649			},
650			listProto(
651				listProto(nullProto(), stringProto("def")),
652				listProto(nullProto(), intProto(67)),
653				listProto(nullProto(), intProto(68)),
654				listProto(nullProto(), boolProto(false)),
655				listProto(nullProto(), floatProto(0.93)),
656				listProto(bytesProto([]byte("foo")), nullProto()),
657				listProto(nullProto(), timeProto(t2)),
658				listProto(nullProto(), dateProto(d2))),
659			StructTypeProto,
660		},
661		{
662			"Null arrays of basic types.",
663			struct {
664				Stringf []NullString
665				Intf    []NullInt64
666				Int64f  []NullInt64
667				Boolf   []NullBool
668				Floatf  []NullFloat64
669				Bytef   [][]byte
670				Timef   []NullTime
671				Datef   []NullDate
672			}{
673				nil,
674				nil,
675				nil,
676				nil,
677				nil,
678				nil,
679				nil,
680				nil,
681			},
682			listProto(
683				nullProto(),
684				nullProto(),
685				nullProto(),
686				nullProto(),
687				nullProto(),
688				nullProto(),
689				nullProto(),
690				nullProto()),
691			StructTypeProto,
692		},
693	} {
694		encodeStructValue(test, t)
695	}
696}
697
698// Test decoding Values.
699func TestDecodeValue(t *testing.T) {
700	for i, test := range []struct {
701		in   *proto3.Value
702		t    *sppb.Type
703		want interface{}
704		fail bool
705	}{
706		// STRING
707		{stringProto("abc"), stringType(), "abc", false},
708		{nullProto(), stringType(), "abc", true},
709		{stringProto("abc"), stringType(), NullString{"abc", true}, false},
710		{nullProto(), stringType(), NullString{}, false},
711		// STRING ARRAY with []NullString
712		{
713			listProto(stringProto("abc"), nullProto(), stringProto("bcd")),
714			listType(stringType()),
715			[]NullString{{"abc", true}, {}, {"bcd", true}},
716			false,
717		},
718		{nullProto(), listType(stringType()), []NullString(nil), false},
719		// STRING ARRAY with []string
720		{
721			listProto(stringProto("abc"), stringProto("bcd")),
722			listType(stringType()),
723			[]string{"abc", "bcd"},
724			false,
725		},
726		// BYTES
727		{bytesProto([]byte("ab")), bytesType(), []byte("ab"), false},
728		{nullProto(), bytesType(), []byte(nil), false},
729		// BYTES ARRAY
730		{listProto(bytesProto([]byte("ab")), nullProto()), listType(bytesType()), [][]byte{[]byte("ab"), nil}, false},
731		{nullProto(), listType(bytesType()), [][]byte(nil), false},
732		//INT64
733		{intProto(15), intType(), int64(15), false},
734		{nullProto(), intType(), int64(0), true},
735		{intProto(15), intType(), NullInt64{15, true}, false},
736		{nullProto(), intType(), NullInt64{}, false},
737		// INT64 ARRAY with []NullInt64
738		{listProto(intProto(91), nullProto(), intProto(87)), listType(intType()), []NullInt64{{91, true}, {}, {87, true}}, false},
739		{nullProto(), listType(intType()), []NullInt64(nil), false},
740		// INT64 ARRAY with []int64
741		{listProto(intProto(91), intProto(87)), listType(intType()), []int64{91, 87}, false},
742		// BOOL
743		{boolProto(true), boolType(), true, false},
744		{nullProto(), boolType(), true, true},
745		{boolProto(true), boolType(), NullBool{true, true}, false},
746		{nullProto(), boolType(), NullBool{}, false},
747		// BOOL ARRAY with []NullBool
748		{listProto(boolProto(true), boolProto(false), nullProto()), listType(boolType()), []NullBool{{true, true}, {false, true}, {}}, false},
749		{nullProto(), listType(boolType()), []NullBool(nil), false},
750		// BOOL ARRAY with []bool
751		{listProto(boolProto(true), boolProto(false)), listType(boolType()), []bool{true, false}, false},
752		// FLOAT64
753		{floatProto(3.14), floatType(), 3.14, false},
754		{nullProto(), floatType(), 0.00, true},
755		{floatProto(3.14), floatType(), NullFloat64{3.14, true}, false},
756		{nullProto(), floatType(), NullFloat64{}, false},
757		// FLOAT64 ARRAY with []NullFloat64
758		{
759			listProto(floatProto(math.Inf(1)), floatProto(math.Inf(-1)), nullProto(), floatProto(3.1)),
760			listType(floatType()),
761			[]NullFloat64{{math.Inf(1), true}, {math.Inf(-1), true}, {}, {3.1, true}},
762			false,
763		},
764		{nullProto(), listType(floatType()), []NullFloat64(nil), false},
765		// FLOAT64 ARRAY with []float64
766		{
767			listProto(floatProto(math.Inf(1)), floatProto(math.Inf(-1)), floatProto(3.1)),
768			listType(floatType()),
769			[]float64{math.Inf(1), math.Inf(-1), 3.1},
770			false,
771		},
772		// TIMESTAMP
773		{timeProto(t1), timeType(), t1, false},
774		{timeProto(t1), timeType(), NullTime{t1, true}, false},
775		{nullProto(), timeType(), NullTime{}, false},
776		// TIMESTAMP ARRAY with []NullTime
777		{listProto(timeProto(t1), timeProto(t2), timeProto(t3), nullProto()), listType(timeType()), []NullTime{{t1, true}, {t2, true}, {t3, true}, {}}, false},
778		{nullProto(), listType(timeType()), []NullTime(nil), false},
779		// TIMESTAMP ARRAY with []time.Time
780		{listProto(timeProto(t1), timeProto(t2), timeProto(t3)), listType(timeType()), []time.Time{t1, t2, t3}, false},
781		// DATE
782		{dateProto(d1), dateType(), d1, false},
783		{dateProto(d1), dateType(), NullDate{d1, true}, false},
784		{nullProto(), dateType(), NullDate{}, false},
785		// DATE ARRAY with []NullDate
786		{listProto(dateProto(d1), dateProto(d2), nullProto()), listType(dateType()), []NullDate{{d1, true}, {d2, true}, {}}, false},
787		{nullProto(), listType(dateType()), []NullDate(nil), false},
788		// DATE ARRAY with []civil.Date
789		{listProto(dateProto(d1), dateProto(d2)), listType(dateType()), []civil.Date{d1, d2}, false},
790		// STRUCT ARRAY
791		// STRUCT schema is equal to the following Go struct:
792		// type s struct {
793		//     Col1 NullInt64
794		//     Col2 []struct {
795		//         SubCol1 float64
796		//         SubCol2 string
797		//     }
798		// }
799		{
800			in: listProto(
801				listProto(
802					intProto(3),
803					listProto(
804						listProto(floatProto(3.14), stringProto("this")),
805						listProto(floatProto(0.57), stringProto("siht")),
806					),
807				),
808				listProto(
809					nullProto(),
810					nullProto(),
811				),
812				nullProto(),
813			),
814			t: listType(
815				structType(
816					mkField("Col1", intType()),
817					mkField(
818						"Col2",
819						listType(
820							structType(
821								mkField("SubCol1", floatType()),
822								mkField("SubCol2", stringType()),
823							),
824						),
825					),
826				),
827			),
828			want: []NullRow{
829				{
830					Row: Row{
831						fields: []*sppb.StructType_Field{
832							mkField("Col1", intType()),
833							mkField(
834								"Col2",
835								listType(
836									structType(
837										mkField("SubCol1", floatType()),
838										mkField("SubCol2", stringType()),
839									),
840								),
841							),
842						},
843						vals: []*proto3.Value{
844							intProto(3),
845							listProto(
846								listProto(floatProto(3.14), stringProto("this")),
847								listProto(floatProto(0.57), stringProto("siht")),
848							),
849						},
850					},
851					Valid: true,
852				},
853				{
854					Row: Row{
855						fields: []*sppb.StructType_Field{
856							mkField("Col1", intType()),
857							mkField(
858								"Col2",
859								listType(
860									structType(
861										mkField("SubCol1", floatType()),
862										mkField("SubCol2", stringType()),
863									),
864								),
865							),
866						},
867						vals: []*proto3.Value{
868							nullProto(),
869							nullProto(),
870						},
871					},
872					Valid: true,
873				},
874				{},
875			},
876			fail: false,
877		},
878		{
879			in: listProto(
880				listProto(
881					intProto(3),
882					listProto(
883						listProto(floatProto(3.14), stringProto("this")),
884						listProto(floatProto(0.57), stringProto("siht")),
885					),
886				),
887				listProto(
888					nullProto(),
889					nullProto(),
890				),
891				nullProto(),
892			),
893			t: listType(
894				structType(
895					mkField("Col1", intType()),
896					mkField(
897						"Col2",
898						listType(
899							structType(
900								mkField("SubCol1", floatType()),
901								mkField("SubCol2", stringType()),
902							),
903						),
904					),
905				),
906			),
907			want: []*struct {
908				Col1      NullInt64
909				StructCol []*struct {
910					SubCol1 NullFloat64
911					SubCol2 string
912				} `spanner:"Col2"`
913			}{
914				{
915					Col1: NullInt64{3, true},
916					StructCol: []*struct {
917						SubCol1 NullFloat64
918						SubCol2 string
919					}{
920						{
921							SubCol1: NullFloat64{3.14, true},
922							SubCol2: "this",
923						},
924						{
925							SubCol1: NullFloat64{0.57, true},
926							SubCol2: "siht",
927						},
928					},
929				},
930				{
931					Col1: NullInt64{},
932					StructCol: []*struct {
933						SubCol1 NullFloat64
934						SubCol2 string
935					}(nil),
936				},
937				nil,
938			},
939			fail: false,
940		},
941		// GenericColumnValue
942		{stringProto("abc"), stringType(), GenericColumnValue{stringType(), stringProto("abc")}, false},
943		{nullProto(), stringType(), GenericColumnValue{stringType(), nullProto()}, false},
944		// not actually valid (stringProto inside int list), but demonstrates pass-through.
945		{
946			in: listProto(intProto(5), nullProto(), stringProto("bcd")),
947			t:  listType(intType()),
948			want: GenericColumnValue{
949				Type:  listType(intType()),
950				Value: listProto(intProto(5), nullProto(), stringProto("bcd")),
951			},
952			fail: false,
953		},
954	} {
955		gotp := reflect.New(reflect.TypeOf(test.want))
956		if err := decodeValue(test.in, test.t, gotp.Interface()); err != nil {
957			if !test.fail {
958				t.Errorf("%d: cannot decode %v(%v): %v", i, test.in, test.t, err)
959			}
960			continue
961		}
962		if test.fail {
963			t.Errorf("%d: decoding %v(%v) succeeds unexpectedly, want error", i, test.in, test.t)
964			continue
965		}
966		got := reflect.Indirect(gotp).Interface()
967		if !testEqual(got, test.want) {
968			t.Errorf("%d: unexpected decoding result - got %v, want %v", i, got, test.want)
969			continue
970		}
971	}
972}
973
974// Test error cases for decodeValue.
975func TestDecodeValueErrors(t *testing.T) {
976	var s string
977	for i, test := range []struct {
978		in *proto3.Value
979		t  *sppb.Type
980		v  interface{}
981	}{
982		{nullProto(), stringType(), nil},
983		{nullProto(), stringType(), 1},
984		{timeProto(t1), timeType(), &s},
985	} {
986		err := decodeValue(test.in, test.t, test.v)
987		if err == nil {
988			t.Errorf("#%d: want error, got nil", i)
989		}
990	}
991}
992
993// Test NaN encoding/decoding.
994func TestNaN(t *testing.T) {
995	// Decode NaN value.
996	f := 0.0
997	nf := NullFloat64{}
998	// To float64
999	if err := decodeValue(floatProto(math.NaN()), floatType(), &f); err != nil {
1000		t.Errorf("decodeValue returns %q for %v, want nil", err, floatProto(math.NaN()))
1001	}
1002	if !math.IsNaN(f) {
1003		t.Errorf("f = %v, want %v", f, math.NaN())
1004	}
1005	// To NullFloat64
1006	if err := decodeValue(floatProto(math.NaN()), floatType(), &nf); err != nil {
1007		t.Errorf("decodeValue returns %q for %v, want nil", err, floatProto(math.NaN()))
1008	}
1009	if !math.IsNaN(nf.Float64) || !nf.Valid {
1010		t.Errorf("f = %v, want %v", f, NullFloat64{math.NaN(), true})
1011	}
1012	// Encode NaN value
1013	// From float64
1014	v, _, err := encodeValue(math.NaN())
1015	if err != nil {
1016		t.Errorf("encodeValue returns %q for NaN, want nil", err)
1017	}
1018	x, ok := v.GetKind().(*proto3.Value_NumberValue)
1019	if !ok {
1020		t.Errorf("incorrect type for v.GetKind(): %T, want *proto3.Value_NumberValue", v.GetKind())
1021	}
1022	if !math.IsNaN(x.NumberValue) {
1023		t.Errorf("x.NumberValue = %v, want %v", x.NumberValue, math.NaN())
1024	}
1025	// From NullFloat64
1026	v, _, err = encodeValue(NullFloat64{math.NaN(), true})
1027	if err != nil {
1028		t.Errorf("encodeValue returns %q for NaN, want nil", err)
1029	}
1030	x, ok = v.GetKind().(*proto3.Value_NumberValue)
1031	if !ok {
1032		t.Errorf("incorrect type for v.GetKind(): %T, want *proto3.Value_NumberValue", v.GetKind())
1033	}
1034	if !math.IsNaN(x.NumberValue) {
1035		t.Errorf("x.NumberValue = %v, want %v", x.NumberValue, math.NaN())
1036	}
1037}
1038
1039func TestGenericColumnValue(t *testing.T) {
1040	for _, test := range []struct {
1041		in   GenericColumnValue
1042		want interface{}
1043		fail bool
1044	}{
1045		{GenericColumnValue{stringType(), stringProto("abc")}, "abc", false},
1046		{GenericColumnValue{stringType(), stringProto("abc")}, 5, true},
1047		{GenericColumnValue{listType(intType()), listProto(intProto(91), nullProto(), intProto(87))}, []NullInt64{{91, true}, {}, {87, true}}, false},
1048		{GenericColumnValue{intType(), intProto(42)}, GenericColumnValue{intType(), intProto(42)}, false}, // trippy! :-)
1049	} {
1050		gotp := reflect.New(reflect.TypeOf(test.want))
1051		if err := test.in.Decode(gotp.Interface()); err != nil {
1052			if !test.fail {
1053				t.Errorf("cannot decode %v to %v: %v", test.in, test.want, err)
1054			}
1055			continue
1056		}
1057		if test.fail {
1058			t.Errorf("decoding %v to %v succeeds unexpectedly", test.in, test.want)
1059		}
1060
1061		// Test we can go backwards as well.
1062		v, err := newGenericColumnValue(test.want)
1063		if err != nil {
1064			t.Errorf("NewGenericColumnValue failed: %v", err)
1065			continue
1066		}
1067		if !testEqual(*v, test.in) {
1068			t.Errorf("unexpected encode result - got %v, want %v", v, test.in)
1069		}
1070	}
1071}
1072
1073func TestDecodeStruct(t *testing.T) {
1074	stype := &sppb.StructType{Fields: []*sppb.StructType_Field{
1075		{Name: "Id", Type: stringType()},
1076		{Name: "Time", Type: timeType()},
1077	}}
1078	lv := listValueProto(stringProto("id"), timeProto(t1))
1079
1080	type (
1081		S1 struct {
1082			ID   string
1083			Time time.Time
1084		}
1085		S2 struct {
1086			ID   string
1087			Time string
1088		}
1089	)
1090	var (
1091		s1 S1
1092		s2 S2
1093	)
1094
1095	for i, test := range []struct {
1096		ptr  interface{}
1097		want interface{}
1098		fail bool
1099	}{
1100		{
1101			ptr:  &s1,
1102			want: &S1{ID: "id", Time: t1},
1103		},
1104		{
1105			ptr:  &s2,
1106			fail: true,
1107		},
1108	} {
1109		err := decodeStruct(stype, lv, test.ptr)
1110		if (err != nil) != test.fail {
1111			t.Errorf("#%d: got error %v, wanted fail: %v", i, err, test.fail)
1112		}
1113		if err == nil && !testEqual(test.ptr, test.want) {
1114			t.Errorf("#%d: got %+v, want %+v", i, test.ptr, test.want)
1115		}
1116	}
1117}
1118
1119func TestEncodeStructValueDynamicStructs(t *testing.T) {
1120	dynStructType := reflect.StructOf([]reflect.StructField{
1121		{Name: "A", Type: reflect.TypeOf(0), Tag: `spanner:"a"`},
1122		{Name: "B", Type: reflect.TypeOf(""), Tag: `spanner:"b"`},
1123	})
1124	dynNullableStructType := reflect.PtrTo(dynStructType)
1125	dynStructArrType := reflect.SliceOf(dynStructType)
1126	dynNullableStructArrType := reflect.SliceOf(dynNullableStructType)
1127
1128	dynStructValue := reflect.New(dynStructType)
1129	dynStructValue.Elem().Field(0).SetInt(10)
1130	dynStructValue.Elem().Field(1).SetString("abc")
1131
1132	dynStructArrValue := reflect.MakeSlice(dynNullableStructArrType, 2, 2)
1133	dynStructArrValue.Index(0).Set(reflect.Zero(dynNullableStructType))
1134	dynStructArrValue.Index(1).Set(dynStructValue)
1135
1136	structProtoType := structType(
1137		mkField("a", intType()),
1138		mkField("b", stringType()))
1139
1140	arrProtoType := listType(structProtoType)
1141
1142	for _, test := range []encodeTest{
1143		{
1144			"Dynanic non-NULL struct value.",
1145			dynStructValue.Elem().Interface(),
1146			listProto(intProto(10), stringProto("abc")),
1147			structProtoType,
1148		},
1149		{
1150			"Dynanic NULL struct value.",
1151			reflect.Zero(dynNullableStructType).Interface(),
1152			nullProto(),
1153			structProtoType,
1154		},
1155		{
1156			"Empty array of dynamic structs.",
1157			reflect.MakeSlice(dynStructArrType, 0, 0).Interface(),
1158			listProto([]*proto3.Value{}...),
1159			arrProtoType,
1160		},
1161		{
1162			"NULL array of non-NULL-able dynamic structs.",
1163			reflect.Zero(dynStructArrType).Interface(),
1164			nullProto(),
1165			arrProtoType,
1166		},
1167		{
1168			"NULL array of NULL-able(nil) dynamic structs.",
1169			reflect.Zero(dynNullableStructArrType).Interface(),
1170			nullProto(),
1171			arrProtoType,
1172		},
1173		{
1174			"Array containing NULL(nil) dynamic-typed struct elements.",
1175			dynStructArrValue.Interface(),
1176			listProto(
1177				nullProto(),
1178				listProto(intProto(10), stringProto("abc"))),
1179			arrProtoType,
1180		},
1181	} {
1182		encodeStructValue(test, t)
1183	}
1184}
1185
1186func TestEncodeStructValueEmptyStruct(t *testing.T) {
1187	emptyListValue := listProto([]*proto3.Value{}...)
1188	emptyStructType := structType([]*sppb.StructType_Field{}...)
1189	emptyStruct := struct{}{}
1190	nullEmptyStruct := (*struct{})(nil)
1191
1192	dynamicEmptyStructType := reflect.StructOf(make([]reflect.StructField, 0, 0))
1193	dynamicStructArrType := reflect.SliceOf(reflect.PtrTo((dynamicEmptyStructType)))
1194
1195	dynamicEmptyStruct := reflect.New(dynamicEmptyStructType)
1196	dynamicNullEmptyStruct := reflect.Zero(reflect.PtrTo(dynamicEmptyStructType))
1197
1198	dynamicStructArrValue := reflect.MakeSlice(dynamicStructArrType, 2, 2)
1199	dynamicStructArrValue.Index(0).Set(dynamicNullEmptyStruct)
1200	dynamicStructArrValue.Index(1).Set(dynamicEmptyStruct)
1201
1202	for _, test := range []encodeTest{
1203		{
1204			"Go empty struct.",
1205			emptyStruct,
1206			emptyListValue,
1207			emptyStructType,
1208		},
1209		{
1210			"Dynamic empty struct.",
1211			dynamicEmptyStruct.Interface(),
1212			emptyListValue,
1213			emptyStructType,
1214		},
1215		{
1216			"Go NULL empty struct.",
1217			nullEmptyStruct,
1218			nullProto(),
1219			emptyStructType,
1220		},
1221		{
1222			"Dynamic NULL empty struct.",
1223			dynamicNullEmptyStruct.Interface(),
1224			nullProto(),
1225			emptyStructType,
1226		},
1227		{
1228			"Non-empty array of dynamic NULL and non-NULL empty structs.",
1229			dynamicStructArrValue.Interface(),
1230			listProto(nullProto(), emptyListValue),
1231			listType(emptyStructType),
1232		},
1233		{
1234			"Non-empty array of nullable empty structs.",
1235			[]*struct{}{nullEmptyStruct, &emptyStruct},
1236			listProto(nullProto(), emptyListValue),
1237			listType(emptyStructType),
1238		},
1239		{
1240			"Empty array of empty struct.",
1241			[]struct{}{},
1242			emptyListValue,
1243			listType(emptyStructType),
1244		},
1245		{
1246			"Null array of empty structs.",
1247			[]struct{}(nil),
1248			nullProto(),
1249			listType(emptyStructType),
1250		},
1251	} {
1252		encodeStructValue(test, t)
1253	}
1254}
1255
1256func TestEncodeStructValueMixedStructTypes(t *testing.T) {
1257	type staticStruct struct {
1258		F int `spanner:"fStatic"`
1259	}
1260	s1 := staticStruct{10}
1261	s2 := (*staticStruct)(nil)
1262
1263	var f float64
1264	dynStructType := reflect.StructOf([]reflect.StructField{
1265		{Name: "A", Type: reflect.TypeOf(f), Tag: `spanner:"fDynamic"`},
1266	})
1267	s3 := reflect.New(dynStructType)
1268	s3.Elem().Field(0).SetFloat(3.14)
1269
1270	for _, test := range []encodeTest{
1271		{
1272			"'struct' with static and dynamic *struct, []*struct, []struct fields",
1273			struct {
1274				A []staticStruct
1275				B []*staticStruct
1276				C interface{}
1277			}{
1278				[]staticStruct{s1, s1},
1279				[]*staticStruct{&s1, s2},
1280				s3.Interface(),
1281			},
1282			listProto(
1283				listProto(listProto(intProto(10)), listProto(intProto(10))),
1284				listProto(listProto(intProto(10)), nullProto()),
1285				listProto(floatProto(3.14))),
1286			structType(
1287				mkField("A", listType(structType(mkField("fStatic", intType())))),
1288				mkField("B", listType(structType(mkField("fStatic", intType())))),
1289				mkField("C", structType(mkField("fDynamic", floatType())))),
1290		},
1291	} {
1292		encodeStructValue(test, t)
1293	}
1294}
1295
1296func TestBindParamsDynamic(t *testing.T) {
1297	// Verify Statement.bindParams generates correct values and types.
1298	st := Statement{
1299		SQL:    "SELECT id from t_foo WHERE col = @var",
1300		Params: map[string]interface{}{"var": nil},
1301	}
1302	want := &sppb.ExecuteSqlRequest{
1303		Params: &proto3.Struct{
1304			Fields: map[string]*proto3.Value{"var": nil},
1305		},
1306		ParamTypes: map[string]*sppb.Type{"var": nil},
1307	}
1308	var (
1309		t1, _ = time.Parse(time.RFC3339Nano, "2016-11-15T15:04:05.999999999Z")
1310		// Boundaries
1311		t2, _ = time.Parse(time.RFC3339Nano, "0001-01-01T00:00:00.000000000Z")
1312	)
1313	dynamicStructType := reflect.StructOf([]reflect.StructField{
1314		{Name: "A", Type: reflect.TypeOf(t1), Tag: `spanner:"field"`},
1315		{Name: "B", Type: reflect.TypeOf(3.14), Tag: `spanner:""`},
1316	})
1317	dynamicStructArrType := reflect.SliceOf(reflect.PtrTo(dynamicStructType))
1318	dynamicEmptyStructType := reflect.StructOf(make([]reflect.StructField, 0, 0))
1319
1320	dynamicStructTypeProto := structType(
1321		mkField("field", timeType()),
1322		mkField("", floatType()))
1323
1324	s3 := reflect.New(dynamicStructType)
1325	s3.Elem().Field(0).Set(reflect.ValueOf(t1))
1326	s3.Elem().Field(1).SetFloat(1.4)
1327
1328	s4 := reflect.New(dynamicStructType)
1329	s4.Elem().Field(0).Set(reflect.ValueOf(t2))
1330	s4.Elem().Field(1).SetFloat(-13.3)
1331
1332	dynamicStructArrayVal := reflect.MakeSlice(dynamicStructArrType, 2, 2)
1333	dynamicStructArrayVal.Index(0).Set(s3)
1334	dynamicStructArrayVal.Index(1).Set(s4)
1335
1336	for _, test := range []struct {
1337		val       interface{}
1338		wantField *proto3.Value
1339		wantType  *sppb.Type
1340	}{
1341		{
1342			s3.Interface(),
1343			listProto(timeProto(t1), floatProto(1.4)),
1344			structType(
1345				mkField("field", timeType()),
1346				mkField("", floatType())),
1347		},
1348		{
1349			reflect.Zero(reflect.PtrTo(dynamicEmptyStructType)).Interface(),
1350			nullProto(),
1351			structType([]*sppb.StructType_Field{}...),
1352		},
1353		{
1354			dynamicStructArrayVal.Interface(),
1355			listProto(
1356				listProto(timeProto(t1), floatProto(1.4)),
1357				listProto(timeProto(t2), floatProto(-13.3))),
1358			listType(dynamicStructTypeProto),
1359		},
1360		{
1361			[]*struct {
1362				F1 time.Time `spanner:"field"`
1363				F2 float64   `spanner:""`
1364			}{
1365				nil,
1366				{t1, 1.4},
1367			},
1368			listProto(
1369				nullProto(),
1370				listProto(timeProto(t1), floatProto(1.4))),
1371			listType(dynamicStructTypeProto),
1372		},
1373	} {
1374		st.Params["var"] = test.val
1375		want.Params.Fields["var"] = test.wantField
1376		want.ParamTypes["var"] = test.wantType
1377		gotParams, gotParamTypes, gotErr := st.convertParams()
1378		if gotErr != nil {
1379			t.Error(gotErr)
1380			continue
1381		}
1382		gotParamField := gotParams.Fields["var"]
1383		if !proto.Equal(gotParamField, test.wantField) {
1384			// handle NaN
1385			if test.wantType.Code == floatType().Code && proto.MarshalTextString(gotParamField) == proto.MarshalTextString(test.wantField) {
1386				continue
1387			}
1388			t.Errorf("%#v: got %v, want %v\n", test.val, gotParamField, test.wantField)
1389		}
1390		gotParamType := gotParamTypes["var"]
1391		if !proto.Equal(gotParamType, test.wantType) {
1392			t.Errorf("%#v: got %v, want %v\n", test.val, gotParamType, test.wantField)
1393		}
1394	}
1395}
1396