From dbc9376a0f03fd23d9c47c11466761ea0fabeaa8 Mon Sep 17 00:00:00 2001 From: Stupnikov Andrey Date: Fri, 8 Feb 2019 02:24:07 +0300 Subject: [PATCH 1/4] arrayWithConstant function implementation; --- dbms/src/Functions/arrayWithConstant.cpp | 72 +++++++++++++++++++ dbms/src/Functions/registerFunctionsArray.cpp | 2 + ...903_array_with_constant_function.reference | 1 + .../00903_array_with_constant_function.sql | 1 + 4 files changed, 76 insertions(+) create mode 100644 dbms/src/Functions/arrayWithConstant.cpp create mode 100644 dbms/tests/queries/0_stateless/00903_array_with_constant_function.reference create mode 100644 dbms/tests/queries/0_stateless/00903_array_with_constant_function.sql 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) From f794ebbec4f197c1a62139da38fabb0ccbc9c851 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 10 Feb 2019 00:13:58 +0300 Subject: [PATCH 2/4] Fixed implementation of "arrayWithConstant" #4309 --- dbms/src/Functions/arrayWithConstant.cpp | 56 ++++++++++++------------ 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/dbms/src/Functions/arrayWithConstant.cpp b/dbms/src/Functions/arrayWithConstant.cpp index 8c9402b1669..5aa91a6284f 100644 --- a/dbms/src/Functions/arrayWithConstant.cpp +++ b/dbms/src/Functions/arrayWithConstant.cpp @@ -3,22 +3,22 @@ #include #include #include -#include #include -#include -namespace DB { -namespace ErrorCodes { +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') = [] -*/ +/* 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 { @@ -28,35 +28,37 @@ public: 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])) { + if (!isNumber(arguments[0])) throw Exception("Illegal type " + arguments[0]->getName() + - " of argument of function " + getName() + - ", expected Integer", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - } + " 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 + + void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t num_rows) 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); + const auto * col_num = block.getByPosition(arguments[0]).column.get(); + const auto * col_value = block.getByPosition(arguments[1]).column.get(); auto offsets_col = ColumnArray::ColumnOffsets::create(); ColumnArray::Offsets & offsets = offsets_col->getData(); + offsets.reserve(num_rows); - offsets.push_back(a); - auto data_col = constant->replicate(offsets); - block.getByPosition(result).column = ColumnArray::create(std::move(data_col), std::move(offsets_col)); + ColumnArray::Offset offset = 0; + for (size_t i = 0; i < num_rows; ++i) + { + offset += col_num->getUInt(i); + offsets.push_back(offset); + } + + block.getByPosition(result).column = ColumnArray::create(col_value->replicate(offsets), std::move(offsets_col)); } }; @@ -65,8 +67,4 @@ void registerFunctionArrayWithConstant(FunctionFactory & factory) factory.registerFunction(); } -} // namespace DB - - - - +} From ad56a42cf463f53ab63815567bc12fa045d8995b Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 10 Feb 2019 00:14:50 +0300 Subject: [PATCH 3/4] Fixed test #4309 --- .../0_stateless/00903_array_with_constant_function.reference | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 6b7497bc7a3..d51331f9855 100644 --- a/dbms/tests/queries/0_stateless/00903_array_with_constant_function.reference +++ b/dbms/tests/queries/0_stateless/00903_array_with_constant_function.reference @@ -1 +1 @@ -['qwerty','qwerty'] [] [1] +['qwerty','qwerty'] [] [1] From 25e7e632079808e376bf5363ad14af2e1aa596e6 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 10 Feb 2019 00:18:33 +0300 Subject: [PATCH 4/4] Added a test --- .../00904_array_with_constant_2.reference | 40 +++++++++++++++++++ .../00904_array_with_constant_2.sql | 4 ++ 2 files changed, 44 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00904_array_with_constant_2.reference create mode 100644 dbms/tests/queries/0_stateless/00904_array_with_constant_2.sql diff --git a/dbms/tests/queries/0_stateless/00904_array_with_constant_2.reference b/dbms/tests/queries/0_stateless/00904_array_with_constant_2.reference new file mode 100644 index 00000000000..b2e919a5a46 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00904_array_with_constant_2.reference @@ -0,0 +1,40 @@ +[0,0,0] +[1,1,1] +[2,2,2] +[3,3,3] +[4,4,4] +[5,5,5] +[6,6,6] +[7,7,7] +[8,8,8] +[9,9,9] +[] +['Hello'] +['Hello','Hello'] +['Hello','Hello','Hello'] +['Hello','Hello','Hello','Hello'] +['Hello','Hello','Hello','Hello','Hello'] +['Hello','Hello','Hello','Hello','Hello','Hello'] +['Hello','Hello','Hello','Hello','Hello','Hello','Hello'] +['Hello','Hello','Hello','Hello','Hello','Hello','Hello','Hello'] +['Hello','Hello','Hello','Hello','Hello','Hello','Hello','Hello','Hello'] +[] +['Hello'] +[NULL,NULL] +[] +[NULL] +['Hello','Hello'] +[] +['Hello'] +[NULL,NULL] +[] +[] +[[]] +[[],[]] +[[],[],[]] +[[],[],[],[]] +[[],[],[],[],[]] +[[],[],[],[],[],[]] +[[],[],[],[],[],[],[]] +[[],[],[],[],[],[],[],[]] +[[],[],[],[],[],[],[],[],[]] diff --git a/dbms/tests/queries/0_stateless/00904_array_with_constant_2.sql b/dbms/tests/queries/0_stateless/00904_array_with_constant_2.sql new file mode 100644 index 00000000000..6e578a12b88 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00904_array_with_constant_2.sql @@ -0,0 +1,4 @@ +SELECT arrayWithConstant(3, number) FROM numbers(10); +SELECT arrayWithConstant(number, 'Hello') FROM numbers(10); +SELECT arrayWithConstant(number % 3, number % 2 ? 'Hello' : NULL) FROM numbers(10); +SELECT arrayWithConstant(number, []) FROM numbers(10);