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

Reply via email to