Remove code duplication, fix bug, add more tests

This commit is contained in:
avogar 2021-10-04 18:22:06 +03:00
parent ae2754ee56
commit 2523053b27
4 changed files with 142 additions and 87 deletions

View File

@ -451,62 +451,14 @@ public:
}
else if constexpr (is_division && is_decimal_b)
{
if (right_nullmap)
processWithRightNullmapImpl<op_case>(a, b, c, size, right_nullmap, [&scale_a](const auto & left, const auto & right)
{
if constexpr (op_case == OpCase::RightConstant)
{
if ((*right_nullmap)[0])
return;
for (size_t i = 0; i < size; ++i)
c[i] = applyScaledDiv<is_decimal_a>(
undec(a[i]), undec(b), scale_a);
}
else
{
for (size_t i = 0; i < size; ++i)
{
if (!(*right_nullmap)[i])
c[i] = applyScaledDiv<is_decimal_a>(
unwrap<op_case, OpCase::LeftConstant>(a, i), undec(b[i]), scale_a);
}
}
}
else
for (size_t i = 0; i < size; ++i)
c[i] = applyScaledDiv<is_decimal_a>(
unwrap<op_case, OpCase::LeftConstant>(a, i), unwrap<op_case, OpCase::RightConstant>(b, i), scale_a);
return applyScaledDiv<is_decimal_a>(left, right, scale_a);
});
return;
}
if (right_nullmap)
{
if constexpr (op_case == OpCase::RightConstant)
{
if ((*right_nullmap)[0])
return;
for (size_t i = 0; i < size; ++i)
c[i] = apply(undec(a[i]), undec(b));
}
else
{
for (size_t i = 0; i < size; ++i)
{
if (!(*right_nullmap)[i])
c[i] = apply(unwrap<op_case, OpCase::LeftConstant>(a, i), undec(b[i]));
}
}
for (size_t i = 0; i < size; ++i)
{
if (!(*right_nullmap)[i])
c[i] = apply(unwrap<op_case, OpCase::LeftConstant>(a, i), unwrap<op_case, OpCase::RightConstant>(b, i));
}
}
else
for (size_t i = 0; i < size; ++i)
c[i] = apply(unwrap<op_case, OpCase::LeftConstant>(a, i), unwrap<op_case, OpCase::RightConstant>(b, i));
processWithRightNullmapImpl<op_case>(a, b, c, size, right_nullmap, [](const auto & left, const auto & right){ return apply(left, right); });
}
template <bool is_decimal_a, bool is_decimal_b, class A, class B>
@ -527,6 +479,33 @@ public:
}
private:
template <OpCase op_case, typename ApplyFunc>
static inline void processWithRightNullmapImpl(const auto & a, const auto & b, ResultContainerType & c, size_t size, const NullMap * right_nullmap, ApplyFunc apply_func)
{
if (right_nullmap)
{
if constexpr (op_case == OpCase::RightConstant)
{
if ((*right_nullmap)[0])
return;
for (size_t i = 0; i < size; ++i)
c[i] = apply_func(undec(a[i]), undec(b));
}
else
{
for (size_t i = 0; i < size; ++i)
{
if (!(*right_nullmap)[i])
c[i] = apply_func(unwrap<op_case, OpCase::LeftConstant>(a, i), undec(b[i]));
}
}
}
else
for (size_t i = 0; i < size; ++i)
c[i] = apply_func(unwrap<op_case, OpCase::LeftConstant>(a, i), unwrap<op_case, OpCase::RightConstant>(b, i));
}
static constexpr bool is_plus_minus = IsOperation<Operation>::plus ||
IsOperation<Operation>::minus;
static constexpr bool is_multiply = IsOperation<Operation>::multiply;
@ -1573,26 +1552,28 @@ public:
}
/// Special case when the function is plus or minus, one of arguments is Date/DateTime and another is Interval.
if (auto function_builder
= getFunctionForIntervalArithmetic(arguments[0].type, arguments[1].type, context))
if (auto function_builder = getFunctionForIntervalArithmetic(arguments[0].type, arguments[1].type, context))
{
return executeDateTimeIntervalPlusMinus(arguments, result_type, input_rows_count, function_builder);
}
/// Special case when the function is plus, minus or multiply, both arguments are tuples.
if (auto function_builder
= getFunctionForTupleArithmetic(arguments[0].type, arguments[1].type, context))
if (auto function_builder = getFunctionForTupleArithmetic(arguments[0].type, arguments[1].type, context))
{
return function_builder->build(arguments)->execute(arguments, result_type, input_rows_count);
}
/// Special case when the function is multiply or divide, one of arguments is Tuple and another is Number.
if (auto function_builder
= getFunctionForTupleAndNumberArithmetic(arguments[0].type, arguments[1].type, context))
if (auto function_builder = getFunctionForTupleAndNumberArithmetic(arguments[0].type, arguments[1].type, context))
{
return executeTupleNumberOperator(arguments, result_type, input_rows_count, function_builder);
}
return executeImpl2(arguments, result_type, input_rows_count);
}
ColumnPtr executeImpl2(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count, const NullMap * right_nullmap = nullptr) const
{
const auto & left_argument = arguments[0];
const auto & right_argument = arguments[1];

View File

@ -2,51 +2,79 @@
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
1
1
1
1
\N
\N
\N
\N
1
1
1
1
\N
\N
\N
\N
1
1
1
1
\N
\N
\N
\N
1
1
1
1
\N
\N
\N
\N
0
0
0
0
\N
\N
\N
\N
1
1
1
1
\N
\N
\N
\N
0
0
0
0
1
\N
0
0
\N
0
1
0
\N
0
1
0
\N
0
1
0
\N
0
1
0
\N
0
1
\N
0
1
\N
0

View File

@ -4,44 +4,86 @@ SELECT 1 / CAST(materialize(NULL), 'Nullable(Decimal(7, 2))');
SELECT materialize(1) / CAST(materialize(NULL), 'Nullable(Decimal(7, 2))');
SELECT 1 / CAST(1, 'Nullable(Decimal(7, 2))');
SELECT materialize(1) / CAST(1, 'Nullable(Decimal(7, 2))');
SELECT 1 / CAST(materialize(1), 'Nullable(Decimal(7, 2))');
SELECT materialize(1) / CAST(materialize(1), 'Nullable(Decimal(7, 2))');
SELECT intDiv(1, CAST(NULL, 'Nullable(Decimal(7, 2))'));
SELECT intDiv(materialize(1), CAST(NULL, 'Nullable(Decimal(7, 2))'));
SELECT intDiv(1, CAST(materialize(NULL), 'Nullable(Decimal(7, 2))'));
SELECT intDiv(materialize(1), CAST(materialize(NULL), 'Nullable(Decimal(7, 2))'));
SELECT intDiv(1, CAST(1, 'Nullable(Decimal(7, 2))'));
SELECT intDiv(materialize(1), CAST(1, 'Nullable(Decimal(7, 2))'));
SELECT intDiv(1, CAST(materialize(1), 'Nullable(Decimal(7, 2))'));
SELECT intDiv(materialize(1), CAST(materialize(1), 'Nullable(Decimal(7, 2))'));
SELECT toDecimal32(1, 2) / CAST(NULL, 'Nullable(UInt32)');
SELECT materialize(toDecimal32(1, 2)) / CAST(NULL, 'Nullable(UInt32)');
SELECT toDecimal32(1, 2) / CAST(materialize(NULL), 'Nullable(UInt32)');
SELECT materialize(toDecimal32(1, 2)) / CAST(materialize(NULL), 'Nullable(UInt32)');
SELECT toDecimal32(1, 2) / CAST(1, 'Nullable(UInt32)');
SELECT materialize(toDecimal32(1, 2)) / CAST(1, 'Nullable(UInt32)');
SELECT toDecimal32(1, 2) / CAST(materialize(1), 'Nullable(UInt32)');
SELECT materialize(toDecimal32(1, 2)) / CAST(materialize(1), 'Nullable(UInt32)');
SELECT intDiv(1, CAST(NULL, 'Nullable(UInt32)'));
SELECT intDiv(materialize(1), CAST(NULL, 'Nullable(UInt32)'));
SELECT intDiv(1, CAST(materialize(NULL), 'Nullable(UInt32)'));
SELECT intDiv(materialize(1), CAST(materialize(NULL), 'Nullable(UInt32)'));
SELECT intDiv(1, CAST(1, 'Nullable(UInt32)'));
SELECT intDiv(materialize(1), CAST(1, 'Nullable(UInt32)'));
SELECT intDiv(1, CAST(materialize(1), 'Nullable(UInt32)'));
SELECT intDiv(materialize(1), CAST(materialize(1), 'Nullable(UInt32)'));
SELECT 1 % CAST(NULL, 'Nullable(UInt32)');
SELECT materialize(1) % CAST(NULL, 'Nullable(UInt32)');
SELECT 1 % CAST(materialize(NULL), 'Nullable(UInt32)');
SELECT materialize(1) % CAST(materialize(NULL), 'Nullable(UInt32)');
SELECT 1 % CAST(1, 'Nullable(UInt32)');
SELECT materialize(1) % CAST(1, 'Nullable(UInt32)');
SELECT 1 % CAST(materialize(1), 'Nullable(UInt32)');
SELECT materialize(1) % CAST(materialize(1), 'Nullable(UInt32)');
SELECT intDiv(1, CAST(NULL, 'Nullable(Float32)'));
SELECT intDiv(materialize(1), CAST(NULL, 'Nullable(Float32)'));
SELECT intDiv(1, CAST(materialize(NULL), 'Nullable(Float32)'));
SELECT intDiv(materialize(1), CAST(materialize(NULL), 'Nullable(Float32)'));
SELECT intDiv(1, CAST(1, 'Nullable(Float32)'));
SELECT intDiv(materialize(1), CAST(1, 'Nullable(Float32)'));
SELECT intDiv(1, CAST(materialize(1), 'Nullable(Float32)'));
SELECT intDiv(materialize(1), CAST(materialize(1), 'Nullable(Float32)'));
SELECT 1 % CAST(NULL, 'Nullable(Float32)');
SELECT materialize(1) % CAST(NULL, 'Nullable(Float32)');
SELECT 1 % CAST(materialize(NULL), 'Nullable(Float32)');
SELECT materialize(1) % CAST(materialize(NULL), 'Nullable(Float32)');
SELECT 1 % CAST(1, 'Nullable(Float32)');
SELECT materialize(1) % CAST(1, 'Nullable(Float32)');
SELECT 1 % CAST(materialize(1), 'Nullable(Float32)');
SELECT materialize(1) % CAST(materialize(1), 'Nullable(Float32)');
DROP TABLE IF EXISTS nullable_division;
CREATE TABLE nullable_division (x UInt32, y UInt32, a Decimal(7, 2), b Decimal(7, 2)) ENGINE=MergeTree() order by x;
CREATE TABLE nullable_division (x UInt32, y Nullable(UInt32), a Decimal(7, 2), b Nullable(Decimal(7, 2))) ENGINE=MergeTree() order by x;
INSERT INTO nullable_division VALUES (1, 1, 1, 1), (1, NULL, 1, NULL), (1, 0, 1, 0);
SELECT if(y = 0, 0, intDiv(x, y)) from nullable_division;

View File

@ -0,0 +1,4 @@
-1 1 -1000 1000 -10000000 1000000 -1000000000 1000000000 123.123 123123123.12312312 Some string fixed Some data 2000-01-06 2000-06-01 19:42:42 2000-04-01 11:21:33.123
1 (2,(3,4)) (((5)))
1 [1,2,3] [[[1,2,3],[4,5,6]],[[7,8,9],[]],[]]
1 ((2,[[3,4],[5,6],[]]),[([[(7,8),(9,10)],[(11,12),(13,14)],[]],[([15,16,17]),([])])])