Skip to content

Commit

Permalink
intDiv, intDivOrZero for decimal [issue-3221]
Browse files Browse the repository at this point in the history
  • Loading branch information
4ertus2 committed Sep 26, 2018
1 parent 6000048 commit b48402e
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 44 deletions.
18 changes: 14 additions & 4 deletions dbms/src/Functions/FunctionsArithmetic.h
Original file line number Diff line number Diff line change
Expand Up @@ -742,15 +742,18 @@ struct DecimalBinaryOperation
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>>;
static constexpr bool is_division = std::is_same_v<Operation<Int32, Int32>, DivideFloatingImpl<Int32, Int32>>;
static constexpr bool is_float_division = std::is_same_v<Operation<Int32, Int32>, DivideFloatingImpl<Int32, Int32>>;
static constexpr bool is_int_division = std::is_same_v<Operation<Int32, Int32>, DivideIntegralImpl<Int32, Int32>> ||
std::is_same_v<Operation<Int32, Int32>, DivideIntegralOrZeroImpl<Int32, Int32>>;
static constexpr bool is_division = is_float_division || is_int_division;
static constexpr bool is_compare = std::is_same_v<Operation<Int32, Int32>, LeastBaseImpl<Int32, Int32>> ||
std::is_same_v<Operation<Int32, Int32>, GreatestBaseImpl<Int32, Int32>>;
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,
using Op = std::conditional_t<is_float_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>>;
Expand Down Expand Up @@ -1019,6 +1022,8 @@ struct BinaryOperationTraits
std::is_same_v<Operation<T0, T0>, MinusImpl<T0, T0>> ||
std::is_same_v<Operation<T0, T0>, MultiplyImpl<T0, T0>> ||
std::is_same_v<Operation<T0, T0>, DivideFloatingImpl<T0, T0>> ||
std::is_same_v<Operation<T0, T0>, DivideIntegralImpl<T0, T0>> ||
std::is_same_v<Operation<T0, T0>, DivideIntegralOrZeroImpl<T0, T0>> ||
std::is_same_v<Operation<T0, T0>, LeastBaseImpl<T0, T0>> ||
std::is_same_v<Operation<T0, T0>, GreatestBaseImpl<T0, T0>>;

Expand Down Expand Up @@ -1320,7 +1325,10 @@ class FunctionBinaryArithmetic : public IFunction
if constexpr (IsDataTypeDecimal<LeftDataType> && IsDataTypeDecimal<RightDataType>)
{
constexpr bool is_multiply = std::is_same_v<Op<UInt8, UInt8>, MultiplyImpl<UInt8, UInt8>>;
constexpr bool is_division = std::is_same_v<Op<UInt8, UInt8>, DivideFloatingImpl<UInt8, UInt8>>;
constexpr bool is_division = std::is_same_v<Op<UInt8, UInt8>, DivideFloatingImpl<UInt8, UInt8>> ||
std::is_same_v<Op<UInt8, UInt8>, DivideIntegralImpl<UInt8, UInt8>> ||
std::is_same_v<Op<UInt8, UInt8>, DivideIntegralOrZeroImpl<UInt8, UInt8>>;

ResultDataType result_type = decimalResultType(left, right, is_multiply, is_division);
type_res = std::make_shared<ResultDataType>(result_type.getPrecision(), result_type.getScale());
}
Expand Down Expand Up @@ -1374,7 +1382,9 @@ class FunctionBinaryArithmetic : public IFunction
{
constexpr bool result_is_decimal = IsDataTypeDecimal<LeftDataType> || IsDataTypeDecimal<RightDataType>;
constexpr bool is_multiply = std::is_same_v<Op<UInt8, UInt8>, MultiplyImpl<UInt8, UInt8>>;
constexpr bool is_division = std::is_same_v<Op<UInt8, UInt8>, DivideFloatingImpl<UInt8, UInt8>>;
constexpr bool is_division = std::is_same_v<Op<UInt8, UInt8>, DivideFloatingImpl<UInt8, UInt8>> ||
std::is_same_v<Op<UInt8, UInt8>, DivideIntegralImpl<UInt8, UInt8>> ||
std::is_same_v<Op<UInt8, UInt8>, DivideIntegralOrZeroImpl<UInt8, UInt8>>;

using T0 = typename LeftDataType::FieldType;
using T1 = typename RightDataType::FieldType;
Expand Down
39 changes: 21 additions & 18 deletions dbms/tests/queries/0_stateless/00700_decimal_arithm.reference
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
84 0 1764 1
84 0 1764 1
84 0 1764 1
84.840 0.000 1799.456400 1.000
84 0 1764 1 1 1
84 0 1764 1 1 1
84 0 1764 1 1 1
84.840 0.000 1799.456400 1.000 1.000 1.000
84.840000000 0.000000000
84.840000000000000000 0.000000000000000000
84.84 0.00 1799.4564 1.00
63 21 -42 882 -882 2 0
63 21 -42 882 -882 2 0
63 21 -42 882 -882 2 0
63.420 21.420 -41.580 890.820 -890.820 2.020 0.505
63.420000000 21.420000000 -41.580000000 890.820000000 -890.820000000 2.020000000 0.505000000
63.420000000000000000 21.420000000000000000 -41.580000000000000000 890.820000000000000000 -890.820000000000000000 2.020000000000000000 0.505000000000000000
63.42 21.42 -41.58 890.82 -890.82 2.02 0.50
63 -21 42 882 -882 0 2
63 -21 42 882 -882 0 2
63 -21 42 882 -882 0 2
63.420 -21.420 41.580 890.820 -890.820 0.495 1.980
84.84 0.00 1799.4564 1.00 1.00 1.00
63 21 -42 882 -882 2 0 2 0
63 21 -42 882 -882 2 0 2 0
63 21 -42 882 -882 2 0 2 0
63.420 21.420 -41.580 890.820 -890.820 2.020 0.505 2.020 0.505
63.420000000 21.420000000 -41.580000000 890.820000000 -890.820000000 2.020000000 0.505000000 2.020000000 0.505000000
63.420000000000000000 21.420000000000000000 -41.580000000000000000 890.820000000000000000 -890.820000000000000000 2.020000000000000000 0.505000000000000000 2.020000000000000000 0.505000000000000000
63.42 21.42 -41.58 890.82 -890.82 2.02 0.50 2.02 0.50
63 -21 42 882 -882 0 2 0 2
63 -21 42 882 -882 0 2 0 2
63 -21 42 882 -882 0 2 0 2
63.420 -21.420 41.580 890.820 -890.820 0.495 1.980 0.495 1.980
63.420000000 -21.420000000 41.580000000 890.820000000 -890.820000000
63.420000000000000000 -21.420000000000000000 41.580000000000000000 890.820000000000000000 -890.820000000000000000 0.495049504950495049 1.980198019801980198
63.42 -21.42 41.58 890.82 -890.82 0.49 1.98
63.420000000000000000 -21.420000000000000000 41.580000000000000000 890.820000000000000000 -890.820000000000000000 0.495049504950495049 1.980198019801980198 0.495049504950495049 1.980198019801980198
63.42 -21.42 41.58 890.82 -890.82 0.49 1.98 0.49 1.98
-42 42 42 42 0.420000000 0.420000000000000000 0.42000000000000000000000000000000000000 42.420 42.420000000 42.42
0 0 0 0 0.000000000 0.000000000000000000 0.00000000000000000000000000000000000000 0.000 0.000000000 0.00
42 -42 -42 -42 -0.420000000 -0.420000000000000000 -0.42000000000000000000000000000000000000 -42.420 -42.420000000 -42.42
Expand All @@ -29,3 +29,6 @@
1 1
1 0 1 0
1 0 1 0
0.0000 \N \N
0.00000000 \N \N
0.000000000000000000 \N \N
48 changes: 26 additions & 22 deletions dbms/tests/queries/0_stateless/00700_decimal_arithm.sql
Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,38 @@ INSERT INTO test.decimal (a, b, c, d, e, f, g, h, i, j) VALUES (0, 0, 0, 0, 0, 0
INSERT INTO test.decimal (a, b, c, d, e, f, g, h, i, j) VALUES (42, 42, 42, 0.42, 0.42, 0.42, 42.42, 42.42, 42.42, 42.42);
INSERT INTO test.decimal (a, b, c, d, e, f, g, h, i, j) VALUES (-42, -42, -42, -0.42, -0.42, -0.42, -42.42, -42.42, -42.42, -42.42);

SELECT a + a, a - a, a * a, a / a FROM test.decimal WHERE a = 42;
SELECT b + b, b - b, b * b, b / b FROM test.decimal WHERE b = 42;
SELECT c + c, c - c, c * c, c / c FROM test.decimal WHERE c = 42;
SELECT e + e, e - e, e * e, e / e FROM test.decimal WHERE e > 0; -- { serverError 69 }
SELECT f + f, f - f, f * f, f / f FROM test.decimal WHERE f > 0; -- { serverError 69 }
SELECT g + g, g - g, g * g, g / g FROM test.decimal WHERE g > 0;
SELECT h + h, h - h, h * h, h / h FROM test.decimal WHERE h > 0; -- { serverError 407 }
SELECT a + a, a - a, a * a, a / a, intDiv(a, a), intDivOrZero(a, a) FROM test.decimal WHERE a = 42;
SELECT b + b, b - b, b * b, b / b, intDiv(b, b), intDivOrZero(b, b) FROM test.decimal WHERE b = 42;
SELECT c + c, c - c, c * c, c / c, intDiv(c, c), intDivOrZero(c, c) FROM test.decimal WHERE c = 42;
SELECT e + e, e - e, e * e, e / e, intDiv(e, e), intDivOrZero(e, e) FROM test.decimal WHERE e > 0; -- { serverError 69 }
SELECT f + f, f - f, f * f, f / f, intDiv(f, f), intDivOrZero(f, f) FROM test.decimal WHERE f > 0; -- { serverError 69 }
SELECT g + g, g - g, g * g, g / g, intDiv(g, g), intDivOrZero(g, g) FROM test.decimal WHERE g > 0;
SELECT h + h, h - h, h * h, h / h, intDiv(h, h), intDivOrZero(h, h) FROM test.decimal WHERE h > 0; -- { serverError 407 }
SELECT h + h, h - h FROM test.decimal WHERE h > 0;
SELECT i + i, i - i, i * i, i / i FROM test.decimal WHERE i > 0; -- { serverError 407 }
SELECT i + i, i - i, i * i, i / i, intDiv(i, i), intDivOrZero(i, i) FROM test.decimal WHERE i > 0; -- { serverError 407 }
SELECT i + i, i - i FROM test.decimal WHERE i > 0;
SELECT j + j, j - j, j * j, j / j FROM test.decimal WHERE j > 0;
SELECT j + j, j - j, j * j, j / j, intDiv(j, j), intDivOrZero(j, j) FROM test.decimal WHERE j > 0;

SELECT a + 21, a - 21, a - 84, a * 21, a * -21, a / 21, a / 84 FROM test.decimal WHERE a = 42;
SELECT b + 21, b - 21, b - 84, b * 21, b * -21, b / 21, b / 84 FROM test.decimal WHERE b = 42;
SELECT c + 21, c - 21, c - 84, c * 21, c * -21, c / 21, c / 84 FROM test.decimal WHERE c = 42;
SELECT a + 21, a - 21, a - 84, a * 21, a * -21, a / 21, a / 84, intDiv(a, 21), intDivOrZero(a, 84) FROM test.decimal WHERE a = 42;
SELECT b + 21, b - 21, b - 84, b * 21, b * -21, b / 21, b / 84, intDiv(b, 21), intDivOrZero(b, 84) FROM test.decimal WHERE b = 42;
SELECT c + 21, c - 21, c - 84, c * 21, c * -21, c / 21, c / 84, intDiv(c, 21), intDivOrZero(c, 84) FROM test.decimal WHERE c = 42;
SELECT e + 21, e - 21, e - 84, e * 21, e * -21, e / 21, e / 84 FROM test.decimal WHERE e > 0; -- { serverError 407 }
SELECT f + 21, f - 21, f - 84, f * 21, f * -21, f / 21, f / 84 FROM test.decimal WHERE f > 0; -- { serverError 407 }
SELECT g + 21, g - 21, g - 84, g * 21, g * -21, g / 21, g / 84 FROM test.decimal WHERE g > 0;
SELECT h + 21, h - 21, h - 84, h * 21, h * -21, h / 21, h / 84 FROM test.decimal WHERE h > 0;
SELECT i + 21, i - 21, i - 84, i * 21, i * -21, i / 21, i / 84 FROM test.decimal WHERE i > 0;
SELECT j + 21, j - 21, j - 84, j * 21, j * -21, j / 21, j / 84 FROM test.decimal WHERE j > 0;
SELECT g + 21, g - 21, g - 84, g * 21, g * -21, g / 21, g / 84, intDiv(g, 21), intDivOrZero(g, 84) FROM test.decimal WHERE g > 0;
SELECT h + 21, h - 21, h - 84, h * 21, h * -21, h / 21, h / 84, intDiv(h, 21), intDivOrZero(h, 84) FROM test.decimal WHERE h > 0;
SELECT i + 21, i - 21, i - 84, i * 21, i * -21, i / 21, i / 84, intDiv(i, 21), intDivOrZero(i, 84) FROM test.decimal WHERE i > 0;
SELECT j + 21, j - 21, j - 84, j * 21, j * -21, j / 21, j / 84, intDiv(j, 21), intDivOrZero(j, 84) FROM test.decimal WHERE j > 0;

SELECT 21 + a, 21 - a, 84 - a, 21 * a, -21 * a, 21 / a, 84 / a FROM test.decimal WHERE a = 42;
SELECT 21 + b, 21 - b, 84 - b, 21 * b, -21 * b, 21 / b, 84 / b FROM test.decimal WHERE b = 42;
SELECT 21 + c, 21 - c, 84 - c, 21 * c, -21 * c, 21 / c, 84 / c FROM test.decimal WHERE c = 42;
SELECT 21 + a, 21 - a, 84 - a, 21 * a, -21 * a, 21 / a, 84 / a, intDiv(21, a), intDivOrZero(84, a) FROM test.decimal WHERE a = 42;
SELECT 21 + b, 21 - b, 84 - b, 21 * b, -21 * b, 21 / b, 84 / b, intDiv(21, b), intDivOrZero(84, b) FROM test.decimal WHERE b = 42;
SELECT 21 + c, 21 - c, 84 - c, 21 * c, -21 * c, 21 / c, 84 / c, intDiv(21, c), intDivOrZero(84, c) FROM test.decimal WHERE c = 42;
SELECT 21 + e, 21 - e, 84 - e, 21 * e, -21 * e, 21 / e, 84 / e FROM test.decimal WHERE e > 0; -- { serverError 407 }
SELECT 21 + f, 21 - f, 84 - f, 21 * f, -21 * f, 21 / f, 84 / f FROM test.decimal WHERE f > 0; -- { serverError 407 }
SELECT 21 + g, 21 - g, 84 - g, 21 * g, -21 * g, 21 / g, 84 / g FROM test.decimal WHERE g > 0;
SELECT 21 + g, 21 - g, 84 - g, 21 * g, -21 * g, 21 / g, 84 / g, intDiv(21, g), intDivOrZero(84, g) FROM test.decimal WHERE g > 0;
SELECT 21 + h, 21 - h, 84 - h, 21 * h, -21 * h, 21 / h, 84 / h FROM test.decimal WHERE h > 0; -- { serverError 407 }
SELECT 21 + h, 21 - h, 84 - h, 21 * h, -21 * h FROM test.decimal WHERE h > 0;
SELECT 21 + i, 21 - i, 84 - i, 21 * i, -21 * i, 21 / i, 84 / i FROM test.decimal WHERE i > 0;
SELECT 21 + j, 21 - j, 84 - j, 21 * j, -21 * j, 21 / j, 84 / j FROM test.decimal WHERE j > 0;
SELECT 21 + i, 21 - i, 84 - i, 21 * i, -21 * i, 21 / i, 84 / i, intDiv(21, i), intDivOrZero(84, i) FROM test.decimal WHERE i > 0;
SELECT 21 + j, 21 - j, 84 - j, 21 * j, -21 * j, 21 / j, 84 / j, intDiv(21, j), intDivOrZero(84, j) FROM test.decimal WHERE j > 0;

SELECT a, -a, -b, -c, -d, -e, -f, -g, -h, -j from test.decimal ORDER BY a;
SELECT abs(a), abs(b), abs(c), abs(d), abs(e), abs(f), abs(g), abs(h), abs(j) from test.decimal ORDER BY a;
Expand All @@ -77,4 +77,8 @@ SELECT toDecimal32(0, 0) / toInt8(0); -- { serverError 153 }
SELECT toDecimal64(0, 1) / toInt32(0); -- { serverError 153 }
SELECT toDecimal128(0, 2) / toInt64(0); -- { serverError 153 }

SELECT toDecimal32(0, 4) AS x, multiIf(x = 0, NULL, intDivOrZero(1, x)), multiIf(x = 0, NULL, intDivOrZero(x, 0));
SELECT toDecimal64(0, 8) AS x, multiIf(x = 0, NULL, intDivOrZero(1, x)), multiIf(x = 0, NULL, intDivOrZero(x, 0));
SELECT toDecimal64(0, 18) AS x, multiIf(x = 0, NULL, intDivOrZero(1, x)), multiIf(x = 0, NULL, intDivOrZero(x, 0));

DROP TABLE IF EXISTS test.decimal;

0 comments on commit b48402e

Please sign in to comment.