github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/internal/table/scanner/scan_raw.go (about) 1 package scanner 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "reflect" 8 "strconv" 9 "strings" 10 "time" 11 12 "github.com/google/uuid" 13 "github.com/ydb-platform/ydb-go-genproto/protos/Ydb" 14 15 "github.com/ydb-platform/ydb-go-sdk/v3/internal/decimal" 16 "github.com/ydb-platform/ydb-go-sdk/v3/internal/types" 17 "github.com/ydb-platform/ydb-go-sdk/v3/internal/value" 18 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors" 19 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xstring" 20 ) 21 22 type rawConverter struct { 23 *valueScanner 24 } 25 26 func (s *rawConverter) String() (v []byte) { 27 s.unwrap() 28 29 return s.bytes() 30 } 31 32 func (s *rawConverter) HasItems() bool { 33 return s.hasItems() 34 } 35 36 func (s *rawConverter) HasNextItem() bool { 37 return s.hasItems() && s.nextItem < len(s.row.GetItems()) 38 } 39 40 func (s *rawConverter) Path() string { 41 var buf bytes.Buffer 42 _, _ = s.WritePathTo(&buf) 43 44 return buf.String() 45 } 46 47 func (s *rawConverter) WritePathTo(w io.Writer) (n int64, err error) { 48 for sp := 0; sp < s.stack.size(); sp++ { 49 if sp > 0 { 50 var m int 51 m, err = io.WriteString(w, ".") 52 if err != nil { 53 return n, xerrors.WithStackTrace(err) 54 } 55 n += int64(m) 56 } 57 x := s.stack.get(sp) 58 s := x.name 59 if s == "" { 60 s = strconv.Itoa(x.i) 61 } 62 var m int 63 m, err = io.WriteString(w, s) 64 if err != nil { 65 return n, xerrors.WithStackTrace(err) 66 } 67 n += int64(m) 68 } 69 70 return n, nil 71 } 72 73 func (s *rawConverter) Type() types.Type { 74 return s.getType() 75 } 76 77 func (s *rawConverter) Bool() (v bool) { 78 if s.Err() != nil { 79 return 80 } 81 s.unwrap() 82 83 return s.bool() 84 } 85 86 func (s *rawConverter) Int8() (v int8) { 87 if s.Err() != nil { 88 return 89 } 90 s.unwrap() 91 92 return s.int8() 93 } 94 95 func (s *rawConverter) Uint8() (v uint8) { 96 if s.Err() != nil { 97 return 98 } 99 s.unwrap() 100 101 return s.uint8() 102 } 103 104 func (s *rawConverter) Int16() (v int16) { 105 if s.Err() != nil { 106 return 107 } 108 s.unwrap() 109 110 return s.int16() 111 } 112 113 func (s *rawConverter) Uint16() (v uint16) { 114 if s.Err() != nil { 115 return 116 } 117 s.unwrap() 118 119 return s.uint16() 120 } 121 122 func (s *rawConverter) Int32() (v int32) { 123 if s.Err() != nil { 124 return 125 } 126 s.unwrap() 127 128 return s.int32() 129 } 130 131 func (s *rawConverter) Uint32() (v uint32) { 132 if s.Err() != nil { 133 return 134 } 135 s.unwrap() 136 137 return s.uint32() 138 } 139 140 func (s *rawConverter) Int64() (v int64) { 141 if s.Err() != nil { 142 return 143 } 144 s.unwrap() 145 146 return s.int64() 147 } 148 149 func (s *rawConverter) Uint64() (v uint64) { 150 if s.Err() != nil { 151 return 152 } 153 s.unwrap() 154 155 return s.uint64() 156 } 157 158 func (s *rawConverter) Float() (v float32) { 159 if s.Err() != nil { 160 return 161 } 162 s.unwrap() 163 164 return s.float() 165 } 166 167 func (s *rawConverter) Double() (v float64) { 168 if s.Err() != nil { 169 return 170 } 171 s.unwrap() 172 173 return s.double() 174 } 175 176 func (s *rawConverter) Date() (v time.Time) { 177 s.unwrap() 178 179 return value.DateToTime(s.uint32()) 180 } 181 182 func (s *rawConverter) Datetime() (v time.Time) { 183 s.unwrap() 184 185 return value.DatetimeToTime(s.uint32()) 186 } 187 188 func (s *rawConverter) Timestamp() (v time.Time) { 189 s.unwrap() 190 191 return value.TimestampToTime(s.uint64()) 192 } 193 194 func (s *rawConverter) Interval() (v time.Duration) { 195 s.unwrap() 196 197 return value.IntervalToDuration(s.int64()) 198 } 199 200 func (s *rawConverter) TzDate() (v time.Time) { 201 s.unwrap() 202 if s.isNull() { 203 return 204 } 205 src, err := value.TzDateToTime(s.text()) 206 if err != nil { 207 _ = s.errorf(0, "rawConverter.TzDate(): %w", err) 208 } 209 210 return src 211 } 212 213 func (s *rawConverter) TzDatetime() (v time.Time) { 214 s.unwrap() 215 if s.isNull() { 216 return 217 } 218 src, err := value.TzDatetimeToTime(s.text()) 219 if err != nil { 220 _ = s.errorf(0, "rawConverter.TzDatetime(): %w", err) 221 } 222 223 return src 224 } 225 226 func (s *rawConverter) TzTimestamp() (v time.Time) { 227 s.unwrap() 228 if s.isNull() { 229 return 230 } 231 src, err := value.TzTimestampToTime(s.text()) 232 if err != nil { 233 _ = s.errorf(0, "rawConverter.TzTimestamp(): %w", err) 234 } 235 236 return src 237 } 238 239 func (s *rawConverter) UTF8() (v string) { 240 if s.Err() != nil { 241 return 242 } 243 s.unwrap() 244 245 return s.text() 246 } 247 248 func (s *rawConverter) YSON() (v []byte) { 249 s.unwrap() 250 251 return s.bytes() 252 } 253 254 func (s *rawConverter) JSON() (v []byte) { 255 s.unwrap() 256 257 return xstring.ToBytes(s.text()) 258 } 259 260 func (s *rawConverter) JSONDocument() (v []byte) { 261 s.unwrap() 262 263 return xstring.ToBytes(s.text()) 264 } 265 266 // removed for https://github.com/ydb-platform/ydb-go-sdk/issues/1501 267 //func (s *rawConverter) UUID() (v [16]byte) { 268 // return s.uuidBytesWithIssue1501().AsBytesArray() 269 //} 270 271 func (s *rawConverter) UUIDWithIssue1501() (v [16]byte) { 272 if s.Err() != nil { 273 return 274 } 275 s.unwrap() 276 277 return s.uint128() 278 } 279 280 func (s *rawConverter) UUIDTyped() (v uuid.UUID) { 281 if s.Err() != nil { 282 return 283 } 284 s.unwrap() 285 286 return s.uuid() 287 } 288 289 func (s *rawConverter) DyNumber() (v string) { 290 if s.Err() != nil { 291 return 292 } 293 s.unwrap() 294 295 return s.text() 296 } 297 298 func (s *rawConverter) Any() interface{} { 299 return s.any() 300 } 301 302 // Value returns current item under scan as value 303 func (s *rawConverter) Value() value.Value { 304 if s.Err() != nil { 305 return nil 306 } 307 s.unwrap() 308 309 return s.value() 310 } 311 312 func (s *rawConverter) AssertType(t types.Type) bool { 313 return s.assertCurrentTypeIs(t) 314 } 315 316 func (s *rawConverter) Null() { 317 if s.Err() != nil || !s.assertCurrentTypeNullable() { 318 return 319 } 320 s.null() 321 } 322 323 func (s *rawConverter) IsNull() bool { 324 if s.Err() != nil { 325 return false 326 } 327 328 return s.isNull() 329 } 330 331 func (s *rawConverter) IsOptional() bool { 332 if s.Err() != nil { 333 return false 334 } 335 336 return s.isCurrentTypeOptional() 337 } 338 339 // --------non-primitive--------- 340 341 func (s *rawConverter) ListIn() (size int) { 342 if s.Err() != nil { 343 return 0 344 } 345 x := s.stack.current() 346 if s.assertTypeList(x.t) != nil { 347 return s.itemsIn() 348 } 349 350 return 0 351 } 352 353 func (s *rawConverter) ListItem(i int) { 354 if s.Err() != nil { 355 return 356 } 357 p := s.stack.parent() 358 if !s.itemsBoundsCheck(p.v.GetItems(), i) { 359 return 360 } 361 if t := s.assertTypeList(p.t); t != nil { 362 s.stack.set(item{ 363 i: i, 364 t: t.ListType.GetItem(), 365 v: p.v.GetItems()[i], 366 }) 367 } 368 } 369 370 func (s *rawConverter) ListOut() { 371 if s.Err() != nil { 372 return 373 } 374 p := s.stack.parent() 375 if t := s.assertTypeList(p.t); t != nil { 376 s.itemsOut() 377 } 378 } 379 380 func (s *rawConverter) TupleIn() (size int) { 381 if s.Err() != nil { 382 return 0 383 } 384 x := s.stack.current() 385 if s.assertTypeTuple(x.t) != nil { 386 return s.itemsIn() 387 } 388 389 return 0 390 } 391 392 func (s *rawConverter) TupleItem(i int) { 393 if s.Err() != nil { 394 return 395 } 396 p := s.stack.parent() 397 if !s.itemsBoundsCheck(p.v.GetItems(), i) { 398 return 399 } 400 if t := s.assertTypeTuple(p.t); t != nil { 401 s.stack.set(item{ 402 i: i, 403 t: t.TupleType.GetElements()[i], 404 v: p.v.GetItems()[i], 405 }) 406 } 407 } 408 409 func (s *rawConverter) TupleOut() { 410 if s.Err() != nil { 411 return 412 } 413 p := s.stack.parent() 414 if t := s.assertTypeTuple(p.t); t != nil { 415 s.itemsOut() 416 } 417 } 418 419 func (s *rawConverter) StructIn() (size int) { 420 if s.Err() != nil { 421 return 0 422 } 423 x := s.stack.current() 424 if s.assertTypeStruct(x.t) != nil { 425 return s.itemsIn() 426 } 427 428 return 0 429 } 430 431 func (s *rawConverter) StructField(i int) (name string) { 432 if s.Err() != nil { 433 return 434 } 435 p := s.stack.parent() 436 if !s.itemsBoundsCheck(p.v.GetItems(), i) { 437 return 438 } 439 if t := s.assertTypeStruct(p.t); t != nil { 440 m := t.StructType.GetMembers()[i] 441 name = m.GetName() 442 s.stack.set(item{ 443 name: m.GetName(), 444 i: i, 445 t: m.GetType(), 446 v: p.v.GetItems()[i], 447 }) 448 } 449 450 return 451 } 452 453 func (s *rawConverter) StructOut() { 454 if s.Err() != nil { 455 return 456 } 457 p := s.stack.parent() 458 if t := s.assertTypeStruct(p.t); t != nil { 459 s.itemsOut() 460 } 461 } 462 463 func (s *rawConverter) DictIn() (size int) { 464 if s.Err() != nil { 465 return 0 466 } 467 x := s.stack.current() 468 if s.assertTypeDict(x.t) != nil { 469 return s.pairsIn() 470 } 471 472 return 0 473 } 474 475 func (s *rawConverter) DictKey(i int) { 476 if s.Err() != nil { 477 return 478 } 479 p := s.stack.parent() 480 if !s.pairsBoundsCheck(p.v.GetPairs(), i) { 481 return 482 } 483 if t := s.assertTypeDict(p.t); t != nil { 484 s.stack.set(item{ 485 i: i, 486 t: t.DictType.GetKey(), 487 v: p.v.GetPairs()[i].GetKey(), 488 }) 489 } 490 } 491 492 func (s *rawConverter) DictPayload(i int) { 493 if s.Err() != nil { 494 return 495 } 496 p := s.stack.parent() 497 if !s.pairsBoundsCheck(p.v.GetPairs(), i) { 498 return 499 } 500 if t := s.assertTypeDict(p.t); t != nil { 501 s.stack.set(item{ 502 i: i, 503 t: t.DictType.GetPayload(), 504 v: p.v.GetPairs()[i].GetPayload(), 505 }) 506 } 507 } 508 509 func (s *rawConverter) DictOut() { 510 if s.Err() != nil { 511 return 512 } 513 p := s.stack.parent() 514 if t := s.assertTypeDict(p.t); t != nil { 515 s.pairsOut() 516 } 517 } 518 519 func (s *rawConverter) Variant() (name string, index uint32) { 520 if s.Err() != nil { 521 return 522 } 523 x := s.stack.current() 524 t := s.assertTypeVariant(x.t) 525 if t == nil { 526 return 527 } 528 v, index := s.variant() 529 if v == nil { 530 return 531 } 532 name, typ := s.unwrapVariantType(t, index) 533 s.stack.scanItem.v = nil 534 s.stack.set(item{ 535 name: name, 536 i: int(index), 537 t: typ, 538 v: v, 539 }) 540 541 return name, index 542 } 543 544 func (s *rawConverter) Unwrap() { 545 if s.Err() != nil { 546 return 547 } 548 x := s.stack.current() 549 t := s.assertTypeOptional(x.t) 550 if t == nil { 551 return 552 } 553 v := x.v 554 if isOptional(t.OptionalType.GetItem()) { 555 v = s.unwrapValue() 556 } 557 s.stack.enter() 558 s.stack.set(item{ 559 name: "*", 560 t: t.OptionalType.GetItem(), 561 v: v, 562 }) 563 } 564 565 func (s *rawConverter) Decimal(t types.Type) (v [16]byte) { 566 if s.Err() != nil { 567 return 568 } 569 s.unwrap() 570 if !s.assertCurrentTypeDecimal(t) { 571 return 572 } 573 574 return s.uint128() 575 } 576 577 func (s *rawConverter) UnwrapDecimal() decimal.Decimal { 578 if s.Err() != nil { 579 return decimal.Decimal{} 580 } 581 s.unwrap() 582 d := s.assertTypeDecimal(s.stack.current().t) 583 if d == nil { 584 return decimal.Decimal{} 585 } 586 587 return decimal.Decimal{ 588 Bytes: s.uint128(), 589 Precision: d.DecimalType.GetPrecision(), 590 Scale: d.DecimalType.GetScale(), 591 } 592 } 593 594 func (s *rawConverter) IsDecimal() bool { 595 if s.Err() != nil { 596 return false 597 } 598 599 return s.isCurrentTypeDecimal() 600 } 601 602 func isEqualDecimal(d *Ydb.DecimalType, t types.Type) bool { 603 w, ok := t.(*types.Decimal) 604 if !ok { 605 panic(fmt.Sprintf("unsupported type conversion from %T to *types.Decimal", w)) 606 } 607 608 return d.GetPrecision() == w.Precision() && d.GetScale() == w.Scale() 609 } 610 611 func (s *rawConverter) isCurrentTypeDecimal() bool { 612 c := s.stack.current() 613 _, ok := c.t.GetType().(*Ydb.Type_DecimalType) 614 615 return ok 616 } 617 618 func (s *rawConverter) unwrapVariantType(typ *Ydb.Type_VariantType, index uint32) (name string, t *Ydb.Type) { 619 i := int(index) 620 switch x := typ.VariantType.GetType().(type) { 621 case *Ydb.VariantType_TupleItems: 622 if i >= len(x.TupleItems.GetElements()) { 623 _ = s.errorf(0, "unimplemented") 624 625 return 626 } 627 628 return "", x.TupleItems.GetElements()[i] 629 630 case *Ydb.VariantType_StructItems: 631 if i >= len(x.StructItems.GetMembers()) { 632 _ = s.errorf(0, "unimplemented") 633 634 return 635 } 636 m := x.StructItems.GetMembers()[i] 637 638 return m.GetName(), m.GetType() 639 640 default: 641 panic("unexpected variant items types") 642 } 643 } 644 645 func (s *rawConverter) variant() (v *Ydb.Value, index uint32) { 646 v = s.unwrapValue() 647 if v == nil { 648 return 649 } 650 x := s.stack.current() // Is not nil if unwrapValue succeeded. 651 index = x.v.GetVariantIndex() 652 653 return 654 } 655 656 func (s *rawConverter) itemsIn() int { 657 x := s.stack.current() 658 if x.isEmpty() { 659 return -1 660 } 661 s.stack.enter() 662 663 return len(x.v.GetItems()) 664 } 665 666 func (s *rawConverter) itemsOut() { 667 s.stack.leave() 668 } 669 670 func (s *rawConverter) itemsBoundsCheck(xs []*Ydb.Value, i int) bool { 671 return s.boundsCheck(len(xs), i) 672 } 673 674 func (s *rawConverter) pairsIn() int { 675 x := s.stack.current() 676 if x.isEmpty() { 677 return -1 678 } 679 s.stack.enter() 680 681 return len(x.v.GetPairs()) 682 } 683 684 func (s *rawConverter) pairsOut() { 685 s.stack.leave() 686 } 687 688 func (s *rawConverter) pairsBoundsCheck(xs []*Ydb.ValuePair, i int) bool { 689 return s.boundsCheck(len(xs), i) 690 } 691 692 func (s *rawConverter) boundsCheck(n, i int) bool { 693 if i < 0 || n <= i { 694 s.boundsError(n, i) 695 696 return false 697 } 698 699 return true 700 } 701 702 func (s *valueScanner) assertTypeOptional(typ *Ydb.Type) (t *Ydb.Type_OptionalType) { 703 if t, _ = typ.GetType().(*Ydb.Type_OptionalType); t == nil { 704 s.typeError(typ.GetType(), t) 705 } 706 707 return 708 } 709 710 func (s *rawConverter) assertCurrentTypeNullable() bool { 711 c := s.stack.current() 712 if isOptional(c.t) { 713 return true 714 } 715 p := s.stack.parent() 716 if isOptional(p.t) { 717 return true 718 } 719 _ = s.errorf( 720 1, 721 "not nullable types at %q: %s (%d %s %s)", 722 s.Path(), 723 s.Type(), 724 s.stack.size(), 725 c.t, 726 p.t, 727 ) 728 729 return false 730 } 731 732 func (s *rawConverter) assertCurrentTypeIs(t types.Type) bool { 733 c := s.stack.current() 734 act := types.TypeFromYDB(c.t) 735 if !types.Equal(act, t) { 736 _ = s.errorf( 737 1, 738 "unexpected types at %q %s: %s; want %s", 739 s.Path(), 740 s.Type(), 741 act, 742 t, 743 ) 744 745 return false 746 } 747 748 return true 749 } 750 751 func (s *rawConverter) assertCurrentTypeDecimal(t types.Type) bool { 752 d := s.assertTypeDecimal(s.stack.current().t) 753 if d == nil { 754 return false 755 } 756 if !isEqualDecimal(d.DecimalType, t) { 757 s.decimalTypeError(t) 758 759 return false 760 } 761 762 return true 763 } 764 765 func (s *rawConverter) assertTypeList(typ *Ydb.Type) (t *Ydb.Type_ListType) { 766 if t, _ = typ.GetType().(*Ydb.Type_ListType); t == nil { 767 s.typeError(typ.GetType(), t) 768 } 769 770 return 771 } 772 773 func (s *rawConverter) assertTypeTuple(typ *Ydb.Type) (t *Ydb.Type_TupleType) { 774 if t, _ = typ.GetType().(*Ydb.Type_TupleType); t == nil { 775 s.typeError(typ.GetType(), t) 776 } 777 778 return 779 } 780 781 func (s *rawConverter) assertTypeStruct(typ *Ydb.Type) (t *Ydb.Type_StructType) { 782 if t, _ = typ.GetType().(*Ydb.Type_StructType); t == nil { 783 s.typeError(typ.GetType(), t) 784 } 785 786 return 787 } 788 789 func (s *rawConverter) assertTypeDict(typ *Ydb.Type) (t *Ydb.Type_DictType) { 790 if t, _ = typ.GetType().(*Ydb.Type_DictType); t == nil { 791 s.typeError(typ.GetType(), t) 792 } 793 794 return 795 } 796 797 func (s *rawConverter) assertTypeDecimal(typ *Ydb.Type) (t *Ydb.Type_DecimalType) { 798 if t, _ = typ.GetType().(*Ydb.Type_DecimalType); t == nil { 799 s.typeError(typ.GetType(), t) 800 } 801 802 return 803 } 804 805 func (s *rawConverter) assertTypeVariant(typ *Ydb.Type) (t *Ydb.Type_VariantType) { 806 if t, _ = typ.GetType().(*Ydb.Type_VariantType); t == nil { 807 s.typeError(typ.GetType(), t) 808 } 809 810 return 811 } 812 813 func (s *rawConverter) boundsError(n, i int) { 814 _ = s.errorf( 815 1, "index out of range: %d; have %d", 816 i, n, 817 ) 818 } 819 820 func (s *rawConverter) decimalTypeError(t types.Type) { 821 _ = s.errorf( 822 1, "unexpected decimal types at %q %s: want %s", 823 s.Path(), s.getType(), t, 824 ) 825 } 826 827 func nameIface(v interface{}) string { 828 if v == nil { 829 return "nil" 830 } 831 t := reflect.TypeOf(v) 832 s := t.String() 833 s = strings.TrimPrefix(s, "*Ydb.Value_") 834 s = strings.TrimSuffix(s, "valueType") 835 s = strings.TrimPrefix(s, "*Ydb.Type_") 836 s = strings.TrimSuffix(s, "Type") 837 838 return s 839 }