From 2c9aff681769387aa517dc9b77542532fd0d6006 Mon Sep 17 00:00:00 2001 From: gitccl Date: Mon, 6 Mar 2023 00:08:40 +0800 Subject: [PATCH 1/3] [Feature](array-function) Support array_concat function --- be/src/vec/CMakeLists.txt | 1 + .../functions/array/function_array_concat.cpp | 84 +++++++++++++++++++ .../array/function_array_register.cpp | 2 + .../array-functions/array_concat.md | 77 +++++++++++++++++ .../array-functions/array_concat.md | 78 +++++++++++++++++ .../doris/analysis/FunctionCallExpr.java | 6 +- gensrc/script/doris_builtins_functions.py | 19 +++++ .../array_functions/test_array_functions.out | 44 ++++++++++ .../test_array_functions_by_literal.out | 21 +++++ .../test_array_with_scale_type.out | 16 ++++ .../test_array_functions.groovy | 6 +- .../test_array_functions_by_literal.groovy | 8 ++ .../test_array_with_scale_type.groovy | 5 ++ 13 files changed, 364 insertions(+), 3 deletions(-) create mode 100644 be/src/vec/functions/array/function_array_concat.cpp create mode 100644 docs/en/docs/sql-manual/sql-functions/array-functions/array_concat.md create mode 100644 docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_concat.md diff --git a/be/src/vec/CMakeLists.txt b/be/src/vec/CMakeLists.txt index 8f7babdcce89e3..35ffd17ab828c9 100644 --- a/be/src/vec/CMakeLists.txt +++ b/be/src/vec/CMakeLists.txt @@ -180,6 +180,7 @@ set(VEC_FILES functions/array/function_array_constructor.cpp functions/array/function_array_with_constant.cpp functions/array/function_array_apply.cpp + functions/array/function_array_concat.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_concat.cpp b/be/src/vec/functions/array/function_array_concat.cpp new file mode 100644 index 00000000000000..a09a561872d98a --- /dev/null +++ b/be/src/vec/functions/array/function_array_concat.cpp @@ -0,0 +1,84 @@ +// 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 + +#include "vec/columns/column_array.h" +#include "vec/data_types/data_type_array.h" +#include "vec/functions/function.h" +#include "vec/functions/simple_function_factory.h" + +namespace doris::vectorized { + +// array_concat([1, 2], [7, 8], [5, 6]) -> [1, 2, 7, 8, 5, 6] +class FunctionArrayConcat : public IFunction { +public: + static constexpr auto name = "array_concat"; + + static FunctionPtr create() { return std::make_shared(); } + + String get_name() const override { return name; } + + bool is_variadic() const override { return true; } + + size_t get_number_of_arguments() const override { return 1; } + + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + DCHECK(arguments.size() > 0) + << "function: " << get_name() << ", arguments should not be empty"; + for (const auto& arg : arguments) { + DCHECK(is_array(arg)) << "argument for function array_concat should be DataTypeArray" + << " and argument is " << arg->get_name(); + } + return arguments[0]; + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + const size_t result, size_t input_rows_count) override { + DataTypePtr column_type = block.get_by_position(arguments[0]).type; + auto nested_type = assert_cast(*column_type).get_nested_type(); + auto result_column = ColumnArray::create(nested_type->create_column(), + ColumnArray::ColumnOffsets::create()); + IColumn& result_nested_col = result_column->get_data(); + ColumnArray::Offsets64& column_offsets = result_column->get_offsets(); + column_offsets.resize(input_rows_count); + + size_t off = 0; + for (size_t row = 0; row < input_rows_count; ++row) { + for (size_t col = 0; col < arguments.size(); ++col) { + ColumnPtr src_column = block.get_by_position(arguments[col]) + .column->convert_to_full_column_if_const(); + const auto& src_column_array = check_and_get_column(*src_column); + const auto& src_column_offsets = src_column_array->get_offsets(); + const size_t length = src_column_offsets[row] - src_column_offsets[row - 1]; + result_nested_col.insert_range_from(src_column_array->get_data(), + src_column_offsets[row - 1], length); + off += length; + } + column_offsets[row] = off; + } + + block.replace_by_position(result, std::move(result_column)); + return Status::OK(); + } +}; + +void register_function_array_concat(SimpleFunctionFactory& factory) { + factory.register_function(); +} + +} // namespace doris::vectorized \ No newline at end of file diff --git a/be/src/vec/functions/array/function_array_register.cpp b/be/src/vec/functions/array/function_array_register.cpp index aa64dff7858687..e553a613bf56a5 100644 --- a/be/src/vec/functions/array/function_array_register.cpp +++ b/be/src/vec/functions/array/function_array_register.cpp @@ -42,6 +42,7 @@ void register_function_array_popback(SimpleFunctionFactory&); void register_function_array_with_constant(SimpleFunctionFactory&); void register_function_array_constructor(SimpleFunctionFactory&); void register_function_array_apply(SimpleFunctionFactory&); +void register_function_array_concat(SimpleFunctionFactory&); void register_function_array(SimpleFunctionFactory& factory) { register_function_array_element(factory); @@ -64,6 +65,7 @@ void register_function_array(SimpleFunctionFactory& factory) { register_function_array_with_constant(factory); register_function_array_constructor(factory); register_function_array_apply(factory); + register_function_array_concat(factory); } } // namespace doris::vectorized diff --git a/docs/en/docs/sql-manual/sql-functions/array-functions/array_concat.md b/docs/en/docs/sql-manual/sql-functions/array-functions/array_concat.md new file mode 100644 index 00000000000000..5d17087aa6b401 --- /dev/null +++ b/docs/en/docs/sql-manual/sql-functions/array-functions/array_concat.md @@ -0,0 +1,77 @@ +--- +{ + "title": "array_concat", + "language": "en" +} +--- + + + +## array_concat + + + +array_concat + + + +### description + +Concat all arrays passed in the arguments + +#### Syntax + +```sql +Array array_concat(Array, ...) +``` + +#### Returned value + +The concated array. + +Type: Array. + +### notice + +`Only supported in vectorized engine` + +### example + +``` +mysql> select array_concat([1, 2], [7, 8], [5, 6]); ++-----------------------------------------------------+ +| array_concat(ARRAY(1, 2), ARRAY(7, 8), ARRAY(5, 6)) | ++-----------------------------------------------------+ +| [1, 2, 7, 8, 5, 6] | ++-----------------------------------------------------+ +1 row in set (0.02 sec) + +mysql> select col2, col3, array_concat(col2, col3) from array_test; ++--------------+-----------+------------------------------+ +| col2 | col3 | array_concat(`col2`, `col3`) | ++--------------+-----------+------------------------------+ +| [1, 2, 3] | [3, 4, 5] | [1, 2, 3, 3, 4, 5] | +| [1, NULL, 2] | [NULL] | [1, NULL, 2, NULL] | +| [1, 2, 3] | NULL | NULL | +| [] | [] | [] | ++--------------+-----------+------------------------------+ +``` + +### keywords + +ARRAY,CONCAT,ARRAY_CONCAT \ No newline at end of file diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_concat.md b/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_concat.md new file mode 100644 index 00000000000000..6ef748a65c21b6 --- /dev/null +++ b/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_concat.md @@ -0,0 +1,78 @@ +--- +{ + "title": "array_concat", + "language": "zh-CN" +} +--- + + + +## array_concat + + + +array_concat + + + +### description + +将输入的所有数组拼接为一个数组 + +#### Syntax + +```sql +Array array_concat(Array, ...) +``` + +#### Returned value + +拼接好的数组 + +类型: Array. + +### notice + +`只支持在向量化引擎中使用` + +### example + +``` +mysql> select array_concat([1, 2], [7, 8], [5, 6]); ++-----------------------------------------------------+ +| array_concat(ARRAY(1, 2), ARRAY(7, 8), ARRAY(5, 6)) | ++-----------------------------------------------------+ +| [1, 2, 7, 8, 5, 6] | ++-----------------------------------------------------+ +1 row in set (0.02 sec) + +mysql> select col2, col3, array_concat(col2, col3) from array_test; ++--------------+-----------+------------------------------+ +| col2 | col3 | array_concat(`col2`, `col3`) | ++--------------+-----------+------------------------------+ +| [1, 2, 3] | [3, 4, 5] | [1, 2, 3, 3, 4, 5] | +| [1, NULL, 2] | [NULL] | [1, NULL, 2, NULL] | +| [1, 2, 3] | NULL | NULL | +| [] | [] | [] | ++--------------+-----------+------------------------------+ +``` + + +### keywords + +ARRAY,CONCAT,ARRAY_CONCAT \ No newline at end of file diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java index 9e101275a046c5..e23bf29084aa2f 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java @@ -1012,7 +1012,8 @@ private void analyzeArrayFunction(Analyzer analyzer) throws AnalysisException { || fnName.getFunction().equalsIgnoreCase("array_union") || fnName.getFunction().equalsIgnoreCase("array_except") || fnName.getFunction().equalsIgnoreCase("array_intersect") - || fnName.getFunction().equalsIgnoreCase("arrays_overlap")) { + || fnName.getFunction().equalsIgnoreCase("arrays_overlap") + || fnName.getFunction().equalsIgnoreCase("array_concat")) { Type[] childTypes = collectChildReturnTypes(); Type compatibleType = childTypes[0]; for (int i = 1; i < childTypes.length; ++i) { @@ -1494,7 +1495,8 @@ private void analyzeNestedFunction() { || fnName.getFunction().equalsIgnoreCase("array_popback") || fnName.getFunction().equalsIgnoreCase("reverse") || fnName.getFunction().equalsIgnoreCase("%element_slice%") - || fnName.getFunction().equalsIgnoreCase("array_except")) { + || fnName.getFunction().equalsIgnoreCase("array_except") + || fnName.getFunction().equalsIgnoreCase("array_concat")) { if (children.size() > 0) { this.type = children.get(0).getType(); } diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index f650e0a28af1ed..a87e33cce76b68 100644 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -411,6 +411,25 @@ [['array_apply'], 'ARRAY_DATETIMEV2', ['ARRAY_DATETIMEV2', 'VARCHAR', 'DATETIMEV2'], ''], [['array_apply'], 'ARRAY_DATEV2', ['ARRAY_DATEV2', 'VARCHAR', 'DATEV2'], ''], + [['array_concat'], 'ARRAY_BOOLEAN', ['ARRAY_BOOLEAN', '...'], ''], + [['array_concat'], 'ARRAY_TINYINT', ['ARRAY_TINYINT', '...'], ''], + [['array_concat'], 'ARRAY_SMALLINT', ['ARRAY_SMALLINT', '...'], ''], + [['array_concat'], 'ARRAY_INT', ['ARRAY_INT', '...'], ''], + [['array_concat'], 'ARRAY_BIGINT', ['ARRAY_BIGINT', '...'], ''], + [['array_concat'], 'ARRAY_LARGEINT', ['ARRAY_LARGEINT', '...'], ''], + [['array_concat'], 'ARRAY_FLOAT', ['ARRAY_FLOAT', '...'], ''], + [['array_concat'], 'ARRAY_DOUBLE', ['ARRAY_DOUBLE', '...'], ''], + [['array_concat'], 'ARRAY_DECIMALV2', ['ARRAY_DECIMALV2', '...'], ''], + [['array_concat'], 'ARRAY_DECIMAL32', ['ARRAY_DECIMAL32', '...'], ''], + [['array_concat'], 'ARRAY_DECIMAL64', ['ARRAY_DECIMAL64', '...'], ''], + [['array_concat'], 'ARRAY_DECIMAL128', ['ARRAY_DECIMAL128', '...'], ''], + [['array_concat'], 'ARRAY_DATETIME', ['ARRAY_DATETIME', '...'], ''], + [['array_concat'], 'ARRAY_DATE', ['ARRAY_DATE', '...'], ''], + [['array_concat'], 'ARRAY_DATETIMEV2', ['ARRAY_DATETIMEV2', '...'], ''], + [['array_concat'], 'ARRAY_DATEV2', ['ARRAY_DATEV2', '...'], ''], + [['array_concat'], 'ARRAY_VARCHAR', ['ARRAY_VARCHAR', '...'], ''], + [['array_concat'], 'ARRAY_STRING', ['ARRAY_STRING', '...'], ''], + [['array_except'], 'ARRAY_BOOLEAN', ['ARRAY_BOOLEAN', 'ARRAY_BOOLEAN'], ''], [['array_except'], 'ARRAY_TINYINT', ['ARRAY_TINYINT', 'ARRAY_TINYINT'], ''], [['array_except'], 'ARRAY_SMALLINT', ['ARRAY_SMALLINT', 'ARRAY_SMALLINT'], ''], 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 e631432cc0b9ed..aacc7ee18fad7e 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 @@ -725,6 +725,50 @@ 8 [8] true 9 [9] true +-- !select -- +1 [1, 2, 3, 1, 2] +2 [4, 5] +3 \N +4 [1, 2, 3, 4, 5, 4, 3, 2, 1] +5 \N +6 \N +7 \N +8 [1, 2, 3, 3, 4, 4, NULL, 1, 2, 2, 3] +9 [1, 2, 3, 1, 2] + +-- !select -- +1 [1, 2, 3, 1, NULL, 2, 1, 2, NULL] +2 [4, 1, NULL, 2, 5, NULL] +3 \N +4 [1, 2, 3, 4, 5, 4, 3, 2, 1, 1, NULL, 2, NULL] +5 \N +6 \N +7 \N +8 [1, 2, 3, 3, 4, 4, NULL, 1, NULL, 2, 1, 2, 2, 3, NULL] +9 [1, 2, 3, 1, NULL, 2, 1, 2, NULL] + +-- !select -- +1 [2023-02-05, 2023-02-06, 2023-02-07, 2023-02-06] +2 [2023-01-05, 2023-01-06, 2023-01-07, 2023-01-06] +3 \N +4 \N +5 \N +6 \N +7 \N +8 \N +9 \N + +-- !select -- +1 [2022-10-15 10:30:00.999, 2022-08-31 12:00:00.999, 2022-10-16 10:30:00.999, 2022-08-31 12:00:00.999, 2023-03-05 10:30:00.999] +2 [2022-11-15 10:30:00.999, 2022-01-31 12:00:00.999, 2022-11-16 10:30:00.999, 2022-01-31 12:00:00.999, 2023-03-05 10:30:00.999] +3 \N +4 \N +5 \N +6 \N +7 \N +8 \N +9 \N + -- !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 a42e84b3b260c3..379a5d2f1ccc9f 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 @@ -536,6 +536,27 @@ _ -- !sql -- [24.99] +-- !sql -- +[1, 2, 3, 2, 3, 4, 8, 1, 2, 9] + +-- !sql -- +[12, 23, 25, NULL, NULL, 66] + +-- !sql -- +[1.2, 1.8, 9, 2.2, 2.8] + +-- !sql -- +['aaa', NULL, 'bbb', 'fff', NULL, 'ccc'] + +-- !sql -- +[12.99, 34.99, 999.28, 123.99] + +-- !sql -- +[2023-03-05, 2023-03-04, 2023-02-01, 2023-02-05] + +-- !sql -- +[2023-03-05 12:23:24.999, 2023-03-05 15:23:23.997] + -- !sql -- [8, NULL] diff --git a/regression-test/data/query_p0/sql_functions/array_functions/test_array_with_scale_type.out b/regression-test/data/query_p0/sql_functions/array_functions/test_array_with_scale_type.out index c4463229de9460..cc5cb7dac8e29d 100644 --- a/regression-test/data/query_p0/sql_functions/array_functions/test_array_with_scale_type.out +++ b/regression-test/data/query_p0/sql_functions/array_functions/test_array_with_scale_type.out @@ -102,3 +102,19 @@ \N \N +-- !select -- +[2022-12-02 22:23:24.999, 2022-12-02 22:23:23.997] +[2022-12-02 22:23:24.999, 2022-12-02 22:23:23.997] + +-- !select -- +[2022-12-01 22:23:24.999, 2022-12-01 23:23:24.999] +[2022-12-02 22:23:24.999, 2022-12-02 23:23:24.999] + +-- !select -- +[2022-12-01 22:23:24.999, 2022-12-01 23:23:24.999, 2022-12-02 22:23:24.999, 2022-12-02 22:23:23.997] +[2022-12-02 22:23:24.999, 2022-12-02 23:23:24.999, 2022-12-02 22:23:24.999, 2022-12-02 22:23:23.997] + +-- !select -- +[22.678, 33.6789, 22.678, 33.6789, 22.678, 33.6789] +[23.678, 34.6789, 23.678, 34.6789, 23.678, 34.6789] + 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 e0d560f7c568d9..5ce3c7467b6233 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 @@ -116,7 +116,11 @@ suite("test_array_functions") { qt_select "SELECT k1, array_position(k8, cast('2023-02-05' as datev2)) FROM ${tableName} ORDER BY k1" qt_select "SELECT k1, array_position(k10, cast('2022-10-15 10:30:00.999' as datetimev2(3))) FROM ${tableName} ORDER BY k1" qt_select_array "SELECT k1, array(k1), array_contains(array(k1), k1) from ${tableName} ORDER BY k1" - + qt_select "SELECT k1, array_concat(k2, k4) FROM ${tableName} ORDER BY k1" + qt_select "SELECT k1, array_concat(k2, [1, null, 2], k4, [null]) FROM ${tableName} ORDER BY k1" + qt_select "SELECT k1, array_concat(k8, k9) FROM ${tableName} ORDER BY k1" + qt_select "SELECT k1, array_concat(k10, k11, array(cast('2023-03-05 10:30:00.999' as datetimev2(3)))) FROM ${tableName} ORDER BY k1" + def tableName2 = "tbl_test_array_range" sql """DROP TABLE IF EXISTS ${tableName2}""" sql """ 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 4f281116ad212a..2b60c8472d2602 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 @@ -223,6 +223,14 @@ suite("test_array_functions_by_literal") { qt_sql """select array_apply(array(cast (24.99 as decimal(10,3)),cast (25.99 as decimal(10,3))), ">", '25')""" qt_sql """select array_apply(array(cast (24.99 as decimal(10,3)),cast (25.99 as decimal(10,3))), "!=", '25.99')""" + qt_sql "select array_concat([1, 2, 3], [2, 3, 4], [8, 1, 2], [9])" + qt_sql "select array_concat([12, 23], [25, null], [null], [66])" + qt_sql "select array_concat([1.2, 1.8], [9.0, 2.2], [2.8])" + qt_sql "select array_concat(['aaa', null], ['bbb', 'fff'], [null, 'ccc'])" + qt_sql "select array_concat(array(cast (12.99 as decimal(10,3)), cast (34.99 as decimal(10,3))), array(cast (999.28 as decimal(10,3)), cast (123.99 as decimal(10,3))))" + qt_sql "select array_concat(array(cast ('2023-03-05' as datev2), cast ('2023-03-04' as datev2)), array(cast ('2023-02-01' as datev2), cast ('2023-02-05' as datev2)))" + qt_sql "select array_concat(array(cast ('2023-03-05 12:23:24.999' as datetimev2(3)),cast ('2023-03-05 15:23:23.997' as datetimev2(3))))" + qt_sql "select array(8, null)" qt_sql "select array('a', 1, 2)" qt_sql "select array(null, null, null)" diff --git a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_with_scale_type.groovy b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_with_scale_type.groovy index ae206f07d20dcd..db85a98b64cd5c 100644 --- a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_with_scale_type.groovy +++ b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_with_scale_type.groovy @@ -75,5 +75,10 @@ suite("test_array_with_scale_type") { qt_select """select array_apply(c_array_decimal, ">=", 22.1) from ${tableName}""" qt_select """select array_apply(c_array_decimal, ">=", null) from ${tableName}""" + qt_select """select array_concat(array(cast ('2022-12-02 22:23:24.999999' as datetimev2(3)),cast ('2022-12-02 22:23:23.997799' as datetimev2(3)))) from ${tableName}""" + qt_select """select array_concat(c_array_datetimev2) from ${tableName}""" + qt_select """select array_concat(c_array_datetimev2, array(cast ('2022-12-02 22:23:24.999999' as datetimev2(3)),cast ('2022-12-02 22:23:23.997799' as datetimev2(3)))) from ${tableName}""" + qt_select """select array_concat(c_array_decimal, c_array_decimal, c_array_decimal) from ${tableName}""" + sql "DROP TABLE IF EXISTS ${tableName}" } \ No newline at end of file From 6c6d21c0d0f3967292f023fb0e4e93f888d83217 Mon Sep 17 00:00:00 2001 From: gitccl Date: Mon, 6 Mar 2023 11:41:49 +0800 Subject: [PATCH 2/3] [test](array-function) add array_concat null test --- .../vec/functions/array/function_array_concat.cpp | 15 ++++++++++++--- docs/sidebars.json | 1 + .../test_array_functions_by_literal.out | 3 +++ .../test_array_functions_by_literal.groovy | 1 + 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/be/src/vec/functions/array/function_array_concat.cpp b/be/src/vec/functions/array/function_array_concat.cpp index a09a561872d98a..7a8a41f29f8254 100644 --- a/be/src/vec/functions/array/function_array_concat.cpp +++ b/be/src/vec/functions/array/function_array_concat.cpp @@ -57,11 +57,20 @@ class FunctionArrayConcat : public IFunction { ColumnArray::Offsets64& column_offsets = result_column->get_offsets(); column_offsets.resize(input_rows_count); + size_t total_size = 0; + for (size_t col : arguments) { + ColumnPtr src_column = + block.get_by_position(col).column->convert_to_full_column_if_const(); + const auto& src_column_array = check_and_get_column(*src_column); + total_size += src_column_array->size(); + } + result_nested_col.reserve(total_size); + size_t off = 0; for (size_t row = 0; row < input_rows_count; ++row) { - for (size_t col = 0; col < arguments.size(); ++col) { - ColumnPtr src_column = block.get_by_position(arguments[col]) - .column->convert_to_full_column_if_const(); + for (size_t col : arguments) { + ColumnPtr src_column = + block.get_by_position(col).column->convert_to_full_column_if_const(); const auto& src_column_array = check_and_get_column(*src_column); const auto& src_column_offsets = src_column_array->get_offsets(); const size_t length = src_column_offsets[row] - src_column_offsets[row - 1]; diff --git a/docs/sidebars.json b/docs/sidebars.json index 363a7da352915c..48d7fbf5e9c8ce 100644 --- a/docs/sidebars.json +++ b/docs/sidebars.json @@ -292,6 +292,7 @@ "sql-manual/sql-functions/array-functions/array_enumerate", "sql-manual/sql-functions/array-functions/array_popback", "sql-manual/sql-functions/array-functions/array_compact", + "sql-manual/sql-functions/array-functions/array_concat", "sql-manual/sql-functions/array-functions/arrays_overlap", "sql-manual/sql-functions/array-functions/countequal", "sql-manual/sql-functions/array-functions/element_at" 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 379a5d2f1ccc9f..450c1f11399c73 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 @@ -548,6 +548,9 @@ _ -- !sql -- ['aaa', NULL, 'bbb', 'fff', NULL, 'ccc'] +-- !sql -- +\N + -- !sql -- [12.99, 34.99, 999.28, 123.99] 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 2b60c8472d2602..b73ca03c8ea243 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 @@ -227,6 +227,7 @@ suite("test_array_functions_by_literal") { qt_sql "select array_concat([12, 23], [25, null], [null], [66])" qt_sql "select array_concat([1.2, 1.8], [9.0, 2.2], [2.8])" qt_sql "select array_concat(['aaa', null], ['bbb', 'fff'], [null, 'ccc'])" + qt_sql "select array_concat(null, [1, 2, 3], null)" qt_sql "select array_concat(array(cast (12.99 as decimal(10,3)), cast (34.99 as decimal(10,3))), array(cast (999.28 as decimal(10,3)), cast (123.99 as decimal(10,3))))" qt_sql "select array_concat(array(cast ('2023-03-05' as datev2), cast ('2023-03-04' as datev2)), array(cast ('2023-02-01' as datev2), cast ('2023-02-05' as datev2)))" qt_sql "select array_concat(array(cast ('2023-03-05 12:23:24.999' as datetimev2(3)),cast ('2023-03-05 15:23:23.997' as datetimev2(3))))" From 8b8eb422dbce2822239a522fdb38955c2b1a8c25 Mon Sep 17 00:00:00 2001 From: gitccl Date: Mon, 6 Mar 2023 12:49:08 +0800 Subject: [PATCH 3/3] [optimize](array-function) make array size calculation more precise --- be/src/vec/functions/array/function_array_concat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/be/src/vec/functions/array/function_array_concat.cpp b/be/src/vec/functions/array/function_array_concat.cpp index 7a8a41f29f8254..02377272e9e2c3 100644 --- a/be/src/vec/functions/array/function_array_concat.cpp +++ b/be/src/vec/functions/array/function_array_concat.cpp @@ -62,7 +62,7 @@ class FunctionArrayConcat : public IFunction { ColumnPtr src_column = block.get_by_position(col).column->convert_to_full_column_if_const(); const auto& src_column_array = check_and_get_column(*src_column); - total_size += src_column_array->size(); + total_size += src_column_array->get_data().size(); } result_nested_col.reserve(total_size);