1 | #include <DataTypes/DataTypeString.h> |
2 | #include <Columns/ColumnString.h> |
3 | #include <Columns/ColumnFixedString.h> |
4 | #include <Functions/FunctionHelpers.h> |
5 | #include <Functions/IFunctionImpl.h> |
6 | |
7 | |
8 | namespace DB |
9 | { |
10 | |
11 | namespace ErrorCodes |
12 | { |
13 | extern const int ILLEGAL_COLUMN; |
14 | extern const int ILLEGAL_TYPE_OF_ARGUMENT; |
15 | } |
16 | |
17 | |
18 | template <typename Impl, typename Name, bool is_injective = false> |
19 | class FunctionStringToString : public IFunction |
20 | { |
21 | public: |
22 | static constexpr auto name = Name::name; |
23 | static FunctionPtr create(const Context &) |
24 | { |
25 | return std::make_shared<FunctionStringToString>(); |
26 | } |
27 | |
28 | String getName() const override |
29 | { |
30 | return name; |
31 | } |
32 | |
33 | size_t getNumberOfArguments() const override |
34 | { |
35 | return 1; |
36 | } |
37 | |
38 | bool isInjective(const Block &) override |
39 | { |
40 | return is_injective; |
41 | } |
42 | |
43 | DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override |
44 | { |
45 | if (!isStringOrFixedString(arguments[0])) |
46 | throw Exception( |
47 | "Illegal type " + arguments[0]->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); |
48 | |
49 | return arguments[0]; |
50 | } |
51 | |
52 | bool useDefaultImplementationForConstants() const override { return true; } |
53 | |
54 | void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) override |
55 | { |
56 | const ColumnPtr column = block.getByPosition(arguments[0]).column; |
57 | if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get())) |
58 | { |
59 | auto col_res = ColumnString::create(); |
60 | Impl::vector(col->getChars(), col->getOffsets(), col_res->getChars(), col_res->getOffsets()); |
61 | block.getByPosition(result).column = std::move(col_res); |
62 | } |
63 | else if (const ColumnFixedString * col_fixed = checkAndGetColumn<ColumnFixedString>(column.get())) |
64 | { |
65 | auto col_res = ColumnFixedString::create(col_fixed->getN()); |
66 | Impl::vector_fixed(col_fixed->getChars(), col_fixed->getN(), col_res->getChars()); |
67 | block.getByPosition(result).column = std::move(col_res); |
68 | } |
69 | else |
70 | throw Exception( |
71 | "Illegal column " + block.getByPosition(arguments[0]).column->getName() + " of argument of function " + getName(), |
72 | ErrorCodes::ILLEGAL_COLUMN); |
73 | } |
74 | }; |
75 | |
76 | } |
77 | |