From 57bb75b75baf337738e1fce4383f1bdad4fa6bf9 Mon Sep 17 00:00:00 2001 From: myrrc Date: Tue, 22 Dec 2020 19:45:03 +0300 Subject: [PATCH] finished rearranging the code --- src/Functions/FunctionBinaryArithmetic.h | 155 +++++++++++++---------- 1 file changed, 85 insertions(+), 70 deletions(-) diff --git a/src/Functions/FunctionBinaryArithmetic.h b/src/Functions/FunctionBinaryArithmetic.h index ec5c9e8bd67..90eb73979b8 100644 --- a/src/Functions/FunctionBinaryArithmetic.h +++ b/src/Functions/FunctionBinaryArithmetic.h @@ -314,7 +314,12 @@ public: if constexpr(op_case == OpCase::LeftConstant) static_assert(!IsDecimalNumber); if constexpr(op_case == OpCase::RightConstant) static_assert(!IsDecimalNumber); - const size_t size = a.size(); + size_t size; + + if constexpr(op_case == OpCase::LeftConstant) + size = b.size(); + else + size = a.size(); if constexpr (is_plus_minus_compare) { @@ -390,11 +395,12 @@ private: Operation>; template - static auto unwrap(const auto& elem, int i) + static auto unwrap(const auto& elem, size_t i) { if constexpr(op_case == target) return undec(elem); - return undec(elem[i]); + else + return undec(elem[i]); } /// there's implicit type conversion here @@ -1062,78 +1068,87 @@ public: if constexpr (std::is_same_v) return nullptr; - - static_assert(!std::is_same_v); - - using T0 = typename LeftDataType::FieldType; - using T1 = typename RightDataType::FieldType; - using ResultType = typename ResultDataType::FieldType; - using ColVecT0 = std::conditional_t, ColumnDecimal, ColumnVector>; - using ColVecT1 = std::conditional_t, ColumnDecimal, ColumnVector>; - using ColVecResult = std::conditional_t, ColumnDecimal, ColumnVector>; - - const auto * const col_left_raw = arguments[0].column.get(); - const auto * const col_right_raw = arguments[1].column.get(); - - const size_t col_left_size = col_left_raw->size(); - - const ColumnConst * const col_left_const = checkAndGetColumnConst(col_left_raw); - const ColumnConst * const col_right_const = checkAndGetColumnConst(col_right_raw); - - const ColVecT0 * const col_left = checkAndGetColumn(col_left_raw); - const ColVecT1 * const col_right = checkAndGetColumn(col_right_raw); - - if constexpr (IsDataTypeDecimal || IsDataTypeDecimal) - return executeNumericWithDecimal( - left, right, - col_left_const, col_right_const, - col_left, col_right, - col_left_size); - - using OpImpl = BinaryOperationImpl, ResultType>; - - /// non-vector result - if (col_left_const && col_right_const) + else // we can't avoid the else because otherwise the compiler may assume the ResultDataType may be Invalid + // and that would produce the compile error. { - const auto res = OpImpl::process( - col_left_const->template getValue(), - col_right_const->template getValue()); + using T0 = typename LeftDataType::FieldType; + using T1 = typename RightDataType::FieldType; + using ResultType = typename ResultDataType::FieldType; + using ColVecT0 = std::conditional_t, ColumnDecimal, ColumnVector>; + using ColVecT1 = std::conditional_t, ColumnDecimal, ColumnVector>; + using ColVecResult = std::conditional_t, ColumnDecimal, ColumnVector>; - return ResultDataType().createColumnConst(col_left_const->size(), toField(res)); - } + const auto * const col_left_raw = arguments[0].column.get(); + const auto * const col_right_raw = arguments[1].column.get(); - typename ColVecResult::MutablePtr col_res = ColVecResult::create(); - auto & vec_res = col_res->getData(); - vec_res.resize(col_left_size); + const size_t col_left_size = col_left_raw->size(); - if (col_left && col_right) - { - OpImpl::template process( - col_left->getData().data(), - col_right->getData().data(), - vec_res.data(), - vec_res.size()); - } - else if (col_left_const && col_right) - { - OpImpl::template process( - col_left_const->template getValue(), - col_right->getData().data(), - vec_res.data(), - vec_res.size()); - } - else if (col_left && col_right_const) - { - OpImpl::template process( - col_left->getData().data(), - col_right_const->template getValue(), - vec_res.data(), - vec_res.size()); - } - else - return nullptr; + const ColumnConst * const col_left_const = checkAndGetColumnConst(col_left_raw); + const ColumnConst * const col_right_const = checkAndGetColumnConst(col_right_raw); - return col_res; + const ColVecT0 * const col_left = checkAndGetColumn(col_left_raw); + const ColVecT1 * const col_right = checkAndGetColumn(col_right_raw); + + if constexpr (IsDataTypeDecimal || IsDataTypeDecimal) + return executeNumericWithDecimal( + left, right, + col_left_const, col_right_const, + col_left, col_right, + col_left_size); + else //can't avoid else and another indentation level, otherwise the compiler would try to instantiate + // ColVecResult for Decimals which would lead to a compile error. + { + using OpImpl = BinaryOperationImpl, ResultType>; + + /// non-vector result + if (col_left_const && col_right_const) + { + const auto res = OpImpl::process( + col_left_const->template getValue(), + col_right_const->template getValue()); + + return ResultDataType().createColumnConst(col_left_const->size(), toField(res)); + } + + typename ColVecResult::MutablePtr col_res = ColVecResult::create(); + + auto & vec_res = col_res->getData(); + vec_res.resize(col_left_size); + + if (col_left && col_right) + { + OpImpl::template process( + col_left->getData().data(), + col_right->getData().data(), + vec_res.data(), + vec_res.size()); + } + else if (col_left_const && col_right) + { + const T0 value = col_left_const->template getValue(); + + OpImpl::template process( + &value, + col_right->getData().data(), + vec_res.data(), + vec_res.size()); + } + else if (col_left && col_right_const) + { + const T1 value = col_right_const->template getValue(); + + OpImpl::template process( + col_left->getData().data(), + &value, + vec_res.data(), + vec_res.size()); + } + else + return nullptr; + + return col_res; + } + } } ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override