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 cc84cfcc0e [feature-wip](array-type) add function array_remove (#10385) cc84cfcc0e is described below commit cc84cfcc0ebe5e50cc219c0163b26b8c0fca653a Author: xy720 <22125576+xy...@users.noreply.github.com> AuthorDate: Fri Jul 15 17:57:49 2022 +0800 [feature-wip](array-type) add function array_remove (#10385) Description: array_remove function remove all elements in array which is equal to the target. --- be/src/vec/CMakeLists.txt | 1 + .../functions/array/function_array_register.cpp | 2 + ...rray_register.cpp => function_array_remove.cpp} | 21 +- be/src/vec/functions/array/function_array_remove.h | 339 +++++++++++++++++++++ .../sql-functions/array-functions/array_remove.md | 97 ++++++ .../sql-functions/array-functions/array_remove.md | 97 ++++++ gensrc/script/doris_builtins_functions.py | 13 + .../array_functions/test_array_functions.out | 7 + .../array_functions/test_array_functions.groovy | 1 + 9 files changed, 561 insertions(+), 17 deletions(-) diff --git a/be/src/vec/CMakeLists.txt b/be/src/vec/CMakeLists.txt index de46796cae..e9646b2729 100644 --- a/be/src/vec/CMakeLists.txt +++ b/be/src/vec/CMakeLists.txt @@ -137,6 +137,7 @@ set(VEC_FILES functions/array/function_array_utils.cpp functions/array/function_arrays_overlap.cpp functions/array/function_array_distinct.cpp + functions/array/function_array_remove.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 05597de95c..573870144b 100644 --- a/be/src/vec/functions/array/function_array_register.cpp +++ b/be/src/vec/functions/array/function_array_register.cpp @@ -28,6 +28,7 @@ void register_function_array_size(SimpleFunctionFactory&); void register_function_array_aggregation(SimpleFunctionFactory&); void register_function_arrays_overlap(SimpleFunctionFactory&); void register_function_array_distinct(SimpleFunctionFactory&); +void register_function_array_remove(SimpleFunctionFactory&); void register_function_array(SimpleFunctionFactory& factory) { register_function_array_element(factory); @@ -36,6 +37,7 @@ void register_function_array(SimpleFunctionFactory& factory) { register_function_array_aggregation(factory); register_function_arrays_overlap(factory); register_function_array_distinct(factory); + register_function_array_remove(factory); } } // namespace doris::vectorized diff --git a/be/src/vec/functions/array/function_array_register.cpp b/be/src/vec/functions/array/function_array_remove.cpp similarity index 51% copy from be/src/vec/functions/array/function_array_register.cpp copy to be/src/vec/functions/array/function_array_remove.cpp index 05597de95c..b7f0eebe36 100644 --- a/be/src/vec/functions/array/function_array_register.cpp +++ b/be/src/vec/functions/array/function_array_remove.cpp @@ -14,28 +14,15 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -// This file is copied from -// https://github.com/ClickHouse/ClickHouse/blob/master/src/Functions/array/registerFunctionsArray.cpp -// and modified by Doris + +#include "vec/functions/array/function_array_remove.h" #include "vec/functions/simple_function_factory.h" namespace doris::vectorized { -void register_function_array_element(SimpleFunctionFactory&); -void register_function_array_index(SimpleFunctionFactory&); -void register_function_array_size(SimpleFunctionFactory&); -void register_function_array_aggregation(SimpleFunctionFactory&); -void register_function_arrays_overlap(SimpleFunctionFactory&); -void register_function_array_distinct(SimpleFunctionFactory&); - -void register_function_array(SimpleFunctionFactory& factory) { - register_function_array_element(factory); - register_function_array_index(factory); - register_function_array_size(factory); - register_function_array_aggregation(factory); - register_function_arrays_overlap(factory); - register_function_array_distinct(factory); +void register_function_array_remove(SimpleFunctionFactory& factory) { + factory.register_function<FunctionArrayRemove>(); } } // namespace doris::vectorized diff --git a/be/src/vec/functions/array/function_array_remove.h b/be/src/vec/functions/array/function_array_remove.h new file mode 100644 index 0000000000..a291a53bc3 --- /dev/null +++ b/be/src/vec/functions/array/function_array_remove.h @@ -0,0 +1,339 @@ +// 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/functions/function.h" +#include "vec/functions/function_helpers.h" + +namespace doris::vectorized { + +class FunctionArrayRemove : public IFunction { +public: + static constexpr auto name = "array_remove"; + static FunctionPtr create() { return std::make_shared<FunctionArrayRemove>(); } + + /// 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; } + + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + DCHECK(is_array(arguments[0])) + << "First argument for function: " << name + << " should be DataTypeArray but it has type " << arguments[0]->get_name() << "."; + return arguments[0]; + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) override { + // For default implementation of nulls args + ColumnsWithTypeAndName args = {block.get_by_position(arguments[0]), + block.get_by_position(arguments[1])}; + + auto res_column = _execute_non_nullable(args, input_rows_count); + if (!res_column) { + return Status::RuntimeError( + fmt::format("unsupported types for function {}({}, {})", get_name(), + block.get_by_position(arguments[0]).type->get_name(), + block.get_by_position(arguments[1]).type->get_name())); + } + DCHECK_EQ(args[0].column->size(), res_column->size()); + block.replace_by_position(result, std::move(res_column)); + return Status::OK(); + } + +private: + template <typename NestedColumnType, typename RightColumnType> + ColumnPtr _execute_number(const ColumnArray::Offsets& offsets, const IColumn& nested_column, + const IColumn& right_column, const UInt8* nested_null_map) { + // check array nested column type and get data + const auto& src_data = reinterpret_cast<const NestedColumnType&>(nested_column).get_data(); + + // check target column type and get data + const auto& target_data = reinterpret_cast<const RightColumnType&>(right_column).get_data(); + + PaddedPODArray<UInt8>* dst_null_map = nullptr; + MutableColumnPtr array_nested_column = nullptr; + IColumn* dst_column; + if (nested_null_map) { + auto dst_nested_column = + ColumnNullable::create(nested_column.clone_empty(), ColumnUInt8::create()); + array_nested_column = dst_nested_column->get_ptr(); + dst_column = dst_nested_column->get_nested_column_ptr(); + dst_null_map = &dst_nested_column->get_null_map_data(); + dst_null_map->reserve(offsets.back()); + } else { + auto dst_nested_column = nested_column.clone_empty(); + array_nested_column = dst_nested_column->get_ptr(); + dst_column = dst_nested_column; + } + + auto& dst_data = reinterpret_cast<NestedColumnType&>(*dst_column).get_data(); + dst_data.reserve(offsets.back()); + + auto dst_offsets_column = ColumnArray::ColumnOffsets::create(); + auto& dst_offsets = dst_offsets_column->get_data(); + dst_offsets.reserve(offsets.size()); + + size_t cur = 0; + for (size_t row = 0; row < offsets.size(); ++row) { + size_t off = offsets[row - 1]; + size_t len = offsets[row] - off; + + if (len == 0) { + // case: array:[], target:1 ==> [] + dst_offsets.push_back(cur); + continue; + } + + size_t count = 0; + for (size_t pos = 0; pos < len; ++pos) { + if (nested_null_map && nested_null_map[off + pos]) { + // case: array:[Null], target:1 ==> [Null] + dst_data.push_back(typename NestedColumnType::value_type()); + dst_null_map->push_back(1); + continue; + } + + if (src_data[off + pos] == target_data[row]) { + ++count; + } else { + dst_data.push_back(src_data[off + pos]); + if (nested_null_map) { + dst_null_map->push_back(0); + } + } + } + + cur += len - count; + dst_offsets.push_back(cur); + } + + auto dst = + ColumnArray::create(std::move(array_nested_column), std::move(dst_offsets_column)); + return dst; + } + + ColumnPtr _execute_string(const ColumnArray::Offsets& offsets, const IColumn& nested_column, + const IColumn& right_column, const UInt8* nested_null_map) { + // check array nested column type and get data + const auto& src_offs = reinterpret_cast<const ColumnString&>(nested_column).get_offsets(); + const auto& src_chars = reinterpret_cast<const ColumnString&>(nested_column).get_chars(); + + // check right column type and get data + const auto& target_offs = reinterpret_cast<const ColumnString&>(right_column).get_offsets(); + const auto& target_chars = reinterpret_cast<const ColumnString&>(right_column).get_chars(); + + PaddedPODArray<UInt8>* dst_null_map = nullptr; + MutableColumnPtr array_nested_column = nullptr; + IColumn* dst_column; + if (nested_null_map) { + auto dst_nested_column = + ColumnNullable::create(nested_column.clone_empty(), ColumnUInt8::create()); + array_nested_column = dst_nested_column->get_ptr(); + dst_column = dst_nested_column->get_nested_column_ptr(); + dst_null_map = &dst_nested_column->get_null_map_data(); + dst_null_map->reserve(offsets.back()); + } else { + auto dst_nested_column = nested_column.clone_empty(); + array_nested_column = dst_nested_column->get_ptr(); + dst_column = dst_nested_column; + } + + auto& dst_offs = reinterpret_cast<ColumnString&>(*dst_column).get_offsets(); + auto& dst_chars = reinterpret_cast<ColumnString&>(*dst_column).get_chars(); + dst_offs.reserve(src_offs.size()); + dst_chars.reserve(src_offs.back()); + + auto dst_offsets_column = ColumnArray::ColumnOffsets::create(); + auto& dst_offsets = dst_offsets_column->get_data(); + dst_offsets.reserve(offsets.size()); + + size_t cur = 0; + for (size_t row = 0; row < offsets.size(); ++row) { + size_t off = offsets[row - 1]; + size_t len = offsets[row] - off; + + if (len == 0) { + // case: array:[], target:'str' ==> [] + dst_offsets.push_back(cur); + continue; + } + + size_t target_off = target_offs[row - 1]; + size_t target_len = target_offs[row] - target_off; + + size_t count = 0; + for (size_t pos = 0; pos < len; ++pos) { + if (nested_null_map && nested_null_map[off + pos]) { + // case: array:[Null], target:'str' ==> [Null] + // dst_chars.push_back(0); + dst_offs.push_back(dst_offs.back()); + dst_null_map->push_back(1); + continue; + } + + size_t src_pos = src_offs[pos + off - 1]; + size_t src_len = src_offs[pos + off] - src_pos; + const char* src_raw_v = reinterpret_cast<const char*>(&src_chars[src_pos]); + const char* target_raw_v = reinterpret_cast<const char*>(&target_chars[target_off]); + + if (std::string_view(src_raw_v, src_len) == + std::string_view(target_raw_v, target_len)) { + ++count; + } else { + const size_t old_size = dst_chars.size(); + const size_t new_size = old_size + src_len; + dst_chars.resize(new_size); + memcpy(&dst_chars[old_size], &src_chars[src_pos], src_len); + dst_offs.push_back(new_size); + if (nested_null_map) { + dst_null_map->push_back(0); + } + } + } + + cur += len - count; + dst_offsets.push_back(cur); + } + + auto dst = + ColumnArray::create(std::move(array_nested_column), std::move(dst_offsets_column)); + return dst; + } + + template <typename NestedColumnType> + ColumnPtr _execute_number_expanded(const ColumnArray::Offsets& offsets, + const IColumn& nested_column, const IColumn& right_column, + const UInt8* nested_null_map) { + if (check_column<ColumnUInt8>(right_column)) { + return _execute_number<NestedColumnType, ColumnUInt8>(offsets, nested_column, + right_column, nested_null_map); + } else if (check_column<ColumnInt8>(right_column)) { + return _execute_number<NestedColumnType, ColumnInt8>(offsets, nested_column, + right_column, nested_null_map); + } else if (check_column<ColumnInt16>(right_column)) { + return _execute_number<NestedColumnType, ColumnInt16>(offsets, nested_column, + right_column, nested_null_map); + } else if (check_column<ColumnInt32>(right_column)) { + return _execute_number<NestedColumnType, ColumnInt32>(offsets, nested_column, + right_column, nested_null_map); + } else if (right_column.is_date_type()) { + return _execute_number<NestedColumnType, ColumnDate>(offsets, nested_column, + right_column, nested_null_map); + } else if (right_column.is_datetime_type()) { + return _execute_number<NestedColumnType, ColumnDateTime>(offsets, nested_column, + right_column, nested_null_map); + } else if (check_column<ColumnInt64>(right_column)) { + return _execute_number<NestedColumnType, ColumnInt64>(offsets, nested_column, + right_column, nested_null_map); + } else if (check_column<ColumnInt128>(right_column)) { + return _execute_number<NestedColumnType, ColumnInt128>(offsets, nested_column, + right_column, nested_null_map); + } else if (check_column<ColumnFloat32>(right_column)) { + return _execute_number<NestedColumnType, ColumnFloat32>(offsets, nested_column, + right_column, nested_null_map); + } else if (check_column<ColumnFloat64>(right_column)) { + return _execute_number<NestedColumnType, ColumnFloat64>(offsets, nested_column, + right_column, nested_null_map); + } else if (check_column<ColumnDecimal128>(right_column)) { + return _execute_number<NestedColumnType, ColumnDecimal128>( + offsets, nested_column, right_column, nested_null_map); + } + return nullptr; + } + + ColumnPtr _execute_non_nullable(const ColumnsWithTypeAndName& arguments, + size_t input_rows_count) { + // check array nested column type and get data + auto left_column = arguments[0].column->convert_to_full_column_if_const(); + const auto& array_column = reinterpret_cast<const ColumnArray&>(*left_column); + const auto& offsets = array_column.get_offsets(); + DCHECK(offsets.size() == input_rows_count); + + // check array right column type and get data + const auto right_column = arguments[1].column->convert_to_full_column_if_const(); + + const UInt8* nested_null_map = nullptr; + ColumnPtr nested_column = nullptr; + if (is_column_nullable(array_column.get_data())) { + const auto& nested_null_column = + reinterpret_cast<const ColumnNullable&>(array_column.get_data()); + nested_null_map = nested_null_column.get_null_map_column().get_data().data(); + nested_column = nested_null_column.get_nested_column_ptr(); + } else { + nested_column = array_column.get_data_ptr(); + } + + auto left_element_type = remove_nullable( + assert_cast<const DataTypeArray&>(*arguments[0].type).get_nested_type()); + auto right_type = remove_nullable((arguments[1]).type); + + ColumnPtr res = nullptr; + if (is_string(right_type) && is_string(left_element_type)) { + res = _execute_string(offsets, *nested_column, *right_column, nested_null_map); + } else if (is_number(right_type) && is_number(left_element_type)) { + if (check_column<ColumnUInt8>(*nested_column)) { + res = _execute_number_expanded<ColumnUInt8>(offsets, *nested_column, *right_column, + nested_null_map); + } else if (check_column<ColumnInt8>(*nested_column)) { + res = _execute_number_expanded<ColumnInt8>(offsets, *nested_column, *right_column, + nested_null_map); + } else if (check_column<ColumnInt16>(*nested_column)) { + res = _execute_number_expanded<ColumnInt16>(offsets, *nested_column, *right_column, + nested_null_map); + } else if (check_column<ColumnInt32>(*nested_column)) { + res = _execute_number_expanded<ColumnInt32>(offsets, *nested_column, *right_column, + nested_null_map); + } else if (check_column<ColumnInt64>(*nested_column)) { + res = _execute_number_expanded<ColumnInt64>(offsets, *nested_column, *right_column, + nested_null_map); + } else if (check_column<ColumnInt128>(*nested_column)) { + res = _execute_number_expanded<ColumnInt128>(offsets, *nested_column, *right_column, + nested_null_map); + } else if (check_column<ColumnFloat32>(*nested_column)) { + res = _execute_number_expanded<ColumnFloat32>(offsets, *nested_column, + *right_column, nested_null_map); + } else if (check_column<ColumnFloat64>(*nested_column)) { + res = _execute_number_expanded<ColumnFloat64>(offsets, *nested_column, + *right_column, nested_null_map); + } else if (check_column<ColumnDecimal128>(*nested_column)) { + res = _execute_number_expanded<ColumnDecimal128>(offsets, *nested_column, + *right_column, nested_null_map); + } + } else if (is_date_or_datetime(right_type) && is_date_or_datetime(left_element_type)) { + if (nested_column->is_date_type()) { + res = _execute_number_expanded<ColumnDate>(offsets, *nested_column, *right_column, + nested_null_map); + } else if (nested_column->is_datetime_type()) { + res = _execute_number_expanded<ColumnDateTime>(offsets, *nested_column, + *right_column, nested_null_map); + } + } + + return res; + } +}; + +} // namespace doris::vectorized diff --git a/docs/en/docs/sql-manual/sql-functions/array-functions/array_remove.md b/docs/en/docs/sql-manual/sql-functions/array-functions/array_remove.md new file mode 100644 index 0000000000..1644a0684b --- /dev/null +++ b/docs/en/docs/sql-manual/sql-functions/array-functions/array_remove.md @@ -0,0 +1,97 @@ +--- +{ + "title": "array_remove", + "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_remove + +### description + +#### Syntax + +``` +ARRAY<T> array_remove(ARRAY<T> arr, T val) +``` + +Remove all elements that equal to element from array. + +### notice + +`Only supported in vectorized engine` + +### example + +``` +mysql> set enable_vectorized_engine=true; + +mysql> select array_remove(['test', NULL, 'value'], 'value'); ++-----------------------------------------------------+ +| array_remove(ARRAY('test', NULL, 'value'), 'value') | ++-----------------------------------------------------+ +| [test, NULL] | ++-----------------------------------------------------+ + +mysql> select k1, k2, array_remove(k2, 1) from array_type_table_1; ++------+--------------------+-----------------------+ +| k1 | k2 | array_remove(`k2`, 1) | ++------+--------------------+-----------------------+ +| 1 | [1, 2, 3] | [2, 3] | +| 2 | [1, 3] | [3] | +| 3 | NULL | NULL | +| 4 | [1, 3] | [3] | +| 5 | [NULL, 1, NULL, 2] | [NULL, NULL, 2] | ++------+--------------------+-----------------------+ + +mysql> select k1, k2, array_remove(k2, k1) from array_type_table_1; ++------+--------------------+--------------------------+ +| k1 | k2 | array_remove(`k2`, `k1`) | ++------+--------------------+--------------------------+ +| 1 | [1, 2, 3] | [2, 3] | +| 2 | [1, 3] | [1, 3] | +| 3 | NULL | NULL | +| 4 | [1, 3] | [1, 3] | +| 5 | [NULL, 1, NULL, 2] | [NULL, 1, NULL, 2] | ++------+--------------------+--------------------------+ + +mysql> select k1, k2, array_remove(k2, date('2022-10-10')) from array_type_table_date; ++------+--------------------------+-------------------------------------------------+ +| k1 | k2 | array_remove(`k2`, date('2022-10-10 00:00:00')) | ++------+--------------------------+-------------------------------------------------+ +| 1 | [2021-10-10, 2022-10-10] | [2021-10-10] | +| 2 | [NULL, 2022-05-14] | [NULL, 2022-05-14] | ++------+--------------------------+-------------------------------------------------+ + +mysql> select k1, k2, array_remove(k2, k1) from array_type_table_nullable; ++------+-----------+--------------------------+ +| k1 | k2 | array_remove(`k2`, `k1`) | ++------+-----------+--------------------------+ +| NULL | [1, 2, 3] | NULL | +| 1 | NULL | NULL | +| NULL | [NULL, 1] | NULL | +| 1 | [NULL, 1] | [NULL] | ++------+-----------+--------------------------+ + +``` + +### keywords + +ARRAY,REMOVE,ARRAY_REMOVE diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_remove.md b/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_remove.md new file mode 100644 index 0000000000..59290d670b --- /dev/null +++ b/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_remove.md @@ -0,0 +1,97 @@ +--- +{ + "title": "array_remove", + "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_remove + +### description + +#### Syntax + +``` +ARRAY<T> array_remove(ARRAY<T> arr, T val) +``` + +返回移除所有的指定元素后的数组,如果输入参数为NULL,则返回NULL + +### notice + +`仅支持向量化引擎中使用` + +### example + +``` +mysql> set enable_vectorized_engine=true; + +mysql> select array_remove(['test', NULL, 'value'], 'value'); ++-----------------------------------------------------+ +| array_remove(ARRAY('test', NULL, 'value'), 'value') | ++-----------------------------------------------------+ +| [test, NULL] | ++-----------------------------------------------------+ + +mysql> select k1, k2, array_remove(k2, 1) from array_type_table_1; ++------+--------------------+-----------------------+ +| k1 | k2 | array_remove(`k2`, 1) | ++------+--------------------+-----------------------+ +| 1 | [1, 2, 3] | [2, 3] | +| 2 | [1, 3] | [3] | +| 3 | NULL | NULL | +| 4 | [1, 3] | [3] | +| 5 | [NULL, 1, NULL, 2] | [NULL, NULL, 2] | ++------+--------------------+-----------------------+ + +mysql> select k1, k2, array_remove(k2, k1) from array_type_table_1; ++------+--------------------+--------------------------+ +| k1 | k2 | array_remove(`k2`, `k1`) | ++------+--------------------+--------------------------+ +| 1 | [1, 2, 3] | [2, 3] | +| 2 | [1, 3] | [1, 3] | +| 3 | NULL | NULL | +| 4 | [1, 3] | [1, 3] | +| 5 | [NULL, 1, NULL, 2] | [NULL, 1, NULL, 2] | ++------+--------------------+--------------------------+ + +mysql> select k1, k2, array_remove(k2, date('2022-10-10')) from array_type_table_date; ++------+--------------------------+-------------------------------------------------+ +| k1 | k2 | array_remove(`k2`, date('2022-10-10 00:00:00')) | ++------+--------------------------+-------------------------------------------------+ +| 1 | [2021-10-10, 2022-10-10] | [2021-10-10] | +| 2 | [NULL, 2022-05-14] | [NULL, 2022-05-14] | ++------+--------------------------+-------------------------------------------------+ + +mysql> select k1, k2, array_remove(k2, k1) from array_type_table_nullable; ++------+-----------+--------------------------+ +| k1 | k2 | array_remove(`k2`, `k1`) | ++------+-----------+--------------------------+ +| NULL | [1, 2, 3] | NULL | +| 1 | NULL | NULL | +| NULL | [NULL, 1] | NULL | +| 1 | [NULL, 1] | [NULL] | ++------+-----------+--------------------------+ + +``` + +### keywords + +ARRAY,REMOVE,ARRAY_REMOVE diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 04d4477e4c..3883e7b1ac 100755 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -212,6 +212,19 @@ visible_functions = [ [['array_product'], 'DOUBLE', ['ARRAY_BIGINT'], '', '', '', 'vec', 'ALWAYS_NULLABLE'], [['array_product'], 'DOUBLE', ['ARRAY_LARGEINT'], '', '', '', 'vec', 'ALWAYS_NULLABLE'], + [['array_remove'], 'ARRAY_TINYINT', ['ARRAY_TINYINT', 'TINYINT'], '', '', '', 'vec', ''], + [['array_remove'], 'ARRAY_SMALLINT', ['ARRAY_SMALLINT', 'SMALLINT'], '', '', '', 'vec', ''], + [['array_remove'], 'ARRAY_INT', ['ARRAY_INT', 'INT'], '', '', '', 'vec', ''], + [['array_remove'], 'ARRAY_BIGINT', ['ARRAY_BIGINT', 'BIGINT'], '', '', '', 'vec', ''], + [['array_remove'], 'ARRAY_LARGEINT', ['ARRAY_LARGEINT', 'LARGEINT'], '', '', '', 'vec', ''], + [['array_remove'], 'ARRAY_FLOAT', ['ARRAY_FLOAT', 'FLOAT'], '', '', '', 'vec', ''], + [['array_remove'], 'ARRAY_DOUBLE', ['ARRAY_DOUBLE', 'DOUBLE'], '', '', '', 'vec', ''], + [['array_remove'], 'ARRAY_DECIMALV2', ['ARRAY_DECIMALV2', 'DECIMALV2'], '', '', '', 'vec', ''], + [['array_remove'], 'ARRAY_DATETIME', ['ARRAY_DATETIME', 'DATETIME'], '', '', '', 'vec', ''], + [['array_remove'], 'ARRAY_DATE', ['ARRAY_DATE', 'DATE'], '', '', '', 'vec', ''], + [['array_remove'], 'ARRAY_VARCHAR', ['ARRAY_VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''], + [['array_remove'], 'ARRAY_STRING', ['ARRAY_STRING', 'STRING'], '', '', '', 'vec', ''], + # Timestamp functions [['unix_timestamp'], 'INT', [], '_ZN5doris18TimestampFunctions7to_unixEPN9doris_udf15FunctionContextE', 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 3f5b7b7ba2..e0830f69b1 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 @@ -31,3 +31,10 @@ 5 [] ['a', 'b', 'c', 'd'] 6 [1, 2, 3, 4, 5] ['a', 'b', 'c', 'd'] +-- !select -- +[2, 3] 1 +[4] 2 +[] 3 +[1, 2, 3, 5, 3, 2, 1] 4 +[] 5 +[1, 2, 3, 4, 5, 4, 3, 2, 1] 6 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 93fb380126..75e16a5c2f 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 @@ -48,4 +48,5 @@ suite("test_array_functions", "query") { qt_select "SELECT k1, cardinality(k2), cardinality(k3) FROM ${tableName} ORDER BY k1" qt_select "SELECT k1, arrays_overlap(k2, k4) FROM ${tableName} ORDER BY k1" qt_select "SELECT k1, array_distinct(k2), array_distinct(k3) FROM ${tableName} ORDER BY k1" + qt_select "SELECT array_remove(k2, k1), k1 FROM ${tableName} ORDER BY k1" } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org