diff --git a/be/src/runtime/type_limit.h b/be/src/runtime/type_limit.h index fcd44d5d3350392..d23a9f1921656c4 100644 --- a/be/src/runtime/type_limit.h +++ b/be/src/runtime/type_limit.h @@ -71,8 +71,8 @@ struct type_limit { } static vectorized::Decimal128 min() { return -max(); } }; -static Int256 MAX_DECIMAL256_INT({999999999999999999ll, 999999999999999999ll, 999999999999999999ll, - 999999999999999999ll, 9999ll}); +static Int256 MAX_DECIMAL256_INT({18446744073709551615ul, 8607968719199866879ul, + 532749306367912313ul, 1593091911132452277ul}); template <> struct type_limit { static vectorized::Decimal256 max() { return vectorized::Decimal256(MAX_DECIMAL256_INT); } diff --git a/be/src/vec/core/decimal_comparison.h b/be/src/vec/core/decimal_comparison.h index 7ee6364c565f2f8..d7eb5cf9d19cb58 100644 --- a/be/src/vec/core/decimal_comparison.h +++ b/be/src/vec/core/decimal_comparison.h @@ -109,12 +109,16 @@ class DecimalComparison { } Shift shift; - if (scale_a < scale_b) + if (scale_a < scale_b) { shift.a = DataTypeDecimal(max_decimal_precision(), scale_b) - .get_scale_multiplier(scale_b - scale_a); - if (scale_a > scale_b) + .get_scale_multiplier(scale_b - scale_a) + .value; + } + if (scale_a > scale_b) { shift.b = DataTypeDecimal(max_decimal_precision(), scale_a) - .get_scale_multiplier(scale_a - scale_b); + .get_scale_multiplier(scale_a - scale_b) + .value; + } return apply_with_scale(a, b, shift); } diff --git a/be/src/vec/core/types.h b/be/src/vec/core/types.h index a0baae5b84b5e6c..1d7a597f6d493b1 100644 --- a/be/src/vec/core/types.h +++ b/be/src/vec/core/types.h @@ -415,7 +415,6 @@ struct Decimal { } } - // TODO: decimal256 static constexpr auto precision = std::is_same_v ? BeConsts::MAX_DECIMAL32_PRECISION @@ -661,8 +660,11 @@ struct Decimal { static constexpr auto precision = std::is_same_v ? BeConsts::MAX_DECIMAL32_PRECISION - : (std::is_same_v ? BeConsts::MAX_DECIMAL64_PRECISION - : BeConsts::MAX_DECIMAL128_PRECISION); + : (std::is_same_v + ? BeConsts::MAX_DECIMAL64_PRECISION + : (std::is_same_v + ? BeConsts::MAX_DECIMAL128_PRECISION + : BeConsts::MAX_DECIMAL256_PRECISION)); bool is_nagetive = value < 0; int max_result_length = precision + (scale > 0) // Add a space for decimal place + (scale == precision) // Add a space for leading 0 @@ -684,7 +686,9 @@ struct Decimal { frac_part = abs_value % decimal_scale_multiplier(scale); } if constexpr (std::is_same_v) { - std::string res {wide::to_string(whole_part)}; + std::string dec_str {wide::to_string(whole_part)}; + auto end = fmt::format_to(str.data() + pos, "{}", dec_str); + pos = end - str.data(); } else { auto end = fmt::format_to(str.data() + pos, "{}", whole_part); pos = end - str.data(); @@ -713,6 +717,9 @@ struct Decimal { const T& scale_multiplier) const { if (UNLIKELY(value == std::numeric_limits::min())) { if constexpr (std::is_same_v) { + std::string dec_str {wide::to_string(value)}; + auto end = fmt::format_to(dst, "{}", dec_str); + return end - dst; } else { auto end = fmt::format_to(dst, "{}", value); return end - dst; @@ -735,6 +742,9 @@ struct Decimal { frac_part = abs_value % scale_multiplier; } if constexpr (std::is_same_v) { + std::string dec_str {wide::to_string(whole_part)}; + auto end = fmt::format_to(dst + pos, "{}", dec_str); + pos = end - dst; } else { auto end = fmt::format_to(dst + pos, "{}", whole_part); pos = end - dst; @@ -759,6 +769,9 @@ struct Decimal { } if (frac_part) { if constexpr (std::is_same_v) { + std::string dec_str {wide::to_string(frac_part)}; + auto end = fmt::format_to(dst + pos, "{}", dec_str); + pos = end - dst; } else { auto end = fmt::format_to(&dst[pos], "{}", frac_part); pos = end - dst; diff --git a/be/src/vec/core/wide_integer.h b/be/src/vec/core/wide_integer.h index 8492d67d96b21a6..c13e0092d47c72f 100644 --- a/be/src/vec/core/wide_integer.h +++ b/be/src/vec/core/wide_integer.h @@ -68,8 +68,8 @@ class integer { template constexpr integer& operator=(const integer& rhs) noexcept; - // template - // constexpr integer& operator=(Arithmetic rhs) noexcept; + template + constexpr integer& operator=(Arithmetic rhs) noexcept; template constexpr integer& operator*=(const Arithmetic& rhs); diff --git a/be/src/vec/core/wide_integer_impl.h b/be/src/vec/core/wide_integer_impl.h index 381a5013ab29e8f..b3f1198d89ed50c 100644 --- a/be/src/vec/core/wide_integer_impl.h +++ b/be/src/vec/core/wide_integer_impl.h @@ -950,17 +950,17 @@ constexpr integer& integer::operator=( return *this; } -// template -// template -// constexpr integer& integer::operator=(T rhs) noexcept { -// if constexpr (IsTupleLike::value) -// _impl::wide_integer_from_tuple_like(*this, rhs); -// else if constexpr (std::is_same_v, CityHash_v1_0_2::uint128>) -// _impl::wide_integer_from_cityhash_uint128(*this, rhs); -// else -// _impl::wide_integer_from_builtin(*this, rhs); -// return *this; -// } +template +template +constexpr integer& integer::operator=(T rhs) noexcept { + if constexpr (IsTupleLike::value) + _impl::wide_integer_from_tuple_like(*this, rhs); + else if constexpr (std::is_same_v, CityHash_v1_0_2::uint128>) + _impl::wide_integer_from_cityhash_uint128(*this, rhs); + else + _impl::wide_integer_from_builtin(*this, rhs); + return *this; +} template template diff --git a/be/src/vec/data_types/data_type_decimal.h b/be/src/vec/data_types/data_type_decimal.h index 8706cc28635725a..0034655886309f5 100644 --- a/be/src/vec/data_types/data_type_decimal.h +++ b/be/src/vec/data_types/data_type_decimal.h @@ -604,19 +604,6 @@ typename T::NativeType max_decimal_value(UInt32 precision) { (UInt32)(max_decimal_precision() - precision)); } -/* -mnt/disk2/tengjianping/doris-master/be/src/util/string_parser.hpp:699:43: error: no matching function for call to 'min_decimal_value' - value = is_negative ? vectorized::min_decimal_value>( - ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -/mnt/disk2/tengjianping/doris-master/be/src/vec/data_types/data_type_decimal.cpp:164:32: note: in instantiation of function template specialization 'doris::StringParser::string_to_decimal>' requested here - res->value = StringParser::string_to_decimal::get_primitive_type()>( - ^ -/mnt/disk2/tengjianping/doris-master/be/src/vec/data_types/data_type_decimal.h:609:24: note: candidate template ignored: constraints not satisfied [with T = vectorized::Decimal>] -typename T::NativeType min_decimal_value(UInt32 precision) { - ^ -/mnt/disk2/tengjianping/doris-master/be/src/vec/data_types/data_type_decimal.h:608:14: note: because 'IsDecimalNumber > >' evaluated to false - requires IsDecimalNumber -*/ template requires IsDecimalNumber typename T::NativeType min_decimal_value(UInt32 precision) { diff --git a/be/test/vec/data_types/decimal_test.cpp b/be/test/vec/data_types/decimal_test.cpp new file mode 100644 index 000000000000000..74a65dd2b246ad2 --- /dev/null +++ b/be/test/vec/data_types/decimal_test.cpp @@ -0,0 +1,81 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#include +#include +#include + +#include + +#include "gtest/gtest_pred_impl.h" +#include "runtime/type_limit.h" +#include "vec/core/types.h" +namespace doris::vectorized { + +TEST(DecimalTest, Decimal256) { + // 9999999999999999999999999999999999999999999999999999999999999999999999999999 + Decimal256 dec1(type_limit::max()); + auto des_str = dec1.to_string(10); + EXPECT_EQ(des_str, + "999999999999999999999999999999999999999999999999999999999999999999.9999999999"); + des_str = dec1.to_string(0); + EXPECT_EQ(des_str, + "9999999999999999999999999999999999999999999999999999999999999999999999999999"); + des_str = dec1.to_string(76); + EXPECT_EQ(des_str, + "0.9999999999999999999999999999999999999999999999999999999999999999999999999999"); + + auto dec2 = type_limit::min(); + des_str = dec2.to_string(10); + EXPECT_EQ(des_str, + "-999999999999999999999999999999999999999999999999999999999999999999.9999999999"); + des_str = dec2.to_string(0); + EXPECT_EQ(des_str, + "-9999999999999999999999999999999999999999999999999999999999999999999999999999"); + des_str = dec2.to_string(76); + EXPECT_EQ(des_str, + "-0.9999999999999999999999999999999999999999999999999999999999999999999999999999"); + + // plus + Decimal256 dec3 = dec1 + dec2; + des_str = dec3.to_string(10); + EXPECT_EQ(des_str, "0.0000000000"); + des_str = dec3.to_string(0); + EXPECT_EQ(des_str, "0"); + des_str = dec3.to_string(76); + EXPECT_EQ(des_str, + "0.0000000000000000000000000000000000000000000000000000000000000000000000000000"); + + // minus + dec2 = type_limit::max(); + dec3 = dec1 - dec2; + des_str = dec3.to_string(10); + EXPECT_EQ(des_str, "0.0000000000"); + + // multiply + + // divide + dec1 = type_limit::max(); + dec2 = vectorized::Decimal256(10); + dec3 = dec1 / dec2; + des_str = dec3.to_string(1); + EXPECT_EQ(des_str, + "99999999999999999999999999999999999999999999999999999999999999999999999999.9"); + + // overflow +} +} // namespace doris::vectorized \ No newline at end of file