@@ -20,6 +20,52 @@ namespace NKikimr::NMiniKQL {
20
20
21
21
namespace {
22
22
23
+ static constexpr std::array<std::pair<NYql::NDecimal::TInt128, NYql::NDecimal::TInt128>, NYql::NDecimal::MaxPrecision + 1 > DecimalBounds = {
24
+ NYql::NDecimal::GetBounds<0 >(),
25
+ NYql::NDecimal::GetBounds<1 >(),
26
+ NYql::NDecimal::GetBounds<2 >(),
27
+ NYql::NDecimal::GetBounds<3 >(),
28
+ NYql::NDecimal::GetBounds<4 >(),
29
+ NYql::NDecimal::GetBounds<5 >(),
30
+ NYql::NDecimal::GetBounds<6 >(),
31
+ NYql::NDecimal::GetBounds<7 >(),
32
+ NYql::NDecimal::GetBounds<8 >(),
33
+ NYql::NDecimal::GetBounds<9 >(),
34
+ NYql::NDecimal::GetBounds<10 >(),
35
+ NYql::NDecimal::GetBounds<11 >(),
36
+ NYql::NDecimal::GetBounds<12 >(),
37
+ NYql::NDecimal::GetBounds<13 >(),
38
+ NYql::NDecimal::GetBounds<14 >(),
39
+ NYql::NDecimal::GetBounds<15 >(),
40
+ NYql::NDecimal::GetBounds<16 >(),
41
+ NYql::NDecimal::GetBounds<17 >(),
42
+ NYql::NDecimal::GetBounds<18 >(),
43
+ NYql::NDecimal::GetBounds<19 >(),
44
+ NYql::NDecimal::GetBounds<20 >(),
45
+ NYql::NDecimal::GetBounds<21 >(),
46
+ NYql::NDecimal::GetBounds<22 >(),
47
+ NYql::NDecimal::GetBounds<23 >(),
48
+ NYql::NDecimal::GetBounds<24 >(),
49
+ NYql::NDecimal::GetBounds<25 >(),
50
+ NYql::NDecimal::GetBounds<26 >(),
51
+ NYql::NDecimal::GetBounds<27 >(),
52
+ NYql::NDecimal::GetBounds<28 >(),
53
+ NYql::NDecimal::GetBounds<29 >(),
54
+ NYql::NDecimal::GetBounds<30 >(),
55
+ NYql::NDecimal::GetBounds<31 >(),
56
+ NYql::NDecimal::GetBounds<32 >(),
57
+ NYql::NDecimal::GetBounds<33 >(),
58
+ NYql::NDecimal::GetBounds<34 >(),
59
+ NYql::NDecimal::GetBounds<35 >(),
60
+ };
61
+
62
+ bool IsNormal (ui8 precision, NYql::NDecimal::TInt128 v) {
63
+ if (precision >= DecimalBounds.size ())
64
+ return false ;
65
+ const auto & db = DecimalBounds[precision];
66
+ return v > db.first && v < db.second ;
67
+ }
68
+
23
69
void ExportTypeToProtoImpl (TType* type, NKikimrMiniKQL::TType& res, const TVector<ui32>* columnOrder = nullptr );
24
70
25
71
Y_FORCE_INLINE void HandleKindDataExport (const TType* type, const NUdf::TUnboxedValuePod& value, Ydb::Value& res) {
@@ -1628,7 +1674,22 @@ Y_FORCE_INLINE NUdf::TUnboxedValue KindDataImport(const TType* type, const Ydb::
1628
1674
return MakeString (value.bytes_value ());
1629
1675
}
1630
1676
case NUdf::TDataType<NUdf::TDecimal>::Id: {
1631
- return NUdf::TUnboxedValuePod (NYql::NDecimal::FromHalfs (value.low_128 (), value.high_128 ()));
1677
+ auto data = NYql::NDecimal::FromHalfs (value.low_128 (), value.high_128 ());
1678
+ auto dataType = static_cast <const TDataType*>(type);
1679
+ auto schemeType = dataType->GetSchemeType ();
1680
+ if (schemeType != NYql::NProto::TypeIds::Decimal) {
1681
+ throw yexception () << " Expected decimal type, but found " << schemeType;
1682
+ }
1683
+ auto decimalType = static_cast <const TDataDecimalType *>(dataType);
1684
+ auto params = decimalType->GetParams ();
1685
+ ui8 precision = params.first ;
1686
+ Y_ENSURE (precision <= NYql::NDecimal::MaxPrecision, " Unsupported decimal precision: " << precision);
1687
+ if (NYql::NDecimal::IsError (data)) {
1688
+ throw yexception () << " Invalid Decimal value" ;
1689
+ }
1690
+ Y_ENSURE (NYql::NDecimal::IsNormal (precision, data),
1691
+ " Invalid Decimal value out of the range for specified precision: " << precision);
1692
+ return NUdf::TUnboxedValuePod (data);
1632
1693
}
1633
1694
default : {
1634
1695
throw yexception () << " Unsupported data type: " << dataType->GetSchemeType ();
0 commit comments