diff --git a/src/Functions/FunctionBinaryArithmetic.h b/src/Functions/FunctionBinaryArithmetic.h index 8c684d3578f..ea6169194e4 100644 --- a/src/Functions/FunctionBinaryArithmetic.h +++ b/src/Functions/FunctionBinaryArithmetic.h @@ -3,6 +3,8 @@ // Include this first, because `#define _asan_poison_address` from // llvm/Support/Compiler.h conflicts with its forward declaration in // sanitizer/asan_interface.h +#include +#include #include #include @@ -467,6 +469,11 @@ public: Case && IsDataTypeDecimal, RightDataType>, Case && IsIntegralOrExtended, LeftDataType>, Case && IsIntegralOrExtended, RightDataType>, + + /// e.g Decimal * Float64 = Float64 + Case && IsFloatingPoint, RightDataType>, + Case && IsFloatingPoint, LeftDataType>, + /// Decimal Real is not supported (traditional DBs convert Decimal Real to Real) Case && !IsIntegralOrExtendedOrDecimal, InvalidType>, Case && !IsIntegralOrExtendedOrDecimal, InvalidType>, @@ -790,10 +797,12 @@ public: } DataTypePtr type_res; - bool valid = castBothTypes(arguments[0].get(), arguments[1].get(), [&](const auto & left, const auto & right) + + const bool valid = castBothTypes(arguments[0].get(), arguments[1].get(), [&](const auto & left, const auto & right) { using LeftDataType = std::decay_t; using RightDataType = std::decay_t; + if constexpr (std::is_same_v || std::is_same_v) { if constexpr (!Op::allow_fixed_string) @@ -810,6 +819,7 @@ public: else { using ResultDataType = typename BinaryOperationTraits::ResultDataType; + if constexpr (!std::is_same_v) { if constexpr (IsDataTypeDecimal && IsDataTypeDecimal) @@ -817,6 +827,10 @@ public: ResultDataType result_type = decimalResultType(left, right); type_res = std::make_shared(result_type.getPrecision(), result_type.getScale()); } + else if constexpr ((IsDataTypeDecimal && IsFloatingPoint) || + (IsDataTypeDecimal && IsFloatingPoint)) + type_res = std::make_shared, + LeftDataType, RightDataType>>(); else if constexpr (IsDataTypeDecimal) type_res = std::make_shared(left.getPrecision(), left.getScale()); else if constexpr (IsDataTypeDecimal) @@ -841,10 +855,15 @@ public: } return false; }); - if (!valid) - throw Exception("Illegal types " + arguments[0]->getName() + " and " + arguments[1]->getName() + " of arguments of function " + String(name), - ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - return type_res; + + if (valid) + return type_res; + + throw Exception( + "Illegal types " + arguments[0]->getName() + + " and " + arguments[1]->getName() + + " of arguments of function " + String(name), + ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); } ColumnPtr executeFixedString(const ColumnsWithTypeAndName & arguments) const diff --git a/src/Functions/multiply.cpp b/src/Functions/multiply.cpp index 7552af7dbf1..18c1927b4a5 100644 --- a/src/Functions/multiply.cpp +++ b/src/Functions/multiply.cpp @@ -25,7 +25,7 @@ struct MultiplyImpl return static_cast(a) * b; } - /// Apply operation and check overflow. It's used for Deciamal operations. @returns true if overflowed, false otherwise. + /// Apply operation and check overflow. It's used for Decimal operations. @returns true if overflowed, false otherwise. template static inline bool apply(A a, B b, Result & c) {