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