This is an automated email from the ASF dual-hosted git repository.
Mryange pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 4bf0731ac73 [fix](function) Report decimal rounding overflow (#68978)
4bf0731ac73 is described below
commit 4bf0731ac73b0e2968fb0ca29c17bbfea25ccbcb
Author: Mryange <[email protected]>
AuthorDate: Thu Oct 15 14:45:21 2026 +0800
[fix](function) Report decimal rounding overflow (#68978)
[fix](function) Report overflow in decimal ceil and floor
### What problem does this PR solve?
Issue Number: N/A
Related PR: #68251
Problem Summary: Decimal CEIL/FLOOR silently returned zero when both the
rounding divisor and the result multiplier exceeded the native Decimal
range. For example, `CEIL(NULLABLE(0.123456789), NULLABLE(-1))` returned
zero instead of reporting that the rounded value cannot fit in the
existing result type. Root cause: the saturated-factor branch discarded
nonzero directed-rounding results. This change reports arithmetic
overflow for positive CEIL and negative FLOOR in that branch, with a
hint to cast the input to a Decimal with sufficient precision. Zero
results and return types remain unchanged.
### Release note
Decimal CEIL/FLOOR now report arithmetic overflow instead of silently
returning zero when a nonzero directed-rounding result requires an
unrepresentable result multiplier.
### Check List (For Author)
- Test:
- [x] Unit Test: ASAN `RoundFunctionTest.*` passed (6/6). Before
updating the legacy overflow expectations, `normal_decimal` and
`normal_decimal_const` failed with arithmetic overflow.
- [x] Coverage includes Decimal32/Decimal64 CEIL and FLOOR overflow for
vector and constant inputs, plus zero and opposite-sign results.
- Behavior changed:
- [x] Yes. Previously incorrect zero results now produce an arithmetic
overflow error; return types are unchanged.
- Does this need documentation?
- [x] Yes. CEIL/FLOOR overflow behavior and casting guidance should be
documented; documentation follow-up is pending.
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label
---
be/src/exprs/function/round.h | 17 +
be/test/exprs/function/function_round_test.cpp | 632 +++++++++++++++----------
2 files changed, 398 insertions(+), 251 deletions(-)
diff --git a/be/src/exprs/function/round.h b/be/src/exprs/function/round.h
index d8d480c30d8..45a01faacd5 100644
--- a/be/src/exprs/function/round.h
+++ b/be/src/exprs/function/round.h
@@ -164,6 +164,23 @@ struct IntegerRoundingComputation {
// A saturated divisor is larger than every valid value of
this Decimal type.
// Only directed rounding can produce one representable
target unit.
if (target_scale >= std::numeric_limits<T>::max()) {
+ if constexpr (rounding_mode == RoundingMode::Floor) {
+ if (*in < 0) {
+ throw doris::Exception(
+ ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+ "Arithmetic overflow in decimal
rounding result. Cast the "
+ "input "
+ "to a Decimal type with sufficient
precision.");
+ }
+ } else if constexpr (rounding_mode ==
RoundingMode::Ceil) {
+ if (*in > 0) {
+ throw doris::Exception(
+ ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+ "Arithmetic overflow in decimal
rounding result. Cast the "
+ "input "
+ "to a Decimal type with sufficient
precision.");
+ }
+ }
*out = T(0);
} else if constexpr (rounding_mode == RoundingMode::Floor)
{
*out = *in < 0 ? -target_scale : T(0);
diff --git a/be/test/exprs/function/function_round_test.cpp
b/be/test/exprs/function/function_round_test.cpp
index deb2482fb9e..37cfb5918c5 100644
--- a/be/test/exprs/function/function_round_test.cpp
+++ b/be/test/exprs/function/function_round_test.cpp
@@ -20,6 +20,7 @@
#include <cstddef>
#include <map>
#include <memory>
+#include <string>
#include <tuple>
#include <utility>
#include <vector>
@@ -46,6 +47,10 @@ namespace doris {
using DecimalTestDataSet =
std::map<std::pair<int, int>, std::vector<std::tuple<Int128, int,
Int128>>>;
+// {precision, scale} -> {input, scale_arg}
+using DecimalOverflowTestDataSet =
+ std::map<std::pair<int, int>, std::vector<std::pair<Int128, int>>>;
+
// input, scale_arg, expectation
using FloatTestDataSet = std::vector<std::tuple<Float64, int, Float64>>;
@@ -353,188 +358,268 @@ const static DecimalTestDataSet
trunc_floor_decimal64_cases = {
// test cases for ceil function of decimal32
const static DecimalTestDataSet ceil_decimal32_cases = {
- {{1, 0},
- {
- {1, -10, 0}, {1, -9, 1000000000}, {1, -8, 100000000},
{1, -7, 10000000},
- {1, -6, 1000000}, {1, -5, 100000}, {1, -4, 10000},
{1, -3, 1000},
- {1, -2, 100}, {1, -1, 10}, {1, 0, 1},
{1, 1, 1},
- {1, 2, 1}, {1, 3, 1}, {1, 4, 1},
{1, 5, 1},
- {1, 6, 1}, {1, 7, 1}, {1, 8, 1},
{1, 9, 1},
- {1, 10, 1},
- }},
+ {{1, 0}, {{1, -9, 1000000000}, {1, -8, 100000000}, {1, -7, 10000000},
{1, -6, 1000000},
+ {1, -5, 100000}, {1, -4, 10000}, {1, -3, 1000},
{1, -2, 100},
+ {1, -1, 10}, {1, 0, 1}, {1, 1, 1},
{1, 2, 1},
+ {1, 3, 1}, {1, 4, 1}, {1, 5, 1},
{1, 6, 1},
+ {1, 7, 1}, {1, 8, 1}, {1, 9, 1},
{1, 10, 1}}},
{{1, 1},
- {
- {1, -10, 0}, {1, -9, 0}, {1, -8, 1000000000}, {1,
-7, 100000000},
- {1, -6, 10000000}, {1, -5, 1000000}, {1, -4, 100000}, {1,
-3, 10000},
- {1, -2, 1000}, {1, -1, 100}, {1, 0, 10}, {1,
1, 1},
- {1, 2, 1}, {1, 3, 1}, {1, 4, 1}, {1,
5, 1},
- {1, 6, 1}, {1, 7, 1}, {1, 8, 1}, {1,
9, 1},
- {1, 10, 1},
- }},
+ {{1, -8, 1000000000},
+ {1, -7, 100000000},
+ {1, -6, 10000000},
+ {1, -5, 1000000},
+ {1, -4, 100000},
+ {1, -3, 10000},
+ {1, -2, 1000},
+ {1, -1, 100},
+ {1, 0, 10},
+ {1, 1, 1},
+ {1, 2, 1},
+ {1, 3, 1},
+ {1, 4, 1},
+ {1, 5, 1},
+ {1, 6, 1},
+ {1, 7, 1},
+ {1, 8, 1},
+ {1, 9, 1},
+ {1, 10, 1}}},
{{2, 0},
- {
- {12, -4, 10000},
- {12, -3, 1000},
- {12, -2, 100},
- {12, -1, 20},
- {12, 0, 12},
- {12, 1, 12},
- {12, 2, 12},
- {12, 3, 12},
- {12, 4, 12},
- }},
+ {{12, -4, 10000},
+ {12, -3, 1000},
+ {12, -2, 100},
+ {12, -1, 20},
+ {12, 0, 12},
+ {12, 1, 12},
+ {12, 2, 12},
+ {12, 3, 12},
+ {12, 4, 12}}},
{{2, 1},
- {
- {12, -4, 100000},
- {12, -3, 10000},
- {12, -2, 1000},
- {12, -1, 100},
- {12, 0, 20},
- {12, 1, 12},
- {12, 2, 12},
- {12, 3, 12},
- {12, 4, 12},
- }},
+ {{12, -4, 100000},
+ {12, -3, 10000},
+ {12, -2, 1000},
+ {12, -1, 100},
+ {12, 0, 20},
+ {12, 1, 12},
+ {12, 2, 12},
+ {12, 3, 12},
+ {12, 4, 12}}},
{{2, 2},
- {
- {12, -4, 1000000},
- {12, -3, 100000},
- {12, -2, 10000},
- {12, -1, 1000},
- {12, 0, 100},
- {12, 1, 20},
- {12, 2, 12},
- {12, 3, 12},
- {12, 4, 12},
- }},
+ {{12, -4, 1000000},
+ {12, -3, 100000},
+ {12, -2, 10000},
+ {12, -1, 1000},
+ {12, 0, 100},
+ {12, 1, 20},
+ {12, 2, 12},
+ {12, 3, 12},
+ {12, 4, 12}}},
{{9, 0},
- {
- {123456789, -10, 0}, {123456789, -9, 1000000000},
- {123456789, -8, 200000000}, {123456789, -7, 130000000},
- {123456789, -6, 124000000}, {123456789, -5, 123500000},
- {123456789, -4, 123460000}, {123456789, -3, 123457000},
- {123456789, -2, 123456800}, {123456789, -1, 123456790},
- {123456789, 0, 123456789}, {123456789, 1, 123456789},
- {123456789, 2, 123456789}, {123456789, 3, 123456789},
- {123456789, 4, 123456789}, {123456789, 5, 123456789},
- {123456789, 6, 123456789}, {123456789, 7, 123456789},
- {123456789, 8, 123456789}, {123456789, 9, 123456789},
- {123456789, 10, 123456789},
- }},
+ {{123456789, -9, 1000000000}, {123456789, -8, 200000000}, {123456789,
-7, 130000000},
+ {123456789, -6, 124000000}, {123456789, -5, 123500000}, {123456789,
-4, 123460000},
+ {123456789, -3, 123457000}, {123456789, -2, 123456800}, {123456789,
-1, 123456790},
+ {123456789, 0, 123456789}, {123456789, 1, 123456789}, {123456789,
2, 123456789},
+ {123456789, 3, 123456789}, {123456789, 4, 123456789}, {123456789,
5, 123456789},
+ {123456789, 6, 123456789}, {123456789, 7, 123456789}, {123456789,
8, 123456789},
+ {123456789, 9, 123456789}, {123456789, 10, 123456789}}},
{{9, 1},
- {
- {123456789, -10, 0}, {123456789, -9, 0},
- {123456789, -8, 1000000000}, {123456789, -7, 200000000},
- {123456789, -6, 130000000}, {123456789, -5, 124000000},
- {123456789, -4, 123500000}, {123456789, -3, 123460000},
- {123456789, -2, 123457000}, {123456789, -1, 123456800},
- {123456789, 0, 123456790}, {123456789, 1, 123456789},
- {123456789, 2, 123456789}, {123456789, 3, 123456789},
- {123456789, 4, 123456789}, {123456789, 5, 123456789},
- {123456789, 6, 123456789}, {123456789, 7, 123456789},
- {123456789, 8, 123456789}, {123456789, 9, 123456789},
- {123456789, 10, 123456789},
- }},
+ {{123456789, -8, 1000000000},
+ {123456789, -7, 200000000},
+ {123456789, -6, 130000000},
+ {123456789, -5, 124000000},
+ {123456789, -4, 123500000},
+ {123456789, -3, 123460000},
+ {123456789, -2, 123457000},
+ {123456789, -1, 123456800},
+ {123456789, 0, 123456790},
+ {123456789, 1, 123456789},
+ {123456789, 2, 123456789},
+ {123456789, 3, 123456789},
+ {123456789, 4, 123456789},
+ {123456789, 5, 123456789},
+ {123456789, 6, 123456789},
+ {123456789, 7, 123456789},
+ {123456789, 8, 123456789},
+ {123456789, 9, 123456789},
+ {123456789, 10, 123456789}}},
{{9, 2},
- {
- {123456789, -10, 0}, {123456789, -9, 0},
- {123456789, -8, 0}, {123456789, -7, 1000000000},
- {123456789, -6, 200000000}, {123456789, -5, 130000000},
- {123456789, -4, 124000000}, {123456789, -3, 123500000},
- {123456789, -2, 123460000}, {123456789, -1, 123457000},
- {123456789, 0, 123456800}, {123456789, 1, 123456790},
- {123456789, 2, 123456789}, {123456789, 3, 123456789},
- {123456789, 4, 123456789}, {123456789, 5, 123456789},
- {123456789, 6, 123456789}, {123456789, 7, 123456789},
- {123456789, 8, 123456789}, {123456789, 9, 123456789},
- {123456789, 10, 123456789},
- }},
+ {{123456789, -7, 1000000000},
+ {123456789, -6, 200000000},
+ {123456789, -5, 130000000},
+ {123456789, -4, 124000000},
+ {123456789, -3, 123500000},
+ {123456789, -2, 123460000},
+ {123456789, -1, 123457000},
+ {123456789, 0, 123456800},
+ {123456789, 1, 123456790},
+ {123456789, 2, 123456789},
+ {123456789, 3, 123456789},
+ {123456789, 4, 123456789},
+ {123456789, 5, 123456789},
+ {123456789, 6, 123456789},
+ {123456789, 7, 123456789},
+ {123456789, 8, 123456789},
+ {123456789, 9, 123456789},
+ {123456789, 10, 123456789}}},
{{9, 3},
- {
- {123456789, -10, 0}, {123456789, -9, 0},
- {123456789, -8, 0}, {123456789, -7, 0},
- {123456789, -6, 1000000000}, {123456789, -5, 200000000},
- {123456789, -4, 130000000}, {123456789, -3, 124000000},
- {123456789, -2, 123500000}, {123456789, -1, 123460000},
- {123456789, 0, 123457000}, {123456789, 1, 123456800},
- {123456789, 2, 123456790}, {123456789, 3, 123456789},
- {123456789, 4, 123456789}, {123456789, 5, 123456789},
- {123456789, 6, 123456789}, {123456789, 7, 123456789},
- {123456789, 8, 123456789}, {123456789, 9, 123456789},
- {123456789, 10, 123456789},
- }},
+ {{123456789, -6, 1000000000},
+ {123456789, -5, 200000000},
+ {123456789, -4, 130000000},
+ {123456789, -3, 124000000},
+ {123456789, -2, 123500000},
+ {123456789, -1, 123460000},
+ {123456789, 0, 123457000},
+ {123456789, 1, 123456800},
+ {123456789, 2, 123456790},
+ {123456789, 3, 123456789},
+ {123456789, 4, 123456789},
+ {123456789, 5, 123456789},
+ {123456789, 6, 123456789},
+ {123456789, 7, 123456789},
+ {123456789, 8, 123456789},
+ {123456789, 9, 123456789},
+ {123456789, 10, 123456789}}},
{{9, 4},
- {
- {123456789, -10, 0}, {123456789, -9, 0},
- {123456789, -8, 0}, {123456789, -7, 0},
- {123456789, -6, 0}, {123456789, -5, 1000000000},
- {123456789, -4, 200000000}, {123456789, -3, 130000000},
- {123456789, -2, 124000000}, {123456789, -1, 123500000},
- {123456789, 0, 123460000}, {123456789, 1, 123457000},
- {123456789, 2, 123456800}, {123456789, 3, 123456790},
- {123456789, 4, 123456789}, {123456789, 5, 123456789},
- {123456789, 6, 123456789}, {123456789, 7, 123456789},
- {123456789, 8, 123456789}, {123456789, 9, 123456789},
- {123456789, 10, 123456789},
- }},
+ {{123456789, -5, 1000000000},
+ {123456789, -4, 200000000},
+ {123456789, -3, 130000000},
+ {123456789, -2, 124000000},
+ {123456789, -1, 123500000},
+ {123456789, 0, 123460000},
+ {123456789, 1, 123457000},
+ {123456789, 2, 123456800},
+ {123456789, 3, 123456790},
+ {123456789, 4, 123456789},
+ {123456789, 5, 123456789},
+ {123456789, 6, 123456789},
+ {123456789, 7, 123456789},
+ {123456789, 8, 123456789},
+ {123456789, 9, 123456789},
+ {123456789, 10, 123456789}}},
{{9, 5},
- {
- {123456789, -10, 0}, {123456789, -9, 0},
- {123456789, -8, 0}, {123456789, -7, 0},
- {123456789, -6, 0}, {123456789, -5, 0},
- {123456789, -4, 1000000000}, {123456789, -3, 200000000},
- {123456789, -2, 130000000}, {123456789, -1, 124000000},
- {123456789, 0, 123500000}, {123456789, 1, 123460000},
- {123456789, 2, 123457000}, {123456789, 3, 123456800},
- {123456789, 4, 123456790}, {123456789, 5, 123456789},
- {123456789, 6, 123456789}, {123456789, 7, 123456789},
- {123456789, 8, 123456789}, {123456789, 9, 123456789},
- {123456789, 10, 123456789},
- }},
+ {{123456789, -4, 1000000000},
+ {123456789, -3, 200000000},
+ {123456789, -2, 130000000},
+ {123456789, -1, 124000000},
+ {123456789, 0, 123500000},
+ {123456789, 1, 123460000},
+ {123456789, 2, 123457000},
+ {123456789, 3, 123456800},
+ {123456789, 4, 123456790},
+ {123456789, 5, 123456789},
+ {123456789, 6, 123456789},
+ {123456789, 7, 123456789},
+ {123456789, 8, 123456789},
+ {123456789, 9, 123456789},
+ {123456789, 10, 123456789}}},
{{9, 6},
- {
- {123456789, -10, 0}, {123456789, -9, 0},
- {123456789, -8, 0}, {123456789, -7, 0},
- {123456789, -6, 0}, {123456789, -5, 0},
- {123456789, -4, 0}, {123456789, -3, 1000000000},
- {123456789, -2, 200000000}, {123456789, -1, 130000000},
- {123456789, 0, 124000000}, {123456789, 1, 123500000},
- {123456789, 2, 123460000}, {123456789, 3, 123457000},
- {123456789, 4, 123456800}, {123456789, 5, 123456790},
- {123456789, 6, 123456789}, {123456789, 7, 123456789},
- {123456789, 8, 123456789}, {123456789, 9, 123456789},
- {123456789, 10, 123456789},
- }},
+ {{123456789, -3, 1000000000},
+ {123456789, -2, 200000000},
+ {123456789, -1, 130000000},
+ {123456789, 0, 124000000},
+ {123456789, 1, 123500000},
+ {123456789, 2, 123460000},
+ {123456789, 3, 123457000},
+ {123456789, 4, 123456800},
+ {123456789, 5, 123456790},
+ {123456789, 6, 123456789},
+ {123456789, 7, 123456789},
+ {123456789, 8, 123456789},
+ {123456789, 9, 123456789},
+ {123456789, 10, 123456789}}},
{{9, 7},
- {
- {123456789, -10, 0}, {123456789, -9, 0},
{123456789, -8, 0},
- {123456789, -7, 0}, {123456789, -6, 0},
{123456789, -5, 0},
- {123456789, -4, 0}, {123456789, -3, 0},
{123456789, -2, 1000000000},
- {123456789, -1, 200000000}, {123456789, 0, 130000000},
{123456789, 1, 124000000},
- {123456789, 2, 123500000}, {123456789, 3, 123460000},
{123456789, 4, 123457000},
- {123456789, 5, 123456800}, {123456789, 6, 123456790},
{123456789, 7, 123456789},
- {123456789, 8, 123456789}, {123456789, 9, 123456789},
{123456789, 10, 123456789},
- }},
+ {{123456789, -2, 1000000000},
+ {123456789, -1, 200000000},
+ {123456789, 0, 130000000},
+ {123456789, 1, 124000000},
+ {123456789, 2, 123500000},
+ {123456789, 3, 123460000},
+ {123456789, 4, 123457000},
+ {123456789, 5, 123456800},
+ {123456789, 6, 123456790},
+ {123456789, 7, 123456789},
+ {123456789, 8, 123456789},
+ {123456789, 9, 123456789},
+ {123456789, 10, 123456789}}},
{{9, 8},
- {
- {123456789, -10, 0}, {123456789, -9, 0},
{123456789, -8, 0},
- {123456789, -7, 0}, {123456789, -6, 0},
{123456789, -5, 0},
- {123456789, -4, 0}, {123456789, -3, 0},
{123456789, -2, 0},
- {123456789, -1, 1000000000}, {123456789, 0, 200000000},
{123456789, 1, 130000000},
- {123456789, 2, 124000000}, {123456789, 3, 123500000},
{123456789, 4, 123460000},
- {123456789, 5, 123457000}, {123456789, 6, 123456800},
{123456789, 7, 123456790},
- {123456789, 8, 123456789}, {123456789, 9, 123456789},
{123456789, 10, 123456789},
- }},
+ {{123456789, -1, 1000000000},
+ {123456789, 0, 200000000},
+ {123456789, 1, 130000000},
+ {123456789, 2, 124000000},
+ {123456789, 3, 123500000},
+ {123456789, 4, 123460000},
+ {123456789, 5, 123457000},
+ {123456789, 6, 123456800},
+ {123456789, 7, 123456790},
+ {123456789, 8, 123456789},
+ {123456789, 9, 123456789},
+ {123456789, 10, 123456789}}},
{{9, 9},
- {
- {123456789, -10, 0}, {123456789, -9, 0},
{123456789, -8, 0},
- {123456789, -7, 0}, {123456789, -6, 0},
{123456789, -5, 0},
- {123456789, -4, 0}, {123456789, -3, 0},
{123456789, -2, 0},
- {123456789, -1, 0}, {123456789, 0, 1000000000},
{123456789, 1, 200000000},
- {123456789, 2, 130000000}, {123456789, 3, 124000000},
{123456789, 4, 123500000},
- {123456789, 5, 123460000}, {123456789, 6, 123457000},
{123456789, 7, 123456800},
- {123456789, 8, 123456790}, {123456789, 9, 123456789},
{123456789, 10, 123456789},
- }}};
+ {{123456789, 0, 1000000000},
+ {123456789, 1, 200000000},
+ {123456789, 2, 130000000},
+ {123456789, 3, 124000000},
+ {123456789, 4, 123500000},
+ {123456789, 5, 123460000},
+ {123456789, 6, 123457000},
+ {123456789, 7, 123456800},
+ {123456789, 8, 123456790},
+ {123456789, 9, 123456789},
+ {123456789, 10, 123456789}}}};
+
+const static DecimalOverflowTestDataSet ceil_decimal32_overflow_cases = {
+ {{1, 0}, {{1, -10}}},
+ {{1, 1}, {{1, -10}, {1, -9}}},
+ {{9, 0}, {{123456789, -10}}},
+ {{9, 1}, {{123456789, -10}, {123456789, -9}}},
+ {{9, 2}, {{123456789, -10}, {123456789, -9}, {123456789, -8}}},
+ {{9, 3}, {{123456789, -10}, {123456789, -9}, {123456789, -8},
{123456789, -7}}},
+ {{9, 4},
+ {{123456789, -10}, {123456789, -9}, {123456789, -8}, {123456789, -7},
{123456789, -6}}},
+ {{9, 5},
+ {{123456789, -10},
+ {123456789, -9},
+ {123456789, -8},
+ {123456789, -7},
+ {123456789, -6},
+ {123456789, -5}}},
+ {{9, 6},
+ {{123456789, -10},
+ {123456789, -9},
+ {123456789, -8},
+ {123456789, -7},
+ {123456789, -6},
+ {123456789, -5},
+ {123456789, -4}}},
+ {{9, 7},
+ {{123456789, -10},
+ {123456789, -9},
+ {123456789, -8},
+ {123456789, -7},
+ {123456789, -6},
+ {123456789, -5},
+ {123456789, -4},
+ {123456789, -3}}},
+ {{9, 8},
+ {{123456789, -10},
+ {123456789, -9},
+ {123456789, -8},
+ {123456789, -7},
+ {123456789, -6},
+ {123456789, -5},
+ {123456789, -4},
+ {123456789, -3},
+ {123456789, -2}}},
+ {{9, 9},
+ {{123456789, -10},
+ {123456789, -9},
+ {123456789, -8},
+ {123456789, -7},
+ {123456789, -6},
+ {123456789, -5},
+ {123456789, -4},
+ {123456789, -3},
+ {123456789, -2},
+ {123456789, -1}}}};
// test cases for ceil function of decimal64
const static DecimalTestDataSet ceil_decimal64_cases = {
@@ -574,89 +659,77 @@ const static DecimalTestDataSet ceil_decimal64_cases = {
{1234567891, 7, 1234567891}, {1234567891, 8,
1234567891},
{1234567891, 9, 1234567891}, {1234567891, 10,
1234567891},
{1234567891, 11, 1234567891}}},
- {{10, 9},
- {{1234567891, -11, 0},
- {1234567891, -10, 0},
- {1234567891, -9, 1000000000000000000},
- {1234567891, -8, 100000000000000000},
- {1234567891, -7, 10000000000000000},
- {1234567891, -6, 1000000000000000},
- {1234567891, -5, 100000000000000},
- {1234567891, -4, 10000000000000},
- {1234567891, -3, 1000000000000},
- {1234567891, -2, 100000000000},
- {1234567891, -1, 10000000000},
- {1234567891, 0, 2000000000},
- {1234567891, 1, 1300000000},
- {1234567891, 2, 1240000000},
- {1234567891, 3, 1235000000},
- {1234567891, 4, 1234600000},
- {1234567891, 5, 1234570000},
- {1234567891, 6, 1234568000},
- {1234567891, 7, 1234567900},
- {1234567891, 8, 1234567900},
- {1234567891, 9, 1234567891},
- {1234567891, 10, 1234567891},
- {1234567891, 11, 1234567891}}},
- {{18, 0},
- {{123456789123456789, -19, 0},
- {123456789123456789, -18, 1000000000000000000},
- {123456789123456789, -17, 200000000000000000},
- {123456789123456789, -16, 130000000000000000},
- {123456789123456789, -15, 124000000000000000},
- {123456789123456789, -14, 123500000000000000},
- {123456789123456789, -13, 123460000000000000},
- {123456789123456789, -12, 123457000000000000},
- {123456789123456789, -11, 123456800000000000},
- {123456789123456789, -10, 123456790000000000},
- {123456789123456789, -9, 123456790000000000},
- {123456789123456789, -8, 123456789200000000},
- {123456789123456789, -7, 123456789130000000},
- {123456789123456789, -6, 123456789124000000},
- {123456789123456789, -5, 123456789123500000},
- {123456789123456789, -4, 123456789123460000},
- {123456789123456789, -3, 123456789123457000},
- {123456789123456789, -2, 123456789123456800},
- {123456789123456789, -1, 123456789123456790},
- {123456789123456789, 0, 123456789123456789},
- {123456789123456789, 1, 123456789123456789},
- {123456789123456789, 2, 123456789123456789},
- {123456789123456789, 3, 123456789123456789},
- {123456789123456789, 4, 123456789123456789},
- {123456789123456789, 5, 123456789123456789},
- {123456789123456789, 6, 123456789123456789},
- {123456789123456789, 7, 123456789123456789},
- {123456789123456789, 8, 123456789123456789},
- {123456789123456789, 18, 123456789123456789}}},
- {{18, 18},
- {{123456789123456789, -1, 0},
- {123456789123456789, 0, 1000000000000000000},
- {123456789123456789, 1, 200000000000000000},
- {123456789123456789, 2, 130000000000000000},
- {123456789123456789, 3, 124000000000000000},
- {123456789123456789, 4, 123500000000000000},
- {123456789123456789, 5, 123460000000000000},
- {123456789123456789, 6, 123457000000000000},
- {123456789123456789, 7, 123456800000000000},
- {123456789123456789, 8, 123456790000000000},
- {123456789123456789, 9, 123456790000000000},
- {123456789123456789, 10, 123456789200000000},
- {123456789123456789, 11, 123456789130000000},
- {123456789123456789, 12, 123456789124000000},
- {123456789123456789, 13, 123456789123500000},
- {123456789123456789, 14, 123456789123460000},
- {123456789123456789, 15, 123456789123457000},
- {123456789123456789, 16, 123456789123456800},
- {123456789123456789, 17, 123456789123456790},
- {123456789123456789, 18, 123456789123456789},
- {123456789123456789, 19, 123456789123456789},
- {123456789123456789, 20, 123456789123456789},
- {123456789123456789, 21, 123456789123456789},
- {123456789123456789, 22, 123456789123456789},
- {123456789123456789, 23, 123456789123456789},
- {123456789123456789, 24, 123456789123456789},
- {123456789123456789, 25, 123456789123456789},
- {123456789123456789, 26, 123456789123456789}}}};
+ {{10, 9}, {{1234567891, -9, 1000000000000000000}, {1234567891, -8,
100000000000000000},
+ {1234567891, -7, 10000000000000000}, {1234567891, -6,
1000000000000000},
+ {1234567891, -5, 100000000000000}, {1234567891, -4,
10000000000000},
+ {1234567891, -3, 1000000000000}, {1234567891, -2,
100000000000},
+ {1234567891, -1, 10000000000}, {1234567891, 0,
2000000000},
+ {1234567891, 1, 1300000000}, {1234567891, 2,
1240000000},
+ {1234567891, 3, 1235000000}, {1234567891, 4,
1234600000},
+ {1234567891, 5, 1234570000}, {1234567891, 6,
1234568000},
+ {1234567891, 7, 1234567900}, {1234567891, 8,
1234567900},
+ {1234567891, 9, 1234567891}, {1234567891, 10,
1234567891},
+ {1234567891, 11, 1234567891}}},
+ {{18, 0}, {{123456789123456789, -18, 1000000000000000000},
+ {123456789123456789, -17, 200000000000000000},
+ {123456789123456789, -16, 130000000000000000},
+ {123456789123456789, -15, 124000000000000000},
+ {123456789123456789, -14, 123500000000000000},
+ {123456789123456789, -13, 123460000000000000},
+ {123456789123456789, -12, 123457000000000000},
+ {123456789123456789, -11, 123456800000000000},
+ {123456789123456789, -10, 123456790000000000},
+ {123456789123456789, -9, 123456790000000000},
+ {123456789123456789, -8, 123456789200000000},
+ {123456789123456789, -7, 123456789130000000},
+ {123456789123456789, -6, 123456789124000000},
+ {123456789123456789, -5, 123456789123500000},
+ {123456789123456789, -4, 123456789123460000},
+ {123456789123456789, -3, 123456789123457000},
+ {123456789123456789, -2, 123456789123456800},
+ {123456789123456789, -1, 123456789123456790},
+ {123456789123456789, 0, 123456789123456789},
+ {123456789123456789, 1, 123456789123456789},
+ {123456789123456789, 2, 123456789123456789},
+ {123456789123456789, 3, 123456789123456789},
+ {123456789123456789, 4, 123456789123456789},
+ {123456789123456789, 5, 123456789123456789},
+ {123456789123456789, 6, 123456789123456789},
+ {123456789123456789, 7, 123456789123456789},
+ {123456789123456789, 8, 123456789123456789},
+ {123456789123456789, 18, 123456789123456789}}},
+ {{18, 18}, {{123456789123456789, 0, 1000000000000000000},
+ {123456789123456789, 1, 200000000000000000},
+ {123456789123456789, 2, 130000000000000000},
+ {123456789123456789, 3, 124000000000000000},
+ {123456789123456789, 4, 123500000000000000},
+ {123456789123456789, 5, 123460000000000000},
+ {123456789123456789, 6, 123457000000000000},
+ {123456789123456789, 7, 123456800000000000},
+ {123456789123456789, 8, 123456790000000000},
+ {123456789123456789, 9, 123456790000000000},
+ {123456789123456789, 10, 123456789200000000},
+ {123456789123456789, 11, 123456789130000000},
+ {123456789123456789, 12, 123456789124000000},
+ {123456789123456789, 13, 123456789123500000},
+ {123456789123456789, 14, 123456789123460000},
+ {123456789123456789, 15, 123456789123457000},
+ {123456789123456789, 16, 123456789123456800},
+ {123456789123456789, 17, 123456789123456790},
+ {123456789123456789, 18, 123456789123456789},
+ {123456789123456789, 19, 123456789123456789},
+ {123456789123456789, 20, 123456789123456789},
+ {123456789123456789, 21, 123456789123456789},
+ {123456789123456789, 22, 123456789123456789},
+ {123456789123456789, 23, 123456789123456789},
+ {123456789123456789, 24, 123456789123456789},
+ {123456789123456789, 25, 123456789123456789},
+ {123456789123456789, 26, 123456789123456789}}}};
+
+const static DecimalOverflowTestDataSet ceil_decimal64_overflow_cases = {
+ {{10, 9}, {{1234567891, -11}, {1234567891, -10}}},
+ {{18, 0}, {{123456789123456789, -19}}},
+ {{18, 18}, {{123456789123456789, -1}}}};
// test cases for round and round_bankers function of decimal32
const static DecimalTestDataSet round_decimal32_cases = {
@@ -974,6 +1047,36 @@ FloatTestDataSet round_bankers_float64_cases = {{2.5, 0,
2.0},
{123.123456, 4, 123.123500},
{123456789.123456, 4,
123456789.123500}};
+template <typename FuncType, typename DecimalType>
+static void check_decimal_rounding_overflow(typename DecimalType::NativeType
input, int precision,
+ int scale, int scale_arg, bool
decimal_col_is_const) {
+ auto func = FuncType::create();
+ auto col_general = ColumnDecimal<DecimalType::PType>::create(1, scale);
+ col_general->get_element(0) = DecimalType(input);
+ auto col_scale = ColumnInt32::create();
+ col_scale->insert(Field::create_field<TYPE_INT>(scale_arg));
+ ColumnPtr input_column = std::move(col_general);
+ if (decimal_col_is_const) {
+ input_column = ColumnConst::create(std::move(input_column), 1);
+ }
+
+ Block block;
+ block.insert({std::move(input_column),
+
std::make_shared<DataTypeDecimal<DecimalType::PType>>(precision, scale),
+ "col_general"});
+ block.insert({std::move(col_scale), std::make_shared<DataTypeInt32>(),
"col_scale"});
+ block.insert({nullptr,
std::make_shared<DataTypeDecimal<DecimalType::PType>>(precision, scale),
+ "col_res"});
+
+ try {
+ static_cast<void>(func->execute_impl(nullptr, block, {0, 1}, 2, 1));
+ FAIL() << "Expected decimal rounding overflow";
+ } catch (const Exception& e) {
+ EXPECT_EQ(e.code(), ErrorCode::ARITHMETIC_OVERFLOW_ERRROR);
+ EXPECT_NE(std::string(e.what()).find("Cast the input"),
std::string::npos);
+ }
+}
+
template <typename FuncType, typename DecimalType>
static void decimal_checker(const DecimalTestDataSet& round_test_cases, bool
decimal_col_is_const) {
static_assert(IsDecimalNumber<DecimalType>);
@@ -1197,6 +1300,33 @@ TEST(RoundFunctionTest, decimal_scale_boundaries) {
0, -1, false,
true);
}
+TEST(RoundFunctionTest, decimal_rounding_overflow) {
+ for (bool decimal_col_is_const : {false, true}) {
+ for (const auto& [type, cases] : ceil_decimal32_overflow_cases) {
+ for (const auto& [input, scale_arg] : cases) {
+ check_decimal_rounding_overflow<Decimal32CeilFunction,
Decimal32>(
+ input, type.first, type.second, scale_arg,
decimal_col_is_const);
+ check_decimal_rounding_overflow<Decimal32FloorFunction,
Decimal32>(
+ -input, type.first, type.second, scale_arg,
decimal_col_is_const);
+ }
+ }
+ for (const auto& [type, cases] : ceil_decimal64_overflow_cases) {
+ for (const auto& [input, scale_arg] : cases) {
+ check_decimal_rounding_overflow<Decimal64CeilFunction,
Decimal64>(
+ input, type.first, type.second, scale_arg,
decimal_col_is_const);
+ check_decimal_rounding_overflow<Decimal64FloorFunction,
Decimal64>(
+ -input, type.first, type.second, scale_arg,
decimal_col_is_const);
+ }
+ }
+ for (Int32 input : {-123456789, 0}) {
+ check_decimal_rounding<Decimal32CeilFunction, Decimal32>(input, 9,
9, -1, 9, 9, 0,
+
decimal_col_is_const, false);
+ check_decimal_rounding<Decimal32FloorFunction, Decimal32>(-input,
9, 9, -1, 9, 9, 0,
+
decimal_col_is_const, false);
+ }
+ }
+}
+
/// tests for func(Column, Column) with float input
TEST(RoundFunctionTest, normal_float) {
float_checker<FloatTruncateFunction, TYPE_FLOAT>(trunc_float32_cases,
false);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]