1 | #include <Functions/IFunctionImpl.h> |
---|---|
2 | #include <Functions/FunctionFactory.h> |
3 | #include <Functions/FunctionHelpers.h> |
4 | #include <DataTypes/DataTypeString.h> |
5 | #include <Columns/ColumnString.h> |
6 | #include <Interpreters/Context.h> |
7 | #include <Common/Macros.h> |
8 | #include <Core/Field.h> |
9 | |
10 | |
11 | namespace DB |
12 | { |
13 | |
14 | namespace ErrorCodes |
15 | { |
16 | extern const int ILLEGAL_TYPE_OF_ARGUMENT; |
17 | extern const int ILLEGAL_COLUMN; |
18 | } |
19 | |
20 | /** Get the value of macro from configuration file. |
21 | * For example, it may be used as a sophisticated replacement for the function 'hostName' if servers have complicated hostnames |
22 | * but you still need to distinguish them by some convenient names. |
23 | */ |
24 | class FunctionGetMacro : public IFunction |
25 | { |
26 | private: |
27 | MultiVersion<Macros>::Version macros; |
28 | |
29 | public: |
30 | static constexpr auto name = "getMacro"; |
31 | static FunctionPtr create(const Context & context) |
32 | { |
33 | return std::make_shared<FunctionGetMacro>(context.getMacros()); |
34 | } |
35 | |
36 | FunctionGetMacro(MultiVersion<Macros>::Version macros_) : macros(std::move(macros_)) {} |
37 | |
38 | String getName() const override |
39 | { |
40 | return name; |
41 | } |
42 | |
43 | bool isDeterministic() const override { return false; } |
44 | |
45 | bool isDeterministicInScopeOfQuery() const override |
46 | { |
47 | return false; |
48 | } |
49 | |
50 | size_t getNumberOfArguments() const override |
51 | { |
52 | return 1; |
53 | } |
54 | |
55 | DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override |
56 | { |
57 | if (!isString(arguments[0])) |
58 | throw Exception("The argument of function "+ getName() + " must have String type", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); |
59 | return std::make_shared<DataTypeString>(); |
60 | } |
61 | |
62 | /** convertToFullColumn needed because in distributed query processing, |
63 | * each server returns its own value. |
64 | */ |
65 | void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override |
66 | { |
67 | const IColumn * arg_column = block.getByPosition(arguments[0]).column.get(); |
68 | const ColumnString * arg_string = checkAndGetColumnConstData<ColumnString>(arg_column); |
69 | |
70 | if (!arg_string) |
71 | throw Exception("The argument of function "+ getName() + " must be constant String", ErrorCodes::ILLEGAL_COLUMN); |
72 | |
73 | block.getByPosition(result).column = block.getByPosition(result).type->createColumnConst( |
74 | input_rows_count, macros->getValue(arg_string->getDataAt(0).toString()))->convertToFullColumnIfConst(); |
75 | } |
76 | }; |
77 | |
78 | |
79 | void registerFunctionGetMacro(FunctionFactory & factory) |
80 | { |
81 | factory.registerFunction<FunctionGetMacro>(); |
82 | } |
83 | |
84 | } |
85 |