ClickHouse/dbms/src/Functions/blockSerializedSize.cpp
Azat Khuzhin e89ceae61a Add blockSerializedSize() function (size on disk without compression)
Sometimes it is useful to know how much does this data will take on
disk, with blockSerializedSize() you can know this (although without
compression).

This can be a major knowledge for various aggregation functions that
tracking some state (i.e. uniqCombined).
2020-02-03 11:26:40 +03:00

67 lines
2.0 KiB
C++

#include <Functions/IFunctionImpl.h>
#include <Functions/FunctionFactory.h>
#include <DataTypes/DataTypesNumber.h>
#include <IO/NullWriteBuffer.h>
namespace DB
{
/// Returns size on disk for *block* (without taking into account compression).
class FunctionBlockSerializedSize : public IFunction
{
public:
static constexpr auto name = "blockSerializedSize";
static FunctionPtr create(const Context &)
{
return std::make_shared<FunctionBlockSerializedSize>();
}
String getName() const override { return name; }
bool useDefaultImplementationForNulls() const override { return false; }
size_t getNumberOfArguments() const override { return 0; }
bool isVariadic() const override { return true; }
DataTypePtr getReturnTypeImpl(const DataTypes & /*arguments*/) const override
{
return std::make_shared<DataTypeUInt64>();
}
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override
{
UInt64 size = 0;
for (size_t i = 0; i < arguments.size(); ++i)
size += blockSerializedSizeOne(block.getByPosition(arguments[i]));
block.getByPosition(result).column = DataTypeUInt64().createColumnConst(
input_rows_count, size)->convertToFullColumnIfConst();
}
UInt64 blockSerializedSizeOne(const ColumnWithTypeAndName & elem) const
{
ColumnPtr full_column = elem.column->convertToFullColumnIfConst();
IDataType::SerializeBinaryBulkSettings settings;
NullWriteBuffer out;
settings.getter = [&out](IDataType::SubstreamPath) -> WriteBuffer * { return &out; };
IDataType::SerializeBinaryBulkStatePtr state;
elem.type->serializeBinaryBulkWithMultipleStreams(*full_column,
0 /** offset */, 0 /** limit */,
settings, state);
return out.count();
}
};
void registerFunctionBlockSerializedSize(FunctionFactory & factory)
{
factory.registerFunction<FunctionBlockSerializedSize>();
}
}