github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/internal/table/scanner/scanner.go (about) 1 package scanner 2 3 import ( 4 "database/sql" 5 "encoding/json" 6 "fmt" 7 "io" 8 "math" 9 "reflect" 10 "time" 11 12 "github.com/ydb-platform/ydb-go-genproto/protos/Ydb" 13 14 "github.com/ydb-platform/ydb-go-sdk/v3/internal/decimal" 15 "github.com/ydb-platform/ydb-go-sdk/v3/internal/scanner" 16 internalTypes "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 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xsync" 21 "github.com/ydb-platform/ydb-go-sdk/v3/table/options" 22 "github.com/ydb-platform/ydb-go-sdk/v3/table/result" 23 "github.com/ydb-platform/ydb-go-sdk/v3/table/result/indexed" 24 "github.com/ydb-platform/ydb-go-sdk/v3/table/result/named" 25 ) 26 27 type valueScanner struct { 28 set *Ydb.ResultSet 29 row *Ydb.Value 30 converter *rawConverter 31 stack scanStack 32 nextRow int 33 nextItem int 34 ignoreTruncated bool 35 markTruncatedAsRetryable bool 36 37 columnIndexes []int 38 39 errMtx xsync.RWMutex 40 err error 41 } 42 43 // ColumnCount returns number of columns in the current result set. 44 func (s *valueScanner) ColumnCount() int { 45 if s.set == nil { 46 return 0 47 } 48 49 return len(s.set.GetColumns()) 50 } 51 52 // Columns allows to iterate over all columns of the current result set. 53 func (s *valueScanner) Columns(it func(options.Column)) { 54 if s.set == nil { 55 return 56 } 57 for _, m := range s.set.GetColumns() { 58 it(options.Column{ 59 Name: m.GetName(), 60 Type: internalTypes.TypeFromYDB(m.GetType()), 61 }) 62 } 63 } 64 65 // RowCount returns number of rows in the result set. 66 func (s *valueScanner) RowCount() int { 67 if s.set == nil { 68 return 0 69 } 70 71 return len(s.set.GetRows()) 72 } 73 74 // ItemCount returns number of items in the current row. 75 func (s *valueScanner) ItemCount() int { 76 if s.row == nil { 77 return 0 78 } 79 80 return len(s.row.GetItems()) 81 } 82 83 // HasNextRow reports whether result row may be advanced. 84 // It may be useful to call HasNextRow() instead of NextRow() to look ahead 85 // without advancing the result rows. 86 func (s *valueScanner) HasNextRow() bool { 87 return s.err == nil && s.set != nil && s.nextRow < len(s.set.GetRows()) 88 } 89 90 // NextRow selects next row in the current result set. 91 // It returns false if there are no more rows in the result set. 92 func (s *valueScanner) NextRow() bool { 93 if !s.HasNextRow() { 94 return false 95 } 96 s.row = s.set.GetRows()[s.nextRow] 97 s.nextRow++ 98 s.nextItem = 0 99 s.stack.reset() 100 101 return true 102 } 103 104 func (s *valueScanner) preScanChecks(lenValues int) (err error) { 105 if s.columnIndexes != nil { 106 if len(s.columnIndexes) != lenValues { 107 return s.errorf( 108 1, 109 "scan row failed: count of values and column are different (%d != %d)", 110 len(s.columnIndexes), 111 lenValues, 112 ) 113 } 114 } 115 if s.ColumnCount() < lenValues { 116 panic(fmt.Sprintf("scan row failed: count of columns less then values (%d < %d)", s.ColumnCount(), lenValues)) 117 } 118 if s.nextItem != 0 { 119 panic("scan row failed: double scan per row") 120 } 121 122 return s.Err() 123 } 124 125 func (s *valueScanner) ScanWithDefaults(values ...indexed.Required) (err error) { 126 if err = s.preScanChecks(len(values)); err != nil { 127 return 128 } 129 for i := range values { 130 if _, ok := values[i].(named.Value); ok { 131 panic("dont use NamedValue with ScanWithDefaults. Use ScanNamed instead") 132 } 133 if s.columnIndexes == nil { 134 if err = s.seekItemByID(i); err != nil { 135 return 136 } 137 } else { 138 if err = s.seekItemByID(s.columnIndexes[i]); err != nil { 139 return 140 } 141 } 142 if s.isCurrentTypeOptional() { 143 s.scanOptional(values[i], true) 144 } else { 145 s.scanRequired(values[i]) 146 } 147 } 148 s.nextItem += len(values) 149 150 return s.Err() 151 } 152 153 func (s *valueScanner) Scan(values ...indexed.RequiredOrOptional) (err error) { 154 if err = s.preScanChecks(len(values)); err != nil { 155 return 156 } 157 for i := range values { 158 if _, ok := values[i].(named.Value); ok { 159 panic("dont use NamedValue with Scan. Use ScanNamed instead") 160 } 161 if s.columnIndexes == nil { 162 if err = s.seekItemByID(i); err != nil { 163 return 164 } 165 } else { 166 if err = s.seekItemByID(s.columnIndexes[i]); err != nil { 167 return 168 } 169 } 170 if s.isCurrentTypeOptional() { 171 s.scanOptional(values[i], false) 172 } else { 173 s.scanRequired(values[i]) 174 } 175 } 176 s.nextItem += len(values) 177 178 return s.Err() 179 } 180 181 func (s *valueScanner) ScanNamed(namedValues ...named.Value) error { 182 if err := s.Err(); err != nil { 183 return err 184 } 185 if s.ColumnCount() < len(namedValues) { 186 panic(fmt.Sprintf("scan row failed: count of columns less then values (%d < %d)", s.ColumnCount(), len(namedValues))) 187 } 188 if s.nextItem != 0 { 189 panic("scan row failed: double scan per row") 190 } 191 for i := range namedValues { 192 if err := s.seekItemByName(namedValues[i].Name); err != nil { 193 return err 194 } 195 switch t := namedValues[i].Type; t { 196 case named.TypeRequired: 197 s.scanRequired(namedValues[i].Value) 198 case named.TypeOptional: 199 s.scanOptional(namedValues[i].Value, false) 200 case named.TypeOptionalWithUseDefault: 201 s.scanOptional(namedValues[i].Value, true) 202 default: 203 panic(fmt.Sprintf("unknown type of named.valueType: %d", t)) 204 } 205 } 206 s.nextItem += len(namedValues) 207 208 return s.Err() 209 } 210 211 // Truncated returns true if current result set has been truncated by server 212 func (s *valueScanner) Truncated() bool { 213 if s.set == nil { 214 _ = s.errorf(0, "there are no sets in the scanner") 215 216 return false 217 } 218 219 return s.set.GetTruncated() 220 } 221 222 // Truncated returns true if current result set has been truncated by server 223 func (s *valueScanner) truncated() bool { 224 if s.set == nil { 225 return false 226 } 227 228 return s.set.GetTruncated() 229 } 230 231 // Err returns error caused Scanner to be broken. 232 func (s *valueScanner) Err() error { 233 s.errMtx.RLock() 234 defer s.errMtx.RUnlock() 235 if s.err != nil { 236 return s.err 237 } 238 if !s.ignoreTruncated && s.truncated() { 239 err := xerrors.Wrap( 240 fmt.Errorf("more than %d rows: %w", len(s.set.GetRows()), result.ErrTruncated), 241 ) 242 if s.markTruncatedAsRetryable { 243 err = xerrors.Retryable(err) 244 } 245 246 return xerrors.WithStackTrace(err) 247 } 248 249 return nil 250 } 251 252 // Must not be exported. 253 func (s *valueScanner) reset(set *Ydb.ResultSet, columnNames ...string) { 254 s.set = set 255 s.row = nil 256 s.nextRow = 0 257 s.nextItem = 0 258 s.columnIndexes = nil 259 s.setColumnIndexes(columnNames) 260 s.stack.reset() 261 s.converter = &rawConverter{ 262 valueScanner: s, 263 } 264 } 265 266 func (s *valueScanner) path() string { 267 buf := xstring.Buffer() 268 defer buf.Free() 269 _, _ = s.writePathTo(buf) 270 271 return buf.String() 272 } 273 274 func (s *valueScanner) writePathTo(w io.Writer) (n int64, err error) { 275 x := s.stack.current() 276 st := x.name 277 m, err := io.WriteString(w, st) 278 if err != nil { 279 return n, xerrors.WithStackTrace(err) 280 } 281 n += int64(m) 282 283 return n, nil 284 } 285 286 func (s *valueScanner) getType() internalTypes.Type { 287 x := s.stack.current() 288 if x.isEmpty() { 289 return nil 290 } 291 292 return internalTypes.TypeFromYDB(x.t) 293 } 294 295 func (s *valueScanner) hasItems() bool { 296 return s.err == nil && s.set != nil && s.row != nil 297 } 298 299 func (s *valueScanner) seekItemByID(id int) error { 300 if !s.hasItems() || id >= len(s.set.GetColumns()) { 301 return s.notFoundColumnByIndex(id) 302 } 303 col := s.set.GetColumns()[id] 304 s.stack.scanItem.name = col.GetName() 305 s.stack.scanItem.t = col.GetType() 306 s.stack.scanItem.v = s.row.GetItems()[id] 307 308 return nil 309 } 310 311 func (s *valueScanner) seekItemByName(name string) error { 312 if !s.hasItems() { 313 return s.notFoundColumnName(name) 314 } 315 for i, c := range s.set.GetColumns() { 316 if name != c.GetName() { 317 continue 318 } 319 s.stack.scanItem.name = c.GetName() 320 s.stack.scanItem.t = c.GetType() 321 s.stack.scanItem.v = s.row.GetItems()[i] 322 323 return s.Err() 324 } 325 326 return s.notFoundColumnName(name) 327 } 328 329 func (s *valueScanner) setColumnIndexes(columns []string) { 330 if columns == nil { 331 s.columnIndexes = nil 332 333 return 334 } 335 s.columnIndexes = make([]int, len(columns)) 336 for i, col := range columns { 337 found := false 338 for j, c := range s.set.GetColumns() { 339 if c.GetName() == col { 340 s.columnIndexes[i] = j 341 found = true 342 343 break 344 } 345 } 346 if !found { 347 _ = s.noColumnError(col) 348 349 return 350 } 351 } 352 } 353 354 // Any returns any primitive or optional value. 355 // Currently, it may return one of these types: 356 // 357 // bool 358 // int8 359 // uint8 360 // int16 361 // uint16 362 // int32 363 // uint32 364 // int64 365 // uint64 366 // float32 367 // float64 368 // []byte 369 // string 370 // [16]byte 371 // 372 //nolint:gocyclo 373 func (s *valueScanner) any() interface{} { 374 x := s.stack.current() 375 if s.Err() != nil || x.isEmpty() { 376 return nil 377 } 378 379 if s.isNull() { 380 return nil 381 } 382 383 if s.isCurrentTypeOptional() { 384 s.unwrap() 385 x = s.stack.current() 386 } 387 388 t := internalTypes.TypeFromYDB(x.t) 389 p, primitive := t.(internalTypes.Primitive) 390 if !primitive { 391 return s.value() 392 } 393 394 switch p { 395 case internalTypes.Bool: 396 return s.bool() 397 case internalTypes.Int8: 398 return s.int8() 399 case internalTypes.Uint8: 400 return s.uint8() 401 case internalTypes.Int16: 402 return s.int16() 403 case internalTypes.Uint16: 404 return s.uint16() 405 case internalTypes.Int32: 406 return s.int32() 407 case internalTypes.Float: 408 return s.float() 409 case internalTypes.Double: 410 return s.double() 411 case internalTypes.Bytes: 412 return s.bytes() 413 case internalTypes.UUID: 414 return s.uint128() 415 case internalTypes.Uint32: 416 return s.uint32() 417 case internalTypes.Date: 418 return value.DateToTime(s.uint32()) 419 case internalTypes.Datetime: 420 return value.DatetimeToTime(s.uint32()) 421 case internalTypes.Uint64: 422 return s.uint64() 423 case internalTypes.Timestamp: 424 return value.TimestampToTime(s.uint64()) 425 case internalTypes.Int64: 426 return s.int64() 427 case internalTypes.Interval: 428 return value.IntervalToDuration(s.int64()) 429 case internalTypes.TzDate: 430 src, err := value.TzDateToTime(s.text()) 431 if err != nil { 432 _ = s.errorf(0, "valueScanner.any(): %w", err) 433 } 434 435 return src 436 case internalTypes.TzDatetime: 437 src, err := value.TzDatetimeToTime(s.text()) 438 if err != nil { 439 _ = s.errorf(0, "valueScanner.any(): %w", err) 440 } 441 442 return src 443 case internalTypes.TzTimestamp: 444 src, err := value.TzTimestampToTime(s.text()) 445 if err != nil { 446 _ = s.errorf(0, "valueScanner.any(): %w", err) 447 } 448 449 return src 450 case internalTypes.Text, internalTypes.DyNumber: 451 return s.text() 452 case 453 internalTypes.YSON, 454 internalTypes.JSON, 455 internalTypes.JSONDocument: 456 return xstring.ToBytes(s.text()) 457 default: 458 _ = s.errorf(0, "unknown primitive types") 459 460 return nil 461 } 462 } 463 464 // valueType returns current item under scan as ydb.valueType types 465 func (s *valueScanner) value() value.Value { 466 x := s.stack.current() 467 468 return value.FromYDB(x.t, x.v) 469 } 470 471 func (s *valueScanner) isCurrentTypeOptional() bool { 472 c := s.stack.current() 473 474 return isOptional(c.t) 475 } 476 477 func (s *valueScanner) isNull() bool { 478 _, yes := s.stack.currentValue().(*Ydb.Value_NullFlagValue) 479 480 return yes 481 } 482 483 // unwrap current item under scan interpreting it as Optional<Type> types 484 // ignores if type is not optional 485 func (s *valueScanner) unwrap() { 486 if s.Err() != nil { 487 return 488 } 489 490 t, _ := s.stack.currentType().(*Ydb.Type_OptionalType) 491 if t == nil { 492 return 493 } 494 495 if isOptional(t.OptionalType.GetItem()) { 496 s.stack.scanItem.v = s.unwrapValue() 497 } 498 s.stack.scanItem.t = t.OptionalType.GetItem() 499 } 500 501 func (s *valueScanner) unwrapValue() (v *Ydb.Value) { 502 x, _ := s.stack.currentValue().(*Ydb.Value_NestedValue) 503 if x == nil { 504 s.valueTypeError(s.stack.currentValue(), x) 505 506 return 507 } 508 509 return x.NestedValue 510 } 511 512 func (s *valueScanner) unwrapDecimal() decimal.Decimal { 513 if s.Err() != nil { 514 return decimal.Decimal{} 515 } 516 s.unwrap() 517 d := s.assertTypeDecimal(s.stack.current().t) 518 if d == nil { 519 return decimal.Decimal{} 520 } 521 522 return decimal.Decimal{ 523 Bytes: s.uint128(), 524 Precision: d.DecimalType.GetPrecision(), 525 Scale: d.DecimalType.GetScale(), 526 } 527 } 528 529 func (s *valueScanner) assertTypeDecimal(typ *Ydb.Type) (t *Ydb.Type_DecimalType) { 530 x := typ.GetType() 531 if t, _ = x.(*Ydb.Type_DecimalType); t == nil { 532 s.typeError(x, t) 533 } 534 535 return 536 } 537 538 func (s *valueScanner) bool() (v bool) { 539 x, _ := s.stack.currentValue().(*Ydb.Value_BoolValue) 540 if x == nil { 541 s.valueTypeError(s.stack.currentValue(), x) 542 543 return 544 } 545 546 return x.BoolValue 547 } 548 549 func (s *valueScanner) int8() (v int8) { 550 d := s.int32() 551 if d < math.MinInt8 || math.MaxInt8 < d { 552 _ = s.overflowError(d, v) 553 554 return 555 } 556 557 return int8(d) 558 } 559 560 func (s *valueScanner) uint8() (v uint8) { 561 d := s.uint32() 562 if d > math.MaxUint8 { 563 _ = s.overflowError(d, v) 564 565 return 566 } 567 568 return uint8(d) 569 } 570 571 func (s *valueScanner) int16() (v int16) { 572 d := s.int32() 573 if d < math.MinInt16 || math.MaxInt16 < d { 574 _ = s.overflowError(d, v) 575 576 return 577 } 578 579 return int16(d) 580 } 581 582 func (s *valueScanner) uint16() (v uint16) { 583 d := s.uint32() 584 if d > math.MaxUint16 { 585 _ = s.overflowError(d, v) 586 587 return 588 } 589 590 return uint16(d) 591 } 592 593 func (s *valueScanner) int32() (v int32) { 594 x, _ := s.stack.currentValue().(*Ydb.Value_Int32Value) 595 if x == nil { 596 s.valueTypeError(s.stack.currentValue(), x) 597 598 return 599 } 600 601 return x.Int32Value 602 } 603 604 func (s *valueScanner) uint32() (v uint32) { 605 x, _ := s.stack.currentValue().(*Ydb.Value_Uint32Value) 606 if x == nil { 607 s.valueTypeError(s.stack.currentValue(), x) 608 609 return 610 } 611 612 return x.Uint32Value 613 } 614 615 func (s *valueScanner) int64() (v int64) { 616 x, _ := s.stack.currentValue().(*Ydb.Value_Int64Value) 617 if x == nil { 618 s.valueTypeError(s.stack.currentValue(), x) 619 620 return 621 } 622 623 return x.Int64Value 624 } 625 626 func (s *valueScanner) uint64() (v uint64) { 627 x, _ := s.stack.currentValue().(*Ydb.Value_Uint64Value) 628 if x == nil { 629 s.valueTypeError(s.stack.currentValue(), x) 630 631 return 632 } 633 634 return x.Uint64Value 635 } 636 637 func (s *valueScanner) float() (v float32) { 638 x, _ := s.stack.currentValue().(*Ydb.Value_FloatValue) 639 if x == nil { 640 s.valueTypeError(s.stack.currentValue(), x) 641 642 return 643 } 644 645 return x.FloatValue 646 } 647 648 func (s *valueScanner) double() (v float64) { 649 x, _ := s.stack.currentValue().(*Ydb.Value_DoubleValue) 650 if x == nil { 651 s.valueTypeError(s.stack.currentValue(), x) 652 653 return 654 } 655 656 return x.DoubleValue 657 } 658 659 func (s *valueScanner) bytes() (v []byte) { 660 x, _ := s.stack.currentValue().(*Ydb.Value_BytesValue) 661 if x == nil { 662 s.valueTypeError(s.stack.currentValue(), x) 663 664 return 665 } 666 667 return x.BytesValue 668 } 669 670 func (s *valueScanner) text() (v string) { 671 x, _ := s.stack.currentValue().(*Ydb.Value_TextValue) 672 if x == nil { 673 s.valueTypeError(s.stack.currentValue(), x) 674 675 return 676 } 677 678 return x.TextValue 679 } 680 681 func (s *valueScanner) low128() (v uint64) { 682 x, _ := s.stack.currentValue().(*Ydb.Value_Low_128) 683 if x == nil { 684 s.valueTypeError(s.stack.currentValue(), x) 685 686 return 687 } 688 689 return x.Low_128 690 } 691 692 func (s *valueScanner) uint128() (v [16]byte) { 693 c := s.stack.current() 694 if c.isEmpty() { 695 _ = s.errorf(0, "not implemented convert to [16]byte") 696 697 return 698 } 699 lo := s.low128() 700 hi := c.v.GetHigh_128() 701 702 return value.BigEndianUint128(hi, lo) 703 } 704 705 func (s *valueScanner) null() { 706 x, _ := s.stack.currentValue().(*Ydb.Value_NullFlagValue) 707 if x == nil { 708 s.valueTypeError(s.stack.currentValue(), x) 709 } 710 } 711 712 func (s *valueScanner) setTime(dst *time.Time) { 713 switch t := s.stack.current().t.GetTypeId(); t { 714 case Ydb.Type_DATE: 715 *dst = value.DateToTime(s.uint32()) 716 case Ydb.Type_DATETIME: 717 *dst = value.DatetimeToTime(s.uint32()) 718 case Ydb.Type_TIMESTAMP: 719 *dst = value.TimestampToTime(s.uint64()) 720 case Ydb.Type_TZ_DATE: 721 src, err := value.TzDateToTime(s.text()) 722 if err != nil { 723 _ = s.errorf(0, "valueScanner.setTime(): %w", err) 724 } 725 *dst = src 726 case Ydb.Type_TZ_DATETIME: 727 src, err := value.TzDatetimeToTime(s.text()) 728 if err != nil { 729 _ = s.errorf(0, "valueScanner.setTime(): %w", err) 730 } 731 *dst = src 732 case Ydb.Type_TZ_TIMESTAMP: 733 src, err := value.TzTimestampToTime(s.text()) 734 if err != nil { 735 _ = s.errorf(0, "valueScanner.setTime(): %w", err) 736 } 737 *dst = src 738 default: 739 _ = s.errorf(0, "valueScanner.setTime(): incorrect source types %s", t) 740 } 741 } 742 743 func (s *valueScanner) setString(dst *string) { 744 switch t := s.stack.current().t.GetTypeId(); t { 745 case Ydb.Type_UUID: 746 src := s.uint128() 747 *dst = xstring.FromBytes(src[:]) 748 case Ydb.Type_UTF8, Ydb.Type_DYNUMBER, Ydb.Type_YSON, Ydb.Type_JSON, Ydb.Type_JSON_DOCUMENT: 749 *dst = s.text() 750 case Ydb.Type_STRING: 751 *dst = xstring.FromBytes(s.bytes()) 752 default: 753 _ = s.errorf(0, "scan row failed: incorrect source types %s", t) 754 } 755 } 756 757 func (s *valueScanner) setByte(dst *[]byte) { 758 switch t := s.stack.current().t.GetTypeId(); t { 759 case Ydb.Type_UUID: 760 src := s.uint128() 761 *dst = src[:] 762 case Ydb.Type_UTF8, Ydb.Type_DYNUMBER, Ydb.Type_YSON, Ydb.Type_JSON, Ydb.Type_JSON_DOCUMENT: 763 *dst = xstring.ToBytes(s.text()) 764 case Ydb.Type_STRING: 765 *dst = s.bytes() 766 default: 767 _ = s.errorf(0, "scan row failed: incorrect source types %s", t) 768 } 769 } 770 771 func (s *valueScanner) trySetByteArray(v interface{}, optional, def bool) bool { 772 rv := reflect.ValueOf(v) 773 if rv.Kind() == reflect.Ptr { 774 rv = rv.Elem() 775 } 776 if rv.Kind() == reflect.Ptr { 777 if !optional { 778 return false 779 } 780 if s.isNull() { 781 rv.Set(reflect.Zero(rv.Type())) 782 783 return true 784 } 785 if rv.IsZero() { 786 nv := reflect.New(rv.Type().Elem()) 787 rv.Set(nv) 788 } 789 rv = rv.Elem() 790 } 791 if rv.Kind() != reflect.Array { 792 return false 793 } 794 if rv.Type().Elem().Kind() != reflect.Uint8 { 795 return false 796 } 797 if def { 798 rv.Set(reflect.Zero(rv.Type())) 799 800 return true 801 } 802 var dst []byte 803 s.setByte(&dst) 804 if rv.Len() != len(dst) { 805 return false 806 } 807 reflect.Copy(rv, reflect.ValueOf(dst)) 808 809 return true 810 } 811 812 //nolint:gocyclo 813 func (s *valueScanner) scanRequired(v interface{}) { 814 switch v := v.(type) { 815 case *bool: 816 *v = s.bool() 817 case *int8: 818 *v = s.int8() 819 case *int16: 820 *v = s.int16() 821 case *int: 822 *v = int(s.int32()) 823 case *int32: 824 *v = s.int32() 825 case *int64: 826 *v = s.int64() 827 case *uint8: 828 *v = s.uint8() 829 case *uint16: 830 *v = s.uint16() 831 case *uint32: 832 *v = s.uint32() 833 case *uint: 834 *v = uint(s.uint32()) 835 case *uint64: 836 *v = s.uint64() 837 case *float32: 838 *v = s.float() 839 case *float64: 840 *v = s.double() 841 case *time.Time: 842 s.setTime(v) 843 case *time.Duration: 844 *v = value.IntervalToDuration(s.int64()) 845 case *string: 846 s.setString(v) 847 case *[]byte: 848 s.setByte(v) 849 case *[16]byte: 850 *v = s.uint128() 851 case *interface{}: 852 *v = s.any() 853 case *value.Value: 854 *v = s.value() 855 case *decimal.Decimal: 856 *v = s.unwrapDecimal() 857 case scanner.Scanner: 858 err := v.UnmarshalYDB(s.converter) 859 if err != nil { 860 _ = s.errorf(0, "ydb.Scanner error: %w", err) 861 } 862 case sql.Scanner: 863 err := v.Scan(s.any()) 864 if err != nil { 865 _ = s.errorf(0, "sql.Scanner error: %w", err) 866 } 867 case json.Unmarshaler: 868 var err error 869 switch s.getType() { 870 case internalTypes.JSON: 871 err = v.UnmarshalJSON(s.converter.JSON()) 872 case internalTypes.JSONDocument: 873 err = v.UnmarshalJSON(s.converter.JSONDocument()) 874 default: 875 _ = s.errorf(0, "ydb required type %T not unsupported for applying to json.Unmarshaler", s.getType()) 876 } 877 if err != nil { 878 _ = s.errorf(0, "json.Unmarshaler error: %w", err) 879 } 880 default: 881 ok := s.trySetByteArray(v, false, false) 882 if !ok { 883 _ = s.errorf(0, "scan row failed: type %T is unknown", v) 884 } 885 } 886 } 887 888 //nolint:gocyclo 889 func (s *valueScanner) scanOptional(v interface{}, defaultValueForOptional bool) { 890 if defaultValueForOptional { 891 if s.isNull() { 892 s.setDefaultValue(v) 893 } else { 894 s.unwrap() 895 s.scanRequired(v) 896 } 897 898 return 899 } 900 switch v := v.(type) { 901 case **bool: 902 if s.isNull() { 903 *v = nil 904 } else { 905 src := s.bool() 906 *v = &src 907 } 908 case **int8: 909 if s.isNull() { 910 *v = nil 911 } else { 912 src := s.int8() 913 *v = &src 914 } 915 case **int16: 916 if s.isNull() { 917 *v = nil 918 } else { 919 src := s.int16() 920 *v = &src 921 } 922 case **int32: 923 if s.isNull() { 924 *v = nil 925 } else { 926 src := s.int32() 927 *v = &src 928 } 929 case **int: 930 if s.isNull() { 931 *v = nil 932 } else { 933 src := int(s.int32()) 934 *v = &src 935 } 936 case **int64: 937 if s.isNull() { 938 *v = nil 939 } else { 940 src := s.int64() 941 *v = &src 942 } 943 case **uint8: 944 if s.isNull() { 945 *v = nil 946 } else { 947 src := s.uint8() 948 *v = &src 949 } 950 case **uint16: 951 if s.isNull() { 952 *v = nil 953 } else { 954 src := s.uint16() 955 *v = &src 956 } 957 case **uint32: 958 if s.isNull() { 959 *v = nil 960 } else { 961 src := s.uint32() 962 *v = &src 963 } 964 case **uint: 965 if s.isNull() { 966 *v = nil 967 } else { 968 src := uint(s.uint32()) 969 *v = &src 970 } 971 case **uint64: 972 if s.isNull() { 973 *v = nil 974 } else { 975 src := s.uint64() 976 *v = &src 977 } 978 case **float32: 979 if s.isNull() { 980 *v = nil 981 } else { 982 src := s.float() 983 *v = &src 984 } 985 case **float64: 986 if s.isNull() { 987 *v = nil 988 } else { 989 src := s.double() 990 *v = &src 991 } 992 case **time.Time: 993 if s.isNull() { 994 *v = nil 995 } else { 996 s.unwrap() 997 var src time.Time 998 s.setTime(&src) 999 *v = &src 1000 } 1001 case **time.Duration: 1002 if s.isNull() { 1003 *v = nil 1004 } else { 1005 src := value.IntervalToDuration(s.int64()) 1006 *v = &src 1007 } 1008 case **string: 1009 if s.isNull() { 1010 *v = nil 1011 } else { 1012 s.unwrap() 1013 var src string 1014 s.setString(&src) 1015 *v = &src 1016 } 1017 case **[]byte: 1018 if s.isNull() { 1019 *v = nil 1020 } else { 1021 s.unwrap() 1022 var src []byte 1023 s.setByte(&src) 1024 *v = &src 1025 } 1026 case **[16]byte: 1027 if s.isNull() { 1028 *v = nil 1029 } else { 1030 src := s.uint128() 1031 *v = &src 1032 } 1033 case **interface{}: 1034 if s.isNull() { 1035 *v = nil 1036 } else { 1037 src := s.any() 1038 *v = &src 1039 } 1040 case *value.Value: 1041 *v = s.value() 1042 case **decimal.Decimal: 1043 if s.isNull() { 1044 *v = nil 1045 } else { 1046 src := s.unwrapDecimal() 1047 *v = &src 1048 } 1049 case scanner.Scanner: 1050 err := v.UnmarshalYDB(s.converter) 1051 if err != nil { 1052 _ = s.errorf(0, "ydb.Scanner error: %w", err) 1053 } 1054 case sql.Scanner: 1055 err := v.Scan(s.any()) 1056 if err != nil { 1057 _ = s.errorf(0, "sql.Scanner error: %w", err) 1058 } 1059 case json.Unmarshaler: 1060 s.unwrap() 1061 var err error 1062 switch s.getType() { 1063 case internalTypes.JSON: 1064 if s.isNull() { 1065 err = v.UnmarshalJSON(nil) 1066 } else { 1067 err = v.UnmarshalJSON(s.converter.JSON()) 1068 } 1069 case internalTypes.JSONDocument: 1070 if s.isNull() { 1071 err = v.UnmarshalJSON(nil) 1072 } else { 1073 err = v.UnmarshalJSON(s.converter.JSONDocument()) 1074 } 1075 default: 1076 _ = s.errorf(0, "ydb optional type %T not unsupported for applying to json.Unmarshaler", s.getType()) 1077 } 1078 if err != nil { 1079 _ = s.errorf(0, "json.Unmarshaler error: %w", err) 1080 } 1081 default: 1082 s.unwrap() 1083 ok := s.trySetByteArray(v, true, false) 1084 if !ok { 1085 rv := reflect.TypeOf(v) 1086 if rv.Kind() == reflect.Ptr && rv.Elem().Kind() == reflect.Ptr { 1087 _ = s.errorf(0, "scan row failed: type %T is unknown", v) 1088 } else { 1089 _ = s.errorf(0, "scan row failed: type %T is not optional! use double pointer or sql.Scanner.", v) 1090 } 1091 } 1092 } 1093 } 1094 1095 func (s *valueScanner) setDefaultValue(dst interface{}) { 1096 switch v := dst.(type) { 1097 case *bool: 1098 *v = false 1099 case *int8: 1100 *v = 0 1101 case *int16: 1102 *v = 0 1103 case *int32: 1104 *v = 0 1105 case *int64: 1106 *v = 0 1107 case *uint8: 1108 *v = 0 1109 case *uint16: 1110 *v = 0 1111 case *uint32: 1112 *v = 0 1113 case *uint64: 1114 *v = 0 1115 case *float32: 1116 *v = 0 1117 case *float64: 1118 *v = 0 1119 case *time.Time: 1120 *v = time.Time{} 1121 case *time.Duration: 1122 *v = 0 1123 case *string: 1124 *v = "" 1125 case *[]byte: 1126 *v = nil 1127 case *[16]byte: 1128 *v = [16]byte{} 1129 case *interface{}: 1130 *v = nil 1131 case *value.Value: 1132 *v = s.value() 1133 case *decimal.Decimal: 1134 *v = decimal.Decimal{} 1135 case sql.Scanner: 1136 err := v.Scan(nil) 1137 if err != nil { 1138 _ = s.errorf(0, "sql.Scanner error: %w", err) 1139 } 1140 case scanner.Scanner: 1141 err := v.UnmarshalYDB(s.converter) 1142 if err != nil { 1143 _ = s.errorf(0, "ydb.Scanner error: %w", err) 1144 } 1145 case json.Unmarshaler: 1146 err := v.UnmarshalJSON(nil) 1147 if err != nil { 1148 _ = s.errorf(0, "json.Unmarshaler error: %w", err) 1149 } 1150 default: 1151 ok := s.trySetByteArray(v, false, true) 1152 if !ok { 1153 _ = s.errorf(0, "scan row failed: type %T is unknown", v) 1154 } 1155 } 1156 } 1157 1158 func (r *baseResult) SetErr(err error) { 1159 r.errMtx.WithLock(func() { 1160 r.err = err 1161 }) 1162 } 1163 1164 func (s *valueScanner) errorf(depth int, f string, args ...interface{}) error { 1165 s.errMtx.Lock() 1166 defer s.errMtx.Unlock() 1167 if s.err != nil { 1168 return s.err 1169 } 1170 s.err = xerrors.WithStackTrace(fmt.Errorf(f, args...), xerrors.WithSkipDepth(depth+1)) 1171 1172 return s.err 1173 } 1174 1175 func (s *valueScanner) typeError(act, exp interface{}) { 1176 _ = s.errorf( 1177 2, 1178 "unexpected types during scan at %q %s: %s; want %s", 1179 s.path(), 1180 s.getType(), 1181 nameIface(act), 1182 nameIface(exp), 1183 ) 1184 } 1185 1186 func (s *valueScanner) valueTypeError(act, exp interface{}) { 1187 // unexpected value during scan at \"migration_status\" Int64: NullFlag; want Int64 1188 _ = s.errorf( 1189 2, 1190 "unexpected value during scan at %q %s: %s; want %s", 1191 s.path(), 1192 s.getType(), 1193 nameIface(act), 1194 nameIface(exp), 1195 ) 1196 } 1197 1198 func (s *valueScanner) notFoundColumnByIndex(idx int) error { 1199 return s.errorf( 1200 2, 1201 "not found %d column", 1202 idx, 1203 ) 1204 } 1205 1206 func (s *valueScanner) notFoundColumnName(name string) error { 1207 return s.errorf( 1208 2, 1209 "not found column '%s'", 1210 name, 1211 ) 1212 } 1213 1214 func (s *valueScanner) noColumnError(name string) error { 1215 return s.errorf( 1216 2, 1217 "no column %q", 1218 name, 1219 ) 1220 } 1221 1222 func (s *valueScanner) overflowError(i, n interface{}) error { 1223 return s.errorf( 1224 2, 1225 "overflow error: %d overflows capacity of %t", 1226 i, 1227 n, 1228 ) 1229 } 1230 1231 var emptyItem item 1232 1233 type item struct { 1234 name string 1235 i int // Index in listing types 1236 t *Ydb.Type 1237 v *Ydb.Value 1238 } 1239 1240 func (x item) isEmpty() bool { 1241 return x.v == nil 1242 } 1243 1244 type scanStack struct { 1245 v []item 1246 p int 1247 scanItem item 1248 } 1249 1250 func (s *scanStack) size() int { 1251 if !s.scanItem.isEmpty() { 1252 s.set(s.scanItem) 1253 } 1254 1255 return s.p + 1 1256 } 1257 1258 func (s *scanStack) get(i int) item { 1259 return s.v[i] 1260 } 1261 1262 func (s *scanStack) reset() { 1263 s.scanItem = emptyItem 1264 s.p = 0 1265 } 1266 1267 func (s *scanStack) enter() { 1268 // support compatibility 1269 if !s.scanItem.isEmpty() { 1270 s.set(s.scanItem) 1271 } 1272 s.scanItem = emptyItem 1273 s.p++ 1274 } 1275 1276 func (s *scanStack) leave() { 1277 s.set(emptyItem) 1278 if s.p > 0 { 1279 s.p-- 1280 } 1281 } 1282 1283 func (s *scanStack) set(v item) { 1284 if s.p == len(s.v) { 1285 s.v = append(s.v, v) 1286 } else { 1287 s.v[s.p] = v 1288 } 1289 } 1290 1291 func (s *scanStack) parent() item { 1292 if s.p == 0 { 1293 return emptyItem 1294 } 1295 1296 return s.v[s.p-1] 1297 } 1298 1299 func (s *scanStack) current() item { 1300 if !s.scanItem.isEmpty() { 1301 return s.scanItem 1302 } 1303 if s.v == nil { 1304 return emptyItem 1305 } 1306 1307 return s.v[s.p] 1308 } 1309 1310 func (s *scanStack) currentValue() interface{} { 1311 if v := s.current().v; v != nil { 1312 return v.GetValue() 1313 } 1314 1315 return nil 1316 } 1317 1318 func (s *scanStack) currentType() interface{} { 1319 if t := s.current().t; t != nil { 1320 return t.GetType() 1321 } 1322 1323 return nil 1324 } 1325 1326 func isOptional(typ *Ydb.Type) bool { 1327 if typ == nil { 1328 return false 1329 } 1330 _, yes := typ.GetType().(*Ydb.Type_OptionalType) 1331 1332 return yes 1333 }