Skip to content

Commit df2fcfa

Browse files
cambyzjuweixingyu12
authored andcommitted
[fix](round) fix round decimal128 overflow (apache#37733) (apache#37965)
1 parent c990324 commit df2fcfa

File tree

3 files changed

+47
-9
lines changed

3 files changed

+47
-9
lines changed

be/src/vec/functions/round.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@
2222

2323
#include "vec/columns/column_const.h"
2424
#include "vec/columns/columns_number.h"
25+
#include "vec/exec/format/format_common.h"
2526
#include "vec/functions/function.h"
2627
#if defined(__SSE4_1__) || defined(__aarch64__)
2728
#include "util/sse_util.hpp"
2829
#else
2930
#include <fenv.h>
3031
#endif
3132
#include <algorithm>
33+
#include <type_traits>
3234

3335
#include "vec/columns/column.h"
3436
#include "vec/columns/column_decimal.h"
@@ -64,7 +66,7 @@ enum class TieBreakingMode {
6466
};
6567

6668
template <typename T, RoundingMode rounding_mode, ScaleMode scale_mode,
67-
TieBreakingMode tie_breaking_mode>
69+
TieBreakingMode tie_breaking_mode, typename U>
6870
struct IntegerRoundingComputation {
6971
static const size_t data_count = 1;
7072

@@ -116,7 +118,7 @@ struct IntegerRoundingComputation {
116118
__builtin_unreachable();
117119
}
118120

119-
static ALWAYS_INLINE T compute(T x, T scale, size_t target_scale) {
121+
static ALWAYS_INLINE T compute(T x, T scale, T target_scale) {
120122
switch (scale_mode) {
121123
case ScaleMode::Zero:
122124
case ScaleMode::Positive:
@@ -128,10 +130,10 @@ struct IntegerRoundingComputation {
128130
__builtin_unreachable();
129131
}
130132

131-
static ALWAYS_INLINE void compute(const T* __restrict in, size_t scale, T* __restrict out,
132-
size_t target_scale) {
133+
static ALWAYS_INLINE void compute(const T* __restrict in, U scale, T* __restrict out,
134+
U target_scale) {
133135
if constexpr (sizeof(T) <= sizeof(scale) && scale_mode == ScaleMode::Negative) {
134-
if (scale > size_t(std::numeric_limits<T>::max())) {
136+
if (scale >= std::numeric_limits<T>::max()) {
135137
*out = 0;
136138
return;
137139
}
@@ -145,23 +147,24 @@ class DecimalRoundingImpl {
145147
private:
146148
using NativeType = typename T::NativeType;
147149
using Op = IntegerRoundingComputation<NativeType, rounding_mode, ScaleMode::Negative,
148-
tie_breaking_mode>;
150+
tie_breaking_mode, NativeType>;
149151
using Container = typename ColumnDecimal<T>::Container;
150152

151153
public:
152154
static NO_INLINE void apply(const Container& in, UInt32 in_scale, Container& out,
153155
Int16 out_scale) {
154156
Int16 scale_arg = in_scale - out_scale;
155157
if (scale_arg > 0) {
156-
size_t scale = int_exp10(scale_arg);
158+
auto scale = DecimalScaleParams::get_scale_factor<NativeType>(scale_arg);
157159

158160
const NativeType* __restrict p_in = reinterpret_cast<const NativeType*>(in.data());
159161
const NativeType* end_in = reinterpret_cast<const NativeType*>(in.data()) + in.size();
160162
NativeType* __restrict p_out = reinterpret_cast<NativeType*>(out.data());
161163

162164
if (out_scale < 0) {
165+
auto negative_scale = DecimalScaleParams::get_scale_factor<NativeType>(-out_scale);
163166
while (p_in < end_in) {
164-
Op::compute(p_in, scale, p_out, int_exp10(-out_scale));
167+
Op::compute(p_in, scale, p_out, negative_scale);
165168
++p_in;
166169
++p_out;
167170
}
@@ -320,7 +323,7 @@ template <typename T, RoundingMode rounding_mode, ScaleMode scale_mode,
320323
TieBreakingMode tie_breaking_mode>
321324
struct IntegerRoundingImpl {
322325
private:
323-
using Op = IntegerRoundingComputation<T, rounding_mode, scale_mode, tie_breaking_mode>;
326+
using Op = IntegerRoundingComputation<T, rounding_mode, scale_mode, tie_breaking_mode, size_t>;
324327
using Container = typename ColumnVector<T>::Container;
325328

326329
public:
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- This file is automatically generated. You should know what you did if you want to edit this
2+
-- !select1 --
3+
186
4+
5+
-- !select2 --
6+
0
7+
8+
-- !select3 --
9+
20000000000000000000000
10+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
suite("test_round_overflow") {
19+
sql "SET enable_nereids_planner=true"
20+
sql "SET enable_fallback_to_original_planner=false"
21+
22+
qt_select1 "select round(coalesce(186,-33280029.8473323000000000000000000));"
23+
qt_select2 "select round(coalesce(186,-33280029.8473323000000000000000000), -20);"
24+
qt_select3 "select round(coalesce(18618500001234567890123.0,-33280029.847332300000000),-22);"
25+
}

0 commit comments

Comments
 (0)