From 108c2022d9102c187bf153210551d1615e877419 Mon Sep 17 00:00:00 2001 From: Maksim Kita Date: Sat, 8 May 2021 17:01:30 +0300 Subject: [PATCH] Function arrayDifference decimal math overflow --- src/Functions/array/arrayDifference.cpp | 19 ++++++++++++++++++- ...ifference_decimal_overflow_ubsan.reference | 0 ...rray_difference_decimal_overflow_ubsan.sql | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 tests/queries/0_stateless/01851_array_difference_decimal_overflow_ubsan.reference create mode 100644 tests/queries/0_stateless/01851_array_difference_decimal_overflow_ubsan.sql diff --git a/src/Functions/array/arrayDifference.cpp b/src/Functions/array/arrayDifference.cpp index b4b30079a4e..45ff117bfdf 100644 --- a/src/Functions/array/arrayDifference.cpp +++ b/src/Functions/array/arrayDifference.cpp @@ -13,6 +13,7 @@ namespace ErrorCodes { extern const int ILLEGAL_TYPE_OF_ARGUMENT; extern const int ILLEGAL_COLUMN; + extern const int DECIMAL_OVERFLOW; } /** arrayDifference() - returns an array with the difference between all pairs of neighboring elements. @@ -63,7 +64,23 @@ struct ArrayDifferenceImpl else { Element curr = src[pos]; - dst[pos] = curr - prev; + + if constexpr (IsDecimalNumber) + { + using ResultNativeType = typename Result::NativeType; + + ResultNativeType result_value; + bool overflow = common::subOverflow(static_cast(curr.value), static_cast(prev), result_value); + if (overflow) + throw Exception(ErrorCodes::DECIMAL_OVERFLOW, "Decimal math overflow"); + + dst[pos] = Result(result_value); + } + else + { + dst[pos] = curr - prev; + } + prev = curr; } } diff --git a/tests/queries/0_stateless/01851_array_difference_decimal_overflow_ubsan.reference b/tests/queries/0_stateless/01851_array_difference_decimal_overflow_ubsan.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/0_stateless/01851_array_difference_decimal_overflow_ubsan.sql b/tests/queries/0_stateless/01851_array_difference_decimal_overflow_ubsan.sql new file mode 100644 index 00000000000..ebf2efda4f1 --- /dev/null +++ b/tests/queries/0_stateless/01851_array_difference_decimal_overflow_ubsan.sql @@ -0,0 +1 @@ +SELECT arrayDifference([toDecimal32(100.0000991821289, 0), -2147483647]) AS x; --{serverError 407}