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

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new daa7c620c6e branch-4.1: [fix](function) avoid ICU default-locale 
contention #66440 (#67071)
daa7c620c6e is described below

commit daa7c620c6e0c275a0a3474395890a7399491ee6
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Tue Aug 25 09:52:10 2026 +0800

    branch-4.1: [fix](function) avoid ICU default-locale contention #66440 
(#67071)
    
    Cherry-picked from #66440
    
    Co-authored-by: York Cao <[email protected]>
---
 be/src/exprs/function/function_string.cpp       |  7 +--
 be/test/exprs/function/function_string_test.cpp | 63 ++++++++++++++++++++++++-
 2 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/be/src/exprs/function/function_string.cpp 
b/be/src/exprs/function/function_string.cpp
index 4eb0b1462cb..4ee19bca304 100644
--- a/be/src/exprs/function/function_string.cpp
+++ b/be/src/exprs/function/function_string.cpp
@@ -18,6 +18,7 @@
 #include <ctype.h>
 #include <math.h>
 #include <re2/stringpiece.h>
+#include <unicode/locid.h>
 #include <unicode/schriter.h>
 #include <unicode/uchar.h>
 #include <unicode/unistr.h>
@@ -593,7 +594,7 @@ struct TransferImpl {
         icu::StringPiece sp;
         sp.set(data, size);
         icu::UnicodeString unicode_str = icu::UnicodeString::fromUTF8(sp);
-        unicode_str.toUpper();
+        unicode_str.toUpper(icu::Locale::getRoot());
         unicode_str.toUTF8String(result);
     }
 
@@ -601,7 +602,7 @@ struct TransferImpl {
         icu::StringPiece sp;
         sp.set(data, size);
         icu::UnicodeString unicode_str = icu::UnicodeString::fromUTF8(sp);
-        unicode_str.toLower();
+        unicode_str.toLower(icu::Locale::getRoot());
         unicode_str.toUTF8String(result);
     }
 };
@@ -683,7 +684,7 @@ struct InitcapImpl {
         icu::StringPiece sp;
         sp.set(data, size);
         icu::UnicodeString unicode_str = icu::UnicodeString::fromUTF8(sp);
-        unicode_str.toLower();
+        unicode_str.toLower(icu::Locale::getRoot());
         icu::UnicodeString output_str;
         bool need_capitalize = true;
         icu::StringCharacterIterator iter(unicode_str);
diff --git a/be/test/exprs/function/function_string_test.cpp 
b/be/test/exprs/function/function_string_test.cpp
index 23bdb855704..fc10591f0ff 100644
--- a/be/test/exprs/function/function_string_test.cpp
+++ b/be/test/exprs/function/function_string_test.cpp
@@ -15,6 +15,9 @@
 // specific language governing permissions and limitations
 // under the License.
 
+#include <unicode/locid.h>
+#include <unicode/utypes.h>
+
 #include <cstdint>
 #include <cstring>
 #include <memory>
@@ -26,6 +29,7 @@
 #include "core/field.h"
 #include "core/types.h"
 #include "exprs/function/function_test_util.h"
+#include "util/defer_op.h"
 #include "util/encryption_util.h"
 #include "util/md5.h"
 
@@ -548,6 +552,8 @@ TEST(function_string_test, function_string_lower_test) {
                 {{std::string("GROSSE")}, std::string("grosse")},
                 {{std::string("Å")}, std::string("å")},
                 {{std::string("ΣΟΦΟΣ")}, std::string("σοφος")},
+                {{std::string("Iİı")}, std::string("ii̇ı")},
+                {{std::string("ΟΣ")}, std::string("ος")},
                 {{std::string("123ABC_")}, std::string("123abc_")},
                 {{std::string("MYtestSTR")}, std::string("myteststr")},
                 {{std::string("")}, std::string("")},
@@ -572,6 +578,7 @@ TEST(function_string_test, function_string_upper_test) {
                 {{std::string("MYtestSTR")}, std::string("MYTESTSTR")},
                 {{std::string("àç")}, std::string("ÀÇ")},
                 {{std::string("straße")}, std::string("STRASSE")},
+                {{std::string("ıi")}, std::string("II")},
                 {{std::string("àçac123")}, std::string("ÀÇAC123")},
                 {{std::string("ffi")}, std::string("FFI")},
                 {{std::string("Dž")}, std::string("DŽ")},
@@ -609,6 +616,59 @@ TEST(function_string_test, function_string_upper_test) {
     }
 }
 
+// LOWER/UPPER/INITCAP case-map through the ICU root locale, independent of the
+// process default locale. Under a Turkish (tr_TR) default locale ICU maps 
ASCII
+// 'I' -> 'ı' (U+0131) and 'i' -> 'İ' (U+0130); the root locale keeps the plain
+// ASCII round-trip. This test installs a tr_TR ICU default and asserts every
+// result stays locale independent.
+//
+// TransferImpl/InitcapImpl only take the ICU path when the whole input buffer
+// contains a non-ASCII byte; pure-ASCII columns use the locale-neutral SIMD/C
+// fast path. Each data set therefore keeps a non-ASCII anchor row so that
+// check_function_all_arg_comb's batched (non-const) combination routes the
+// ASCII rows through ICU, where the default locale would otherwise leak in.
+TEST(function_string_test, function_string_case_root_locale_test) {
+    UErrorCode status = U_ZERO_ERROR;
+    const icu::Locale saved_default = icu::Locale::getDefault();
+    icu::Locale::setDefault(icu::Locale("tr", "TR"), status);
+    ASSERT_TRUE(U_SUCCESS(status)) << "failed to install tr_TR ICU default 
locale";
+    // RAII restore of the process-wide ICU default locale, even if an 
assertion
+    // below throws during stack unwinding.
+    Defer restore_default {[&]() {
+        UErrorCode restore_status = U_ZERO_ERROR;
+        icu::Locale::setDefault(saved_default, restore_status);
+    }};
+
+    InputTypeSet input_types = {PrimitiveType::TYPE_VARCHAR};
+    {
+        DataSet data_set = {
+                {{std::string("I")}, std::string("i")},             // tr 
default -> "ı"
+                {{std::string("KIZILAY")}, std::string("kizilay")}, // tr 
default -> "kızılay"
+                {{std::string("ÀÇ")}, std::string("àç")},           // 
non-ASCII anchor: forces ICU
+        };
+        check_function_all_arg_comb<DataTypeString, 
true>(std::string("lower"), input_types,
+                                                          data_set);
+    }
+    {
+        DataSet data_set = {
+                {{std::string("i")}, std::string("I")},               // tr 
default -> "İ"
+                {{std::string("istanbul")}, std::string("ISTANBUL")}, // tr 
default -> "İSTANBUL"
+                {{std::string("straße")}, std::string("STRASSE")},    // 
length-changing anchor
+        };
+        check_function_all_arg_comb<DataTypeString, 
true>(std::string("upper"), input_types,
+                                                          data_set);
+    }
+    {
+        DataSet data_set = {
+                {{std::string("BIT")}, std::string("Bit")},                 // 
tr default -> "Bıt"
+                {{std::string("KIZILAY BIT")}, std::string("Kizilay Bit")}, // 
tr -> "Kızılay Bıt"
+                {{std::string("ÀÇ")}, std::string("Àç")},                   // 
non-ASCII anchor
+        };
+        check_function_all_arg_comb<DataTypeString, 
true>(std::string("initcap"), input_types,
+                                                          data_set);
+    }
+}
+
 TEST(function_string_test, function_string_trim_test) {
     std::string func_name = "trim";
     {
@@ -3425,7 +3485,8 @@ TEST(function_string_test, function_initcap) {
                          std::string("Grosse     Àstanbul , Àçac123    
Σοφος")},
                         {{std::string("HELLO, WORLD!")}, std::string("Hello, 
World!")},
                         {{std::string("HHHH+-1; asAAss__!")}, 
std::string("Hhhh+-1; Asaass__!")},
-                        {{std::string("a,B,C,D")}, std::string("A,B,C,D")}};
+                        {{std::string("a,B,C,D")}, std::string("A,B,C,D")},
+                        {{std::string("straße")}, std::string("Straße")}};
 
     check_function_all_arg_comb<DataTypeString, true>(func_name, input_types, 
data_set);
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to