mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 01:51:59 +00:00
Supported nullable for runningDifference function. #2590
This commit is contained in:
parent
7a06e6375b
commit
5e3c0c0238
@ -33,6 +33,7 @@
|
||||
#include <Storages/IStorage.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <Storages/getStructureOfRemoteTable.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -1468,7 +1469,7 @@ private:
|
||||
/// It is possible to track value from previous block, to calculate continuously across all blocks. Not implemented.
|
||||
|
||||
template <typename Src, typename Dst>
|
||||
static void process(const PaddedPODArray<Src> & src, PaddedPODArray<Dst> & dst)
|
||||
static void process(const PaddedPODArray<Src> & src, PaddedPODArray<Dst> & dst, const NullMap * null_map)
|
||||
{
|
||||
size_t size = src.size();
|
||||
dst.resize(size);
|
||||
@ -1478,13 +1479,26 @@ private:
|
||||
|
||||
/// It is possible to SIMD optimize this loop. By no need for that in practice.
|
||||
|
||||
dst[0] = is_first_line_zero ? 0 : src[0];
|
||||
Src prev = src[0];
|
||||
for (size_t i = 1; i < size; ++i)
|
||||
Src prev;
|
||||
bool has_prev_value = false;
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
auto cur = src[i];
|
||||
dst[i] = static_cast<Dst>(cur) - prev;
|
||||
prev = cur;
|
||||
if (null_map && (*null_map)[i])
|
||||
continue;
|
||||
|
||||
if (!has_prev_value)
|
||||
{
|
||||
dst[i] = is_first_line_zero ? 0 : src[i];
|
||||
prev = src[i];
|
||||
has_prev_value = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto cur = src[i];
|
||||
dst[i] = static_cast<Dst>(cur) - prev;
|
||||
prev = cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1547,14 +1561,19 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useDefaultImplementationForNulls() const override { return false; }
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
|
||||
{
|
||||
DataTypePtr res;
|
||||
dispatchForSourceType(*arguments[0], [&](auto field_type_tag)
|
||||
dispatchForSourceType(*removeNullable(arguments[0]), [&](auto field_type_tag)
|
||||
{
|
||||
res = std::make_shared<DataTypeNumber<DstFieldType<decltype(field_type_tag)>>>();
|
||||
});
|
||||
|
||||
if (arguments[0]->isNullable())
|
||||
res = makeNullable(res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -1570,16 +1589,29 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
auto res_column = res_type->createColumn();
|
||||
auto res_column = removeNullable(res_type)->createColumn();
|
||||
auto * src_column = src.column.get();
|
||||
ColumnPtr null_map_column = nullptr;
|
||||
const NullMap * null_map = nullptr;
|
||||
if (auto * nullable_column = checkAndGetColumn<ColumnNullable>(src_column))
|
||||
{
|
||||
src_column = &nullable_column->getNestedColumn();
|
||||
null_map_column = nullable_column->getNullMapColumnPtr();
|
||||
null_map = &nullable_column->getNullMapData();
|
||||
}
|
||||
|
||||
dispatchForSourceType(*src.type, [&](auto field_type_tag)
|
||||
dispatchForSourceType(*removeNullable(src.type), [&](auto field_type_tag)
|
||||
{
|
||||
using SrcFieldType = decltype(field_type_tag);
|
||||
process(static_cast<const ColumnVector<SrcFieldType> &>(*src.column).getData(),
|
||||
static_cast<ColumnVector<DstFieldType<SrcFieldType>> &>(*res_column).getData());
|
||||
|
||||
process(static_cast<const ColumnVector<SrcFieldType> &>(*src_column).getData(),
|
||||
static_cast<ColumnVector<DstFieldType<SrcFieldType>> &>(*res_column).getData(), null_map);
|
||||
});
|
||||
|
||||
block.getByPosition(result).column = std::move(res_column);
|
||||
if (null_map_column)
|
||||
block.getByPosition(result).column = ColumnNullable::create(std::move(res_column), null_map_column);
|
||||
else
|
||||
block.getByPosition(result).column = std::move(res_column);
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user