Skip to content

Commit 8c733ee

Browse files
authored
Merge pull request #732 from ydb-platform/decimal
* Added `table/types.ToDecimal()` converter from `table/types.Value` …
2 parents 8823220 + 00c7f21 commit 8c733ee

File tree

4 files changed

+88
-1
lines changed

4 files changed

+88
-1
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
* Added `table/types.ToDecimal()` converter from `table/types.Value` to `table/types.Decimal`
2+
13
## v3.46.1
2-
* Implemented `xcontext.With{Cancel,Timeout}` with stack record and switched all usages from standard `context.With{Cancel,Timeout}`
4+
* Implemented `internal/xcontext.With{Cancel,Timeout}` with stack record and switched all usages from standard `context.With{Cancel,Timeout}`
35

46
## v3.46.0
57
* Refactored package `log` for support typed fields in log messages

internal/value/value.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,11 +410,31 @@ func DatetimeValueFromTime(t time.Time) datetimeValue {
410410
return datetimeValue(t.Unix())
411411
}
412412

413+
var _ DecimalValuer = (*decimalValue)(nil)
414+
413415
type decimalValue struct {
414416
value [16]byte
415417
innerType *DecimalType
416418
}
417419

420+
func (v *decimalValue) Value() [16]byte {
421+
return v.value
422+
}
423+
424+
func (v *decimalValue) Precision() uint32 {
425+
return v.innerType.Precision
426+
}
427+
428+
func (v *decimalValue) Scale() uint32 {
429+
return v.innerType.Scale
430+
}
431+
432+
type DecimalValuer interface {
433+
Value() [16]byte
434+
Precision() uint32
435+
Scale() uint32
436+
}
437+
418438
func (v *decimalValue) castTo(dst interface{}) error {
419439
return xerrors.WithStackTrace(fmt.Errorf("cannot cast '%+v' to '%T' destination", v, dst))
420440
}

table/types/cast.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@ func CastTo(v Value, dst interface{}) error {
1818
return value.CastTo(v, dst)
1919
}
2020

21+
func ToDecimal(v Value) (*Decimal, error) {
22+
if valuer, isDecimalValuer := v.(value.DecimalValuer); isDecimalValuer {
23+
return &Decimal{
24+
Bytes: valuer.Value(),
25+
Precision: valuer.Precision(),
26+
Scale: valuer.Scale(),
27+
}, nil
28+
}
29+
return nil, xerrors.WithStackTrace(fmt.Errorf("value type '%s' is not decimal type", v.Type().Yql()))
30+
}
31+
2132
func TupleItems(v Value) ([]Value, error) {
2233
if vv, has := v.(interface {
2334
Items() []Value

table/types/cast_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package types
2+
3+
import (
4+
"math/big"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func TestToDecimal(t *testing.T) {
11+
for _, tt := range []struct {
12+
v Value
13+
d *Decimal
14+
err bool
15+
}{
16+
{
17+
v: DecimalValue(&Decimal{
18+
Bytes: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5},
19+
Precision: 22,
20+
Scale: 9,
21+
}),
22+
d: &Decimal{
23+
Bytes: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5},
24+
Precision: 22,
25+
Scale: 9,
26+
},
27+
err: false,
28+
},
29+
{
30+
v: DecimalValueFromBigInt(big.NewInt(123456789), 22, 9),
31+
d: &Decimal{
32+
Bytes: [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 91, 205, 21},
33+
Precision: 22,
34+
Scale: 9,
35+
},
36+
err: false,
37+
},
38+
{
39+
v: Uint64Value(0),
40+
d: nil,
41+
err: true,
42+
},
43+
} {
44+
t.Run("", func(t *testing.T) {
45+
d, err := ToDecimal(tt.v)
46+
if tt.err {
47+
require.Error(t, err)
48+
} else {
49+
require.NoError(t, err)
50+
require.Equal(t, tt.d, d)
51+
}
52+
})
53+
}
54+
}

0 commit comments

Comments
 (0)