diff --git a/dbms/src/Functions/FunctionsMiscellaneous.h b/dbms/src/Functions/FunctionsMiscellaneous.h index e97457e3e13..07fe04389cf 100644 --- a/dbms/src/Functions/FunctionsMiscellaneous.h +++ b/dbms/src/Functions/FunctionsMiscellaneous.h @@ -11,32 +11,6 @@ namespace DB { -/** Creates an array, multiplying the column (the first argument) by the number of elements in the array (the second argument). - */ -class FunctionReplicate : public IFunction -{ -public: - static constexpr auto name = "replicate"; - static FunctionPtr create(const Context & context); - - String getName() const override - { - return name; - } - - size_t getNumberOfArguments() const override - { - return 2; - } - - bool useDefaultImplementationForNulls() const override { return false; } - - DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override; - - void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override; -}; - - /// Executes expression. Uses for lambda functions implementation. Can't be created from factory. class FunctionExpression : public IFunctionBase, public IPreparedFunction, public std::enable_shared_from_this diff --git a/dbms/src/Functions/registerFunctionsMiscellaneous.cpp b/dbms/src/Functions/registerFunctionsMiscellaneous.cpp index 85cf3571560..e6fe5ca1524 100644 --- a/dbms/src/Functions/registerFunctionsMiscellaneous.cpp +++ b/dbms/src/Functions/registerFunctionsMiscellaneous.cpp @@ -39,7 +39,6 @@ void registerFunctionFinalizeAggregation(FunctionFactory &); void registerFunctionToLowCardinality(FunctionFactory &); void registerFunctionLowCardinalityIndices(FunctionFactory &); void registerFunctionLowCardinalityKeys(FunctionFactory &); -void registerFunctionsReplicate(FunctionFactory &); void registerFunctionsIn(FunctionFactory &); void registerFunctionsMiscellaneous(FunctionFactory & factory) @@ -80,7 +79,6 @@ void registerFunctionsMiscellaneous(FunctionFactory & factory) registerFunctionToLowCardinality(factory); registerFunctionLowCardinalityIndices(factory); registerFunctionLowCardinalityKeys(factory); - registerFunctionReplicate(factory); registerFunctionsIn(factory); } diff --git a/dbms/src/Functions/replicate.cpp b/dbms/src/Functions/replicate.cpp new file mode 100644 index 00000000000..756b745ccde --- /dev/null +++ b/dbms/src/Functions/replicate.cpp @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include + + +namespace DB +{ + +/** Creates an array, multiplying the column (the first argument) by the number of elements in the array (the second argument). + */ +class FunctionReplicate : public IFunction +{ +public: + static constexpr auto name = "replicate"; + + static FunctionPtr create(const Context &) + { + return std::make_shared(); + } + + String getName() const override + { + return name; + } + + size_t getNumberOfArguments() const override + { + return 2; + } + + bool useDefaultImplementationForNulls() const override { return false; } + + DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override + { + const DataTypeArray * array_type = checkAndGetDataType(arguments[1].get()); + if (!array_type) + throw Exception("Second argument for function " + getName() + " must be array.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + return std::make_shared(arguments[0]); + } + + void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t) override + { + ColumnPtr first_column = block.getByPosition(arguments[0]).column; + const ColumnArray * array_column = checkAndGetColumn(block.getByPosition(arguments[1]).column.get()); + ColumnPtr temp_column; + if (!array_column) + { + auto const_array_column = checkAndGetColumnConst(block.getByPosition(arguments[1]).column.get()); + if (!const_array_column) + throw Exception("Unexpected column for replicate", ErrorCodes::ILLEGAL_COLUMN); + temp_column = const_array_column->convertToFullColumn(); + array_column = checkAndGetColumn(temp_column.get()); + } + block.getByPosition(result).column + = ColumnArray::create(first_column->replicate(array_column->getOffsets()), array_column->getOffsetsPtr()); + } +}; + + +void registerFunctionReplicate(FunctionFactory & factory) +{ + factory.registerFunction(); +} + +}