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