fix crash on decimal division by zero [issue-3221]

This commit is contained in:
chertus 2018-09-26 14:25:50 +03:00
parent b326b95592
commit 69dd660919
2 changed files with 23 additions and 10 deletions

View File

@ -739,16 +739,6 @@ template <> struct NativeType<Decimal128> { using Type = Int128; };
template <typename A, typename B, template <typename, typename> typename Operation, typename ResultType_, bool _check_overflow = true>
struct DecimalBinaryOperation
{
using ResultType = ResultType_;
using NativeResultType = typename NativeType<ResultType>::Type;
using Op = Operation<NativeResultType, NativeResultType>;
using ColVecA = std::conditional_t<IsDecimalNumber<A>, ColumnDecimal<A>, ColumnVector<A>>;
using ColVecB = std::conditional_t<IsDecimalNumber<B>, ColumnDecimal<B>, ColumnVector<B>>;
using ArrayA = typename ColVecA::Container;
using ArrayB = typename ColVecB::Container;
using ArrayC = typename ColumnDecimal<ResultType>::Container;
using SelfNoOverflow = DecimalBinaryOperation<A, B, Operation, ResultType_, false>;
static constexpr bool is_plus_minus = std::is_same_v<Operation<Int32, Int32>, PlusImpl<Int32, Int32>> ||
std::is_same_v<Operation<Int32, Int32>, MinusImpl<Int32, Int32>>;
static constexpr bool is_multiply = std::is_same_v<Operation<Int32, Int32>, MultiplyImpl<Int32, Int32>>;
@ -758,6 +748,18 @@ struct DecimalBinaryOperation
static constexpr bool is_plus_minus_compare = is_plus_minus || is_compare;
static constexpr bool can_overflow = is_plus_minus || is_multiply;
using ResultType = ResultType_;
using NativeResultType = typename NativeType<ResultType>::Type;
using Op = std::conditional_t<is_division,
DivideIntegralImpl<NativeResultType, NativeResultType>, /// substitute divide by intDiv (throw on division by zero)
Operation<NativeResultType, NativeResultType>>;
using ColVecA = std::conditional_t<IsDecimalNumber<A>, ColumnDecimal<A>, ColumnVector<A>>;
using ColVecB = std::conditional_t<IsDecimalNumber<B>, ColumnDecimal<B>, ColumnVector<B>>;
using ArrayA = typename ColVecA::Container;
using ArrayB = typename ColVecB::Container;
using ArrayC = typename ColumnDecimal<ResultType>::Container;
using SelfNoOverflow = DecimalBinaryOperation<A, B, Operation, ResultType_, false>;
static void vector_vector(const ArrayA & a, const ArrayB & b, ArrayC & c, ResultType scale_a, ResultType scale_b, bool check_overflow)
{
if (check_overflow)

View File

@ -66,4 +66,15 @@ SELECT (i * i) != 0, (i / i) = 1 FROM test.decimal WHERE i > 0;
SELECT e + 1 > e, e + 10 > e, 1 + e > e, 10 + e > e FROM test.decimal WHERE e > 0;
SELECT f + 1 > f, f + 10 > f, 1 + f > f, 10 + f > f FROM test.decimal WHERE f > 0;
SELECT 1 / toDecimal32(0, 0); -- { serverError 153 }
SELECT 1 / toDecimal64(0, 1); -- { serverError 153 }
SELECT 1 / toDecimal128(0, 2); -- { serverError 153 }
SELECT 0 / toDecimal32(0, 3); -- { serverError 153 }
SELECT 0 / toDecimal64(0, 4); -- { serverError 153 }
SELECT 0 / toDecimal128(0, 5); -- { serverError 153 }
SELECT toDecimal32(0, 0) / toInt8(0); -- { serverError 153 }
SELECT toDecimal64(0, 1) / toInt32(0); -- { serverError 153 }
SELECT toDecimal128(0, 2) / toInt64(0); -- { serverError 153 }
DROP TABLE IF EXISTS test.decimal;