You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by ga...@apache.org on 2023/02/01 03:17:13 UTC
[doris] branch master updated: [Refactor](function) Rewrite the function elt (#16287)
This is an automated email from the ASF dual-hosted git repository.
gabriellee 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 95d7c2de26 [Refactor](function) Rewrite the function elt (#16287)
95d7c2de26 is described below
commit 95d7c2de26385c5f4003a8c09f2e12df160a520e
Author: HappenLee <ha...@hotmail.com>
AuthorDate: Wed Feb 1 11:17:06 2023 +0800
[Refactor](function) Rewrite the function elt (#16287)
---
be/src/vec/functions/function_string.h | 105 +++++++++++++++++----
.../string_functions/test_string_function.out | 17 +++-
.../string_functions/test_string_function.groovy | 1 +
3 files changed, 99 insertions(+), 24 deletions(-)
diff --git a/be/src/vec/functions/function_string.h b/be/src/vec/functions/function_string.h
index 07cff73325..2a50b609e1 100644
--- a/be/src/vec/functions/function_string.h
+++ b/be/src/vec/functions/function_string.h
@@ -731,36 +731,103 @@ public:
DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
return make_nullable(std::make_shared<DataTypeString>());
}
- bool use_default_implementation_for_nulls() const override { return true; }
+ 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 {
int arguent_size = arguments.size();
- auto pos_col =
- block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
- if (auto* nullable = check_and_get_column<const ColumnNullable>(*pos_col)) {
- pos_col = nullable->get_nested_column_ptr();
- }
- auto& pos_data = assert_cast<const ColumnInt32*>(pos_col.get())->get_data();
- auto pos = pos_data[0];
int num_children = arguent_size - 1;
- if (pos < 1 || num_children == 0 || pos > num_children) {
- auto null_map = ColumnUInt8::create(input_rows_count, 1);
- auto res = ColumnString::create();
- auto& res_data = res->get_chars();
- auto& res_offset = res->get_offsets();
- res_offset.resize(input_rows_count);
+ auto res = ColumnString::create();
+
+ if (auto const_column = check_and_get_column<ColumnConst>(
+ *block.get_by_position(arguments[0]).column)) {
+ auto data = const_column->get_data_at(0);
+ // return NULL, pos is null or pos < 0 or pos > num_children
+ auto is_null = data.data == nullptr;
+ auto pos = is_null ? 0 : *(Int32*)data.data;
+ is_null = pos <= 0 || pos > num_children;
+
+ auto null_map = ColumnUInt8::create(input_rows_count, is_null);
+ if (is_null) {
+ res->insert_many_defaults(input_rows_count);
+ } else {
+ auto& target_column = block.get_by_position(arguments[pos]).column;
+ if (auto target_const_column = check_and_get_column<ColumnConst>(*target_column)) {
+ auto target_data = target_const_column->get_data_at(0);
+ if (target_data.data == nullptr) {
+ null_map = ColumnUInt8::create(input_rows_count, is_null);
+ res->insert_many_defaults(input_rows_count);
+ } else {
+ res->insert_many_data(target_data.data, target_data.size, input_rows_count);
+ }
+ } else if (auto target_nullable_column =
+ check_and_get_column<ColumnNullable>(*target_column)) {
+ auto& target_null_map = target_nullable_column->get_null_map_data();
+ VectorizedUtils::update_null_map(
+ assert_cast<ColumnUInt8&>(*null_map).get_data(), target_null_map);
+
+ auto& target_str_column = assert_cast<const ColumnString&>(
+ target_nullable_column->get_nested_column());
+ res->get_chars().assign(target_str_column.get_chars().begin(),
+ target_str_column.get_chars().end());
+ res->get_offsets().assign(target_str_column.get_offsets().begin(),
+ target_str_column.get_offsets().end());
+ } else {
+ auto& target_str_column = assert_cast<const ColumnString&>(*target_column);
+ res->get_chars().assign(target_str_column.get_chars().begin(),
+ target_str_column.get_chars().end());
+ res->get_offsets().assign(target_str_column.get_offsets().begin(),
+ target_str_column.get_offsets().end());
+ }
+ }
+ block.get_by_position(result).column =
+ ColumnNullable::create(std::move(res), std::move(null_map));
+ } else if (auto pos_null_column = check_and_get_column<ColumnNullable>(
+ *block.get_by_position(arguments[0]).column)) {
+ auto& pos_column =
+ assert_cast<const ColumnInt32&>(pos_null_column->get_nested_column());
+ auto& pos_null_map = pos_null_column->get_null_map_data();
+ auto null_map = ColumnUInt8::create(input_rows_count, false);
+ auto& res_null_map = assert_cast<ColumnUInt8&>(*null_map).get_data();
+
for (size_t i = 0; i < input_rows_count; ++i) {
- res_offset[i] = res_data.size();
+ auto pos = pos_column.get_element(i);
+ res_null_map[i] =
+ pos_null_map[i] || pos <= 0 || pos > num_children ||
+ block.get_by_position(arguments[pos]).column->get_data_at(i).data ==
+ nullptr;
+ if (res_null_map[i]) {
+ res->insert_default();
+ } else {
+ auto insert_data = block.get_by_position(arguments[pos]).column->get_data_at(i);
+ res->insert_data(insert_data.data, insert_data.size);
+ }
}
block.get_by_position(result).column =
ColumnNullable::create(std::move(res), std::move(null_map));
- return Status::OK();
- }
+ } else {
+ auto& pos_column =
+ assert_cast<const ColumnInt32&>(*block.get_by_position(arguments[0]).column);
+ auto null_map = ColumnUInt8::create(input_rows_count, false);
+ auto& res_null_map = assert_cast<ColumnUInt8&>(*null_map).get_data();
- block.get_by_position(result).column =
- make_nullable(block.get_by_position(arguments[pos]).column);
+ for (size_t i = 0; i < input_rows_count; ++i) {
+ auto pos = pos_column.get_element(i);
+ res_null_map[i] =
+ pos <= 0 || pos > num_children ||
+ block.get_by_position(arguments[pos]).column->get_data_at(i).data ==
+ nullptr;
+ if (res_null_map[i]) {
+ res->insert_default();
+ } else {
+ auto insert_data = block.get_by_position(arguments[pos]).column->get_data_at(i);
+ res->insert_data(insert_data.data, insert_data.size);
+ }
+ }
+ block.get_by_position(result).column =
+ ColumnNullable::create(std::move(res), std::move(null_map));
+ }
return Status::OK();
}
};
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 cf6ad2c94c..671cdc2cc8 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
@@ -11,6 +11,12 @@ doris
-- !sql --
\N
+-- !sql --
+1 varchar varchar
+2 varchar \N
+3 varchar \N
+4 varchar \N
+
-- !sql --
ac
@@ -225,7 +231,7 @@ hello
world
-- !sql --
-\\N
+\N
-- !sql --
world
@@ -234,10 +240,10 @@ world
hello
-- !sql --
-\\N
+\N
-- !sql --
-\\N
+\N
-- !sql --
abc
@@ -246,7 +252,7 @@ abc
#xyz
-- !sql --
-\\N
+\N
-- !sql --
xyz
@@ -255,7 +261,7 @@ xyz
123#
-- !sql --
-\\N
+\N
-- !sql --
true
@@ -367,3 +373,4 @@ tNEW-STRorigin str
-- !sql --
d***is
+
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 8975cb2c68..569e7822c5 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
@@ -22,6 +22,7 @@ suite("test_string_function") {
qt_sql "select elt(1, \"hello\", \"doris\");"
qt_sql "select elt(2, \"hello\", \"doris\");"
qt_sql "select elt(3, \"hello\", \"doris\");"
+ qt_sql "select c1, c2, elt(c1, c2) from (select number as c1, 'varchar' as c2 from numbers('number'='5') where number > 0) a;"
qt_sql "select append_trailing_char_if_absent('a','c');"
qt_sql "select append_trailing_char_if_absent('ac','c');"
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org