1/*
2Copyright 2017 Google LLC
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package spanner
18
19import (
20	"encoding/base64"
21	"fmt"
22	"math"
23	"reflect"
24	"strconv"
25	"time"
26
27	"cloud.google.com/go/civil"
28	"cloud.google.com/go/internal/fields"
29	proto "github.com/golang/protobuf/proto"
30	proto3 "github.com/golang/protobuf/ptypes/struct"
31	sppb "google.golang.org/genproto/googleapis/spanner/v1"
32	"google.golang.org/grpc/codes"
33)
34
35const commitTimestampPlaceholderString = "spanner.commit_timestamp()"
36
37var (
38	// CommitTimestamp is a special value used to tell Cloud Spanner
39	// to insert the commit timestamp of the transaction into a column.
40	// It can be used in a Mutation, or directly used in
41	// InsertStruct or InsertMap. See ExampleCommitTimestamp.
42	// This is just a placeholder and the actual value stored in this
43	// variable has no meaning.
44	CommitTimestamp = commitTimestamp
45	commitTimestamp = time.Unix(0, 0).In(time.FixedZone("CommitTimestamp placeholder", 0xDB))
46)
47
48// NullInt64 represents a Cloud Spanner INT64 that may be NULL.
49type NullInt64 struct {
50	Int64 int64
51	Valid bool // Valid is true if Int64 is not NULL.
52}
53
54// String implements Stringer.String for NullInt64
55func (n NullInt64) String() string {
56	if !n.Valid {
57		return fmt.Sprintf("%v", "<null>")
58	}
59	return fmt.Sprintf("%v", n.Int64)
60}
61
62// NullString represents a Cloud Spanner STRING that may be NULL.
63type NullString struct {
64	StringVal string
65	Valid     bool // Valid is true if StringVal is not NULL.
66}
67
68// String implements Stringer.String for NullString
69func (n NullString) String() string {
70	if !n.Valid {
71		return fmt.Sprintf("%v", "<null>")
72	}
73	return fmt.Sprintf("%q", n.StringVal)
74}
75
76// NullFloat64 represents a Cloud Spanner FLOAT64 that may be NULL.
77type NullFloat64 struct {
78	Float64 float64
79	Valid   bool // Valid is true if Float64 is not NULL.
80}
81
82// Cloud Spanner STRUCT (aka STRUCT) values (https://cloud.google.com/spanner/docs/data-types#struct-type)
83// can be represented by a Go struct value.
84// The spanner.StructType  of such values is built from the field types and field tag information
85// of the Go struct. If a field in the struct type definition has a "spanner:<field_name>" tag,
86// then the value of the "spanner" key in the tag is used as the name for that field in the
87// built spanner.StructType, otherwise the field name in the struct definition is used. To specify a
88// field with an empty field name in a Cloud Spanner STRUCT type, use the `spanner:""` tag
89// annotation against the corresponding field in the Go struct's type definition.
90//
91// A STRUCT value can contain STRUCT-typed and Array-of-STRUCT typed fields and these can be
92// specified using named struct-typed and []struct-typed fields inside a Go struct. However,
93// embedded struct fields are not allowed. Unexported struct fields are ignored.
94//
95// NULL STRUCT values in Cloud Spanner are typed. A nil pointer to a Go struct value can be used to
96// specify a NULL STRUCT value of the corresponding spanner.StructType.  Nil and empty slices of a
97// Go STRUCT type can be used to specify NULL and empty array values respectively of the
98// corresponding spanner.StructType. A slice of pointers to a Go struct type can be used to specify
99// an array of NULL-able STRUCT values.
100
101// String implements Stringer.String for NullFloat64
102func (n NullFloat64) String() string {
103	if !n.Valid {
104		return fmt.Sprintf("%v", "<null>")
105	}
106	return fmt.Sprintf("%v", n.Float64)
107}
108
109// NullBool represents a Cloud Spanner BOOL that may be NULL.
110type NullBool struct {
111	Bool  bool
112	Valid bool // Valid is true if Bool is not NULL.
113}
114
115// String implements Stringer.String for NullBool
116func (n NullBool) String() string {
117	if !n.Valid {
118		return fmt.Sprintf("%v", "<null>")
119	}
120	return fmt.Sprintf("%v", n.Bool)
121}
122
123// NullTime represents a Cloud Spanner TIMESTAMP that may be null.
124type NullTime struct {
125	Time  time.Time
126	Valid bool // Valid is true if Time is not NULL.
127}
128
129// String implements Stringer.String for NullTime
130func (n NullTime) String() string {
131	if !n.Valid {
132		return "<null>"
133	}
134	return fmt.Sprintf("%q", n.Time.Format(time.RFC3339Nano))
135}
136
137// NullDate represents a Cloud Spanner DATE that may be null.
138type NullDate struct {
139	Date  civil.Date
140	Valid bool // Valid is true if Date is not NULL.
141}
142
143// String implements Stringer.String for NullDate
144func (n NullDate) String() string {
145	if !n.Valid {
146		return "<null>"
147	}
148	return fmt.Sprintf("%q", n.Date)
149}
150
151// NullRow represents a Cloud Spanner STRUCT that may be NULL.
152// See also the document for Row.
153// Note that NullRow is not a valid Cloud Spanner column Type.
154type NullRow struct {
155	Row   Row
156	Valid bool // Valid is true if Row is not NULL.
157}
158
159// GenericColumnValue represents the generic encoded value and type of the
160// column.  See google.spanner.v1.ResultSet proto for details.  This can be
161// useful for proxying query results when the result types are not known in
162// advance.
163//
164// If you populate a GenericColumnValue from a row using Row.Column or related
165// methods, do not modify the contents of Type and Value.
166type GenericColumnValue struct {
167	Type  *sppb.Type
168	Value *proto3.Value
169}
170
171// Decode decodes a GenericColumnValue. The ptr argument should be a pointer
172// to a Go value that can accept v.
173func (v GenericColumnValue) Decode(ptr interface{}) error {
174	return decodeValue(v.Value, v.Type, ptr)
175}
176
177// NewGenericColumnValue creates a GenericColumnValue from Go value that is
178// valid for Cloud Spanner.
179func newGenericColumnValue(v interface{}) (*GenericColumnValue, error) {
180	value, typ, err := encodeValue(v)
181	if err != nil {
182		return nil, err
183	}
184	return &GenericColumnValue{Value: value, Type: typ}, nil
185}
186
187// errTypeMismatch returns error for destination not having a compatible type
188// with source Cloud Spanner type.
189func errTypeMismatch(srcCode, elCode sppb.TypeCode, dst interface{}) error {
190	s := srcCode.String()
191	if srcCode == sppb.TypeCode_ARRAY {
192		s = fmt.Sprintf("%v[%v]", srcCode, elCode)
193	}
194	return spannerErrorf(codes.InvalidArgument, "type %T cannot be used for decoding %s", dst, s)
195}
196
197// errNilSpannerType returns error for nil Cloud Spanner type in decoding.
198func errNilSpannerType() error {
199	return spannerErrorf(codes.FailedPrecondition, "unexpected nil Cloud Spanner data type in decoding")
200}
201
202// errNilSrc returns error for decoding from nil proto value.
203func errNilSrc() error {
204	return spannerErrorf(codes.FailedPrecondition, "unexpected nil Cloud Spanner value in decoding")
205}
206
207// errNilDst returns error for decoding into nil interface{}.
208func errNilDst(dst interface{}) error {
209	return spannerErrorf(codes.InvalidArgument, "cannot decode into nil type %T", dst)
210}
211
212// errNilArrElemType returns error for input Cloud Spanner data type being a array but without a
213// non-nil array element type.
214func errNilArrElemType(t *sppb.Type) error {
215	return spannerErrorf(codes.FailedPrecondition, "array type %v is with nil array element type", t)
216}
217
218func errUnsupportedEmbeddedStructFields(fname string) error {
219	return spannerErrorf(codes.InvalidArgument, "Embedded field: %s. Embedded and anonymous fields are not allowed "+
220		"when converting Go structs to Cloud Spanner STRUCT values. To create a STRUCT value with an "+
221		"unnamed field, use a `spanner:\"\"` field tag.", fname)
222}
223
224// errDstNotForNull returns error for decoding a SQL NULL value into a destination which doesn't
225// support NULL values.
226func errDstNotForNull(dst interface{}) error {
227	return spannerErrorf(codes.InvalidArgument, "destination %T cannot support NULL SQL values", dst)
228}
229
230// errBadEncoding returns error for decoding wrongly encoded types.
231func errBadEncoding(v *proto3.Value, err error) error {
232	return spannerErrorf(codes.FailedPrecondition, "%v wasn't correctly encoded: <%v>", v, err)
233}
234
235func parseNullTime(v *proto3.Value, p *NullTime, code sppb.TypeCode, isNull bool) error {
236	if p == nil {
237		return errNilDst(p)
238	}
239	if code != sppb.TypeCode_TIMESTAMP {
240		return errTypeMismatch(code, sppb.TypeCode_TYPE_CODE_UNSPECIFIED, p)
241	}
242	if isNull {
243		*p = NullTime{}
244		return nil
245	}
246	x, err := getStringValue(v)
247	if err != nil {
248		return err
249	}
250	y, err := time.Parse(time.RFC3339Nano, x)
251	if err != nil {
252		return errBadEncoding(v, err)
253	}
254	p.Valid = true
255	p.Time = y
256	return nil
257}
258
259// decodeValue decodes a protobuf Value into a pointer to a Go value, as
260// specified by sppb.Type.
261func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}) error {
262	if v == nil {
263		return errNilSrc()
264	}
265	if t == nil {
266		return errNilSpannerType()
267	}
268	code := t.Code
269	acode := sppb.TypeCode_TYPE_CODE_UNSPECIFIED
270	if code == sppb.TypeCode_ARRAY {
271		if t.ArrayElementType == nil {
272			return errNilArrElemType(t)
273		}
274		acode = t.ArrayElementType.Code
275	}
276	_, isNull := v.Kind.(*proto3.Value_NullValue)
277
278	// Do the decoding based on the type of ptr.
279	switch p := ptr.(type) {
280	case nil:
281		return errNilDst(nil)
282	case *string:
283		if p == nil {
284			return errNilDst(p)
285		}
286		if code != sppb.TypeCode_STRING {
287			return errTypeMismatch(code, acode, ptr)
288		}
289		if isNull {
290			return errDstNotForNull(ptr)
291		}
292		x, err := getStringValue(v)
293		if err != nil {
294			return err
295		}
296		*p = x
297	case *NullString:
298		if p == nil {
299			return errNilDst(p)
300		}
301		if code != sppb.TypeCode_STRING {
302			return errTypeMismatch(code, acode, ptr)
303		}
304		if isNull {
305			*p = NullString{}
306			break
307		}
308		x, err := getStringValue(v)
309		if err != nil {
310			return err
311		}
312		p.Valid = true
313		p.StringVal = x
314	case *[]NullString:
315		if p == nil {
316			return errNilDst(p)
317		}
318		if acode != sppb.TypeCode_STRING {
319			return errTypeMismatch(code, acode, ptr)
320		}
321		if isNull {
322			*p = nil
323			break
324		}
325		x, err := getListValue(v)
326		if err != nil {
327			return err
328		}
329		y, err := decodeNullStringArray(x)
330		if err != nil {
331			return err
332		}
333		*p = y
334	case *[]string:
335		if p == nil {
336			return errNilDst(p)
337		}
338		if acode != sppb.TypeCode_STRING {
339			return errTypeMismatch(code, acode, ptr)
340		}
341		if isNull {
342			*p = nil
343			break
344		}
345		x, err := getListValue(v)
346		if err != nil {
347			return err
348		}
349		y, err := decodeStringArray(x)
350		if err != nil {
351			return err
352		}
353		*p = y
354	case *[]byte:
355		if p == nil {
356			return errNilDst(p)
357		}
358		if code != sppb.TypeCode_BYTES {
359			return errTypeMismatch(code, acode, ptr)
360		}
361		if isNull {
362			*p = nil
363			break
364		}
365		x, err := getStringValue(v)
366		if err != nil {
367			return err
368		}
369		y, err := base64.StdEncoding.DecodeString(x)
370		if err != nil {
371			return errBadEncoding(v, err)
372		}
373		*p = y
374	case *[][]byte:
375		if p == nil {
376			return errNilDst(p)
377		}
378		if acode != sppb.TypeCode_BYTES {
379			return errTypeMismatch(code, acode, ptr)
380		}
381		if isNull {
382			*p = nil
383			break
384		}
385		x, err := getListValue(v)
386		if err != nil {
387			return err
388		}
389		y, err := decodeByteArray(x)
390		if err != nil {
391			return err
392		}
393		*p = y
394	case *int64:
395		if p == nil {
396			return errNilDst(p)
397		}
398		if code != sppb.TypeCode_INT64 {
399			return errTypeMismatch(code, acode, ptr)
400		}
401		if isNull {
402			return errDstNotForNull(ptr)
403		}
404		x, err := getStringValue(v)
405		if err != nil {
406			return err
407		}
408		y, err := strconv.ParseInt(x, 10, 64)
409		if err != nil {
410			return errBadEncoding(v, err)
411		}
412		*p = y
413	case *NullInt64:
414		if p == nil {
415			return errNilDst(p)
416		}
417		if code != sppb.TypeCode_INT64 {
418			return errTypeMismatch(code, acode, ptr)
419		}
420		if isNull {
421			*p = NullInt64{}
422			break
423		}
424		x, err := getStringValue(v)
425		if err != nil {
426			return err
427		}
428		y, err := strconv.ParseInt(x, 10, 64)
429		if err != nil {
430			return errBadEncoding(v, err)
431		}
432		p.Valid = true
433		p.Int64 = y
434	case *[]NullInt64:
435		if p == nil {
436			return errNilDst(p)
437		}
438		if acode != sppb.TypeCode_INT64 {
439			return errTypeMismatch(code, acode, ptr)
440		}
441		if isNull {
442			*p = nil
443			break
444		}
445		x, err := getListValue(v)
446		if err != nil {
447			return err
448		}
449		y, err := decodeNullInt64Array(x)
450		if err != nil {
451			return err
452		}
453		*p = y
454	case *[]int64:
455		if p == nil {
456			return errNilDst(p)
457		}
458		if acode != sppb.TypeCode_INT64 {
459			return errTypeMismatch(code, acode, ptr)
460		}
461		if isNull {
462			*p = nil
463			break
464		}
465		x, err := getListValue(v)
466		if err != nil {
467			return err
468		}
469		y, err := decodeInt64Array(x)
470		if err != nil {
471			return err
472		}
473		*p = y
474	case *bool:
475		if p == nil {
476			return errNilDst(p)
477		}
478		if code != sppb.TypeCode_BOOL {
479			return errTypeMismatch(code, acode, ptr)
480		}
481		if isNull {
482			return errDstNotForNull(ptr)
483		}
484		x, err := getBoolValue(v)
485		if err != nil {
486			return err
487		}
488		*p = x
489	case *NullBool:
490		if p == nil {
491			return errNilDst(p)
492		}
493		if code != sppb.TypeCode_BOOL {
494			return errTypeMismatch(code, acode, ptr)
495		}
496		if isNull {
497			*p = NullBool{}
498			break
499		}
500		x, err := getBoolValue(v)
501		if err != nil {
502			return err
503		}
504		p.Valid = true
505		p.Bool = x
506	case *[]NullBool:
507		if p == nil {
508			return errNilDst(p)
509		}
510		if acode != sppb.TypeCode_BOOL {
511			return errTypeMismatch(code, acode, ptr)
512		}
513		if isNull {
514			*p = nil
515			break
516		}
517		x, err := getListValue(v)
518		if err != nil {
519			return err
520		}
521		y, err := decodeNullBoolArray(x)
522		if err != nil {
523			return err
524		}
525		*p = y
526	case *[]bool:
527		if p == nil {
528			return errNilDst(p)
529		}
530		if acode != sppb.TypeCode_BOOL {
531			return errTypeMismatch(code, acode, ptr)
532		}
533		if isNull {
534			*p = nil
535			break
536		}
537		x, err := getListValue(v)
538		if err != nil {
539			return err
540		}
541		y, err := decodeBoolArray(x)
542		if err != nil {
543			return err
544		}
545		*p = y
546	case *float64:
547		if p == nil {
548			return errNilDst(p)
549		}
550		if code != sppb.TypeCode_FLOAT64 {
551			return errTypeMismatch(code, acode, ptr)
552		}
553		if isNull {
554			return errDstNotForNull(ptr)
555		}
556		x, err := getFloat64Value(v)
557		if err != nil {
558			return err
559		}
560		*p = x
561	case *NullFloat64:
562		if p == nil {
563			return errNilDst(p)
564		}
565		if code != sppb.TypeCode_FLOAT64 {
566			return errTypeMismatch(code, acode, ptr)
567		}
568		if isNull {
569			*p = NullFloat64{}
570			break
571		}
572		x, err := getFloat64Value(v)
573		if err != nil {
574			return err
575		}
576		p.Valid = true
577		p.Float64 = x
578	case *[]NullFloat64:
579		if p == nil {
580			return errNilDst(p)
581		}
582		if acode != sppb.TypeCode_FLOAT64 {
583			return errTypeMismatch(code, acode, ptr)
584		}
585		if isNull {
586			*p = nil
587			break
588		}
589		x, err := getListValue(v)
590		if err != nil {
591			return err
592		}
593		y, err := decodeNullFloat64Array(x)
594		if err != nil {
595			return err
596		}
597		*p = y
598	case *[]float64:
599		if p == nil {
600			return errNilDst(p)
601		}
602		if acode != sppb.TypeCode_FLOAT64 {
603			return errTypeMismatch(code, acode, ptr)
604		}
605		if isNull {
606			*p = nil
607			break
608		}
609		x, err := getListValue(v)
610		if err != nil {
611			return err
612		}
613		y, err := decodeFloat64Array(x)
614		if err != nil {
615			return err
616		}
617		*p = y
618	case *time.Time:
619		var nt NullTime
620		if isNull {
621			return errDstNotForNull(ptr)
622		}
623		err := parseNullTime(v, &nt, code, isNull)
624		if err != nil {
625			return nil
626		}
627		*p = nt.Time
628	case *NullTime:
629		err := parseNullTime(v, p, code, isNull)
630		if err != nil {
631			return err
632		}
633	case *[]NullTime:
634		if p == nil {
635			return errNilDst(p)
636		}
637		if acode != sppb.TypeCode_TIMESTAMP {
638			return errTypeMismatch(code, acode, ptr)
639		}
640		if isNull {
641			*p = nil
642			break
643		}
644		x, err := getListValue(v)
645		if err != nil {
646			return err
647		}
648		y, err := decodeNullTimeArray(x)
649		if err != nil {
650			return err
651		}
652		*p = y
653	case *[]time.Time:
654		if p == nil {
655			return errNilDst(p)
656		}
657		if acode != sppb.TypeCode_TIMESTAMP {
658			return errTypeMismatch(code, acode, ptr)
659		}
660		if isNull {
661			*p = nil
662			break
663		}
664		x, err := getListValue(v)
665		if err != nil {
666			return err
667		}
668		y, err := decodeTimeArray(x)
669		if err != nil {
670			return err
671		}
672		*p = y
673	case *civil.Date:
674		if p == nil {
675			return errNilDst(p)
676		}
677		if code != sppb.TypeCode_DATE {
678			return errTypeMismatch(code, acode, ptr)
679		}
680		if isNull {
681			return errDstNotForNull(ptr)
682		}
683		x, err := getStringValue(v)
684		if err != nil {
685			return err
686		}
687		y, err := civil.ParseDate(x)
688		if err != nil {
689			return errBadEncoding(v, err)
690		}
691		*p = y
692	case *NullDate:
693		if p == nil {
694			return errNilDst(p)
695		}
696		if code != sppb.TypeCode_DATE {
697			return errTypeMismatch(code, acode, ptr)
698		}
699		if isNull {
700			*p = NullDate{}
701			break
702		}
703		x, err := getStringValue(v)
704		if err != nil {
705			return err
706		}
707		y, err := civil.ParseDate(x)
708		if err != nil {
709			return errBadEncoding(v, err)
710		}
711		p.Valid = true
712		p.Date = y
713	case *[]NullDate:
714		if p == nil {
715			return errNilDst(p)
716		}
717		if acode != sppb.TypeCode_DATE {
718			return errTypeMismatch(code, acode, ptr)
719		}
720		if isNull {
721			*p = nil
722			break
723		}
724		x, err := getListValue(v)
725		if err != nil {
726			return err
727		}
728		y, err := decodeNullDateArray(x)
729		if err != nil {
730			return err
731		}
732		*p = y
733	case *[]civil.Date:
734		if p == nil {
735			return errNilDst(p)
736		}
737		if acode != sppb.TypeCode_DATE {
738			return errTypeMismatch(code, acode, ptr)
739		}
740		if isNull {
741			*p = nil
742			break
743		}
744		x, err := getListValue(v)
745		if err != nil {
746			return err
747		}
748		y, err := decodeDateArray(x)
749		if err != nil {
750			return err
751		}
752		*p = y
753	case *[]NullRow:
754		if p == nil {
755			return errNilDst(p)
756		}
757		if acode != sppb.TypeCode_STRUCT {
758			return errTypeMismatch(code, acode, ptr)
759		}
760		if isNull {
761			*p = nil
762			break
763		}
764		x, err := getListValue(v)
765		if err != nil {
766			return err
767		}
768		y, err := decodeRowArray(t.ArrayElementType.StructType, x)
769		if err != nil {
770			return err
771		}
772		*p = y
773	case *GenericColumnValue:
774		*p = GenericColumnValue{Type: t, Value: v}
775	default:
776		// Check if the proto encoding is for an array of structs.
777		if !(code == sppb.TypeCode_ARRAY && acode == sppb.TypeCode_STRUCT) {
778			return errTypeMismatch(code, acode, ptr)
779		}
780		vp := reflect.ValueOf(p)
781		if !vp.IsValid() {
782			return errNilDst(p)
783		}
784		if !isPtrStructPtrSlice(vp.Type()) {
785			// The container is not a pointer to a struct pointer slice.
786			return errTypeMismatch(code, acode, ptr)
787		}
788		// Only use reflection for nil detection on slow path.
789		// Also, IsNil panics on many types, so check it after the type check.
790		if vp.IsNil() {
791			return errNilDst(p)
792		}
793		if isNull {
794			// The proto Value is encoding NULL, set the pointer to struct
795			// slice to nil as well.
796			vp.Elem().Set(reflect.Zero(vp.Elem().Type()))
797			break
798		}
799		x, err := getListValue(v)
800		if err != nil {
801			return err
802		}
803		if err = decodeStructArray(t.ArrayElementType.StructType, x, p); err != nil {
804			return err
805		}
806	}
807	return nil
808}
809
810// errSrvVal returns an error for getting a wrong source protobuf value in decoding.
811func errSrcVal(v *proto3.Value, want string) error {
812	return spannerErrorf(codes.FailedPrecondition, "cannot use %v(Kind: %T) as %s Value",
813		v, v.GetKind(), want)
814}
815
816// getStringValue returns the string value encoded in proto3.Value v whose
817// kind is proto3.Value_StringValue.
818func getStringValue(v *proto3.Value) (string, error) {
819	if x, ok := v.GetKind().(*proto3.Value_StringValue); ok && x != nil {
820		return x.StringValue, nil
821	}
822	return "", errSrcVal(v, "String")
823}
824
825// getBoolValue returns the bool value encoded in proto3.Value v whose
826// kind is proto3.Value_BoolValue.
827func getBoolValue(v *proto3.Value) (bool, error) {
828	if x, ok := v.GetKind().(*proto3.Value_BoolValue); ok && x != nil {
829		return x.BoolValue, nil
830	}
831	return false, errSrcVal(v, "Bool")
832}
833
834// getListValue returns the proto3.ListValue contained in proto3.Value v whose
835// kind is proto3.Value_ListValue.
836func getListValue(v *proto3.Value) (*proto3.ListValue, error) {
837	if x, ok := v.GetKind().(*proto3.Value_ListValue); ok && x != nil {
838		return x.ListValue, nil
839	}
840	return nil, errSrcVal(v, "List")
841}
842
843// errUnexpectedNumStr returns error for decoder getting a unexpected string for
844// representing special float values.
845func errUnexpectedNumStr(s string) error {
846	return spannerErrorf(codes.FailedPrecondition, "unexpected string value %q for number", s)
847}
848
849// getFloat64Value returns the float64 value encoded in proto3.Value v whose
850// kind is proto3.Value_NumberValue / proto3.Value_StringValue.
851// Cloud Spanner uses string to encode NaN, Infinity and -Infinity.
852func getFloat64Value(v *proto3.Value) (float64, error) {
853	switch x := v.GetKind().(type) {
854	case *proto3.Value_NumberValue:
855		if x == nil {
856			break
857		}
858		return x.NumberValue, nil
859	case *proto3.Value_StringValue:
860		if x == nil {
861			break
862		}
863		switch x.StringValue {
864		case "NaN":
865			return math.NaN(), nil
866		case "Infinity":
867			return math.Inf(1), nil
868		case "-Infinity":
869			return math.Inf(-1), nil
870		default:
871			return 0, errUnexpectedNumStr(x.StringValue)
872		}
873	}
874	return 0, errSrcVal(v, "Number")
875}
876
877// errNilListValue returns error for unexpected nil ListValue in decoding Cloud Spanner ARRAYs.
878func errNilListValue(sqlType string) error {
879	return spannerErrorf(codes.FailedPrecondition, "unexpected nil ListValue in decoding %v array", sqlType)
880}
881
882// errDecodeArrayElement returns error for failure in decoding single array element.
883func errDecodeArrayElement(i int, v proto.Message, sqlType string, err error) error {
884	se, ok := toSpannerError(err).(*Error)
885	if !ok {
886		return spannerErrorf(codes.Unknown,
887			"cannot decode %v(array element %v) as %v, error = <%v>", v, i, sqlType, err)
888	}
889	se.decorate(fmt.Sprintf("cannot decode %v(array element %v) as %v", v, i, sqlType))
890	return se
891}
892
893// decodeNullStringArray decodes proto3.ListValue pb into a NullString slice.
894func decodeNullStringArray(pb *proto3.ListValue) ([]NullString, error) {
895	if pb == nil {
896		return nil, errNilListValue("STRING")
897	}
898	a := make([]NullString, len(pb.Values))
899	for i, v := range pb.Values {
900		if err := decodeValue(v, stringType(), &a[i]); err != nil {
901			return nil, errDecodeArrayElement(i, v, "STRING", err)
902		}
903	}
904	return a, nil
905}
906
907// decodeStringArray decodes proto3.ListValue pb into a string slice.
908func decodeStringArray(pb *proto3.ListValue) ([]string, error) {
909	if pb == nil {
910		return nil, errNilListValue("STRING")
911	}
912	a := make([]string, len(pb.Values))
913	st := stringType()
914	for i, v := range pb.Values {
915		if err := decodeValue(v, st, &a[i]); err != nil {
916			return nil, errDecodeArrayElement(i, v, "STRING", err)
917		}
918	}
919	return a, nil
920}
921
922// decodeNullInt64Array decodes proto3.ListValue pb into a NullInt64 slice.
923func decodeNullInt64Array(pb *proto3.ListValue) ([]NullInt64, error) {
924	if pb == nil {
925		return nil, errNilListValue("INT64")
926	}
927	a := make([]NullInt64, len(pb.Values))
928	for i, v := range pb.Values {
929		if err := decodeValue(v, intType(), &a[i]); err != nil {
930			return nil, errDecodeArrayElement(i, v, "INT64", err)
931		}
932	}
933	return a, nil
934}
935
936// decodeInt64Array decodes proto3.ListValue pb into a int64 slice.
937func decodeInt64Array(pb *proto3.ListValue) ([]int64, error) {
938	if pb == nil {
939		return nil, errNilListValue("INT64")
940	}
941	a := make([]int64, len(pb.Values))
942	for i, v := range pb.Values {
943		if err := decodeValue(v, intType(), &a[i]); err != nil {
944			return nil, errDecodeArrayElement(i, v, "INT64", err)
945		}
946	}
947	return a, nil
948}
949
950// decodeNullBoolArray decodes proto3.ListValue pb into a NullBool slice.
951func decodeNullBoolArray(pb *proto3.ListValue) ([]NullBool, error) {
952	if pb == nil {
953		return nil, errNilListValue("BOOL")
954	}
955	a := make([]NullBool, len(pb.Values))
956	for i, v := range pb.Values {
957		if err := decodeValue(v, boolType(), &a[i]); err != nil {
958			return nil, errDecodeArrayElement(i, v, "BOOL", err)
959		}
960	}
961	return a, nil
962}
963
964// decodeBoolArray decodes proto3.ListValue pb into a bool slice.
965func decodeBoolArray(pb *proto3.ListValue) ([]bool, error) {
966	if pb == nil {
967		return nil, errNilListValue("BOOL")
968	}
969	a := make([]bool, len(pb.Values))
970	for i, v := range pb.Values {
971		if err := decodeValue(v, boolType(), &a[i]); err != nil {
972			return nil, errDecodeArrayElement(i, v, "BOOL", err)
973		}
974	}
975	return a, nil
976}
977
978// decodeNullFloat64Array decodes proto3.ListValue pb into a NullFloat64 slice.
979func decodeNullFloat64Array(pb *proto3.ListValue) ([]NullFloat64, error) {
980	if pb == nil {
981		return nil, errNilListValue("FLOAT64")
982	}
983	a := make([]NullFloat64, len(pb.Values))
984	for i, v := range pb.Values {
985		if err := decodeValue(v, floatType(), &a[i]); err != nil {
986			return nil, errDecodeArrayElement(i, v, "FLOAT64", err)
987		}
988	}
989	return a, nil
990}
991
992// decodeFloat64Array decodes proto3.ListValue pb into a float64 slice.
993func decodeFloat64Array(pb *proto3.ListValue) ([]float64, error) {
994	if pb == nil {
995		return nil, errNilListValue("FLOAT64")
996	}
997	a := make([]float64, len(pb.Values))
998	for i, v := range pb.Values {
999		if err := decodeValue(v, floatType(), &a[i]); err != nil {
1000			return nil, errDecodeArrayElement(i, v, "FLOAT64", err)
1001		}
1002	}
1003	return a, nil
1004}
1005
1006// decodeByteArray decodes proto3.ListValue pb into a slice of byte slice.
1007func decodeByteArray(pb *proto3.ListValue) ([][]byte, error) {
1008	if pb == nil {
1009		return nil, errNilListValue("BYTES")
1010	}
1011	a := make([][]byte, len(pb.Values))
1012	for i, v := range pb.Values {
1013		if err := decodeValue(v, bytesType(), &a[i]); err != nil {
1014			return nil, errDecodeArrayElement(i, v, "BYTES", err)
1015		}
1016	}
1017	return a, nil
1018}
1019
1020// decodeNullTimeArray decodes proto3.ListValue pb into a NullTime slice.
1021func decodeNullTimeArray(pb *proto3.ListValue) ([]NullTime, error) {
1022	if pb == nil {
1023		return nil, errNilListValue("TIMESTAMP")
1024	}
1025	a := make([]NullTime, len(pb.Values))
1026	for i, v := range pb.Values {
1027		if err := decodeValue(v, timeType(), &a[i]); err != nil {
1028			return nil, errDecodeArrayElement(i, v, "TIMESTAMP", err)
1029		}
1030	}
1031	return a, nil
1032}
1033
1034// decodeTimeArray decodes proto3.ListValue pb into a time.Time slice.
1035func decodeTimeArray(pb *proto3.ListValue) ([]time.Time, error) {
1036	if pb == nil {
1037		return nil, errNilListValue("TIMESTAMP")
1038	}
1039	a := make([]time.Time, len(pb.Values))
1040	for i, v := range pb.Values {
1041		if err := decodeValue(v, timeType(), &a[i]); err != nil {
1042			return nil, errDecodeArrayElement(i, v, "TIMESTAMP", err)
1043		}
1044	}
1045	return a, nil
1046}
1047
1048// decodeNullDateArray decodes proto3.ListValue pb into a NullDate slice.
1049func decodeNullDateArray(pb *proto3.ListValue) ([]NullDate, error) {
1050	if pb == nil {
1051		return nil, errNilListValue("DATE")
1052	}
1053	a := make([]NullDate, len(pb.Values))
1054	for i, v := range pb.Values {
1055		if err := decodeValue(v, dateType(), &a[i]); err != nil {
1056			return nil, errDecodeArrayElement(i, v, "DATE", err)
1057		}
1058	}
1059	return a, nil
1060}
1061
1062// decodeDateArray decodes proto3.ListValue pb into a civil.Date slice.
1063func decodeDateArray(pb *proto3.ListValue) ([]civil.Date, error) {
1064	if pb == nil {
1065		return nil, errNilListValue("DATE")
1066	}
1067	a := make([]civil.Date, len(pb.Values))
1068	for i, v := range pb.Values {
1069		if err := decodeValue(v, dateType(), &a[i]); err != nil {
1070			return nil, errDecodeArrayElement(i, v, "DATE", err)
1071		}
1072	}
1073	return a, nil
1074}
1075
1076func errNotStructElement(i int, v *proto3.Value) error {
1077	return errDecodeArrayElement(i, v, "STRUCT",
1078		spannerErrorf(codes.FailedPrecondition, "%v(type: %T) doesn't encode Cloud Spanner STRUCT", v, v))
1079}
1080
1081// decodeRowArray decodes proto3.ListValue pb into a NullRow slice according to
1082// the structural information given in sppb.StructType ty.
1083func decodeRowArray(ty *sppb.StructType, pb *proto3.ListValue) ([]NullRow, error) {
1084	if pb == nil {
1085		return nil, errNilListValue("STRUCT")
1086	}
1087	a := make([]NullRow, len(pb.Values))
1088	for i := range pb.Values {
1089		switch v := pb.Values[i].GetKind().(type) {
1090		case *proto3.Value_ListValue:
1091			a[i] = NullRow{
1092				Row: Row{
1093					fields: ty.Fields,
1094					vals:   v.ListValue.Values,
1095				},
1096				Valid: true,
1097			}
1098		// Null elements not currently supported by the server, see
1099		// https://cloud.google.com/spanner/docs/query-syntax#using-structs-with-select
1100		case *proto3.Value_NullValue:
1101			// no-op, a[i] is NullRow{} already
1102		default:
1103			return nil, errNotStructElement(i, pb.Values[i])
1104		}
1105	}
1106	return a, nil
1107}
1108
1109// errNilSpannerStructType returns error for unexpected nil Cloud Spanner STRUCT schema type in decoding.
1110func errNilSpannerStructType() error {
1111	return spannerErrorf(codes.FailedPrecondition, "unexpected nil StructType in decoding Cloud Spanner STRUCT")
1112}
1113
1114// errUnnamedField returns error for decoding a Cloud Spanner STRUCT with unnamed field into a Go struct.
1115func errUnnamedField(ty *sppb.StructType, i int) error {
1116	return spannerErrorf(codes.InvalidArgument, "unnamed field %v in Cloud Spanner STRUCT %+v", i, ty)
1117}
1118
1119// errNoOrDupGoField returns error for decoding a Cloud Spanner
1120// STRUCT into a Go struct which is either missing a field, or has duplicate fields.
1121func errNoOrDupGoField(s interface{}, f string) error {
1122	return spannerErrorf(codes.InvalidArgument, "Go struct %+v(type %T) has no or duplicate fields for Cloud Spanner STRUCT field %v", s, s, f)
1123}
1124
1125// errDupColNames returns error for duplicated Cloud Spanner STRUCT field names found in decoding a Cloud Spanner STRUCT into a Go struct.
1126func errDupSpannerField(f string, ty *sppb.StructType) error {
1127	return spannerErrorf(codes.InvalidArgument, "duplicated field name %q in Cloud Spanner STRUCT %+v", f, ty)
1128}
1129
1130// errDecodeStructField returns error for failure in decoding a single field of a Cloud Spanner STRUCT.
1131func errDecodeStructField(ty *sppb.StructType, f string, err error) error {
1132	se, ok := toSpannerError(err).(*Error)
1133	if !ok {
1134		return spannerErrorf(codes.Unknown,
1135			"cannot decode field %v of Cloud Spanner STRUCT %+v, error = <%v>", f, ty, err)
1136	}
1137	se.decorate(fmt.Sprintf("cannot decode field %v of Cloud Spanner STRUCT %+v", f, ty))
1138	return se
1139}
1140
1141// decodeStruct decodes proto3.ListValue pb into struct referenced by pointer ptr, according to
1142// the structural information given in sppb.StructType ty.
1143func decodeStruct(ty *sppb.StructType, pb *proto3.ListValue, ptr interface{}) error {
1144	if reflect.ValueOf(ptr).IsNil() {
1145		return errNilDst(ptr)
1146	}
1147	if ty == nil {
1148		return errNilSpannerStructType()
1149	}
1150	// t holds the structural information of ptr.
1151	t := reflect.TypeOf(ptr).Elem()
1152	// v is the actual value that ptr points to.
1153	v := reflect.ValueOf(ptr).Elem()
1154
1155	fields, err := fieldCache.Fields(t)
1156	if err != nil {
1157		return toSpannerError(err)
1158	}
1159	seen := map[string]bool{}
1160	for i, f := range ty.Fields {
1161		if f.Name == "" {
1162			return errUnnamedField(ty, i)
1163		}
1164		sf := fields.Match(f.Name)
1165		if sf == nil {
1166			return errNoOrDupGoField(ptr, f.Name)
1167		}
1168		if seen[f.Name] {
1169			// We don't allow duplicated field name.
1170			return errDupSpannerField(f.Name, ty)
1171		}
1172		// Try to decode a single field.
1173		if err := decodeValue(pb.Values[i], f.Type, v.FieldByIndex(sf.Index).Addr().Interface()); err != nil {
1174			return errDecodeStructField(ty, f.Name, err)
1175		}
1176		// Mark field f.Name as processed.
1177		seen[f.Name] = true
1178	}
1179	return nil
1180}
1181
1182// isPtrStructPtrSlice returns true if ptr is a pointer to a slice of struct pointers.
1183func isPtrStructPtrSlice(t reflect.Type) bool {
1184	if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Slice {
1185		// t is not a pointer to a slice.
1186		return false
1187	}
1188	if t = t.Elem(); t.Elem().Kind() != reflect.Ptr || t.Elem().Elem().Kind() != reflect.Struct {
1189		// the slice that t points to is not a slice of struct pointers.
1190		return false
1191	}
1192	return true
1193}
1194
1195// decodeStructArray decodes proto3.ListValue pb into struct slice referenced by pointer ptr, according to the
1196// structural information given in a sppb.StructType.
1197func decodeStructArray(ty *sppb.StructType, pb *proto3.ListValue, ptr interface{}) error {
1198	if pb == nil {
1199		return errNilListValue("STRUCT")
1200	}
1201	// Type of the struct pointers stored in the slice that ptr points to.
1202	ts := reflect.TypeOf(ptr).Elem().Elem()
1203	// The slice that ptr points to, might be nil at this point.
1204	v := reflect.ValueOf(ptr).Elem()
1205	// Allocate empty slice.
1206	v.Set(reflect.MakeSlice(v.Type(), 0, len(pb.Values)))
1207	// Decode every struct in pb.Values.
1208	for i, pv := range pb.Values {
1209		// Check if pv is a NULL value.
1210		if _, isNull := pv.Kind.(*proto3.Value_NullValue); isNull {
1211			// Append a nil pointer to the slice.
1212			v.Set(reflect.Append(v, reflect.New(ts).Elem()))
1213			continue
1214		}
1215		// Allocate empty struct.
1216		s := reflect.New(ts.Elem())
1217		// Get proto3.ListValue l from proto3.Value pv.
1218		l, err := getListValue(pv)
1219		if err != nil {
1220			return errDecodeArrayElement(i, pv, "STRUCT", err)
1221		}
1222		// Decode proto3.ListValue l into struct referenced by s.Interface().
1223		if err = decodeStruct(ty, l, s.Interface()); err != nil {
1224			return errDecodeArrayElement(i, pv, "STRUCT", err)
1225		}
1226		// Append the decoded struct back into the slice.
1227		v.Set(reflect.Append(v, s))
1228	}
1229	return nil
1230}
1231
1232// errEncoderUnsupportedType returns error for not being able to encode a value of
1233// certain type.
1234func errEncoderUnsupportedType(v interface{}) error {
1235	return spannerErrorf(codes.InvalidArgument, "client doesn't support type %T", v)
1236}
1237
1238// encodeValue encodes a Go native type into a proto3.Value.
1239func encodeValue(v interface{}) (*proto3.Value, *sppb.Type, error) {
1240	pb := &proto3.Value{
1241		Kind: &proto3.Value_NullValue{NullValue: proto3.NullValue_NULL_VALUE},
1242	}
1243	var pt *sppb.Type
1244	var err error
1245	switch v := v.(type) {
1246	case nil:
1247	case string:
1248		pb.Kind = stringKind(v)
1249		pt = stringType()
1250	case NullString:
1251		if v.Valid {
1252			return encodeValue(v.StringVal)
1253		}
1254		pt = stringType()
1255	case []string:
1256		if v != nil {
1257			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1258			if err != nil {
1259				return nil, nil, err
1260			}
1261		}
1262		pt = listType(stringType())
1263	case []NullString:
1264		if v != nil {
1265			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1266			if err != nil {
1267				return nil, nil, err
1268			}
1269		}
1270		pt = listType(stringType())
1271	case []byte:
1272		if v != nil {
1273			pb.Kind = stringKind(base64.StdEncoding.EncodeToString(v))
1274		}
1275		pt = bytesType()
1276	case [][]byte:
1277		if v != nil {
1278			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1279			if err != nil {
1280				return nil, nil, err
1281			}
1282		}
1283		pt = listType(bytesType())
1284	case int:
1285		pb.Kind = stringKind(strconv.FormatInt(int64(v), 10))
1286		pt = intType()
1287	case []int:
1288		if v != nil {
1289			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1290			if err != nil {
1291				return nil, nil, err
1292			}
1293		}
1294		pt = listType(intType())
1295	case int64:
1296		pb.Kind = stringKind(strconv.FormatInt(v, 10))
1297		pt = intType()
1298	case []int64:
1299		if v != nil {
1300			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1301			if err != nil {
1302				return nil, nil, err
1303			}
1304		}
1305		pt = listType(intType())
1306	case NullInt64:
1307		if v.Valid {
1308			return encodeValue(v.Int64)
1309		}
1310		pt = intType()
1311	case []NullInt64:
1312		if v != nil {
1313			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1314			if err != nil {
1315				return nil, nil, err
1316			}
1317		}
1318		pt = listType(intType())
1319	case bool:
1320		pb.Kind = &proto3.Value_BoolValue{BoolValue: v}
1321		pt = boolType()
1322	case []bool:
1323		if v != nil {
1324			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1325			if err != nil {
1326				return nil, nil, err
1327			}
1328		}
1329		pt = listType(boolType())
1330	case NullBool:
1331		if v.Valid {
1332			return encodeValue(v.Bool)
1333		}
1334		pt = boolType()
1335	case []NullBool:
1336		if v != nil {
1337			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1338			if err != nil {
1339				return nil, nil, err
1340			}
1341		}
1342		pt = listType(boolType())
1343	case float64:
1344		pb.Kind = &proto3.Value_NumberValue{NumberValue: v}
1345		pt = floatType()
1346	case []float64:
1347		if v != nil {
1348			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1349			if err != nil {
1350				return nil, nil, err
1351			}
1352		}
1353		pt = listType(floatType())
1354	case NullFloat64:
1355		if v.Valid {
1356			return encodeValue(v.Float64)
1357		}
1358		pt = floatType()
1359	case []NullFloat64:
1360		if v != nil {
1361			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1362			if err != nil {
1363				return nil, nil, err
1364			}
1365		}
1366		pt = listType(floatType())
1367	case time.Time:
1368		if v == commitTimestamp {
1369			pb.Kind = stringKind(commitTimestampPlaceholderString)
1370		} else {
1371			pb.Kind = stringKind(v.UTC().Format(time.RFC3339Nano))
1372		}
1373		pt = timeType()
1374	case []time.Time:
1375		if v != nil {
1376			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1377			if err != nil {
1378				return nil, nil, err
1379			}
1380		}
1381		pt = listType(timeType())
1382	case NullTime:
1383		if v.Valid {
1384			return encodeValue(v.Time)
1385		}
1386		pt = timeType()
1387	case []NullTime:
1388		if v != nil {
1389			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1390			if err != nil {
1391				return nil, nil, err
1392			}
1393		}
1394		pt = listType(timeType())
1395	case civil.Date:
1396		pb.Kind = stringKind(v.String())
1397		pt = dateType()
1398	case []civil.Date:
1399		if v != nil {
1400			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1401			if err != nil {
1402				return nil, nil, err
1403			}
1404		}
1405		pt = listType(dateType())
1406	case NullDate:
1407		if v.Valid {
1408			return encodeValue(v.Date)
1409		}
1410		pt = dateType()
1411	case []NullDate:
1412		if v != nil {
1413			pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] })
1414			if err != nil {
1415				return nil, nil, err
1416			}
1417		}
1418		pt = listType(dateType())
1419	case GenericColumnValue:
1420		// Deep clone to ensure subsequent changes to v before
1421		// transmission don't affect our encoded value.
1422		pb = proto.Clone(v.Value).(*proto3.Value)
1423		pt = proto.Clone(v.Type).(*sppb.Type)
1424	case []GenericColumnValue:
1425		return nil, nil, errEncoderUnsupportedType(v)
1426	default:
1427		if !isStructOrArrayOfStructValue(v) {
1428			return nil, nil, errEncoderUnsupportedType(v)
1429		}
1430		typ := reflect.TypeOf(v)
1431
1432		// Value is a Go struct value/ptr.
1433		if (typ.Kind() == reflect.Struct) ||
1434			(typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct) {
1435			return encodeStruct(v)
1436		}
1437
1438		// Value is a slice of Go struct values/ptrs.
1439		if typ.Kind() == reflect.Slice {
1440			return encodeStructArray(v)
1441		}
1442	}
1443	return pb, pt, nil
1444}
1445
1446// Encodes a Go struct value/ptr in v to the spanner Value and Type protos. v itself must
1447// be non-nil.
1448func encodeStruct(v interface{}) (*proto3.Value, *sppb.Type, error) {
1449	typ := reflect.TypeOf(v)
1450	val := reflect.ValueOf(v)
1451
1452	// Pointer to struct.
1453	if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct {
1454		typ = typ.Elem()
1455		if val.IsNil() {
1456			// nil pointer to struct, representing a NULL STRUCT value. Use a dummy value to
1457			// get the type.
1458			_, st, err := encodeStruct(reflect.Zero(typ).Interface())
1459			if err != nil {
1460				return nil, nil, err
1461			}
1462			return nullProto(), st, nil
1463		}
1464		val = val.Elem()
1465	}
1466
1467	if typ.Kind() != reflect.Struct {
1468		return nil, nil, errEncoderUnsupportedType(v)
1469	}
1470
1471	stf := make([]*sppb.StructType_Field, 0, typ.NumField())
1472	stv := make([]*proto3.Value, 0, typ.NumField())
1473
1474	for i := 0; i < typ.NumField(); i++ {
1475		// If the field has a 'spanner' tag, use the value of that tag as the field name.
1476		// This is used to build STRUCT types with unnamed/duplicate fields.
1477		sf := typ.Field(i)
1478		fval := val.Field(i)
1479
1480		// Embedded fields are not allowed.
1481		if sf.Anonymous {
1482			return nil, nil, errUnsupportedEmbeddedStructFields(sf.Name)
1483		}
1484
1485		// Unexported fields are ignored.
1486		if !fval.CanInterface() {
1487			continue
1488		}
1489
1490		fname, ok := sf.Tag.Lookup("spanner")
1491		if !ok {
1492			fname = sf.Name
1493		}
1494
1495		eval, etype, err := encodeValue(fval.Interface())
1496		if err != nil {
1497			return nil, nil, err
1498		}
1499
1500		stf = append(stf, mkField(fname, etype))
1501		stv = append(stv, eval)
1502	}
1503
1504	return listProto(stv...), structType(stf...), nil
1505}
1506
1507// Encodes a slice of Go struct values/ptrs in v to the spanner Value and Type protos. v itself
1508// must be non-nil.
1509func encodeStructArray(v interface{}) (*proto3.Value, *sppb.Type, error) {
1510	etyp := reflect.TypeOf(v).Elem()
1511	sliceval := reflect.ValueOf(v)
1512
1513	// Slice of pointers to structs.
1514	if etyp.Kind() == reflect.Ptr {
1515		etyp = etyp.Elem()
1516	}
1517
1518	// Use a dummy struct value to get the element type
1519	_, elemTyp, err := encodeStruct(reflect.Zero(etyp).Interface())
1520	if err != nil {
1521		return nil, nil, err
1522	}
1523
1524	// nil slice represents a NULL array-of-struct.
1525	if sliceval.IsNil() {
1526		return nullProto(), listType(elemTyp), nil
1527	}
1528
1529	values := make([]*proto3.Value, 0, sliceval.Len())
1530
1531	for i := 0; i < sliceval.Len(); i++ {
1532		ev, _, err := encodeStruct(sliceval.Index(i).Interface())
1533		if err != nil {
1534			return nil, nil, err
1535		}
1536		values = append(values, ev)
1537	}
1538	return listProto(values...), listType(elemTyp), nil
1539}
1540
1541func isStructOrArrayOfStructValue(v interface{}) bool {
1542	typ := reflect.TypeOf(v)
1543	if typ.Kind() == reflect.Slice {
1544		typ = typ.Elem()
1545	}
1546	if typ.Kind() == reflect.Ptr {
1547		typ = typ.Elem()
1548	}
1549	return typ.Kind() == reflect.Struct
1550}
1551
1552func isSupportedMutationType(v interface{}) bool {
1553	switch v.(type) {
1554	case nil, string, NullString, []string, []NullString,
1555		[]byte, [][]byte,
1556		int, []int, int64, []int64, NullInt64, []NullInt64,
1557		bool, []bool, NullBool, []NullBool,
1558		float64, []float64, NullFloat64, []NullFloat64,
1559		time.Time, []time.Time, NullTime, []NullTime,
1560		civil.Date, []civil.Date, NullDate, []NullDate,
1561		GenericColumnValue:
1562		return true
1563	default:
1564		return false
1565	}
1566}
1567
1568// encodeValueArray encodes a Value array into a proto3.ListValue.
1569func encodeValueArray(vs []interface{}) (*proto3.ListValue, error) {
1570	lv := &proto3.ListValue{}
1571	lv.Values = make([]*proto3.Value, 0, len(vs))
1572	for _, v := range vs {
1573		if !isSupportedMutationType(v) {
1574			return nil, errEncoderUnsupportedType(v)
1575		}
1576		pb, _, err := encodeValue(v)
1577		if err != nil {
1578			return nil, err
1579		}
1580		lv.Values = append(lv.Values, pb)
1581	}
1582	return lv, nil
1583}
1584
1585// encodeArray assumes that all values of the array element type encode without error.
1586func encodeArray(len int, at func(int) interface{}) (*proto3.Value, error) {
1587	vs := make([]*proto3.Value, len)
1588	var err error
1589	for i := 0; i < len; i++ {
1590		vs[i], _, err = encodeValue(at(i))
1591		if err != nil {
1592			return nil, err
1593		}
1594	}
1595	return listProto(vs...), nil
1596}
1597
1598func spannerTagParser(t reflect.StructTag) (name string, keep bool, other interface{}, err error) {
1599	if s := t.Get("spanner"); s != "" {
1600		if s == "-" {
1601			return "", false, nil, nil
1602		}
1603		return s, true, nil, nil
1604	}
1605	return "", true, nil, nil
1606}
1607
1608var fieldCache = fields.NewCache(spannerTagParser, nil, nil)
1609