This is an automated email from the ASF dual-hosted git repository. xuyang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 43490a33a5 [feature-array](array-type) Add array function array_with_constant (#14115) 43490a33a5 is described below commit 43490a33a5fd62f8d4ac5046875dd65432879e1e Author: lihangyu <15605149...@163.com> AuthorDate: Fri Nov 11 22:08:43 2022 +0800 [feature-array](array-type) Add array function array_with_constant (#14115) Return array of constants with length num. ``` mysql> select array_with_constant(4, 1223); +------------------------------+ | array_with_constant(4, 1223) | +------------------------------+ | [1223, 1223, 1223, 1223] | +------------------------------+ 1 row in set (0.01 sec) ``` co-authored-by @eldenmoon --- be/src/vec/CMakeLists.txt | 1 + .../functions/array/function_array_register.cpp | 2 + .../array/function_array_with_constant.cpp | 86 ++++++++++++++++++++++ .../array-functions/array_with_constant.md | 73 ++++++++++++++++++ .../array-functions/array_with_constant.md | 72 ++++++++++++++++++ gensrc/script/doris_builtins_functions.py | 14 ++++ .../array_functions/test_array_functions.out | 36 +++++++++ .../test_array_functions_by_literal.out | 16 +++- .../test_array_functions_with_where.out | 3 + .../array_functions/test_array_functions.groovy | 4 + .../test_array_functions_by_literal.groovy | 5 +- .../test_array_functions_with_where.groovy | 2 + 12 files changed, 311 insertions(+), 3 deletions(-) diff --git a/be/src/vec/CMakeLists.txt b/be/src/vec/CMakeLists.txt index e05c40255a..b40f7c1955 100644 --- a/be/src/vec/CMakeLists.txt +++ b/be/src/vec/CMakeLists.txt @@ -150,6 +150,7 @@ set(VEC_FILES functions/array/function_array_enumerate.cpp functions/array/function_array_range.cpp functions/array/function_array_popback.cpp + functions/array/function_array_with_constant.cpp exprs/table_function/vexplode_json_array.cpp functions/math.cpp functions/function_bitmap.cpp diff --git a/be/src/vec/functions/array/function_array_register.cpp b/be/src/vec/functions/array/function_array_register.cpp index 2112d92509..e8c2fd4c0f 100644 --- a/be/src/vec/functions/array/function_array_register.cpp +++ b/be/src/vec/functions/array/function_array_register.cpp @@ -38,6 +38,7 @@ void register_function_array_difference(SimpleFunctionFactory&); void register_function_array_enumerate(SimpleFunctionFactory&); void register_function_array_range(SimpleFunctionFactory&); void register_function_array_popback(SimpleFunctionFactory&); +void register_function_array_with_constant(SimpleFunctionFactory&); void register_function_array(SimpleFunctionFactory& factory) { register_function_array_element(factory); @@ -56,6 +57,7 @@ void register_function_array(SimpleFunctionFactory& factory) { register_function_array_enumerate(factory); register_function_array_range(factory); register_function_array_popback(factory); + register_function_array_with_constant(factory); } } // namespace doris::vectorized diff --git a/be/src/vec/functions/array/function_array_with_constant.cpp b/be/src/vec/functions/array/function_array_with_constant.cpp new file mode 100644 index 0000000000..af2600cbaf --- /dev/null +++ b/be/src/vec/functions/array/function_array_with_constant.cpp @@ -0,0 +1,86 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#include "vec/columns/column_array.h" +#include "vec/columns/column_const.h" +#include "vec/data_types/data_type_array.h" +#include "vec/data_types/data_type_number.h" +#include "vec/functions/function.h" +#include "vec/functions/function_helpers.h" +#include "vec/functions/simple_function_factory.h" + +namespace doris::vectorized { + +/* array_with_constant(num, T) - return array of constants with length num. + * array_with_constant(2, 'xxx') = ['xxx', 'xxx'] + */ +class FunctionArrayWithConstant : public IFunction { +public: + static constexpr auto name = "array_with_constant"; + static FunctionPtr create() { return std::make_shared<FunctionArrayWithConstant>(); } + + /// Get function name. + String get_name() const override { return name; } + + bool is_variadic() const override { return false; } + + size_t get_number_of_arguments() const override { return 2; } + + // need handle null cases + bool use_default_implementation_for_nulls() const override { return false; } + + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + return std::make_shared<DataTypeArray>(make_nullable(arguments[1])); + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) override { + auto num = block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); + auto value = block.get_by_position(arguments[1]).column->convert_to_full_column_if_const(); + auto offsets_col = ColumnVector<ColumnArray::Offset64>::create(); + ColumnArray::Offsets64& offsets = offsets_col->get_data(); + offsets.reserve(input_rows_count); + ColumnArray::Offset64 offset = 0; + std::vector<uint32_t> array_sizes; + array_sizes.reserve(input_rows_count); + for (size_t i = 0; i < input_rows_count; ++i) { + auto array_size = num->get_int(i); + if (UNLIKELY(array_size < 0)) { + return Status::RuntimeError("Array size can not be negative in function:" + + get_name()); + } + offset += array_size; + offsets.push_back(offset); + array_sizes.push_back(array_size); + } + auto clone = value->clone_empty(); + clone->reserve(input_rows_count); + value->replicate(array_sizes.data(), offset, *clone->assume_mutable().get()); + if (!clone->is_nullable()) { + clone = ColumnNullable::create(std::move(clone), ColumnUInt8::create(clone->size(), 0)); + } + auto array = ColumnArray::create(std::move(clone), std::move(offsets_col)); + block.replace_by_position(result, std::move(array)); + return Status::OK(); + } +}; + +void register_function_array_with_constant(SimpleFunctionFactory& factory) { + factory.register_function<FunctionArrayWithConstant>(); +} + +} // namespace doris::vectorized diff --git a/docs/en/docs/sql-manual/sql-functions/array-functions/array_with_constant.md b/docs/en/docs/sql-manual/sql-functions/array-functions/array_with_constant.md new file mode 100644 index 0000000000..2816cfe236 --- /dev/null +++ b/docs/en/docs/sql-manual/sql-functions/array-functions/array_with_constant.md @@ -0,0 +1,73 @@ +--- +{ + "title": "array_with_constant", + "language": "en" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + +## array_with_constant + +### description + +#### Syntax + +``` +ARRAY<T> array_with_constant(n, T) +``` + +get array of constants with n length +### notice + +`Only supported in vectorized engine` + +### example + +``` +mysql> set enable_vectorized_engine=true; + +mysql> select array_with_constant(2, "hello"); ++---------------------------------+ +| array_with_constant(2, 'hello') | ++---------------------------------+ +| ['hello', 'hello'] | ++---------------------------------+ +1 row in set (0.04 sec) + +mysql> select array_with_constant(3, 12345); ++-------------------------------+ +| array_with_constant(3, 12345) | ++-------------------------------+ +| [12345, 12345, 12345] | ++-------------------------------+ +1 row in set (0.01 sec) + +mysql> select array_with_constant(3, null); ++------------------------------+ +| array_with_constant(3, NULL) | ++------------------------------+ +| [NULL, NULL, NULL] | ++------------------------------+ +1 row in set (0.01 sec) + +``` + +### keywords + +ARRAY,WITH_CONSTANT,ARRAY_WITH_CONSTANT diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_with_constant.md b/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_with_constant.md new file mode 100644 index 0000000000..2eb94b47d1 --- /dev/null +++ b/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_with_constant.md @@ -0,0 +1,72 @@ +--- +{ + "title": "array_with_constant", + "language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + +## array_with_constant + +### description + +#### Syntax + +``` +ARRAY<T> array_with_constant(n, T) +``` +返回一个数组, 包含n个重复的T常量 + +### notice + +`Only supported in vectorized engine` + +### example + +``` +mysql> set enable_vectorized_engine=true; + +mysql> select array_with_constant(2, "hello"); ++---------------------------------+ +| array_with_constant(2, 'hello') | ++---------------------------------+ +| ['hello', 'hello'] | ++---------------------------------+ +1 row in set (0.04 sec) + +mysql> select array_with_constant(3, 12345); ++-------------------------------+ +| array_with_constant(3, 12345) | ++-------------------------------+ +| [12345, 12345, 12345] | ++-------------------------------+ +1 row in set (0.01 sec) + +mysql> select array_with_constant(3, null); ++------------------------------+ +| array_with_constant(3, NULL) | ++------------------------------+ +| [NULL, NULL, NULL] | ++------------------------------+ +1 row in set (0.01 sec) +``` + +### keywords + +ARRAY,WITH_CONSTANT,ARRAY_WITH_CONSTANT diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 7286afef02..1c5694697d 100755 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -449,6 +449,20 @@ visible_functions = [ [['array_popback'], 'ARRAY_DECIMALV2', ['ARRAY_DECIMALV2'], '', '', '', 'vec', ''], [['array_popback'], 'ARRAY_VARCHAR', ['ARRAY_VARCHAR'], '', '', '', 'vec', ''], [['array_popback'], 'ARRAY_STRING', ['ARRAY_STRING'], '', '', '', 'vec', ''], + + [['array_with_constant'], 'ARRAY_BOOLEAN', ['BIGINT', 'BOOLEAN'], '', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['array_with_constant'], 'ARRAY_TINYINT', ['BIGINT', 'TINYINT'], '', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['array_with_constant'], 'ARRAY_SMALLINT', ['BIGINT','SMALLINT'], '', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['array_with_constant'], 'ARRAY_INT', ['BIGINT', 'INT'], '', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['array_with_constant'], 'ARRAY_BIGINT', ['BIGINT', 'BIGINT'], '', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['array_with_constant'], 'ARRAY_LARGEINT', ['BIGINT', 'LARGEINT'], '', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['array_with_constant'], 'ARRAY_DATETIME', ['BIGINT', 'DATETIME'], '', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['array_with_constant'], 'ARRAY_DATE', ['BIGINT', 'DATE'], '', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['array_with_constant'], 'ARRAY_FLOAT', ['BIGINT', 'FLOAT'], '', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['array_with_constant'], 'ARRAY_DOUBLE', ['BIGINT', 'DOUBLE'], '', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['array_with_constant'], 'ARRAY_DECIMALV2', ['BIGINT', 'DECIMALV2'], '', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['array_with_constant'], 'ARRAY_VARCHAR', ['BIGINT', 'VARCHAR'], '', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['array_with_constant'], 'ARRAY_STRING', ['BIGINT', 'STRING'], '', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], [['array_range'], 'ARRAY_INT', ['INT'], '', '', '', 'vec', 'ALWAYS_NULLABLE'], [['array_range'], 'ARRAY_INT', ['INT', 'INT'], '', '', '', 'vec', 'ALWAYS_NULLABLE'], diff --git a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions.out b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions.out index 4bb260669c..def00a0861 100644 --- a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions.out +++ b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions.out @@ -215,6 +215,42 @@ 6 \N 7 \N +-- !select -- +1 [1, 1, 1] +2 [2, 2, 2] +3 [3, 3, 3] +4 [4, 4, 4] +5 [5, 5, 5] +6 [6, 6, 6] +7 [7, 7, 7] + +-- !select -- +1 [NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL] +2 [NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL] +3 [NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL] +4 [NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL] +5 [NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL] +6 [NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL] +7 [NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL] + +-- !select -- +1 ['a', 'a'] +2 ['a', 'a'] +3 ['a', 'a'] +4 ['a', 'a'] +5 ['a', 'a'] +6 ['a', 'a'] +7 ['a', 'a'] + +-- !select -- +1 [123, 123] +2 [123, 123] +3 [123, 123] +4 [123, 123] +5 [123, 123] +6 [123, 123] +7 [123, 123] + -- !select -- \N \N -1 \N diff --git a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out index b0fbe79c27..6e746f26ab 100644 --- a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out +++ b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out @@ -123,7 +123,7 @@ false 3 -- !sql -- -6 +6.0 -- !sql -- 2.0 @@ -138,7 +138,7 @@ false 3 -- !sql -- -6 +6.0 -- !sql -- \N @@ -377,3 +377,15 @@ any_any_1_2___any -- !sql -- _ +-- !sql -- +['_', '_', '_'] + +-- !sql -- +['1', '1'] + +-- !sql -- +[1223, 1223, 1223, 1223] + +-- !sql -- +[NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL] + diff --git a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_with_where.out b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_with_where.out index feca051aa5..610a739472 100644 --- a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_with_where.out +++ b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_with_where.out @@ -15,3 +15,6 @@ 1 3 2 1 +-- !select -- +\N [NULL, NULL, NULL, NULL, NULL] + diff --git a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions.groovy b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions.groovy index 156b9c491b..7f9ea92138 100644 --- a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions.groovy +++ b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions.groovy @@ -70,6 +70,10 @@ suite("test_array_functions") { qt_select "SELECT k1, array_popback(k5) from ${tableName} ORDER BY k1" qt_select "SELECT k1, array_popback(k6) from ${tableName} ORDER BY k1" qt_select "SELECT k1, array_popback(k7) from ${tableName} ORDER BY k1" + qt_select "SELECT k1, array_with_constant(3, k1) from ${tableName} ORDER BY k1" + qt_select "SELECT k1, array_with_constant(10, null) from ${tableName} ORDER BY k1" + qt_select "SELECT k1, array_with_constant(2, 'a') from ${tableName} ORDER BY k1" + qt_select "SELECT k1, array_with_constant(2, 123) from ${tableName} ORDER BY k1" def tableName2 = "tbl_test_array_range" sql """DROP TABLE IF EXISTS ${tableName2}""" diff --git a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy index 05adf3f873..8dc62e8d98 100644 --- a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy +++ b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy @@ -168,7 +168,10 @@ suite("test_array_functions_by_literal") { qt_sql "select array_join([null, null, 1, 2, '', '', null], '_', 'any')" qt_sql "select array_join([''], '_')" qt_sql "select array_join(['', ''], '_')" - + qt_sql "select array_with_constant(3, '_')" + qt_sql "select array_with_constant(2, '1')" + qt_sql "select array_with_constant(4, 1223)" + qt_sql "select array_with_constant(8, null)" // abnormal test test { sql "select array_intersect([1, 2, 3, 1, 2, 3], '1[3, 2, 5]')" diff --git a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_with_where.groovy b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_with_where.groovy index 2bbc9e69fb..5ad39b199f 100644 --- a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_with_where.groovy +++ b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_with_where.groovy @@ -38,12 +38,14 @@ suite("test_array_functions_with_where") { sql """ INSERT INTO ${tableName} VALUES(1, [1, 2, 3], ["a", "b", ""], [1, 2]) """ sql """ INSERT INTO ${tableName} VALUES(2, [4], NULL, [5]) """ sql """ INSERT INTO ${tableName} VALUES(3, [], [], NULL) """ + sql """ INSERT INTO ${tableName} VALUES(NULL, [], NULL, NULL) """ qt_select "SELECT k1, size(k2) FROM ${tableName} WHERE size(k2)=3 ORDER BY k1" qt_select "SELECT k1, size(k2) FROM ${tableName} WHERE array_contains(k2, 4) ORDER BY k1" qt_select "SELECT k1, size(k2) FROM ${tableName} WHERE element_at(k2, 1)=1 ORDER BY k1" qt_select "SELECT k1, size(k2) FROM ${tableName} WHERE arrays_overlap(k2, k4) ORDER BY k1" qt_select "SELECT k1, size(k2) FROM ${tableName} WHERE cardinality(k2)>0 ORDER BY k1, size(k2)" + qt_select "SELECT k1, array_with_constant(5, k1) FROM ${tableName} WHERE k1 is null ORDER BY k1, size(k2)" test { sql "select k1, size(k2) FROM ${tableName} WHERE k2 = []" --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org