mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
Remove code duplication, fix bug, add more tests
This commit is contained in:
parent
ae2754ee56
commit
2523053b27
@ -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];
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
4
tests/queries/0_stateless/tmp
Normal file
4
tests/queries/0_stateless/tmp
Normal 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]),([])])])
|
Loading…
Reference in New Issue
Block a user