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 "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 35// nullString is returned by the String methods of NullableValues when the 36// underlying database value is null. 37const nullString = "<null>" 38const commitTimestampPlaceholderString = "spanner.commit_timestamp()" 39 40var ( 41 // CommitTimestamp is a special value used to tell Cloud Spanner to insert 42 // the commit timestamp of the transaction into a column. It can be used in 43 // a Mutation, or directly used in InsertStruct or InsertMap. See 44 // ExampleCommitTimestamp. This is just a placeholder and the actual value 45 // stored in this variable has no meaning. 46 CommitTimestamp = commitTimestamp 47 commitTimestamp = time.Unix(0, 0).In(time.FixedZone("CommitTimestamp placeholder", 0xDB)) 48) 49 50// NullableValue is the interface implemented by all null value wrapper types. 51type NullableValue interface { 52 // IsNull returns true if the underlying database value is null. 53 IsNull() bool 54} 55 56// NullInt64 represents a Cloud Spanner INT64 that may be NULL. 57type NullInt64 struct { 58 Int64 int64 59 Valid bool // Valid is true if Int64 is not NULL. 60} 61 62// IsNull implements NullableValue.IsNull for NullInt64. 63func (n NullInt64) IsNull() bool { 64 return !n.Valid 65} 66 67// String implements Stringer.String for NullInt64 68func (n NullInt64) String() string { 69 if !n.Valid { 70 return nullString 71 } 72 return fmt.Sprintf("%v", n.Int64) 73} 74 75// NullString represents a Cloud Spanner STRING that may be NULL. 76type NullString struct { 77 StringVal string 78 Valid bool // Valid is true if StringVal is not NULL. 79} 80 81// IsNull implements NullableValue.IsNull for NullString. 82func (n NullString) IsNull() bool { 83 return !n.Valid 84} 85 86// String implements Stringer.String for NullString 87func (n NullString) String() string { 88 if !n.Valid { 89 return nullString 90 } 91 return n.StringVal 92} 93 94// NullFloat64 represents a Cloud Spanner FLOAT64 that may be NULL. 95type NullFloat64 struct { 96 Float64 float64 97 Valid bool // Valid is true if Float64 is not NULL. 98} 99 100// IsNull implements NullableValue.IsNull for NullFloat64. 101func (n NullFloat64) IsNull() bool { 102 return !n.Valid 103} 104 105// String implements Stringer.String for NullFloat64 106func (n NullFloat64) String() string { 107 if !n.Valid { 108 return nullString 109 } 110 return fmt.Sprintf("%v", n.Float64) 111} 112 113// NullBool represents a Cloud Spanner BOOL that may be NULL. 114type NullBool struct { 115 Bool bool 116 Valid bool // Valid is true if Bool is not NULL. 117} 118 119// IsNull implements NullableValue.IsNull for NullBool. 120func (n NullBool) IsNull() bool { 121 return !n.Valid 122} 123 124// String implements Stringer.String for NullBool 125func (n NullBool) String() string { 126 if !n.Valid { 127 return nullString 128 } 129 return fmt.Sprintf("%v", n.Bool) 130} 131 132// NullTime represents a Cloud Spanner TIMESTAMP that may be null. 133type NullTime struct { 134 Time time.Time 135 Valid bool // Valid is true if Time is not NULL. 136} 137 138// IsNull implements NullableValue.IsNull for NullTime. 139func (n NullTime) IsNull() bool { 140 return !n.Valid 141} 142 143// String implements Stringer.String for NullTime 144func (n NullTime) String() string { 145 if !n.Valid { 146 return nullString 147 } 148 return n.Time.Format(time.RFC3339Nano) 149} 150 151// NullDate represents a Cloud Spanner DATE that may be null. 152type NullDate struct { 153 Date civil.Date 154 Valid bool // Valid is true if Date is not NULL. 155} 156 157// IsNull implements NullableValue.IsNull for NullDate. 158func (n NullDate) IsNull() bool { 159 return !n.Valid 160} 161 162// String implements Stringer.String for NullDate 163func (n NullDate) String() string { 164 if !n.Valid { 165 return nullString 166 } 167 return n.Date.String() 168} 169 170// NullRow represents a Cloud Spanner STRUCT that may be NULL. 171// See also the document for Row. 172// Note that NullRow is not a valid Cloud Spanner column Type. 173type NullRow struct { 174 Row Row 175 Valid bool // Valid is true if Row is not NULL. 176} 177 178// GenericColumnValue represents the generic encoded value and type of the 179// column. See google.spanner.v1.ResultSet proto for details. This can be 180// useful for proxying query results when the result types are not known in 181// advance. 182// 183// If you populate a GenericColumnValue from a row using Row.Column or related 184// methods, do not modify the contents of Type and Value. 185type GenericColumnValue struct { 186 Type *sppb.Type 187 Value *proto3.Value 188} 189 190// Decode decodes a GenericColumnValue. The ptr argument should be a pointer 191// to a Go value that can accept v. 192func (v GenericColumnValue) Decode(ptr interface{}) error { 193 return decodeValue(v.Value, v.Type, ptr) 194} 195 196// NewGenericColumnValue creates a GenericColumnValue from Go value that is 197// valid for Cloud Spanner. 198func newGenericColumnValue(v interface{}) (*GenericColumnValue, error) { 199 value, typ, err := encodeValue(v) 200 if err != nil { 201 return nil, err 202 } 203 return &GenericColumnValue{Value: value, Type: typ}, nil 204} 205 206// errTypeMismatch returns error for destination not having a compatible type 207// with source Cloud Spanner type. 208func errTypeMismatch(srcCode, elCode sppb.TypeCode, dst interface{}) error { 209 s := srcCode.String() 210 if srcCode == sppb.TypeCode_ARRAY { 211 s = fmt.Sprintf("%v[%v]", srcCode, elCode) 212 } 213 return spannerErrorf(codes.InvalidArgument, "type %T cannot be used for decoding %s", dst, s) 214} 215 216// errNilSpannerType returns error for nil Cloud Spanner type in decoding. 217func errNilSpannerType() error { 218 return spannerErrorf(codes.FailedPrecondition, "unexpected nil Cloud Spanner data type in decoding") 219} 220 221// errNilSrc returns error for decoding from nil proto value. 222func errNilSrc() error { 223 return spannerErrorf(codes.FailedPrecondition, "unexpected nil Cloud Spanner value in decoding") 224} 225 226// errNilDst returns error for decoding into nil interface{}. 227func errNilDst(dst interface{}) error { 228 return spannerErrorf(codes.InvalidArgument, "cannot decode into nil type %T", dst) 229} 230 231// errNilArrElemType returns error for input Cloud Spanner data type being a array but without a 232// non-nil array element type. 233func errNilArrElemType(t *sppb.Type) error { 234 return spannerErrorf(codes.FailedPrecondition, "array type %v is with nil array element type", t) 235} 236 237func errUnsupportedEmbeddedStructFields(fname string) error { 238 return spannerErrorf(codes.InvalidArgument, "Embedded field: %s. Embedded and anonymous fields are not allowed "+ 239 "when converting Go structs to Cloud Spanner STRUCT values. To create a STRUCT value with an "+ 240 "unnamed field, use a `spanner:\"\"` field tag.", fname) 241} 242 243// errDstNotForNull returns error for decoding a SQL NULL value into a destination which doesn't 244// support NULL values. 245func errDstNotForNull(dst interface{}) error { 246 return spannerErrorf(codes.InvalidArgument, "destination %T cannot support NULL SQL values", dst) 247} 248 249// errBadEncoding returns error for decoding wrongly encoded types. 250func errBadEncoding(v *proto3.Value, err error) error { 251 return spannerErrorf(codes.FailedPrecondition, "%v wasn't correctly encoded: <%v>", v, err) 252} 253 254func parseNullTime(v *proto3.Value, p *NullTime, code sppb.TypeCode, isNull bool) error { 255 if p == nil { 256 return errNilDst(p) 257 } 258 if code != sppb.TypeCode_TIMESTAMP { 259 return errTypeMismatch(code, sppb.TypeCode_TYPE_CODE_UNSPECIFIED, p) 260 } 261 if isNull { 262 *p = NullTime{} 263 return nil 264 } 265 x, err := getStringValue(v) 266 if err != nil { 267 return err 268 } 269 y, err := time.Parse(time.RFC3339Nano, x) 270 if err != nil { 271 return errBadEncoding(v, err) 272 } 273 p.Valid = true 274 p.Time = y 275 return nil 276} 277 278// decodeValue decodes a protobuf Value into a pointer to a Go value, as 279// specified by sppb.Type. 280func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}) error { 281 if v == nil { 282 return errNilSrc() 283 } 284 if t == nil { 285 return errNilSpannerType() 286 } 287 code := t.Code 288 acode := sppb.TypeCode_TYPE_CODE_UNSPECIFIED 289 if code == sppb.TypeCode_ARRAY { 290 if t.ArrayElementType == nil { 291 return errNilArrElemType(t) 292 } 293 acode = t.ArrayElementType.Code 294 } 295 _, isNull := v.Kind.(*proto3.Value_NullValue) 296 297 // Do the decoding based on the type of ptr. 298 switch p := ptr.(type) { 299 case nil: 300 return errNilDst(nil) 301 case *string: 302 if p == nil { 303 return errNilDst(p) 304 } 305 if code != sppb.TypeCode_STRING { 306 return errTypeMismatch(code, acode, ptr) 307 } 308 if isNull { 309 return errDstNotForNull(ptr) 310 } 311 x, err := getStringValue(v) 312 if err != nil { 313 return err 314 } 315 *p = x 316 case *NullString: 317 if p == nil { 318 return errNilDst(p) 319 } 320 if code != sppb.TypeCode_STRING { 321 return errTypeMismatch(code, acode, ptr) 322 } 323 if isNull { 324 *p = NullString{} 325 break 326 } 327 x, err := getStringValue(v) 328 if err != nil { 329 return err 330 } 331 p.Valid = true 332 p.StringVal = x 333 case *[]NullString: 334 if p == nil { 335 return errNilDst(p) 336 } 337 if acode != sppb.TypeCode_STRING { 338 return errTypeMismatch(code, acode, ptr) 339 } 340 if isNull { 341 *p = nil 342 break 343 } 344 x, err := getListValue(v) 345 if err != nil { 346 return err 347 } 348 y, err := decodeNullStringArray(x) 349 if err != nil { 350 return err 351 } 352 *p = y 353 case *[]string: 354 if p == nil { 355 return errNilDst(p) 356 } 357 if acode != sppb.TypeCode_STRING { 358 return errTypeMismatch(code, acode, ptr) 359 } 360 if isNull { 361 *p = nil 362 break 363 } 364 x, err := getListValue(v) 365 if err != nil { 366 return err 367 } 368 y, err := decodeStringArray(x) 369 if err != nil { 370 return err 371 } 372 *p = y 373 case *[]byte: 374 if p == nil { 375 return errNilDst(p) 376 } 377 if code != sppb.TypeCode_BYTES { 378 return errTypeMismatch(code, acode, ptr) 379 } 380 if isNull { 381 *p = nil 382 break 383 } 384 x, err := getStringValue(v) 385 if err != nil { 386 return err 387 } 388 y, err := base64.StdEncoding.DecodeString(x) 389 if err != nil { 390 return errBadEncoding(v, err) 391 } 392 *p = y 393 case *[][]byte: 394 if p == nil { 395 return errNilDst(p) 396 } 397 if acode != sppb.TypeCode_BYTES { 398 return errTypeMismatch(code, acode, ptr) 399 } 400 if isNull { 401 *p = nil 402 break 403 } 404 x, err := getListValue(v) 405 if err != nil { 406 return err 407 } 408 y, err := decodeByteArray(x) 409 if err != nil { 410 return err 411 } 412 *p = y 413 case *int64: 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 return errDstNotForNull(ptr) 422 } 423 x, err := getStringValue(v) 424 if err != nil { 425 return err 426 } 427 y, err := strconv.ParseInt(x, 10, 64) 428 if err != nil { 429 return errBadEncoding(v, err) 430 } 431 *p = y 432 case *NullInt64: 433 if p == nil { 434 return errNilDst(p) 435 } 436 if code != sppb.TypeCode_INT64 { 437 return errTypeMismatch(code, acode, ptr) 438 } 439 if isNull { 440 *p = NullInt64{} 441 break 442 } 443 x, err := getStringValue(v) 444 if err != nil { 445 return err 446 } 447 y, err := strconv.ParseInt(x, 10, 64) 448 if err != nil { 449 return errBadEncoding(v, err) 450 } 451 p.Valid = true 452 p.Int64 = y 453 case *[]NullInt64: 454 if p == nil { 455 return errNilDst(p) 456 } 457 if acode != sppb.TypeCode_INT64 { 458 return errTypeMismatch(code, acode, ptr) 459 } 460 if isNull { 461 *p = nil 462 break 463 } 464 x, err := getListValue(v) 465 if err != nil { 466 return err 467 } 468 y, err := decodeNullInt64Array(x) 469 if err != nil { 470 return err 471 } 472 *p = y 473 case *[]int64: 474 if p == nil { 475 return errNilDst(p) 476 } 477 if acode != sppb.TypeCode_INT64 { 478 return errTypeMismatch(code, acode, ptr) 479 } 480 if isNull { 481 *p = nil 482 break 483 } 484 x, err := getListValue(v) 485 if err != nil { 486 return err 487 } 488 y, err := decodeInt64Array(x) 489 if err != nil { 490 return err 491 } 492 *p = y 493 case *bool: 494 if p == nil { 495 return errNilDst(p) 496 } 497 if code != sppb.TypeCode_BOOL { 498 return errTypeMismatch(code, acode, ptr) 499 } 500 if isNull { 501 return errDstNotForNull(ptr) 502 } 503 x, err := getBoolValue(v) 504 if err != nil { 505 return err 506 } 507 *p = x 508 case *NullBool: 509 if p == nil { 510 return errNilDst(p) 511 } 512 if code != sppb.TypeCode_BOOL { 513 return errTypeMismatch(code, acode, ptr) 514 } 515 if isNull { 516 *p = NullBool{} 517 break 518 } 519 x, err := getBoolValue(v) 520 if err != nil { 521 return err 522 } 523 p.Valid = true 524 p.Bool = x 525 case *[]NullBool: 526 if p == nil { 527 return errNilDst(p) 528 } 529 if acode != sppb.TypeCode_BOOL { 530 return errTypeMismatch(code, acode, ptr) 531 } 532 if isNull { 533 *p = nil 534 break 535 } 536 x, err := getListValue(v) 537 if err != nil { 538 return err 539 } 540 y, err := decodeNullBoolArray(x) 541 if err != nil { 542 return err 543 } 544 *p = y 545 case *[]bool: 546 if p == nil { 547 return errNilDst(p) 548 } 549 if acode != sppb.TypeCode_BOOL { 550 return errTypeMismatch(code, acode, ptr) 551 } 552 if isNull { 553 *p = nil 554 break 555 } 556 x, err := getListValue(v) 557 if err != nil { 558 return err 559 } 560 y, err := decodeBoolArray(x) 561 if err != nil { 562 return err 563 } 564 *p = y 565 case *float64: 566 if p == nil { 567 return errNilDst(p) 568 } 569 if code != sppb.TypeCode_FLOAT64 { 570 return errTypeMismatch(code, acode, ptr) 571 } 572 if isNull { 573 return errDstNotForNull(ptr) 574 } 575 x, err := getFloat64Value(v) 576 if err != nil { 577 return err 578 } 579 *p = x 580 case *NullFloat64: 581 if p == nil { 582 return errNilDst(p) 583 } 584 if code != sppb.TypeCode_FLOAT64 { 585 return errTypeMismatch(code, acode, ptr) 586 } 587 if isNull { 588 *p = NullFloat64{} 589 break 590 } 591 x, err := getFloat64Value(v) 592 if err != nil { 593 return err 594 } 595 p.Valid = true 596 p.Float64 = x 597 case *[]NullFloat64: 598 if p == nil { 599 return errNilDst(p) 600 } 601 if acode != sppb.TypeCode_FLOAT64 { 602 return errTypeMismatch(code, acode, ptr) 603 } 604 if isNull { 605 *p = nil 606 break 607 } 608 x, err := getListValue(v) 609 if err != nil { 610 return err 611 } 612 y, err := decodeNullFloat64Array(x) 613 if err != nil { 614 return err 615 } 616 *p = y 617 case *[]float64: 618 if p == nil { 619 return errNilDst(p) 620 } 621 if acode != sppb.TypeCode_FLOAT64 { 622 return errTypeMismatch(code, acode, ptr) 623 } 624 if isNull { 625 *p = nil 626 break 627 } 628 x, err := getListValue(v) 629 if err != nil { 630 return err 631 } 632 y, err := decodeFloat64Array(x) 633 if err != nil { 634 return err 635 } 636 *p = y 637 case *time.Time: 638 var nt NullTime 639 if isNull { 640 return errDstNotForNull(ptr) 641 } 642 err := parseNullTime(v, &nt, code, isNull) 643 if err != nil { 644 return err 645 } 646 *p = nt.Time 647 case *NullTime: 648 err := parseNullTime(v, p, code, isNull) 649 if err != nil { 650 return err 651 } 652 case *[]NullTime: 653 if p == nil { 654 return errNilDst(p) 655 } 656 if acode != sppb.TypeCode_TIMESTAMP { 657 return errTypeMismatch(code, acode, ptr) 658 } 659 if isNull { 660 *p = nil 661 break 662 } 663 x, err := getListValue(v) 664 if err != nil { 665 return err 666 } 667 y, err := decodeNullTimeArray(x) 668 if err != nil { 669 return err 670 } 671 *p = y 672 case *[]time.Time: 673 if p == nil { 674 return errNilDst(p) 675 } 676 if acode != sppb.TypeCode_TIMESTAMP { 677 return errTypeMismatch(code, acode, ptr) 678 } 679 if isNull { 680 *p = nil 681 break 682 } 683 x, err := getListValue(v) 684 if err != nil { 685 return err 686 } 687 y, err := decodeTimeArray(x) 688 if err != nil { 689 return err 690 } 691 *p = y 692 case *civil.Date: 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 return errDstNotForNull(ptr) 701 } 702 x, err := getStringValue(v) 703 if err != nil { 704 return err 705 } 706 y, err := civil.ParseDate(x) 707 if err != nil { 708 return errBadEncoding(v, err) 709 } 710 *p = y 711 case *NullDate: 712 if p == nil { 713 return errNilDst(p) 714 } 715 if code != sppb.TypeCode_DATE { 716 return errTypeMismatch(code, acode, ptr) 717 } 718 if isNull { 719 *p = NullDate{} 720 break 721 } 722 x, err := getStringValue(v) 723 if err != nil { 724 return err 725 } 726 y, err := civil.ParseDate(x) 727 if err != nil { 728 return errBadEncoding(v, err) 729 } 730 p.Valid = true 731 p.Date = y 732 case *[]NullDate: 733 if p == nil { 734 return errNilDst(p) 735 } 736 if acode != sppb.TypeCode_DATE { 737 return errTypeMismatch(code, acode, ptr) 738 } 739 if isNull { 740 *p = nil 741 break 742 } 743 x, err := getListValue(v) 744 if err != nil { 745 return err 746 } 747 y, err := decodeNullDateArray(x) 748 if err != nil { 749 return err 750 } 751 *p = y 752 case *[]civil.Date: 753 if p == nil { 754 return errNilDst(p) 755 } 756 if acode != sppb.TypeCode_DATE { 757 return errTypeMismatch(code, acode, ptr) 758 } 759 if isNull { 760 *p = nil 761 break 762 } 763 x, err := getListValue(v) 764 if err != nil { 765 return err 766 } 767 y, err := decodeDateArray(x) 768 if err != nil { 769 return err 770 } 771 *p = y 772 case *[]NullRow: 773 if p == nil { 774 return errNilDst(p) 775 } 776 if acode != sppb.TypeCode_STRUCT { 777 return errTypeMismatch(code, acode, ptr) 778 } 779 if isNull { 780 *p = nil 781 break 782 } 783 x, err := getListValue(v) 784 if err != nil { 785 return err 786 } 787 y, err := decodeRowArray(t.ArrayElementType.StructType, x) 788 if err != nil { 789 return err 790 } 791 *p = y 792 case *GenericColumnValue: 793 *p = GenericColumnValue{Type: t, Value: v} 794 default: 795 // Check if the pointer is a variant of a base type. 796 decodableType := getDecodableSpannerType(ptr) 797 if decodableType != spannerTypeUnknown { 798 if isNull && !decodableType.supportsNull() { 799 return errDstNotForNull(ptr) 800 } 801 return decodableType.decodeValueToCustomType(v, t, acode, ptr) 802 } 803 804 // Check if the proto encoding is for an array of structs. 805 if !(code == sppb.TypeCode_ARRAY && acode == sppb.TypeCode_STRUCT) { 806 return errTypeMismatch(code, acode, ptr) 807 } 808 vp := reflect.ValueOf(p) 809 if !vp.IsValid() { 810 return errNilDst(p) 811 } 812 if !isPtrStructPtrSlice(vp.Type()) { 813 // The container is not a pointer to a struct pointer slice. 814 return errTypeMismatch(code, acode, ptr) 815 } 816 // Only use reflection for nil detection on slow path. 817 // Also, IsNil panics on many types, so check it after the type check. 818 if vp.IsNil() { 819 return errNilDst(p) 820 } 821 if isNull { 822 // The proto Value is encoding NULL, set the pointer to struct 823 // slice to nil as well. 824 vp.Elem().Set(reflect.Zero(vp.Elem().Type())) 825 break 826 } 827 x, err := getListValue(v) 828 if err != nil { 829 return err 830 } 831 if err = decodeStructArray(t.ArrayElementType.StructType, x, p); err != nil { 832 return err 833 } 834 } 835 return nil 836} 837 838// decodableSpannerType represents the Go types that a value from a Spanner 839// database can be converted to. 840type decodableSpannerType uint 841 842const ( 843 spannerTypeUnknown decodableSpannerType = iota 844 spannerTypeInvalid 845 spannerTypeNonNullString 846 spannerTypeByteArray 847 spannerTypeNonNullInt64 848 spannerTypeNonNullBool 849 spannerTypeNonNullFloat64 850 spannerTypeNonNullTime 851 spannerTypeNonNullDate 852 spannerTypeNullString 853 spannerTypeNullInt64 854 spannerTypeNullBool 855 spannerTypeNullFloat64 856 spannerTypeNullTime 857 spannerTypeNullDate 858 spannerTypeArrayOfNonNullString 859 spannerTypeArrayOfByteArray 860 spannerTypeArrayOfNonNullInt64 861 spannerTypeArrayOfNonNullBool 862 spannerTypeArrayOfNonNullFloat64 863 spannerTypeArrayOfNonNullTime 864 spannerTypeArrayOfNonNullDate 865 spannerTypeArrayOfNullString 866 spannerTypeArrayOfNullInt64 867 spannerTypeArrayOfNullBool 868 spannerTypeArrayOfNullFloat64 869 spannerTypeArrayOfNullTime 870 spannerTypeArrayOfNullDate 871) 872 873// supportsNull returns true for the Go types that can hold a null value from 874// Spanner. 875func (d decodableSpannerType) supportsNull() bool { 876 switch d { 877 case spannerTypeNonNullString, spannerTypeNonNullInt64, spannerTypeNonNullBool, spannerTypeNonNullFloat64, spannerTypeNonNullTime, spannerTypeNonNullDate: 878 return false 879 default: 880 return true 881 } 882} 883 884// The following list of types represent the struct types that represent a 885// specific Spanner data type in Go. If a pointer to one of these types is 886// passed to decodeValue, the client library will decode one column value into 887// the struct. For pointers to all other struct types, the client library will 888// treat it as a generic struct that should contain a field for each column in 889// the result set that is being decoded. 890 891var typeOfNonNullTime = reflect.TypeOf(time.Time{}) 892var typeOfNonNullDate = reflect.TypeOf(civil.Date{}) 893var typeOfNullString = reflect.TypeOf(NullString{}) 894var typeOfNullInt64 = reflect.TypeOf(NullInt64{}) 895var typeOfNullBool = reflect.TypeOf(NullBool{}) 896var typeOfNullFloat64 = reflect.TypeOf(NullFloat64{}) 897var typeOfNullTime = reflect.TypeOf(NullTime{}) 898var typeOfNullDate = reflect.TypeOf(NullDate{}) 899 900// getDecodableSpannerType returns the corresponding decodableSpannerType of 901// the given pointer. 902func getDecodableSpannerType(ptr interface{}) decodableSpannerType { 903 kind := reflect.Indirect(reflect.ValueOf(ptr)).Kind() 904 if kind == reflect.Invalid { 905 return spannerTypeInvalid 906 } 907 switch kind { 908 case reflect.Invalid: 909 return spannerTypeInvalid 910 case reflect.String: 911 return spannerTypeNonNullString 912 case reflect.Int64: 913 return spannerTypeNonNullInt64 914 case reflect.Bool: 915 return spannerTypeNonNullBool 916 case reflect.Float64: 917 return spannerTypeNonNullFloat64 918 case reflect.Struct: 919 t := reflect.Indirect(reflect.ValueOf(ptr)).Type() 920 if t.ConvertibleTo(typeOfNonNullTime) { 921 return spannerTypeNonNullTime 922 } 923 if t.ConvertibleTo(typeOfNonNullDate) { 924 return spannerTypeNonNullDate 925 } 926 if t.ConvertibleTo(typeOfNullString) { 927 return spannerTypeNullString 928 } 929 if t.ConvertibleTo(typeOfNullInt64) { 930 return spannerTypeNullInt64 931 } 932 if t.ConvertibleTo(typeOfNullBool) { 933 return spannerTypeNullBool 934 } 935 if t.ConvertibleTo(typeOfNullFloat64) { 936 return spannerTypeNullFloat64 937 } 938 if t.ConvertibleTo(typeOfNullTime) { 939 return spannerTypeNullTime 940 } 941 if t.ConvertibleTo(typeOfNullDate) { 942 return spannerTypeNullDate 943 } 944 case reflect.Slice: 945 kind := reflect.Indirect(reflect.ValueOf(ptr)).Type().Elem().Kind() 946 switch kind { 947 case reflect.Invalid: 948 return spannerTypeUnknown 949 case reflect.String: 950 return spannerTypeArrayOfNonNullString 951 case reflect.Uint8: 952 return spannerTypeByteArray 953 case reflect.Int64: 954 return spannerTypeArrayOfNonNullInt64 955 case reflect.Bool: 956 return spannerTypeArrayOfNonNullBool 957 case reflect.Float64: 958 return spannerTypeArrayOfNonNullFloat64 959 case reflect.Struct: 960 t := reflect.Indirect(reflect.ValueOf(ptr)).Type().Elem() 961 if t.ConvertibleTo(typeOfNonNullTime) { 962 return spannerTypeArrayOfNonNullTime 963 } 964 if t.ConvertibleTo(typeOfNonNullDate) { 965 return spannerTypeArrayOfNonNullDate 966 } 967 if t.ConvertibleTo(typeOfNullString) { 968 return spannerTypeArrayOfNullString 969 } 970 if t.ConvertibleTo(typeOfNullInt64) { 971 return spannerTypeArrayOfNullInt64 972 } 973 if t.ConvertibleTo(typeOfNullBool) { 974 return spannerTypeArrayOfNullBool 975 } 976 if t.ConvertibleTo(typeOfNullFloat64) { 977 return spannerTypeArrayOfNullFloat64 978 } 979 if t.ConvertibleTo(typeOfNullTime) { 980 return spannerTypeArrayOfNullTime 981 } 982 if t.ConvertibleTo(typeOfNullDate) { 983 return spannerTypeArrayOfNullDate 984 } 985 case reflect.Slice: 986 // The only array-of-array type that is supported is [][]byte. 987 kind := reflect.Indirect(reflect.ValueOf(ptr)).Type().Elem().Elem().Kind() 988 switch kind { 989 case reflect.Uint8: 990 return spannerTypeArrayOfByteArray 991 } 992 } 993 } 994 // Not convertible to a known base type. 995 return spannerTypeUnknown 996} 997 998// decodeValueToCustomType decodes a protobuf Value into a pointer to a Go 999// value. It must be possible to convert the value to the type pointed to by 1000// the pointer. 1001func (dsc decodableSpannerType) decodeValueToCustomType(v *proto3.Value, t *sppb.Type, acode sppb.TypeCode, ptr interface{}) error { 1002 code := t.Code 1003 _, isNull := v.Kind.(*proto3.Value_NullValue) 1004 if dsc == spannerTypeInvalid { 1005 return errNilDst(ptr) 1006 } 1007 if isNull && !dsc.supportsNull() { 1008 return errDstNotForNull(ptr) 1009 } 1010 1011 var result interface{} 1012 switch dsc { 1013 case spannerTypeNonNullString, spannerTypeNullString: 1014 if code != sppb.TypeCode_STRING { 1015 return errTypeMismatch(code, acode, ptr) 1016 } 1017 if isNull { 1018 result = &NullString{} 1019 break 1020 } 1021 x, err := getStringValue(v) 1022 if err != nil { 1023 return err 1024 } 1025 if dsc == spannerTypeNonNullString { 1026 result = &x 1027 } else { 1028 result = &NullString{x, !isNull} 1029 } 1030 case spannerTypeByteArray: 1031 if code != sppb.TypeCode_BYTES { 1032 return errTypeMismatch(code, acode, ptr) 1033 } 1034 if isNull { 1035 result = []byte(nil) 1036 break 1037 } 1038 x, err := getStringValue(v) 1039 if err != nil { 1040 return err 1041 } 1042 y, err := base64.StdEncoding.DecodeString(x) 1043 if err != nil { 1044 return errBadEncoding(v, err) 1045 } 1046 result = y 1047 case spannerTypeNonNullInt64, spannerTypeNullInt64: 1048 if code != sppb.TypeCode_INT64 { 1049 return errTypeMismatch(code, acode, ptr) 1050 } 1051 if isNull { 1052 result = &NullInt64{} 1053 break 1054 } 1055 x, err := getStringValue(v) 1056 if err != nil { 1057 return err 1058 } 1059 y, err := strconv.ParseInt(x, 10, 64) 1060 if err != nil { 1061 return errBadEncoding(v, err) 1062 } 1063 if dsc == spannerTypeNonNullInt64 { 1064 result = &y 1065 } else { 1066 result = &NullInt64{y, !isNull} 1067 } 1068 case spannerTypeNonNullBool, spannerTypeNullBool: 1069 if code != sppb.TypeCode_BOOL { 1070 return errTypeMismatch(code, acode, ptr) 1071 } 1072 if isNull { 1073 result = &NullBool{} 1074 break 1075 } 1076 x, err := getBoolValue(v) 1077 if err != nil { 1078 return err 1079 } 1080 if dsc == spannerTypeNonNullBool { 1081 result = &x 1082 } else { 1083 result = &NullBool{x, !isNull} 1084 } 1085 case spannerTypeNonNullFloat64, spannerTypeNullFloat64: 1086 if code != sppb.TypeCode_FLOAT64 { 1087 return errTypeMismatch(code, acode, ptr) 1088 } 1089 if isNull { 1090 result = &NullFloat64{} 1091 break 1092 } 1093 x, err := getFloat64Value(v) 1094 if err != nil { 1095 return err 1096 } 1097 if dsc == spannerTypeNonNullFloat64 { 1098 result = &x 1099 } else { 1100 result = &NullFloat64{x, !isNull} 1101 } 1102 case spannerTypeNonNullTime, spannerTypeNullTime: 1103 var nt NullTime 1104 err := parseNullTime(v, &nt, code, isNull) 1105 if err != nil { 1106 return err 1107 } 1108 if dsc == spannerTypeNonNullTime { 1109 result = &nt.Time 1110 } else { 1111 result = &nt 1112 } 1113 case spannerTypeNonNullDate, spannerTypeNullDate: 1114 if code != sppb.TypeCode_DATE { 1115 return errTypeMismatch(code, acode, ptr) 1116 } 1117 if isNull { 1118 result = &NullDate{} 1119 break 1120 } 1121 x, err := getStringValue(v) 1122 if err != nil { 1123 return err 1124 } 1125 y, err := civil.ParseDate(x) 1126 if err != nil { 1127 return errBadEncoding(v, err) 1128 } 1129 if dsc == spannerTypeNonNullDate { 1130 result = &y 1131 } else { 1132 result = &NullDate{y, !isNull} 1133 } 1134 case spannerTypeArrayOfNonNullString, spannerTypeArrayOfNullString: 1135 if acode != sppb.TypeCode_STRING { 1136 return errTypeMismatch(code, acode, ptr) 1137 } 1138 if isNull { 1139 ptr = nil 1140 return nil 1141 } 1142 x, err := getListValue(v) 1143 if err != nil { 1144 return err 1145 } 1146 y, err := decodeGenericArray(reflect.TypeOf(ptr).Elem(), x, stringType(), "STRING") 1147 if err != nil { 1148 return err 1149 } 1150 result = y 1151 case spannerTypeArrayOfByteArray: 1152 if acode != sppb.TypeCode_BYTES { 1153 return errTypeMismatch(code, acode, ptr) 1154 } 1155 if isNull { 1156 ptr = nil 1157 return nil 1158 } 1159 x, err := getListValue(v) 1160 if err != nil { 1161 return err 1162 } 1163 y, err := decodeGenericArray(reflect.TypeOf(ptr).Elem(), x, bytesType(), "BYTES") 1164 if err != nil { 1165 return err 1166 } 1167 result = y 1168 case spannerTypeArrayOfNonNullInt64, spannerTypeArrayOfNullInt64: 1169 if acode != sppb.TypeCode_INT64 { 1170 return errTypeMismatch(code, acode, ptr) 1171 } 1172 if isNull { 1173 ptr = nil 1174 return nil 1175 } 1176 x, err := getListValue(v) 1177 if err != nil { 1178 return err 1179 } 1180 y, err := decodeGenericArray(reflect.TypeOf(ptr).Elem(), x, intType(), "INT64") 1181 if err != nil { 1182 return err 1183 } 1184 result = y 1185 case spannerTypeArrayOfNonNullBool, spannerTypeArrayOfNullBool: 1186 if acode != sppb.TypeCode_BOOL { 1187 return errTypeMismatch(code, acode, ptr) 1188 } 1189 if isNull { 1190 ptr = nil 1191 return nil 1192 } 1193 x, err := getListValue(v) 1194 if err != nil { 1195 return err 1196 } 1197 y, err := decodeGenericArray(reflect.TypeOf(ptr).Elem(), x, boolType(), "BOOL") 1198 if err != nil { 1199 return err 1200 } 1201 result = y 1202 case spannerTypeArrayOfNonNullFloat64, spannerTypeArrayOfNullFloat64: 1203 if acode != sppb.TypeCode_FLOAT64 { 1204 return errTypeMismatch(code, acode, ptr) 1205 } 1206 if isNull { 1207 ptr = nil 1208 return nil 1209 } 1210 x, err := getListValue(v) 1211 if err != nil { 1212 return err 1213 } 1214 y, err := decodeGenericArray(reflect.TypeOf(ptr).Elem(), x, floatType(), "FLOAT64") 1215 if err != nil { 1216 return err 1217 } 1218 result = y 1219 case spannerTypeArrayOfNonNullTime, spannerTypeArrayOfNullTime: 1220 if acode != sppb.TypeCode_TIMESTAMP { 1221 return errTypeMismatch(code, acode, ptr) 1222 } 1223 if isNull { 1224 ptr = nil 1225 return nil 1226 } 1227 x, err := getListValue(v) 1228 if err != nil { 1229 return err 1230 } 1231 y, err := decodeGenericArray(reflect.TypeOf(ptr).Elem(), x, timeType(), "TIMESTAMP") 1232 if err != nil { 1233 return err 1234 } 1235 result = y 1236 case spannerTypeArrayOfNonNullDate, spannerTypeArrayOfNullDate: 1237 if acode != sppb.TypeCode_DATE { 1238 return errTypeMismatch(code, acode, ptr) 1239 } 1240 if isNull { 1241 ptr = nil 1242 return nil 1243 } 1244 x, err := getListValue(v) 1245 if err != nil { 1246 return err 1247 } 1248 y, err := decodeGenericArray(reflect.TypeOf(ptr).Elem(), x, dateType(), "DATE") 1249 if err != nil { 1250 return err 1251 } 1252 result = y 1253 default: 1254 // This should not be possible. 1255 return fmt.Errorf("unknown decodable type found: %v", dsc) 1256 } 1257 source := reflect.Indirect(reflect.ValueOf(result)) 1258 destination := reflect.Indirect(reflect.ValueOf(ptr)) 1259 destination.Set(source.Convert(destination.Type())) 1260 return nil 1261} 1262 1263// errSrvVal returns an error for getting a wrong source protobuf value in decoding. 1264func errSrcVal(v *proto3.Value, want string) error { 1265 return spannerErrorf(codes.FailedPrecondition, "cannot use %v(Kind: %T) as %s Value", 1266 v, v.GetKind(), want) 1267} 1268 1269// getStringValue returns the string value encoded in proto3.Value v whose 1270// kind is proto3.Value_StringValue. 1271func getStringValue(v *proto3.Value) (string, error) { 1272 if x, ok := v.GetKind().(*proto3.Value_StringValue); ok && x != nil { 1273 return x.StringValue, nil 1274 } 1275 return "", errSrcVal(v, "String") 1276} 1277 1278// getBoolValue returns the bool value encoded in proto3.Value v whose 1279// kind is proto3.Value_BoolValue. 1280func getBoolValue(v *proto3.Value) (bool, error) { 1281 if x, ok := v.GetKind().(*proto3.Value_BoolValue); ok && x != nil { 1282 return x.BoolValue, nil 1283 } 1284 return false, errSrcVal(v, "Bool") 1285} 1286 1287// getListValue returns the proto3.ListValue contained in proto3.Value v whose 1288// kind is proto3.Value_ListValue. 1289func getListValue(v *proto3.Value) (*proto3.ListValue, error) { 1290 if x, ok := v.GetKind().(*proto3.Value_ListValue); ok && x != nil { 1291 return x.ListValue, nil 1292 } 1293 return nil, errSrcVal(v, "List") 1294} 1295 1296// errUnexpectedNumStr returns error for decoder getting a unexpected string for 1297// representing special float values. 1298func errUnexpectedNumStr(s string) error { 1299 return spannerErrorf(codes.FailedPrecondition, "unexpected string value %q for number", s) 1300} 1301 1302// getFloat64Value returns the float64 value encoded in proto3.Value v whose 1303// kind is proto3.Value_NumberValue / proto3.Value_StringValue. 1304// Cloud Spanner uses string to encode NaN, Infinity and -Infinity. 1305func getFloat64Value(v *proto3.Value) (float64, error) { 1306 switch x := v.GetKind().(type) { 1307 case *proto3.Value_NumberValue: 1308 if x == nil { 1309 break 1310 } 1311 return x.NumberValue, nil 1312 case *proto3.Value_StringValue: 1313 if x == nil { 1314 break 1315 } 1316 switch x.StringValue { 1317 case "NaN": 1318 return math.NaN(), nil 1319 case "Infinity": 1320 return math.Inf(1), nil 1321 case "-Infinity": 1322 return math.Inf(-1), nil 1323 default: 1324 return 0, errUnexpectedNumStr(x.StringValue) 1325 } 1326 } 1327 return 0, errSrcVal(v, "Number") 1328} 1329 1330// errNilListValue returns error for unexpected nil ListValue in decoding Cloud Spanner ARRAYs. 1331func errNilListValue(sqlType string) error { 1332 return spannerErrorf(codes.FailedPrecondition, "unexpected nil ListValue in decoding %v array", sqlType) 1333} 1334 1335// errDecodeArrayElement returns error for failure in decoding single array element. 1336func errDecodeArrayElement(i int, v proto.Message, sqlType string, err error) error { 1337 var se *Error 1338 if !errorAs(err, &se) { 1339 return spannerErrorf(codes.Unknown, 1340 "cannot decode %v(array element %v) as %v, error = <%v>", v, i, sqlType, err) 1341 } 1342 se.decorate(fmt.Sprintf("cannot decode %v(array element %v) as %v", v, i, sqlType)) 1343 return se 1344} 1345 1346// decodeGenericArray decodes proto3.ListValue pb into a slice which type is 1347// determined through reflection. 1348func decodeGenericArray(tp reflect.Type, pb *proto3.ListValue, t *sppb.Type, sqlType string) (interface{}, error) { 1349 if pb == nil { 1350 return nil, errNilListValue(sqlType) 1351 } 1352 a := reflect.MakeSlice(tp, len(pb.Values), len(pb.Values)) 1353 for i, v := range pb.Values { 1354 if err := decodeValue(v, t, a.Index(i).Addr().Interface()); err != nil { 1355 return nil, errDecodeArrayElement(i, v, "STRING", err) 1356 } 1357 } 1358 return a.Interface(), nil 1359} 1360 1361// decodeNullStringArray decodes proto3.ListValue pb into a NullString slice. 1362func decodeNullStringArray(pb *proto3.ListValue) ([]NullString, error) { 1363 if pb == nil { 1364 return nil, errNilListValue("STRING") 1365 } 1366 a := make([]NullString, len(pb.Values)) 1367 for i, v := range pb.Values { 1368 if err := decodeValue(v, stringType(), &a[i]); err != nil { 1369 return nil, errDecodeArrayElement(i, v, "STRING", err) 1370 } 1371 } 1372 return a, nil 1373} 1374 1375// decodeStringArray decodes proto3.ListValue pb into a string slice. 1376func decodeStringArray(pb *proto3.ListValue) ([]string, error) { 1377 if pb == nil { 1378 return nil, errNilListValue("STRING") 1379 } 1380 a := make([]string, len(pb.Values)) 1381 st := stringType() 1382 for i, v := range pb.Values { 1383 if err := decodeValue(v, st, &a[i]); err != nil { 1384 return nil, errDecodeArrayElement(i, v, "STRING", err) 1385 } 1386 } 1387 return a, nil 1388} 1389 1390// decodeNullInt64Array decodes proto3.ListValue pb into a NullInt64 slice. 1391func decodeNullInt64Array(pb *proto3.ListValue) ([]NullInt64, error) { 1392 if pb == nil { 1393 return nil, errNilListValue("INT64") 1394 } 1395 a := make([]NullInt64, len(pb.Values)) 1396 for i, v := range pb.Values { 1397 if err := decodeValue(v, intType(), &a[i]); err != nil { 1398 return nil, errDecodeArrayElement(i, v, "INT64", err) 1399 } 1400 } 1401 return a, nil 1402} 1403 1404// decodeInt64Array decodes proto3.ListValue pb into a int64 slice. 1405func decodeInt64Array(pb *proto3.ListValue) ([]int64, error) { 1406 if pb == nil { 1407 return nil, errNilListValue("INT64") 1408 } 1409 a := make([]int64, len(pb.Values)) 1410 for i, v := range pb.Values { 1411 if err := decodeValue(v, intType(), &a[i]); err != nil { 1412 return nil, errDecodeArrayElement(i, v, "INT64", err) 1413 } 1414 } 1415 return a, nil 1416} 1417 1418// decodeNullBoolArray decodes proto3.ListValue pb into a NullBool slice. 1419func decodeNullBoolArray(pb *proto3.ListValue) ([]NullBool, error) { 1420 if pb == nil { 1421 return nil, errNilListValue("BOOL") 1422 } 1423 a := make([]NullBool, len(pb.Values)) 1424 for i, v := range pb.Values { 1425 if err := decodeValue(v, boolType(), &a[i]); err != nil { 1426 return nil, errDecodeArrayElement(i, v, "BOOL", err) 1427 } 1428 } 1429 return a, nil 1430} 1431 1432// decodeBoolArray decodes proto3.ListValue pb into a bool slice. 1433func decodeBoolArray(pb *proto3.ListValue) ([]bool, error) { 1434 if pb == nil { 1435 return nil, errNilListValue("BOOL") 1436 } 1437 a := make([]bool, len(pb.Values)) 1438 for i, v := range pb.Values { 1439 if err := decodeValue(v, boolType(), &a[i]); err != nil { 1440 return nil, errDecodeArrayElement(i, v, "BOOL", err) 1441 } 1442 } 1443 return a, nil 1444} 1445 1446// decodeNullFloat64Array decodes proto3.ListValue pb into a NullFloat64 slice. 1447func decodeNullFloat64Array(pb *proto3.ListValue) ([]NullFloat64, error) { 1448 if pb == nil { 1449 return nil, errNilListValue("FLOAT64") 1450 } 1451 a := make([]NullFloat64, len(pb.Values)) 1452 for i, v := range pb.Values { 1453 if err := decodeValue(v, floatType(), &a[i]); err != nil { 1454 return nil, errDecodeArrayElement(i, v, "FLOAT64", err) 1455 } 1456 } 1457 return a, nil 1458} 1459 1460// decodeFloat64Array decodes proto3.ListValue pb into a float64 slice. 1461func decodeFloat64Array(pb *proto3.ListValue) ([]float64, error) { 1462 if pb == nil { 1463 return nil, errNilListValue("FLOAT64") 1464 } 1465 a := make([]float64, len(pb.Values)) 1466 for i, v := range pb.Values { 1467 if err := decodeValue(v, floatType(), &a[i]); err != nil { 1468 return nil, errDecodeArrayElement(i, v, "FLOAT64", err) 1469 } 1470 } 1471 return a, nil 1472} 1473 1474// decodeByteArray decodes proto3.ListValue pb into a slice of byte slice. 1475func decodeByteArray(pb *proto3.ListValue) ([][]byte, error) { 1476 if pb == nil { 1477 return nil, errNilListValue("BYTES") 1478 } 1479 a := make([][]byte, len(pb.Values)) 1480 for i, v := range pb.Values { 1481 if err := decodeValue(v, bytesType(), &a[i]); err != nil { 1482 return nil, errDecodeArrayElement(i, v, "BYTES", err) 1483 } 1484 } 1485 return a, nil 1486} 1487 1488// decodeNullTimeArray decodes proto3.ListValue pb into a NullTime slice. 1489func decodeNullTimeArray(pb *proto3.ListValue) ([]NullTime, error) { 1490 if pb == nil { 1491 return nil, errNilListValue("TIMESTAMP") 1492 } 1493 a := make([]NullTime, len(pb.Values)) 1494 for i, v := range pb.Values { 1495 if err := decodeValue(v, timeType(), &a[i]); err != nil { 1496 return nil, errDecodeArrayElement(i, v, "TIMESTAMP", err) 1497 } 1498 } 1499 return a, nil 1500} 1501 1502// decodeTimeArray decodes proto3.ListValue pb into a time.Time slice. 1503func decodeTimeArray(pb *proto3.ListValue) ([]time.Time, error) { 1504 if pb == nil { 1505 return nil, errNilListValue("TIMESTAMP") 1506 } 1507 a := make([]time.Time, len(pb.Values)) 1508 for i, v := range pb.Values { 1509 if err := decodeValue(v, timeType(), &a[i]); err != nil { 1510 return nil, errDecodeArrayElement(i, v, "TIMESTAMP", err) 1511 } 1512 } 1513 return a, nil 1514} 1515 1516// decodeNullDateArray decodes proto3.ListValue pb into a NullDate slice. 1517func decodeNullDateArray(pb *proto3.ListValue) ([]NullDate, error) { 1518 if pb == nil { 1519 return nil, errNilListValue("DATE") 1520 } 1521 a := make([]NullDate, len(pb.Values)) 1522 for i, v := range pb.Values { 1523 if err := decodeValue(v, dateType(), &a[i]); err != nil { 1524 return nil, errDecodeArrayElement(i, v, "DATE", err) 1525 } 1526 } 1527 return a, nil 1528} 1529 1530// decodeDateArray decodes proto3.ListValue pb into a civil.Date slice. 1531func decodeDateArray(pb *proto3.ListValue) ([]civil.Date, error) { 1532 if pb == nil { 1533 return nil, errNilListValue("DATE") 1534 } 1535 a := make([]civil.Date, len(pb.Values)) 1536 for i, v := range pb.Values { 1537 if err := decodeValue(v, dateType(), &a[i]); err != nil { 1538 return nil, errDecodeArrayElement(i, v, "DATE", err) 1539 } 1540 } 1541 return a, nil 1542} 1543 1544func errNotStructElement(i int, v *proto3.Value) error { 1545 return errDecodeArrayElement(i, v, "STRUCT", 1546 spannerErrorf(codes.FailedPrecondition, "%v(type: %T) doesn't encode Cloud Spanner STRUCT", v, v)) 1547} 1548 1549// decodeRowArray decodes proto3.ListValue pb into a NullRow slice according to 1550// the structural information given in sppb.StructType ty. 1551func decodeRowArray(ty *sppb.StructType, pb *proto3.ListValue) ([]NullRow, error) { 1552 if pb == nil { 1553 return nil, errNilListValue("STRUCT") 1554 } 1555 a := make([]NullRow, len(pb.Values)) 1556 for i := range pb.Values { 1557 switch v := pb.Values[i].GetKind().(type) { 1558 case *proto3.Value_ListValue: 1559 a[i] = NullRow{ 1560 Row: Row{ 1561 fields: ty.Fields, 1562 vals: v.ListValue.Values, 1563 }, 1564 Valid: true, 1565 } 1566 // Null elements not currently supported by the server, see 1567 // https://cloud.google.com/spanner/docs/query-syntax#using-structs-with-select 1568 case *proto3.Value_NullValue: 1569 // no-op, a[i] is NullRow{} already 1570 default: 1571 return nil, errNotStructElement(i, pb.Values[i]) 1572 } 1573 } 1574 return a, nil 1575} 1576 1577// errNilSpannerStructType returns error for unexpected nil Cloud Spanner STRUCT 1578// schema type in decoding. 1579func errNilSpannerStructType() error { 1580 return spannerErrorf(codes.FailedPrecondition, "unexpected nil StructType in decoding Cloud Spanner STRUCT") 1581} 1582 1583// errUnnamedField returns error for decoding a Cloud Spanner STRUCT with 1584// unnamed field into a Go struct. 1585func errUnnamedField(ty *sppb.StructType, i int) error { 1586 return spannerErrorf(codes.InvalidArgument, "unnamed field %v in Cloud Spanner STRUCT %+v", i, ty) 1587} 1588 1589// errNoOrDupGoField returns error for decoding a Cloud Spanner 1590// STRUCT into a Go struct which is either missing a field, or has duplicate 1591// fields. 1592func errNoOrDupGoField(s interface{}, f string) error { 1593 return spannerErrorf(codes.InvalidArgument, "Go struct %+v(type %T) has no or duplicate fields for Cloud Spanner STRUCT field %v", s, s, f) 1594} 1595 1596// errDupColNames returns error for duplicated Cloud Spanner STRUCT field names 1597// found in decoding a Cloud Spanner STRUCT into a Go struct. 1598func errDupSpannerField(f string, ty *sppb.StructType) error { 1599 return spannerErrorf(codes.InvalidArgument, "duplicated field name %q in Cloud Spanner STRUCT %+v", f, ty) 1600} 1601 1602// errDecodeStructField returns error for failure in decoding a single field of 1603// a Cloud Spanner STRUCT. 1604func errDecodeStructField(ty *sppb.StructType, f string, err error) error { 1605 var se *Error 1606 if !errorAs(err, &se) { 1607 return spannerErrorf(codes.Unknown, 1608 "cannot decode field %v of Cloud Spanner STRUCT %+v, error = <%v>", f, ty, err) 1609 } 1610 se.decorate(fmt.Sprintf("cannot decode field %v of Cloud Spanner STRUCT %+v", f, ty)) 1611 return se 1612} 1613 1614// decodeStruct decodes proto3.ListValue pb into struct referenced by pointer 1615// ptr, according to 1616// the structural information given in sppb.StructType ty. 1617func decodeStruct(ty *sppb.StructType, pb *proto3.ListValue, ptr interface{}) error { 1618 if reflect.ValueOf(ptr).IsNil() { 1619 return errNilDst(ptr) 1620 } 1621 if ty == nil { 1622 return errNilSpannerStructType() 1623 } 1624 // t holds the structural information of ptr. 1625 t := reflect.TypeOf(ptr).Elem() 1626 // v is the actual value that ptr points to. 1627 v := reflect.ValueOf(ptr).Elem() 1628 1629 fields, err := fieldCache.Fields(t) 1630 if err != nil { 1631 return toSpannerError(err) 1632 } 1633 seen := map[string]bool{} 1634 for i, f := range ty.Fields { 1635 if f.Name == "" { 1636 return errUnnamedField(ty, i) 1637 } 1638 sf := fields.Match(f.Name) 1639 if sf == nil { 1640 return errNoOrDupGoField(ptr, f.Name) 1641 } 1642 if seen[f.Name] { 1643 // We don't allow duplicated field name. 1644 return errDupSpannerField(f.Name, ty) 1645 } 1646 // Try to decode a single field. 1647 if err := decodeValue(pb.Values[i], f.Type, v.FieldByIndex(sf.Index).Addr().Interface()); err != nil { 1648 return errDecodeStructField(ty, f.Name, err) 1649 } 1650 // Mark field f.Name as processed. 1651 seen[f.Name] = true 1652 } 1653 return nil 1654} 1655 1656// isPtrStructPtrSlice returns true if ptr is a pointer to a slice of struct pointers. 1657func isPtrStructPtrSlice(t reflect.Type) bool { 1658 if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Slice { 1659 // t is not a pointer to a slice. 1660 return false 1661 } 1662 if t = t.Elem(); t.Elem().Kind() != reflect.Ptr || t.Elem().Elem().Kind() != reflect.Struct { 1663 // the slice that t points to is not a slice of struct pointers. 1664 return false 1665 } 1666 return true 1667} 1668 1669// decodeStructArray decodes proto3.ListValue pb into struct slice referenced by 1670// pointer ptr, according to the 1671// structural information given in a sppb.StructType. 1672func decodeStructArray(ty *sppb.StructType, pb *proto3.ListValue, ptr interface{}) error { 1673 if pb == nil { 1674 return errNilListValue("STRUCT") 1675 } 1676 // Type of the struct pointers stored in the slice that ptr points to. 1677 ts := reflect.TypeOf(ptr).Elem().Elem() 1678 // The slice that ptr points to, might be nil at this point. 1679 v := reflect.ValueOf(ptr).Elem() 1680 // Allocate empty slice. 1681 v.Set(reflect.MakeSlice(v.Type(), 0, len(pb.Values))) 1682 // Decode every struct in pb.Values. 1683 for i, pv := range pb.Values { 1684 // Check if pv is a NULL value. 1685 if _, isNull := pv.Kind.(*proto3.Value_NullValue); isNull { 1686 // Append a nil pointer to the slice. 1687 v.Set(reflect.Append(v, reflect.New(ts).Elem())) 1688 continue 1689 } 1690 // Allocate empty struct. 1691 s := reflect.New(ts.Elem()) 1692 // Get proto3.ListValue l from proto3.Value pv. 1693 l, err := getListValue(pv) 1694 if err != nil { 1695 return errDecodeArrayElement(i, pv, "STRUCT", err) 1696 } 1697 // Decode proto3.ListValue l into struct referenced by s.Interface(). 1698 if err = decodeStruct(ty, l, s.Interface()); err != nil { 1699 return errDecodeArrayElement(i, pv, "STRUCT", err) 1700 } 1701 // Append the decoded struct back into the slice. 1702 v.Set(reflect.Append(v, s)) 1703 } 1704 return nil 1705} 1706 1707// errEncoderUnsupportedType returns error for not being able to encode a value 1708// of certain type. 1709func errEncoderUnsupportedType(v interface{}) error { 1710 return spannerErrorf(codes.InvalidArgument, "client doesn't support type %T", v) 1711} 1712 1713// encodeValue encodes a Go native type into a proto3.Value. 1714func encodeValue(v interface{}) (*proto3.Value, *sppb.Type, error) { 1715 pb := &proto3.Value{ 1716 Kind: &proto3.Value_NullValue{NullValue: proto3.NullValue_NULL_VALUE}, 1717 } 1718 var pt *sppb.Type 1719 var err error 1720 switch v := v.(type) { 1721 case nil: 1722 case string: 1723 pb.Kind = stringKind(v) 1724 pt = stringType() 1725 case NullString: 1726 if v.Valid { 1727 return encodeValue(v.StringVal) 1728 } 1729 pt = stringType() 1730 case []string: 1731 if v != nil { 1732 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1733 if err != nil { 1734 return nil, nil, err 1735 } 1736 } 1737 pt = listType(stringType()) 1738 case []NullString: 1739 if v != nil { 1740 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1741 if err != nil { 1742 return nil, nil, err 1743 } 1744 } 1745 pt = listType(stringType()) 1746 case []byte: 1747 if v != nil { 1748 pb.Kind = stringKind(base64.StdEncoding.EncodeToString(v)) 1749 } 1750 pt = bytesType() 1751 case [][]byte: 1752 if v != nil { 1753 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1754 if err != nil { 1755 return nil, nil, err 1756 } 1757 } 1758 pt = listType(bytesType()) 1759 case int: 1760 pb.Kind = stringKind(strconv.FormatInt(int64(v), 10)) 1761 pt = intType() 1762 case []int: 1763 if v != nil { 1764 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1765 if err != nil { 1766 return nil, nil, err 1767 } 1768 } 1769 pt = listType(intType()) 1770 case int64: 1771 pb.Kind = stringKind(strconv.FormatInt(v, 10)) 1772 pt = intType() 1773 case []int64: 1774 if v != nil { 1775 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1776 if err != nil { 1777 return nil, nil, err 1778 } 1779 } 1780 pt = listType(intType()) 1781 case NullInt64: 1782 if v.Valid { 1783 return encodeValue(v.Int64) 1784 } 1785 pt = intType() 1786 case []NullInt64: 1787 if v != nil { 1788 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1789 if err != nil { 1790 return nil, nil, err 1791 } 1792 } 1793 pt = listType(intType()) 1794 case bool: 1795 pb.Kind = &proto3.Value_BoolValue{BoolValue: v} 1796 pt = boolType() 1797 case []bool: 1798 if v != nil { 1799 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1800 if err != nil { 1801 return nil, nil, err 1802 } 1803 } 1804 pt = listType(boolType()) 1805 case NullBool: 1806 if v.Valid { 1807 return encodeValue(v.Bool) 1808 } 1809 pt = boolType() 1810 case []NullBool: 1811 if v != nil { 1812 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1813 if err != nil { 1814 return nil, nil, err 1815 } 1816 } 1817 pt = listType(boolType()) 1818 case float64: 1819 pb.Kind = &proto3.Value_NumberValue{NumberValue: v} 1820 pt = floatType() 1821 case []float64: 1822 if v != nil { 1823 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1824 if err != nil { 1825 return nil, nil, err 1826 } 1827 } 1828 pt = listType(floatType()) 1829 case NullFloat64: 1830 if v.Valid { 1831 return encodeValue(v.Float64) 1832 } 1833 pt = floatType() 1834 case []NullFloat64: 1835 if v != nil { 1836 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1837 if err != nil { 1838 return nil, nil, err 1839 } 1840 } 1841 pt = listType(floatType()) 1842 case time.Time: 1843 if v == commitTimestamp { 1844 pb.Kind = stringKind(commitTimestampPlaceholderString) 1845 } else { 1846 pb.Kind = stringKind(v.UTC().Format(time.RFC3339Nano)) 1847 } 1848 pt = timeType() 1849 case []time.Time: 1850 if v != nil { 1851 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1852 if err != nil { 1853 return nil, nil, err 1854 } 1855 } 1856 pt = listType(timeType()) 1857 case NullTime: 1858 if v.Valid { 1859 return encodeValue(v.Time) 1860 } 1861 pt = timeType() 1862 case []NullTime: 1863 if v != nil { 1864 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1865 if err != nil { 1866 return nil, nil, err 1867 } 1868 } 1869 pt = listType(timeType()) 1870 case civil.Date: 1871 pb.Kind = stringKind(v.String()) 1872 pt = dateType() 1873 case []civil.Date: 1874 if v != nil { 1875 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1876 if err != nil { 1877 return nil, nil, err 1878 } 1879 } 1880 pt = listType(dateType()) 1881 case NullDate: 1882 if v.Valid { 1883 return encodeValue(v.Date) 1884 } 1885 pt = dateType() 1886 case []NullDate: 1887 if v != nil { 1888 pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) 1889 if err != nil { 1890 return nil, nil, err 1891 } 1892 } 1893 pt = listType(dateType()) 1894 case GenericColumnValue: 1895 // Deep clone to ensure subsequent changes to v before 1896 // transmission don't affect our encoded value. 1897 pb = proto.Clone(v.Value).(*proto3.Value) 1898 pt = proto.Clone(v.Type).(*sppb.Type) 1899 case []GenericColumnValue: 1900 return nil, nil, errEncoderUnsupportedType(v) 1901 default: 1902 // Check if the value is a variant of a base type. 1903 decodableType := getDecodableSpannerType(v) 1904 if decodableType != spannerTypeUnknown && decodableType != spannerTypeInvalid { 1905 converted, err := convertCustomTypeValue(decodableType, v) 1906 if err != nil { 1907 return nil, nil, err 1908 } 1909 return encodeValue(converted) 1910 } 1911 1912 if !isStructOrArrayOfStructValue(v) { 1913 return nil, nil, errEncoderUnsupportedType(v) 1914 } 1915 typ := reflect.TypeOf(v) 1916 1917 // Value is a Go struct value/ptr. 1918 if (typ.Kind() == reflect.Struct) || 1919 (typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct) { 1920 return encodeStruct(v) 1921 } 1922 1923 // Value is a slice of Go struct values/ptrs. 1924 if typ.Kind() == reflect.Slice { 1925 return encodeStructArray(v) 1926 } 1927 } 1928 return pb, pt, nil 1929} 1930 1931func convertCustomTypeValue(sourceType decodableSpannerType, v interface{}) (interface{}, error) { 1932 // destination will be initialized to a base type. The input value will be 1933 // converted to this type and copied to destination. 1934 var destination reflect.Value 1935 switch sourceType { 1936 case spannerTypeInvalid: 1937 return nil, fmt.Errorf("cannot encode a value to type spannerTypeInvalid") 1938 case spannerTypeNonNullString: 1939 destination = reflect.Indirect(reflect.New(reflect.TypeOf(""))) 1940 case spannerTypeNullString: 1941 destination = reflect.Indirect(reflect.New(reflect.TypeOf(NullString{}))) 1942 case spannerTypeByteArray: 1943 // Return a nil array directly if the input value is nil instead of 1944 // creating an empty slice and returning that. 1945 if reflect.ValueOf(v).IsNil() { 1946 return []byte(nil), nil 1947 } 1948 destination = reflect.MakeSlice(reflect.TypeOf([]byte{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 1949 case spannerTypeNonNullInt64: 1950 destination = reflect.Indirect(reflect.New(reflect.TypeOf(int64(0)))) 1951 case spannerTypeNullInt64: 1952 destination = reflect.Indirect(reflect.New(reflect.TypeOf(NullInt64{}))) 1953 case spannerTypeNonNullBool: 1954 destination = reflect.Indirect(reflect.New(reflect.TypeOf(false))) 1955 case spannerTypeNullBool: 1956 destination = reflect.Indirect(reflect.New(reflect.TypeOf(NullBool{}))) 1957 case spannerTypeNonNullFloat64: 1958 destination = reflect.Indirect(reflect.New(reflect.TypeOf(float64(0.0)))) 1959 case spannerTypeNullFloat64: 1960 destination = reflect.Indirect(reflect.New(reflect.TypeOf(NullFloat64{}))) 1961 case spannerTypeNonNullTime: 1962 destination = reflect.Indirect(reflect.New(reflect.TypeOf(time.Time{}))) 1963 case spannerTypeNullTime: 1964 destination = reflect.Indirect(reflect.New(reflect.TypeOf(NullTime{}))) 1965 case spannerTypeNonNullDate: 1966 destination = reflect.Indirect(reflect.New(reflect.TypeOf(civil.Date{}))) 1967 case spannerTypeNullDate: 1968 destination = reflect.Indirect(reflect.New(reflect.TypeOf(NullDate{}))) 1969 case spannerTypeArrayOfNonNullString: 1970 if reflect.ValueOf(v).IsNil() { 1971 return []string(nil), nil 1972 } 1973 destination = reflect.MakeSlice(reflect.TypeOf([]string{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 1974 case spannerTypeArrayOfNullString: 1975 if reflect.ValueOf(v).IsNil() { 1976 return []NullString(nil), nil 1977 } 1978 destination = reflect.MakeSlice(reflect.TypeOf([]NullString{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 1979 case spannerTypeArrayOfByteArray: 1980 if reflect.ValueOf(v).IsNil() { 1981 return [][]byte(nil), nil 1982 } 1983 destination = reflect.MakeSlice(reflect.TypeOf([][]byte{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 1984 case spannerTypeArrayOfNonNullInt64: 1985 if reflect.ValueOf(v).IsNil() { 1986 return []int64(nil), nil 1987 } 1988 destination = reflect.MakeSlice(reflect.TypeOf([]int64{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 1989 case spannerTypeArrayOfNullInt64: 1990 if reflect.ValueOf(v).IsNil() { 1991 return []NullInt64(nil), nil 1992 } 1993 destination = reflect.MakeSlice(reflect.TypeOf([]NullInt64{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 1994 case spannerTypeArrayOfNonNullBool: 1995 if reflect.ValueOf(v).IsNil() { 1996 return []bool(nil), nil 1997 } 1998 destination = reflect.MakeSlice(reflect.TypeOf([]bool{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 1999 case spannerTypeArrayOfNullBool: 2000 if reflect.ValueOf(v).IsNil() { 2001 return []NullBool(nil), nil 2002 } 2003 destination = reflect.MakeSlice(reflect.TypeOf([]NullBool{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 2004 case spannerTypeArrayOfNonNullFloat64: 2005 if reflect.ValueOf(v).IsNil() { 2006 return []float64(nil), nil 2007 } 2008 destination = reflect.MakeSlice(reflect.TypeOf([]float64{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 2009 case spannerTypeArrayOfNullFloat64: 2010 if reflect.ValueOf(v).IsNil() { 2011 return []NullFloat64(nil), nil 2012 } 2013 destination = reflect.MakeSlice(reflect.TypeOf([]NullFloat64{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 2014 case spannerTypeArrayOfNonNullTime: 2015 if reflect.ValueOf(v).IsNil() { 2016 return []time.Time(nil), nil 2017 } 2018 destination = reflect.MakeSlice(reflect.TypeOf([]time.Time{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 2019 case spannerTypeArrayOfNullTime: 2020 if reflect.ValueOf(v).IsNil() { 2021 return []NullTime(nil), nil 2022 } 2023 destination = reflect.MakeSlice(reflect.TypeOf([]NullTime{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 2024 case spannerTypeArrayOfNonNullDate: 2025 if reflect.ValueOf(v).IsNil() { 2026 return []civil.Date(nil), nil 2027 } 2028 destination = reflect.MakeSlice(reflect.TypeOf([]civil.Date{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 2029 case spannerTypeArrayOfNullDate: 2030 if reflect.ValueOf(v).IsNil() { 2031 return []NullDate(nil), nil 2032 } 2033 destination = reflect.MakeSlice(reflect.TypeOf([]NullDate{}), reflect.ValueOf(v).Len(), reflect.ValueOf(v).Cap()) 2034 default: 2035 // This should not be possible. 2036 return nil, fmt.Errorf("unknown decodable type found: %v", sourceType) 2037 } 2038 // destination has been initialized. Convert and copy the input value to 2039 // destination. That must be done per element if the input type is a slice 2040 // or an array. 2041 if destination.Kind() == reflect.Slice || destination.Kind() == reflect.Array { 2042 sourceSlice := reflect.ValueOf(v) 2043 for i := 0; i < destination.Len(); i++ { 2044 source := reflect.Indirect(sourceSlice.Index(i)) 2045 destination.Index(i).Set(source.Convert(destination.Type().Elem())) 2046 } 2047 } else { 2048 source := reflect.Indirect(reflect.ValueOf(v)) 2049 destination.Set(source.Convert(destination.Type())) 2050 } 2051 // Return the converted value. 2052 return destination.Interface(), nil 2053} 2054 2055// Encodes a Go struct value/ptr in v to the spanner Value and Type protos. v 2056// itself must be non-nil. 2057func encodeStruct(v interface{}) (*proto3.Value, *sppb.Type, error) { 2058 typ := reflect.TypeOf(v) 2059 val := reflect.ValueOf(v) 2060 2061 // Pointer to struct. 2062 if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct { 2063 typ = typ.Elem() 2064 if val.IsNil() { 2065 // nil pointer to struct, representing a NULL STRUCT value. Use a 2066 // dummy value to get the type. 2067 _, st, err := encodeStruct(reflect.Zero(typ).Interface()) 2068 if err != nil { 2069 return nil, nil, err 2070 } 2071 return nullProto(), st, nil 2072 } 2073 val = val.Elem() 2074 } 2075 2076 if typ.Kind() != reflect.Struct { 2077 return nil, nil, errEncoderUnsupportedType(v) 2078 } 2079 2080 stf := make([]*sppb.StructType_Field, 0, typ.NumField()) 2081 stv := make([]*proto3.Value, 0, typ.NumField()) 2082 2083 for i := 0; i < typ.NumField(); i++ { 2084 // If the field has a 'spanner' tag, use the value of that tag as the field name. 2085 // This is used to build STRUCT types with unnamed/duplicate fields. 2086 sf := typ.Field(i) 2087 fval := val.Field(i) 2088 2089 // Embedded fields are not allowed. 2090 if sf.Anonymous { 2091 return nil, nil, errUnsupportedEmbeddedStructFields(sf.Name) 2092 } 2093 2094 // Unexported fields are ignored. 2095 if !fval.CanInterface() { 2096 continue 2097 } 2098 2099 fname, ok := sf.Tag.Lookup("spanner") 2100 if !ok { 2101 fname = sf.Name 2102 } 2103 2104 eval, etype, err := encodeValue(fval.Interface()) 2105 if err != nil { 2106 return nil, nil, err 2107 } 2108 2109 stf = append(stf, mkField(fname, etype)) 2110 stv = append(stv, eval) 2111 } 2112 2113 return listProto(stv...), structType(stf...), nil 2114} 2115 2116// Encodes a slice of Go struct values/ptrs in v to the spanner Value and Type 2117// protos. v itself must be non-nil. 2118func encodeStructArray(v interface{}) (*proto3.Value, *sppb.Type, error) { 2119 etyp := reflect.TypeOf(v).Elem() 2120 sliceval := reflect.ValueOf(v) 2121 2122 // Slice of pointers to structs. 2123 if etyp.Kind() == reflect.Ptr { 2124 etyp = etyp.Elem() 2125 } 2126 2127 // Use a dummy struct value to get the element type. 2128 _, elemTyp, err := encodeStruct(reflect.Zero(etyp).Interface()) 2129 if err != nil { 2130 return nil, nil, err 2131 } 2132 2133 // nil slice represents a NULL array-of-struct. 2134 if sliceval.IsNil() { 2135 return nullProto(), listType(elemTyp), nil 2136 } 2137 2138 values := make([]*proto3.Value, 0, sliceval.Len()) 2139 2140 for i := 0; i < sliceval.Len(); i++ { 2141 ev, _, err := encodeStruct(sliceval.Index(i).Interface()) 2142 if err != nil { 2143 return nil, nil, err 2144 } 2145 values = append(values, ev) 2146 } 2147 return listProto(values...), listType(elemTyp), nil 2148} 2149 2150func isStructOrArrayOfStructValue(v interface{}) bool { 2151 typ := reflect.TypeOf(v) 2152 if typ.Kind() == reflect.Slice { 2153 typ = typ.Elem() 2154 } 2155 if typ.Kind() == reflect.Ptr { 2156 typ = typ.Elem() 2157 } 2158 return typ.Kind() == reflect.Struct 2159} 2160 2161func isSupportedMutationType(v interface{}) bool { 2162 switch v.(type) { 2163 case nil, string, NullString, []string, []NullString, 2164 []byte, [][]byte, 2165 int, []int, int64, []int64, NullInt64, []NullInt64, 2166 bool, []bool, NullBool, []NullBool, 2167 float64, []float64, NullFloat64, []NullFloat64, 2168 time.Time, []time.Time, NullTime, []NullTime, 2169 civil.Date, []civil.Date, NullDate, []NullDate, 2170 GenericColumnValue: 2171 return true 2172 default: 2173 return false 2174 } 2175} 2176 2177// encodeValueArray encodes a Value array into a proto3.ListValue. 2178func encodeValueArray(vs []interface{}) (*proto3.ListValue, error) { 2179 lv := &proto3.ListValue{} 2180 lv.Values = make([]*proto3.Value, 0, len(vs)) 2181 for _, v := range vs { 2182 if !isSupportedMutationType(v) { 2183 return nil, errEncoderUnsupportedType(v) 2184 } 2185 pb, _, err := encodeValue(v) 2186 if err != nil { 2187 return nil, err 2188 } 2189 lv.Values = append(lv.Values, pb) 2190 } 2191 return lv, nil 2192} 2193 2194// encodeArray assumes that all values of the array element type encode without 2195// error. 2196func encodeArray(len int, at func(int) interface{}) (*proto3.Value, error) { 2197 vs := make([]*proto3.Value, len) 2198 var err error 2199 for i := 0; i < len; i++ { 2200 vs[i], _, err = encodeValue(at(i)) 2201 if err != nil { 2202 return nil, err 2203 } 2204 } 2205 return listProto(vs...), nil 2206} 2207 2208func spannerTagParser(t reflect.StructTag) (name string, keep bool, other interface{}, err error) { 2209 if s := t.Get("spanner"); s != "" { 2210 if s == "-" { 2211 return "", false, nil, nil 2212 } 2213 return s, true, nil, nil 2214 } 2215 return "", true, nil, nil 2216} 2217 2218var fieldCache = fields.NewCache(spannerTagParser, nil, nil) 2219