From 8c8f48c4c2d28b2191273e4bbadb75574a7b9c7e Mon Sep 17 00:00:00 2001 From: carlvinhust2012 Date: Mon, 15 Aug 2022 11:43:17 +0800 Subject: [PATCH] [feature-wip](array-type) add the array_join function (#11406) this pr is used to add the array_join function. Co-authored-by: hucheng01 --- .../array/function_array_aggregation.cpp | 16 +- .../vec/functions/array/function_array_join.h | 243 ++++++++++++++++++ .../functions/array/function_array_mapped.h | 12 +- .../array-functions/array_join.md | 104 ++++++++ .../array-functions/array_join.md | 104 ++++++++ gensrc/script/doris_builtins_functions.py | 31 +++ .../array_functions/test_array_functions.out | 9 + .../test_array_functions.groovy | 1 + 8 files changed, 512 insertions(+), 8 deletions(-) create mode 100644 be/src/vec/functions/array/function_array_join.h create mode 100644 docs/en/docs/sql-manual/sql-functions/array-functions/array_join.md create mode 100644 docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_join.md diff --git a/be/src/vec/functions/array/function_array_aggregation.cpp b/be/src/vec/functions/array/function_array_aggregation.cpp index 422cc0e3c1..171e9098a4 100644 --- a/be/src/vec/functions/array/function_array_aggregation.cpp +++ b/be/src/vec/functions/array/function_array_aggregation.cpp @@ -31,6 +31,7 @@ #include "vec/core/types.h" #include "vec/data_types/data_type.h" #include "vec/data_types/data_type_nullable.h" +#include "vec/functions/array/function_array_join.h" #include "vec/functions/array/function_array_mapped.h" #include "vec/functions/simple_function_factory.h" @@ -139,14 +140,20 @@ struct ArrayAggregateImpl { using column_type = ColumnArray; using data_type = DataTypeArray; - static DataTypePtr get_return_type(const DataTypeArray* data_type_array) { + static bool _is_variadic() { return false; } + + static size_t _get_number_of_arguments() { return 1; } + + static DataTypePtr get_return_type(const DataTypes& arguments) { using Function = AggregateFunction>; + const DataTypeArray* data_type_array = + static_cast(remove_nullable(arguments[0]).get()); auto function = Function::create(data_type_array->get_nested_type()); return function->get_return_type(); } - static Status execute(Block& block, size_t result, const DataTypeArray* data_type_array, - const ColumnArray& array) { + static Status execute(Block& block, const ColumnNumbers& arguments, size_t result, + const DataTypeArray* data_type_array, const ColumnArray& array) { ColumnPtr res; DataTypePtr type = data_type_array->get_nested_type(); const IColumn* data = array.get_data_ptr().get(); @@ -275,12 +282,15 @@ using FunctionArrayAverage = using FunctionArrayProduct = FunctionArrayMapped, NameArrayProduct>; +using FunctionArrayJoin = FunctionArrayMapped; + void register_function_array_aggregation(SimpleFunctionFactory& factory) { factory.register_function(); factory.register_function(); factory.register_function(); factory.register_function(); factory.register_function(); + factory.register_function(); } } // namespace vectorized diff --git a/be/src/vec/functions/array/function_array_join.h b/be/src/vec/functions/array/function_array_join.h new file mode 100644 index 0000000000..452ba0df0b --- /dev/null +++ b/be/src/vec/functions/array/function_array_join.h @@ -0,0 +1,243 @@ +// 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. +#pragma once + +#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/data_types/data_type_string.h" +#include "vec/functions/array/function_array_utils.h" + +namespace doris::vectorized { + +struct NameArrayJoin { + static constexpr auto name = "array_join"; +}; + +struct ArrayJoinImpl { +public: + using column_type = ColumnArray; + using NullMapType = PaddedPODArray; + + static bool _is_variadic() { return true; } + + static size_t _get_number_of_arguments() { return 0; } + + static DataTypePtr get_return_type(const DataTypes& arguments) { + DCHECK(is_array(arguments[0])) + << "first argument for function: array_join should be DataTypeArray" + << " and arguments[0] is " << arguments[0]->get_name(); + DCHECK(is_string_or_fixed_string(arguments[1])) + << "second argument for function: array_join should be DataTypeString" + << ", and arguments[1] is " << arguments[1]->get_name(); + if (arguments.size() > 2) { + DCHECK(is_string_or_fixed_string(arguments[2])) + << "third argument for function: array_join should be DataTypeString" + << ", and arguments[2] is " << arguments[2]->get_name(); + } + + return std::make_shared(); + } + + static Status execute(Block& block, const ColumnNumbers& arguments, size_t result, + const DataTypeArray* data_type_array, const ColumnArray& array) { + ColumnPtr src_column = + block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); + ColumnArrayExecutionData src; + if (!extract_column_array_info(*src_column, src)) { + return Status::RuntimeError(fmt::format( + "execute failed, unsupported types for function {}({})", "array_join", + block.get_by_position(arguments[0]).type->get_name())); + } + + ColumnPtr sep_column = + block.get_by_position(arguments[1]).column->convert_to_full_column_if_const(); + ColumnPtr null_replace_column = + (arguments.size() > 2 ? block.get_by_position(arguments[2]) + .column->convert_to_full_column_if_const() + : nullptr); + + std::string sep_str = _get_string_from_column(sep_column); + std::string null_replace_str = _get_string_from_column(null_replace_column); + + auto nested_type = data_type_array->get_nested_type(); + auto dest_column_ptr = ColumnString::create(); + DCHECK(dest_column_ptr != nullptr); + + auto res_val = _execute_by_type(*src.nested_col, *src.offsets_ptr, src.nested_nullmap_data, + sep_str, null_replace_str, nested_type, dest_column_ptr); + if (!res_val) { + return Status::RuntimeError(fmt::format( + "execute failed or unsupported types for function {}({},{},{})", "array_join", + block.get_by_position(arguments[0]).type->get_name(), + block.get_by_position(arguments[1]).type->get_name(), + (arguments.size() > 2 ? block.get_by_position(arguments[2]).type->get_name() + : ""))); + } + + block.replace_by_position(result, std::move(dest_column_ptr)); + return Status::OK(); + } + +private: + static std::string _get_string_from_column(const ColumnPtr& column_ptr) { + if (!column_ptr) { + return std::string(""); + } + const ColumnString* column_string_ptr = check_and_get_column(*column_ptr); + StringRef str_ref = column_string_ptr->get_data_at(0); + std::string str(str_ref.data, str_ref.size); + return str; + } + + static void _fill_result_string(const std::string& input_str, const std::string& sep_str, + std::string& result_str) { + if (result_str.size() == 0) { + result_str.append(input_str); + } else { + result_str.append(sep_str); + result_str.append(input_str); + } + return; + } + + template + static bool _execute_number(const IColumn& src_column, const ColumnArray::Offsets& src_offsets, + const UInt8* src_null_map, const std::string& sep_str, + const std::string& null_replace_str, DataTypePtr& nested_type, + ColumnString* dest_column_ptr) { + using NestType = typename ColumnType::value_type; + bool is_decimal = IsDecimalNumber; + + const ColumnType* src_data_concrete = reinterpret_cast(&src_column); + if (!src_data_concrete) { + return false; + } + + ColumnArray::Offset prev_src_offset = 0; + for (auto curr_src_offset : src_offsets) { + std::string result_str; + for (ColumnArray::Offset j = prev_src_offset; j < curr_src_offset; ++j) { + if (src_null_map && src_null_map[j]) { + if (null_replace_str.size() == 0) { + continue; + } else { + _fill_result_string(null_replace_str, sep_str, result_str); + continue; + } + } + + if (is_decimal) { + DecimalV2Value decimal_value = + (DecimalV2Value)(src_data_concrete->get_data()[j]); + std::string decimal_str = decimal_value.to_string(); + _fill_result_string(decimal_str, sep_str, result_str); + } else { + std::string elem_str = remove_nullable(nested_type)->to_string(src_column, j); + _fill_result_string(elem_str, sep_str, result_str); + } + } + + dest_column_ptr->insert_data(result_str.c_str(), result_str.size()); + prev_src_offset = curr_src_offset; + } + + return true; + } + + static bool _execute_string(const IColumn& src_column, const ColumnArray::Offsets& src_offsets, + const UInt8* src_null_map, const std::string& sep_str, + const std::string& null_replace_str, + ColumnString* dest_column_ptr) { + const ColumnString* src_data_concrete = reinterpret_cast(&src_column); + if (!src_data_concrete) { + return false; + } + + ColumnArray::Offset prev_src_offset = 0; + for (auto curr_src_offset : src_offsets) { + std::string result_str; + for (ColumnArray::Offset j = prev_src_offset; j < curr_src_offset; ++j) { + if (src_null_map && src_null_map[j]) { + if (null_replace_str.size() == 0) { + continue; + } else { + _fill_result_string(null_replace_str, sep_str, result_str); + continue; + } + } + + StringRef src_str_ref = src_data_concrete->get_data_at(j); + std::string elem_str(src_str_ref.data, src_str_ref.size); + _fill_result_string(elem_str, sep_str, result_str); + } + + dest_column_ptr->insert_data(result_str.c_str(), result_str.size()); + prev_src_offset = curr_src_offset; + } + return true; + } + + static bool _execute_by_type(const IColumn& src_column, const ColumnArray::Offsets& src_offsets, + const UInt8* src_null_map, const std::string& sep_str, + const std::string& null_replace_str, DataTypePtr& nested_type, + ColumnString* dest_column_ptr) { + bool res = false; + WhichDataType which(remove_nullable(nested_type)); + if (which.is_uint8()) { + res = _execute_number(src_column, src_offsets, src_null_map, sep_str, + null_replace_str, nested_type, dest_column_ptr); + } else if (which.is_int8()) { + res = _execute_number(src_column, src_offsets, src_null_map, sep_str, + null_replace_str, nested_type, dest_column_ptr); + } else if (which.is_int16()) { + res = _execute_number(src_column, src_offsets, src_null_map, sep_str, + null_replace_str, nested_type, dest_column_ptr); + } else if (which.is_int32()) { + res = _execute_number(src_column, src_offsets, src_null_map, sep_str, + null_replace_str, nested_type, dest_column_ptr); + } else if (which.is_int64()) { + res = _execute_number(src_column, src_offsets, src_null_map, sep_str, + null_replace_str, nested_type, dest_column_ptr); + } else if (which.is_int128()) { + res = _execute_number(src_column, src_offsets, src_null_map, sep_str, + null_replace_str, nested_type, dest_column_ptr); + } else if (which.is_float32()) { + res = _execute_number(src_column, src_offsets, src_null_map, sep_str, + null_replace_str, nested_type, dest_column_ptr); + } else if (which.is_float64()) { + res = _execute_number(src_column, src_offsets, src_null_map, sep_str, + null_replace_str, nested_type, dest_column_ptr); + } else if (which.is_date()) { + res = _execute_number(src_column, src_offsets, src_null_map, sep_str, + null_replace_str, nested_type, dest_column_ptr); + } else if (which.is_date_time()) { + res = _execute_number(src_column, src_offsets, src_null_map, sep_str, + null_replace_str, nested_type, dest_column_ptr); + } else if (which.is_decimal128()) { + res = _execute_number(src_column, src_offsets, src_null_map, sep_str, + null_replace_str, nested_type, dest_column_ptr); + } else if (which.is_string()) { + res = _execute_string(src_column, src_offsets, src_null_map, sep_str, null_replace_str, + dest_column_ptr); + } + return res; + } +}; + +} // namespace doris::vectorized \ No newline at end of file diff --git a/be/src/vec/functions/array/function_array_mapped.h b/be/src/vec/functions/array/function_array_mapped.h index 0314d480ea..9f9bcf9e21 100644 --- a/be/src/vec/functions/array/function_array_mapped.h +++ b/be/src/vec/functions/array/function_array_mapped.h @@ -60,13 +60,15 @@ public: } const auto* data_type_array = static_cast(remove_nullable(typed_column.type).get()); - return Impl::execute(block, result, data_type_array, *column_array); + return Impl::execute(block, arguments, result, data_type_array, *column_array); } - size_t get_number_of_arguments() const override { return 1; } + + bool is_variadic() const override { return Impl::_is_variadic(); } + + size_t get_number_of_arguments() const override { return Impl::_get_number_of_arguments(); } + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { - const DataTypeArray* data_type_array = - static_cast(remove_nullable(arguments[0]).get()); - return Impl::get_return_type(data_type_array); + return Impl::get_return_type(arguments); } }; diff --git a/docs/en/docs/sql-manual/sql-functions/array-functions/array_join.md b/docs/en/docs/sql-manual/sql-functions/array-functions/array_join.md new file mode 100644 index 0000000000..f342f48415 --- /dev/null +++ b/docs/en/docs/sql-manual/sql-functions/array-functions/array_join.md @@ -0,0 +1,104 @@ +--- +{ + "title": "array_join", + "language": "en" +} +--- + + + +## array_join + +### description + +#### Syntax + +``` +VARCHAR array_join(ARRAY arr, VARCHAR sep[, VARCHAR null_replace]) +``` + +Combines all elements in the array to generate a new string according to the separator (sep) +and the string to replace NULL (null_replace). +If sep is NULL, return NULL. +If null_replace is NULL, return NULL. +If sep is an empty string, no delimiter is applied. +If null_replace is an empty string or not specified, the NULL elements in the array are discarded directly. + +### notice + +`Only supported in vectorized engine` + +### example + +``` +mysql> set enable_vectorized_engine=true; + +mysql> select k1, k2, array_join(k1, '_', 'null') from array_test order by k1; ++------+-----------------------------+------------------------------------+ +| k1 | k2 | array_join(`k2`, '_', 'null') | ++------+-----------------------------+------------------------------------+ +| 1 | [1, 2, 3, 4, 5] | 1_2_3_4_5 | +| 2 | [6, 7, 8] | 6_7_8 | +| 3 | [] | | +| 4 | NULL | NULL | +| 5 | [1, 2, 3, 4, 5, 4, 3, 2, 1] | 1_2_3_4_5_4_3_2_1 | +| 6 | [1, 2, 3, NULL] | 1_2_3_null | +| 7 | [4, 5, 6, NULL, NULL] | 4_5_6_null_null | ++------+-----------------------------+------------------------------------+ + +mysql> select k1, k2, array_join(k2, '_', 'null') from array_test01 order by k1; ++------+-----------------------------------+------------------------------------+ +| k1 | k2 | array_join(`k2`, '_', 'null') | ++------+-----------------------------------+------------------------------------+ +| 1 | ['a', 'b', 'c', 'd'] | a_b_c_d | +| 2 | ['e', 'f', 'g', 'h'] | e_f_g_h | +| 3 | [NULL, 'a', NULL, 'b', NULL, 'c'] | null_a_null_b_null_c | +| 4 | ['d', 'e', NULL, ' '] | d_e_null_ | +| 5 | [' ', NULL, 'f', 'g'] | _null_f_g | ++------+-----------------------------------+------------------------------------+ + +mysql> select k1, k2, array_join(k2, '_') from array_test order by k1; ++------+-----------------------------+----------------------------+ +| k1 | k2 | array_join(`k2`, '_') | ++------+-----------------------------+----------------------------+ +| 1 | [1, 2, 3, 4, 5] | 1_2_3_4_5 | +| 2 | [6, 7, 8] | 6_7_8 | +| 3 | [] | | +| 4 | NULL | NULL | +| 5 | [1, 2, 3, 4, 5, 4, 3, 2, 1] | 1_2_3_4_5_4_3_2_1 | +| 6 | [1, 2, 3, NULL] | 1_2_3 | +| 7 | [4, 5, 6, NULL, NULL] | 4_5_6 | ++------+-----------------------------+----------------------------+ + +mysql> select k1, k2, array_join(k2, '_') from array_test01 order by k1; ++------+-----------------------------------+----------------------------+ +| k1 | k2 | array_join(`k2`, '_') | ++------+-----------------------------------+----------------------------+ +| 1 | ['a', 'b', 'c', 'd'] | a_b_c_d | +| 2 | ['e', 'f', 'g', 'h'] | e_f_g_h | +| 3 | [NULL, 'a', NULL, 'b', NULL, 'c'] | a_b_c | +| 4 | ['d', 'e', NULL, ' '] | d_e_ | +| 5 | [' ', NULL, 'f', 'g'] | _f_g | ++------+-----------------------------------+----------------------------+ +``` + +### keywords + +ARRAY, JOIN, ARRAY_JOIN \ No newline at end of file diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_join.md b/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_join.md new file mode 100644 index 0000000000..d3ce520b59 --- /dev/null +++ b/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_join.md @@ -0,0 +1,104 @@ +--- +{ + "title": "array_join", + "language": "zh-CN" +} +--- + + + +## array_join + +### description + +#### Syntax + +``` +VARCHAR array_join(ARRAY arr, VARCHAR sep[, VARCHAR null_replace]) +``` + +根据分隔符(sep)和替换NULL的字符串(null_replace), 将数组中的所有元素组合成一个新的字符串。 +若sep为NULL,则返回值为NULL。 +若null_replace为NULL,则返回值也为NULL。 +若sep为空字符串,则不应用任何分隔符。 +若null_replace为空字符串或者不指定,则直接丢弃数组中的NULL元素。 + +### notice + +`仅支持向量化引擎中使用` + +### example + +``` + +mysql> set enable_vectorized_engine=true; + +mysql> select k1, k2, array_join(k1, '_', 'null') from array_test order by k1; ++------+-----------------------------+------------------------------------+ +| k1 | k2 | array_join(`k2`, '_', 'null') | ++------+-----------------------------+------------------------------------+ +| 1 | [1, 2, 3, 4, 5] | 1_2_3_4_5 | +| 2 | [6, 7, 8] | 6_7_8 | +| 3 | [] | | +| 4 | NULL | NULL | +| 5 | [1, 2, 3, 4, 5, 4, 3, 2, 1] | 1_2_3_4_5_4_3_2_1 | +| 6 | [1, 2, 3, NULL] | 1_2_3_null | +| 7 | [4, 5, 6, NULL, NULL] | 4_5_6_null_null | ++------+-----------------------------+------------------------------------+ + +mysql> select k1, k2, array_join(k2, '_', 'null') from array_test01 order by k1; ++------+-----------------------------------+------------------------------------+ +| k1 | k2 | array_join(`k2`, '_', 'null') | ++------+-----------------------------------+------------------------------------+ +| 1 | ['a', 'b', 'c', 'd'] | a_b_c_d | +| 2 | ['e', 'f', 'g', 'h'] | e_f_g_h | +| 3 | [NULL, 'a', NULL, 'b', NULL, 'c'] | null_a_null_b_null_c | +| 4 | ['d', 'e', NULL, ' '] | d_e_null_ | +| 5 | [' ', NULL, 'f', 'g'] | _null_f_g | ++------+-----------------------------------+------------------------------------+ + +mysql> select k1, k2, array_join(k2, '_') from array_test order by k1; ++------+-----------------------------+----------------------------+ +| k1 | k2 | array_join(`k2`, '_') | ++------+-----------------------------+----------------------------+ +| 1 | [1, 2, 3, 4, 5] | 1_2_3_4_5 | +| 2 | [6, 7, 8] | 6_7_8 | +| 3 | [] | | +| 4 | NULL | NULL | +| 5 | [1, 2, 3, 4, 5, 4, 3, 2, 1] | 1_2_3_4_5_4_3_2_1 | +| 6 | [1, 2, 3, NULL] | 1_2_3 | +| 7 | [4, 5, 6, NULL, NULL] | 4_5_6 | ++------+-----------------------------+----------------------------+ + +mysql> select k1, k2, array_join(k2, '_') from array_test01 order by k1; ++------+-----------------------------------+----------------------------+ +| k1 | k2 | array_join(`k2`, '_') | ++------+-----------------------------------+----------------------------+ +| 1 | ['a', 'b', 'c', 'd'] | a_b_c_d | +| 2 | ['e', 'f', 'g', 'h'] | e_f_g_h | +| 3 | [NULL, 'a', NULL, 'b', NULL, 'c'] | a_b_c | +| 4 | ['d', 'e', NULL, ' '] | d_e_ | +| 5 | [' ', NULL, 'f', 'g'] | _f_g | ++------+-----------------------------------+----------------------------+ +``` + +### keywords + +ARRAY, JOIN, ARRAY_JOIN diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index fb1b1ddab1..3223cf600b 100755 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -211,6 +211,37 @@ visible_functions = [ [['array_sort'], 'ARRAY_VARCHAR', ['ARRAY_VARCHAR'], '', '', '', 'vec', ''], [['array_sort'], 'ARRAY_STRING', ['ARRAY_STRING'], '', '', '', 'vec', ''], + # array_join takes two params + [['array_join'], 'STRING', ['ARRAY_TINYINT','VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_SMALLINT','VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_INT','VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_BIGINT','VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_LARGEINT','VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_DATETIME','VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_DATE','VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_DATETIMEV2','VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_DATEV2','VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_FLOAT','VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_DOUBLE','VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_DECIMALV2','VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_VARCHAR','VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_STRING','VARCHAR'], '', '', '', 'vec', ''], + # array_join takes three params + [['array_join'], 'STRING', ['ARRAY_TINYINT','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_SMALLINT','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_INT','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_BIGINT','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_LARGEINT','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_DATETIME','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_DATE','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_DATETIMEV2','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_DATEV2','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_FLOAT','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_DOUBLE','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_DECIMALV2','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_VARCHAR','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_join'], 'STRING', ['ARRAY_STRING','VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_min'], 'TINYINT', ['ARRAY_TINYINT'], '', '', '', 'vec', 'ALWAYS_NULLABLE'], [['array_min'], 'SMALLINT', ['ARRAY_SMALLINT'], '', '', '', 'vec', 'ALWAYS_NULLABLE'], [['array_min'], 'INT', ['ARRAY_INT'], '', '', '', 'vec', 'ALWAYS_NULLABLE'], diff --git a/regression-test/data/query/sql_functions/array_functions/test_array_functions.out b/regression-test/data/query/sql_functions/array_functions/test_array_functions.out index c2883d4f9d..518865780d 100644 --- a/regression-test/data/query/sql_functions/array_functions/test_array_functions.out +++ b/regression-test/data/query/sql_functions/array_functions/test_array_functions.out @@ -107,3 +107,12 @@ 6 [1, 2, 3, 4, 5, 4, 3, 2, 1] ['a', 'b', 'c', 'd', 'c', 'b', 'a'] \N 7 [NULL, 10, NULL, 9, 8] ['h', NULL, 'g', NULL, 'f'] \N +-- !select -- +1 1_2_3 a-b- +2 4 \N +3 +4 1_2_3_4_5_4_3_2_1 +5 a-b-c-d-c-b-a +6 1_2_3_4_5_4_3_2_1 a-b-c-d-c-b-a +7 8_9_null_10_null f-null-g-null-h + diff --git a/regression-test/suites/query/sql_functions/array_functions/test_array_functions.groovy b/regression-test/suites/query/sql_functions/array_functions/test_array_functions.groovy index 4797c2d5fa..d5abee4374 100644 --- a/regression-test/suites/query/sql_functions/array_functions/test_array_functions.groovy +++ b/regression-test/suites/query/sql_functions/array_functions/test_array_functions.groovy @@ -57,4 +57,5 @@ suite("test_array_functions", "query") { qt_select "SELECT k1, array_slice(k2, 2) FROM ${tableName} ORDER BY k1" qt_select "SELECT k1, array_slice(k2, 1, 2) FROM ${tableName} ORDER BY k1" qt_select "SELECT k1, reverse(k2), reverse(k3), reverse(k4) FROM ${tableName} ORDER BY k1" + qt_select "SELECT k1, array_join(k2, '_', 'null'), array_join(k3, '-', 'null') FROM ${tableName} ORDER BY k1" }