ClickHouse
67 строк · 2.3 Кб
1#include <Functions/replicate.h>
2#include <Functions/IFunction.h>
3#include <Functions/FunctionFactory.h>
4#include <Functions/FunctionHelpers.h>
5#include <DataTypes/DataTypeArray.h>
6#include <Columns/ColumnArray.h>
7#include <Interpreters/Context.h>
8
9
10namespace DB
11{
12namespace ErrorCodes
13{
14extern const int ILLEGAL_TYPE_OF_ARGUMENT;
15extern const int ILLEGAL_COLUMN;
16extern const int TOO_FEW_ARGUMENTS_FOR_FUNCTION;
17}
18
19DataTypePtr FunctionReplicate::getReturnTypeImpl(const DataTypes & arguments) const
20{
21if (arguments.size() < 2)
22throw Exception(ErrorCodes::TOO_FEW_ARGUMENTS_FOR_FUNCTION,
23"Function {} expect at least two arguments, got {}", getName(), arguments.size());
24
25for (size_t i = 1; i < arguments.size(); ++i)
26{
27const DataTypeArray * array_type = checkAndGetDataType<DataTypeArray>(arguments[i].get());
28if (!array_type)
29throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
30"Argument {} for function {} must be array.",
31i + 1, getName());
32}
33return std::make_shared<DataTypeArray>(arguments[0]);
34}
35
36ColumnPtr FunctionReplicate::executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t) const
37{
38ColumnPtr first_column = arguments[0].column;
39ColumnPtr offsets;
40
41for (size_t i = 1; i < arguments.size(); ++i)
42{
43const ColumnArray * array_column = checkAndGetColumn<ColumnArray>(arguments[i].column.get());
44ColumnPtr temp_column;
45if (!array_column)
46{
47const auto * const_array_column = checkAndGetColumnConst<ColumnArray>(arguments[i].column.get());
48if (!const_array_column)
49throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Unexpected column for replicate");
50temp_column = const_array_column->convertToFullColumn();
51array_column = checkAndGetColumn<ColumnArray>(temp_column.get());
52}
53
54if (!offsets || offsets->empty())
55offsets = array_column->getOffsetsPtr();
56}
57
58const auto & offsets_data = assert_cast<const ColumnArray::ColumnOffsets &>(*offsets).getData(); /// NOLINT
59return ColumnArray::create(first_column->replicate(offsets_data)->convertToFullColumnIfConst(), offsets);
60}
61
62REGISTER_FUNCTION(Replicate)
63{
64factory.registerFunction<FunctionReplicate>();
65}
66
67}
68