ClickHouse
88 строк · 2.8 Кб
1#include <DataTypes/DataTypesNumber.h>
2#include <Columns/ColumnsNumber.h>
3#include <Functions/FunctionFactory.h>
4#include <Functions/FunctionHelpers.h>
5#include <Functions/IFunction.h>
6
7
8namespace DB
9{
10
11namespace
12{
13
14/** byteSize() - get the value size in number of bytes for accounting purposes.
15*/
16class FunctionByteSize : public IFunction
17{
18public:
19static constexpr auto name = "byteSize";
20static FunctionPtr create(ContextPtr)
21{
22return std::make_shared<FunctionByteSize>();
23}
24
25String getName() const override { return name; }
26bool useDefaultImplementationForNulls() const override { return false; }
27bool useDefaultImplementationForNothing() const override { return false; }
28bool useDefaultImplementationForLowCardinalityColumns() const override { return false; }
29bool useDefaultImplementationForSparseColumns() const override { return false; }
30bool isVariadic() const override { return true; }
31bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
32size_t getNumberOfArguments() const override { return 0; }
33
34DataTypePtr getReturnTypeImpl(const DataTypes & /*arguments*/) const override
35{
36return std::make_shared<DataTypeUInt64>();
37}
38
39ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
40{
41size_t num_args = arguments.size();
42
43/// If the resulting size is constant, return constant column.
44
45bool all_constant = true;
46UInt64 constant_size = 0;
47for (size_t arg_num = 0; arg_num < num_args; ++arg_num)
48{
49if (arguments[arg_num].type->isValueUnambiguouslyRepresentedInFixedSizeContiguousMemoryRegion())
50{
51constant_size += arguments[arg_num].type->getSizeOfValueInMemory();
52}
53else
54{
55all_constant = false;
56break;
57}
58}
59
60if (all_constant)
61return result_type->createColumnConst(input_rows_count, constant_size);
62
63auto result_col = ColumnUInt64::create(input_rows_count);
64auto & vec_res = result_col->getData();
65for (size_t arg_num = 0; arg_num < num_args; ++arg_num)
66{
67const IColumn * column = arguments[arg_num].column.get();
68
69if (arg_num == 0)
70for (size_t row_num = 0; row_num < input_rows_count; ++row_num)
71vec_res[row_num] = column->byteSizeAt(row_num);
72else
73for (size_t row_num = 0; row_num < input_rows_count; ++row_num)
74vec_res[row_num] += column->byteSizeAt(row_num);
75}
76
77return result_col;
78}
79};
80
81}
82
83REGISTER_FUNCTION(ByteSize)
84{
85factory.registerFunction<FunctionByteSize>();
86}
87
88}
89