This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.1 by this push:
new f7900b53ce1 [enhancement](function) floor/ceil/round/round_bankers can
use column as scale argument (#34391)
f7900b53ce1 is described below
commit f7900b53ce103f9d149d8b7b118ac52758902a8f
Author: Chester <[email protected]>
AuthorDate: Mon May 6 22:17:31 2024 +0800
[enhancement](function) floor/ceil/round/round_bankers can use column as
scale argument (#34391)
---
be/src/vec/functions/function_truncate.h | 245 -----
be/src/vec/functions/math.cpp | 97 +-
be/src/vec/functions/round.cpp | 50 +
be/src/vec/functions/round.h | 156 ++-
be/src/vec/functions/simple_function_factory.h | 2 +
be/test/vec/function/function_round_test.cpp | 1133 ++++++++++++++++++++
.../function/function_truncate_decimal_test.cpp | 370 -------
.../apache/doris/analysis/FunctionCallExpr.java | 26 +-
.../functions/ComputePrecisionForRound.java | 32 +-
.../math_functions/test_function_truncate.out | 3 +
.../sql_functions/math_functions/test_round.out | 79 ++
.../math_functions/test_function_truncate.groovy | 4 +
.../sql_functions/math_functions/test_round.groovy | 121 +++
13 files changed, 1522 insertions(+), 796 deletions(-)
diff --git a/be/src/vec/functions/function_truncate.h
b/be/src/vec/functions/function_truncate.h
deleted file mode 100644
index e29bc99c041..00000000000
--- a/be/src/vec/functions/function_truncate.h
+++ /dev/null
@@ -1,245 +0,0 @@
-// 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 <cstddef>
-#include <functional>
-#include <type_traits>
-#include <utility>
-
-#include "common/exception.h"
-#include "common/status.h"
-#include "olap/olap_common.h"
-#include "round.h"
-#include "vec/columns/column.h"
-#include "vec/columns/column_const.h"
-#include "vec/columns/column_decimal.h"
-#include "vec/columns/column_vector.h"
-#include "vec/common/assert_cast.h"
-#include "vec/core/call_on_type_index.h"
-#include "vec/core/field.h"
-#include "vec/core/types.h"
-#include "vec/data_types/data_type.h"
-#include "vec/data_types/data_type_decimal.h"
-#include "vec/data_types/data_type_number.h"
-
-namespace doris::vectorized {
-
-struct TruncateFloatOneArgImpl {
- static constexpr auto name = "truncate";
- static DataTypes get_variadic_argument_types() { return
{std::make_shared<DataTypeFloat64>()}; }
-};
-
-struct TruncateFloatTwoArgImpl {
- static constexpr auto name = "truncate";
- static DataTypes get_variadic_argument_types() {
- return {std::make_shared<DataTypeFloat64>(),
std::make_shared<DataTypeInt32>()};
- }
-};
-
-struct TruncateDecimalOneArgImpl {
- static constexpr auto name = "truncate";
- static DataTypes get_variadic_argument_types() {
- // All Decimal types are named Decimal, and real scale will be passed
as type argument for execute function
- // So we can just register Decimal32 here
- return {std::make_shared<DataTypeDecimal<Decimal32>>(9, 0)};
- }
-};
-
-struct TruncateDecimalTwoArgImpl {
- static constexpr auto name = "truncate";
- static DataTypes get_variadic_argument_types() {
- return {std::make_shared<DataTypeDecimal<Decimal32>>(9, 0),
- std::make_shared<DataTypeInt32>()};
- }
-};
-
-template <typename Impl>
-class FunctionTruncate : public FunctionRounding<Impl, RoundingMode::Trunc,
TieBreakingMode::Auto> {
-public:
- static FunctionPtr create() { return std::make_shared<FunctionTruncate>();
}
-
- ColumnNumbers get_arguments_that_are_always_constant() const override {
return {}; }
- // SELECT number, truncate(123.345, 1) FROM number("numbers"="10")
- // should NOT behave like two column arguments, so we can not use const
column default implementation
- bool use_default_implementation_for_constants() const override { return
false; }
-
- Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
- size_t result, size_t input_rows_count) const override
{
- const ColumnWithTypeAndName& column_general =
block.get_by_position(arguments[0]);
- ColumnPtr res;
-
- // potential argument types:
- // 0. truncate(ColumnConst, ColumnConst)
- // 1. truncate(Column), truncate(Column, ColumnConst)
- // 2. truncate(Column, Column)
- // 3. truncate(ColumnConst, Column)
-
- if (arguments.size() == 2 &&
is_column_const(*block.get_by_position(arguments[0]).column) &&
- is_column_const(*block.get_by_position(arguments[1]).column)) {
- // truncate(ColumnConst, ColumnConst)
- auto col_general =
- assert_cast<const
ColumnConst&>(*column_general.column).get_data_column_ptr();
- Int16 scale_arg = 0;
- RETURN_IF_ERROR(FunctionTruncate<Impl>::get_scale_arg(
- block.get_by_position(arguments[1]), &scale_arg));
-
- auto call = [&](const auto& types) -> bool {
- using Types = std::decay_t<decltype(types)>;
- using DataType = typename Types::LeftType;
-
- if constexpr (IsDataTypeNumber<DataType> ||
IsDataTypeDecimal<DataType>) {
- using FieldType = typename DataType::FieldType;
- res = Dispatcher<FieldType, RoundingMode::Trunc,
-
TieBreakingMode::Auto>::apply_vec_const(col_general,
-
scale_arg);
- return true;
- }
-
- return false;
- };
-
-#if !defined(__SSE4_1__) && !defined(__aarch64__)
- /// In case of "nearbyint" function is used, we should ensure the
expected rounding mode for the Banker's rounding.
- /// Actually it is by default. But we will set it just in case.
-
- if constexpr (rounding_mode == RoundingMode::Round) {
- if (0 != fesetround(FE_TONEAREST)) {
- return Status::InvalidArgument("Cannot set floating point
rounding mode");
- }
- }
-#endif
-
- if
(!call_on_index_and_data_type<void>(column_general.type->get_type_id(), call)) {
- return Status::InvalidArgument("Invalid argument type {} for
function {}",
-
column_general.type->get_name(), "truncate");
- }
- // Important, make sure the result column has the same size as the
input column
- res = ColumnConst::create(std::move(res), input_rows_count);
- } else if (arguments.size() == 1 ||
- (arguments.size() == 2 &&
-
is_column_const(*block.get_by_position(arguments[1]).column))) {
- // truncate(Column) or truncate(Column, ColumnConst)
- Int16 scale_arg = 0;
- if (arguments.size() == 2) {
- RETURN_IF_ERROR(FunctionTruncate<Impl>::get_scale_arg(
- block.get_by_position(arguments[1]), &scale_arg));
- }
-
- auto call = [&](const auto& types) -> bool {
- using Types = std::decay_t<decltype(types)>;
- using DataType = typename Types::LeftType;
-
- if constexpr (IsDataTypeNumber<DataType> ||
IsDataTypeDecimal<DataType>) {
- using FieldType = typename DataType::FieldType;
- res = Dispatcher<FieldType, RoundingMode::Trunc,
TieBreakingMode::Auto>::
- apply_vec_const(column_general.column.get(),
scale_arg);
- return true;
- }
-
- return false;
- };
-#if !defined(__SSE4_1__) && !defined(__aarch64__)
- /// In case of "nearbyint" function is used, we should ensure the
expected rounding mode for the Banker's rounding.
- /// Actually it is by default. But we will set it just in case.
-
- if constexpr (rounding_mode == RoundingMode::Round) {
- if (0 != fesetround(FE_TONEAREST)) {
- return Status::InvalidArgument("Cannot set floating point
rounding mode");
- }
- }
-#endif
-
- if
(!call_on_index_and_data_type<void>(column_general.type->get_type_id(), call)) {
- return Status::InvalidArgument("Invalid argument type {} for
function {}",
-
column_general.type->get_name(), "truncate");
- }
-
- } else if
(is_column_const(*block.get_by_position(arguments[0]).column)) {
- // truncate(ColumnConst, Column)
- const ColumnWithTypeAndName& column_scale =
block.get_by_position(arguments[1]);
- const ColumnConst& const_col_general =
- assert_cast<const ColumnConst&>(*column_general.column);
-
- auto call = [&](const auto& types) -> bool {
- using Types = std::decay_t<decltype(types)>;
- using DataType = typename Types::LeftType;
-
- if constexpr (IsDataTypeNumber<DataType> ||
IsDataTypeDecimal<DataType>) {
- using FieldType = typename DataType::FieldType;
- res = Dispatcher<FieldType, RoundingMode::Trunc,
TieBreakingMode::Auto>::
- apply_const_vec(&const_col_general,
column_scale.column.get());
- return true;
- }
-
- return false;
- };
-
-#if !defined(__SSE4_1__) && !defined(__aarch64__)
- /// In case of "nearbyint" function is used, we should ensure the
expected rounding mode for the Banker's rounding.
- /// Actually it is by default. But we will set it just in case.
-
- if constexpr (rounding_mode == RoundingMode::Round) {
- if (0 != fesetround(FE_TONEAREST)) {
- return Status::InvalidArgument("Cannot set floating point
rounding mode");
- }
- }
-#endif
-
- if
(!call_on_index_and_data_type<void>(column_general.type->get_type_id(), call)) {
- return Status::InvalidArgument("Invalid argument type {} for
function {}",
-
column_general.type->get_name(), "truncate");
- }
- } else {
- // truncate(Column, Column)
- const ColumnWithTypeAndName& column_scale =
block.get_by_position(arguments[1]);
-
- auto call = [&](const auto& types) -> bool {
- using Types = std::decay_t<decltype(types)>;
- using DataType = typename Types::LeftType;
-
- if constexpr (IsDataTypeNumber<DataType> ||
IsDataTypeDecimal<DataType>) {
- using FieldType = typename DataType::FieldType;
- res = Dispatcher<FieldType, RoundingMode::Trunc,
TieBreakingMode::Auto>::
- apply_vec_vec(column_general.column.get(),
column_scale.column.get());
- return true;
- }
- return false;
- };
-
-#if !defined(__SSE4_1__) && !defined(__aarch64__)
- /// In case of "nearbyint" function is used, we should ensure the
expected rounding mode for the Banker's rounding.
- /// Actually it is by default. But we will set it just in case.
-
- if constexpr (rounding_mode == RoundingMode::Round) {
- if (0 != fesetround(FE_TONEAREST)) {
- return Status::InvalidArgument("Cannot set floating point
rounding mode");
- }
- }
-#endif
-
- if
(!call_on_index_and_data_type<void>(column_general.type->get_type_id(), call)) {
- return Status::InvalidArgument("Invalid argument type {} for
function {}",
-
column_general.type->get_name(), "truncate");
- }
- }
-
- block.replace_by_position(result, std::move(res));
- return Status::OK();
- }
-};
-
-} // namespace doris::vectorized
diff --git a/be/src/vec/functions/math.cpp b/be/src/vec/functions/math.cpp
index c0dfe761576..bc086ce4447 100644
--- a/be/src/vec/functions/math.cpp
+++ b/be/src/vec/functions/math.cpp
@@ -15,29 +15,20 @@
// specific language governing permissions and limitations
// under the License.
-#include <stdint.h>
-#include <string.h>
+#include <cstdint>
+#include <cstring>
-#include <boost/iterator/iterator_facade.hpp>
// IWYU pragma: no_include <bits/std_abs.h>
-#include <algorithm>
#include <cmath>
-#include <memory>
#include <string>
#include <type_traits>
-#include <utility>
#include "common/status.h"
-#include "vec/aggregate_functions/aggregate_function.h"
#include "vec/columns/column.h"
#include "vec/columns/column_string.h"
#include "vec/columns/column_vector.h"
#include "vec/columns/columns_number.h"
#include "vec/core/types.h"
-#include "vec/data_types/data_type.h"
-#include "vec/data_types/data_type_decimal.h"
-#include "vec/data_types/data_type_nullable.h"
-#include "vec/data_types/data_type_number.h"
#include "vec/data_types/data_type_string.h"
#include "vec/data_types/number_traits.h"
#include "vec/functions/function_binary_arithmetic.h"
@@ -46,9 +37,7 @@
#include "vec/functions/function_math_unary.h"
#include "vec/functions/function_string.h"
#include "vec/functions/function_totype.h"
-#include "vec/functions/function_truncate.h"
#include "vec/functions/function_unary_arithmetic.h"
-#include "vec/functions/round.h"
#include "vec/functions/simple_function_factory.h"
namespace doris {
@@ -330,92 +319,15 @@ struct PowName {
};
using FunctionPow = FunctionBinaryArithmetic<PowImpl, PowName, false>;
-struct TruncateName {
- static constexpr auto name = "truncate";
-};
-
-struct CeilName {
- static constexpr auto name = "ceil";
-};
-
-struct FloorName {
- static constexpr auto name = "floor";
-};
-
-struct RoundName {
- static constexpr auto name = "round";
-};
-
-struct RoundBankersName {
- static constexpr auto name = "round_bankers";
-};
-
-/// round(double,int32)-->double
-/// key_str:roundFloat64Int32
-template <typename Name>
-struct DoubleRoundTwoImpl {
- static constexpr auto name = Name::name;
-
- static DataTypes get_variadic_argument_types() {
- return {std::make_shared<vectorized::DataTypeFloat64>(),
- std::make_shared<vectorized::DataTypeInt32>()};
- }
-};
-
-template <typename Name>
-struct DoubleRoundOneImpl {
- static constexpr auto name = Name::name;
-
- static DataTypes get_variadic_argument_types() {
- return {std::make_shared<vectorized::DataTypeFloat64>()};
- }
-};
-
-template <typename Name>
-struct DecimalRoundTwoImpl {
- static constexpr auto name = Name::name;
-
- static DataTypes get_variadic_argument_types() {
- return {std::make_shared<vectorized::DataTypeDecimal<Decimal32>>(9, 0),
- std::make_shared<vectorized::DataTypeInt32>()};
- }
-};
-
-template <typename Name>
-struct DecimalRoundOneImpl {
- static constexpr auto name = Name::name;
-
- static DataTypes get_variadic_argument_types() {
- return {std::make_shared<vectorized::DataTypeDecimal<Decimal32>>(9,
0)};
- }
-};
-
// TODO: Now math may cause one thread compile time too long, because the
function in math
// so mush. Split it to speed up compile time in the future
void register_function_math(SimpleFunctionFactory& factory) {
-#define REGISTER_ROUND_FUNCTIONS(IMPL)
\
- factory.register_function<
\
- FunctionRounding<IMPL<RoundName>, RoundingMode::Round,
TieBreakingMode::Auto>>(); \
- factory.register_function<
\
- FunctionRounding<IMPL<FloorName>, RoundingMode::Floor,
TieBreakingMode::Auto>>(); \
- factory.register_function<
\
- FunctionRounding<IMPL<CeilName>, RoundingMode::Ceil,
TieBreakingMode::Auto>>(); \
- factory.register_function<FunctionRounding<IMPL<RoundBankersName>,
RoundingMode::Round, \
- TieBreakingMode::Bankers>>();
-
- REGISTER_ROUND_FUNCTIONS(DecimalRoundOneImpl)
- REGISTER_ROUND_FUNCTIONS(DecimalRoundTwoImpl)
- REGISTER_ROUND_FUNCTIONS(DoubleRoundOneImpl)
- REGISTER_ROUND_FUNCTIONS(DoubleRoundTwoImpl)
- factory.register_alias("round", "dround");
factory.register_function<FunctionAcos>();
factory.register_function<FunctionAsin>();
factory.register_function<FunctionAtan>();
factory.register_function<FunctionAtan2>();
factory.register_function<FunctionCos>();
factory.register_function<FunctionCosh>();
- factory.register_alias("ceil", "dceil");
- factory.register_alias("ceil", "ceiling");
factory.register_function<FunctionE>();
factory.register_alias("ln", "dlog1");
factory.register_function<FunctionLog>();
@@ -434,7 +346,6 @@ void register_function_math(SimpleFunctionFactory& factory)
{
factory.register_function<FunctionCbrt>();
factory.register_function<FunctionTan>();
factory.register_function<FunctionTanh>();
- factory.register_alias("floor", "dfloor");
factory.register_function<FunctionPow>();
factory.register_alias("pow", "power");
factory.register_alias("pow", "dpow");
@@ -444,9 +355,5 @@ void register_function_math(SimpleFunctionFactory& factory)
{
factory.register_function<FunctionRadians>();
factory.register_function<FunctionDegrees>();
factory.register_function<FunctionBin>();
- factory.register_function<FunctionTruncate<TruncateFloatOneArgImpl>>();
- factory.register_function<FunctionTruncate<TruncateFloatTwoArgImpl>>();
- factory.register_function<FunctionTruncate<TruncateDecimalOneArgImpl>>();
- factory.register_function<FunctionTruncate<TruncateDecimalTwoArgImpl>>();
}
} // namespace doris::vectorized
diff --git a/be/src/vec/functions/round.cpp b/be/src/vec/functions/round.cpp
new file mode 100644
index 00000000000..6b6fc42d653
--- /dev/null
+++ b/be/src/vec/functions/round.cpp
@@ -0,0 +1,50 @@
+// 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 "round.h"
+
+#include "vec/functions/simple_function_factory.h"
+
+namespace doris::vectorized {
+
+// We split round funcs from register_function_math() in math.cpp to here,
+// so that to speed up compile time and make code more readable.
+void register_function_round(SimpleFunctionFactory& factory) {
+#define REGISTER_ROUND_FUNCTIONS(IMPL)
\
+ factory.register_function<
\
+ FunctionRounding<IMPL<TruncateName>, RoundingMode::Trunc,
TieBreakingMode::Auto>>(); \
+ factory.register_function<
\
+ FunctionRounding<IMPL<FloorName>, RoundingMode::Floor,
TieBreakingMode::Auto>>(); \
+ factory.register_function<
\
+ FunctionRounding<IMPL<RoundName>, RoundingMode::Round,
TieBreakingMode::Auto>>(); \
+ factory.register_function<
\
+ FunctionRounding<IMPL<CeilName>, RoundingMode::Ceil,
TieBreakingMode::Auto>>(); \
+ factory.register_function<FunctionRounding<IMPL<RoundBankersName>,
RoundingMode::Round, \
+ TieBreakingMode::Bankers>>();
+
+ REGISTER_ROUND_FUNCTIONS(DecimalRoundOneImpl)
+ REGISTER_ROUND_FUNCTIONS(DecimalRoundTwoImpl)
+ REGISTER_ROUND_FUNCTIONS(DoubleRoundOneImpl)
+ REGISTER_ROUND_FUNCTIONS(DoubleRoundTwoImpl)
+
+ factory.register_alias("ceil", "dceil");
+ factory.register_alias("ceil", "ceiling");
+ factory.register_alias("floor", "dfloor");
+ factory.register_alias("round", "dround");
+}
+
+} // namespace doris::vectorized
diff --git a/be/src/vec/functions/round.h b/be/src/vec/functions/round.h
index a9d1e7a019c..70d41bc5fe0 100644
--- a/be/src/vec/functions/round.h
+++ b/be/src/vec/functions/round.h
@@ -21,7 +21,6 @@
#pragma once
#include <cstddef>
-#include <cstdint>
#include "common/exception.h"
#include "common/status.h"
@@ -184,8 +183,6 @@ public:
}
}
- // NOTE: This function is only tested for truncate
- // DO NOT USE THIS METHOD FOR OTHER ROUNDING BASED FUNCTION UNTIL YOU KNOW
EXACTLY WHAT YOU ARE DOING !!!
static NO_INLINE void apply(const NativeType& in, UInt32 in_scale,
NativeType& out,
Int16 out_scale) {
Int16 scale_arg = in_scale - out_scale;
@@ -480,15 +477,8 @@ struct Dispatcher {
}
}
- // NOTE: This function is only tested for truncate
- // DO NOT USE THIS METHOD FOR OTHER ROUNDING BASED FUNCTION UNTIL YOU KNOW
EXACTLY WHAT YOU ARE DOING !!!
static ColumnPtr apply_vec_vec(const IColumn* col_general, const IColumn*
col_scale) {
- if constexpr (rounding_mode != RoundingMode::Trunc) {
- throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
- "Using column as scale is only supported
for function truncate");
- }
-
- const ColumnInt32& col_scale_i32 = assert_cast<const
ColumnInt32&>(*col_scale);
+ const auto& col_scale_i32 = assert_cast<const
ColumnInt32&>(*col_scale);
const size_t input_row_count = col_scale_i32.size();
for (size_t i = 0; i < input_row_count; ++i) {
const Int32 scale_arg = col_scale_i32.get_data()[i];
@@ -526,7 +516,7 @@ struct Dispatcher {
} else if constexpr (IsDecimalNumber<T>) {
const auto* decimal_col = assert_cast<const
ColumnDecimal<T>*>(col_general);
- // For truncate, ALWAYS use SAME scale with source Decimal column
+ // ALWAYS use SAME scale with source Decimal column
const Int32 input_scale = decimal_col->get_scale();
auto col_res = ColumnDecimal<T>::create(input_row_count,
input_scale);
@@ -537,7 +527,7 @@ struct Dispatcher {
}
for (size_t i = 0; i < input_row_count; ++i) {
- // For truncate(ColumnDecimal, ColumnInt32), we should always
have same scale with source Decimal column
+ // For func(ColumnDecimal, ColumnInt32), we should always have
same scale with source Decimal column
// So we need this check to make sure the result have correct
digits count
//
// Case 0: scale_arg <= -(integer part digits count)
@@ -564,16 +554,9 @@ struct Dispatcher {
}
}
- // NOTE: This function is only tested for truncate
- // DO NOT USE THIS METHOD FOR OTHER ROUNDING BASED FUNCTION UNTIL YOU KNOW
EXACTLY WHAT YOU ARE DOING !!! only test for truncate
static ColumnPtr apply_const_vec(const ColumnConst* const_col_general,
const IColumn* col_scale) {
- if constexpr (rounding_mode != RoundingMode::Trunc) {
- throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
- "Using column as scale is only supported
for function truncate");
- }
-
- const ColumnInt32& col_scale_i32 = assert_cast<const
ColumnInt32&>(*col_scale);
+ const auto& col_scale_i32 = assert_cast<const
ColumnInt32&>(*col_scale);
const size_t input_rows_count = col_scale->size();
for (size_t i = 0; i < input_rows_count; ++i) {
@@ -602,7 +585,7 @@ struct Dispatcher {
}
for (size_t i = 0; i < input_rows_count; ++i) {
- // For truncate(ColumnDecimal, ColumnInt32), we should always
have same scale with source Decimal column
+ // For func(ColumnDecimal, ColumnInt32), we should always have
same scale with source Decimal column
// So we need this check to make sure the result have correct
digits count
//
// Case 0: scale_arg <= -(integer part digits count)
@@ -647,9 +630,9 @@ struct Dispatcher {
return col_res;
} else {
- throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
- "Unsupported column {} for function
truncate",
- const_col_general->get_name());
+ LOG(FATAL) << "__builtin_unreachable";
+ __builtin_unreachable();
+ return nullptr;
}
}
};
@@ -696,34 +679,73 @@ public:
return Status::OK();
}
- ColumnNumbers get_arguments_that_are_always_constant() const override {
return {1}; }
+ /// SELECT number, truncate(123.345, 1) FROM number("numbers"="10")
+ /// should NOT behave like two column arguments, so we can not use const
column default implementation
+ bool use_default_implementation_for_constants() const override { return
false; }
+ //// We moved and optimized the execute_impl logic of function_truncate.h
from PR#32746,
+ //// as well as make it suitable for all functions.
Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
- size_t result, size_t /*input_rows_count*/) const
override {
- const ColumnWithTypeAndName& column =
block.get_by_position(arguments[0]);
- Int16 scale_arg = 0;
- if (arguments.size() == 2) {
- RETURN_IF_ERROR(get_scale_arg(block.get_by_position(arguments[1]),
&scale_arg));
- }
+ size_t result, size_t input_rows_count) const override
{
+ const ColumnWithTypeAndName& column_general =
block.get_by_position(arguments[0]);
+ const bool is_col_general_const =
is_column_const(*column_general.column);
+ const auto* col_general = is_col_general_const
+ ? assert_cast<const
ColumnConst&>(*column_general.column)
+ .get_data_column_ptr()
+ : column_general.column.get();
ColumnPtr res;
+
+ /// potential argument types:
+ /// if the SECOND argument is MISSING(would be considered as ZERO
const) or CONST, then we have the following type:
+ /// 1. func(Column), func(ColumnConst), func(Column, ColumnConst),
func(ColumnConst, ColumnConst)
+ /// otherwise, the SECOND arugment is COLUMN, we have another type:
+ /// 2. func(Column, Column), func(ColumnConst, Column)
+
auto call = [&](const auto& types) -> bool {
using Types = std::decay_t<decltype(types)>;
using DataType = typename Types::LeftType;
if constexpr (IsDataTypeNumber<DataType> ||
IsDataTypeDecimal<DataType>) {
using FieldType = typename DataType::FieldType;
- res = Dispatcher<FieldType, rounding_mode,
tie_breaking_mode>::apply_vec_const(
- column.column.get(), scale_arg);
+ if (arguments.size() == 1 ||
+
is_column_const(*block.get_by_position(arguments[1]).column)) {
+ // the SECOND argument is MISSING or CONST
+ Int16 scale_arg = 0;
+ if (arguments.size() == 2) {
+ RETURN_IF_ERROR(
+
get_scale_arg(block.get_by_position(arguments[1]), &scale_arg));
+ }
+
+ res = Dispatcher<FieldType, rounding_mode,
tie_breaking_mode>::apply_vec_const(
+ col_general, scale_arg);
+
+ if (arguments.size() == 2 && is_col_general_const) {
+ // Important, make sure the result column has the same
size as the input column
+ res = ColumnConst::create(std::move(res),
input_rows_count);
+ }
+ } else {
+ // the SECOND arugment is COLUMN
+ if (is_col_general_const) {
+ res = Dispatcher<FieldType, rounding_mode,
tie_breaking_mode>::
+ apply_const_vec(
+ &assert_cast<const
ColumnConst&>(*column_general.column),
+
block.get_by_position(arguments[1]).column.get());
+ } else {
+ res = Dispatcher<FieldType, rounding_mode,
tie_breaking_mode>::
+ apply_vec_vec(col_general,
+
block.get_by_position(arguments[1]).column.get());
+ }
+ }
return true;
}
+
return false;
};
#if !defined(__SSE4_1__) && !defined(__aarch64__)
/// In case of "nearbyint" function is used, we should ensure the
expected rounding mode for the Banker's rounding.
/// Actually it is by default. But we will set it just in case.
-
if constexpr (rounding_mode == RoundingMode::Round) {
if (0 != fesetround(FE_TONEAREST)) {
return Status::InvalidArgument("Cannot set floating point
rounding mode");
@@ -731,9 +753,9 @@ public:
}
#endif
- if (!call_on_index_and_data_type<void>(column.type->get_type_id(),
call)) {
+ if
(!call_on_index_and_data_type<void>(column_general.type->get_type_id(), call)) {
return Status::InvalidArgument("Invalid argument type {} for
function {}",
- column.type->get_name(), name);
+ column_general.type->get_name(),
name);
}
block.replace_by_position(result, std::move(res));
@@ -741,4 +763,64 @@ public:
}
};
+struct TruncateName {
+ static constexpr auto name = "truncate";
+};
+
+struct FloorName {
+ static constexpr auto name = "floor";
+};
+
+struct CeilName {
+ static constexpr auto name = "ceil";
+};
+
+struct RoundName {
+ static constexpr auto name = "round";
+};
+
+struct RoundBankersName {
+ static constexpr auto name = "round_bankers";
+};
+
+/// round(double,int32)-->double
+/// key_str:roundFloat64Int32
+template <typename Name>
+struct DoubleRoundTwoImpl {
+ static constexpr auto name = Name::name;
+
+ static DataTypes get_variadic_argument_types() {
+ return {std::make_shared<vectorized::DataTypeFloat64>(),
+ std::make_shared<vectorized::DataTypeInt32>()};
+ }
+};
+
+template <typename Name>
+struct DoubleRoundOneImpl {
+ static constexpr auto name = Name::name;
+
+ static DataTypes get_variadic_argument_types() {
+ return {std::make_shared<vectorized::DataTypeFloat64>()};
+ }
+};
+
+template <typename Name>
+struct DecimalRoundTwoImpl {
+ static constexpr auto name = Name::name;
+
+ static DataTypes get_variadic_argument_types() {
+ return {std::make_shared<vectorized::DataTypeDecimal<Decimal32>>(9, 0),
+ std::make_shared<vectorized::DataTypeInt32>()};
+ }
+};
+
+template <typename Name>
+struct DecimalRoundOneImpl {
+ static constexpr auto name = Name::name;
+
+ static DataTypes get_variadic_argument_types() {
+ return {std::make_shared<vectorized::DataTypeDecimal<Decimal32>>(9,
0)};
+ }
+};
+
} // namespace doris::vectorized
diff --git a/be/src/vec/functions/simple_function_factory.h
b/be/src/vec/functions/simple_function_factory.h
index 052e2e89134..889a9743635 100644
--- a/be/src/vec/functions/simple_function_factory.h
+++ b/be/src/vec/functions/simple_function_factory.h
@@ -46,6 +46,7 @@ void register_function_int_div(SimpleFunctionFactory&
factory);
void register_function_bit(SimpleFunctionFactory& factory);
void register_function_bit_count(SimpleFunctionFactory& factory);
void register_function_bit_shift(SimpleFunctionFactory& factory);
+void register_function_round(SimpleFunctionFactory& factory);
void register_function_math(SimpleFunctionFactory& factory);
void register_function_modulo(SimpleFunctionFactory& factory);
void register_function_bitmap(SimpleFunctionFactory& factory);
@@ -226,6 +227,7 @@ public:
register_function_conv(instance);
register_function_plus(instance);
register_function_minus(instance);
+ register_function_round(instance);
register_function_math(instance);
register_function_multiply(instance);
register_function_divide(instance);
diff --git a/be/test/vec/function/function_round_test.cpp
b/be/test/vec/function/function_round_test.cpp
new file mode 100644
index 00000000000..10ad1c2c0f1
--- /dev/null
+++ b/be/test/vec/function/function_round_test.cpp
@@ -0,0 +1,1133 @@
+// 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 <climits>
+#include <cmath>
+#include <cstddef>
+#include <map>
+#include <memory>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "function_test_util.h"
+#include "vec/columns/column.h"
+#include "vec/columns/column_const.h"
+#include "vec/columns/column_decimal.h"
+#include "vec/columns/columns_number.h"
+#include "vec/common/assert_cast.h"
+#include "vec/core/column_numbers.h"
+#include "vec/core/types.h"
+#include "vec/data_types/data_type_decimal.h"
+#include "vec/data_types/data_type_number.h"
+#include "vec/functions/round.h"
+
+/**
+ This BE UT focus on enhancement of round based function, which enables them
+ to use column as scale argument. We test
truncate/floor/ceil/round/round_bankers
+ together by moving test cases of function_truncate_test.cpp here.
+*/
+
+namespace doris::vectorized {
+// {precision, scale} -> {input, scale_arg, expectation}
+using DecimalTestDataSet =
+ std::map<std::pair<int, int>, std::vector<std::tuple<Int128, int,
Int128>>>;
+
+// input, scale_arg, expectation
+using FloatTestDataSet = std::vector<std::tuple<Float64, int, Float64>>;
+
+using DecimalTruncateFunction =
FunctionRounding<DecimalRoundTwoImpl<TruncateName>,
+ RoundingMode::Trunc,
TieBreakingMode::Auto>;
+using DecimalFloorFunction = FunctionRounding<DecimalRoundTwoImpl<FloorName>,
RoundingMode::Floor,
+ TieBreakingMode::Auto>;
+using DecimalCeilFunction =
+ FunctionRounding<DecimalRoundTwoImpl<CeilName>, RoundingMode::Ceil,
TieBreakingMode::Auto>;
+using DecimalRoundFunction = FunctionRounding<DecimalRoundTwoImpl<RoundName>,
RoundingMode::Round,
+ TieBreakingMode::Auto>;
+using DecimalRoundBankersFunction =
FunctionRounding<DecimalRoundTwoImpl<RoundBankersName>,
+ RoundingMode::Round,
TieBreakingMode::Bankers>;
+
+using FloatTruncateFunction =
FunctionRounding<DoubleRoundTwoImpl<TruncateName>,
+ RoundingMode::Trunc,
TieBreakingMode::Auto>;
+using FloatFloorFunction =
+ FunctionRounding<DoubleRoundTwoImpl<FloorName>, RoundingMode::Floor,
TieBreakingMode::Auto>;
+using FloatCeilFunction =
+ FunctionRounding<DoubleRoundTwoImpl<CeilName>, RoundingMode::Ceil,
TieBreakingMode::Auto>;
+using FloatRoundFunction =
+ FunctionRounding<DoubleRoundTwoImpl<RoundName>, RoundingMode::Round,
TieBreakingMode::Auto>;
+using FloatRoundBankersFunction =
FunctionRounding<DoubleRoundTwoImpl<RoundBankersName>,
+ RoundingMode::Round,
TieBreakingMode::Bankers>;
+
+// test cases for truncate and floor function of decimal32
+const static DecimalTestDataSet trunc_floor_decimal32_cases = {
+ {{1, 0},
+ {
+ {1, -10, 0}, {1, -9, 0}, {1, -8, 0}, {1, -7, 0}, {1, -6, 0},
{1, -5, 0},
+ {1, -4, 0}, {1, -3, 0}, {1, -2, 0}, {1, -1, 0}, {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, 0}, {1, -7, 0}, {1, -6, 0},
{1, -5, 0},
+ {1, -4, 0}, {1, -3, 0}, {1, -2, 0}, {1, -1, 0}, {1, 0, 0},
{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, 0},
+ {12, -3, 0},
+ {12, -2, 0},
+ {12, -1, 10},
+ {12, 0, 12},
+ {12, 1, 12},
+ {12, 2, 12},
+ {12, 3, 12},
+ {12, 4, 12},
+ }},
+ {{2, 1},
+ {
+ {12, -4, 0},
+ {12, -3, 0},
+ {12, -2, 0},
+ {12, -1, 0},
+ {12, 0, 10},
+ {12, 1, 12},
+ {12, 2, 12},
+ {12, 3, 12},
+ {12, 4, 12},
+ }},
+ {{2, 2},
+ {
+ {12, -4, 0},
+ {12, -3, 0},
+ {12, -2, 0},
+ {12, -1, 0},
+ {12, 0, 0},
+ {12, 1, 10},
+ {12, 2, 12},
+ {12, 3, 12},
+ {12, 4, 12},
+ }},
+ {{9, 0},
+ {
+ {123456789, -10, 0}, {123456789, -9, 0},
{123456789, -8, 100000000},
+ {123456789, -7, 120000000}, {123456789, -6, 123000000},
{123456789, -5, 123400000},
+ {123456789, -4, 123450000}, {123456789, -3, 123456000},
{123456789, -2, 123456700},
+ {123456789, -1, 123456780}, {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, 0},
+ {123456789, -7, 100000000}, {123456789, -6, 120000000},
{123456789, -5, 123000000},
+ {123456789, -4, 123400000}, {123456789, -3, 123450000},
{123456789, -2, 123456000},
+ {123456789, -1, 123456700}, {123456789, 0, 123456780},
{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, 0}, {123456789, -6, 100000000},
{123456789, -5, 120000000},
+ {123456789, -4, 123000000}, {123456789, -3, 123400000},
{123456789, -2, 123450000},
+ {123456789, -1, 123456000}, {123456789, 0, 123456700},
{123456789, 1, 123456780},
+ {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, 0},
{123456789, -5, 100000000},
+ {123456789, -4, 120000000}, {123456789, -3, 123000000},
{123456789, -2, 123400000},
+ {123456789, -1, 123450000}, {123456789, 0, 123456000},
{123456789, 1, 123456700},
+ {123456789, 2, 123456780}, {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, 0},
+ {123456789, -4, 100000000}, {123456789, -3, 120000000},
{123456789, -2, 123000000},
+ {123456789, -1, 123400000}, {123456789, 0, 123450000},
{123456789, 1, 123456000},
+ {123456789, 2, 123456700}, {123456789, 3, 123456780},
{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, 0}, {123456789, -3, 100000000},
{123456789, -2, 120000000},
+ {123456789, -1, 123000000}, {123456789, 0, 123400000},
{123456789, 1, 123450000},
+ {123456789, 2, 123456000}, {123456789, 3, 123456700},
{123456789, 4, 123456780},
+ {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, 0},
{123456789, -2, 100000000},
+ {123456789, -1, 120000000}, {123456789, 0, 123000000},
{123456789, 1, 123400000},
+ {123456789, 2, 123450000}, {123456789, 3, 123456000},
{123456789, 4, 123456700},
+ {123456789, 5, 123456780}, {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, 0},
+ {123456789, -1, 100000000}, {123456789, 0, 120000000},
{123456789, 1, 123000000},
+ {123456789, 2, 123400000}, {123456789, 3, 123450000},
{123456789, 4, 123456000},
+ {123456789, 5, 123456700}, {123456789, 6, 123456780},
{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, 0}, {123456789, 0, 100000000},
{123456789, 1, 120000000},
+ {123456789, 2, 123000000}, {123456789, 3, 123400000},
{123456789, 4, 123450000},
+ {123456789, 5, 123456000}, {123456789, 6, 123456700},
{123456789, 7, 123456780},
+ {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, 0},
{123456789, 1, 100000000},
+ {123456789, 2, 120000000}, {123456789, 3, 123000000},
{123456789, 4, 123400000},
+ {123456789, 5, 123450000}, {123456789, 6, 123456000},
{123456789, 7, 123456700},
+ {123456789, 8, 123456780}, {123456789, 9, 123456789},
{123456789, 10, 123456789},
+ }}};
+
+// test cases for truncate and floor function of decimal64
+const static DecimalTestDataSet trunc_floor_decimal64_cases = {
+ {{10, 0},
+ {{1234567891, -11, 0}, {1234567891, -10, 0},
{1234567891, -9, 1000000000},
+ {1234567891, -8, 1200000000}, {1234567891, -7, 1230000000},
{1234567891, -6, 1234000000},
+ {1234567891, -5, 1234500000}, {1234567891, -4, 1234560000},
{1234567891, -3, 1234567000},
+ {1234567891, -2, 1234567800}, {1234567891, -1, 1234567890},
{1234567891, 0, 1234567891},
+ {1234567891, 1, 1234567891}, {1234567891, 2, 1234567891},
{1234567891, 3, 1234567891},
+ {1234567891, 4, 1234567891}, {1234567891, 5, 1234567891},
{1234567891, 6, 1234567891},
+ {1234567891, 7, 1234567891}, {1234567891, 8, 1234567891},
{1234567891, 9, 1234567891},
+ {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}}},
+ {{10, 1},
+ {{1234567891, -11, 0}, {1234567891, -10, 0},
{1234567891, -9, 0},
+ {1234567891, -8, 1000000000}, {1234567891, -7, 1200000000},
{1234567891, -6, 1230000000},
+ {1234567891, -5, 1234000000}, {1234567891, -4, 1234500000},
{1234567891, -3, 1234560000},
+ {1234567891, -2, 1234567000}, {1234567891, -1, 1234567800},
{1234567891, 0, 1234567890},
+ {1234567891, 1, 1234567891}, {1234567891, 2, 1234567891},
{1234567891, 3, 1234567891},
+ {1234567891, 4, 1234567891}, {1234567891, 5, 1234567891},
{1234567891, 6, 1234567891},
+ {1234567891, 7, 1234567891}, {1234567891, 8, 1234567891},
{1234567891, 9, 1234567891},
+ {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}
+
+ }},
+ {{10, 2},
+ {{1234567891, -11, 0}, {1234567891, -10, 0},
{1234567891, -9, 0},
+ {1234567891, -8, 0}, {1234567891, -7, 1000000000},
{1234567891, -6, 1200000000},
+ {1234567891, -5, 1230000000}, {1234567891, -4, 1234000000},
{1234567891, -3, 1234500000},
+ {1234567891, -2, 1234560000}, {1234567891, -1, 1234567000},
{1234567891, 0, 1234567800},
+ {1234567891, 1, 1234567890}, {1234567891, 2, 1234567891},
{1234567891, 3, 1234567891},
+ {1234567891, 4, 1234567891}, {1234567891, 5, 1234567891},
{1234567891, 6, 1234567891},
+ {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, 0},
+ {1234567891, -8, 0}, {1234567891, -7, 0},
{1234567891, -6, 0},
+ {1234567891, -5, 0}, {1234567891, -4, 0},
{1234567891, -3, 0},
+ {1234567891, -2, 0}, {1234567891, -1, 0},
{1234567891, 0, 1000000000},
+ {1234567891, 1, 1200000000}, {1234567891, 2, 1230000000},
{1234567891, 3, 1234000000},
+ {1234567891, 4, 1234500000}, {1234567891, 5, 1234560000},
{1234567891, 6, 1234567000},
+ {1234567891, 7, 1234567800}, {1234567891, 8, 1234567890},
{1234567891, 9, 1234567891},
+ {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}}},
+ {{18, 0},
+ {{123456789123456789, -19, 0},
+ {123456789123456789, -18, 0},
+ {123456789123456789, -17, 100000000000000000},
+ {123456789123456789, -16, 120000000000000000},
+ {123456789123456789, -15, 123000000000000000},
+ {123456789123456789, -14, 123400000000000000},
+ {123456789123456789, -13, 123450000000000000},
+ {123456789123456789, -12, 123456000000000000},
+ {123456789123456789, -11, 123456700000000000},
+ {123456789123456789, -10, 123456780000000000},
+ {123456789123456789, -9, 123456789000000000},
+ {123456789123456789, -8, 123456789100000000},
+ {123456789123456789, -7, 123456789120000000},
+ {123456789123456789, -6, 123456789123000000},
+ {123456789123456789, -5, 123456789123400000},
+ {123456789123456789, -4, 123456789123450000},
+ {123456789123456789, -3, 123456789123456000},
+ {123456789123456789, -2, 123456789123456700},
+ {123456789123456789, -1, 123456789123456780},
+ {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, 0},
+ {123456789123456789, 1, 100000000000000000},
+ {123456789123456789, 2, 120000000000000000},
+ {123456789123456789, 3, 123000000000000000},
+ {123456789123456789, 4, 123400000000000000},
+ {123456789123456789, 5, 123450000000000000},
+ {123456789123456789, 6, 123456000000000000},
+ {123456789123456789, 7, 123456700000000000},
+ {123456789123456789, 8, 123456780000000000},
+ {123456789123456789, 9, 123456789000000000},
+ {123456789123456789, 10, 123456789100000000},
+ {123456789123456789, 11, 123456789120000000},
+ {123456789123456789, 12, 123456789123000000},
+ {123456789123456789, 13, 123456789123400000},
+ {123456789123456789, 14, 123456789123450000},
+ {123456789123456789, 15, 123456789123456000},
+ {123456789123456789, 16, 123456789123456700},
+ {123456789123456789, 17, 123456789123456780},
+ {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}}}};
+
+// 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, 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},
+ }},
+ {{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},
+ }},
+ {{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},
+ }},
+ {{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},
+ }},
+ {{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},
+ }},
+ {{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},
+ }},
+ {{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},
+ }},
+ {{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},
+ }},
+ {{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},
+ }},
+ {{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},
+ }},
+ {{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},
+ }},
+ {{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},
+ }},
+ {{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},
+ }},
+ {{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},
+ }}};
+
+// test cases for ceil function of decimal64
+const static DecimalTestDataSet ceil_decimal64_cases = {
+ {{10, 0}, {{1234567891, -11, 100000000000}, {1234567891, -10,
10000000000},
+ {1234567891, -9, 2000000000}, {1234567891, -8,
1300000000},
+ {1234567891, -7, 1240000000}, {1234567891, -6,
1235000000},
+ {1234567891, -5, 1234600000}, {1234567891, -4,
1234570000},
+ {1234567891, -3, 1234568000}, {1234567891, -2,
1234567900},
+ {1234567891, -1, 1234567900}, {1234567891, 0,
1234567891},
+ {1234567891, 1, 1234567891}, {1234567891, 2,
1234567891},
+ {1234567891, 3, 1234567891}, {1234567891, 4,
1234567891},
+ {1234567891, 5, 1234567891}, {1234567891, 6,
1234567891},
+ {1234567891, 7, 1234567891}, {1234567891, 8,
1234567891},
+ {1234567891, 9, 1234567891}, {1234567891, 10,
1234567891},
+ {1234567891, 11, 1234567891}}},
+ {{10, 1}, {{1234567891, -11, 1000000000000}, {1234567891, -10,
100000000000},
+ {1234567891, -9, 10000000000}, {1234567891, -8,
2000000000},
+ {1234567891, -7, 1300000000}, {1234567891, -6,
1240000000},
+ {1234567891, -5, 1235000000}, {1234567891, -4,
1234600000},
+ {1234567891, -3, 1234570000}, {1234567891, -2,
1234568000},
+ {1234567891, -1, 1234567900}, {1234567891, 0,
1234567900},
+ {1234567891, 1, 1234567891}, {1234567891, 2,
1234567891},
+ {1234567891, 3, 1234567891}, {1234567891, 4,
1234567891},
+ {1234567891, 5, 1234567891}, {1234567891, 6,
1234567891},
+ {1234567891, 7, 1234567891}, {1234567891, 8,
1234567891},
+ {1234567891, 9, 1234567891}, {1234567891, 10,
1234567891},
+ {1234567891, 11, 1234567891}}},
+ {{10, 2}, {{1234567891, -11, 10000000000000}, {1234567891, -10,
1000000000000},
+ {1234567891, -9, 100000000000}, {1234567891, -8,
10000000000},
+ {1234567891, -7, 2000000000}, {1234567891, -6,
1300000000},
+ {1234567891, -5, 1240000000}, {1234567891, -4,
1235000000},
+ {1234567891, -3, 1234600000}, {1234567891, -2,
1234570000},
+ {1234567891, -1, 1234568000}, {1234567891, 0,
1234567900},
+ {1234567891, 1, 1234567900}, {1234567891, 2,
1234567891},
+ {1234567891, 3, 1234567891}, {1234567891, 4,
1234567891},
+ {1234567891, 5, 1234567891}, {1234567891, 6,
1234567891},
+ {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}}}};
+
+// test cases for round and round_bankers function of decimal32
+const static DecimalTestDataSet round_decimal32_cases = {
+ {{1, 0},
+ {
+ {1, -10, 0}, {1, -9, 0}, {1, -8, 0}, {1, -7, 0}, {1, -6, 0},
{1, -5, 0},
+ {1, -4, 0}, {1, -3, 0}, {1, -2, 0}, {1, -1, 0}, {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, 0}, {1, -7, 0}, {1, -6, 0},
{1, -5, 0},
+ {1, -4, 0}, {1, -3, 0}, {1, -2, 0}, {1, -1, 0}, {1, 0, 0},
{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, 0},
+ {12, -3, 0},
+ {12, -2, 0},
+ {12, -1, 10},
+ {12, 0, 12},
+ {12, 1, 12},
+ {12, 2, 12},
+ {12, 3, 12},
+ {12, 4, 12},
+ }},
+ {{2, 1},
+ {
+ {12, -4, 0},
+ {12, -3, 0},
+ {12, -2, 0},
+ {12, -1, 0},
+ {12, 0, 10},
+ {12, 1, 12},
+ {12, 2, 12},
+ {12, 3, 12},
+ {12, 4, 12},
+ }},
+ {{2, 2},
+ {
+ {12, -4, 0},
+ {12, -3, 0},
+ {12, -2, 0},
+ {12, -1, 0},
+ {12, 0, 0},
+ {12, 1, 10},
+ {12, 2, 12},
+ {12, 3, 12},
+ {12, 4, 12},
+ }},
+ {{9, 0},
+ {
+ {123456789, -10, 0}, {123456789, -9, 0},
{123456789, -8, 100000000},
+ {123456789, -7, 120000000}, {123456789, -6, 123000000},
{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, 0},
+ {123456789, -7, 100000000}, {123456789, -6, 120000000},
{123456789, -5, 123000000},
+ {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, 0}, {123456789, -6, 100000000},
{123456789, -5, 120000000},
+ {123456789, -4, 123000000}, {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, 0},
{123456789, -5, 100000000},
+ {123456789, -4, 120000000}, {123456789, -3, 123000000},
{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, 0},
+ {123456789, -4, 100000000}, {123456789, -3, 120000000},
{123456789, -2, 123000000},
+ {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, 0}, {123456789, -3, 100000000},
{123456789, -2, 120000000},
+ {123456789, -1, 123000000}, {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, 0},
{123456789, -2, 100000000},
+ {123456789, -1, 120000000}, {123456789, 0, 123000000},
{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, 0},
+ {123456789, -1, 100000000}, {123456789, 0, 120000000},
{123456789, 1, 123000000},
+ {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, 0}, {123456789, 0, 100000000},
{123456789, 1, 120000000},
+ {123456789, 2, 123000000}, {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, 0},
{123456789, 1, 100000000},
+ {123456789, 2, 120000000}, {123456789, 3, 123000000},
{123456789, 4, 123500000},
+ {123456789, 5, 123460000}, {123456789, 6, 123457000},
{123456789, 7, 123456800},
+ {123456789, 8, 123456790}, {123456789, 9, 123456789},
{123456789, 10, 123456789},
+ }}};
+
+// test cases for round and round_bankers function of decimal64
+const static DecimalTestDataSet round_decimal64_cases = {
+ {{10, 0},
+ {{1234567891, -11, 0}, {1234567891, -10, 0},
{1234567891, -9, 1000000000},
+ {1234567891, -8, 1200000000}, {1234567891, -7, 1230000000},
{1234567891, -6, 1235000000},
+ {1234567891, -5, 1234600000}, {1234567891, -4, 1234570000},
{1234567891, -3, 1234568000},
+ {1234567891, -2, 1234567900}, {1234567891, -1, 1234567890},
{1234567891, 0, 1234567891},
+ {1234567891, 1, 1234567891}, {1234567891, 2, 1234567891},
{1234567891, 3, 1234567891},
+ {1234567891, 4, 1234567891}, {1234567891, 5, 1234567891},
{1234567891, 6, 1234567891},
+ {1234567891, 7, 1234567891}, {1234567891, 8, 1234567891},
{1234567891, 9, 1234567891},
+ {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}}},
+ {{10, 1},
+ {{1234567891, -11, 0}, {1234567891, -10, 0},
{1234567891, -9, 0},
+ {1234567891, -8, 1000000000}, {1234567891, -7, 1200000000},
{1234567891, -6, 1230000000},
+ {1234567891, -5, 1235000000}, {1234567891, -4, 1234600000},
{1234567891, -3, 1234570000},
+ {1234567891, -2, 1234568000}, {1234567891, -1, 1234567900},
{1234567891, 0, 1234567890},
+ {1234567891, 1, 1234567891}, {1234567891, 2, 1234567891},
{1234567891, 3, 1234567891},
+ {1234567891, 4, 1234567891}, {1234567891, 5, 1234567891},
{1234567891, 6, 1234567891},
+ {1234567891, 7, 1234567891}, {1234567891, 8, 1234567891},
{1234567891, 9, 1234567891},
+ {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}
+
+ }},
+ {{10, 2},
+ {{1234567891, -11, 0}, {1234567891, -10, 0},
{1234567891, -9, 0},
+ {1234567891, -8, 0}, {1234567891, -7, 1000000000},
{1234567891, -6, 1200000000},
+ {1234567891, -5, 1230000000}, {1234567891, -4, 1235000000},
{1234567891, -3, 1234600000},
+ {1234567891, -2, 1234570000}, {1234567891, -1, 1234568000},
{1234567891, 0, 1234567900},
+ {1234567891, 1, 1234567890}, {1234567891, 2, 1234567891},
{1234567891, 3, 1234567891},
+ {1234567891, 4, 1234567891}, {1234567891, 5, 1234567891},
{1234567891, 6, 1234567891},
+ {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, 0},
+ {1234567891, -8, 0}, {1234567891, -7, 0},
{1234567891, -6, 0},
+ {1234567891, -5, 0}, {1234567891, -4, 0},
{1234567891, -3, 0},
+ {1234567891, -2, 0}, {1234567891, -1, 0},
{1234567891, 0, 1000000000},
+ {1234567891, 1, 1200000000}, {1234567891, 2, 1230000000},
{1234567891, 3, 1235000000},
+ {1234567891, 4, 1234600000}, {1234567891, 5, 1234570000},
{1234567891, 6, 1234568000},
+ {1234567891, 7, 1234567900}, {1234567891, 8, 1234567890},
{1234567891, 9, 1234567891},
+ {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}}},
+ {{18, 0},
+ {{123456789123456789, -19, 0},
+ {123456789123456789, -18, 0},
+ {123456789123456789, -17, 100000000000000000},
+ {123456789123456789, -16, 120000000000000000},
+ {123456789123456789, -15, 123000000000000000},
+ {123456789123456789, -14, 123500000000000000},
+ {123456789123456789, -13, 123460000000000000},
+ {123456789123456789, -12, 123457000000000000},
+ {123456789123456789, -11, 123456800000000000},
+ {123456789123456789, -10, 123456790000000000},
+ {123456789123456789, -9, 123456789000000000},
+ {123456789123456789, -8, 123456789100000000},
+ {123456789123456789, -7, 123456789120000000},
+ {123456789123456789, -6, 123456789123000000},
+ {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, 0},
+ {123456789123456789, 1, 100000000000000000},
+ {123456789123456789, 2, 120000000000000000},
+ {123456789123456789, 3, 123000000000000000},
+ {123456789123456789, 4, 123500000000000000},
+ {123456789123456789, 5, 123460000000000000},
+ {123456789123456789, 6, 123457000000000000},
+ {123456789123456789, 7, 123456800000000000},
+ {123456789123456789, 8, 123456790000000000},
+ {123456789123456789, 9, 123456789000000000},
+ {123456789123456789, 10, 123456789100000000},
+ {123456789123456789, 11, 123456789120000000},
+ {123456789123456789, 12, 123456789123000000},
+ {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}}}};
+
+// test cases for truncate function of float32
+FloatTestDataSet trunc_float32_cases = {
+ {10.0, 1, 10.0}, {10.0, 0, 10.0}, {-124.3867, -2, -100}, {123.123456,
4, 123.123400}};
+
+// test cases for truncate function of float64
+FloatTestDataSet trunc_float64_cases = {{10.0, 1, 10.0},
+ {10.0, 0, 10.0},
+ {-124.3867, -2, -100},
+ {123.123456, 1, 123.100000},
+ {123456789.123456, 4,
123456789.123400}};
+
+// test cases for floor function of float32
+FloatTestDataSet floor_float32_cases = {
+ {10.1234, 1, 10.1}, {10.3, 0, 10.0}, {-124.3867, -2, -200},
{123.123456, 4, 123.123400}};
+
+// test cases for floor function of float64
+FloatTestDataSet floor_float64_cases = {{10.1234, 1, 10.1},
+ {10.3, 0, 10.0},
+ {-124.3867, -2, -200},
+ {123.123456, 4, 123.123400},
+ {123456789.123456, 5,
123456789.123450}};
+
+// test cases for ceil function of float32
+FloatTestDataSet ceil_float32_cases = {
+ {10.1234, 1, 10.2}, {10.3, 0, 11}, {-124.3867, -2, -100}, {123.123456,
4, 123.123500}};
+
+// test cases for ceil function of float64
+FloatTestDataSet ceil_float64_cases = {{10.1234, 1, 10.2},
+ {10.3, 0, 11},
+ {-124.3867, -2, -100},
+ {123.123456, 4, 123.123500},
+ {123456789.123456, 4,
123456789.123500}};
+
+// test cases for round function of float32
+FloatTestDataSet round_float32_cases = {{2.5, 0, 3.0},
+ {10.1234, 1, 10.1},
+ {10.3, 0, 10},
+ {-124.3867, -2, -100},
+ {123.123456, 4, 123.123500}};
+
+// test cases for round function of float64
+FloatTestDataSet round_float64_cases = {{2.5, 0, 3.0},
+ {10.1234, 1, 10.1},
+ {10.3, 0, 10},
+ {-124.3867, -2, -100},
+ {123.123456, 4, 123.123500},
+ {123456789.123456, 4,
123456789.123500}};
+
+// test cases for round_bankers function of float32
+FloatTestDataSet round_bankers_float32_cases = {{2.5, 0, 2.0},
+ {10.1234, 1, 10.1},
+ {10.3, 0, 10},
+ {-124.3867, -2, -100},
+ {123.123456, 4, 123.123500}};
+
+// test cases for round_bankers function of float64
+FloatTestDataSet round_bankers_float64_cases = {{2.5, 0, 2.0},
+ {10.1234, 1, 10.1},
+ {10.3, 0, 10},
+ {-124.3867, -2, -100},
+ {123.123456, 4, 123.123500},
+ {123456789.123456, 4,
123456789.123500}};
+
+template <typename FuncType, typename DecimalType>
+static void decimal_checker(const DecimalTestDataSet& round_test_cases, bool
decimal_col_is_const) {
+ static_assert(IsDecimalNumber<DecimalType>);
+ auto func = std::dynamic_pointer_cast<FuncType>(FuncType::create());
+ FunctionContext* context = nullptr;
+
+ for (const auto& test_case : round_test_cases) {
+ Block block;
+ size_t res_idx = 2;
+ ColumnNumbers arguments = {0, 1, 2};
+ const int precision = test_case.first.first;
+ const int scale = test_case.first.second;
+ const size_t input_rows_count = test_case.second.size();
+ auto col_general =
ColumnDecimal<DecimalType>::create(input_rows_count, scale);
+ auto col_scale = ColumnInt32::create();
+ auto col_res_expected =
ColumnDecimal<DecimalType>::create(input_rows_count, scale);
+ size_t rid = 0;
+
+ for (const auto& test_date : test_case.second) {
+ auto input = std::get<0>(test_date);
+ auto scale_arg = std::get<1>(test_date);
+ auto expectation = std::get<2>(test_date);
+ col_general->get_element(rid) = DecimalType(input);
+ col_scale->insert(scale_arg);
+ col_res_expected->get_element(rid) = DecimalType(expectation);
+ rid++;
+ }
+
+ if (decimal_col_is_const) {
+ block.insert({ColumnConst::create(col_general->clone_resized(1),
1),
+
std::make_shared<DataTypeDecimal<DecimalType>>(precision, scale),
+ "col_general_const"});
+ } else {
+ block.insert({col_general->clone(),
+
std::make_shared<DataTypeDecimal<DecimalType>>(precision, scale),
+ "col_general"});
+ }
+
+ block.insert({col_scale->clone(), std::make_shared<DataTypeInt32>(),
"col_scale"});
+ block.insert({nullptr,
std::make_shared<DataTypeDecimal<DecimalType>>(precision, scale),
+ "col_res"});
+
+ auto status = func->execute_impl(context, block, arguments, res_idx,
input_rows_count);
+ auto col_res = assert_cast<const ColumnDecimal<DecimalType>&>(
+ *(block.get_by_position(res_idx).column));
+ EXPECT_TRUE(status.ok());
+
+ for (size_t i = 0; i < input_rows_count; ++i) {
+ auto res = col_res.get_element(i);
+ auto res_expected = col_res_expected->get_element(i);
+ EXPECT_EQ(res, res_expected)
+ << "function " << func->get_name() << " decimal_type "
+ << TypeName<DecimalType>().get() << " precision " <<
precision
+ << " input_scale " << scale << " input " <<
col_general->get_element(i)
+ << " scale_arg " << col_scale->get_element(i) << "
decimal_col_is_const "
+ << decimal_col_is_const << " res " << res << "
res_expected " << res_expected;
+ }
+ }
+}
+
+template <typename FuncType, typename FloatType>
+static void float_checker(const FloatTestDataSet& round_test_cases, bool
float_col_is_const) {
+ static_assert(IsNumber<FloatType>);
+ auto func = std::dynamic_pointer_cast<FuncType>(FuncType::create());
+ FunctionContext* context = nullptr;
+
+ for (const auto& test_case : round_test_cases) {
+ auto col_general = ColumnVector<FloatType>::create(1);
+ auto col_scale = ColumnInt32::create();
+ auto col_res_expected = ColumnVector<FloatType>::create(1);
+ size_t rid = 0;
+
+ Block block;
+ size_t res_idx = 2;
+ ColumnNumbers arguments = {0, 1, 2};
+
+ auto input = std::get<0>(test_case);
+ auto scale_arg = std::get<1>(test_case);
+ auto expectation = std::get<2>(test_case);
+ col_general->get_element(rid) = FloatType(input);
+ col_scale->insert(scale_arg);
+ col_res_expected->get_element(rid) = FloatType(expectation);
+ rid++;
+
+ if (float_col_is_const) {
+ block.insert({ColumnConst::create(col_general->clone_resized(1),
1),
+ std::make_shared<DataTypeNumber<FloatType>>(),
"col_general_const"});
+ } else {
+ block.insert({col_general->clone(),
std::make_shared<DataTypeNumber<FloatType>>(),
+ "col_general"});
+ }
+
+ block.insert({col_scale->clone(), std::make_shared<DataTypeInt32>(),
"col_scale"});
+ block.insert({nullptr, std::make_shared<DataTypeNumber<FloatType>>(),
"col_res"});
+
+ auto status = func->execute_impl(context, block, arguments, res_idx,
1);
+ auto col_res = assert_cast<const ColumnVector<FloatType>&>(
+ *(block.get_by_position(res_idx).column));
+ EXPECT_TRUE(status.ok());
+
+ auto res = col_res.get_element(0);
+ auto res_expected = col_res_expected->get_element(0);
+ EXPECT_EQ(res, res_expected)
+ << "function " << func->get_name() << " float_type " <<
TypeName<FloatType>().get()
+ << " input " << col_general->get_element(0) << " scale_arg "
+ << col_scale->get_element(0) << " float_col_is_const " <<
float_col_is_const
+ << " res " << res << " res_expected " << res_expected;
+ }
+}
+
+/// tests for func(Column, Column) with decimal input
+TEST(RoundFunctionTest, normal_decimal) {
+ decimal_checker<DecimalTruncateFunction,
Decimal32>(trunc_floor_decimal32_cases, false);
+ decimal_checker<DecimalTruncateFunction,
Decimal64>(trunc_floor_decimal64_cases, false);
+
+ decimal_checker<DecimalFloorFunction,
Decimal32>(trunc_floor_decimal32_cases, false);
+ decimal_checker<DecimalFloorFunction,
Decimal64>(trunc_floor_decimal64_cases, false);
+
+ decimal_checker<DecimalCeilFunction, Decimal32>(ceil_decimal32_cases,
false);
+ decimal_checker<DecimalCeilFunction, Decimal64>(ceil_decimal64_cases,
false);
+
+ decimal_checker<DecimalRoundFunction, Decimal32>(round_decimal32_cases,
false);
+ decimal_checker<DecimalRoundFunction, Decimal64>(round_decimal64_cases,
false);
+
+ decimal_checker<DecimalRoundBankersFunction,
Decimal32>(round_decimal32_cases, false);
+ decimal_checker<DecimalRoundBankersFunction,
Decimal64>(round_decimal64_cases, false);
+}
+
+/// tests for func(ColumnConst, Column) with decimal input
+TEST(RoundFunctionTest, normal_decimal_const) {
+ decimal_checker<DecimalTruncateFunction,
Decimal32>(trunc_floor_decimal32_cases, true);
+ decimal_checker<DecimalTruncateFunction,
Decimal64>(trunc_floor_decimal64_cases, true);
+
+ decimal_checker<DecimalFloorFunction,
Decimal32>(trunc_floor_decimal32_cases, true);
+ decimal_checker<DecimalFloorFunction,
Decimal64>(trunc_floor_decimal64_cases, true);
+
+ decimal_checker<DecimalCeilFunction, Decimal32>(ceil_decimal32_cases,
true);
+ decimal_checker<DecimalCeilFunction, Decimal64>(ceil_decimal64_cases,
true);
+
+ decimal_checker<DecimalRoundFunction, Decimal32>(round_decimal32_cases,
true);
+ decimal_checker<DecimalRoundFunction, Decimal64>(round_decimal64_cases,
true);
+
+ decimal_checker<DecimalRoundBankersFunction,
Decimal32>(round_decimal32_cases, true);
+ decimal_checker<DecimalRoundBankersFunction,
Decimal64>(round_decimal64_cases, true);
+}
+
+/// tests for func(Column, Column) with float input
+TEST(RoundFunctionTest, normal_float) {
+ float_checker<FloatTruncateFunction, Float32>(trunc_float32_cases, false);
+ float_checker<FloatTruncateFunction, Float64>(trunc_float64_cases, false);
+
+ float_checker<FloatFloorFunction, Float32>(floor_float32_cases, false);
+ float_checker<FloatFloorFunction, Float64>(floor_float64_cases, false);
+
+ float_checker<FloatCeilFunction, Float32>(ceil_float32_cases, false);
+ float_checker<FloatCeilFunction, Float64>(ceil_float64_cases, false);
+
+ float_checker<FloatRoundFunction, Float32>(round_float32_cases, false);
+ float_checker<FloatRoundFunction, Float64>(round_float64_cases, false);
+
+ float_checker<FloatRoundBankersFunction,
Float32>(round_bankers_float32_cases, false);
+ float_checker<FloatRoundBankersFunction,
Float64>(round_bankers_float64_cases, false);
+}
+
+/// tests for func(ColumnConst, Column) with float input
+TEST(RoundFunctionTest, normal_float_const) {
+ float_checker<FloatTruncateFunction, Float32>(trunc_float32_cases, true);
+ float_checker<FloatTruncateFunction, Float64>(trunc_float64_cases, true);
+
+ float_checker<FloatFloorFunction, Float32>(floor_float32_cases, true);
+ float_checker<FloatFloorFunction, Float64>(floor_float64_cases, true);
+
+ float_checker<FloatCeilFunction, Float32>(ceil_float32_cases, true);
+ float_checker<FloatCeilFunction, Float64>(ceil_float64_cases, true);
+
+ float_checker<FloatRoundFunction, Float32>(round_float32_cases, true);
+ float_checker<FloatRoundFunction, Float64>(round_float64_cases, true);
+
+ float_checker<FloatRoundBankersFunction,
Float32>(round_bankers_float32_cases, true);
+ float_checker<FloatRoundBankersFunction,
Float64>(round_bankers_float64_cases, true);
+}
+
+} // namespace doris::vectorized
diff --git a/be/test/vec/function/function_truncate_decimal_test.cpp
b/be/test/vec/function/function_truncate_decimal_test.cpp
deleted file mode 100644
index 36fcaa14e67..00000000000
--- a/be/test/vec/function/function_truncate_decimal_test.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
-// 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 <gtest/gtest-message.h>
-#include <gtest/gtest.h>
-
-#include <climits>
-#include <cmath>
-#include <cstddef>
-#include <cstdint>
-#include <iomanip>
-#include <limits>
-#include <map>
-#include <memory>
-#include <string>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-#include "function_test_util.h"
-#include "vec/columns/column.h"
-#include "vec/columns/column_const.h"
-#include "vec/columns/column_decimal.h"
-#include "vec/columns/columns_number.h"
-#include "vec/common/assert_cast.h"
-#include "vec/core/column_numbers.h"
-#include "vec/core/types.h"
-#include "vec/data_types/data_type_decimal.h"
-#include "vec/data_types/data_type_number.h"
-#include "vec/functions/function_truncate.h"
-
-namespace doris::vectorized {
-// {precision, scale} -> {input, scale_arg, expectation}
-using TestDataSet = std::map<std::pair<int, int>,
std::vector<std::tuple<Int128, int, Int128>>>;
-
-const static TestDataSet truncate_decimal32_cases = {
- {{1, 0},
- {
- {1, -10, 0}, {1, -9, 0}, {1, -8, 0}, {1, -7, 0}, {1, -6, 0},
{1, -5, 0},
- {1, -4, 0}, {1, -3, 0}, {1, -2, 0}, {1, -1, 0}, {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, 0}, {1, -7, 0}, {1, -6, 0},
{1, -5, 0},
- {1, -4, 0}, {1, -3, 0}, {1, -2, 0}, {1, -1, 0}, {1, 0, 0},
{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, 0},
- {12, -3, 0},
- {12, -2, 0},
- {12, -1, 10},
- {12, 0, 12},
- {12, 1, 12},
- {12, 2, 12},
- {12, 3, 12},
- {12, 4, 12},
- }},
- {{2, 1},
- {
- {12, -4, 0},
- {12, -3, 0},
- {12, -2, 0},
- {12, -1, 0},
- {12, 0, 10},
- {12, 1, 12},
- {12, 2, 12},
- {12, 3, 12},
- {12, 4, 12},
- }},
- {{2, 2},
- {
- {12, -4, 0},
- {12, -3, 0},
- {12, -2, 0},
- {12, -1, 0},
- {12, 0, 0},
- {12, 1, 10},
- {12, 2, 12},
- {12, 3, 12},
- {12, 4, 12},
- }},
- {{9, 0},
- {
- {123456789, -10, 0}, {123456789, -9, 0},
{123456789, -8, 100000000},
- {123456789, -7, 120000000}, {123456789, -6, 123000000},
{123456789, -5, 123400000},
- {123456789, -4, 123450000}, {123456789, -3, 123456000},
{123456789, -2, 123456700},
- {123456789, -1, 123456780}, {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, 0},
- {123456789, -7, 100000000}, {123456789, -6, 120000000},
{123456789, -5, 123000000},
- {123456789, -4, 123400000}, {123456789, -3, 123450000},
{123456789, -2, 123456000},
- {123456789, -1, 123456700}, {123456789, 0, 123456780},
{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, 0}, {123456789, -6, 100000000},
{123456789, -5, 120000000},
- {123456789, -4, 123000000}, {123456789, -3, 123400000},
{123456789, -2, 123450000},
- {123456789, -1, 123456000}, {123456789, 0, 123456700},
{123456789, 1, 123456780},
- {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, 0},
{123456789, -5, 100000000},
- {123456789, -4, 120000000}, {123456789, -3, 123000000},
{123456789, -2, 123400000},
- {123456789, -1, 123450000}, {123456789, 0, 123456000},
{123456789, 1, 123456700},
- {123456789, 2, 123456780}, {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, 0},
- {123456789, -4, 100000000}, {123456789, -3, 120000000},
{123456789, -2, 123000000},
- {123456789, -1, 123400000}, {123456789, 0, 123450000},
{123456789, 1, 123456000},
- {123456789, 2, 123456700}, {123456789, 3, 123456780},
{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, 0}, {123456789, -3, 100000000},
{123456789, -2, 120000000},
- {123456789, -1, 123000000}, {123456789, 0, 123400000},
{123456789, 1, 123450000},
- {123456789, 2, 123456000}, {123456789, 3, 123456700},
{123456789, 4, 123456780},
- {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, 0},
{123456789, -2, 100000000},
- {123456789, -1, 120000000}, {123456789, 0, 123000000},
{123456789, 1, 123400000},
- {123456789, 2, 123450000}, {123456789, 3, 123456000},
{123456789, 4, 123456700},
- {123456789, 5, 123456780}, {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, 0},
- {123456789, -1, 100000000}, {123456789, 0, 120000000},
{123456789, 1, 123000000},
- {123456789, 2, 123400000}, {123456789, 3, 123450000},
{123456789, 4, 123456000},
- {123456789, 5, 123456700}, {123456789, 6, 123456780},
{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, 0}, {123456789, 0, 100000000},
{123456789, 1, 120000000},
- {123456789, 2, 123000000}, {123456789, 3, 123400000},
{123456789, 4, 123450000},
- {123456789, 5, 123456000}, {123456789, 6, 123456700},
{123456789, 7, 123456780},
- {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, 0},
{123456789, 1, 100000000},
- {123456789, 2, 120000000}, {123456789, 3, 123000000},
{123456789, 4, 123400000},
- {123456789, 5, 123450000}, {123456789, 6, 123456000},
{123456789, 7, 123456700},
- {123456789, 8, 123456780}, {123456789, 9, 123456789},
{123456789, 10, 123456789},
- }}};
-
-const static TestDataSet truncate_decimal64_cases = {
- {{10, 0},
- {{1234567891, -11, 0}, {1234567891, -10, 0},
{1234567891, -9, 1000000000},
- {1234567891, -8, 1200000000}, {1234567891, -7, 1230000000},
{1234567891, -6, 1234000000},
- {1234567891, -5, 1234500000}, {1234567891, -4, 1234560000},
{1234567891, -3, 1234567000},
- {1234567891, -2, 1234567800}, {1234567891, -1, 1234567890},
{1234567891, 0, 1234567891},
- {1234567891, 1, 1234567891}, {1234567891, 2, 1234567891},
{1234567891, 3, 1234567891},
- {1234567891, 4, 1234567891}, {1234567891, 5, 1234567891},
{1234567891, 6, 1234567891},
- {1234567891, 7, 1234567891}, {1234567891, 8, 1234567891},
{1234567891, 9, 1234567891},
- {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}}},
- {{10, 1},
- {{1234567891, -11, 0}, {1234567891, -10, 0},
{1234567891, -9, 0},
- {1234567891, -8, 1000000000}, {1234567891, -7, 1200000000},
{1234567891, -6, 1230000000},
- {1234567891, -5, 1234000000}, {1234567891, -4, 1234500000},
{1234567891, -3, 1234560000},
- {1234567891, -2, 1234567000}, {1234567891, -1, 1234567800},
{1234567891, 0, 1234567890},
- {1234567891, 1, 1234567891}, {1234567891, 2, 1234567891},
{1234567891, 3, 1234567891},
- {1234567891, 4, 1234567891}, {1234567891, 5, 1234567891},
{1234567891, 6, 1234567891},
- {1234567891, 7, 1234567891}, {1234567891, 8, 1234567891},
{1234567891, 9, 1234567891},
- {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}
-
- }},
- {{10, 2},
- {{1234567891, -11, 0}, {1234567891, -10, 0},
{1234567891, -9, 0},
- {1234567891, -8, 0}, {1234567891, -7, 1000000000},
{1234567891, -6, 1200000000},
- {1234567891, -5, 1230000000}, {1234567891, -4, 1234000000},
{1234567891, -3, 1234500000},
- {1234567891, -2, 1234560000}, {1234567891, -1, 1234567000},
{1234567891, 0, 1234567800},
- {1234567891, 1, 1234567890}, {1234567891, 2, 1234567891},
{1234567891, 3, 1234567891},
- {1234567891, 4, 1234567891}, {1234567891, 5, 1234567891},
{1234567891, 6, 1234567891},
- {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, 0},
- {1234567891, -8, 0}, {1234567891, -7, 0},
{1234567891, -6, 0},
- {1234567891, -5, 0}, {1234567891, -4, 0},
{1234567891, -3, 0},
- {1234567891, -2, 0}, {1234567891, -1, 0},
{1234567891, 0, 1000000000},
- {1234567891, 1, 1200000000}, {1234567891, 2, 1230000000},
{1234567891, 3, 1234000000},
- {1234567891, 4, 1234500000}, {1234567891, 5, 1234560000},
{1234567891, 6, 1234567000},
- {1234567891, 7, 1234567800}, {1234567891, 8, 1234567890},
{1234567891, 9, 1234567891},
- {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}}},
- {{18, 0},
- {{123456789123456789, -19, 0},
- {123456789123456789, -18, 0},
- {123456789123456789, -17, 100000000000000000},
- {123456789123456789, -16, 120000000000000000},
- {123456789123456789, -15, 123000000000000000},
- {123456789123456789, -14, 123400000000000000},
- {123456789123456789, -13, 123450000000000000},
- {123456789123456789, -12, 123456000000000000},
- {123456789123456789, -11, 123456700000000000},
- {123456789123456789, -10, 123456780000000000},
- {123456789123456789, -9, 123456789000000000},
- {123456789123456789, -8, 123456789100000000},
- {123456789123456789, -7, 123456789120000000},
- {123456789123456789, -6, 123456789123000000},
- {123456789123456789, -5, 123456789123400000},
- {123456789123456789, -4, 123456789123450000},
- {123456789123456789, -3, 123456789123456000},
- {123456789123456789, -2, 123456789123456700},
- {123456789123456789, -1, 123456789123456780},
- {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, 0},
- {123456789123456789, 1, 100000000000000000},
- {123456789123456789, 2, 120000000000000000},
- {123456789123456789, 3, 123000000000000000},
- {123456789123456789, 4, 123400000000000000},
- {123456789123456789, 5, 123450000000000000},
- {123456789123456789, 6, 123456000000000000},
- {123456789123456789, 7, 123456700000000000},
- {123456789123456789, 8, 123456780000000000},
- {123456789123456789, 9, 123456789000000000},
- {123456789123456789, 10, 123456789100000000},
- {123456789123456789, 11, 123456789120000000},
- {123456789123456789, 12, 123456789123000000},
- {123456789123456789, 13, 123456789123400000},
- {123456789123456789, 14, 123456789123450000},
- {123456789123456789, 15, 123456789123456000},
- {123456789123456789, 16, 123456789123456700},
- {123456789123456789, 17, 123456789123456780},
- {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}}}};
-
-template <typename FuncType, typename DecimalType>
-static void checker(const TestDataSet& truncate_test_cases, bool
decimal_col_is_const) {
- static_assert(IsDecimalNumber<DecimalType>);
- auto func = std::dynamic_pointer_cast<FuncType>(FuncType::create());
- FunctionContext* context = nullptr;
-
- for (const auto& test_case : truncate_test_cases) {
- Block block;
- size_t res_idx = 2;
- ColumnNumbers arguments = {0, 1, 2};
- const int precision = test_case.first.first;
- const int scale = test_case.first.second;
- const size_t input_rows_count = test_case.second.size();
- auto col_general =
ColumnDecimal<DecimalType>::create(input_rows_count, scale);
- auto col_scale = ColumnInt32::create();
- auto col_res_expected =
ColumnDecimal<DecimalType>::create(input_rows_count, scale);
- size_t rid = 0;
-
- for (const auto& test_date : test_case.second) {
- auto input = std::get<0>(test_date);
- auto scale_arg = std::get<1>(test_date);
- auto expectation = std::get<2>(test_date);
- col_general->get_element(rid) = DecimalType(input);
- col_scale->insert(scale_arg);
- col_res_expected->get_element(rid) = DecimalType(expectation);
- rid++;
- }
-
- if (decimal_col_is_const) {
- block.insert({ColumnConst::create(col_general->clone_resized(1),
1),
-
std::make_shared<DataTypeDecimal<DecimalType>>(precision, scale),
- "col_general_const"});
- } else {
- block.insert({col_general->clone(),
-
std::make_shared<DataTypeDecimal<DecimalType>>(precision, scale),
- "col_general"});
- }
-
- block.insert({col_scale->clone(), std::make_shared<DataTypeInt32>(),
"col_scale"});
- block.insert({nullptr,
std::make_shared<DataTypeDecimal<DecimalType>>(precision, scale),
- "col_res"});
-
- auto status = func->execute_impl(context, block, arguments, res_idx,
input_rows_count);
- auto col_res = assert_cast<const ColumnDecimal<DecimalType>&>(
- *(block.get_by_position(res_idx).column));
- EXPECT_TRUE(status.ok());
-
- for (size_t i = 0; i < input_rows_count; ++i) {
- auto res = col_res.get_element(i);
- auto res_expected = col_res_expected->get_element(i);
- EXPECT_EQ(res, res_expected)
- << "precision " << precision << " input_scale " << scale
<< " input "
- << col_general->get_element(i) << " scale_arg " <<
col_scale->get_element(i)
- << " res " << res << " res_expected " << res_expected;
- }
- }
-}
-TEST(TruncateFunctionTest, normal_decimal) {
- checker<FunctionTruncate<TruncateDecimalTwoArgImpl>,
Decimal32>(truncate_decimal32_cases,
- false);
- checker<FunctionTruncate<TruncateDecimalTwoArgImpl>,
Decimal64>(truncate_decimal64_cases,
- false);
-}
-
-TEST(TruncateFunctionTest, normal_decimal_const) {
- checker<FunctionTruncate<TruncateDecimalTwoArgImpl>,
Decimal32>(truncate_decimal32_cases, true);
- checker<FunctionTruncate<TruncateDecimalTwoArgImpl>,
Decimal64>(truncate_decimal64_cases, true);
-}
-
-} // namespace doris::vectorized
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
index f62b45eb2e3..5253ff7fde1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
@@ -115,30 +115,8 @@ public class FunctionCallExpr extends Expr {
return returnType;
}
};
- java.util.function.BiFunction<ArrayList<Expr>, Type, Type> roundRule =
(children, returnType) -> {
- Preconditions.checkArgument(children != null && children.size() >
0);
- if (children.size() == 1 &&
children.get(0).getType().isDecimalV3()) {
- return
ScalarType.createDecimalV3Type(children.get(0).getType().getPrecision(), 0);
- } else if (children.size() == 2) {
- Preconditions.checkArgument(children.get(1) instanceof
IntLiteral
- || (children.get(1) instanceof CastExpr
- && children.get(1).getChild(0) instanceof
IntLiteral),
- "2nd argument of function round/floor/ceil must be
literal");
- if (children.get(1) instanceof CastExpr &&
children.get(1).getChild(0) instanceof IntLiteral) {
-
children.get(1).getChild(0).setType(children.get(1).getType());
- children.set(1, children.get(1).getChild(0));
- } else {
- children.get(1).setType(Type.INT);
- }
- int scaleArg = (int) (((IntLiteral)
children.get(1)).getValue());
- return
ScalarType.createDecimalV3Type(children.get(0).getType().getPrecision(),
- Math.min(Math.max(scaleArg, 0), ((ScalarType)
children.get(0).getType()).decimalScale()));
- } else {
- return returnType;
- }
- };
- java.util.function.BiFunction<ArrayList<Expr>, Type, Type>
truncateRule = (children, returnType) -> {
+ java.util.function.BiFunction<ArrayList<Expr>, Type, Type> roundRule =
(children, returnType) -> {
Preconditions.checkArgument(children != null && children.size() >
0);
if (children.size() == 1 &&
children.get(0).getType().isDecimalV3()) {
return
ScalarType.createDecimalV3Type(children.get(0).getType().getPrecision(), 0);
@@ -268,7 +246,7 @@ public class FunctionCallExpr extends Expr {
PRECISION_INFER_RULE.put("dround", roundRule);
PRECISION_INFER_RULE.put("dceil", roundRule);
PRECISION_INFER_RULE.put("dfloor", roundRule);
- PRECISION_INFER_RULE.put("truncate", truncateRule);
+ PRECISION_INFER_RULE.put("truncate", roundRule);
}
public static final ImmutableSet<String> TIME_FUNCTIONS_WITH_PRECISION =
new ImmutableSortedSet.Builder(
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ComputePrecisionForRound.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ComputePrecisionForRound.java
index 6b6308c516c..eedbfea6df9 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ComputePrecisionForRound.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ComputePrecisionForRound.java
@@ -20,13 +20,10 @@ package
org.apache.doris.nereids.trees.expressions.functions;
import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Cast;
import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.scalar.Truncate;
import org.apache.doris.nereids.trees.expressions.literal.IntegerLikeLiteral;
import org.apache.doris.nereids.types.DecimalV3Type;
import org.apache.doris.nereids.types.coercion.Int32OrLessType;
-import com.google.common.base.Preconditions;
-
/** ComputePrecisionForRound */
public interface ComputePrecisionForRound extends ComputePrecision {
@Override
@@ -40,34 +37,19 @@ public interface ComputePrecisionForRound extends
ComputePrecision {
Expression floatLength = getArgument(1);
int scale;
- if (this instanceof Truncate) {
- if (floatLength.isLiteral() || (
- floatLength instanceof Cast &&
floatLength.child(0).isLiteral()
- && floatLength.child(0).getDataType()
instanceof Int32OrLessType)) {
- // Scale argument is a literal or cast from other literal
- if (floatLength instanceof Cast) {
- scale = ((IntegerLikeLiteral)
floatLength.child(0)).getIntValue();
- } else {
- scale = ((IntegerLikeLiteral)
floatLength).getIntValue();
- }
- scale = Math.min(Math.max(scale, 0),
decimalV3Type.getScale());
- } else {
- // Truncate could use Column as its scale argument.
- // Result scale will always same with input Decimal in
this situation.
- scale = decimalV3Type.getScale();
- }
- } else {
- Preconditions.checkArgument(floatLength.getDataType()
instanceof Int32OrLessType
- && (floatLength.isLiteral() || (
- floatLength instanceof Cast &&
floatLength.child(0).isLiteral()
- && floatLength.child(0).getDataType()
instanceof Int32OrLessType)),
- "2nd argument of function round/floor/ceil must be
literal");
+ if (floatLength.isLiteral() || (floatLength instanceof Cast &&
floatLength.child(0).isLiteral()
+ && floatLength.child(0).getDataType() instanceof
Int32OrLessType)) {
+ // Scale argument is a literal or cast from other literal
if (floatLength instanceof Cast) {
scale = ((IntegerLikeLiteral)
floatLength.child(0)).getIntValue();
} else {
scale = ((IntegerLikeLiteral) floatLength).getIntValue();
}
scale = Math.min(Math.max(scale, 0), decimalV3Type.getScale());
+ } else {
+ // Func could use Column as its scale argument.
+ // Result scale will always same with input Decimal in this
situation.
+ scale = decimalV3Type.getScale();
}
return signature.withArgumentType(0, decimalV3Type)
diff --git
a/regression-test/data/query_p0/sql_functions/math_functions/test_function_truncate.out
b/regression-test/data/query_p0/sql_functions/math_functions/test_function_truncate.out
index 24f675ffbe2..80d77f50dc3 100644
---
a/regression-test/data/query_p0/sql_functions/math_functions/test_function_truncate.out
+++
b/regression-test/data/query_p0/sql_functions/math_functions/test_function_truncate.out
@@ -1,4 +1,7 @@
-- This file is automatically generated. You should know what you did if you
want to edit this
+-- !sql --
+10.0 10.0
+
-- !sql --
0 123.3
1 123.3
diff --git
a/regression-test/data/query_p0/sql_functions/math_functions/test_round.out
b/regression-test/data/query_p0/sql_functions/math_functions/test_round.out
index 50d15b2843b..1ebc9cf5b89 100644
--- a/regression-test/data/query_p0/sql_functions/math_functions/test_round.out
+++ b/regression-test/data/query_p0/sql_functions/math_functions/test_round.out
@@ -140,3 +140,82 @@
-- !query --
0.000 0.000 0.000
+-- !floor_dec9 --
+1 123456789 123456789 12345678.1 12345678.1
0.123456789 0.100000000
+1 123456789 123456789 12345678.1 12345678.1
0.123456789 0.100000000
+
+-- !floor_dec10 --
+1 123456789 123456789 1.123456789 1.100000000
0.1234567890 0.1000000000
+1 123456789 123456789 1.123456789 1.100000000
0.1234567890 0.1000000000
+
+-- !floor_flo --
+1 12345.123 12345.12 1.2345678912345679E8 1.23456789123E8
+1 12345.123 12345.12 1.2345678912345679E8 1.23456789123E8
+
+-- !ceil_dec9 --
+1 123456789 123456789 12345678.1 12345678.1
0.123456789 0.200000000
+1 123456789 123456789 12345678.1 12345678.1
0.123456789 0.200000000
+
+-- !ceil_dec10 --
+1 123456789 123456789 1.123456789 1.200000000
0.1234567890 0.2000000000
+1 123456789 123456789 1.123456789 1.200000000
0.1234567890 0.2000000000
+
+-- !ceil_flo --
+1 12345.123 12346.0 1.2345678912345679E8 1.2345679E8
+1 12345.123 12346.0 1.2345678912345679E8 1.2345679E8
+
+-- !round_dec9 --
+1 123456789 123456789 12345678.1 12345678.1
0.123456789 0.100000000
+1 123456789 123456789 12345678.1 12345678.1
0.123456789 0.100000000
+
+-- !round_dec10 --
+1 123456789 123456789 1.123456789 1.100000000
0.1234567890 0.1000000000
+1 123456789 123456789 1.123456789 1.100000000
0.1234567890 0.1000000000
+
+-- !round_flo --
+1 12345.123 12350.0 1.2345678912345679E8 1.234568E8
+1 12345.123 12350.0 1.2345678912345679E8 1.234568E8
+
+-- !round_bankers_dec9 --
+1 123456789 123456789 12345678.1 12345678.1
0.123456789 0.100000000
+1 123456789 123456789 12345678.1 12345678.1
0.123456789 0.100000000
+
+-- !round_bankers_dec10 --
+1 123456789 123456789 1.123456789 1.100000000
0.1234567890 0.1000000000
+1 123456789 123456789 1.123456789 1.100000000
0.1234567890 0.1000000000
+
+-- !round_bankers_flo --
+1 12345.123 12350.0 1.2345678912345679E8 1.234568E8
+1 12345.123 12350.0 1.2345678912345679E8 1.234568E8
+
+-- !all_funcs_compare_dec --
+5 1.123456789 1.123450000 1.123450000 1.123460000
1.123460000 1.123460000
+
+-- !bankers_compare --
+2.5 0 3.0 2.0
+
+-- !nested_func --
+1 2
+
+-- !pos_zero_neg_compare --
+1 1.2345678912345679E8 1.234568E8 1.2345679E8 1.2345678913E8
+1 1.2345678912345679E8 1.234568E8 1.2345679E8 1.2345678913E8
+
+-- !cast_dec --
+0E-8 0.00
+
+-- !col_const_compare --
+1 1.123456789 1.100000000 1.1 1.100000000 1.1
+
+-- !floor_dec128 --
+1 1234567891234567891 1234567891234567891 1234567891234567891
1234567891.123456789 1234567891 1234567891.100000000
0.1234567891234567891 0 0.1000000000000000000
+
+-- !ceil_dec128 --
+1 1234567891234567891 1234567891234567891 1234567891234567891
1234567891.123456789 1234567892 1234567891.200000000
0.1234567891234567891 1 0.2000000000000000000
+
+-- !round_dec128 --
+1 1234567891234567891 1234567891234567891 1234567891234567891
1234567891.123456789 1234567891 1234567891.100000000
0.1234567891234567891 0 0.1000000000000000000
+
+-- !round_bankers_dec128 --
+1 1234567891234567891 1234567891234567891 1234567891234567891
1234567891.123456789 1234567891 1234567891.100000000
0.1234567891234567891 0 0.1000000000000000000
+
diff --git
a/regression-test/suites/query_p0/sql_functions/math_functions/test_function_truncate.groovy
b/regression-test/suites/query_p0/sql_functions/math_functions/test_function_truncate.groovy
index 767140e7a6f..b7c36dfbaa1 100644
---
a/regression-test/suites/query_p0/sql_functions/math_functions/test_function_truncate.groovy
+++
b/regression-test/suites/query_p0/sql_functions/math_functions/test_function_truncate.groovy
@@ -16,6 +16,10 @@
// under the License.
suite("test_function_truncate") {
+ // NOTICE: This single const argument test should never cause BE crash,
+ // like branch2.0's behavior, so we added it to check.
+ qt_sql """SELECT truncate(10.12345), truncate(cast(10.12345 as decimal(7,
5)));"""
+
qt_sql """
SELECT number, truncate(123.345 , 1) FROM numbers("number"="10");
"""
diff --git
a/regression-test/suites/query_p0/sql_functions/math_functions/test_round.groovy
b/regression-test/suites/query_p0/sql_functions/math_functions/test_round.groovy
index efdc003fbd4..1d8bbb9df49 100644
---
a/regression-test/suites/query_p0/sql_functions/math_functions/test_round.groovy
+++
b/regression-test/suites/query_p0/sql_functions/math_functions/test_round.groovy
@@ -143,4 +143,125 @@
qt_query """ select cast(round(sum(d1), 2) as decimalv3(27, 3)),
cast(round(sum(d2), 2) as decimalv3(27, 3)), cast(round(sum(d3),2) as
decimalv3(27, 3)) from ${tableName3} """
qt_query """ select cast(round(sum(d1), -2) as decimalv3(27, 3)),
cast(round(sum(d2), -2) as decimalv3(27, 3)), cast(round(sum(d3), -2) as
decimalv3(27, 3)) from ${tableName3} """
qt_query """ select cast(round(sum(d1), -4) as decimalv3(27, 3)),
cast(round(sum(d2), -4) as decimalv3(27, 3)), cast(round(sum(d3), -4) as
decimalv3(27, 3)) from ${tableName3} """
+
+ /// Testing with enhanced round function, which can deal with scale being
a column, like this:
+ /// func(Column, Column), func(ColumnConst, Column).
+ /// Consider truncate() has been tested in test_function_truncate.groovy,
so we focus on the rest here.
+ sql """DROP TABLE IF EXISTS test_enhanced_round;"""
+ sql """
+ CREATE TABLE test_enhanced_round (
+ rid int, flo float, dou double,
+ dec90 decimal(9, 0), dec91 decimal(9, 1), dec99 decimal(9, 9),
+ dec100 decimal(10,0), dec109 decimal(10,9), dec1010 decimal(10,10),
+ number int DEFAULT 1)
+ DISTRIBUTED BY HASH(rid)
+ PROPERTIES("replication_num" = "1" );
+ """
+ sql """
+ INSERT INTO test_enhanced_round
+ VALUES
+ (1, 12345.123, 123456789.123456789,
+ 123456789, 12345678.1, 0.123456789,
+ 123456789.1, 1.123456789, 0.123456789, 1);
+ """
+ sql """
+ INSERT INTO test_enhanced_round
+ VALUES
+ (2, 12345.123, 123456789.123456789,
+ 123456789, 12345678.1, 0.123456789,
+ 123456789.1, 1.123456789, 0.123456789, 1);
+ """
+ qt_floor_dec9 """
+ SELECT number, dec90, floor(dec90, number), dec91, floor(dec91,
number), dec99, floor(dec99, number) FROM test_enhanced_round order by rid;
+ """
+ qt_floor_dec10 """
+ SELECT number, dec100, floor(dec100, number), dec109, floor(dec109,
number), dec1010, floor(dec1010, number) FROM test_enhanced_round order by rid;
+ """
+ qt_floor_flo """
+ SELECT number, flo, floor(flo, number + 1), dou, floor(dou, number +
2) FROM test_enhanced_round order by rid;
+ """
+ qt_ceil_dec9 """
+ SELECT number, dec90, ceil(dec90, number), dec91, ceil(dec91, number),
dec99, ceil(dec99, number) FROM test_enhanced_round order by rid;
+ """
+ qt_ceil_dec10 """
+ SELECT number, dec100, ceil(dec100, number), dec109, ceil(dec109,
number), dec1010, ceil(dec1010, number) FROM test_enhanced_round order by rid;
+ """
+ qt_ceil_flo """
+ SELECT number, flo, ceil(flo, number - 1), dou, ceil(dou, number - 2)
FROM test_enhanced_round order by rid;
+ """
+ qt_round_dec9 """
+ SELECT number, dec90, round(dec90, number), dec91, round(dec91,
number), dec99, round(dec99, number) FROM test_enhanced_round order by rid;
+ """
+ qt_round_dec10 """
+ SELECT number, dec100, round(dec100, number), dec109, round(dec109,
number), dec1010, round(dec1010, number) FROM test_enhanced_round order by rid;
+ """
+ qt_round_flo """
+ SELECT number, flo, round(flo, number - 2), dou, round(dou, number -
3) FROM test_enhanced_round order by rid;
+ """
+ qt_round_bankers_dec9 """
+ SELECT number, dec90, round_bankers(dec90, number), dec91,
round_bankers(dec91, number), dec99, round_bankers(dec99, number) FROM
test_enhanced_round order by rid;
+ """
+ qt_round_bankers_dec10 """
+ SELECT number, dec100, round_bankers(dec100, number), dec109,
round_bankers(dec109, number), dec1010, round_bankers(dec1010, number) FROM
test_enhanced_round order by rid;
+ """
+ qt_round_bankers_flo """
+ SELECT number, flo, round_bankers(flo, number - 2), dou,
round_bankers(dou, number - 3) FROM test_enhanced_round order by rid;
+ """
+
+ qt_all_funcs_compare_dec """
+ SELECT number + 4 as new_number, dec109, truncate(dec109, number + 4)
as t_res, floor(dec109, number + 4) as f_res, ceil(dec109, number + 4) as
c_res, round(dec109, number + 4) as r_res,
+ round_bankers(dec109, number + 4) as rb_res FROM
test_enhanced_round where rid = 1;
+ """
+ qt_bankers_compare """
+ SELECT number * 2.5 as input1, number - 1 as input2, round(number *
2.5, number - 1) as r_res, round_bankers(number * 2.5, number - 1) as rb_res
FROM test_enhanced_round where rid = 1;
+ """
+ qt_nested_func """
+ SELECT number, floor(floor(number * floor(number) + 1),
ceil(floor(number))) as nested_col FROM test_enhanced_round where rid = 1;
+ """
+ qt_pos_zero_neg_compare """
+ SELECT number, dou, ceil(dou, (-2) * number), ceil(dou, 0 * number),
ceil(dou, 2 * number) FROM test_enhanced_round;
+ """
+ qt_cast_dec """
+ SELECT round(cast(0 as Decimal(9,8)), 10), round(cast(0 as
Decimal(9,8)), 2);
+ """
+ //For func(x, d), if d is a column and x has Decimal type, scale of result
Decimal will always be same with input Decimal.
+ qt_col_const_compare """
+ SELECT number, dec109, floor(dec109, number) as f_col_col,
floor(dec109, 1) as f_col_const,
+ floor(1.123456789, number) as f_const_col, floor(1.123456789, 1) as
f_const_const FROM test_enhanced_round limit 1;
+ """
+
+ sql """DROP TABLE IF EXISTS test_enhanced_round_dec128;"""
+ sql """
+ CREATE TABLE test_enhanced_round_dec128 (
+ rid int, dec190 decimal(19,0), dec199 decimal(19,9), dec1919
decimal(19,19),
+ dec380 decimal(38,0), dec3819 decimal(38,19), dec3838
decimal(38,38),
+ number int DEFAULT 1
+ )
+ DISTRIBUTED BY HASH(rid)
+ PROPERTIES("replication_num" = "1" );
+ """
+ sql """
+ INSERT INTO test_enhanced_round_dec128
+ VALUES
+ (1, 1234567891234567891.0, 1234567891.123456789, 0.1234567891234567891,
+ 12345678912345678912345678912345678912.0,
+ 1234567891234567891.1234567891234567891,
+
0.12345678912345678912345678912345678912345678912345678912345678912345678912,
1);
+ """
+ qt_floor_dec128 """
+ SELECT number, dec190, floor(dec190, 0), floor(dec190, number),
dec199, floor(dec199, 0), floor(dec199, number),
+ dec1919, floor(dec1919, 0), floor(dec1919, number) FROM
test_enhanced_round_dec128 order by rid;
+ """
+ qt_ceil_dec128 """
+ SELECT number, dec190, ceil(dec190, 0), ceil(dec190, number), dec199,
ceil(dec199, 0), ceil(dec199, number),
+ dec1919, ceil(dec1919, 0), ceil(dec1919, number) FROM
test_enhanced_round_dec128 order by rid;
+ """
+ qt_round_dec128 """
+ SELECT number, dec190, round(dec190, 0), round(dec190, number),
dec199, round(dec199, 0), round(dec199, number),
+ dec1919, round(dec1919, 0), round(dec1919, number) FROM
test_enhanced_round_dec128 order by rid;
+ """
+ qt_round_bankers_dec128 """
+ SELECT number, dec190, round_bankers(dec190, 0), round_bankers(dec190,
number), dec199, round_bankers(dec199, 0), round_bankers(dec199, number),
+ dec1919, round_bankers(dec1919, 0), round_bankers(dec1919, number)
FROM test_enhanced_round_dec128 order by rid;
+ """
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]