mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
unari arithm operations for decimal (partial support)
This commit is contained in:
parent
e31e4e164f
commit
a338f657d5
@ -602,7 +602,9 @@ struct AbsImpl
|
||||
|
||||
static inline ResultType apply(A a)
|
||||
{
|
||||
if constexpr (std::is_integral_v<A> && std::is_signed_v<A>)
|
||||
if constexpr (std::is_same_v<A, __int128>)
|
||||
return a < 0 ? -a : a;
|
||||
else if constexpr (std::is_integral_v<A> && std::is_signed_v<A>)
|
||||
return a < 0 ? static_cast<ResultType>(~a) + 1 : a;
|
||||
else if constexpr (std::is_integral_v<A> && std::is_unsigned_v<A>)
|
||||
return static_cast<ResultType>(a);
|
||||
@ -1238,6 +1240,9 @@ struct FunctionUnaryArithmeticMonotonicity;
|
||||
template <template <typename> class Op, typename Name, bool is_injective>
|
||||
class FunctionUnaryArithmetic : public IFunction
|
||||
{
|
||||
//static constexpr bool allow_decimal = std::is_same_v<Op<Int8>, NegateImpl<Int8>> || std::is_same_v<Op<Int8>, AbsImpl<Int8>>;
|
||||
static constexpr bool allow_decimal = std::is_same_v<Op<Int8>, NegateImpl<Int8>>;
|
||||
|
||||
template <typename F>
|
||||
static bool castType(const IDataType * type, F && f)
|
||||
{
|
||||
@ -1251,7 +1256,10 @@ class FunctionUnaryArithmetic : public IFunction
|
||||
DataTypeInt32,
|
||||
DataTypeInt64,
|
||||
DataTypeFloat32,
|
||||
DataTypeFloat64
|
||||
DataTypeFloat64,
|
||||
DataTypeDecimal<Int32>,
|
||||
DataTypeDecimal<Int64>
|
||||
//DataTypeDecimal<Int128> // TODO: needs visitor
|
||||
>(type, std::forward<F>(f));
|
||||
}
|
||||
|
||||
@ -1274,8 +1282,17 @@ public:
|
||||
DataTypePtr result;
|
||||
bool valid = castType(arguments[0].get(), [&](const auto & type)
|
||||
{
|
||||
using T0 = typename std::decay_t<decltype(type)>::FieldType;
|
||||
result = std::make_shared<DataTypeNumber<typename Op<T0>::ResultType>>();
|
||||
using DataType = std::decay_t<decltype(type)>;
|
||||
using T0 = typename DataType::FieldType;
|
||||
|
||||
if constexpr (IsDecimal<DataType>)
|
||||
{
|
||||
if constexpr (!allow_decimal)
|
||||
return false;
|
||||
result = std::make_shared<DataType>(type.getPrecision(), type.getScale());
|
||||
}
|
||||
else
|
||||
result = std::make_shared<DataTypeNumber<typename Op<T0>::ResultType>>();
|
||||
return true;
|
||||
});
|
||||
if (!valid)
|
||||
@ -1288,16 +1305,37 @@ public:
|
||||
{
|
||||
bool valid = castType(block.getByPosition(arguments[0]).type.get(), [&](const auto & type)
|
||||
{
|
||||
using T0 = typename std::decay_t<decltype(type)>::FieldType;
|
||||
if (auto col = checkAndGetColumn<ColumnVector<T0>>(block.getByPosition(arguments[0]).column.get()))
|
||||
using DataType = std::decay_t<decltype(type)>;
|
||||
using T0 = typename DataType::FieldType;
|
||||
|
||||
if constexpr (IsDecimal<DataType>)
|
||||
{
|
||||
auto col_res = ColumnVector<typename Op<T0>::ResultType>::create();
|
||||
auto & vec_res = col_res->getData();
|
||||
vec_res.resize(col->getData().size());
|
||||
UnaryOperationImpl<T0, Op<T0>>::vector(col->getData(), vec_res);
|
||||
block.getByPosition(result).column = std::move(col_res);
|
||||
return true;
|
||||
if constexpr (allow_decimal)
|
||||
{
|
||||
if (auto col = checkAndGetColumn<ColumnVector<T0, false>>(block.getByPosition(arguments[0]).column.get()))
|
||||
{
|
||||
auto col_res = ColumnVector<typename Op<T0>::ResultType, false>::create();
|
||||
auto & vec_res = col_res->getData();
|
||||
vec_res.resize(col->getData().size());
|
||||
UnaryOperationImpl<T0, Op<T0>>::vector(col->getData(), vec_res);
|
||||
block.getByPosition(result).column = std::move(col_res);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto col = checkAndGetColumn<ColumnVector<T0>>(block.getByPosition(arguments[0]).column.get()))
|
||||
{
|
||||
auto col_res = ColumnVector<typename Op<T0>::ResultType>::create();
|
||||
auto & vec_res = col_res->getData();
|
||||
vec_res.resize(col->getData().size());
|
||||
UnaryOperationImpl<T0, Op<T0>>::vector(col->getData(), vec_res);
|
||||
block.getByPosition(result).column = std::move(col_res);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
if (!valid)
|
||||
|
@ -17,3 +17,6 @@
|
||||
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
|
||||
-42 42 42 0.420000000 0.420000000000000000 42.420 42.420000000 42.42
|
||||
0 0 0 0.000000000 0.000000000000000000 0.000 0.000000000 0.00
|
||||
42 -42 -42 -0.420000000 -0.420000000000000000 -42.420 -42.420000000 -42.42
|
||||
|
@ -49,4 +49,6 @@ 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 a, -a, -b, -d, -e, -g, -h, -j from test.decimal ORDER BY a;
|
||||
|
||||
DROP TABLE IF EXISTS test.decimal;
|
||||
|
Loading…
Reference in New Issue
Block a user