diff --git a/be/src/vec/functions/function_binary_arithmetic.h b/be/src/vec/functions/function_binary_arithmetic.h index 6f07fa9f73..34b7851403 100644 --- a/be/src/vec/functions/function_binary_arithmetic.h +++ b/be/src/vec/functions/function_binary_arithmetic.h @@ -20,6 +20,9 @@ #pragma once +#include + +#include "runtime/decimalv2_value.h" #include "vec/columns/column_const.h" #include "vec/columns/column_decimal.h" #include "vec/columns/column_nullable.h" @@ -241,9 +244,13 @@ struct DecimalBinaryOperation { } } - /// default: use it if no return before - for (size_t i = 0; i < size; ++i) { - c[i] = apply(a[i], b[i]); + if constexpr (OpTraits::is_multiply && std::is_same_v && + std::is_same_v) { + Op::vector_vector(a, b, c); + } else { + for (size_t i = 0; i < size; i++) { + c[i] = apply(a[i], b[i]); + } } } diff --git a/be/src/vec/functions/multiply.cpp b/be/src/vec/functions/multiply.cpp index 95475ed847..da20805861 100644 --- a/be/src/vec/functions/multiply.cpp +++ b/be/src/vec/functions/multiply.cpp @@ -18,6 +18,8 @@ // https://github.com/ClickHouse/ClickHouse/blob/master/src/Functions/Multiply.cpp // and modified by Doris +#include "runtime/decimalv2_value.h" +#include "vec/columns/column_decimal.h" #include "vec/common/arithmetic_overflow.h" #include "vec/functions/function_binary_arithmetic.h" #include "vec/functions/simple_function_factory.h" @@ -35,9 +37,29 @@ struct MultiplyImpl { } template - static inline DecimalV2Value apply(DecimalV2Value a, DecimalV2Value b) { + static inline DecimalV2Value apply(const DecimalV2Value& a, const DecimalV2Value& b) { return a * b; } + + static void vector_vector(const ColumnDecimal128::Container& a, + const ColumnDecimal128::Container& b, + ColumnDecimal128::Container& c) { + size_t size = c.size(); + int8 sgn[size]; + + for (int i = 0; i < size; i++) { + sgn[i] = ((DecimalV2Value(a[i]).value() >= 0) == (DecimalV2Value(b[i]).value() >= 0)) + ? 1 + : -1; + } + + for (int i = 0; i < size; i++) { + c[i] = (DecimalV2Value(a[i]).value() * DecimalV2Value(b[i]).value() - sgn[i]) / + DecimalV2Value::ONE_BILLION + + sgn[i]; + } + } + /// Apply operation and check overflow. It's used for Deciamal operations. @returns true if overflowed, false otherwise. template static inline bool apply(A a, B b, Result& c) {