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
8namespace DB
9{
10
11namespace ErrorCodes
12{
13 extern const int ILLEGAL_COLUMN;
14 extern const int ILLEGAL_TYPE_OF_ARGUMENT;
15}
16
17
18template <typename Impl, typename Name, bool is_injective = false>
19class FunctionStringToString : public IFunction
20{
21public:
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