| 1 | #if defined(__ELF__) && !defined(__FreeBSD__) | 
|---|---|
| 2 | |
| 3 | #include <Common/SymbolIndex.h> | 
| 4 | #include <Columns/ColumnString.h> | 
| 5 | #include <Columns/ColumnsNumber.h> | 
| 6 | #include <DataTypes/DataTypeString.h> | 
| 7 | #include <Functions/IFunctionImpl.h> | 
| 8 | #include <Functions/FunctionHelpers.h> | 
| 9 | #include <Functions/FunctionFactory.h> | 
| 10 | #include <Interpreters/Context.h> | 
| 11 | #include <IO/WriteHelpers.h> | 
| 12 | |
| 13 | |
| 14 | namespace DB | 
| 15 | { | 
| 16 | |
| 17 | namespace ErrorCodes | 
| 18 | { | 
| 19 | extern const int ILLEGAL_COLUMN; | 
| 20 | extern const int ILLEGAL_TYPE_OF_ARGUMENT; | 
| 21 | extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; | 
| 22 | extern const int FUNCTION_NOT_ALLOWED; | 
| 23 | } | 
| 24 | |
| 25 | class FunctionAddressToSymbol : public IFunction | 
| 26 | { | 
| 27 | public: | 
| 28 | static constexpr auto name = "addressToSymbol"; | 
| 29 | static FunctionPtr create(const Context & context) | 
| 30 | { | 
| 31 | if (!context.getSettingsRef().allow_introspection_functions) | 
| 32 | throw Exception( "Introspection functions are disabled, because setting 'allow_introspection_functions' is set to 0", ErrorCodes::FUNCTION_NOT_ALLOWED); | 
| 33 | return std::make_shared<FunctionAddressToSymbol>(); | 
| 34 | } | 
| 35 | |
| 36 | String getName() const override | 
| 37 | { | 
| 38 | return name; | 
| 39 | } | 
| 40 | |
| 41 | size_t getNumberOfArguments() const override | 
| 42 | { | 
| 43 | return 1; | 
| 44 | } | 
| 45 | |
| 46 | DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override | 
| 47 | { | 
| 48 | if (arguments.size() != 1) | 
| 49 | throw Exception( "Function "+ getName() + " needs exactly one argument; passed " | 
| 50 | + toString(arguments.size()) + ".", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); | 
| 51 | |
| 52 | const auto & type = arguments[0].type; | 
| 53 | |
| 54 | if (!WhichDataType(type.get()).isUInt64()) | 
| 55 | throw Exception( "The only argument for function "+ getName() + " must be UInt64. Found " | 
| 56 | + type->getName() + " instead.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); | 
| 57 | |
| 58 | return std::make_shared<DataTypeString>(); | 
| 59 | } | 
| 60 | |
| 61 | bool useDefaultImplementationForConstants() const override | 
| 62 | { | 
| 63 | return true; | 
| 64 | } | 
| 65 | |
| 66 | void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override | 
| 67 | { | 
| 68 | const SymbolIndex & symbol_index = SymbolIndex::instance(); | 
| 69 | |
| 70 | const ColumnPtr & column = block.getByPosition(arguments[0]).column; | 
| 71 | const ColumnUInt64 * column_concrete = checkAndGetColumn<ColumnUInt64>(column.get()); | 
| 72 | |
| 73 | if (!column_concrete) | 
| 74 | throw Exception( "Illegal column "+ column->getName() + " of argument of function "+ getName(), ErrorCodes::ILLEGAL_COLUMN); | 
| 75 | |
| 76 | const typename ColumnVector<UInt64>::Container & data = column_concrete->getData(); | 
| 77 | auto result_column = ColumnString::create(); | 
| 78 | |
| 79 | for (size_t i = 0; i < input_rows_count; ++i) | 
| 80 | { | 
| 81 | if (const auto * symbol = symbol_index.findSymbol(reinterpret_cast<const void *>(data[i]))) | 
| 82 | result_column->insertDataWithTerminatingZero(symbol->name, strlen(symbol->name) + 1); | 
| 83 | else | 
| 84 | result_column->insertDefault(); | 
| 85 | } | 
| 86 | |
| 87 | block.getByPosition(result).column = std::move(result_column); | 
| 88 | } | 
| 89 | }; | 
| 90 | |
| 91 | void registerFunctionAddressToSymbol(FunctionFactory & factory) | 
| 92 | { | 
| 93 | factory.registerFunction<FunctionAddressToSymbol>(); | 
| 94 | } | 
| 95 | |
| 96 | } | 
| 97 | |
| 98 | #endif | 
| 99 | 
