From 225bdb1fda1db70da0e2e3c2086568dff46cf295 Mon Sep 17 00:00:00 2001 From: qiye Date: Tue, 14 Sep 2021 09:59:13 +0800 Subject: [PATCH] [Bug] fix `replace` function bug (#6605) * fix replace function bug * fix replace docs --- be/src/exprs/string_functions.cpp | 9 +++++++-- be/test/exprs/string_functions_test.cpp | 5 +++++ docs/.vuepress/sidebar/en.js | 1 + docs/.vuepress/sidebar/zh-CN.js | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/be/src/exprs/string_functions.cpp b/be/src/exprs/string_functions.cpp index 8df42cd86f..233be37c2b 100644 --- a/be/src/exprs/string_functions.cpp +++ b/be/src/exprs/string_functions.cpp @@ -972,14 +972,19 @@ StringVal StringFunctions::replace(FunctionContext* context, const StringVal& or if (origStr.is_null || oldStr.is_null || newStr.is_null) { return StringVal::null(); } + // Empty string is a substring of all strings. + // If old str is an empty string, the std::string.find(oldStr) is always return 0. + // With an empty old str, there is no need to do replace. + if (oldStr.len == 0) { + return origStr; + } std::string orig_str = std::string(reinterpret_cast(origStr.ptr), origStr.len); std::string old_str = std::string(reinterpret_cast(oldStr.ptr), oldStr.len); std::string new_str = std::string(reinterpret_cast(newStr.ptr), newStr.len); std::string::size_type pos = 0; std::string::size_type oldLen = old_str.size(); std::string::size_type newLen = new_str.size(); - while ((pos = orig_str.find(old_str, pos))) { - if (pos == std::string::npos) break; + while ((pos = orig_str.find(old_str, pos)) != std::string::npos) { orig_str.replace(pos, oldLen, new_str); pos += newLen; } diff --git a/be/test/exprs/string_functions_test.cpp b/be/test/exprs/string_functions_test.cpp index d950f11ce3..fe894cda66 100644 --- a/be/test/exprs/string_functions_test.cpp +++ b/be/test/exprs/string_functions_test.cpp @@ -559,6 +559,11 @@ TEST_F(StringFunctionsTest, replace) { ASSERT_EQ(StringVal("http://华夏zhongguo:9090"), StringFunctions::replace(ctx, StringVal("http://中国hello:9090"), StringVal("中国hello"), StringVal("华夏zhongguo"))); + + //old substring is at the beginning of string + ASSERT_EQ(StringVal("ftp://www.baidu.com:9090"), + StringFunctions::replace(ctx, StringVal("http://www.baidu.com:9090"), + StringVal("http"), StringVal("ftp"))); } TEST_F(StringFunctionsTest, parse_url) { diff --git a/docs/.vuepress/sidebar/en.js b/docs/.vuepress/sidebar/en.js index 8791ab30b7..2b7aba3af9 100644 --- a/docs/.vuepress/sidebar/en.js +++ b/docs/.vuepress/sidebar/en.js @@ -346,6 +346,7 @@ module.exports = [ "money_format", "null_or_empty", "repeat", + "replace", "reverse", "right", "rpad", diff --git a/docs/.vuepress/sidebar/zh-CN.js b/docs/.vuepress/sidebar/zh-CN.js index 50363555fe..a3b7525820 100644 --- a/docs/.vuepress/sidebar/zh-CN.js +++ b/docs/.vuepress/sidebar/zh-CN.js @@ -350,6 +350,7 @@ module.exports = [ "money_format", "null_or_empty", "repeat", + "replace", "reverse", "right", "rpad",