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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]