ClickHouse

Форк
0
/
tupleConcat.cpp 
104 строки · 3.3 Кб
1
#include <Columns/ColumnTuple.h>
2
#include <DataTypes/DataTypeTuple.h>
3
#include <Functions/FunctionFactory.h>
4
#include <Functions/FunctionHelpers.h>
5
#include <Functions/IFunction.h>
6

7
#include <base/range.h>
8

9
namespace DB
10
{
11
namespace ErrorCodes
12
{
13
    extern const int ILLEGAL_TYPE_OF_ARGUMENT;
14
    extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
15
    extern const int ILLEGAL_COLUMN;
16
}
17

18
/// tupleConcat(tup1, ...) - concatenate tuples.
19
class FunctionTupleConcat : public IFunction
20
{
21
public:
22
    static constexpr auto name = "tupleConcat";
23
    static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionTupleConcat>(); }
24

25
    String getName() const override { return name; }
26

27
    bool isVariadic() const override { return true; }
28

29
    size_t getNumberOfArguments() const override { return 0; }
30

31
    bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return true; }
32

33
    bool useDefaultImplementationForConstants() const override { return true; }
34

35
    DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
36
    {
37
        if (arguments.empty())
38
            throw Exception(
39
                ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
40
                "Function {} requires at least one argument.",
41
                getName());
42

43
        DataTypes tuple_arg_types;
44

45
        for (const auto arg_idx : collections::range(0, arguments.size()))
46
        {
47
            const auto * arg = arguments[arg_idx].get();
48
            if (!isTuple(arg))
49
                throw Exception(
50
                    ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
51
                    "Illegal type {} of argument {} of function {}",
52
                    arg->getName(),
53
                    arg_idx + 1,
54
                    getName());
55

56
            const auto * type = checkAndGetDataType<DataTypeTuple>(arg);
57
            for (const auto & elem : type->getElements())
58
                tuple_arg_types.push_back(elem);
59
        }
60

61
        return std::make_shared<DataTypeTuple>(tuple_arg_types);
62
    }
63

64
    ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t) const override
65
    {
66
        const size_t num_arguments = arguments.size();
67
        Columns columns;
68

69
        for (size_t i = 0; i < num_arguments; i++)
70
        {
71
            const DataTypeTuple * arg_type = checkAndGetDataType<DataTypeTuple>(arguments[i].type.get());
72

73
            if (!arg_type)
74
                throw Exception(
75
                    ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
76
                    "Illegal type {} of argument {} of function {}",
77
                    arguments[i].type->getName(),
78
                    i + 1,
79
                    getName());
80

81
            ColumnPtr arg_col = arguments[i].column->convertToFullColumnIfConst();
82
            const ColumnTuple * tuple_col = checkAndGetColumn<ColumnTuple>(arg_col.get());
83

84
            if (!tuple_col)
85
                throw Exception(
86
                    ErrorCodes::ILLEGAL_COLUMN,
87
                    "Illegal column {} of argument of function {}",
88
                    arguments[i].column->getName(),
89
                    getName());
90

91
            for (const auto & inner_col : tuple_col->getColumns())
92
                columns.push_back(inner_col);
93
        }
94

95
        return ColumnTuple::create(columns);
96
    }
97
};
98

99
REGISTER_FUNCTION(TupleConcat)
100
{
101
    factory.registerFunction<FunctionTupleConcat>();
102
}
103

104
}
105

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.