github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/internal/value/value.go (about) 1 package value 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "math/big" 7 "reflect" 8 "sort" 9 "strconv" 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/allocator" 16 "github.com/ydb-platform/ydb-go-sdk/v3/internal/decimal" 17 "github.com/ydb-platform/ydb-go-sdk/v3/internal/types" 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 const ( 23 decimalPrecision uint32 = 22 24 decimalScale uint32 = 9 25 ) 26 27 type Value interface { 28 Type() types.Type 29 Yql() string 30 31 castTo(dst interface{}) error 32 toYDB(a *allocator.Allocator) *Ydb.Value 33 } 34 35 func ToYDB(v Value, a *allocator.Allocator) *Ydb.TypedValue { 36 tv := a.TypedValue() 37 38 tv.Type = v.Type().ToYDB(a) 39 tv.Value = v.toYDB(a) 40 41 return tv 42 } 43 44 // BigEndianUint128 builds a big-endian uint128 value. 45 func BigEndianUint128(hi, lo uint64) (v [16]byte) { 46 binary.BigEndian.PutUint64(v[0:8], hi) 47 binary.BigEndian.PutUint64(v[8:16], lo) 48 49 return v 50 } 51 52 func FromYDB(t *Ydb.Type, v *Ydb.Value) Value { 53 vv, err := fromYDB(t, v) 54 if err != nil { 55 panic(err) 56 } 57 58 return vv 59 } 60 61 func nullValueFromYDB(x *Ydb.Value, t types.Type) (_ Value, ok bool) { 62 for { 63 switch xx := x.GetValue().(type) { 64 case *Ydb.Value_NestedValue: 65 x = xx.NestedValue 66 case *Ydb.Value_NullFlagValue: 67 switch tt := t.(type) { 68 case types.Optional: 69 return NullValue(tt.InnerType()), true 70 case types.Void: 71 return VoidValue(), true 72 default: 73 return nil, false 74 } 75 default: 76 return nil, false 77 } 78 } 79 } 80 81 //nolint:funlen 82 func primitiveValueFromYDB(t types.Primitive, v *Ydb.Value) (Value, error) { 83 switch t { 84 case types.Bool: 85 return BoolValue(v.GetBoolValue()), nil 86 87 case types.Int8: 88 return Int8Value(int8(v.GetInt32Value())), nil 89 90 case types.Int16: 91 return Int16Value(int16(v.GetInt32Value())), nil 92 93 case types.Int32: 94 return Int32Value(v.GetInt32Value()), nil 95 96 case types.Int64: 97 return Int64Value(v.GetInt64Value()), nil 98 99 case types.Uint8: 100 return Uint8Value(uint8(v.GetUint32Value())), nil 101 102 case types.Uint16: 103 return Uint16Value(uint16(v.GetUint32Value())), nil 104 105 case types.Uint32: 106 return Uint32Value(v.GetUint32Value()), nil 107 108 case types.Uint64: 109 return Uint64Value(v.GetUint64Value()), nil 110 111 case types.Date: 112 return DateValue(v.GetUint32Value()), nil 113 114 case types.Datetime: 115 return DatetimeValue(v.GetUint32Value()), nil 116 117 case types.Interval: 118 return IntervalValue(v.GetInt64Value()), nil 119 120 case types.Timestamp: 121 return TimestampValue(v.GetUint64Value()), nil 122 123 case types.Float: 124 return FloatValue(v.GetFloatValue()), nil 125 126 case types.Double: 127 return DoubleValue(v.GetDoubleValue()), nil 128 129 case types.Text: 130 return TextValue(v.GetTextValue()), nil 131 132 case types.YSON: 133 switch vv := v.GetValue().(type) { 134 case *Ydb.Value_TextValue: 135 return YSONValue(xstring.ToBytes(vv.TextValue)), nil 136 case *Ydb.Value_BytesValue: 137 return YSONValue(vv.BytesValue), nil 138 default: 139 return nil, xerrors.WithStackTrace(fmt.Errorf("uncovered YSON internal type: %T", vv)) 140 } 141 142 case types.JSON: 143 return JSONValue(v.GetTextValue()), nil 144 145 case types.JSONDocument: 146 return JSONDocumentValue(v.GetTextValue()), nil 147 148 case types.DyNumber: 149 return DyNumberValue(v.GetTextValue()), nil 150 151 case types.TzDate: 152 return TzDateValue(v.GetTextValue()), nil 153 154 case types.TzDatetime: 155 return TzDatetimeValue(v.GetTextValue()), nil 156 157 case types.TzTimestamp: 158 return TzTimestampValue(v.GetTextValue()), nil 159 160 case types.Bytes: 161 return BytesValue(v.GetBytesValue()), nil 162 163 case types.UUID: 164 return UUIDFromYDBPair(v.GetHigh_128(), v.GetLow_128()), nil 165 default: 166 return nil, xerrors.WithStackTrace(fmt.Errorf("uncovered primitive type: %T", t)) 167 } 168 } 169 170 //nolint:funlen 171 func fromYDB(t *Ydb.Type, v *Ydb.Value) (Value, error) { 172 tt := types.TypeFromYDB(t) 173 174 if vv, ok := nullValueFromYDB(v, tt); ok { 175 return vv, nil 176 } 177 178 switch ttt := tt.(type) { 179 case types.Primitive: 180 return primitiveValueFromYDB(ttt, v) 181 182 case types.Void: 183 return VoidValue(), nil 184 185 case types.Null: 186 return NullValue(tt), nil 187 188 case *types.Decimal: 189 return DecimalValue(BigEndianUint128(v.GetHigh_128(), v.GetLow_128()), ttt.Precision(), ttt.Scale()), nil 190 191 case types.Optional: 192 tt, ok := t.GetType().(*Ydb.Type_OptionalType) 193 if !ok { 194 panic(fmt.Sprintf("unsupported type conversion from %T to *Ydb.Type_OptionalType", tt)) 195 } 196 t = tt.OptionalType.GetItem() 197 if nestedValue, ok := v.GetValue().(*Ydb.Value_NestedValue); ok { 198 return OptionalValue(FromYDB(t, nestedValue.NestedValue)), nil 199 } 200 201 return OptionalValue(FromYDB(t, v)), nil 202 203 case *types.List: 204 return ListValue(func() []Value { 205 vv := make([]Value, len(v.GetItems())) 206 a := allocator.New() 207 defer a.Free() 208 for i, vvv := range v.GetItems() { 209 vv[i] = FromYDB(ttt.ItemType().ToYDB(a), vvv) 210 } 211 212 return vv 213 }()...), nil 214 215 case *types.Tuple: 216 return TupleValue(func() []Value { 217 vv := make([]Value, len(v.GetItems())) 218 a := allocator.New() 219 defer a.Free() 220 for i, vvv := range v.GetItems() { 221 vv[i] = FromYDB(ttt.ItemType(i).ToYDB(a), vvv) 222 } 223 224 return vv 225 }()...), nil 226 227 case *types.Struct: 228 return StructValue(func() []StructValueField { 229 vv := make([]StructValueField, len(v.GetItems())) 230 a := allocator.New() 231 defer a.Free() 232 for i, vvv := range v.GetItems() { 233 vv[i] = StructValueField{ 234 Name: ttt.Field(i).Name, 235 V: FromYDB(ttt.Field(i).T.ToYDB(a), vvv), 236 } 237 } 238 239 return vv 240 }()...), nil 241 242 case *types.Dict: 243 return DictValue(func() []DictValueField { 244 vv := make([]DictValueField, len(v.GetPairs())) 245 a := allocator.New() 246 defer a.Free() 247 for i, vvv := range v.GetPairs() { 248 vv[i] = DictValueField{ 249 K: FromYDB(ttt.KeyType().ToYDB(a), vvv.GetKey()), 250 V: FromYDB(ttt.ValueType().ToYDB(a), vvv.GetPayload()), 251 } 252 } 253 254 return vv 255 }()...), nil 256 257 case *types.Set: 258 return SetValue(func() []Value { 259 vv := make([]Value, len(v.GetPairs())) 260 a := allocator.New() 261 defer a.Free() 262 for i, vvv := range v.GetPairs() { 263 vv[i] = FromYDB(ttt.ItemType().ToYDB(a), vvv.GetKey()) 264 } 265 266 return vv 267 }()...), nil 268 269 case *types.VariantStruct: 270 a := allocator.New() 271 defer a.Free() 272 273 val, ok := v.GetValue().(*Ydb.Value_NestedValue) 274 if !ok { 275 panic(fmt.Sprintf("unsupported type conversion from %T to *Ydb.Value_NestedValue", val)) 276 } 277 278 return VariantValueStruct( 279 FromYDB( 280 ttt.Struct.Field(int(v.GetVariantIndex())).T.ToYDB(a), 281 val.NestedValue, 282 ), 283 ttt.Struct.Field(int(v.GetVariantIndex())).Name, 284 ttt.Struct, 285 ), nil 286 287 case *types.VariantTuple: 288 a := allocator.New() 289 defer a.Free() 290 291 val, ok := v.GetValue().(*Ydb.Value_NestedValue) 292 if !ok { 293 panic(fmt.Sprintf("unsupported type conversion from %T to *Ydb.Value_NestedValue", val)) 294 } 295 296 return VariantValueTuple( 297 FromYDB( 298 ttt.Tuple.ItemType(int(v.GetVariantIndex())).ToYDB(a), 299 val.NestedValue, 300 ), 301 v.GetVariantIndex(), 302 ttt.Tuple, 303 ), nil 304 305 case *types.PgType: 306 return &pgValue{ 307 t: types.PgType{ 308 OID: ttt.OID, 309 }, 310 val: v.GetTextValue(), 311 }, nil 312 313 default: 314 return nil, xerrors.WithStackTrace(fmt.Errorf("uncovered type: %T", ttt)) 315 } 316 } 317 318 type boolValue bool 319 320 func (v boolValue) castTo(dst interface{}) error { 321 switch vv := dst.(type) { 322 case *bool: 323 *vv = bool(v) 324 325 return nil 326 case *string: 327 *vv = strconv.FormatBool(bool(v)) 328 329 return nil 330 default: 331 return xerrors.WithStackTrace(fmt.Errorf( 332 "%w '%s(%+v)' to '%T' destination", 333 ErrCannotCast, v.Type().Yql(), v, vv, 334 )) 335 } 336 } 337 338 func (v boolValue) Yql() string { 339 return strconv.FormatBool(bool(v)) 340 } 341 342 func (boolValue) Type() types.Type { 343 return types.Bool 344 } 345 346 func (v boolValue) toYDB(a *allocator.Allocator) *Ydb.Value { 347 vv := a.Bool() 348 349 vv.BoolValue = bool(v) 350 351 vvv := a.Value() 352 vvv.Value = vv 353 354 return vvv 355 } 356 357 func BoolValue(v bool) boolValue { 358 return boolValue(v) 359 } 360 361 type dateValue uint32 362 363 func (v dateValue) castTo(dst interface{}) error { 364 switch vv := dst.(type) { 365 case *time.Time: 366 *vv = DateToTime(uint32(v)).UTC() 367 368 return nil 369 case *uint64: 370 *vv = uint64(v) 371 372 return nil 373 case *int64: 374 *vv = int64(v) 375 376 return nil 377 case *int32: 378 *vv = int32(v) 379 380 return nil 381 default: 382 return xerrors.WithStackTrace(fmt.Errorf( 383 "%w '%s(%+v)' to '%T' destination", 384 ErrCannotCast, v.Type().Yql(), v, vv, 385 )) 386 } 387 } 388 389 func (v dateValue) Yql() string { 390 return fmt.Sprintf("%s(%q)", v.Type().Yql(), DateToTime(uint32(v)).UTC().Format(LayoutDate)) 391 } 392 393 func (dateValue) Type() types.Type { 394 return types.Date 395 } 396 397 func (v dateValue) toYDB(a *allocator.Allocator) *Ydb.Value { 398 vv := a.Uint32() 399 400 vv.Uint32Value = uint32(v) 401 402 vvv := a.Value() 403 vvv.Value = vv 404 405 return vvv 406 } 407 408 // DateValue returns ydb date value by given days since Epoch 409 func DateValue(v uint32) dateValue { 410 return dateValue(v) 411 } 412 413 func DateValueFromTime(t time.Time) dateValue { 414 return dateValue(uint64(t.Sub(epoch)/time.Second) / secondsPerDay) 415 } 416 417 type datetimeValue uint32 418 419 func (v datetimeValue) castTo(dst interface{}) error { 420 switch vv := dst.(type) { 421 case *time.Time: 422 *vv = DatetimeToTime(uint32(v)) 423 424 return nil 425 case *uint64: 426 *vv = uint64(v) 427 428 return nil 429 case *int64: 430 *vv = int64(v) 431 432 return nil 433 case *uint32: 434 *vv = uint32(v) 435 436 return nil 437 default: 438 return xerrors.WithStackTrace(fmt.Errorf( 439 "%w '%s(%+v)' to '%T' destination", 440 ErrCannotCast, v.Type().Yql(), v, vv, 441 )) 442 } 443 } 444 445 func (v datetimeValue) Yql() string { 446 return fmt.Sprintf("%s(%q)", v.Type().Yql(), DatetimeToTime(uint32(v)).UTC().Format(LayoutDatetime)) 447 } 448 449 func (datetimeValue) Type() types.Type { 450 return types.Datetime 451 } 452 453 func (v datetimeValue) toYDB(a *allocator.Allocator) *Ydb.Value { 454 vv := a.Uint32() 455 vv.Uint32Value = uint32(v) 456 457 vvv := a.Value() 458 vvv.Value = vv 459 460 return vvv 461 } 462 463 // DatetimeValue makes ydb datetime value from seconds since Epoch 464 func DatetimeValue(v uint32) datetimeValue { 465 return datetimeValue(v) 466 } 467 468 func DatetimeValueFromTime(t time.Time) datetimeValue { 469 return datetimeValue(t.Unix()) 470 } 471 472 var _ DecimalValuer = (*decimalValue)(nil) 473 474 type decimalValue struct { 475 value [16]byte 476 innerType *types.Decimal 477 } 478 479 func (v *decimalValue) Value() [16]byte { 480 return v.value 481 } 482 483 func (v *decimalValue) Precision() uint32 { 484 return v.innerType.Precision() 485 } 486 487 func (v *decimalValue) Scale() uint32 { 488 return v.innerType.Scale() 489 } 490 491 type DecimalValuer interface { 492 Value() [16]byte 493 Precision() uint32 494 Scale() uint32 495 } 496 497 func (v *decimalValue) castTo(dst interface{}) error { 498 return xerrors.WithStackTrace(fmt.Errorf( 499 "%w '%+v' to '%T' destination", 500 ErrCannotCast, v, dst, 501 )) 502 } 503 504 func (v *decimalValue) Yql() string { 505 buffer := xstring.Buffer() 506 defer buffer.Free() 507 buffer.WriteString(v.innerType.Name()) 508 buffer.WriteByte('(') 509 buffer.WriteByte('"') 510 s := decimal.FromBytes(v.value[:], v.innerType.Precision(), v.innerType.Scale()).String() 511 buffer.WriteString(s[:len(s)-int(v.innerType.Scale())] + "." + s[len(s)-int(v.innerType.Scale()):]) 512 buffer.WriteByte('"') 513 buffer.WriteByte(',') 514 buffer.WriteString(strconv.FormatUint(uint64(v.innerType.Precision()), 10)) 515 buffer.WriteByte(',') 516 buffer.WriteString(strconv.FormatUint(uint64(v.innerType.Scale()), 10)) 517 buffer.WriteByte(')') 518 519 return buffer.String() 520 } 521 522 func (v *decimalValue) Type() types.Type { 523 return v.innerType 524 } 525 526 func (v *decimalValue) toYDB(a *allocator.Allocator) *Ydb.Value { 527 var bytes [16]byte 528 if v != nil { 529 bytes = v.value 530 } 531 vv := a.Low128() 532 vv.Low_128 = binary.BigEndian.Uint64(bytes[8:16]) 533 534 vvv := a.Value() 535 vvv.High_128 = binary.BigEndian.Uint64(bytes[0:8]) 536 vvv.Value = vv 537 538 return vvv 539 } 540 541 func DecimalValueFromBigInt(v *big.Int, precision, scale uint32) *decimalValue { 542 b := decimal.BigIntToByte(v, precision, scale) 543 544 return DecimalValue(b, precision, scale) 545 } 546 547 func DecimalValueFromString(str string, precision, scale uint32) (Value, error) { 548 bigI, err := decimal.Parse(str, precision, scale) 549 if err != nil { 550 return nil, err 551 } 552 553 return DecimalValueFromBigInt(bigI, precision, scale), nil 554 } 555 556 func DecimalValue(v [16]byte, precision, scale uint32) *decimalValue { 557 return &decimalValue{ 558 value: v, 559 innerType: types.NewDecimal( 560 precision, 561 scale, 562 ), 563 } 564 } 565 566 type ( 567 DictValueField struct { 568 K Value 569 V Value 570 } 571 dictValue struct { 572 t types.Type 573 values []DictValueField 574 } 575 ) 576 577 func (v *dictValue) DictValues() map[Value]Value { 578 values := make(map[Value]Value, len(v.values)) 579 for i := range v.values { 580 values[v.values[i].K] = v.values[i].V 581 } 582 583 return values 584 } 585 586 func (v *dictValue) castTo(dst interface{}) error { 587 return xerrors.WithStackTrace(fmt.Errorf( 588 "%w '%+v' to '%T' destination", 589 ErrCannotCast, v, dst, 590 )) 591 } 592 593 func (v *dictValue) Yql() string { 594 buffer := xstring.Buffer() 595 defer buffer.Free() 596 buffer.WriteByte('{') 597 for i := range v.values { 598 if i != 0 { 599 buffer.WriteByte(',') 600 } 601 buffer.WriteString(v.values[i].K.Yql()) 602 buffer.WriteByte(':') 603 buffer.WriteString(v.values[i].V.Yql()) 604 } 605 buffer.WriteByte('}') 606 607 return buffer.String() 608 } 609 610 func (v *dictValue) Type() types.Type { 611 return v.t 612 } 613 614 func (v *dictValue) toYDB(a *allocator.Allocator) *Ydb.Value { 615 var values []DictValueField 616 if v != nil { 617 values = v.values 618 } 619 vvv := a.Value() 620 621 for i := range values { 622 pair := a.Pair() 623 624 pair.Key = values[i].K.toYDB(a) 625 pair.Payload = values[i].V.toYDB(a) 626 627 vvv.Pairs = append(vvv.GetPairs(), pair) 628 } 629 630 return vvv 631 } 632 633 func DictValue(values ...DictValueField) *dictValue { 634 sort.Slice(values, func(i, j int) bool { 635 return values[i].K.Yql() < values[j].K.Yql() 636 }) 637 var t types.Type 638 switch { 639 case len(values) > 0: 640 t = types.NewDict(values[0].K.Type(), values[0].V.Type()) 641 default: 642 t = types.NewEmptyDict() 643 } 644 645 return &dictValue{ 646 t: t, 647 values: values, 648 } 649 } 650 651 type doubleValue struct { 652 value float64 653 } 654 655 func (v *doubleValue) castTo(dst interface{}) error { 656 switch vv := dst.(type) { 657 case *string: 658 *vv = strconv.FormatFloat(v.value, 'f', -1, 64) 659 660 return nil 661 case *[]byte: 662 *vv = xstring.ToBytes(strconv.FormatFloat(v.value, 'f', -1, 64)) 663 664 return nil 665 case *float64: 666 *vv = v.value 667 668 return nil 669 default: 670 return xerrors.WithStackTrace(fmt.Errorf( 671 "%w '%s(%+v)' to '%T' destination", 672 ErrCannotCast, v.Type().Yql(), v, vv, 673 )) 674 } 675 } 676 677 func (v *doubleValue) Yql() string { 678 return fmt.Sprintf("%s(\"%v\")", v.Type().Yql(), v.value) 679 } 680 681 func (*doubleValue) Type() types.Type { 682 return types.Double 683 } 684 685 func (v *doubleValue) toYDB(a *allocator.Allocator) *Ydb.Value { 686 vv := a.Double() 687 if v != nil { 688 vv.DoubleValue = v.value 689 } 690 691 vvv := a.Value() 692 vvv.Value = vv 693 694 return vvv 695 } 696 697 func DoubleValue(v float64) *doubleValue { 698 return &doubleValue{value: v} 699 } 700 701 type dyNumberValue string 702 703 func (v dyNumberValue) castTo(dst interface{}) error { 704 switch vv := dst.(type) { 705 case *string: 706 *vv = string(v) 707 708 return nil 709 case *[]byte: 710 *vv = xstring.ToBytes(string(v)) 711 712 return nil 713 default: 714 return xerrors.WithStackTrace(fmt.Errorf( 715 "%w '%s(%+v)' to '%T' destination", 716 ErrCannotCast, v.Type().Yql(), v, vv, 717 )) 718 } 719 } 720 721 func (v dyNumberValue) Yql() string { 722 return fmt.Sprintf("%s(%q)", v.Type().Yql(), string(v)) 723 } 724 725 func (dyNumberValue) Type() types.Type { 726 return types.DyNumber 727 } 728 729 func (v dyNumberValue) toYDB(a *allocator.Allocator) *Ydb.Value { 730 vv := a.Text() 731 vv.TextValue = string(v) 732 733 vvv := a.Value() 734 vvv.Value = vv 735 736 return vvv 737 } 738 739 func DyNumberValue(v string) dyNumberValue { 740 return dyNumberValue(v) 741 } 742 743 type floatValue struct { 744 value float32 745 } 746 747 func (v *floatValue) castTo(dst interface{}) error { 748 switch vv := dst.(type) { 749 case *string: 750 *vv = strconv.FormatFloat(float64(v.value), 'f', -1, 32) 751 752 return nil 753 case *[]byte: 754 *vv = xstring.ToBytes(strconv.FormatFloat(float64(v.value), 'f', -1, 32)) 755 756 return nil 757 case *float64: 758 *vv = float64(v.value) 759 760 return nil 761 case *float32: 762 *vv = v.value 763 764 return nil 765 default: 766 return xerrors.WithStackTrace(fmt.Errorf( 767 "%w '%s(%+v)' to '%T' destination", 768 ErrCannotCast, v.Type().Yql(), v, vv, 769 )) 770 } 771 } 772 773 func (v *floatValue) Yql() string { 774 return fmt.Sprintf("%s(\"%v\")", v.Type().Yql(), v.value) 775 } 776 777 func (*floatValue) Type() types.Type { 778 return types.Float 779 } 780 781 func (v *floatValue) toYDB(a *allocator.Allocator) *Ydb.Value { 782 vv := a.Float() 783 if v != nil { 784 vv.FloatValue = v.value 785 } 786 787 vvv := a.Value() 788 vvv.Value = vv 789 790 return vvv 791 } 792 793 func FloatValue(v float32) *floatValue { 794 return &floatValue{value: v} 795 } 796 797 type int8Value int8 798 799 func (v int8Value) castTo(dst interface{}) error { 800 switch vv := dst.(type) { 801 case *string: 802 *vv = strconv.FormatInt(int64(v), 10) 803 804 return nil 805 case *[]byte: 806 *vv = xstring.ToBytes(strconv.FormatInt(int64(v), 10)) 807 808 return nil 809 case *int64: 810 *vv = int64(v) 811 812 return nil 813 814 case *int32: 815 *vv = int32(v) 816 817 return nil 818 819 case *int16: 820 *vv = int16(v) 821 822 return nil 823 824 case *int8: 825 *vv = int8(v) 826 827 return nil 828 829 case *float64: 830 *vv = float64(v) 831 832 return nil 833 case *float32: 834 *vv = float32(v) 835 836 return nil 837 default: 838 return xerrors.WithStackTrace(fmt.Errorf( 839 "%w '%s(%+v)' to '%T' destination", 840 ErrCannotCast, v.Type().Yql(), v, vv, 841 )) 842 } 843 } 844 845 func (v int8Value) Yql() string { 846 return strconv.FormatUint(uint64(v), 10) + "t" 847 } 848 849 func (int8Value) Type() types.Type { 850 return types.Int8 851 } 852 853 func (v int8Value) toYDB(a *allocator.Allocator) *Ydb.Value { 854 vv := a.Int32() 855 vv.Int32Value = int32(v) 856 857 vvv := a.Value() 858 vvv.Value = vv 859 860 return vvv 861 } 862 863 func Int8Value(v int8) int8Value { 864 return int8Value(v) 865 } 866 867 type int16Value int16 868 869 func (v int16Value) castTo(dst interface{}) error { 870 switch vv := dst.(type) { 871 case *string: 872 *vv = strconv.FormatInt(int64(v), 10) 873 874 return nil 875 case *[]byte: 876 *vv = xstring.ToBytes(strconv.FormatInt(int64(v), 10)) 877 878 return nil 879 case *int64: 880 *vv = int64(v) 881 882 return nil 883 case *int32: 884 *vv = int32(v) 885 886 return nil 887 case *int16: 888 *vv = int16(v) 889 890 return nil 891 case *float64: 892 *vv = float64(v) 893 894 return nil 895 case *float32: 896 *vv = float32(v) 897 898 return nil 899 default: 900 return xerrors.WithStackTrace(fmt.Errorf( 901 "%w '%s(%+v)' to '%T' destination", 902 ErrCannotCast, v.Type().Yql(), v, vv, 903 )) 904 } 905 } 906 907 func (v int16Value) Yql() string { 908 return strconv.FormatUint(uint64(v), 10) + "s" 909 } 910 911 func (int16Value) Type() types.Type { 912 return types.Int16 913 } 914 915 func (v int16Value) toYDB(a *allocator.Allocator) *Ydb.Value { 916 vv := a.Int32() 917 vv.Int32Value = int32(v) 918 919 vvv := a.Value() 920 vvv.Value = vv 921 922 return vvv 923 } 924 925 func Int16Value(v int16) int16Value { 926 return int16Value(v) 927 } 928 929 type int32Value int32 930 931 func (v int32Value) castTo(dst interface{}) error { 932 switch vv := dst.(type) { 933 case *string: 934 *vv = strconv.FormatInt(int64(v), 10) 935 936 return nil 937 case *[]byte: 938 *vv = xstring.ToBytes(strconv.FormatInt(int64(v), 10)) 939 940 return nil 941 case *int64: 942 *vv = int64(v) 943 944 return nil 945 946 case *int: 947 *vv = int(v) 948 949 return nil 950 951 case *int32: 952 *vv = int32(v) 953 954 return nil 955 956 case *float64: 957 *vv = float64(v) 958 959 return nil 960 case *float32: 961 *vv = float32(v) 962 963 return nil 964 default: 965 return xerrors.WithStackTrace(fmt.Errorf( 966 "%w '%s(%+v)' to '%T' destination", 967 ErrCannotCast, v.Type().Yql(), v, vv, 968 )) 969 } 970 } 971 972 func (v int32Value) Yql() string { 973 return strconv.FormatInt(int64(v), 10) 974 } 975 976 func (int32Value) Type() types.Type { 977 return types.Int32 978 } 979 980 func (v int32Value) toYDB(a *allocator.Allocator) *Ydb.Value { 981 vv := a.Int32() 982 vv.Int32Value = int32(v) 983 984 vvv := a.Value() 985 vvv.Value = vv 986 987 return vvv 988 } 989 990 func Int32Value(v int32) int32Value { 991 return int32Value(v) 992 } 993 994 type int64Value int64 995 996 func (v int64Value) castTo(dst interface{}) error { 997 switch vv := dst.(type) { 998 case *string: 999 *vv = strconv.FormatInt(int64(v), 10) 1000 1001 return nil 1002 case *[]byte: 1003 *vv = xstring.ToBytes(strconv.FormatInt(int64(v), 10)) 1004 1005 return nil 1006 case *int64: 1007 *vv = int64(v) 1008 1009 return nil 1010 1011 case *float64: 1012 *vv = float64(v) 1013 1014 return nil 1015 default: 1016 return xerrors.WithStackTrace(fmt.Errorf( 1017 "%w '%s(%+v)' to '%T' destination", 1018 ErrCannotCast, v.Type().Yql(), v, vv, 1019 )) 1020 } 1021 } 1022 1023 func (v int64Value) Yql() string { 1024 return strconv.FormatUint(uint64(v), 10) + "l" 1025 } 1026 1027 func (int64Value) Type() types.Type { 1028 return types.Int64 1029 } 1030 1031 func (v int64Value) toYDB(a *allocator.Allocator) *Ydb.Value { 1032 vv := a.Int64() 1033 vv.Int64Value = int64(v) 1034 1035 vvv := a.Value() 1036 vvv.Value = vv 1037 1038 return vvv 1039 } 1040 1041 func Int64Value(v int64) int64Value { 1042 return int64Value(v) 1043 } 1044 1045 type intervalValue int64 1046 1047 func (v intervalValue) castTo(dst interface{}) error { 1048 switch vv := dst.(type) { 1049 case *time.Duration: 1050 *vv = IntervalToDuration(int64(v)) 1051 1052 return nil 1053 case *int64: 1054 *vv = int64(v) 1055 1056 return nil 1057 default: 1058 return xerrors.WithStackTrace(fmt.Errorf( 1059 "%w '%s(%+v)' to '%T' destination", 1060 ErrCannotCast, v.Type().Yql(), v, vv, 1061 )) 1062 } 1063 } 1064 1065 func (v intervalValue) Yql() string { 1066 buffer := xstring.Buffer() 1067 defer buffer.Free() 1068 buffer.WriteString(v.Type().Yql()) 1069 buffer.WriteByte('(') 1070 buffer.WriteByte('"') 1071 d := IntervalToDuration(int64(v)) 1072 if d < 0 { 1073 buffer.WriteByte('-') 1074 d = -d 1075 } 1076 buffer.WriteByte('P') 1077 //nolint:gomnd 1078 if days := d / time.Hour / 24; days > 0 { 1079 d -= days * time.Hour * 24 //nolint:durationcheck 1080 buffer.WriteString(strconv.FormatInt(int64(days), 10)) 1081 buffer.WriteByte('D') 1082 } 1083 if d > 0 { 1084 buffer.WriteByte('T') 1085 } 1086 if hours := d / time.Hour; hours > 0 { 1087 d -= hours * time.Hour //nolint:durationcheck 1088 buffer.WriteString(strconv.FormatInt(int64(hours), 10)) 1089 buffer.WriteByte('H') 1090 } 1091 if minutes := d / time.Minute; minutes > 0 { 1092 d -= minutes * time.Minute //nolint:durationcheck 1093 buffer.WriteString(strconv.FormatInt(int64(minutes), 10)) 1094 buffer.WriteByte('M') 1095 } 1096 if d > 0 { 1097 seconds := float64(d) / float64(time.Second) 1098 fmt.Fprintf(buffer, "%0.6f", seconds) 1099 buffer.WriteByte('S') 1100 } 1101 buffer.WriteByte('"') 1102 buffer.WriteByte(')') 1103 1104 return buffer.String() 1105 } 1106 1107 func (intervalValue) Type() types.Type { 1108 return types.Interval 1109 } 1110 1111 func (v intervalValue) toYDB(a *allocator.Allocator) *Ydb.Value { 1112 vv := a.Int64() 1113 vv.Int64Value = int64(v) 1114 1115 vvv := a.Value() 1116 vvv.Value = vv 1117 1118 return vvv 1119 } 1120 1121 // IntervalValue makes Value from given microseconds value 1122 func IntervalValue(v int64) intervalValue { 1123 return intervalValue(v) 1124 } 1125 1126 func IntervalValueFromDuration(v time.Duration) intervalValue { 1127 return intervalValue(durationToMicroseconds(v)) 1128 } 1129 1130 type jsonValue string 1131 1132 func (v jsonValue) castTo(dst interface{}) error { 1133 switch vv := dst.(type) { 1134 case *string: 1135 *vv = string(v) 1136 1137 return nil 1138 case *[]byte: 1139 *vv = xstring.ToBytes(string(v)) 1140 1141 return nil 1142 default: 1143 return xerrors.WithStackTrace(fmt.Errorf( 1144 "%w '%s(%+v)' to '%T' destination", 1145 ErrCannotCast, v.Type().Yql(), v, vv, 1146 )) 1147 } 1148 } 1149 1150 func (v jsonValue) Yql() string { 1151 return fmt.Sprintf("%s(@@%s@@)", v.Type().Yql(), string(v)) 1152 } 1153 1154 func (jsonValue) Type() types.Type { 1155 return types.JSON 1156 } 1157 1158 func (v jsonValue) toYDB(a *allocator.Allocator) *Ydb.Value { 1159 vv := a.Text() 1160 vv.TextValue = string(v) 1161 1162 vvv := a.Value() 1163 vvv.Value = vv 1164 1165 return vvv 1166 } 1167 1168 func JSONValue(v string) jsonValue { 1169 return jsonValue(v) 1170 } 1171 1172 type jsonDocumentValue string 1173 1174 func (v jsonDocumentValue) castTo(dst interface{}) error { 1175 switch vv := dst.(type) { 1176 case *string: 1177 *vv = string(v) 1178 1179 return nil 1180 case *[]byte: 1181 *vv = xstring.ToBytes(string(v)) 1182 1183 return nil 1184 default: 1185 return xerrors.WithStackTrace(fmt.Errorf( 1186 "%w '%s(%+v)' to '%T' destination", 1187 ErrCannotCast, v.Type().Yql(), v, vv, 1188 )) 1189 } 1190 } 1191 1192 func (v jsonDocumentValue) Yql() string { 1193 return fmt.Sprintf("%s(@@%s@@)", v.Type().Yql(), string(v)) 1194 } 1195 1196 func (jsonDocumentValue) Type() types.Type { 1197 return types.JSONDocument 1198 } 1199 1200 func (v jsonDocumentValue) toYDB(a *allocator.Allocator) *Ydb.Value { 1201 vv := a.Text() 1202 vv.TextValue = string(v) 1203 1204 vvv := a.Value() 1205 vvv.Value = vv 1206 1207 return vvv 1208 } 1209 1210 func JSONDocumentValue(v string) jsonDocumentValue { 1211 return jsonDocumentValue(v) 1212 } 1213 1214 type listValue struct { 1215 t types.Type 1216 items []Value 1217 } 1218 1219 func (v *listValue) ListItems() []Value { 1220 return v.items 1221 } 1222 1223 func (v *listValue) castTo(dst interface{}) error { 1224 return xerrors.WithStackTrace(fmt.Errorf( 1225 "%w '%s(%+v)' to '%T' destination", 1226 ErrCannotCast, v.Type().Yql(), v, dst, 1227 )) 1228 } 1229 1230 func (v *listValue) Yql() string { 1231 buffer := xstring.Buffer() 1232 defer buffer.Free() 1233 buffer.WriteByte('[') 1234 for i, item := range v.items { 1235 if i != 0 { 1236 buffer.WriteByte(',') 1237 } 1238 buffer.WriteString(item.Yql()) 1239 } 1240 buffer.WriteByte(']') 1241 1242 return buffer.String() 1243 } 1244 1245 func (v *listValue) Type() types.Type { 1246 return v.t 1247 } 1248 1249 func (v *listValue) toYDB(a *allocator.Allocator) *Ydb.Value { 1250 var items []Value 1251 if v != nil { 1252 items = v.items 1253 } 1254 vvv := a.Value() 1255 1256 for _, vv := range items { 1257 vvv.Items = append(vvv.GetItems(), vv.toYDB(a)) 1258 } 1259 1260 return vvv 1261 } 1262 1263 func ListValue(items ...Value) *listValue { 1264 var t types.Type 1265 switch { 1266 case len(items) > 0: 1267 t = types.NewList(items[0].Type()) 1268 default: 1269 t = types.NewEmptyList() 1270 } 1271 1272 return &listValue{ 1273 t: t, 1274 items: items, 1275 } 1276 } 1277 1278 type pgValue struct { 1279 t types.PgType 1280 val string 1281 } 1282 1283 func (v pgValue) castTo(dst interface{}) error { 1284 return xerrors.WithStackTrace(fmt.Errorf( 1285 "%w PgType to '%T' destination", 1286 ErrCannotCast, dst, 1287 )) 1288 } 1289 1290 func (v pgValue) Type() types.Type { 1291 return v.t 1292 } 1293 1294 func (v pgValue) toYDB(_ *allocator.Allocator) *Ydb.Value { 1295 //nolint:godox 1296 // TODO: make allocator 1297 return &Ydb.Value{ 1298 Value: &Ydb.Value_TextValue{ 1299 TextValue: v.val, 1300 }, 1301 } 1302 } 1303 1304 func (v pgValue) Yql() string { 1305 //nolint:godox 1306 // TODO: call special function for unknown oids 1307 // https://github.com/ydb-platform/ydb/issues/2706 1308 return fmt.Sprintf(`PgConst("%v", PgType(%v))`, v.val, v.t.OID) 1309 } 1310 1311 type setValue struct { 1312 t types.Type 1313 items []Value 1314 } 1315 1316 func (v *setValue) castTo(dst interface{}) error { 1317 return xerrors.WithStackTrace(fmt.Errorf( 1318 "%w '%+v' to '%T' destination", 1319 ErrCannotCast, v, dst, 1320 )) 1321 } 1322 1323 func (v *setValue) Yql() string { 1324 buffer := xstring.Buffer() 1325 defer buffer.Free() 1326 buffer.WriteByte('{') 1327 for i, item := range v.items { 1328 if i != 0 { 1329 buffer.WriteByte(',') 1330 } 1331 buffer.WriteString(item.Yql()) 1332 } 1333 buffer.WriteByte('}') 1334 1335 return buffer.String() 1336 } 1337 1338 func (v *setValue) Type() types.Type { 1339 return v.t 1340 } 1341 1342 func (v *setValue) toYDB(a *allocator.Allocator) *Ydb.Value { 1343 vvv := a.Value() 1344 1345 for _, vv := range v.items { 1346 pair := a.Pair() 1347 1348 pair.Key = vv.toYDB(a) 1349 pair.Payload = _voidValue 1350 1351 vvv.Pairs = append(vvv.GetPairs(), pair) 1352 } 1353 1354 return vvv 1355 } 1356 1357 func PgValue(oid uint32, val string) pgValue { 1358 return pgValue{ 1359 t: types.PgType{ 1360 OID: oid, 1361 }, 1362 val: val, 1363 } 1364 } 1365 1366 func SetValue(items ...Value) *setValue { 1367 sort.Slice(items, func(i, j int) bool { 1368 return items[i].Yql() < items[j].Yql() 1369 }) 1370 1371 var t types.Type 1372 switch { 1373 case len(items) > 0: 1374 t = types.NewSet(items[0].Type()) 1375 default: 1376 t = types.EmptySet() 1377 } 1378 1379 return &setValue{ 1380 t: t, 1381 items: items, 1382 } 1383 } 1384 1385 func NullValue(t types.Type) *optionalValue { 1386 return &optionalValue{ 1387 innerType: types.NewOptional(t), 1388 value: nil, 1389 } 1390 } 1391 1392 type optionalValue struct { 1393 innerType types.Type 1394 value Value 1395 } 1396 1397 func (v *optionalValue) castTo(dst interface{}) error { 1398 ptr := reflect.ValueOf(dst) 1399 if ptr.Kind() != reflect.Pointer { 1400 return xerrors.WithStackTrace(fmt.Errorf("%w: '%s'", errDestinationTypeIsNotAPointer, ptr.Kind().String())) 1401 } 1402 1403 inner := reflect.Indirect(ptr) 1404 1405 if inner.Kind() != reflect.Pointer { 1406 if v.value == nil { 1407 if ptr.CanAddr() { 1408 ptr.SetZero() 1409 } 1410 1411 return nil 1412 } 1413 1414 if err := v.value.castTo(ptr.Interface()); err != nil { 1415 return xerrors.WithStackTrace(err) 1416 } 1417 1418 return nil 1419 } 1420 1421 if v.value == nil { 1422 inner.SetZero() 1423 1424 return nil 1425 } 1426 1427 inner.Set(reflect.New(inner.Type().Elem())) 1428 1429 if err := v.value.castTo(inner.Interface()); err != nil { 1430 return xerrors.WithStackTrace(err) 1431 } 1432 1433 return nil 1434 } 1435 1436 func (v *optionalValue) Yql() string { 1437 if v.value == nil { 1438 return fmt.Sprintf("Nothing(%s)", v.Type().Yql()) 1439 } 1440 1441 return fmt.Sprintf("Just(%s)", v.value.Yql()) 1442 } 1443 1444 func (v *optionalValue) Type() types.Type { 1445 return v.innerType 1446 } 1447 1448 func (v *optionalValue) toYDB(a *allocator.Allocator) *Ydb.Value { 1449 vv := a.Value() 1450 if _, opt := v.value.(*optionalValue); opt { 1451 vvv := a.Nested() 1452 vvv.NestedValue = v.value.toYDB(a) 1453 vv.Value = vvv 1454 } else { 1455 if v.value != nil { 1456 vv = v.value.toYDB(a) 1457 } else { 1458 vv.Value = a.NullFlag() 1459 } 1460 } 1461 1462 return vv 1463 } 1464 1465 func OptionalValue(v Value) *optionalValue { 1466 return &optionalValue{ 1467 innerType: types.NewOptional(v.Type()), 1468 value: v, 1469 } 1470 } 1471 1472 type ( 1473 StructValueField struct { 1474 Name string 1475 V Value 1476 } 1477 structValue struct { 1478 t types.Type 1479 fields []StructValueField 1480 } 1481 ) 1482 1483 func (v *structValue) StructFields() map[string]Value { 1484 fields := make(map[string]Value, len(v.fields)) 1485 for i := range v.fields { 1486 fields[v.fields[i].Name] = v.fields[i].V 1487 } 1488 1489 return fields 1490 } 1491 1492 func (v *structValue) castTo(dst interface{}) error { 1493 return xerrors.WithStackTrace(fmt.Errorf( 1494 "%w '%+v' to '%T' destination", 1495 ErrCannotCast, v, dst, 1496 )) 1497 } 1498 1499 func (v *structValue) Yql() string { 1500 buffer := xstring.Buffer() 1501 defer buffer.Free() 1502 buffer.WriteString("<|") 1503 for i := range v.fields { 1504 if i != 0 { 1505 buffer.WriteByte(',') 1506 } 1507 buffer.WriteString("`" + v.fields[i].Name + "`:") 1508 buffer.WriteString(v.fields[i].V.Yql()) 1509 } 1510 buffer.WriteString("|>") 1511 1512 return buffer.String() 1513 } 1514 1515 func (v *structValue) Type() types.Type { 1516 return v.t 1517 } 1518 1519 func (v *structValue) toYDB(a *allocator.Allocator) *Ydb.Value { 1520 vvv := a.Value() 1521 1522 for i := range v.fields { 1523 vvv.Items = append(vvv.GetItems(), v.fields[i].V.toYDB(a)) 1524 } 1525 1526 return vvv 1527 } 1528 1529 func StructValue(fields ...StructValueField) *structValue { 1530 sort.Slice(fields, func(i, j int) bool { 1531 return fields[i].Name < fields[j].Name 1532 }) 1533 structFields := make([]types.StructField, 0, len(fields)) 1534 for i := range fields { 1535 structFields = append(structFields, types.StructField{ 1536 Name: fields[i].Name, 1537 T: fields[i].V.Type(), 1538 }) 1539 } 1540 1541 return &structValue{ 1542 t: types.NewStruct(structFields...), 1543 fields: fields, 1544 } 1545 } 1546 1547 type timestampValue uint64 1548 1549 func (v timestampValue) castTo(dst interface{}) error { 1550 switch vv := dst.(type) { 1551 case *time.Time: 1552 *vv = TimestampToTime(uint64(v)) 1553 1554 return nil 1555 case *uint64: 1556 *vv = uint64(v) 1557 1558 return nil 1559 default: 1560 return xerrors.WithStackTrace(fmt.Errorf( 1561 "%w '%s(%+v)' to '%T' destination", 1562 ErrCannotCast, v.Type().Yql(), v, vv, 1563 )) 1564 } 1565 } 1566 1567 func (v timestampValue) Yql() string { 1568 return fmt.Sprintf("%s(%q)", v.Type().Yql(), TimestampToTime(uint64(v)).UTC().Format(LayoutTimestamp)) 1569 } 1570 1571 func (timestampValue) Type() types.Type { 1572 return types.Timestamp 1573 } 1574 1575 func (v timestampValue) toYDB(a *allocator.Allocator) *Ydb.Value { 1576 vv := a.Uint64() 1577 vv.Uint64Value = uint64(v) 1578 1579 vvv := a.Value() 1580 vvv.Value = vv 1581 1582 return vvv 1583 } 1584 1585 // TimestampValue makes ydb timestamp value by given microseconds since Epoch 1586 func TimestampValue(v uint64) timestampValue { 1587 return timestampValue(v) 1588 } 1589 1590 func TimestampValueFromTime(t time.Time) timestampValue { 1591 return timestampValue(t.Sub(epoch) / time.Microsecond) 1592 } 1593 1594 type tupleValue struct { 1595 t types.Type 1596 items []Value 1597 } 1598 1599 func (v *tupleValue) TupleItems() []Value { 1600 return v.items 1601 } 1602 1603 func (v *tupleValue) castTo(dst interface{}) error { 1604 if len(v.items) == 1 { 1605 return v.items[0].castTo(dst) 1606 } 1607 1608 return xerrors.WithStackTrace(fmt.Errorf( 1609 "%w '%+v' to '%T' destination", 1610 ErrCannotCast, v, dst, 1611 )) 1612 } 1613 1614 func (v *tupleValue) Yql() string { 1615 buffer := xstring.Buffer() 1616 defer buffer.Free() 1617 buffer.WriteByte('(') 1618 for i, item := range v.items { 1619 if i != 0 { 1620 buffer.WriteByte(',') 1621 } 1622 buffer.WriteString(item.Yql()) 1623 } 1624 buffer.WriteByte(')') 1625 1626 return buffer.String() 1627 } 1628 1629 func (v *tupleValue) Type() types.Type { 1630 return v.t 1631 } 1632 1633 func (v *tupleValue) toYDB(a *allocator.Allocator) *Ydb.Value { 1634 var items []Value 1635 if v != nil { 1636 items = v.items 1637 } 1638 vvv := a.Value() 1639 1640 for _, vv := range items { 1641 vvv.Items = append(vvv.GetItems(), vv.toYDB(a)) 1642 } 1643 1644 return vvv 1645 } 1646 1647 func TupleValue(values ...Value) *tupleValue { 1648 tupleItems := make([]types.Type, 0, len(values)) 1649 for _, v := range values { 1650 tupleItems = append(tupleItems, v.Type()) 1651 } 1652 1653 return &tupleValue{ 1654 t: types.NewTuple(tupleItems...), 1655 items: values, 1656 } 1657 } 1658 1659 type tzDateValue string 1660 1661 func (v tzDateValue) castTo(dst interface{}) error { 1662 switch vv := dst.(type) { 1663 case *string: 1664 *vv = string(v) 1665 1666 return nil 1667 case *[]byte: 1668 *vv = xstring.ToBytes(string(v)) 1669 1670 return nil 1671 default: 1672 return xerrors.WithStackTrace(fmt.Errorf( 1673 "%w '%s(%+v)' to '%T' destination", 1674 ErrCannotCast, v.Type().Yql(), v, vv, 1675 )) 1676 } 1677 } 1678 1679 func (v tzDateValue) Yql() string { 1680 return fmt.Sprintf("%s(%q)", v.Type().Yql(), string(v)) 1681 } 1682 1683 func (tzDateValue) Type() types.Type { 1684 return types.TzDate 1685 } 1686 1687 func (v tzDateValue) toYDB(a *allocator.Allocator) *Ydb.Value { 1688 vv := a.Text() 1689 vv.TextValue = string(v) 1690 1691 vvv := a.Value() 1692 vvv.Value = vv 1693 1694 return vvv 1695 } 1696 1697 func TzDateValue(v string) tzDateValue { 1698 return tzDateValue(v) 1699 } 1700 1701 func TzDateValueFromTime(t time.Time) tzDateValue { 1702 return tzDateValue(t.Format(LayoutDate)) 1703 } 1704 1705 type tzDatetimeValue string 1706 1707 func (v tzDatetimeValue) castTo(dst interface{}) error { 1708 switch vv := dst.(type) { 1709 case *string: 1710 *vv = string(v) 1711 1712 return nil 1713 case *[]byte: 1714 *vv = xstring.ToBytes(string(v)) 1715 1716 return nil 1717 default: 1718 return xerrors.WithStackTrace(fmt.Errorf( 1719 "%w '%s(%+v)' to '%T' destination", 1720 ErrCannotCast, v.Type().Yql(), v, vv, 1721 )) 1722 } 1723 } 1724 1725 func (v tzDatetimeValue) Yql() string { 1726 return fmt.Sprintf("%s(%q)", v.Type().Yql(), string(v)) 1727 } 1728 1729 func (tzDatetimeValue) Type() types.Type { 1730 return types.TzDatetime 1731 } 1732 1733 func (v tzDatetimeValue) toYDB(a *allocator.Allocator) *Ydb.Value { 1734 vv := a.Text() 1735 vv.TextValue = string(v) 1736 1737 vvv := a.Value() 1738 vvv.Value = vv 1739 1740 return vvv 1741 } 1742 1743 func TzDatetimeValue(v string) tzDatetimeValue { 1744 return tzDatetimeValue(v) 1745 } 1746 1747 func TzDatetimeValueFromTime(t time.Time) tzDatetimeValue { 1748 return tzDatetimeValue(t.Format(LayoutDatetime)) 1749 } 1750 1751 type tzTimestampValue string 1752 1753 func (v tzTimestampValue) castTo(dst interface{}) error { 1754 switch vv := dst.(type) { 1755 case *time.Time: 1756 t, err := TzTimestampToTime(string(v)) 1757 if err != nil { 1758 return err 1759 } 1760 *vv = t 1761 1762 return nil 1763 case *string: 1764 *vv = string(v) 1765 1766 return nil 1767 case *[]byte: 1768 *vv = xstring.ToBytes(string(v)) 1769 1770 return nil 1771 default: 1772 return xerrors.WithStackTrace(fmt.Errorf( 1773 "%w '%s(%+v)' to '%T' destination", 1774 ErrCannotCast, v.Type().Yql(), v, vv, 1775 )) 1776 } 1777 } 1778 1779 func (v tzTimestampValue) Yql() string { 1780 return fmt.Sprintf("%s(%q)", v.Type().Yql(), string(v)) 1781 } 1782 1783 func (tzTimestampValue) Type() types.Type { 1784 return types.TzTimestamp 1785 } 1786 1787 func (v tzTimestampValue) toYDB(a *allocator.Allocator) *Ydb.Value { 1788 vv := a.Text() 1789 vv.TextValue = string(v) 1790 1791 vvv := a.Value() 1792 vvv.Value = vv 1793 1794 return vvv 1795 } 1796 1797 func TzTimestampValue(v string) tzTimestampValue { 1798 return tzTimestampValue(v) 1799 } 1800 1801 func TzTimestampValueFromTime(t time.Time) tzTimestampValue { 1802 return tzTimestampValue(t.Format(LayoutTimestamp)) 1803 } 1804 1805 type uint8Value uint8 1806 1807 func (v uint8Value) castTo(dst interface{}) error { 1808 switch vv := dst.(type) { 1809 case *string: 1810 *vv = strconv.FormatInt(int64(v), 10) 1811 1812 return nil 1813 case *[]byte: 1814 *vv = xstring.ToBytes(strconv.FormatInt(int64(v), 10)) 1815 1816 return nil 1817 case *uint64: 1818 *vv = uint64(v) 1819 1820 return nil 1821 case *int64: 1822 *vv = int64(v) 1823 1824 return nil 1825 case *uint32: 1826 *vv = uint32(v) 1827 1828 return nil 1829 case *int32: 1830 *vv = int32(v) 1831 1832 return nil 1833 case *uint16: 1834 *vv = uint16(v) 1835 1836 return nil 1837 case *int16: 1838 *vv = int16(v) 1839 1840 return nil 1841 case *uint8: 1842 *vv = uint8(v) 1843 1844 return nil 1845 case *float64: 1846 *vv = float64(v) 1847 1848 return nil 1849 case *float32: 1850 *vv = float32(v) 1851 1852 return nil 1853 default: 1854 return xerrors.WithStackTrace(fmt.Errorf( 1855 "%w '%s(%+v)' to '%T' destination", 1856 ErrCannotCast, v.Type().Yql(), v, vv, 1857 )) 1858 } 1859 } 1860 1861 func (v uint8Value) Yql() string { 1862 return strconv.FormatUint(uint64(v), 10) + "ut" 1863 } 1864 1865 func (uint8Value) Type() types.Type { 1866 return types.Uint8 1867 } 1868 1869 func (v uint8Value) toYDB(a *allocator.Allocator) *Ydb.Value { 1870 vv := a.Uint32() 1871 vv.Uint32Value = uint32(v) 1872 1873 vvv := a.Value() 1874 vvv.Value = vv 1875 1876 return vvv 1877 } 1878 1879 func Uint8Value(v uint8) uint8Value { 1880 return uint8Value(v) 1881 } 1882 1883 type uint16Value uint16 1884 1885 func (v uint16Value) castTo(dst interface{}) error { 1886 switch vv := dst.(type) { 1887 case *string: 1888 *vv = strconv.FormatInt(int64(v), 10) 1889 1890 return nil 1891 case *[]byte: 1892 *vv = xstring.ToBytes(strconv.FormatInt(int64(v), 10)) 1893 1894 return nil 1895 case *uint64: 1896 *vv = uint64(v) 1897 1898 return nil 1899 case *int64: 1900 *vv = int64(v) 1901 1902 return nil 1903 case *uint32: 1904 *vv = uint32(v) 1905 1906 return nil 1907 case *int32: 1908 *vv = int32(v) 1909 1910 return nil 1911 case *uint16: 1912 *vv = uint16(v) 1913 1914 return nil 1915 case *float32: 1916 *vv = float32(v) 1917 1918 return nil 1919 case *float64: 1920 *vv = float64(v) 1921 1922 return nil 1923 default: 1924 return xerrors.WithStackTrace(fmt.Errorf( 1925 "%w '%s(%+v)' to '%T' destination", 1926 ErrCannotCast, v.Type().Yql(), v, vv, 1927 )) 1928 } 1929 } 1930 1931 func (v uint16Value) Yql() string { 1932 return strconv.FormatUint(uint64(v), 10) + "us" 1933 } 1934 1935 func (uint16Value) Type() types.Type { 1936 return types.Uint16 1937 } 1938 1939 func (v uint16Value) toYDB(a *allocator.Allocator) *Ydb.Value { 1940 vv := a.Uint32() 1941 vv.Uint32Value = uint32(v) 1942 1943 vvv := a.Value() 1944 vvv.Value = vv 1945 1946 return vvv 1947 } 1948 1949 func Uint16Value(v uint16) uint16Value { 1950 return uint16Value(v) 1951 } 1952 1953 type uint32Value uint32 1954 1955 func (v uint32Value) castTo(dst interface{}) error { 1956 switch vv := dst.(type) { 1957 case *string: 1958 *vv = strconv.FormatInt(int64(v), 10) 1959 1960 return nil 1961 case *[]byte: 1962 *vv = xstring.ToBytes(strconv.FormatInt(int64(v), 10)) 1963 1964 return nil 1965 case *uint64: 1966 *vv = uint64(v) 1967 1968 return nil 1969 case *int64: 1970 *vv = int64(v) 1971 1972 return nil 1973 case *uint32: 1974 *vv = uint32(v) 1975 1976 return nil 1977 case *float64: 1978 *vv = float64(v) 1979 1980 return nil 1981 default: 1982 return xerrors.WithStackTrace(fmt.Errorf( 1983 "%w '%s(%+v)' to '%T' destination", 1984 ErrCannotCast, v.Type().Yql(), v, vv, 1985 )) 1986 } 1987 } 1988 1989 func (v uint32Value) Yql() string { 1990 return strconv.FormatUint(uint64(v), 10) + "u" 1991 } 1992 1993 func (uint32Value) Type() types.Type { 1994 return types.Uint32 1995 } 1996 1997 func (v uint32Value) toYDB(a *allocator.Allocator) *Ydb.Value { 1998 vv := a.Uint32() 1999 vv.Uint32Value = uint32(v) 2000 2001 vvv := a.Value() 2002 vvv.Value = vv 2003 2004 return vvv 2005 } 2006 2007 func Uint32Value(v uint32) uint32Value { 2008 return uint32Value(v) 2009 } 2010 2011 type uint64Value uint64 2012 2013 func (v uint64Value) castTo(dst interface{}) error { 2014 switch vv := dst.(type) { 2015 case *string: 2016 *vv = strconv.FormatInt(int64(v), 10) 2017 2018 return nil 2019 case *[]byte: 2020 *vv = xstring.ToBytes(strconv.FormatInt(int64(v), 10)) 2021 2022 return nil 2023 case *uint64: 2024 *vv = uint64(v) 2025 2026 return nil 2027 default: 2028 return xerrors.WithStackTrace(fmt.Errorf( 2029 "%w '%s(%+v)' to '%T' destination", 2030 ErrCannotCast, v.Type().Yql(), v, vv, 2031 )) 2032 } 2033 } 2034 2035 func (v uint64Value) Yql() string { 2036 return strconv.FormatUint(uint64(v), 10) + "ul" 2037 } 2038 2039 func (uint64Value) Type() types.Type { 2040 return types.Uint64 2041 } 2042 2043 func (v uint64Value) toYDB(a *allocator.Allocator) *Ydb.Value { 2044 vv := a.Uint64() 2045 vv.Uint64Value = uint64(v) 2046 2047 vvv := a.Value() 2048 vvv.Value = vv 2049 2050 return vvv 2051 } 2052 2053 func Uint64Value(v uint64) uint64Value { 2054 return uint64Value(v) 2055 } 2056 2057 type textValue string 2058 2059 func (v textValue) castTo(dst interface{}) error { 2060 switch vv := dst.(type) { 2061 case *string: 2062 *vv = string(v) 2063 2064 return nil 2065 case *[]byte: 2066 *vv = xstring.ToBytes(string(v)) 2067 2068 return nil 2069 default: 2070 return xerrors.WithStackTrace(fmt.Errorf( 2071 "%w '%s(%q)' to '%T' destination", 2072 ErrCannotCast, v.Type().Yql(), v, vv, 2073 )) 2074 } 2075 } 2076 2077 func (v textValue) Yql() string { 2078 return fmt.Sprintf("%qu", string(v)) 2079 } 2080 2081 func (textValue) Type() types.Type { 2082 return types.Text 2083 } 2084 2085 func (v textValue) toYDB(a *allocator.Allocator) *Ydb.Value { 2086 vv := a.Text() 2087 vv.TextValue = string(v) 2088 2089 vvv := a.Value() 2090 vvv.Value = vv 2091 2092 return vvv 2093 } 2094 2095 func TextValue(v string) textValue { 2096 return textValue(v) 2097 } 2098 2099 type UUIDIssue1501FixedBytesWrapper struct { 2100 val [16]byte 2101 } 2102 2103 func NewUUIDIssue1501FixedBytesWrapper(val [16]byte) UUIDIssue1501FixedBytesWrapper { 2104 return UUIDIssue1501FixedBytesWrapper{val: val} 2105 } 2106 2107 // PublicRevertReorderForIssue1501 needs for fix uuid when it was good stored in DB, 2108 // but read as reordered. It may happen within migration period. 2109 func (w UUIDIssue1501FixedBytesWrapper) PublicRevertReorderForIssue1501() uuid.UUID { 2110 return uuid.UUID(uuidFixBytesOrder(w.val)) 2111 } 2112 2113 func (w UUIDIssue1501FixedBytesWrapper) AsBytesArray() [16]byte { 2114 return w.val 2115 } 2116 2117 func (w UUIDIssue1501FixedBytesWrapper) AsBytesSlice() []byte { 2118 return w.val[:] 2119 } 2120 2121 func (w UUIDIssue1501FixedBytesWrapper) AsBrokenString() string { 2122 return string(w.val[:]) 2123 } 2124 2125 type uuidValue struct { 2126 value uuid.UUID 2127 reproduceStorageBug bool 2128 } 2129 2130 func (v *uuidValue) castTo(dst interface{}) error { 2131 switch vv := dst.(type) { 2132 case *string: 2133 return ErrIssue1501BadUUID 2134 case *[]byte: 2135 return ErrIssue1501BadUUID 2136 case *[16]byte: 2137 return ErrIssue1501BadUUID 2138 case *UUIDIssue1501FixedBytesWrapper: 2139 *vv = NewUUIDIssue1501FixedBytesWrapper(uuidReorderBytesForReadWithBug(v.value)) 2140 2141 return nil 2142 case *uuid.UUID: 2143 *vv = v.value 2144 2145 return nil 2146 default: 2147 return xerrors.WithStackTrace(fmt.Errorf( 2148 "%w '%s(%+v)' to '%T' destination", 2149 ErrCannotCast, v.Type().Yql(), v, vv, 2150 )) 2151 } 2152 } 2153 2154 func (v *uuidValue) Yql() string { 2155 buffer := xstring.Buffer() 2156 defer buffer.Free() 2157 buffer.WriteString(v.Type().Yql()) 2158 buffer.WriteByte('(') 2159 buffer.WriteByte('"') 2160 buffer.WriteString(v.value.String()) 2161 buffer.WriteByte('"') 2162 buffer.WriteByte(')') 2163 2164 return buffer.String() 2165 } 2166 2167 func (*uuidValue) Type() types.Type { 2168 return types.UUID 2169 } 2170 2171 func (v *uuidValue) toYDB(a *allocator.Allocator) *Ydb.Value { 2172 if v.reproduceStorageBug { 2173 return v.toYDBWithBug(a) 2174 } 2175 2176 var low, high uint64 2177 if v != nil { 2178 low, high = UUIDToHiLoPair(v.value) 2179 } 2180 vv := a.Low128() 2181 vv.Low_128 = low 2182 2183 vvv := a.Value() 2184 vvv.High_128 = high 2185 vvv.Value = vv 2186 2187 return vvv 2188 } 2189 2190 func UUIDToHiLoPair(id uuid.UUID) (low, high uint64) { 2191 bytes := uuidDirectBytesToLe(id) 2192 low = binary.LittleEndian.Uint64(bytes[0:8]) 2193 high = binary.LittleEndian.Uint64(bytes[8:16]) 2194 2195 return low, high 2196 } 2197 2198 func (v *uuidValue) toYDBWithBug(a *allocator.Allocator) *Ydb.Value { 2199 var bytes [16]byte 2200 if v != nil { 2201 bytes = v.value 2202 } 2203 vv := a.Low128() 2204 vv.Low_128 = binary.BigEndian.Uint64(bytes[8:16]) 2205 2206 vvv := a.Value() 2207 vvv.High_128 = binary.BigEndian.Uint64(bytes[0:8]) 2208 vvv.Value = vv 2209 2210 return vvv 2211 } 2212 2213 func UUIDFromYDBPair(high uint64, low uint64) *uuidValue { 2214 var res uuid.UUID 2215 binary.LittleEndian.PutUint64(res[:], low) 2216 binary.LittleEndian.PutUint64(res[8:], high) 2217 res = uuidLeBytesToDirect(res) 2218 2219 return &uuidValue{value: res} 2220 } 2221 2222 func Uuid(val uuid.UUID) *uuidValue { //nolint:revive,stylecheck 2223 return &uuidValue{value: val} 2224 } 2225 2226 func UUIDWithIssue1501Value(v [16]byte) *uuidValue { 2227 return &uuidValue{value: v, reproduceStorageBug: true} 2228 } 2229 2230 func uuidDirectBytesToLe(direct [16]byte) [16]byte { 2231 // ordered as uuid bytes le in python 2232 // https://docs.python.org/3/library/uuid.html#uuid.UUID.bytes_le 2233 var le [16]byte 2234 le[0] = direct[3] 2235 le[1] = direct[2] 2236 le[2] = direct[1] 2237 le[3] = direct[0] 2238 le[4] = direct[5] 2239 le[5] = direct[4] 2240 le[6] = direct[7] 2241 le[7] = direct[6] 2242 le[8] = direct[8] 2243 le[9] = direct[9] 2244 le[10] = direct[10] 2245 le[11] = direct[11] 2246 le[12] = direct[12] 2247 le[13] = direct[13] 2248 le[14] = direct[14] 2249 le[15] = direct[15] 2250 2251 return le 2252 } 2253 2254 func uuidLeBytesToDirect(direct [16]byte) [16]byte { 2255 // ordered as uuid bytes le in python 2256 // https://docs.python.org/3/library/uuid.html#uuid.UUID.bytes_le 2257 var le [16]byte 2258 le[3] = direct[0] 2259 le[2] = direct[1] 2260 le[1] = direct[2] 2261 le[0] = direct[3] 2262 le[5] = direct[4] 2263 le[4] = direct[5] 2264 le[7] = direct[6] 2265 le[6] = direct[7] 2266 le[8] = direct[8] 2267 le[9] = direct[9] 2268 le[10] = direct[10] 2269 le[11] = direct[11] 2270 le[12] = direct[12] 2271 le[13] = direct[13] 2272 le[14] = direct[14] 2273 le[15] = direct[15] 2274 2275 return le 2276 } 2277 2278 func uuidReorderBytesForReadWithBug(val [16]byte) [16]byte { 2279 var res [16]byte 2280 res[0] = val[15] 2281 res[1] = val[14] 2282 res[2] = val[13] 2283 res[3] = val[12] 2284 res[4] = val[11] 2285 res[5] = val[10] 2286 res[6] = val[9] 2287 res[7] = val[8] 2288 res[8] = val[6] 2289 res[9] = val[7] 2290 res[10] = val[4] 2291 res[11] = val[5] 2292 res[12] = val[0] 2293 res[13] = val[1] 2294 res[14] = val[2] 2295 res[15] = val[3] 2296 2297 return res 2298 } 2299 2300 // uuidFixBytesOrder is reverse for uuidReorderBytesForReadWithBug 2301 func uuidFixBytesOrder(val [16]byte) [16]byte { 2302 var res [16]byte 2303 res[0] = val[12] 2304 res[1] = val[13] 2305 res[2] = val[14] 2306 res[3] = val[15] 2307 res[4] = val[10] 2308 res[5] = val[11] 2309 res[6] = val[8] 2310 res[7] = val[9] 2311 res[8] = val[7] 2312 res[9] = val[6] 2313 res[10] = val[5] 2314 res[11] = val[4] 2315 res[12] = val[3] 2316 res[13] = val[2] 2317 res[14] = val[1] 2318 res[15] = val[0] 2319 2320 return res 2321 } 2322 2323 type variantValue struct { 2324 innerType types.Type 2325 value Value 2326 idx uint32 2327 } 2328 2329 func (v *variantValue) Variant() (name string, index uint32) { 2330 switch t := v.innerType.(type) { 2331 case *types.VariantStruct: 2332 return t.Field(int(v.idx)).Name, v.idx 2333 default: 2334 return "", v.idx 2335 } 2336 } 2337 2338 func (v *variantValue) Value() Value { 2339 return v.value 2340 } 2341 2342 func (v *variantValue) castTo(dst interface{}) error { 2343 return v.value.castTo(dst) 2344 } 2345 2346 func (v *variantValue) Yql() string { 2347 buffer := xstring.Buffer() 2348 defer buffer.Free() 2349 buffer.WriteString("Variant(") 2350 buffer.WriteString(v.value.Yql()) 2351 buffer.WriteByte(',') 2352 switch t := v.innerType.(type) { 2353 case *types.VariantStruct: 2354 fmt.Fprintf(buffer, "%q", t.Field(int(v.idx)).Name) 2355 case *types.VariantTuple: 2356 fmt.Fprint(buffer, "\""+strconv.FormatUint(uint64(v.idx), 10)+"\"") 2357 } 2358 buffer.WriteByte(',') 2359 buffer.WriteString(v.Type().Yql()) 2360 buffer.WriteByte(')') 2361 2362 return buffer.String() 2363 } 2364 2365 func (v *variantValue) Type() types.Type { 2366 return v.innerType 2367 } 2368 2369 func (v *variantValue) toYDB(a *allocator.Allocator) *Ydb.Value { 2370 vvv := a.Value() 2371 2372 nested := a.Nested() 2373 nested.NestedValue = v.value.toYDB(a) 2374 2375 vvv.Value = nested 2376 vvv.VariantIndex = v.idx 2377 2378 return vvv 2379 } 2380 2381 func VariantValueTuple(v Value, idx uint32, t types.Type) *variantValue { 2382 if tt, has := t.(*types.Tuple); has { 2383 t = types.NewVariantTuple(tt.InnerTypes()...) 2384 } 2385 2386 return &variantValue{ 2387 innerType: t, 2388 value: v, 2389 idx: idx, 2390 } 2391 } 2392 2393 func VariantValueStruct(v Value, name string, t types.Type) *variantValue { 2394 var idx int 2395 switch tt := t.(type) { 2396 case *types.Struct: 2397 fields := tt.Fields() 2398 sort.Slice(fields, func(i, j int) bool { 2399 return fields[i].Name < fields[j].Name 2400 }) 2401 idx = sort.Search(len(fields), func(i int) bool { 2402 return fields[i].Name >= name 2403 }) 2404 t = types.NewVariantStruct(fields...) 2405 case *types.VariantStruct: 2406 fields := tt.Fields() 2407 sort.Slice(fields, func(i, j int) bool { 2408 return fields[i].Name < fields[j].Name 2409 }) 2410 idx = sort.Search(len(fields), func(i int) bool { 2411 return fields[i].Name >= name 2412 }) 2413 } 2414 2415 return &variantValue{ 2416 innerType: t, 2417 value: v, 2418 idx: uint32(idx), 2419 } 2420 } 2421 2422 type voidValue struct{} 2423 2424 func (v voidValue) castTo(dst interface{}) error { 2425 return xerrors.WithStackTrace(fmt.Errorf( 2426 "%w '%s' to '%T' destination", 2427 ErrCannotCast, v.Type().Yql(), dst, 2428 )) 2429 } 2430 2431 func (v voidValue) Yql() string { 2432 return v.Type().Yql() + "()" 2433 } 2434 2435 var ( 2436 _voidValueType = types.Void{} 2437 _voidValue = &Ydb.Value{ 2438 Value: new(Ydb.Value_NullFlagValue), 2439 } 2440 ) 2441 2442 func (voidValue) Type() types.Type { 2443 return _voidValueType 2444 } 2445 2446 func (voidValue) toYDB(*allocator.Allocator) *Ydb.Value { 2447 return _voidValue 2448 } 2449 2450 func VoidValue() voidValue { 2451 return voidValue{} 2452 } 2453 2454 type ysonValue []byte 2455 2456 func (v ysonValue) castTo(dst interface{}) error { 2457 switch vv := dst.(type) { 2458 case *string: 2459 *vv = xstring.FromBytes(v) 2460 2461 return nil 2462 case *[]byte: 2463 *vv = v 2464 2465 return nil 2466 default: 2467 return xerrors.WithStackTrace(fmt.Errorf( 2468 "%w '%s(%+v)' to '%T' destination", 2469 ErrCannotCast, v.Type().Yql(), v, vv, 2470 )) 2471 } 2472 } 2473 2474 func (v ysonValue) Yql() string { 2475 return fmt.Sprintf("%s(%q)", v.Type().Yql(), string(v)) 2476 } 2477 2478 func (ysonValue) Type() types.Type { 2479 return types.YSON 2480 } 2481 2482 func (v ysonValue) toYDB(a *allocator.Allocator) *Ydb.Value { 2483 vv := a.Bytes() 2484 if v != nil { 2485 vv.BytesValue = v 2486 } 2487 2488 vvv := a.Value() 2489 vvv.Value = vv 2490 2491 return vvv 2492 } 2493 2494 func YSONValue(v []byte) ysonValue { 2495 return v 2496 } 2497 2498 //nolint:funlen 2499 func zeroPrimitiveValue(t types.Primitive) Value { 2500 switch t { 2501 case types.Bool: 2502 return BoolValue(false) 2503 2504 case types.Int8: 2505 return Int8Value(0) 2506 2507 case types.Uint8: 2508 return Uint8Value(0) 2509 2510 case types.Int16: 2511 return Int16Value(0) 2512 2513 case types.Uint16: 2514 return Uint16Value(0) 2515 2516 case types.Int32: 2517 return Int32Value(0) 2518 2519 case types.Uint32: 2520 return Uint32Value(0) 2521 2522 case types.Int64: 2523 return Int64Value(0) 2524 2525 case types.Uint64: 2526 return Uint64Value(0) 2527 2528 case types.Float: 2529 return FloatValue(0) 2530 2531 case types.Double: 2532 return DoubleValue(0) 2533 2534 case types.Date: 2535 return DateValue(0) 2536 2537 case types.Datetime: 2538 return DatetimeValue(0) 2539 2540 case types.Timestamp: 2541 return TimestampValue(0) 2542 2543 case types.Interval: 2544 return IntervalValue(0) 2545 2546 case types.Text: 2547 return TextValue("") 2548 2549 case types.YSON: 2550 return YSONValue([]byte("")) 2551 2552 case types.JSON: 2553 return JSONValue("") 2554 2555 case types.JSONDocument: 2556 return JSONDocumentValue("") 2557 2558 case types.DyNumber: 2559 return DyNumberValue("") 2560 2561 case types.TzDate: 2562 return TzDateValue("") 2563 2564 case types.TzDatetime: 2565 return TzDatetimeValue("") 2566 2567 case types.TzTimestamp: 2568 return TzTimestampValue("") 2569 2570 case types.Bytes: 2571 return BytesValue([]byte{}) 2572 2573 case types.UUID: 2574 return UUIDWithIssue1501Value([16]byte{}) 2575 2576 default: 2577 panic(fmt.Sprintf("uncovered primitive type '%T'", t)) 2578 } 2579 } 2580 2581 func ZeroValue(t types.Type) Value { 2582 switch t := t.(type) { 2583 case types.Primitive: 2584 return zeroPrimitiveValue(t) 2585 2586 case types.Optional: 2587 return NullValue(t.InnerType()) 2588 2589 case *types.Void: 2590 return VoidValue() 2591 2592 case *types.List, *types.EmptyList: 2593 return &listValue{ 2594 t: t, 2595 } 2596 case *types.Set: 2597 return &setValue{ 2598 t: t, 2599 } 2600 case *types.Dict: 2601 return &dictValue{ 2602 t: t.ValueType(), 2603 } 2604 case *types.EmptyDict: 2605 return &dictValue{ 2606 t: t, 2607 } 2608 case *types.Tuple: 2609 return TupleValue(func() []Value { 2610 innerTypes := t.InnerTypes() 2611 values := make([]Value, len(innerTypes)) 2612 for i, tt := range innerTypes { 2613 values[i] = ZeroValue(tt) 2614 } 2615 2616 return values 2617 }()...) 2618 case *types.Struct: 2619 return StructValue(func() []StructValueField { 2620 fields := t.Fields() 2621 values := make([]StructValueField, len(fields)) 2622 for i := range fields { 2623 values[i] = StructValueField{ 2624 Name: fields[i].Name, 2625 V: ZeroValue(fields[i].T), 2626 } 2627 } 2628 2629 return values 2630 }()...) 2631 case *types.Decimal: 2632 return DecimalValue([16]byte{}, decimalPrecision, decimalScale) 2633 2634 default: 2635 panic(fmt.Sprintf("type '%T' have not a zero value", t)) 2636 } 2637 } 2638 2639 type bytesValue []byte 2640 2641 func (v bytesValue) castTo(dst interface{}) error { 2642 switch vv := dst.(type) { 2643 case *string: 2644 *vv = xstring.FromBytes(v) 2645 2646 return nil 2647 case *[]byte: 2648 *vv = v 2649 2650 return nil 2651 default: 2652 return xerrors.WithStackTrace(fmt.Errorf( 2653 "%w '%s(%+v)' to '%T' destination", 2654 ErrCannotCast, v.Type().Yql(), v, vv, 2655 )) 2656 } 2657 } 2658 2659 func (v bytesValue) Yql() string { 2660 return fmt.Sprintf("%q", string(v)) 2661 } 2662 2663 func (bytesValue) Type() types.Type { 2664 return types.Bytes 2665 } 2666 2667 func (v bytesValue) toYDB(a *allocator.Allocator) *Ydb.Value { 2668 vv := a.Bytes() 2669 2670 vv.BytesValue = v 2671 2672 vvv := a.Value() 2673 vvv.Value = vv 2674 2675 return vvv 2676 } 2677 2678 func BytesValue(v []byte) bytesValue { 2679 return v 2680 }