You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by li...@apache.org on 2022/10/19 03:10:42 UTC

[doris] branch master updated: [function](string_function) add new string function 'not_null_or_empty' (#13418)

This is an automated email from the ASF dual-hosted git repository.

lihaopeng 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 8a068c8c92 [function](string_function) add new string function 'not_null_or_empty' (#13418)
8a068c8c92 is described below

commit 8a068c8c9278d9c44c4e724c6eb914178ed814f4
Author: zy-kkk <zh...@qq.com>
AuthorDate: Wed Oct 19 11:10:37 2022 +0800

    [function](string_function) add new string function 'not_null_or_empty' (#13418)
---
 be/src/exprs/string_functions.cpp                  |  8 +++
 be/src/exprs/string_functions.h                    |  2 +
 be/src/vec/functions/function_string.cpp           |  1 +
 be/src/vec/functions/function_string.h             | 64 +++++++++++++++++-----
 .../string-functions/not_null_or_empty.md          | 60 ++++++++++++++++++++
 docs/sidebars.json                                 |  1 +
 .../string-functions/not_null_or_empty.md          | 60 ++++++++++++++++++++
 gensrc/script/doris_builtins_functions.py          |  7 +++
 .../string_functions/test_string_function.out      |  9 +++
 .../string_functions/test_string_function.groovy   |  4 ++
 10 files changed, 202 insertions(+), 14 deletions(-)

diff --git a/be/src/exprs/string_functions.cpp b/be/src/exprs/string_functions.cpp
index 8c381f5d0c..bb033d0c04 100644
--- a/be/src/exprs/string_functions.cpp
+++ b/be/src/exprs/string_functions.cpp
@@ -143,6 +143,14 @@ BooleanVal StringFunctions::null_or_empty(FunctionContext* context, const String
     }
 }
 
+BooleanVal StringFunctions::not_null_or_empty(FunctionContext* context, const StringVal& str) {
+    if (str.is_null || str.len == 0) {
+        return 0;
+    } else {
+        return 1;
+    }
+}
+
 StringVal StringFunctions::space(FunctionContext* context, const IntVal& len) {
     if (len.is_null) {
         return StringVal::null();
diff --git a/be/src/exprs/string_functions.h b/be/src/exprs/string_functions.h
index ac9cfee632..ad8cc356a5 100644
--- a/be/src/exprs/string_functions.h
+++ b/be/src/exprs/string_functions.h
@@ -60,6 +60,8 @@ public:
                                            const doris_udf::StringVal& suffix);
     static doris_udf::BooleanVal null_or_empty(doris_udf::FunctionContext* context,
                                                const doris_udf::StringVal& str);
+    static doris_udf::BooleanVal not_null_or_empty(doris_udf::FunctionContext* context,
+                                                   const doris_udf::StringVal& str);
     static doris_udf::StringVal space(doris_udf::FunctionContext* context,
                                       const doris_udf::IntVal& len);
     static doris_udf::StringVal repeat(doris_udf::FunctionContext* context,
diff --git a/be/src/vec/functions/function_string.cpp b/be/src/vec/functions/function_string.cpp
index 8ab6066372..b8bf150249 100644
--- a/be/src/vec/functions/function_string.cpp
+++ b/be/src/vec/functions/function_string.cpp
@@ -666,6 +666,7 @@ void register_function_string(SimpleFunctionFactory& factory) {
     factory.register_function<FunctionLeft>();
     factory.register_function<FunctionRight>();
     factory.register_function<FunctionNullOrEmpty>();
+    factory.register_function<FunctionNotNullOrEmpty>();
     factory.register_function<FunctionStringConcat>();
     factory.register_function<FunctionStringElt>();
     factory.register_function<FunctionStringConcatWs>();
diff --git a/be/src/vec/functions/function_string.h b/be/src/vec/functions/function_string.h
index c916cd17f5..9588e7a2c0 100644
--- a/be/src/vec/functions/function_string.h
+++ b/be/src/vec/functions/function_string.h
@@ -391,6 +391,37 @@ public:
     }
 };
 
+struct NullOrEmptyImpl {
+    static DataTypes get_variadic_argument_types() { return {std::make_shared<DataTypeUInt8>()}; }
+
+    static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
+                          size_t result, size_t input_rows_count, bool reverse) {
+        auto res_map = ColumnUInt8::create(input_rows_count, 0);
+
+        auto column = block.get_by_position(arguments[0]).column;
+        if (auto* nullable = check_and_get_column<const ColumnNullable>(*column)) {
+            column = nullable->get_nested_column_ptr();
+            VectorizedUtils::update_null_map(res_map->get_data(), nullable->get_null_map_data());
+        }
+        auto str_col = assert_cast<const ColumnString*>(column.get());
+        const auto& offsets = str_col->get_offsets();
+
+        auto& res_map_data = res_map->get_data();
+        for (int i = 0; i < input_rows_count; ++i) {
+            int size = offsets[i] - offsets[i - 1];
+            res_map_data[i] |= (size == 0);
+        }
+        if (reverse) {
+            for (int i = 0; i < input_rows_count; ++i) {
+                res_map_data[i] = !res_map_data[i];
+            }
+        }
+
+        block.replace_by_position(result, std::move(res_map));
+        return Status::OK();
+    }
+};
+
 class FunctionNullOrEmpty : public IFunction {
 public:
     static constexpr auto name = "null_or_empty";
@@ -407,23 +438,28 @@ public:
 
     Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
                         size_t result, size_t input_rows_count) override {
-        auto res_map = ColumnUInt8::create(input_rows_count, 0);
+        NullOrEmptyImpl::execute(context, block, arguments, result, input_rows_count, false);
+        return Status::OK();
+    }
+};
 
-        auto column = block.get_by_position(arguments[0]).column;
-        if (auto* nullable = check_and_get_column<const ColumnNullable>(*column)) {
-            column = nullable->get_nested_column_ptr();
-            VectorizedUtils::update_null_map(res_map->get_data(), nullable->get_null_map_data());
-        }
-        auto str_col = assert_cast<const ColumnString*>(column.get());
-        const auto& offsets = str_col->get_offsets();
+class FunctionNotNullOrEmpty : public IFunction {
+public:
+    static constexpr auto name = "not_null_or_empty";
+    static FunctionPtr create() { return std::make_shared<FunctionNotNullOrEmpty>(); }
+    String get_name() const override { return name; }
+    size_t get_number_of_arguments() const override { return 1; }
 
-        auto& res_map_data = res_map->get_data();
-        for (int i = 0; i < input_rows_count; ++i) {
-            int size = offsets[i] - offsets[i - 1];
-            res_map_data[i] |= (size == 0);
-        }
+    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
+        return std::make_shared<DataTypeUInt8>();
+    }
 
-        block.replace_by_position(result, std::move(res_map));
+    bool use_default_implementation_for_nulls() const override { return false; }
+    bool use_default_implementation_for_constants() const override { return true; }
+
+    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
+                        size_t result, size_t input_rows_count) override {
+        NullOrEmptyImpl::execute(context, block, arguments, result, input_rows_count, true);
         return Status::OK();
     }
 };
diff --git a/docs/en/docs/sql-manual/sql-functions/string-functions/not_null_or_empty.md b/docs/en/docs/sql-manual/sql-functions/string-functions/not_null_or_empty.md
new file mode 100644
index 0000000000..9d807e1107
--- /dev/null
+++ b/docs/en/docs/sql-manual/sql-functions/string-functions/not_null_or_empty.md
@@ -0,0 +1,60 @@
+---
+{
+    "title": "not_null_or_empty",
+    "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.
+-->
+
+## not_null_or_empty
+### description
+#### Syntax
+
+`BOOLEAN NOT_NULL_OR_EMPTY (VARCHAR str)`
+
+It returns false if the string is an empty string or NULL. Otherwise it returns true.
+
+### example
+
+```
+MySQL [(none)]> select not_null_or_empty(null);
++-------------------------+
+| not_null_or_empty(NULL) |
++-------------------------+
+|                       0 |
++-------------------------+
+
+MySQL [(none)]> select not_null_or_empty("");
++-----------------------+
+| not_null_or_empty('') |
++-----------------------+
+|                     0 |
++-----------------------+
+
+MySQL [(none)]> select not_null_or_empty("a");
++------------------------+
+| not_null_or_empty('a') |
++------------------------+
+|                      1 |
++------------------------+
+```
+### keywords
+    NOT_NULL_OR_EMPTY
diff --git a/docs/sidebars.json b/docs/sidebars.json
index 8c7cb3a277..8721e9b76f 100644
--- a/docs/sidebars.json
+++ b/docs/sidebars.json
@@ -371,6 +371,7 @@
                                 "sql-manual/sql-functions/string-functions/ltrim",
                                 "sql-manual/sql-functions/string-functions/rtrim",
                                 "sql-manual/sql-functions/string-functions/null_or_empty",
+                                "sql-manual/sql-functions/string-functions/not_null_or_empty",
                                 "sql-manual/sql-functions/string-functions/hex",
                                 "sql-manual/sql-functions/string-functions/unhex",
                                 "sql-manual/sql-functions/string-functions/elt",
diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/not_null_or_empty.md b/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/not_null_or_empty.md
new file mode 100644
index 0000000000..89d0cb0b88
--- /dev/null
+++ b/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/not_null_or_empty.md
@@ -0,0 +1,60 @@
+---
+{
+    "title": "not_null_or_empty",
+    "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.
+-->
+
+## not_null_or_empty
+### description
+#### Syntax
+
+`BOOLEAN NOT_NULL_OR_EMPTY (VARCHAR str)`
+
+如果字符串为空字符串或者NULL,返回false。否则,返回true。
+
+### example
+
+```
+MySQL [(none)]> select not_null_or_empty(null);
++-------------------------+
+| not_null_or_empty(NULL) |
++-------------------------+
+|                       0 |
++-------------------------+
+
+MySQL [(none)]> select not_null_or_empty("");
++-----------------------+
+| not_null_or_empty('') |
++-----------------------+
+|                     0 |
++-----------------------+
+
+MySQL [(none)]> select not_null_or_empty("a");
++------------------------+
+| not_null_or_empty('a') |
++------------------------+
+|                      1 |
++------------------------+
+```
+### keywords
+    NOT_NULL_OR_EMPTY
diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py
index f1bb4faf86..621bcb3764 100755
--- a/gensrc/script/doris_builtins_functions.py
+++ b/gensrc/script/doris_builtins_functions.py
@@ -2026,6 +2026,9 @@ visible_functions = [
     [['null_or_empty'], 'BOOLEAN', ['VARCHAR'],
         '_ZN5doris15StringFunctions13null_or_emptyEPN9doris_udf15FunctionContextERKNS1_9StringValE',
         '', '', 'vec', 'ALWAYS_NOT_NULLABLE'],
+    [['not_null_or_empty'], 'BOOLEAN', ['VARCHAR'],
+     '_ZN5doris15StringFunctions17not_null_or_emptyEPN9doris_udf15FunctionContextERKNS1_9StringValE',
+     '', '', 'vec', 'ALWAYS_NOT_NULLABLE'],
     [['space'], 'VARCHAR', ['INT'],
         '_ZN5doris15StringFunctions5spaceEPN9doris_udf15FunctionContextERKNS1_6IntValE', '', '', 'vec', ''],
     [['repeat'], 'VARCHAR', ['VARCHAR', 'INT'],
@@ -2157,6 +2160,9 @@ visible_functions = [
     [['null_or_empty'], 'BOOLEAN', ['STRING'],
         '_ZN5doris15StringFunctions13null_or_emptyEPN9doris_udf15FunctionContextERKNS1_9StringValE',
         '', '', 'vec', 'ALWAYS_NOT_NULLABLE'],
+    [['not_null_or_empty'], 'BOOLEAN', ['STRING'],
+     '_ZN5doris15StringFunctions17not_null_or_emptyEPN9doris_udf15FunctionContextERKNS1_9StringValE',
+     '', '', 'vec', 'ALWAYS_NOT_NULLABLE'],
     [['space'], 'STRING', ['INT'],
         '_ZN5doris15StringFunctions5spaceEPN9doris_udf15FunctionContextERKNS1_6IntValE', '', '', 'vec', ''],
     [['repeat'], 'STRING', ['STRING', 'INT'],
@@ -2714,6 +2720,7 @@ non_null_result_with_null_param_functions = [
     'nvl',
     'nullif',
     'null_or_empty',
+    'not_null_or_empty'
     'coalesce',
     'array',
     'json_array',
diff --git a/regression-test/data/query_p0/sql_functions/string_functions/test_string_function.out b/regression-test/data/query_p0/sql_functions/string_functions/test_string_function.out
index d0f2b8c71a..1eaf68bbca 100644
--- a/regression-test/data/query_p0/sql_functions/string_functions/test_string_function.out
+++ b/regression-test/data/query_p0/sql_functions/string_functions/test_string_function.out
@@ -185,6 +185,15 @@ true
 -- !sql --
 false
 
+-- !sql --
+false
+
+-- !sql --
+false
+
+-- !sql --
+true
+
 -- !sql --
 aaa
 
diff --git a/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function.groovy b/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function.groovy
index 80ef709bd3..2a107ef487 100644
--- a/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function.groovy
+++ b/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function.groovy
@@ -102,6 +102,10 @@ suite("test_string_function") {
     qt_sql "select null_or_empty(\"\");"
     qt_sql "select null_or_empty(\"a\");"
 
+    qt_sql "select not_null_or_empty(null);"
+    qt_sql "select not_null_or_empty(\"\");"
+    qt_sql "select not_null_or_empty(\"a\");"
+
     qt_sql "SELECT repeat(\"a\", 3);"
     qt_sql "SELECT repeat(\"a\", -1);"
     qt_sql "SELECT repeat(\"a\", 0);"


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org