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