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