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/json"
21	"fmt"
22	"math"
23	"math/big"
24	"reflect"
25	"testing"
26	"time"
27
28	"cloud.google.com/go/civil"
29	"cloud.google.com/go/internal/testutil"
30	"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	t1 = mustParseTime("2016-11-15T15:04:05.999999999Z")
38	// Boundaries
39	t2 = mustParseTime("0001-01-01T00:00:00.000000000Z")
40	t3 = mustParseTime("9999-12-31T23:59:59.999999999Z")
41	// Local timezone
42	t4 = time.Now()
43	d1 = mustParseDate("2016-11-15")
44	d2 = mustParseDate("1678-01-01")
45)
46
47func mustParseTime(s string) time.Time {
48	t, err := time.Parse(time.RFC3339Nano, s)
49	if err != nil {
50		panic(err)
51	}
52	return t
53}
54
55func mustParseDate(s string) civil.Date {
56	d, err := civil.ParseDate(s)
57	if err != nil {
58		panic(err)
59	}
60	return d
61}
62
63type customStructToString struct {
64	A string
65	B string
66}
67
68// Convert the customStructToString
69func (c customStructToString) EncodeSpanner() (interface{}, error) {
70	return "A-B", nil
71}
72
73// Convert to customStructToString
74func (c *customStructToString) DecodeSpanner(val interface{}) (err error) {
75	c.A = "A"
76	c.B = "B"
77	return nil
78}
79
80type customStructToInt struct {
81	A int64
82	B int64
83}
84
85// Convert the customStructToInt
86func (c customStructToInt) EncodeSpanner() (interface{}, error) {
87	return 123, nil
88}
89
90// Convert to customStructToInt
91func (c *customStructToInt) DecodeSpanner(val interface{}) (err error) {
92	c.A = 1
93	c.B = 23
94	return nil
95}
96
97type customStructToFloat struct {
98	A float64
99	B float64
100}
101
102// Convert the customStructToFloat
103func (c customStructToFloat) EncodeSpanner() (interface{}, error) {
104	return 123.123, nil
105}
106
107// Convert to customStructToFloat
108func (c *customStructToFloat) DecodeSpanner(val interface{}) (err error) {
109	c.A = 1.23
110	c.B = 12.3
111	return nil
112}
113
114type customStructToBool struct {
115	A bool
116	B bool
117}
118
119// Convert the customStructToBool
120func (c customStructToBool) EncodeSpanner() (interface{}, error) {
121	return true, nil
122}
123
124// Convert to customStructToBool
125func (c *customStructToBool) DecodeSpanner(val interface{}) (err error) {
126	c.A = true
127	c.B = false
128	return nil
129}
130
131type customStructToBytes struct {
132	A []byte
133	B []byte
134}
135
136// Convert the customStructToBytes
137func (c customStructToBytes) EncodeSpanner() (interface{}, error) {
138	return []byte("AB"), nil
139}
140
141// Convert to customStructToBytes
142func (c *customStructToBytes) DecodeSpanner(val interface{}) (err error) {
143	c.A = []byte("A")
144	c.B = []byte("B")
145	return nil
146}
147
148type customStructToTime struct {
149	A string
150	B string
151}
152
153// Convert the customStructToTime
154func (c customStructToTime) EncodeSpanner() (interface{}, error) {
155	return t1, nil
156}
157
158// Convert to customStructToTime
159func (c *customStructToTime) DecodeSpanner(val interface{}) (err error) {
160	c.A = "A"
161	c.B = "B"
162	return nil
163}
164
165type customStructToDate struct {
166	A string
167	B string
168}
169
170// Convert the customStructToDate
171func (c customStructToDate) EncodeSpanner() (interface{}, error) {
172	return d1, nil
173}
174
175// Convert to customStructToDate
176func (c *customStructToDate) DecodeSpanner(val interface{}) (err error) {
177	c.A = "A"
178	c.B = "B"
179	return nil
180}
181
182// Test encoding Values.
183func TestEncodeValue(t *testing.T) {
184	type CustomString string
185	type CustomBytes []byte
186	type CustomInt64 int64
187	type CustomBool bool
188	type CustomFloat64 float64
189	type CustomTime time.Time
190	type CustomDate civil.Date
191	type CustomNumeric big.Rat
192
193	type CustomNullString NullString
194	type CustomNullInt64 NullInt64
195	type CustomNullBool NullBool
196	type CustomNullFloat64 NullFloat64
197	type CustomNullTime NullTime
198	type CustomNullDate NullDate
199	type CustomNullNumeric NullNumeric
200
201	sValue := "abc"
202	var sNilPtr *string
203	iValue := int64(7)
204	var iNilPtr *int64
205	bValue := true
206	var bNilPtr *bool
207	fValue := 3.14
208	var fNilPtr *float64
209	tValue := t1
210	var tNilPtr *time.Time
211	dValue := d1
212	var dNilPtr *civil.Date
213	numValuePtr := big.NewRat(12345, 1e3)
214	var numNilPtr *big.Rat
215	num2ValuePtr := big.NewRat(12345, 1e4)
216
217	var (
218		tString  = stringType()
219		tInt     = intType()
220		tBool    = boolType()
221		tFloat   = floatType()
222		tBytes   = bytesType()
223		tTime    = timeType()
224		tDate    = dateType()
225		tNumeric = numericType()
226	)
227	for i, test := range []struct {
228		in       interface{}
229		want     *proto3.Value
230		wantType *sppb.Type
231		name     string
232	}{
233		// STRING / STRING ARRAY:
234		{"abc", stringProto("abc"), tString, "string"},
235		{NullString{"abc", true}, stringProto("abc"), tString, "NullString with value"},
236		{NullString{"abc", false}, nullProto(), tString, "NullString with null"},
237		{&sValue, stringProto("abc"), tString, "*string with value"},
238		{sNilPtr, nullProto(), tString, "*string with null"},
239		{[]string(nil), nullProto(), listType(tString), "null []string"},
240		{[]string{"abc", "bcd"}, listProto(stringProto("abc"), stringProto("bcd")), listType(tString), "[]string"},
241		{[]NullString{{"abcd", true}, {"xyz", false}}, listProto(stringProto("abcd"), nullProto()), listType(tString), "[]NullString"},
242		{[]*string{&sValue, sNilPtr}, listProto(stringProto("abc"), nullProto()), listType(tString), "[]*string"},
243		// BYTES / BYTES ARRAY
244		{[]byte("foo"), bytesProto([]byte("foo")), tBytes, "[]byte with value"},
245		{[]byte(nil), nullProto(), tBytes, "null []byte"},
246		{[][]byte{nil, []byte("ab")}, listProto(nullProto(), bytesProto([]byte("ab"))), listType(tBytes), "[][]byte"},
247		{[][]byte(nil), nullProto(), listType(tBytes), "null [][]byte"},
248		// INT64 / INT64 ARRAY
249		{7, intProto(7), tInt, "int"},
250		{[]int(nil), nullProto(), listType(tInt), "null []int"},
251		{[]int{31, 127}, listProto(intProto(31), intProto(127)), listType(tInt), "[]int"},
252		{int64(81), intProto(81), tInt, "int64"},
253		{[]int64(nil), nullProto(), listType(tInt), "null []int64"},
254		{[]int64{33, 129}, listProto(intProto(33), intProto(129)), listType(tInt), "[]int64"},
255		{NullInt64{11, true}, intProto(11), tInt, "NullInt64 with value"},
256		{NullInt64{11, false}, nullProto(), tInt, "NullInt64 with null"},
257		{&iValue, intProto(7), tInt, "*int64 with value"},
258		{iNilPtr, nullProto(), tInt, "*int64 with null"},
259		{[]NullInt64{{35, true}, {131, false}}, listProto(intProto(35), nullProto()), listType(tInt), "[]NullInt64"},
260		{[]*int64{&iValue, iNilPtr}, listProto(intProto(7), nullProto()), listType(tInt), "[]*int64"},
261		// BOOL / BOOL ARRAY
262		{true, boolProto(true), tBool, "bool"},
263		{NullBool{true, true}, boolProto(true), tBool, "NullBool with value"},
264		{NullBool{true, false}, nullProto(), tBool, "NullBool with null"},
265		{&bValue, boolProto(true), tBool, "*bool with value"},
266		{bNilPtr, nullProto(), tBool, "*bool with null"},
267		{[]bool{true, false}, listProto(boolProto(true), boolProto(false)), listType(tBool), "[]bool"},
268		{[]NullBool{{true, true}, {true, false}}, listProto(boolProto(true), nullProto()), listType(tBool), "[]NullBool"},
269		{[]*bool{&bValue, bNilPtr}, listProto(boolProto(true), nullProto()), listType(tBool), "[]*bool"},
270		// FLOAT64 / FLOAT64 ARRAY
271		{3.14, floatProto(3.14), tFloat, "float"},
272		{NullFloat64{3.1415, true}, floatProto(3.1415), tFloat, "NullFloat64 with value"},
273		{NullFloat64{math.Inf(1), true}, floatProto(math.Inf(1)), tFloat, "NullFloat64 with infinity"},
274		{NullFloat64{3.14159, false}, nullProto(), tFloat, "NullFloat64 with null"},
275		{&fValue, floatProto(3.14), tFloat, "*float64 with value"},
276		{fNilPtr, nullProto(), tFloat, "*float64 with null"},
277		{[]float64(nil), nullProto(), listType(tFloat), "null []float64"},
278		{[]float64{3.141, 0.618, math.Inf(-1)}, listProto(floatProto(3.141), floatProto(0.618), floatProto(math.Inf(-1))), listType(tFloat), "[]float64"},
279		{[]NullFloat64{{3.141, true}, {0.618, false}}, listProto(floatProto(3.141), nullProto()), listType(tFloat), "[]NullFloat64"},
280		{[]*float64{&fValue, fNilPtr}, listProto(floatProto(3.14), nullProto()), listType(tFloat), "[]NullFloat64"},
281		// NUMERIC / NUMERIC ARRAY
282		{*numValuePtr, numericProto(numValuePtr), tNumeric, "big.Rat"},
283		{numValuePtr, numericProto(numValuePtr), tNumeric, "*big.Rat"},
284		{numNilPtr, nullProto(), tNumeric, "*big.Rat with null"},
285		{NullNumeric{*numValuePtr, true}, numericProto(numValuePtr), tNumeric, "NullNumeric with value"},
286		{NullNumeric{*numValuePtr, false}, nullProto(), tNumeric, "NullNumeric with null"},
287		{[]big.Rat(nil), nullProto(), listType(tNumeric), "null []big.Rat"},
288		{[]big.Rat{*numValuePtr, *num2ValuePtr}, listProto(numericProto(numValuePtr), numericProto(num2ValuePtr)), listType(tNumeric), "[]big.Rat"},
289		{[]NullNumeric{{*numValuePtr, true}, {*numValuePtr, false}}, listProto(numericProto(numValuePtr), nullProto()), listType(tNumeric), "[]NullNumeric"},
290		{[]*big.Rat{nil, numValuePtr}, listProto(nullProto(), numericProto(numValuePtr)), listType(tNumeric), "[]*big.Rat"},
291		{[]*big.Rat(nil), nullProto(), listType(tNumeric), "null []*big.Rat"},
292		// TIMESTAMP / TIMESTAMP ARRAY
293		{t1, timeProto(t1), tTime, "time"},
294		{NullTime{t1, true}, timeProto(t1), tTime, "NullTime with value"},
295		{NullTime{t1, false}, nullProto(), tTime, "NullTime with null"},
296		{&tValue, timeProto(t1), tTime, "*time.Time with value"},
297		{tNilPtr, nullProto(), tTime, "*time.Time with null"},
298		{[]time.Time(nil), nullProto(), listType(tTime), "null []time"},
299		{[]time.Time{t1, t2, t3, t4}, listProto(timeProto(t1), timeProto(t2), timeProto(t3), timeProto(t4)), listType(tTime), "[]time"},
300		{[]NullTime{{t1, true}, {t1, false}}, listProto(timeProto(t1), nullProto()), listType(tTime), "[]NullTime"},
301		{[]*time.Time{&tValue, tNilPtr}, listProto(timeProto(t1), nullProto()), listType(tTime), "[]*time.Time"},
302		// DATE / DATE ARRAY
303		{d1, dateProto(d1), tDate, "date"},
304		{NullDate{d1, true}, dateProto(d1), tDate, "NullDate with value"},
305		{NullDate{civil.Date{}, false}, nullProto(), tDate, "NullDate with null"},
306		{&dValue, dateProto(d1), tDate, "*civil.Date with value"},
307		{dNilPtr, nullProto(), tDate, "*civil.Date with null"},
308		{[]civil.Date(nil), nullProto(), listType(tDate), "null []date"},
309		{[]civil.Date{d1, d2}, listProto(dateProto(d1), dateProto(d2)), listType(tDate), "[]date"},
310		{[]NullDate{{d1, true}, {civil.Date{}, false}}, listProto(dateProto(d1), nullProto()), listType(tDate), "[]NullDate"},
311		{[]*civil.Date{&dValue, dNilPtr}, listProto(dateProto(d1), nullProto()), listType(tDate), "[]*civil.Date"},
312		// GenericColumnValue
313		{GenericColumnValue{tString, stringProto("abc")}, stringProto("abc"), tString, "GenericColumnValue with value"},
314		{GenericColumnValue{tString, nullProto()}, nullProto(), tString, "GenericColumnValue with null"},
315		// not actually valid (stringProto inside int list), but demonstrates pass-through.
316		{
317			GenericColumnValue{
318				Type:  listType(tInt),
319				Value: listProto(intProto(5), nullProto(), stringProto("bcd")),
320			},
321			listProto(intProto(5), nullProto(), stringProto("bcd")),
322			listType(tInt),
323			"pass-through",
324		},
325		// placeholder
326		{CommitTimestamp, stringProto(commitTimestampPlaceholderString), tTime, "CommitTimestampPlaceholder"},
327		// CUSTOM STRING / CUSTOM STRING ARRAY
328		{CustomString("abc"), stringProto("abc"), tString, "CustomString"},
329		{CustomNullString{"abc", true}, stringProto("abc"), tString, "CustomNullString with value"},
330		{CustomNullString{"abc", false}, nullProto(), tString, "CustomNullString with null"},
331		{[]CustomString(nil), nullProto(), listType(tString), "null []CustomString"},
332		{[]CustomString{"abc", "bcd"}, listProto(stringProto("abc"), stringProto("bcd")), listType(tString), "[]CustomString"},
333		{[]CustomNullString(nil), nullProto(), listType(tString), "null []NullCustomString"},
334		{[]CustomNullString{{"abcd", true}, {"xyz", false}}, listProto(stringProto("abcd"), nullProto()), listType(tString), "[]NullCustomString"},
335		// CUSTOM BYTES / CUSTOM BYTES ARRAY
336		{CustomBytes("foo"), bytesProto([]byte("foo")), tBytes, "CustomBytes with value"},
337		{CustomBytes(nil), nullProto(), tBytes, "null CustomBytes"},
338		{[]CustomBytes{nil, CustomBytes("ab")}, listProto(nullProto(), bytesProto([]byte("ab"))), listType(tBytes), "[]CustomBytes"},
339		{[]CustomBytes(nil), nullProto(), listType(tBytes), "null []CustomBytes"},
340		// CUSTOM INT64 / CUSTOM INT64 ARRAY
341		{CustomInt64(81), intProto(81), tInt, "CustomInt64"},
342		{[]CustomInt64(nil), nullProto(), listType(tInt), "null []CustomInt64"},
343		{[]CustomInt64{33, 129}, listProto(intProto(33), intProto(129)), listType(tInt), "[]CustomInt64"},
344		{CustomNullInt64{11, true}, intProto(11), tInt, "CustomNullInt64 with value"},
345		{CustomNullInt64{11, false}, nullProto(), tInt, "CustomNullInt64 with null"},
346		{[]CustomNullInt64(nil), nullProto(), listType(tInt), "null []CustomNullInt64"},
347		{[]CustomNullInt64{{35, true}, {131, false}}, listProto(intProto(35), nullProto()), listType(tInt), "[]CustomNullInt64"},
348		// CUSTOM BOOL / CUSTOM BOOL ARRAY
349		{CustomBool(true), boolProto(true), tBool, "CustomBool"},
350		{CustomNullBool{true, true}, boolProto(true), tBool, "CustomNullBool with value"},
351		{CustomNullBool{true, false}, nullProto(), tBool, "CustomNullBool with null"},
352		{[]CustomBool{true, false}, listProto(boolProto(true), boolProto(false)), listType(tBool), "[]CustomBool"},
353		{[]CustomNullBool{{true, true}, {true, false}}, listProto(boolProto(true), nullProto()), listType(tBool), "[]CustomNullBool"},
354		// FLOAT64 / FLOAT64 ARRAY
355		{CustomFloat64(3.14), floatProto(3.14), tFloat, "CustomFloat64"},
356		{CustomNullFloat64{3.1415, true}, floatProto(3.1415), tFloat, "CustomNullFloat64 with value"},
357		{CustomNullFloat64{math.Inf(1), true}, floatProto(math.Inf(1)), tFloat, "CustomNullFloat64 with infinity"},
358		{CustomNullFloat64{3.14159, false}, nullProto(), tFloat, "CustomNullFloat64 with null"},
359		{[]CustomFloat64(nil), nullProto(), listType(tFloat), "null []CustomFloat64"},
360		{[]CustomFloat64{3.141, 0.618, CustomFloat64(math.Inf(-1))}, listProto(floatProto(3.141), floatProto(0.618), floatProto(math.Inf(-1))), listType(tFloat), "[]CustomFloat64"},
361		{[]CustomNullFloat64(nil), nullProto(), listType(tFloat), "null []CustomNullFloat64"},
362		{[]CustomNullFloat64{{3.141, true}, {0.618, false}}, listProto(floatProto(3.141), nullProto()), listType(tFloat), "[]CustomNullFloat64"},
363		// CUSTOM TIMESTAMP / CUSTOM TIMESTAMP ARRAY
364		{CustomTime(t1), timeProto(t1), tTime, "CustomTime"},
365		{CustomNullTime{t1, true}, timeProto(t1), tTime, "CustomNullTime with value"},
366		{CustomNullTime{t1, false}, nullProto(), tTime, "CustomNullTime with null"},
367		{[]CustomTime(nil), nullProto(), listType(tTime), "null []CustomTime"},
368		{[]CustomTime{CustomTime(t1), CustomTime(t2), CustomTime(t3), CustomTime(t4)}, listProto(timeProto(t1), timeProto(t2), timeProto(t3), timeProto(t4)), listType(tTime), "[]CustomTime"},
369		{[]CustomNullTime(nil), nullProto(), listType(tTime), "null []CustomNullTime"},
370		{[]CustomNullTime{{t1, true}, {t1, false}}, listProto(timeProto(t1), nullProto()), listType(tTime), "[]CustomNullTime"},
371		// CUSTOM DATE / CUSTOM DATE ARRAY
372		{CustomDate(d1), dateProto(d1), tDate, "CustomDate"},
373		{CustomNullDate{d1, true}, dateProto(d1), tDate, "CustomNullDate with value"},
374		{CustomNullDate{civil.Date{}, false}, nullProto(), tDate, "CustomNullDate with null"},
375		{[]CustomDate(nil), nullProto(), listType(tDate), "null []CustomDate"},
376		{[]CustomDate{CustomDate(d1), CustomDate(d2)}, listProto(dateProto(d1), dateProto(d2)), listType(tDate), "[]CustomDate"},
377		{[]CustomNullDate(nil), nullProto(), listType(tDate), "null []CustomNullDate"},
378		{[]CustomNullDate{{d1, true}, {civil.Date{}, false}}, listProto(dateProto(d1), nullProto()), listType(tDate), "[]NullDate"},
379		// CUSTOM STRUCT
380		{customStructToString{"A", "B"}, stringProto("A-B"), tString, "a struct to string"},
381		{customStructToInt{1, 23}, intProto(123), tInt, "a struct to int"},
382		{customStructToFloat{1.23, 12.3}, floatProto(123.123), tFloat, "a struct to float"},
383		{customStructToBool{true, false}, boolProto(true), tBool, "a struct to bool"},
384		{customStructToBytes{[]byte("A"), []byte("B")}, bytesProto([]byte("AB")), tBytes, "a struct to bytes"},
385		{customStructToTime{"A", "B"}, timeProto(tValue), tTime, "a struct to time"},
386		{customStructToDate{"A", "B"}, dateProto(dValue), tDate, "a struct to date"},
387		// CUSTOM NUMERIC / CUSTOM NUMERIC ARRAY
388		{CustomNumeric(*numValuePtr), numericProto(numValuePtr), tNumeric, "CustomNumeric"},
389		{CustomNullNumeric{*numValuePtr, true}, numericProto(numValuePtr), tNumeric, "CustomNullNumeric with value"},
390		{CustomNullNumeric{*numValuePtr, false}, nullProto(), tNumeric, "CustomNullNumeric with null"},
391		{[]CustomNumeric(nil), nullProto(), listType(tNumeric), "null []CustomNumeric"},
392		{[]CustomNumeric{CustomNumeric(*numValuePtr), CustomNumeric(*num2ValuePtr)}, listProto(numericProto(numValuePtr), numericProto(num2ValuePtr)), listType(tNumeric), "[]CustomNumeric"},
393		{[]CustomNullNumeric(nil), nullProto(), listType(tNumeric), "null []CustomNullNumeric"},
394		{[]CustomNullNumeric{{*numValuePtr, true}, {*num2ValuePtr, false}}, listProto(numericProto(numValuePtr), nullProto()), listType(tNumeric), "[]CustomNullNumeric"},
395	} {
396		got, gotType, err := encodeValue(test.in)
397		if err != nil {
398			t.Fatalf("#%d (%s): got error during encoding: %v, want nil", i, test.name, err)
399		}
400		if !testEqual(got, test.want) {
401			t.Errorf("#%d (%s): got encode result: %v, want %v", i, test.name, got, test.want)
402		}
403		if !testEqual(gotType, test.wantType) {
404			t.Errorf("#%d (%s): got encode type: %v, want %v", i, test.name, gotType, test.wantType)
405		}
406	}
407}
408
409type encodeTest struct {
410	desc     string
411	in       interface{}
412	want     *proto3.Value
413	wantType *sppb.Type
414}
415
416func checkStructEncoding(desc string, got *proto3.Value, gotType *sppb.Type,
417	want *proto3.Value, wantType *sppb.Type, t *testing.T) {
418	if !testEqual(got, want) {
419		t.Errorf("Test %s: got encode result: %v, want %v", desc, got, want)
420	}
421	if !testEqual(gotType, wantType) {
422		t.Errorf("Test %s: got encode type: %v, want %v", desc, gotType, wantType)
423	}
424}
425
426// Testcase code
427func encodeStructValue(test encodeTest, t *testing.T) {
428	got, gotType, err := encodeValue(test.in)
429	if err != nil {
430		t.Fatalf("Test %s: got error during encoding: %v, want nil", test.desc, err)
431	}
432	checkStructEncoding(test.desc, got, gotType, test.want, test.wantType, t)
433}
434
435func TestEncodeStructValuePointers(t *testing.T) {
436	type structf struct {
437		F int `spanner:"ff2"`
438	}
439	nestedStructProto := structType(mkField("ff2", intType()))
440
441	type testType struct {
442		Stringf    string
443		Structf    *structf
444		ArrStructf []*structf
445	}
446	testTypeProto := structType(
447		mkField("Stringf", stringType()),
448		mkField("Structf", nestedStructProto),
449		mkField("ArrStructf", listType(nestedStructProto)))
450
451	for _, test := range []encodeTest{
452		{
453			"Pointer to Go struct with pointers-to-(array)-struct fields.",
454			&testType{"hello", &structf{50}, []*structf{{30}, {40}}},
455			listProto(
456				stringProto("hello"),
457				listProto(intProto(50)),
458				listProto(
459					listProto(intProto(30)),
460					listProto(intProto(40)))),
461			testTypeProto,
462		},
463		{
464			"Nil pointer to Go struct representing a NULL struct value.",
465			(*testType)(nil),
466			nullProto(),
467			testTypeProto,
468		},
469		{
470			"Slice of pointers to Go structs with NULL and non-NULL elements.",
471			[]*testType{
472				(*testType)(nil),
473				{"hello", nil, []*structf{nil, {40}}},
474				{"world", &structf{70}, nil},
475			},
476			listProto(
477				nullProto(),
478				listProto(
479					stringProto("hello"),
480					nullProto(),
481					listProto(nullProto(), listProto(intProto(40)))),
482				listProto(
483					stringProto("world"),
484					listProto(intProto(70)),
485					nullProto())),
486			listType(testTypeProto),
487		},
488		{
489			"Nil slice of pointers to structs representing a NULL array of structs.",
490			[]*testType(nil),
491			nullProto(),
492			listType(testTypeProto),
493		},
494		{
495			"Empty slice of pointers to structs representing an empty array of structs.",
496			[]*testType{},
497			listProto(),
498			listType(testTypeProto),
499		},
500	} {
501		encodeStructValue(test, t)
502	}
503}
504
505func TestEncodeStructValueErrors(t *testing.T) {
506	type Embedded struct {
507		A int
508	}
509	type embedded struct {
510		B bool
511	}
512	x := 0
513
514	for _, test := range []struct {
515		desc    string
516		in      interface{}
517		wantErr error
518	}{
519		{
520			"Unsupported embedded fields.",
521			struct{ Embedded }{Embedded{10}},
522			errUnsupportedEmbeddedStructFields("Embedded"),
523		},
524		{
525			"Unsupported pointer to embedded fields.",
526			struct{ *Embedded }{&Embedded{10}},
527			errUnsupportedEmbeddedStructFields("Embedded"),
528		},
529		{
530			"Unsupported embedded + unexported fields.",
531			struct {
532				int
533				*bool
534				embedded
535			}{10, nil, embedded{false}},
536			errUnsupportedEmbeddedStructFields("int"),
537		},
538		{
539			"Unsupported type.",
540			(**struct{})(nil),
541			errEncoderUnsupportedType((**struct{})(nil)),
542		},
543		{
544			"Unsupported type.",
545			3,
546			errEncoderUnsupportedType(3),
547		},
548		{
549			"Unsupported type.",
550			&x,
551			errEncoderUnsupportedType(&x),
552		},
553	} {
554		_, _, got := encodeStruct(test.in)
555		if got == nil || !testEqual(test.wantErr, got) {
556			t.Errorf("Test: %s, expected error %v during decoding, got %v", test.desc, test.wantErr, got)
557		}
558	}
559}
560
561func TestEncodeStructValueArrayStructFields(t *testing.T) {
562	type structf struct {
563		Intff int
564	}
565
566	structfType := structType(mkField("Intff", intType()))
567	for _, test := range []encodeTest{
568		{
569			"Unnamed array-of-struct-typed field.",
570			struct {
571				Intf       int
572				ArrStructf []structf `spanner:""`
573			}{10, []structf{{1}, {2}}},
574			listProto(
575				intProto(10),
576				listProto(
577					listProto(intProto(1)),
578					listProto(intProto(2)))),
579			structType(
580				mkField("Intf", intType()),
581				mkField("", listType(structfType))),
582		},
583		{
584			"Null array-of-struct-typed field.",
585			struct {
586				Intf       int
587				ArrStructf []structf
588			}{10, []structf(nil)},
589			listProto(intProto(10), nullProto()),
590			structType(
591				mkField("Intf", intType()),
592				mkField("ArrStructf", listType(structfType))),
593		},
594		{
595			"Array-of-struct-typed field representing empty array.",
596			struct {
597				Intf       int
598				ArrStructf []structf
599			}{10, []structf{}},
600			listProto(intProto(10), listProto([]*proto3.Value{}...)),
601			structType(
602				mkField("Intf", intType()),
603				mkField("ArrStructf", listType(structfType))),
604		},
605		{
606			"Array-of-struct-typed field with nullable struct elements.",
607			struct {
608				Intf       int
609				ArrStructf []*structf
610			}{
611				10,
612				[]*structf{(*structf)(nil), {1}},
613			},
614			listProto(
615				intProto(10),
616				listProto(
617					nullProto(),
618					listProto(intProto(1)))),
619			structType(
620				mkField("Intf", intType()),
621				mkField("ArrStructf", listType(structfType))),
622		},
623	} {
624		encodeStructValue(test, t)
625	}
626}
627
628func TestEncodeStructValueStructFields(t *testing.T) {
629	type structf struct {
630		Intff int
631	}
632	structfType := structType(mkField("Intff", intType()))
633	for _, test := range []encodeTest{
634		{
635			"Named struct-type field.",
636			struct {
637				Intf    int
638				Structf structf
639			}{10, structf{10}},
640			listProto(intProto(10), listProto(intProto(10))),
641			structType(
642				mkField("Intf", intType()),
643				mkField("Structf", structfType)),
644		},
645		{
646			"Unnamed struct-type field.",
647			struct {
648				Intf    int
649				Structf structf `spanner:""`
650			}{10, structf{10}},
651			listProto(intProto(10), listProto(intProto(10))),
652			structType(
653				mkField("Intf", intType()),
654				mkField("", structfType)),
655		},
656		{
657			"Duplicate struct-typed field.",
658			struct {
659				Structf1 structf `spanner:""`
660				Structf2 structf `spanner:""`
661			}{structf{10}, structf{20}},
662			listProto(listProto(intProto(10)), listProto(intProto(20))),
663			structType(
664				mkField("", structfType),
665				mkField("", structfType)),
666		},
667		{
668			"Null struct-typed field.",
669			struct {
670				Intf    int
671				Structf *structf
672			}{10, nil},
673			listProto(intProto(10), nullProto()),
674			structType(
675				mkField("Intf", intType()),
676				mkField("Structf", structfType)),
677		},
678		{
679			"Empty struct-typed field.",
680			struct {
681				Intf    int
682				Structf struct{}
683			}{10, struct{}{}},
684			listProto(intProto(10), listProto([]*proto3.Value{}...)),
685			structType(
686				mkField("Intf", intType()),
687				mkField("Structf", structType([]*sppb.StructType_Field{}...))),
688		},
689	} {
690		encodeStructValue(test, t)
691	}
692}
693
694func TestEncodeStructValueFieldNames(t *testing.T) {
695	type embedded struct {
696		B bool
697	}
698
699	for _, test := range []encodeTest{
700		{
701			"Duplicate fields.",
702			struct {
703				Field1    int `spanner:"field"`
704				DupField1 int `spanner:"field"`
705			}{10, 20},
706			listProto(intProto(10), intProto(20)),
707			structType(
708				mkField("field", intType()),
709				mkField("field", intType())),
710		},
711		{
712			"Duplicate Fields (different types).",
713			struct {
714				IntField    int    `spanner:"field"`
715				StringField string `spanner:"field"`
716			}{10, "abc"},
717			listProto(intProto(10), stringProto("abc")),
718			structType(
719				mkField("field", intType()),
720				mkField("field", stringType())),
721		},
722		{
723			"Duplicate unnamed fields.",
724			struct {
725				Dup  int `spanner:""`
726				Dup1 int `spanner:""`
727			}{10, 20},
728			listProto(intProto(10), intProto(20)),
729			structType(
730				mkField("", intType()),
731				mkField("", intType())),
732		},
733		{
734			"Named and unnamed fields.",
735			struct {
736				Field  string
737				Field1 int    `spanner:""`
738				Field2 string `spanner:"field"`
739			}{"abc", 10, "def"},
740			listProto(stringProto("abc"), intProto(10), stringProto("def")),
741			structType(
742				mkField("Field", stringType()),
743				mkField("", intType()),
744				mkField("field", stringType())),
745		},
746		{
747			"Ignored unexported fields.",
748			struct {
749				Field  int
750				field  bool
751				Field1 string `spanner:"field"`
752			}{10, false, "abc"},
753			listProto(intProto(10), stringProto("abc")),
754			structType(
755				mkField("Field", intType()),
756				mkField("field", stringType())),
757		},
758		{
759			"Ignored unexported struct/slice fields.",
760			struct {
761				a      []*embedded
762				b      []embedded
763				c      embedded
764				d      *embedded
765				Field1 string `spanner:"field"`
766			}{nil, nil, embedded{}, nil, "def"},
767			listProto(stringProto("def")),
768			structType(
769				mkField("field", stringType())),
770		},
771	} {
772		encodeStructValue(test, t)
773	}
774}
775
776func TestEncodeStructValueBasicFields(t *testing.T) {
777	type CustomString string
778	type CustomBytes []byte
779	type CustomInt64 int64
780	type CustomBool bool
781	type CustomFloat64 float64
782	type CustomTime time.Time
783	type CustomDate civil.Date
784
785	type CustomNullString NullString
786	type CustomNullInt64 NullInt64
787	type CustomNullBool NullBool
788	type CustomNullFloat64 NullFloat64
789	type CustomNullTime NullTime
790	type CustomNullDate NullDate
791
792	sValue := "abc"
793	iValue := int64(300)
794	bValue := false
795	fValue := 3.45
796	tValue := t1
797	dValue := d1
798
799	StructTypeProto := structType(
800		mkField("Stringf", stringType()),
801		mkField("Intf", intType()),
802		mkField("Boolf", boolType()),
803		mkField("Floatf", floatType()),
804		mkField("Bytef", bytesType()),
805		mkField("Timef", timeType()),
806		mkField("Datef", dateType()))
807
808	for _, test := range []encodeTest{
809		{
810			"Basic types.",
811			struct {
812				Stringf string
813				Intf    int
814				Boolf   bool
815				Floatf  float64
816				Bytef   []byte
817				Timef   time.Time
818				Datef   civil.Date
819			}{"abc", 300, false, 3.45, []byte("foo"), t1, d1},
820			listProto(
821				stringProto("abc"),
822				intProto(300),
823				boolProto(false),
824				floatProto(3.45),
825				bytesProto([]byte("foo")),
826				timeProto(t1),
827				dateProto(d1)),
828			StructTypeProto,
829		},
830		{
831			"Pointers to basic types.",
832			struct {
833				Stringf *string
834				Intf    *int64
835				Boolf   *bool
836				Floatf  *float64
837				Bytef   []byte
838				Timef   *time.Time
839				Datef   *civil.Date
840			}{&sValue, &iValue, &bValue, &fValue, []byte("foo"), &tValue, &dValue},
841			listProto(
842				stringProto("abc"),
843				intProto(300),
844				boolProto(false),
845				floatProto(3.45),
846				bytesProto([]byte("foo")),
847				timeProto(t1),
848				dateProto(d1)),
849			StructTypeProto,
850		},
851		{
852			"Pointers to basic types with null values.",
853			struct {
854				Stringf *string
855				Intf    *int64
856				Boolf   *bool
857				Floatf  *float64
858				Bytef   []byte
859				Timef   *time.Time
860				Datef   *civil.Date
861			}{nil, nil, nil, nil, nil, nil, nil},
862			listProto(
863				nullProto(),
864				nullProto(),
865				nullProto(),
866				nullProto(),
867				nullProto(),
868				nullProto(),
869				nullProto()),
870			StructTypeProto,
871		},
872		{
873			"Basic custom types.",
874			struct {
875				Stringf CustomString
876				Intf    CustomInt64
877				Boolf   CustomBool
878				Floatf  CustomFloat64
879				Bytef   CustomBytes
880				Timef   CustomTime
881				Datef   CustomDate
882			}{"abc", 300, false, 3.45, []byte("foo"), CustomTime(t1), CustomDate(d1)},
883			listProto(
884				stringProto("abc"),
885				intProto(300),
886				boolProto(false),
887				floatProto(3.45),
888				bytesProto([]byte("foo")),
889				timeProto(t1),
890				dateProto(d1)),
891			StructTypeProto,
892		},
893		{
894			"Basic types null values.",
895			struct {
896				Stringf NullString
897				Intf    NullInt64
898				Boolf   NullBool
899				Floatf  NullFloat64
900				Bytef   []byte
901				Timef   NullTime
902				Datef   NullDate
903			}{
904				NullString{"abc", false},
905				NullInt64{4, false},
906				NullBool{false, false},
907				NullFloat64{5.6, false},
908				nil,
909				NullTime{t1, false},
910				NullDate{d1, false},
911			},
912			listProto(
913				nullProto(),
914				nullProto(),
915				nullProto(),
916				nullProto(),
917				nullProto(),
918				nullProto(),
919				nullProto()),
920			StructTypeProto,
921		},
922		{
923			"Basic custom types null values.",
924			struct {
925				Stringf CustomNullString
926				Intf    CustomNullInt64
927				Boolf   CustomNullBool
928				Floatf  CustomNullFloat64
929				Bytef   CustomBytes
930				Timef   CustomNullTime
931				Datef   CustomNullDate
932			}{
933				CustomNullString{"abc", false},
934				CustomNullInt64{4, false},
935				CustomNullBool{false, false},
936				CustomNullFloat64{5.6, false},
937				nil,
938				CustomNullTime{t1, false},
939				CustomNullDate{d1, false},
940			},
941			listProto(
942				nullProto(),
943				nullProto(),
944				nullProto(),
945				nullProto(),
946				nullProto(),
947				nullProto(),
948				nullProto()),
949			StructTypeProto,
950		},
951	} {
952		encodeStructValue(test, t)
953	}
954}
955
956func TestEncodeStructValueArrayFields(t *testing.T) {
957	type CustomString string
958	type CustomBytes []byte
959	type CustomInt64 int64
960	type CustomBool bool
961	type CustomFloat64 float64
962	type CustomTime time.Time
963	type CustomDate civil.Date
964
965	type CustomNullString NullString
966	type CustomNullInt64 NullInt64
967	type CustomNullBool NullBool
968	type CustomNullFloat64 NullFloat64
969	type CustomNullTime NullTime
970	type CustomNullDate NullDate
971
972	sValue := "def"
973	var sNilPtr *string
974	iValue := int64(68)
975	var iNilPtr *int64
976	bValue := true
977	var bNilPtr *bool
978	fValue := 3.14
979	var fNilPtr *float64
980	tValue := t1
981	var tNilPtr *time.Time
982	dValue := d1
983	var dNilPtr *civil.Date
984
985	StructTypeProto := structType(
986		mkField("Stringf", listType(stringType())),
987		mkField("Intf", listType(intType())),
988		mkField("Int64f", listType(intType())),
989		mkField("Boolf", listType(boolType())),
990		mkField("Floatf", listType(floatType())),
991		mkField("Bytef", listType(bytesType())),
992		mkField("Timef", listType(timeType())),
993		mkField("Datef", listType(dateType())))
994
995	for _, test := range []encodeTest{
996		{
997			"Arrays of basic types with non-nullable elements",
998			struct {
999				Stringf []string
1000				Intf    []int
1001				Int64f  []int64
1002				Boolf   []bool
1003				Floatf  []float64
1004				Bytef   [][]byte
1005				Timef   []time.Time
1006				Datef   []civil.Date
1007			}{
1008				[]string{"abc", "def"},
1009				[]int{4, 67},
1010				[]int64{5, 68},
1011				[]bool{false, true},
1012				[]float64{3.45, 0.93},
1013				[][]byte{[]byte("foo"), nil},
1014				[]time.Time{t1, t2},
1015				[]civil.Date{d1, d2},
1016			},
1017			listProto(
1018				listProto(stringProto("abc"), stringProto("def")),
1019				listProto(intProto(4), intProto(67)),
1020				listProto(intProto(5), intProto(68)),
1021				listProto(boolProto(false), boolProto(true)),
1022				listProto(floatProto(3.45), floatProto(0.93)),
1023				listProto(bytesProto([]byte("foo")), nullProto()),
1024				listProto(timeProto(t1), timeProto(t2)),
1025				listProto(dateProto(d1), dateProto(d2))),
1026			StructTypeProto,
1027		},
1028		{
1029			"Arrays of basic custom types with non-nullable elements",
1030			struct {
1031				Stringf []CustomString
1032				Intf    []CustomInt64
1033				Int64f  []CustomInt64
1034				Boolf   []CustomBool
1035				Floatf  []CustomFloat64
1036				Bytef   []CustomBytes
1037				Timef   []CustomTime
1038				Datef   []CustomDate
1039			}{
1040				[]CustomString{"abc", "def"},
1041				[]CustomInt64{4, 67},
1042				[]CustomInt64{5, 68},
1043				[]CustomBool{false, true},
1044				[]CustomFloat64{3.45, 0.93},
1045				[]CustomBytes{[]byte("foo"), nil},
1046				[]CustomTime{CustomTime(t1), CustomTime(t2)},
1047				[]CustomDate{CustomDate(d1), CustomDate(d2)},
1048			},
1049			listProto(
1050				listProto(stringProto("abc"), stringProto("def")),
1051				listProto(intProto(4), intProto(67)),
1052				listProto(intProto(5), intProto(68)),
1053				listProto(boolProto(false), boolProto(true)),
1054				listProto(floatProto(3.45), floatProto(0.93)),
1055				listProto(bytesProto([]byte("foo")), nullProto()),
1056				listProto(timeProto(t1), timeProto(t2)),
1057				listProto(dateProto(d1), dateProto(d2))),
1058			StructTypeProto,
1059		},
1060		{
1061			"Arrays of basic types with nullable elements.",
1062			struct {
1063				Stringf []NullString
1064				Intf    []NullInt64
1065				Int64f  []NullInt64
1066				Boolf   []NullBool
1067				Floatf  []NullFloat64
1068				Bytef   [][]byte
1069				Timef   []NullTime
1070				Datef   []NullDate
1071			}{
1072				[]NullString{{"abc", false}, {"def", true}},
1073				[]NullInt64{{4, false}, {67, true}},
1074				[]NullInt64{{5, false}, {68, true}},
1075				[]NullBool{{true, false}, {false, true}},
1076				[]NullFloat64{{3.45, false}, {0.93, true}},
1077				[][]byte{[]byte("foo"), nil},
1078				[]NullTime{{t1, false}, {t2, true}},
1079				[]NullDate{{d1, false}, {d2, true}},
1080			},
1081			listProto(
1082				listProto(nullProto(), stringProto("def")),
1083				listProto(nullProto(), intProto(67)),
1084				listProto(nullProto(), intProto(68)),
1085				listProto(nullProto(), boolProto(false)),
1086				listProto(nullProto(), floatProto(0.93)),
1087				listProto(bytesProto([]byte("foo")), nullProto()),
1088				listProto(nullProto(), timeProto(t2)),
1089				listProto(nullProto(), dateProto(d2))),
1090			StructTypeProto,
1091		},
1092		{
1093			"Arrays of pointers to basic types with nullable elements.",
1094			struct {
1095				Stringf []*string
1096				Intf    []*int64
1097				Int64f  []*int64
1098				Boolf   []*bool
1099				Floatf  []*float64
1100				Bytef   [][]byte
1101				Timef   []*time.Time
1102				Datef   []*civil.Date
1103			}{
1104				[]*string{sNilPtr, &sValue},
1105				[]*int64{iNilPtr, &iValue},
1106				[]*int64{iNilPtr, &iValue},
1107				[]*bool{bNilPtr, &bValue},
1108				[]*float64{fNilPtr, &fValue},
1109				[][]byte{[]byte("foo"), nil},
1110				[]*time.Time{tNilPtr, &tValue},
1111				[]*civil.Date{dNilPtr, &dValue},
1112			},
1113			listProto(
1114				listProto(nullProto(), stringProto("def")),
1115				listProto(nullProto(), intProto(68)),
1116				listProto(nullProto(), intProto(68)),
1117				listProto(nullProto(), boolProto(true)),
1118				listProto(nullProto(), floatProto(3.14)),
1119				listProto(bytesProto([]byte("foo")), nullProto()),
1120				listProto(nullProto(), timeProto(t1)),
1121				listProto(nullProto(), dateProto(d1))),
1122			StructTypeProto,
1123		},
1124		{
1125			"Arrays of basic custom types with nullable elements.",
1126			struct {
1127				Stringf []CustomNullString
1128				Intf    []CustomNullInt64
1129				Int64f  []CustomNullInt64
1130				Boolf   []CustomNullBool
1131				Floatf  []CustomNullFloat64
1132				Bytef   []CustomBytes
1133				Timef   []CustomNullTime
1134				Datef   []CustomNullDate
1135			}{
1136				[]CustomNullString{{"abc", false}, {"def", true}},
1137				[]CustomNullInt64{{4, false}, {67, true}},
1138				[]CustomNullInt64{{5, false}, {68, true}},
1139				[]CustomNullBool{{true, false}, {false, true}},
1140				[]CustomNullFloat64{{3.45, false}, {0.93, true}},
1141				[]CustomBytes{[]byte("foo"), nil},
1142				[]CustomNullTime{{t1, false}, {t2, true}},
1143				[]CustomNullDate{{d1, false}, {d2, true}},
1144			},
1145			listProto(
1146				listProto(nullProto(), stringProto("def")),
1147				listProto(nullProto(), intProto(67)),
1148				listProto(nullProto(), intProto(68)),
1149				listProto(nullProto(), boolProto(false)),
1150				listProto(nullProto(), floatProto(0.93)),
1151				listProto(bytesProto([]byte("foo")), nullProto()),
1152				listProto(nullProto(), timeProto(t2)),
1153				listProto(nullProto(), dateProto(d2))),
1154			StructTypeProto,
1155		},
1156		{
1157			"Null arrays of basic types.",
1158			struct {
1159				Stringf []NullString
1160				Intf    []NullInt64
1161				Int64f  []NullInt64
1162				Boolf   []NullBool
1163				Floatf  []NullFloat64
1164				Bytef   [][]byte
1165				Timef   []NullTime
1166				Datef   []NullDate
1167			}{
1168				nil,
1169				nil,
1170				nil,
1171				nil,
1172				nil,
1173				nil,
1174				nil,
1175				nil,
1176			},
1177			listProto(
1178				nullProto(),
1179				nullProto(),
1180				nullProto(),
1181				nullProto(),
1182				nullProto(),
1183				nullProto(),
1184				nullProto(),
1185				nullProto()),
1186			StructTypeProto,
1187		},
1188		{
1189			"Null arrays of basic custom types.",
1190			struct {
1191				Stringf []CustomNullString
1192				Intf    []CustomNullInt64
1193				Int64f  []CustomNullInt64
1194				Boolf   []CustomNullBool
1195				Floatf  []CustomNullFloat64
1196				Bytef   []CustomBytes
1197				Timef   []CustomNullTime
1198				Datef   []CustomNullDate
1199			}{
1200				nil,
1201				nil,
1202				nil,
1203				nil,
1204				nil,
1205				nil,
1206				nil,
1207				nil,
1208			},
1209			listProto(
1210				nullProto(),
1211				nullProto(),
1212				nullProto(),
1213				nullProto(),
1214				nullProto(),
1215				nullProto(),
1216				nullProto(),
1217				nullProto()),
1218			StructTypeProto,
1219		},
1220	} {
1221		encodeStructValue(test, t)
1222	}
1223}
1224
1225// Test decoding Values.
1226func TestDecodeValue(t *testing.T) {
1227	type CustomString string
1228	type CustomBytes []byte
1229	type CustomInt64 int64
1230	type CustomBool bool
1231	type CustomFloat64 float64
1232	type CustomTime time.Time
1233	type CustomDate civil.Date
1234	type CustomNumeric big.Rat
1235
1236	type CustomNullString NullString
1237	type CustomNullInt64 NullInt64
1238	type CustomNullBool NullBool
1239	type CustomNullFloat64 NullFloat64
1240	type CustomNullTime NullTime
1241	type CustomNullDate NullDate
1242	type CustomNullNumeric NullNumeric
1243
1244	// Pointer values.
1245	sValue := "abc"
1246	var sNilPtr *string
1247	s2Value := "bcd"
1248
1249	iValue := int64(15)
1250	var iNilPtr *int64
1251	i1Value := int64(91)
1252	i2Value := int64(87)
1253
1254	bValue := true
1255	var bNilPtr *bool
1256	b2Value := false
1257
1258	fValue := 3.14
1259	var fNilPtr *float64
1260	f2Value := 6.626
1261
1262	numValuePtr := big.NewRat(12345, 1e3)
1263	var numNilPtr *big.Rat
1264	num2ValuePtr := big.NewRat(12345, 1e4)
1265
1266	tValue := t1
1267	var tNilPtr *time.Time
1268	t2Value := t2
1269
1270	dValue := d1
1271	var dNilPtr *civil.Date
1272	d2Value := d2
1273
1274	for _, test := range []struct {
1275		desc      string
1276		proto     *proto3.Value
1277		protoType *sppb.Type
1278		want      interface{}
1279		wantErr   bool
1280	}{
1281		// STRING
1282		{desc: "decode STRING to string", proto: stringProto("abc"), protoType: stringType(), want: "abc"},
1283		{desc: "decode NULL to string", proto: nullProto(), protoType: stringType(), want: "abc", wantErr: true},
1284		{desc: "decode STRING to *string", proto: stringProto("abc"), protoType: stringType(), want: &sValue},
1285		{desc: "decode NULL to *string", proto: nullProto(), protoType: stringType(), want: sNilPtr},
1286		{desc: "decode STRING to NullString", proto: stringProto("abc"), protoType: stringType(), want: NullString{"abc", true}},
1287		{desc: "decode NULL to NullString", proto: nullProto(), protoType: stringType(), want: NullString{}},
1288		// STRING ARRAY with []NullString
1289		{desc: "decode ARRAY<STRING> to []NullString", proto: listProto(stringProto("abc"), nullProto(), stringProto("bcd")), protoType: listType(stringType()), want: []NullString{{"abc", true}, {}, {"bcd", true}}},
1290		{desc: "decode NULL to []NullString", proto: nullProto(), protoType: listType(stringType()), want: []NullString(nil)},
1291		// STRING ARRAY with []string
1292		{desc: "decode ARRAY<STRING> to []string", proto: listProto(stringProto("abc"), stringProto("bcd")), protoType: listType(stringType()), want: []string{"abc", "bcd"}},
1293		// STRING ARRAY with []*string
1294		{desc: "decode ARRAY<STRING> to []*string", proto: listProto(stringProto("abc"), nullProto(), stringProto("bcd")), protoType: listType(stringType()), want: []*string{&sValue, sNilPtr, &s2Value}},
1295		{desc: "decode NULL to []*string", proto: nullProto(), protoType: listType(stringType()), want: []*string(nil)},
1296		// BYTES
1297		{desc: "decode BYTES to []byte", proto: bytesProto([]byte("ab")), protoType: bytesType(), want: []byte("ab")},
1298		{desc: "decode NULL to []byte", proto: nullProto(), protoType: bytesType(), want: []byte(nil)},
1299		// BYTES ARRAY
1300		{desc: "decode ARRAY<BYTES> to [][]byte", proto: listProto(bytesProto([]byte("ab")), nullProto()), protoType: listType(bytesType()), want: [][]byte{[]byte("ab"), nil}},
1301		{desc: "decode NULL to [][]byte", proto: nullProto(), protoType: listType(bytesType()), want: [][]byte(nil)},
1302		//INT64
1303		{desc: "decode INT64 to int64", proto: intProto(15), protoType: intType(), want: int64(15)},
1304		{desc: "decode NULL to int64", proto: nullProto(), protoType: intType(), want: int64(0), wantErr: true},
1305		{desc: "decode INT64 to *int64", proto: intProto(15), protoType: intType(), want: &iValue},
1306		{desc: "decode NULL to *int64", proto: nullProto(), protoType: intType(), want: iNilPtr},
1307		{desc: "decode INT64 to NullInt64", proto: intProto(15), protoType: intType(), want: NullInt64{15, true}},
1308		{desc: "decode NULL to NullInt64", proto: nullProto(), protoType: intType(), want: NullInt64{}},
1309		// INT64 ARRAY with []NullInt64
1310		{desc: "decode ARRAY<INT64> to []NullInt64", proto: listProto(intProto(91), nullProto(), intProto(87)), protoType: listType(intType()), want: []NullInt64{{91, true}, {}, {87, true}}},
1311		{desc: "decode NULL to []NullInt64", proto: nullProto(), protoType: listType(intType()), want: []NullInt64(nil)},
1312		// INT64 ARRAY with []int64
1313		{desc: "decode ARRAY<INT64> to []int64", proto: listProto(intProto(91), intProto(87)), protoType: listType(intType()), want: []int64{91, 87}},
1314		// INT64 ARRAY with []*int64
1315		{desc: "decode ARRAY<INT64> to []*int64", proto: listProto(intProto(91), nullProto(), intProto(87)), protoType: listType(intType()), want: []*int64{&i1Value, nil, &i2Value}},
1316		{desc: "decode NULL to []*int64", proto: nullProto(), protoType: listType(intType()), want: []*int64(nil)},
1317		// BOOL
1318		{desc: "decode BOOL to bool", proto: boolProto(true), protoType: boolType(), want: true},
1319		{desc: "decode NULL to bool", proto: nullProto(), protoType: boolType(), want: true, wantErr: true},
1320		{desc: "decode BOOL to *bool", proto: boolProto(true), protoType: boolType(), want: &bValue},
1321		{desc: "decode NULL to *bool", proto: nullProto(), protoType: boolType(), want: bNilPtr},
1322		{desc: "decode BOOL to NullBool", proto: boolProto(true), protoType: boolType(), want: NullBool{true, true}},
1323		{desc: "decode BOOL to NullBool", proto: nullProto(), protoType: boolType(), want: NullBool{}},
1324		// BOOL ARRAY with []NullBool
1325		{desc: "decode ARRAY<BOOL> to []NullBool", proto: listProto(boolProto(true), boolProto(false), nullProto()), protoType: listType(boolType()), want: []NullBool{{true, true}, {false, true}, {}}},
1326		{desc: "decode NULL to []NullBool", proto: nullProto(), protoType: listType(boolType()), want: []NullBool(nil)},
1327		// BOOL ARRAY with []bool
1328		{desc: "decode ARRAY<BOOL> to []bool", proto: listProto(boolProto(true), boolProto(false)), protoType: listType(boolType()), want: []bool{true, false}},
1329		// BOOL ARRAY with []*bool
1330		{desc: "decode ARRAY<BOOL> to []*bool", proto: listProto(boolProto(true), nullProto(), boolProto(false)), protoType: listType(boolType()), want: []*bool{&bValue, bNilPtr, &b2Value}},
1331		{desc: "decode NULL to []*bool", proto: nullProto(), protoType: listType(boolType()), want: []*bool(nil)},
1332		// FLOAT64
1333		{desc: "decode FLOAT64 to float64", proto: floatProto(3.14), protoType: floatType(), want: 3.14},
1334		{desc: "decode NULL to float64", proto: nullProto(), protoType: floatType(), want: 0.00, wantErr: true},
1335		{desc: "decode FLOAT64 to *float64", proto: floatProto(3.14), protoType: floatType(), want: &fValue},
1336		{desc: "decode NULL to *float64", proto: nullProto(), protoType: floatType(), want: fNilPtr},
1337		{desc: "decode FLOAT64 to NullFloat64", proto: floatProto(3.14), protoType: floatType(), want: NullFloat64{3.14, true}},
1338		{desc: "decode NULL to NullFloat64", proto: nullProto(), protoType: floatType(), want: NullFloat64{}},
1339		// FLOAT64 ARRAY with []NullFloat64
1340		{desc: "decode ARRAY<FLOAT64> to []NullFloat64", proto: listProto(floatProto(math.Inf(1)), floatProto(math.Inf(-1)), nullProto(), floatProto(3.1)), protoType: listType(floatType()), want: []NullFloat64{{math.Inf(1), true}, {math.Inf(-1), true}, {}, {3.1, true}}},
1341		{desc: "decode NULL to []NullFloat64", proto: nullProto(), protoType: listType(floatType()), want: []NullFloat64(nil)},
1342		// FLOAT64 ARRAY with []float64
1343		{desc: "decode ARRAY<FLOAT64> to []float64", proto: listProto(floatProto(math.Inf(1)), floatProto(math.Inf(-1)), floatProto(3.1)), protoType: listType(floatType()), want: []float64{math.Inf(1), math.Inf(-1), 3.1}},
1344		// FLOAT64 ARRAY with []*float64
1345		{desc: "decode ARRAY<FLOAT64> to []*float64", proto: listProto(floatProto(fValue), nullProto(), floatProto(f2Value)), protoType: listType(floatType()), want: []*float64{&fValue, nil, &f2Value}},
1346		{desc: "decode NULL to []*float64", proto: nullProto(), protoType: listType(floatType()), want: []*float64(nil)},
1347		// NUMERIC
1348		{desc: "decode NUMERIC to big.Rat", proto: numericProto(numValuePtr), protoType: numericType(), want: *numValuePtr},
1349		{desc: "decode NUMERIC to NullNumeric", proto: numericProto(numValuePtr), protoType: numericType(), want: NullNumeric{*numValuePtr, true}},
1350		{desc: "decode NULL to NullNumeric", proto: nullProto(), protoType: numericType(), want: NullNumeric{}},
1351		{desc: "decode NUMERIC to *big.Rat", proto: numericProto(numValuePtr), protoType: numericType(), want: numValuePtr},
1352		{desc: "decode NULL to *big.Rat", proto: nullProto(), protoType: numericType(), want: numNilPtr},
1353		// NUMERIC ARRAY with []NullNumeric
1354		{desc: "decode ARRAY<Numeric> to []NullNumeric", proto: listProto(numericProto(numValuePtr), numericProto(num2ValuePtr), nullProto()), protoType: listType(numericType()), want: []NullNumeric{{*numValuePtr, true}, {*num2ValuePtr, true}, {}}},
1355		{desc: "decode NULL to []NullNumeric", proto: nullProto(), protoType: listType(numericType()), want: []NullNumeric(nil)},
1356		// NUMERIC ARRAY with []big.Rat
1357		{desc: "decode ARRAY<NUMERIC> to []big.Rat", proto: listProto(numericProto(numValuePtr), numericProto(num2ValuePtr)), protoType: listType(numericType()), want: []big.Rat{*numValuePtr, *num2ValuePtr}},
1358		// NUMERIC ARRAY with []*big.Rat
1359		{desc: "decode ARRAY<NUMERIC> to []*big.Rat", proto: listProto(numericProto(numValuePtr), nullProto(), numericProto(num2ValuePtr)), protoType: listType(numericType()), want: []*big.Rat{numValuePtr, nil, num2ValuePtr}},
1360		{desc: "decode NULL to []*big.Rat", proto: nullProto(), protoType: listType(numericType()), want: []*big.Rat(nil)},
1361		// TIMESTAMP
1362		{desc: "decode TIMESTAMP to time.Time", proto: timeProto(t1), protoType: timeType(), want: t1},
1363		{desc: "decode TIMESTAMP to NullTime", proto: timeProto(t1), protoType: timeType(), want: NullTime{t1, true}},
1364		{desc: "decode NULL to NullTime", proto: nullProto(), protoType: timeType(), want: NullTime{}},
1365		{desc: "decode TIMESTAMP to *time.Time", proto: timeProto(t1), protoType: timeType(), want: &tValue},
1366		{desc: "decode NULL to *time.Time", proto: nullProto(), protoType: timeType(), want: tNilPtr},
1367		{desc: "decode INT64 to time.Time", proto: intProto(7), protoType: timeType(), want: time.Time{}, wantErr: true},
1368		// TIMESTAMP ARRAY with []NullTime
1369		{desc: "decode ARRAY<TIMESTAMP> to []NullTime", proto: listProto(timeProto(t1), timeProto(t2), timeProto(t3), nullProto()), protoType: listType(timeType()), want: []NullTime{{t1, true}, {t2, true}, {t3, true}, {}}},
1370		{desc: "decode NULL to []NullTime", proto: nullProto(), protoType: listType(timeType()), want: []NullTime(nil)},
1371		// TIMESTAMP ARRAY with []time.Time
1372		{desc: "decode ARRAY<TIMESTAMP> to []time.Time", proto: listProto(timeProto(t1), timeProto(t2), timeProto(t3)), protoType: listType(timeType()), want: []time.Time{t1, t2, t3}},
1373		// TIMESTAMP ARRAY with []*time.Time
1374		{desc: "decode ARRAY<TIMESTAMP> to []*time.Time", proto: listProto(timeProto(t1), nullProto(), timeProto(t2)), protoType: listType(timeType()), want: []*time.Time{&tValue, nil, &t2Value}},
1375		{desc: "decode NULL to []*time.Time", proto: nullProto(), protoType: listType(timeType()), want: []*time.Time(nil)},
1376		// DATE
1377		{desc: "decode DATE to civil.Date", proto: dateProto(d1), protoType: dateType(), want: d1},
1378		{desc: "decode DATE to NullDate", proto: dateProto(d1), protoType: dateType(), want: NullDate{d1, true}},
1379		{desc: "decode NULL to NullDate", proto: nullProto(), protoType: dateType(), want: NullDate{}},
1380		{desc: "decode DATE to *civil.Date", proto: dateProto(d1), protoType: dateType(), want: &dValue},
1381		{desc: "decode NULL to *civil.Date", proto: nullProto(), protoType: dateType(), want: dNilPtr},
1382		// DATE ARRAY with []NullDate
1383		{desc: "decode ARRAY<DATE> to []NullDate", proto: listProto(dateProto(d1), dateProto(d2), nullProto()), protoType: listType(dateType()), want: []NullDate{{d1, true}, {d2, true}, {}}},
1384		{desc: "decode NULL to []NullDate", proto: nullProto(), protoType: listType(dateType()), want: []NullDate(nil)},
1385		// DATE ARRAY with []civil.Date
1386		{desc: "decode ARRAY<DATE> to []civil.Date", proto: listProto(dateProto(d1), dateProto(d2)), protoType: listType(dateType()), want: []civil.Date{d1, d2}},
1387		// DATE ARRAY with []NullDate
1388		{desc: "decode ARRAY<DATE> to []*civil.Date", proto: listProto(dateProto(d1), nullProto(), dateProto(d2)), protoType: listType(dateType()), want: []*civil.Date{&dValue, nil, &d2Value}},
1389		{desc: "decode NULL to []*civil.Date", proto: nullProto(), protoType: listType(dateType()), want: []*civil.Date(nil)},
1390		// STRUCT ARRAY
1391		// STRUCT schema is equal to the following Go struct:
1392		// type s struct {
1393		//     Col1 NullInt64
1394		//     Col2 []struct {
1395		//         SubCol1 float64
1396		//         SubCol2 string
1397		//     }
1398		// }
1399		{
1400			desc: "decode ARRAY<STRUCT> to []NullRow",
1401			proto: listProto(
1402				listProto(
1403					intProto(3),
1404					listProto(
1405						listProto(floatProto(3.14), stringProto("this")),
1406						listProto(floatProto(0.57), stringProto("siht")),
1407					),
1408				),
1409				listProto(
1410					nullProto(),
1411					nullProto(),
1412				),
1413				nullProto(),
1414			),
1415			protoType: listType(
1416				structType(
1417					mkField("Col1", intType()),
1418					mkField(
1419						"Col2",
1420						listType(
1421							structType(
1422								mkField("SubCol1", floatType()),
1423								mkField("SubCol2", stringType()),
1424							),
1425						),
1426					),
1427				),
1428			),
1429			want: []NullRow{
1430				{
1431					Row: Row{
1432						fields: []*sppb.StructType_Field{
1433							mkField("Col1", intType()),
1434							mkField(
1435								"Col2",
1436								listType(
1437									structType(
1438										mkField("SubCol1", floatType()),
1439										mkField("SubCol2", stringType()),
1440									),
1441								),
1442							),
1443						},
1444						vals: []*proto3.Value{
1445							intProto(3),
1446							listProto(
1447								listProto(floatProto(3.14), stringProto("this")),
1448								listProto(floatProto(0.57), stringProto("siht")),
1449							),
1450						},
1451					},
1452					Valid: true,
1453				},
1454				{
1455					Row: Row{
1456						fields: []*sppb.StructType_Field{
1457							mkField("Col1", intType()),
1458							mkField(
1459								"Col2",
1460								listType(
1461									structType(
1462										mkField("SubCol1", floatType()),
1463										mkField("SubCol2", stringType()),
1464									),
1465								),
1466							),
1467						},
1468						vals: []*proto3.Value{
1469							nullProto(),
1470							nullProto(),
1471						},
1472					},
1473					Valid: true,
1474				},
1475				{},
1476			},
1477		},
1478		{
1479			desc: "decode ARRAY<STRUCT> to []*struct",
1480			proto: listProto(
1481				listProto(
1482					intProto(3),
1483					listProto(
1484						listProto(floatProto(3.14), stringProto("this")),
1485						listProto(floatProto(0.57), stringProto("siht")),
1486					),
1487				),
1488				listProto(
1489					nullProto(),
1490					nullProto(),
1491				),
1492				nullProto(),
1493			),
1494			protoType: listType(
1495				structType(
1496					mkField("Col1", intType()),
1497					mkField(
1498						"Col2",
1499						listType(
1500							structType(
1501								mkField("SubCol1", floatType()),
1502								mkField("SubCol2", stringType()),
1503							),
1504						),
1505					),
1506				),
1507			),
1508			want: []*struct {
1509				Col1      NullInt64
1510				StructCol []*struct {
1511					SubCol1 NullFloat64
1512					SubCol2 string
1513				} `spanner:"Col2"`
1514			}{
1515				{
1516					Col1: NullInt64{3, true},
1517					StructCol: []*struct {
1518						SubCol1 NullFloat64
1519						SubCol2 string
1520					}{
1521						{
1522							SubCol1: NullFloat64{3.14, true},
1523							SubCol2: "this",
1524						},
1525						{
1526							SubCol1: NullFloat64{0.57, true},
1527							SubCol2: "siht",
1528						},
1529					},
1530				},
1531				{
1532					Col1: NullInt64{},
1533					StructCol: []*struct {
1534						SubCol1 NullFloat64
1535						SubCol2 string
1536					}(nil),
1537				},
1538				nil,
1539			},
1540		},
1541		// GenericColumnValue
1542		{desc: "decode STRING to GenericColumnValue", proto: stringProto("abc"), protoType: stringType(), want: GenericColumnValue{stringType(), stringProto("abc")}},
1543		{desc: "decode NULL to GenericColumnValue", proto: nullProto(), protoType: stringType(), want: GenericColumnValue{stringType(), nullProto()}},
1544		// not actually valid (stringProto inside int list), but demonstrates pass-through.
1545		{desc: "decode ARRAY<INT64> to GenericColumnValue", proto: listProto(intProto(5), nullProto(), stringProto("bcd")), protoType: listType(intType()), want: GenericColumnValue{Type: listType(intType()), Value: listProto(intProto(5), nullProto(), stringProto("bcd"))}},
1546
1547		// Custom base types.
1548		{desc: "decode STRING to CustomString", proto: stringProto("bar"), protoType: stringType(), want: CustomString("bar")},
1549		{desc: "decode BYTES to CustomBytes", proto: bytesProto([]byte("ab")), protoType: bytesType(), want: CustomBytes("ab")},
1550		{desc: "decode INT64 to CustomInt64", proto: intProto(-100), protoType: intType(), want: CustomInt64(-100)},
1551		{desc: "decode BOOL to CustomBool", proto: boolProto(true), protoType: boolType(), want: CustomBool(true)},
1552		{desc: "decode FLOAT64 to CustomFloat64", proto: floatProto(6.626), protoType: floatType(), want: CustomFloat64(6.626)},
1553		{desc: "decode NUMERIC to CustomNumeric", proto: numericProto(numValuePtr), protoType: numericType(), want: CustomNumeric(*numValuePtr)},
1554		{desc: "decode TIMESTAMP to CustomTimestamp", proto: timeProto(t1), protoType: timeType(), want: CustomTime(t1)},
1555		{desc: "decode DATE to CustomDate", proto: dateProto(d1), protoType: dateType(), want: CustomDate(d1)},
1556
1557		{desc: "decode NULL to CustomString", proto: nullProto(), protoType: stringType(), want: CustomString(""), wantErr: true},
1558		{desc: "decode NULL to CustomBytes", proto: nullProto(), protoType: bytesType(), want: CustomBytes(nil)},
1559		{desc: "decode NULL to CustomInt64", proto: nullProto(), protoType: intType(), want: CustomInt64(0), wantErr: true},
1560		{desc: "decode NULL to CustomBool", proto: nullProto(), protoType: boolType(), want: CustomBool(false), wantErr: true},
1561		{desc: "decode NULL to CustomFloat64", proto: nullProto(), protoType: floatType(), want: CustomFloat64(0), wantErr: true},
1562		{desc: "decode NULL to CustomNumeric", proto: nullProto(), protoType: numericType(), want: CustomNumeric{}, wantErr: true},
1563		{desc: "decode NULL to CustomTime", proto: nullProto(), protoType: timeType(), want: CustomTime{}, wantErr: true},
1564		{desc: "decode NULL to CustomDate", proto: nullProto(), protoType: dateType(), want: CustomDate{}, wantErr: true},
1565
1566		{desc: "decode STRING to CustomNullString", proto: stringProto("bar"), protoType: stringType(), want: CustomNullString{"bar", true}},
1567		{desc: "decode INT64 to CustomNullInt64", proto: intProto(-100), protoType: intType(), want: CustomNullInt64{-100, true}},
1568		{desc: "decode BOOL to CustomNullBool", proto: boolProto(true), protoType: boolType(), want: CustomNullBool{true, true}},
1569		{desc: "decode FLOAT64 to CustomNullFloat64", proto: floatProto(6.626), protoType: floatType(), want: CustomNullFloat64{6.626, true}},
1570		{desc: "decode NUMERIC to CustomNullNumeric", proto: numericProto(numValuePtr), protoType: numericType(), want: CustomNullNumeric{*numValuePtr, true}},
1571		{desc: "decode TIMESTAMP to CustomNullTime", proto: timeProto(t1), protoType: timeType(), want: CustomNullTime{t1, true}},
1572		{desc: "decode DATE to CustomNullDate", proto: dateProto(d1), protoType: dateType(), want: CustomNullDate{d1, true}},
1573
1574		{desc: "decode NULL to CustomNullString", proto: nullProto(), protoType: stringType(), want: CustomNullString{}},
1575		{desc: "decode NULL to CustomNullInt64", proto: nullProto(), protoType: intType(), want: CustomNullInt64{}},
1576		{desc: "decode NULL to CustomNullBool", proto: nullProto(), protoType: boolType(), want: CustomNullBool{}},
1577		{desc: "decode NULL to CustomNullFloat64", proto: nullProto(), protoType: floatType(), want: CustomNullFloat64{}},
1578		{desc: "decode NULL to CustomNullNumeric", proto: nullProto(), protoType: numericType(), want: CustomNullNumeric{}},
1579		{desc: "decode NULL to CustomNullTime", proto: nullProto(), protoType: timeType(), want: CustomNullTime{}},
1580		{desc: "decode NULL to CustomNullDate", proto: nullProto(), protoType: dateType(), want: CustomNullDate{}},
1581
1582		// STRING ARRAY
1583		{desc: "decode NULL to []CustomString", proto: nullProto(), protoType: listType(stringType()), want: []CustomString(nil)},
1584		{desc: "decode ARRAY<STRING> to []CustomString", proto: listProto(stringProto("abc"), stringProto("bcd")), protoType: listType(stringType()), want: []CustomString{"abc", "bcd"}},
1585		{desc: "decode ARRAY<STRING> with NULL values to []CustomString", proto: listProto(stringProto("abc"), nullProto(), stringProto("bcd")), protoType: listType(stringType()), want: []CustomString{}, wantErr: true},
1586		{desc: "decode NULL to []CustomNullString", proto: nullProto(), protoType: listType(stringType()), want: []CustomNullString(nil)},
1587		{desc: "decode ARRAY<STRING> to []CustomNullString", proto: listProto(stringProto("abc"), nullProto(), stringProto("bcd")), protoType: listType(stringType()), want: []CustomNullString{{"abc", true}, {}, {"bcd", true}}},
1588		// BYTES ARRAY
1589		{desc: "decode NULL to []CustomBytes", proto: nullProto(), protoType: listType(bytesType()), want: []CustomBytes(nil)},
1590		{desc: "decode ARRAY<BYTES> to []CustomBytes", proto: listProto(bytesProto([]byte("abc")), nullProto(), bytesProto([]byte("bcd"))), protoType: listType(bytesType()), want: []CustomBytes{CustomBytes("abc"), CustomBytes(nil), CustomBytes("bcd")}},
1591		// INT64 ARRAY
1592		{desc: "decode NULL to []CustomInt64", proto: nullProto(), protoType: listType(intType()), want: []CustomInt64(nil)},
1593		{desc: "decode ARRAY<INT64> with NULL values to []CustomInt64", proto: listProto(intProto(-100), nullProto(), intProto(100)), protoType: listType(intType()), want: []CustomInt64{}, wantErr: true},
1594		{desc: "decode ARRAY<INT64> to []CustomInt64", proto: listProto(intProto(-100), intProto(100)), protoType: listType(intType()), want: []CustomInt64{-100, 100}},
1595		{desc: "decode NULL to []CustomNullInt64", proto: nullProto(), protoType: listType(intType()), want: []CustomNullInt64(nil)},
1596		{desc: "decode ARRAY<INT64> to []CustomNullInt64", proto: listProto(intProto(-100), nullProto(), intProto(100)), protoType: listType(intType()), want: []CustomNullInt64{{-100, true}, {}, {100, true}}},
1597		// BOOL ARRAY
1598		{desc: "decode NULL to []CustomBool", proto: nullProto(), protoType: listType(boolType()), want: []CustomBool(nil)},
1599		{desc: "decode ARRAY<BOOL> with NULL values to []CustomBool", proto: listProto(boolProto(false), nullProto(), boolProto(true)), protoType: listType(boolType()), want: []CustomBool{}, wantErr: true},
1600		{desc: "decode ARRAY<BOOL> to []CustomBool", proto: listProto(boolProto(false), boolProto(true)), protoType: listType(boolType()), want: []CustomBool{false, true}},
1601		{desc: "decode NULL to []CustomNullBool", proto: nullProto(), protoType: listType(boolType()), want: []CustomNullBool(nil)},
1602		{desc: "decode ARRAY<BOOL> to []CustomNullBool", proto: listProto(boolProto(false), nullProto(), boolProto(true)), protoType: listType(boolType()), want: []CustomNullBool{{false, true}, {}, {true, true}}},
1603		// FLOAT64 ARRAY
1604		{desc: "decode NULL to []CustomFloat64", proto: nullProto(), protoType: listType(floatType()), want: []CustomFloat64(nil)},
1605		{desc: "decode ARRAY<FLOAT64> with NULL values to []CustomFloat64", proto: listProto(floatProto(3.14), nullProto(), floatProto(6.626)), protoType: listType(floatType()), want: []CustomFloat64{}, wantErr: true},
1606		{desc: "decode ARRAY<FLOAT64> to []CustomFloat64", proto: listProto(floatProto(3.14), floatProto(6.626)), protoType: listType(floatType()), want: []CustomFloat64{3.14, 6.626}},
1607		{desc: "decode NULL to []CustomNullFloat64", proto: nullProto(), protoType: listType(floatType()), want: []CustomNullFloat64(nil)},
1608		{desc: "decode ARRAY<FLOAT64> to []CustomNullFloat64", proto: listProto(floatProto(3.14), nullProto(), floatProto(6.626)), protoType: listType(floatType()), want: []CustomNullFloat64{{3.14, true}, {}, {6.626, true}}},
1609		// NUMERIC ARRAY
1610		{desc: "decode NULL to []CustomNumeric", proto: nullProto(), protoType: listType(numericType()), want: []CustomNumeric(nil)},
1611		{desc: "decode ARRAY<NUMERIC> with NULL values to []CustomNumeric", proto: listProto(numericProto(numValuePtr), nullProto(), numericProto(num2ValuePtr)), protoType: listType(numericType()), want: []CustomNumeric{}, wantErr: true},
1612		{desc: "decode ARRAY<NUMERIC> to []CustomNumeric", proto: listProto(numericProto(numValuePtr), numericProto(num2ValuePtr)), protoType: listType(numericType()), want: []CustomNumeric{CustomNumeric(*numValuePtr), CustomNumeric(*num2ValuePtr)}},
1613		{desc: "decode NULL to []CustomNullNumeric", proto: nullProto(), protoType: listType(numericType()), want: []CustomNullNumeric(nil)},
1614		{desc: "decode ARRAY<NUMERIC> to []CustomNullNumeric", proto: listProto(numericProto(numValuePtr), nullProto(), numericProto(num2ValuePtr)), protoType: listType(numericType()), want: []CustomNullNumeric{{*numValuePtr, true}, {}, {*num2ValuePtr, true}}},
1615		// TIME ARRAY
1616		{desc: "decode NULL to []CustomTime", proto: nullProto(), protoType: listType(timeType()), want: []CustomTime(nil)},
1617		{desc: "decode ARRAY<TIMESTAMP> with NULL values to []CustomTime", proto: listProto(timeProto(t1), nullProto(), timeProto(t2)), protoType: listType(timeType()), want: []CustomTime{}, wantErr: true},
1618		{desc: "decode ARRAY<TIMESTAMP> to []CustomTime", proto: listProto(timeProto(t1), timeProto(t2)), protoType: listType(timeType()), want: []CustomTime{CustomTime(t1), CustomTime(t2)}},
1619		{desc: "decode NULL to []CustomNullTime", proto: nullProto(), protoType: listType(timeType()), want: []CustomNullTime(nil)},
1620		{desc: "decode ARRAY<TIMESTAMP> to []CustomNullTime", proto: listProto(timeProto(t1), nullProto(), timeProto(t2)), protoType: listType(timeType()), want: []CustomNullTime{{t1, true}, {}, {t2, true}}},
1621		// DATE ARRAY
1622		{desc: "decode NULL to []CustomDate", proto: nullProto(), protoType: listType(dateType()), want: []CustomDate(nil)},
1623		{desc: "decode ARRAY<DATE> with NULL values to []CustomDate", proto: listProto(dateProto(d1), nullProto(), dateProto(d2)), protoType: listType(dateType()), want: []CustomDate{}, wantErr: true},
1624		{desc: "decode ARRAY<DATE> to []CustomDate", proto: listProto(dateProto(d1), dateProto(d2)), protoType: listType(dateType()), want: []CustomDate{CustomDate(d1), CustomDate(d2)}},
1625		{desc: "decode NULL to []CustomNullDate", proto: nullProto(), protoType: listType(dateType()), want: []CustomNullDate(nil)},
1626		{desc: "decode ARRAY<DATE> to []CustomNullDate", proto: listProto(dateProto(d1), nullProto(), dateProto(d2)), protoType: listType(dateType()), want: []CustomNullDate{{d1, true}, {}, {d2, true}}},
1627		// CUSTOM STRUCT
1628		{desc: "decode STRING to CustomStructToString", proto: stringProto("A-B"), protoType: stringType(), want: customStructToString{"A", "B"}},
1629		{desc: "decode INT64 to CustomStructToInt", proto: intProto(123), protoType: intType(), want: customStructToInt{1, 23}},
1630		{desc: "decode FLOAT64 to CustomStructToFloat", proto: floatProto(123.123), protoType: floatType(), want: customStructToFloat{1.23, 12.3}},
1631		{desc: "decode BOOL to CustomStructToBool", proto: boolProto(true), protoType: boolType(), want: customStructToBool{true, false}},
1632		{desc: "decode BYTES to CustomStructToBytes", proto: bytesProto([]byte("AB")), protoType: bytesType(), want: customStructToBytes{[]byte("A"), []byte("B")}},
1633		{desc: "decode TIMESTAMP to CustomStructToTime", proto: timeProto(t1), protoType: timeType(), want: customStructToTime{"A", "B"}},
1634		{desc: "decode DATE to CustomStructToDate", proto: dateProto(d1), protoType: dateType(), want: customStructToDate{"A", "B"}},
1635	} {
1636		gotp := reflect.New(reflect.TypeOf(test.want))
1637		v := gotp.Interface()
1638		// Initialize the input to a non-zero value to ensure that the decode
1639		// method will override this with the actual value, or a zero value in
1640		// case of a NULL.
1641		switch nullValue := v.(type) {
1642		case *NullString:
1643			nullValue.StringVal = "foo"
1644		case *NullInt64:
1645			nullValue.Int64 = -100
1646		case *NullFloat64:
1647			nullValue.Float64 = 3.14
1648		case *NullBool:
1649			nullValue.Bool = true
1650		case *NullTime:
1651			nullValue.Time = time.Unix(100, 100)
1652		case *NullDate:
1653			nullValue.Date = civil.DateOf(time.Unix(100, 200))
1654		default:
1655		}
1656		err := decodeValue(test.proto, test.protoType, v)
1657		if test.wantErr {
1658			if err == nil {
1659				t.Errorf("%s: missing expected decode failure for %v(%v)", test.desc, test.proto, test.protoType)
1660			}
1661			continue
1662		}
1663		if err != nil {
1664			t.Errorf("%s: cannot decode %v(%v): %v", test.desc, test.proto, test.protoType, err)
1665			continue
1666		}
1667		got := reflect.Indirect(gotp).Interface()
1668		if !testutil.Equal(got, test.want, cmp.AllowUnexported(CustomNumeric{}, CustomTime{}, CustomDate{}, Row{}, big.Rat{}, big.Int{})) {
1669			t.Errorf("%s: unexpected decoding result - got %v (%T), want %v (%T)", test.desc, got, got, test.want, test.want)
1670		}
1671	}
1672}
1673
1674// Test error cases for decodeValue.
1675func TestDecodeValueErrors(t *testing.T) {
1676	var s string
1677	for i, test := range []struct {
1678		in *proto3.Value
1679		t  *sppb.Type
1680		v  interface{}
1681	}{
1682		{nullProto(), stringType(), nil},
1683		{nullProto(), stringType(), 1},
1684		{timeProto(t1), timeType(), &s},
1685	} {
1686		err := decodeValue(test.in, test.t, test.v)
1687		if err == nil {
1688			t.Errorf("#%d: want error, got nil", i)
1689		}
1690	}
1691}
1692
1693func TestGetDecodableSpannerType(t *testing.T) {
1694	type CustomString string
1695	type CustomInt64 int64
1696	type CustomBool bool
1697	type CustomFloat64 float64
1698	type CustomTime time.Time
1699	type CustomDate civil.Date
1700	type CustomNumeric big.Rat
1701
1702	type CustomNullString NullString
1703	type CustomNullInt64 NullInt64
1704	type CustomNullBool NullBool
1705	type CustomNullFloat64 NullFloat64
1706	type CustomNullTime NullTime
1707	type CustomNullDate NullDate
1708	type CustomNullNumeric NullNumeric
1709
1710	type StringEmbedded struct {
1711		string
1712	}
1713	type NullStringEmbedded struct {
1714		NullString
1715	}
1716
1717	for i, test := range []struct {
1718		in   interface{}
1719		want decodableSpannerType
1720	}{
1721		{"foo", spannerTypeNonNullString},
1722		{[]byte("ab"), spannerTypeByteArray},
1723		{[]byte(nil), spannerTypeByteArray},
1724		{int64(123), spannerTypeNonNullInt64},
1725		{true, spannerTypeNonNullBool},
1726		{3.14, spannerTypeNonNullFloat64},
1727		{time.Now(), spannerTypeNonNullTime},
1728		{civil.DateOf(time.Now()), spannerTypeNonNullDate},
1729		{NullString{}, spannerTypeNullString},
1730		{NullInt64{}, spannerTypeNullInt64},
1731		{NullBool{}, spannerTypeNullBool},
1732		{NullFloat64{}, spannerTypeNullFloat64},
1733		{NullTime{}, spannerTypeNullTime},
1734		{NullDate{}, spannerTypeNullDate},
1735		{*big.NewRat(1234, 1000), spannerTypeNonNullNumeric},
1736		{big.Rat{}, spannerTypeNonNullNumeric},
1737		{NullNumeric{}, spannerTypeNullNumeric},
1738
1739		{[]string{"foo", "bar"}, spannerTypeArrayOfNonNullString},
1740		{[][]byte{{1, 2, 3}, {3, 2, 1}}, spannerTypeArrayOfByteArray},
1741		{[][]byte{}, spannerTypeArrayOfByteArray},
1742		{[]int64{int64(123)}, spannerTypeArrayOfNonNullInt64},
1743		{[]bool{true}, spannerTypeArrayOfNonNullBool},
1744		{[]float64{3.14}, spannerTypeArrayOfNonNullFloat64},
1745		{[]time.Time{time.Now()}, spannerTypeArrayOfNonNullTime},
1746		{[]civil.Date{civil.DateOf(time.Now())}, spannerTypeArrayOfNonNullDate},
1747		{[]NullString{}, spannerTypeArrayOfNullString},
1748		{[]NullInt64{}, spannerTypeArrayOfNullInt64},
1749		{[]NullBool{}, spannerTypeArrayOfNullBool},
1750		{[]NullFloat64{}, spannerTypeArrayOfNullFloat64},
1751		{[]NullTime{}, spannerTypeArrayOfNullTime},
1752		{[]NullDate{}, spannerTypeArrayOfNullDate},
1753		{[]big.Rat{}, spannerTypeArrayOfNonNullNumeric},
1754		{[]big.Rat{*big.NewRat(1234, 1000), *big.NewRat(1234, 100)}, spannerTypeArrayOfNonNullNumeric},
1755		{[]NullNumeric{}, spannerTypeArrayOfNullNumeric},
1756
1757		{CustomString("foo"), spannerTypeNonNullString},
1758		{CustomInt64(-100), spannerTypeNonNullInt64},
1759		{CustomBool(true), spannerTypeNonNullBool},
1760		{CustomFloat64(3.141592), spannerTypeNonNullFloat64},
1761		{CustomTime(time.Now()), spannerTypeNonNullTime},
1762		{CustomDate(civil.DateOf(time.Now())), spannerTypeNonNullDate},
1763		{CustomNumeric(*big.NewRat(1234, 1000)), spannerTypeNonNullNumeric},
1764
1765		{[]CustomString{}, spannerTypeArrayOfNonNullString},
1766		{[]CustomInt64{}, spannerTypeArrayOfNonNullInt64},
1767		{[]CustomBool{}, spannerTypeArrayOfNonNullBool},
1768		{[]CustomFloat64{}, spannerTypeArrayOfNonNullFloat64},
1769		{[]CustomTime{}, spannerTypeArrayOfNonNullTime},
1770		{[]CustomDate{}, spannerTypeArrayOfNonNullDate},
1771		{[]CustomNumeric{}, spannerTypeArrayOfNonNullNumeric},
1772
1773		{CustomNullString{}, spannerTypeNullString},
1774		{CustomNullInt64{}, spannerTypeNullInt64},
1775		{CustomNullBool{}, spannerTypeNullBool},
1776		{CustomNullFloat64{}, spannerTypeNullFloat64},
1777		{CustomNullTime{}, spannerTypeNullTime},
1778		{CustomNullDate{}, spannerTypeNullDate},
1779		{CustomNullNumeric{}, spannerTypeNullNumeric},
1780
1781		{[]CustomNullString{}, spannerTypeArrayOfNullString},
1782		{[]CustomNullInt64{}, spannerTypeArrayOfNullInt64},
1783		{[]CustomNullBool{}, spannerTypeArrayOfNullBool},
1784		{[]CustomNullFloat64{}, spannerTypeArrayOfNullFloat64},
1785		{[]CustomNullTime{}, spannerTypeArrayOfNullTime},
1786		{[]CustomNullDate{}, spannerTypeArrayOfNullDate},
1787		{[]CustomNullNumeric{}, spannerTypeArrayOfNullNumeric},
1788
1789		{StringEmbedded{}, spannerTypeUnknown},
1790		{NullStringEmbedded{}, spannerTypeUnknown},
1791	} {
1792		// Pass a pointer to the original value.
1793		gotp := reflect.New(reflect.TypeOf(test.in))
1794		got := getDecodableSpannerType(gotp.Interface(), true)
1795		if got != test.want {
1796			t.Errorf("%d: unexpected decodable type from a pointer - got %v, want %v", i, got, test.want)
1797		}
1798
1799		// Pass the original value.
1800		got = getDecodableSpannerType(test.in, false)
1801		if got != test.want {
1802			t.Errorf("%d: unexpected decodable type from a value - got %v, want %v", i, got, test.want)
1803		}
1804	}
1805}
1806
1807// Test NaN encoding/decoding.
1808func TestNaN(t *testing.T) {
1809	// Decode NaN value.
1810	f := 0.0
1811	nf := NullFloat64{}
1812	// To float64
1813	if err := decodeValue(floatProto(math.NaN()), floatType(), &f); err != nil {
1814		t.Errorf("decodeValue returns %q for %v, want nil", err, floatProto(math.NaN()))
1815	}
1816	if !math.IsNaN(f) {
1817		t.Errorf("f = %v, want %v", f, math.NaN())
1818	}
1819	// To NullFloat64
1820	if err := decodeValue(floatProto(math.NaN()), floatType(), &nf); err != nil {
1821		t.Errorf("decodeValue returns %q for %v, want nil", err, floatProto(math.NaN()))
1822	}
1823	if !math.IsNaN(nf.Float64) || !nf.Valid {
1824		t.Errorf("f = %v, want %v", f, NullFloat64{math.NaN(), true})
1825	}
1826	// Encode NaN value
1827	// From float64
1828	v, _, err := encodeValue(math.NaN())
1829	if err != nil {
1830		t.Errorf("encodeValue returns %q for NaN, want nil", err)
1831	}
1832	x, ok := v.GetKind().(*proto3.Value_NumberValue)
1833	if !ok {
1834		t.Errorf("incorrect type for v.GetKind(): %T, want *proto3.Value_NumberValue", v.GetKind())
1835	}
1836	if !math.IsNaN(x.NumberValue) {
1837		t.Errorf("x.NumberValue = %v, want %v", x.NumberValue, math.NaN())
1838	}
1839	// From NullFloat64
1840	v, _, err = encodeValue(NullFloat64{math.NaN(), true})
1841	if err != nil {
1842		t.Errorf("encodeValue returns %q for NaN, want nil", err)
1843	}
1844	x, ok = v.GetKind().(*proto3.Value_NumberValue)
1845	if !ok {
1846		t.Errorf("incorrect type for v.GetKind(): %T, want *proto3.Value_NumberValue", v.GetKind())
1847	}
1848	if !math.IsNaN(x.NumberValue) {
1849		t.Errorf("x.NumberValue = %v, want %v", x.NumberValue, math.NaN())
1850	}
1851}
1852
1853func TestGenericColumnValue(t *testing.T) {
1854	for _, test := range []struct {
1855		in   GenericColumnValue
1856		want interface{}
1857		fail bool
1858	}{
1859		{GenericColumnValue{stringType(), stringProto("abc")}, "abc", false},
1860		{GenericColumnValue{stringType(), stringProto("abc")}, 5, true},
1861		{GenericColumnValue{listType(intType()), listProto(intProto(91), nullProto(), intProto(87))}, []NullInt64{{91, true}, {}, {87, true}}, false},
1862		{GenericColumnValue{intType(), intProto(42)}, GenericColumnValue{intType(), intProto(42)}, false}, // trippy! :-)
1863	} {
1864		gotp := reflect.New(reflect.TypeOf(test.want))
1865		if err := test.in.Decode(gotp.Interface()); err != nil {
1866			if !test.fail {
1867				t.Errorf("cannot decode %v to %v: %v", test.in, test.want, err)
1868			}
1869			continue
1870		}
1871		if test.fail {
1872			t.Errorf("decoding %v to %v succeeds unexpectedly", test.in, test.want)
1873		}
1874
1875		// Test we can go backwards as well.
1876		v, err := newGenericColumnValue(test.want)
1877		if err != nil {
1878			t.Errorf("NewGenericColumnValue failed: %v", err)
1879			continue
1880		}
1881		if !testEqual(*v, test.in) {
1882			t.Errorf("unexpected encode result - got %v, want %v", v, test.in)
1883		}
1884	}
1885}
1886
1887func TestDecodeStruct(t *testing.T) {
1888	type CustomString string
1889	type CustomTime time.Time
1890	stype := &sppb.StructType{Fields: []*sppb.StructType_Field{
1891		{Name: "Id", Type: stringType()},
1892		{Name: "Time", Type: timeType()},
1893	}}
1894	lv := listValueProto(stringProto("id"), timeProto(t1))
1895
1896	type (
1897		S1 struct {
1898			ID   string
1899			Time time.Time
1900		}
1901		S2 struct {
1902			ID   string
1903			Time string
1904		}
1905		S3 struct {
1906			ID   CustomString
1907			Time CustomTime
1908		}
1909		S4 struct {
1910			ID   CustomString
1911			Time CustomString
1912		}
1913		S5 struct {
1914			NullString
1915			Time CustomTime
1916		}
1917	)
1918	var (
1919		s1 S1
1920		s2 S2
1921		s3 S3
1922		s4 S4
1923		s5 S5
1924	)
1925
1926	for _, test := range []struct {
1927		desc string
1928		ptr  interface{}
1929		want interface{}
1930		fail bool
1931	}{
1932		{
1933			desc: "decode to S1",
1934			ptr:  &s1,
1935			want: &S1{ID: "id", Time: t1},
1936		},
1937		{
1938			desc: "decode to S2",
1939			ptr:  &s2,
1940			fail: true,
1941		},
1942		{
1943			desc: "decode to S3",
1944			ptr:  &s3,
1945			want: &S3{ID: CustomString("id"), Time: CustomTime(t1)},
1946		},
1947		{
1948			desc: "decode to S4",
1949			ptr:  &s4,
1950			fail: true,
1951		},
1952		{
1953			desc: "decode to S5",
1954			ptr:  &s5,
1955			fail: true,
1956		},
1957	} {
1958		err := decodeStruct(stype, lv, test.ptr)
1959		if (err != nil) != test.fail {
1960			t.Errorf("%s: got error %v, wanted fail: %v", test.desc, err, test.fail)
1961		}
1962		if err == nil {
1963			if !testutil.Equal(test.ptr, test.want, cmp.AllowUnexported(CustomTime{})) {
1964				t.Errorf("%s: got %+v, want %+v", test.desc, test.ptr, test.want)
1965			}
1966		}
1967	}
1968}
1969
1970func TestDecodeStructWithPointers(t *testing.T) {
1971	stype := &sppb.StructType{Fields: []*sppb.StructType_Field{
1972		{Name: "Str", Type: stringType()},
1973		{Name: "Int", Type: intType()},
1974		{Name: "Bool", Type: boolType()},
1975		{Name: "Float", Type: floatType()},
1976		{Name: "Time", Type: timeType()},
1977		{Name: "Date", Type: dateType()},
1978		{Name: "StrArray", Type: listType(stringType())},
1979		{Name: "IntArray", Type: listType(intType())},
1980		{Name: "BoolArray", Type: listType(boolType())},
1981		{Name: "FloatArray", Type: listType(floatType())},
1982		{Name: "TimeArray", Type: listType(timeType())},
1983		{Name: "DateArray", Type: listType(dateType())},
1984	}}
1985	lv := []*proto3.ListValue{
1986		listValueProto(
1987			stringProto("id"),
1988			intProto(15),
1989			boolProto(true),
1990			floatProto(3.14),
1991			timeProto(t1),
1992			dateProto(d1),
1993			listProto(stringProto("id1"), nullProto(), stringProto("id2")),
1994			listProto(intProto(16), nullProto(), intProto(17)),
1995			listProto(boolProto(true), nullProto(), boolProto(false)),
1996			listProto(floatProto(3.14), nullProto(), floatProto(6.626)),
1997			listProto(timeProto(t1), nullProto(), timeProto(t2)),
1998			listProto(dateProto(d1), nullProto(), dateProto(d2)),
1999		),
2000		listValueProto(
2001			nullProto(),
2002			nullProto(),
2003			nullProto(),
2004			nullProto(),
2005			nullProto(),
2006			nullProto(),
2007			nullProto(),
2008			nullProto(),
2009			nullProto(),
2010			nullProto(),
2011			nullProto(),
2012			nullProto(),
2013		),
2014	}
2015
2016	type S1 struct {
2017		Str        *string
2018		Int        *int64
2019		Bool       *bool
2020		Float      *float64
2021		Time       *time.Time
2022		Date       *civil.Date
2023		StrArray   []*string
2024		IntArray   []*int64
2025		BoolArray  []*bool
2026		FloatArray []*float64
2027		TimeArray  []*time.Time
2028		DateArray  []*civil.Date
2029	}
2030	var s1 S1
2031	sValue := "id"
2032	iValue := int64(15)
2033	bValue := true
2034	fValue := 3.14
2035	tValue := t1
2036	dValue := d1
2037	sArrayValue1 := "id1"
2038	sArrayValue2 := "id2"
2039	sArrayValue := []*string{&sArrayValue1, nil, &sArrayValue2}
2040	iArrayValue1 := int64(16)
2041	iArrayValue2 := int64(17)
2042	iArrayValue := []*int64{&iArrayValue1, nil, &iArrayValue2}
2043	bArrayValue1 := true
2044	bArrayValue2 := false
2045	bArrayValue := []*bool{&bArrayValue1, nil, &bArrayValue2}
2046	f1Value := 3.14
2047	f2Value := 6.626
2048	fArrayValue := []*float64{&f1Value, nil, &f2Value}
2049	t1Value := t1
2050	t2Value := t2
2051	tArrayValue := []*time.Time{&t1Value, nil, &t2Value}
2052	d1Value := d1
2053	d2Value := d2
2054	dArrayValue := []*civil.Date{&d1Value, nil, &d2Value}
2055
2056	for i, test := range []struct {
2057		desc string
2058		ptr  *S1
2059		want *S1
2060		fail bool
2061	}{
2062		{
2063			desc: "decode values to S1",
2064			ptr:  &s1,
2065			want: &S1{Str: &sValue, Int: &iValue, Bool: &bValue, Float: &fValue, Time: &tValue, Date: &dValue, StrArray: sArrayValue, IntArray: iArrayValue, BoolArray: bArrayValue, FloatArray: fArrayValue, TimeArray: tArrayValue, DateArray: dArrayValue},
2066		},
2067		{
2068			desc: "decode nulls to S1",
2069			ptr:  &s1,
2070			want: &S1{Str: nil, Int: nil, Bool: nil, Float: nil, Time: nil, Date: nil, StrArray: nil, IntArray: nil, BoolArray: nil, FloatArray: nil, TimeArray: nil, DateArray: nil},
2071		},
2072	} {
2073		err := decodeStruct(stype, lv[i], test.ptr)
2074		if (err != nil) != test.fail {
2075			t.Errorf("%s: got error %v, wanted fail: %v", test.desc, err, test.fail)
2076		}
2077		if err == nil {
2078			if !testutil.Equal(test.ptr, test.want) {
2079				t.Errorf("%s: got %+v, want %+v", test.desc, test.ptr, test.want)
2080			}
2081		}
2082	}
2083}
2084
2085func TestEncodeStructValueDynamicStructs(t *testing.T) {
2086	dynStructType := reflect.StructOf([]reflect.StructField{
2087		{Name: "A", Type: reflect.TypeOf(0), Tag: `spanner:"a"`},
2088		{Name: "B", Type: reflect.TypeOf(""), Tag: `spanner:"b"`},
2089	})
2090	dynNullableStructType := reflect.PtrTo(dynStructType)
2091	dynStructArrType := reflect.SliceOf(dynStructType)
2092	dynNullableStructArrType := reflect.SliceOf(dynNullableStructType)
2093
2094	dynStructValue := reflect.New(dynStructType)
2095	dynStructValue.Elem().Field(0).SetInt(10)
2096	dynStructValue.Elem().Field(1).SetString("abc")
2097
2098	dynStructArrValue := reflect.MakeSlice(dynNullableStructArrType, 2, 2)
2099	dynStructArrValue.Index(0).Set(reflect.Zero(dynNullableStructType))
2100	dynStructArrValue.Index(1).Set(dynStructValue)
2101
2102	structProtoType := structType(
2103		mkField("a", intType()),
2104		mkField("b", stringType()))
2105
2106	arrProtoType := listType(structProtoType)
2107
2108	for _, test := range []encodeTest{
2109		{
2110			"Dynanic non-NULL struct value.",
2111			dynStructValue.Elem().Interface(),
2112			listProto(intProto(10), stringProto("abc")),
2113			structProtoType,
2114		},
2115		{
2116			"Dynanic NULL struct value.",
2117			reflect.Zero(dynNullableStructType).Interface(),
2118			nullProto(),
2119			structProtoType,
2120		},
2121		{
2122			"Empty array of dynamic structs.",
2123			reflect.MakeSlice(dynStructArrType, 0, 0).Interface(),
2124			listProto([]*proto3.Value{}...),
2125			arrProtoType,
2126		},
2127		{
2128			"NULL array of non-NULL-able dynamic structs.",
2129			reflect.Zero(dynStructArrType).Interface(),
2130			nullProto(),
2131			arrProtoType,
2132		},
2133		{
2134			"NULL array of NULL-able(nil) dynamic structs.",
2135			reflect.Zero(dynNullableStructArrType).Interface(),
2136			nullProto(),
2137			arrProtoType,
2138		},
2139		{
2140			"Array containing NULL(nil) dynamic-typed struct elements.",
2141			dynStructArrValue.Interface(),
2142			listProto(
2143				nullProto(),
2144				listProto(intProto(10), stringProto("abc"))),
2145			arrProtoType,
2146		},
2147	} {
2148		encodeStructValue(test, t)
2149	}
2150}
2151
2152func TestEncodeStructValueEmptyStruct(t *testing.T) {
2153	emptyListValue := listProto([]*proto3.Value{}...)
2154	emptyStructType := structType([]*sppb.StructType_Field{}...)
2155	emptyStruct := struct{}{}
2156	nullEmptyStruct := (*struct{})(nil)
2157
2158	dynamicEmptyStructType := reflect.StructOf(make([]reflect.StructField, 0, 0))
2159	dynamicStructArrType := reflect.SliceOf(reflect.PtrTo((dynamicEmptyStructType)))
2160
2161	dynamicEmptyStruct := reflect.New(dynamicEmptyStructType)
2162	dynamicNullEmptyStruct := reflect.Zero(reflect.PtrTo(dynamicEmptyStructType))
2163
2164	dynamicStructArrValue := reflect.MakeSlice(dynamicStructArrType, 2, 2)
2165	dynamicStructArrValue.Index(0).Set(dynamicNullEmptyStruct)
2166	dynamicStructArrValue.Index(1).Set(dynamicEmptyStruct)
2167
2168	for _, test := range []encodeTest{
2169		{
2170			"Go empty struct.",
2171			emptyStruct,
2172			emptyListValue,
2173			emptyStructType,
2174		},
2175		{
2176			"Dynamic empty struct.",
2177			dynamicEmptyStruct.Interface(),
2178			emptyListValue,
2179			emptyStructType,
2180		},
2181		{
2182			"Go NULL empty struct.",
2183			nullEmptyStruct,
2184			nullProto(),
2185			emptyStructType,
2186		},
2187		{
2188			"Dynamic NULL empty struct.",
2189			dynamicNullEmptyStruct.Interface(),
2190			nullProto(),
2191			emptyStructType,
2192		},
2193		{
2194			"Non-empty array of dynamic NULL and non-NULL empty structs.",
2195			dynamicStructArrValue.Interface(),
2196			listProto(nullProto(), emptyListValue),
2197			listType(emptyStructType),
2198		},
2199		{
2200			"Non-empty array of nullable empty structs.",
2201			[]*struct{}{nullEmptyStruct, &emptyStruct},
2202			listProto(nullProto(), emptyListValue),
2203			listType(emptyStructType),
2204		},
2205		{
2206			"Empty array of empty struct.",
2207			[]struct{}{},
2208			emptyListValue,
2209			listType(emptyStructType),
2210		},
2211		{
2212			"Null array of empty structs.",
2213			[]struct{}(nil),
2214			nullProto(),
2215			listType(emptyStructType),
2216		},
2217	} {
2218		encodeStructValue(test, t)
2219	}
2220}
2221
2222func TestEncodeStructValueMixedStructTypes(t *testing.T) {
2223	type staticStruct struct {
2224		F int `spanner:"fStatic"`
2225	}
2226	s1 := staticStruct{10}
2227	s2 := (*staticStruct)(nil)
2228
2229	var f float64
2230	dynStructType := reflect.StructOf([]reflect.StructField{
2231		{Name: "A", Type: reflect.TypeOf(f), Tag: `spanner:"fDynamic"`},
2232	})
2233	s3 := reflect.New(dynStructType)
2234	s3.Elem().Field(0).SetFloat(3.14)
2235
2236	for _, test := range []encodeTest{
2237		{
2238			"'struct' with static and dynamic *struct, []*struct, []struct fields",
2239			struct {
2240				A []staticStruct
2241				B []*staticStruct
2242				C interface{}
2243			}{
2244				[]staticStruct{s1, s1},
2245				[]*staticStruct{&s1, s2},
2246				s3.Interface(),
2247			},
2248			listProto(
2249				listProto(listProto(intProto(10)), listProto(intProto(10))),
2250				listProto(listProto(intProto(10)), nullProto()),
2251				listProto(floatProto(3.14))),
2252			structType(
2253				mkField("A", listType(structType(mkField("fStatic", intType())))),
2254				mkField("B", listType(structType(mkField("fStatic", intType())))),
2255				mkField("C", structType(mkField("fDynamic", floatType())))),
2256		},
2257	} {
2258		encodeStructValue(test, t)
2259	}
2260}
2261
2262func TestBindParamsDynamic(t *testing.T) {
2263	// Verify Statement.bindParams generates correct values and types.
2264	st := Statement{
2265		SQL:    "SELECT id from t_foo WHERE col = @var",
2266		Params: map[string]interface{}{"var": nil},
2267	}
2268	want := &sppb.ExecuteSqlRequest{
2269		Params: &proto3.Struct{
2270			Fields: map[string]*proto3.Value{"var": nil},
2271		},
2272		ParamTypes: map[string]*sppb.Type{"var": nil},
2273	}
2274	var (
2275		t1, _ = time.Parse(time.RFC3339Nano, "2016-11-15T15:04:05.999999999Z")
2276		// Boundaries
2277		t2, _ = time.Parse(time.RFC3339Nano, "0001-01-01T00:00:00.000000000Z")
2278	)
2279	dynamicStructType := reflect.StructOf([]reflect.StructField{
2280		{Name: "A", Type: reflect.TypeOf(t1), Tag: `spanner:"field"`},
2281		{Name: "B", Type: reflect.TypeOf(3.14), Tag: `spanner:""`},
2282	})
2283	dynamicStructArrType := reflect.SliceOf(reflect.PtrTo(dynamicStructType))
2284	dynamicEmptyStructType := reflect.StructOf(make([]reflect.StructField, 0, 0))
2285
2286	dynamicStructTypeProto := structType(
2287		mkField("field", timeType()),
2288		mkField("", floatType()))
2289
2290	s3 := reflect.New(dynamicStructType)
2291	s3.Elem().Field(0).Set(reflect.ValueOf(t1))
2292	s3.Elem().Field(1).SetFloat(1.4)
2293
2294	s4 := reflect.New(dynamicStructType)
2295	s4.Elem().Field(0).Set(reflect.ValueOf(t2))
2296	s4.Elem().Field(1).SetFloat(-13.3)
2297
2298	dynamicStructArrayVal := reflect.MakeSlice(dynamicStructArrType, 2, 2)
2299	dynamicStructArrayVal.Index(0).Set(s3)
2300	dynamicStructArrayVal.Index(1).Set(s4)
2301
2302	for _, test := range []struct {
2303		val       interface{}
2304		wantField *proto3.Value
2305		wantType  *sppb.Type
2306	}{
2307		{
2308			s3.Interface(),
2309			listProto(timeProto(t1), floatProto(1.4)),
2310			structType(
2311				mkField("field", timeType()),
2312				mkField("", floatType())),
2313		},
2314		{
2315			reflect.Zero(reflect.PtrTo(dynamicEmptyStructType)).Interface(),
2316			nullProto(),
2317			structType([]*sppb.StructType_Field{}...),
2318		},
2319		{
2320			dynamicStructArrayVal.Interface(),
2321			listProto(
2322				listProto(timeProto(t1), floatProto(1.4)),
2323				listProto(timeProto(t2), floatProto(-13.3))),
2324			listType(dynamicStructTypeProto),
2325		},
2326		{
2327			[]*struct {
2328				F1 time.Time `spanner:"field"`
2329				F2 float64   `spanner:""`
2330			}{
2331				nil,
2332				{t1, 1.4},
2333			},
2334			listProto(
2335				nullProto(),
2336				listProto(timeProto(t1), floatProto(1.4))),
2337			listType(dynamicStructTypeProto),
2338		},
2339	} {
2340		st.Params["var"] = test.val
2341		want.Params.Fields["var"] = test.wantField
2342		want.ParamTypes["var"] = test.wantType
2343		gotParams, gotParamTypes, gotErr := st.convertParams()
2344		if gotErr != nil {
2345			t.Error(gotErr)
2346			continue
2347		}
2348		gotParamField := gotParams.Fields["var"]
2349		if !proto.Equal(gotParamField, test.wantField) {
2350			// handle NaN
2351			if test.wantType.Code == floatType().Code && proto.MarshalTextString(gotParamField) == proto.MarshalTextString(test.wantField) {
2352				continue
2353			}
2354			t.Errorf("%#v: got %v, want %v\n", test.val, gotParamField, test.wantField)
2355		}
2356		gotParamType := gotParamTypes["var"]
2357		if !proto.Equal(gotParamType, test.wantType) {
2358			t.Errorf("%#v: got %v, want %v\n", test.val, gotParamType, test.wantField)
2359		}
2360	}
2361}
2362
2363// Test converting nullable types to json strings.
2364func TestJSONMarshal_NullTypes(t *testing.T) {
2365	type testcase struct {
2366		input  interface{}
2367		expect string
2368	}
2369
2370	for _, test := range []struct {
2371		name  string
2372		cases []testcase
2373	}{
2374		{
2375			"NullString",
2376			[]testcase{
2377				{input: NullString{"this is a test string", true}, expect: `"this is a test string"`},
2378				{input: &NullString{"this is a test string", true}, expect: `"this is a test string"`},
2379				{input: &NullString{"this is a test string", false}, expect: "null"},
2380				{input: NullString{}, expect: "null"},
2381			},
2382		},
2383		{
2384			"NullInt64",
2385			[]testcase{
2386				{input: NullInt64{int64(123), true}, expect: "123"},
2387				{input: &NullInt64{int64(123), true}, expect: "123"},
2388				{input: &NullInt64{int64(123), false}, expect: "null"},
2389				{input: NullInt64{}, expect: "null"},
2390			},
2391		},
2392		{
2393			"NullFloat64",
2394			[]testcase{
2395				{input: NullFloat64{float64(123.123), true}, expect: "123.123"},
2396				{input: &NullFloat64{float64(123.123), true}, expect: "123.123"},
2397				{input: &NullFloat64{float64(123.123), false}, expect: "null"},
2398				{input: NullFloat64{}, expect: "null"},
2399			},
2400		},
2401		{
2402			"NullBool",
2403			[]testcase{
2404				{input: NullBool{true, true}, expect: "true"},
2405				{input: &NullBool{true, true}, expect: "true"},
2406				{input: &NullBool{true, false}, expect: "null"},
2407				{input: NullBool{}, expect: "null"},
2408			},
2409		},
2410		{
2411			"NullTime",
2412			[]testcase{
2413				{input: NullTime{time.Date(2009, 11, 17, 20, 34, 58, 651387237, time.UTC), true}, expect: `"2009-11-17T20:34:58.651387237Z"`},
2414				{input: &NullTime{time.Date(2009, 11, 17, 20, 34, 58, 651387237, time.UTC), true}, expect: `"2009-11-17T20:34:58.651387237Z"`},
2415				{input: &NullTime{time.Date(2009, 11, 17, 20, 34, 58, 651387237, time.UTC), false}, expect: "null"},
2416				{input: NullTime{}, expect: "null"},
2417			},
2418		},
2419		{
2420			"NullDate",
2421			[]testcase{
2422				{input: NullDate{civil.Date{Year: 2009, Month: time.November, Day: 17}, true}, expect: `"2009-11-17"`},
2423				{input: &NullDate{civil.Date{Year: 2009, Month: time.November, Day: 17}, true}, expect: `"2009-11-17"`},
2424				{input: &NullDate{civil.Date{Year: 2009, Month: time.November, Day: 17}, false}, expect: "null"},
2425				{input: NullDate{}, expect: "null"},
2426			},
2427		},
2428		{
2429			"NullNumeric",
2430			[]testcase{
2431				{input: NullNumeric{*big.NewRat(1234123456789, 1e9), true}, expect: `"1234.123456789"`},
2432				{input: &NullNumeric{*big.NewRat(1234123456789, 1e9), true}, expect: `"1234.123456789"`},
2433				{input: &NullNumeric{*big.NewRat(1234123456789, 1e9), false}, expect: "null"},
2434				{input: NullNumeric{}, expect: "null"},
2435			},
2436		},
2437	} {
2438		t.Run(test.name, func(t *testing.T) {
2439			for _, tc := range test.cases {
2440				bytes, _ := json.Marshal(tc.input)
2441				got := string(bytes)
2442				if got != tc.expect {
2443					t.Fatalf("Incorrect marshalling to json strings: got %v, want %v", got, tc.expect)
2444				}
2445			}
2446		})
2447	}
2448}
2449
2450// Test converting json strings to nullable types.
2451func TestJSONUnmarshal_NullTypes(t *testing.T) {
2452	type testcase struct {
2453		input       []byte
2454		got         interface{}
2455		isNull      bool
2456		expect      string
2457		expectError bool
2458	}
2459
2460	for _, test := range []struct {
2461		name  string
2462		cases []testcase
2463	}{
2464		{
2465			"NullString",
2466			[]testcase{
2467				{input: []byte(`"this is a test string"`), got: NullString{}, isNull: false, expect: "this is a test string", expectError: false},
2468				{input: []byte(`""`), got: NullString{}, isNull: false, expect: "", expectError: false},
2469				{input: []byte("null"), got: NullString{}, isNull: true, expect: nullString, expectError: false},
2470				{input: nil, got: NullString{}, isNull: true, expect: nullString, expectError: true},
2471				{input: []byte(""), got: NullString{}, isNull: true, expect: nullString, expectError: true},
2472				{input: []byte(`"hello`), got: NullString{}, isNull: true, expect: nullString, expectError: true},
2473			},
2474		},
2475		{
2476			"NullInt64",
2477			[]testcase{
2478				{input: []byte("123"), got: NullInt64{}, isNull: false, expect: "123", expectError: false},
2479				{input: []byte("null"), got: NullInt64{}, isNull: true, expect: nullString, expectError: false},
2480				{input: nil, got: NullInt64{}, isNull: true, expect: nullString, expectError: true},
2481				{input: []byte(""), got: NullInt64{}, isNull: true, expect: nullString, expectError: true},
2482				{input: []byte(`"hello`), got: NullInt64{}, isNull: true, expect: nullString, expectError: true},
2483			},
2484		},
2485		{
2486			"NullFloat64",
2487			[]testcase{
2488				{input: []byte("123.123"), got: NullFloat64{}, isNull: false, expect: "123.123", expectError: false},
2489				{input: []byte("null"), got: NullFloat64{}, isNull: true, expect: nullString, expectError: false},
2490				{input: nil, got: NullFloat64{}, isNull: true, expect: nullString, expectError: true},
2491				{input: []byte(""), got: NullFloat64{}, isNull: true, expect: nullString, expectError: true},
2492				{input: []byte(`"hello`), got: NullFloat64{}, isNull: true, expect: nullString, expectError: true},
2493			},
2494		},
2495		{
2496			"NullBool",
2497			[]testcase{
2498				{input: []byte("true"), got: NullBool{}, isNull: false, expect: "true", expectError: false},
2499				{input: []byte("null"), got: NullBool{}, isNull: true, expect: nullString, expectError: false},
2500				{input: nil, got: NullBool{}, isNull: true, expect: nullString, expectError: true},
2501				{input: []byte(""), got: NullBool{}, isNull: true, expect: nullString, expectError: true},
2502				{input: []byte(`"hello`), got: NullBool{}, isNull: true, expect: nullString, expectError: true},
2503			},
2504		},
2505		{
2506			"NullTime",
2507			[]testcase{
2508				{input: []byte(`"2009-11-17T20:34:58.651387237Z"`), got: NullTime{}, isNull: false, expect: "2009-11-17T20:34:58.651387237Z", expectError: false},
2509				{input: []byte("null"), got: NullTime{}, isNull: true, expect: nullString, expectError: false},
2510				{input: nil, got: NullTime{}, isNull: true, expect: nullString, expectError: true},
2511				{input: []byte(""), got: NullTime{}, isNull: true, expect: nullString, expectError: true},
2512				{input: []byte(`"hello`), got: NullTime{}, isNull: true, expect: nullString, expectError: true},
2513			},
2514		},
2515		{
2516			"NullDate",
2517			[]testcase{
2518				{input: []byte(`"2009-11-17"`), got: NullDate{}, isNull: false, expect: "2009-11-17", expectError: false},
2519				{input: []byte("null"), got: NullDate{}, isNull: true, expect: nullString, expectError: false},
2520				{input: nil, got: NullDate{}, isNull: true, expect: nullString, expectError: true},
2521				{input: []byte(""), got: NullDate{}, isNull: true, expect: nullString, expectError: true},
2522				{input: []byte(`"hello`), got: NullDate{}, isNull: true, expect: nullString, expectError: true},
2523			},
2524		},
2525		{
2526			"NullNumeric",
2527			[]testcase{
2528				{input: []byte(`"1234.123456789"`), got: NullNumeric{}, isNull: false, expect: "1234.123456789", expectError: false},
2529				{input: []byte("null"), got: NullNumeric{}, isNull: true, expect: nullString, expectError: false},
2530				{input: nil, got: NullNumeric{}, isNull: true, expect: nullString, expectError: true},
2531				{input: []byte(""), got: NullNumeric{}, isNull: true, expect: nullString, expectError: true},
2532				{input: []byte(`"1234.123456789`), got: NullNumeric{}, isNull: true, expect: nullString, expectError: true},
2533			},
2534		},
2535	} {
2536		t.Run(test.name, func(t *testing.T) {
2537			for _, tc := range test.cases {
2538				switch v := tc.got.(type) {
2539				case NullString:
2540					err := json.Unmarshal(tc.input, &v)
2541					expectUnmarshalNullableTypes(t, err, v, tc.isNull, tc.expect, tc.expectError)
2542				case NullInt64:
2543					err := json.Unmarshal(tc.input, &v)
2544					expectUnmarshalNullableTypes(t, err, v, tc.isNull, tc.expect, tc.expectError)
2545				case NullFloat64:
2546					err := json.Unmarshal(tc.input, &v)
2547					expectUnmarshalNullableTypes(t, err, v, tc.isNull, tc.expect, tc.expectError)
2548				case NullBool:
2549					err := json.Unmarshal(tc.input, &v)
2550					expectUnmarshalNullableTypes(t, err, v, tc.isNull, tc.expect, tc.expectError)
2551				case NullTime:
2552					err := json.Unmarshal(tc.input, &v)
2553					expectUnmarshalNullableTypes(t, err, v, tc.isNull, tc.expect, tc.expectError)
2554				case NullDate:
2555					err := json.Unmarshal(tc.input, &v)
2556					expectUnmarshalNullableTypes(t, err, v, tc.isNull, tc.expect, tc.expectError)
2557				case NullNumeric:
2558					err := json.Unmarshal(tc.input, &v)
2559					expectUnmarshalNullableTypes(t, err, v, tc.isNull, tc.expect, tc.expectError)
2560				default:
2561					t.Fatalf("Unknown type: %T", v)
2562				}
2563			}
2564		})
2565	}
2566}
2567
2568func expectUnmarshalNullableTypes(t *testing.T, err error, v interface{}, isNull bool, expect string, expectError bool) {
2569	if expectError {
2570		if err == nil {
2571			t.Fatalf("Expect to get an error, but got a nil")
2572		}
2573		return
2574	}
2575
2576	if err != nil {
2577		t.Fatalf("Got an error when unmarshalling a valid json string: %q", err)
2578	}
2579	if s, ok := v.(NullableValue); !ok || s.IsNull() != isNull {
2580		t.Fatalf("Incorrect unmarshalling a json string to nullable types: got %q, want %q", v, expect)
2581	}
2582	if s, ok := v.(fmt.Stringer); !ok || s.String() != expect {
2583		t.Fatalf("Incorrect unmarshalling a json string to nullable types: got %q, want %q", v, expect)
2584	}
2585}
2586