ClickHouse
67 строк · 2.2 Кб
1#include <Functions/IFunction.h>
2#include <Functions/FunctionFactory.h>
3#include <Functions/FunctionHelpers.h>
4
5namespace DB
6{
7
8namespace ErrorCodes
9{
10extern const int ILLEGAL_COLUMN;
11}
12
13namespace
14{
15
16class FunctionGetSubcolumn : public IFunction
17{
18public:
19static constexpr auto name = "getSubcolumn";
20static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionGetSubcolumn>(); }
21
22String getName() const override { return name; }
23size_t getNumberOfArguments() const override { return 2; }
24bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo &) const override { return true; }
25bool useDefaultImplementationForConstants() const override { return true; }
26ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; }
27
28DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
29{
30auto subcolumn_name = getSubcolumnName(arguments);
31return arguments[0].type->getSubcolumnType(subcolumn_name);
32}
33
34ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
35{
36auto subcolumn_name = getSubcolumnName(arguments);
37return arguments[0].type->getSubcolumn(subcolumn_name, arguments[0].column);
38}
39
40private:
41static std::string_view getSubcolumnName(const ColumnsWithTypeAndName & arguments)
42{
43const auto * column = arguments[1].column.get();
44if (!isString(arguments[1].type) || !column || !checkAndGetColumnConstStringOrFixedString(column))
45throw Exception(ErrorCodes::ILLEGAL_COLUMN,
46"The second argument of function {} should be a constant string with the name of a subcolumn", name);
47
48return column->getDataAt(0).toView();
49}
50};
51
52}
53
54REGISTER_FUNCTION(GetSubcolumn)
55{
56factory.registerFunction<FunctionGetSubcolumn>(FunctionDocumentation{
57.description=R"(
58Receives the expression or identifier and constant string with the name of subcolumn.
59
60Returns requested subcolumn extracted from the expression.
61)",
62.examples{{"getSubcolumn", "SELECT getSubcolumn(array_col, 'size0'), getSubcolumn(tuple_col, 'elem_name')", ""}},
63.categories{"OtherFunctions"}
64});
65}
66
67}
68