diff --git a/dbms/src/Functions/arrayWithConstant.cpp b/dbms/src/Functions/arrayWithConstant.cpp new file mode 100644 index 00000000000..8c9402b1669 --- /dev/null +++ b/dbms/src/Functions/arrayWithConstant.cpp @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace DB { +namespace ErrorCodes { + extern const int ILLEGAL_TYPE_OF_ARGUMENT; +} + +/* +* arrayWithConstant(num, const) - make array of constants with length num. +* arrayWithConstant(3, 'hello') = ['hello', 'hello', 'hello'] +* arrayWithConstant(1, 'hello') = ['hello'] +* arrayWithConstant(0, 'hello') = [] +*/ + +class FunctionArrayWithConstant : public IFunction +{ +public: + static constexpr auto name = "arrayWithConstant"; + + static FunctionPtr create(const Context &) { return std::make_shared(); } + + String getName() const override { return name; } + + size_t getNumberOfArguments() const override { return 2; } + + DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override + { + if (!isUnsignedInteger(arguments[0])) { + throw Exception("Illegal type " + arguments[0]->getName() + + " of argument of function " + getName() + + ", expected Integer", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + } + return std::make_shared(arguments[1]); + } + + + bool useDefaultImplementationForConstants() const override { return true; } + + bool useDefaultImplementationForNulls() const override { return false; } + void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t) override + { + const auto * num = block.getByPosition(arguments[0]).column.get(); + const auto * constant = block.getByPosition(arguments[1]).column.get(); + uint64_t a = num->getUInt(0); + + auto offsets_col = ColumnArray::ColumnOffsets::create(); + ColumnArray::Offsets & offsets = offsets_col->getData(); + + offsets.push_back(a); + auto data_col = constant->replicate(offsets); + block.getByPosition(result).column = ColumnArray::create(std::move(data_col), std::move(offsets_col)); + } +}; + +void registerFunctionArrayWithConstant(FunctionFactory & factory) +{ + factory.registerFunction(); +} + +} // namespace DB + + + + diff --git a/dbms/src/Functions/registerFunctionsArray.cpp b/dbms/src/Functions/registerFunctionsArray.cpp index ac7a5b38cad..27447c7a6af 100644 --- a/dbms/src/Functions/registerFunctionsArray.cpp +++ b/dbms/src/Functions/registerFunctionsArray.cpp @@ -28,6 +28,7 @@ void registerFunctionArrayEnumerateUniq(FunctionFactory &); void registerFunctionArrayEnumerateDense(FunctionFactory &); void registerFunctionArrayUniq(FunctionFactory &); void registerFunctionArrayDistinct(FunctionFactory &); +void registerFunctionArrayWithConstant(FunctionFactory &); void registerFunctionsArray(FunctionFactory & factory) { @@ -56,6 +57,7 @@ void registerFunctionsArray(FunctionFactory & factory) registerFunctionArrayEnumerateDense(factory); registerFunctionArrayUniq(factory); registerFunctionArrayDistinct(factory); + registerFunctionArrayWithConstant(factory); } } diff --git a/dbms/tests/queries/0_stateless/00903_array_with_constant_function.reference b/dbms/tests/queries/0_stateless/00903_array_with_constant_function.reference new file mode 100644 index 00000000000..6b7497bc7a3 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00903_array_with_constant_function.reference @@ -0,0 +1 @@ +['qwerty','qwerty'] [] [1] diff --git a/dbms/tests/queries/0_stateless/00903_array_with_constant_function.sql b/dbms/tests/queries/0_stateless/00903_array_with_constant_function.sql new file mode 100644 index 00000000000..f434bbb4d31 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00903_array_with_constant_function.sql @@ -0,0 +1 @@ +select arrayWithConstant(2, 'qwerty'), arrayWithConstant(0, -1), arrayWithConstant(1, 1)