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

morningman 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 e04c13b7a6 [enhancement](exception safe) make function state exception 
safe (#16771)
e04c13b7a6 is described below

commit e04c13b7a636687d871d528c3935254a0933ab49
Author: yiguolei <676222...@qq.com>
AuthorDate: Mon Feb 20 23:01:45 2023 +0800

    [enhancement](exception safe) make function state exception safe (#16771)
---
 be/src/exprs/json_functions.cpp            | 34 -----------------------
 be/src/exprs/json_functions.h              |  3 --
 be/src/exprs/string_functions.cpp          | 15 +++++-----
 be/src/exprs/string_functions.h            |  4 +--
 be/src/olap/in_list_predicate.h            | 15 +---------
 be/src/olap/like_column_predicate.cpp      | 10 +++----
 be/src/olap/like_column_predicate.h        |  1 -
 be/src/udf/udf.cpp                         | 10 +++----
 be/src/udf/udf.h                           |  3 +-
 be/src/udf/udf_internal.h                  |  4 +--
 be/src/vec/functions/function_convert_tz.h |  8 +-----
 be/src/vec/functions/function_java_udf.cpp | 10 +++----
 be/src/vec/functions/function_java_udf.h   | 14 ++++++++--
 be/src/vec/functions/function_regexp.cpp   | 44 ++++++++++++++----------------
 be/src/vec/functions/function_string.h     | 23 ++++++++++------
 be/src/vec/functions/functions_geo.cpp     | 23 ++--------------
 be/src/vec/functions/in.h                  |  6 +---
 be/src/vec/functions/like.cpp              |  9 ++----
 be/src/vec/functions/random.cpp            | 14 +---------
 19 files changed, 83 insertions(+), 167 deletions(-)

diff --git a/be/src/exprs/json_functions.cpp b/be/src/exprs/json_functions.cpp
index 8600fd9041..3016463482 100644
--- a/be/src/exprs/json_functions.cpp
+++ b/be/src/exprs/json_functions.cpp
@@ -43,40 +43,6 @@ namespace doris {
 // json path cannot contains: ", [, ]
 static const re2::RE2 JSON_PATTERN("^([^\\\"\\[\\]]*)(?:\\[([0-9]+|\\*)\\])?");
 
-rapidjson::Value JsonFunctions::parse_str_with_flag(const StringVal& arg, 
const StringVal& flag,
-                                                    const int num,
-                                                    
rapidjson::Document::AllocatorType& allocator) {
-    rapidjson::Value val;
-    if (arg.is_null || *(flag.ptr + num) == '0') { //null
-        rapidjson::Value nullObject(rapidjson::kNullType);
-        val = nullObject;
-    } else if (*(flag.ptr + num) == '1') { //bool
-        bool res = ((arg == "1") ? true : false);
-        val.SetBool(res);
-    } else if (*(flag.ptr + num) == '2') { //int
-        std::stringstream ss;
-        ss << arg.ptr;
-        int number = 0;
-        ss >> number;
-        val.SetInt(number);
-    } else if (*(flag.ptr + num) == '3') { //double
-        std::stringstream ss;
-        ss << arg.ptr;
-        double number = 0.0;
-        ss >> number;
-        val.SetDouble(number);
-    } else if (*(flag.ptr + num) == '4' || *(flag.ptr + num) == '5') {
-        StringPiece str((char*)arg.ptr, arg.len);
-        if (*(flag.ptr + num) == '4') {
-            str = str.substr(1, str.length() - 2);
-        }
-        val.SetString(str.data(), str.length(), allocator);
-    } else {
-        DCHECK(false) << "parse json type error with unknown type";
-    }
-    return val;
-}
-
 rapidjson::Value* JsonFunctions::match_value(const std::vector<JsonPath>& 
parsed_paths,
                                              rapidjson::Value* document,
                                              
rapidjson::Document::AllocatorType& mem_allocator,
diff --git a/be/src/exprs/json_functions.h b/be/src/exprs/json_functions.h
index 5740427867..39fbda875b 100644
--- a/be/src/exprs/json_functions.h
+++ b/be/src/exprs/json_functions.h
@@ -121,8 +121,5 @@ private:
                                          bool is_insert_null = false);
     static void get_parsed_paths(const std::vector<std::string>& path_exprs,
                                  std::vector<JsonPath>* parsed_paths);
-    static rapidjson::Value parse_str_with_flag(const StringVal& arg, const 
StringVal& flag,
-                                                const int num,
-                                                
rapidjson::Document::AllocatorType& allocator);
 };
 } // namespace doris
diff --git a/be/src/exprs/string_functions.cpp 
b/be/src/exprs/string_functions.cpp
index 4ef1039c73..a9b4b737e8 100644
--- a/be/src/exprs/string_functions.cpp
+++ b/be/src/exprs/string_functions.cpp
@@ -62,8 +62,9 @@ bool StringFunctions::set_re2_options(const StringVal& 
match_parameter, std::str
 }
 
 // The caller owns the returned regex. Returns nullptr if the pattern could 
not be compiled.
-re2::RE2* StringFunctions::compile_regex(const StringVal& pattern, 
std::string* error_str,
-                                         const StringVal& match_parameter) {
+bool StringFunctions::compile_regex(const StringVal& pattern, std::string* 
error_str,
+                                    const StringVal& match_parameter,
+                                    std::unique_ptr<re2::RE2>& re) {
     re2::StringPiece pattern_sp(reinterpret_cast<char*>(pattern.ptr), 
pattern.len);
     re2::RE2::Options options;
     // Disable error logging in case e.g. every row causes an error
@@ -74,19 +75,19 @@ re2::RE2* StringFunctions::compile_regex(const StringVal& 
pattern, std::string*
     options.set_dot_nl(true);
     if (!match_parameter.is_null &&
         !StringFunctions::set_re2_options(match_parameter, error_str, 
&options)) {
-        return nullptr;
+        return false;
     }
-    re2::RE2* re = new re2::RE2(pattern_sp, options);
+    re.reset(new re2::RE2(pattern_sp, options));
     if (!re->ok()) {
         std::stringstream ss;
         ss << "Could not compile regexp pattern: "
            << std::string(reinterpret_cast<char*>(pattern.ptr), pattern.len) 
<< std::endl
            << "Error: " << re->error();
         *error_str = ss.str();
-        delete re;
-        return nullptr;
+        re.reset();
+        return false;
     }
-    return re;
+    return true;
 }
 
 } // namespace doris
diff --git a/be/src/exprs/string_functions.h b/be/src/exprs/string_functions.h
index bcdff6f80a..373686dbb6 100644
--- a/be/src/exprs/string_functions.h
+++ b/be/src/exprs/string_functions.h
@@ -38,7 +38,7 @@ public:
                                 re2::RE2::Options* opts);
 
     // The caller owns the returned regex. Returns nullptr if the pattern 
could not be compiled.
-    static re2::RE2* compile_regex(const StringVal& pattern, std::string* 
error_str,
-                                   const StringVal& match_parameter);
+    static bool compile_regex(const StringVal& pattern, std::string* error_str,
+                              const StringVal& match_parameter, 
std::unique_ptr<re2::RE2>& re);
 };
 } // namespace doris
diff --git a/be/src/olap/in_list_predicate.h b/be/src/olap/in_list_predicate.h
index 5a0990cc21..182abc25a6 100644
--- a/be/src/olap/in_list_predicate.h
+++ b/be/src/olap/in_list_predicate.h
@@ -146,7 +146,6 @@ public:
                 }
             }
         } else {
-            should_delete = false;
             _values = ((HybridSetType*)hybrid_set.get())->get_inner_set();
         }
 
@@ -156,22 +155,11 @@ public:
     }
 
     ~InListPredicateBase() override {
-        if (should_delete) {
+        if constexpr (is_string_type(Type) || Type == TYPE_DECIMALV2 || 
is_date_type(Type)) {
             delete _values;
         }
     }
 
-    // Only for test
-    InListPredicateBase(uint32_t column_id, phmap::flat_hash_set<T>& values,
-                        T min_value = type_limit<T>::min(), T max_value = 
type_limit<T>::max(),
-                        bool is_opposite = false)
-            : ColumnPredicate(column_id, is_opposite),
-              _values(&values),
-              _min_value(min_value),
-              _max_value(max_value) {
-        should_delete = false;
-    }
-
     PredicateType type() const override { return PT; }
 
     Status evaluate(BitmapIndexIterator* iterator, uint32_t num_rows,
@@ -552,7 +540,6 @@ private:
     }
 
     phmap::flat_hash_set<T>* _values;
-    bool should_delete = true;
     mutable std::map<std::pair<RowsetId, uint32_t>, 
std::vector<vectorized::UInt8>>
             _segment_id_to_value_in_dict_flags;
     T _min_value;
diff --git a/be/src/olap/like_column_predicate.cpp 
b/be/src/olap/like_column_predicate.cpp
index cc5eb83a0b..cb5a127f82 100644
--- a/be/src/olap/like_column_predicate.cpp
+++ b/be/src/olap/like_column_predicate.cpp
@@ -27,11 +27,9 @@ template <>
 LikeColumnPredicate<true>::LikeColumnPredicate(bool opposite, uint32_t 
column_id,
                                                doris_udf::FunctionContext* 
fn_ctx,
                                                doris_udf::StringVal val)
-        : ColumnPredicate(column_id, opposite),
-          _fn_ctx(fn_ctx),
-          pattern(reinterpret_cast<char*>(val.ptr), val.len) {
+        : ColumnPredicate(column_id, opposite), 
pattern(reinterpret_cast<char*>(val.ptr), val.len) {
     _state = reinterpret_cast<StateType*>(
-            
_fn_ctx->get_function_state(doris_udf::FunctionContext::THREAD_LOCAL));
+            
fn_ctx->get_function_state(doris_udf::FunctionContext::THREAD_LOCAL));
     _state->search_state.clone(_like_state);
 }
 
@@ -39,9 +37,9 @@ template <>
 LikeColumnPredicate<false>::LikeColumnPredicate(bool opposite, uint32_t 
column_id,
                                                 doris_udf::FunctionContext* 
fn_ctx,
                                                 doris_udf::StringVal val)
-        : ColumnPredicate(column_id, opposite), _fn_ctx(fn_ctx), pattern(val) {
+        : ColumnPredicate(column_id, opposite), pattern(val) {
     _state = reinterpret_cast<StateType*>(
-            
_fn_ctx->get_function_state(doris_udf::FunctionContext::THREAD_LOCAL));
+            
fn_ctx->get_function_state(doris_udf::FunctionContext::THREAD_LOCAL));
 }
 
 template <bool is_vectorized>
diff --git a/be/src/olap/like_column_predicate.h 
b/be/src/olap/like_column_predicate.h
index d5d964b6c3..a38f9228fb 100644
--- a/be/src/olap/like_column_predicate.h
+++ b/be/src/olap/like_column_predicate.h
@@ -143,7 +143,6 @@ private:
 
     std::string _origin;
     // lifetime controlled by scan node
-    doris_udf::FunctionContext* _fn_ctx;
     using PatternType = std::conditional_t<is_vectorized, StringRef, 
StringVal>;
     using StateType = vectorized::LikeState;
     PatternType pattern;
diff --git a/be/src/udf/udf.cpp b/be/src/udf/udf.cpp
index cf7345122f..785b2c7db0 100644
--- a/be/src/udf/udf.cpp
+++ b/be/src/udf/udf.cpp
@@ -310,14 +310,14 @@ void FunctionContext::free(int64_t bytes) {
     _impl->_external_bytes_tracked -= bytes;
 }
 
-void FunctionContext::set_function_state(FunctionStateScope scope, void* ptr) {
+void FunctionContext::set_function_state(FunctionStateScope scope, 
std::shared_ptr<void> ptr) {
     assert(!_impl->_closed);
     switch (scope) {
     case THREAD_LOCAL:
-        _impl->_thread_local_fn_state = ptr;
+        _impl->_thread_local_fn_state = std::move(ptr);
         break;
     case FRAGMENT_LOCAL:
-        _impl->_fragment_local_fn_state = ptr;
+        _impl->_fragment_local_fn_state = std::move(ptr);
         break;
     default:
         std::stringstream ss;
@@ -475,9 +475,9 @@ void* 
FunctionContext::get_function_state(FunctionStateScope scope) const {
     // assert(!_impl->_closed);
     switch (scope) {
     case THREAD_LOCAL:
-        return _impl->_thread_local_fn_state;
+        return _impl->_thread_local_fn_state.get();
     case FRAGMENT_LOCAL:
-        return _impl->_fragment_local_fn_state;
+        return _impl->_fragment_local_fn_state.get();
     default:
         // TODO: signal error somehow
         return nullptr;
diff --git a/be/src/udf/udf.h b/be/src/udf/udf.h
index 88b06c5bc1..b57e930e36 100644
--- a/be/src/udf/udf.h
+++ b/be/src/udf/udf.h
@@ -25,6 +25,7 @@
 #include <cstdint>
 #include <functional>
 #include <iostream>
+#include <memory>
 #include <vector>
 
 // This is the only Doris header required to develop UDFs and UDAs. This header
@@ -215,7 +216,7 @@ public:
     /// GetFunctionState() is called when no pointer is set, it will return
     /// nullptr. SetFunctionState() does not take ownership of 'ptr'; it is up 
to the UDF/UDA
     /// to clean up any function state if necessary.
-    void set_function_state(FunctionStateScope scope, void* ptr);
+    void set_function_state(FunctionStateScope scope, std::shared_ptr<void> 
ptr);
 
     void* get_function_state(FunctionStateScope scope) const;
 
diff --git a/be/src/udf/udf_internal.h b/be/src/udf/udf_internal.h
index 41407a4220..ab786a6954 100644
--- a/be/src/udf/udf_internal.h
+++ b/be/src/udf/udf_internal.h
@@ -152,8 +152,8 @@ private:
     std::vector<uint8_t*> _local_allocations;
 
     /// The function state accessed via FunctionContext::Get/SetFunctionState()
-    void* _thread_local_fn_state;
-    void* _fragment_local_fn_state;
+    std::shared_ptr<void> _thread_local_fn_state;
+    std::shared_ptr<void> _fragment_local_fn_state;
 
     // The number of bytes allocated externally by the user function. In some 
cases,
     // it is too inconvenient to use the Allocate()/Free() APIs in the 
FunctionContext,
diff --git a/be/src/vec/functions/function_convert_tz.h 
b/be/src/vec/functions/function_convert_tz.h
index b4a222ef6f..caf704cde9 100644
--- a/be/src/vec/functions/function_convert_tz.h
+++ b/be/src/vec/functions/function_convert_tz.h
@@ -140,17 +140,11 @@ public:
         if (scope != FunctionContext::THREAD_LOCAL) {
             return Status::OK();
         }
-        context->set_function_state(scope, new ConvertTzCtx);
+        context->set_function_state(scope, std::make_shared<ConvertTzCtx>());
         return Status::OK();
     }
 
     Status close(FunctionContext* context, FunctionContext::FunctionStateScope 
scope) override {
-        if (scope == FunctionContext::THREAD_LOCAL) {
-            auto* convert_ctx = reinterpret_cast<ConvertTzCtx*>(
-                    
context->get_function_state(FunctionContext::THREAD_LOCAL));
-            delete convert_ctx;
-            context->set_function_state(FunctionContext::THREAD_LOCAL, 
nullptr);
-        }
         return Status::OK();
     }
 
diff --git a/be/src/vec/functions/function_java_udf.cpp 
b/be/src/vec/functions/function_java_udf.cpp
index abffb8d8bc..0a031e186f 100644
--- a/be/src/vec/functions/function_java_udf.cpp
+++ b/be/src/vec/functions/function_java_udf.cpp
@@ -64,7 +64,8 @@ Status JavaFunctionCall::prepare(FunctionContext* context,
     executor_close_id_ = env->GetMethodID(executor_cl_, "close", 
EXECUTOR_CLOSE_SIGNATURE);
     RETURN_ERROR_IF_EXC(env);
 
-    JniContext* jni_ctx = new JniContext(_argument_types.size(), this);
+    std::shared_ptr<JniContext> jni_ctx =
+            std::make_shared<JniContext>(_argument_types.size(), this);
     context->set_function_state(FunctionContext::THREAD_LOCAL, jni_ctx);
 
     // Add a scoped cleanup jni reference object. This cleans up local refs 
made below.
@@ -308,10 +309,9 @@ Status JavaFunctionCall::close(FunctionContext* context,
                                FunctionContext::FunctionStateScope scope) {
     JniContext* jni_ctx = reinterpret_cast<JniContext*>(
             context->get_function_state(FunctionContext::THREAD_LOCAL));
-    if (jni_ctx != nullptr) {
-        delete jni_ctx;
-        context->set_function_state(FunctionContext::THREAD_LOCAL, nullptr);
-    }
+    // JNIContext own some resource and its release method depend on 
JavaFunctionCall
+    // has to release the resource before JavaFunctionCall is deconstructed.
+    jni_ctx->close();
     return Status::OK();
 }
 } // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_java_udf.h 
b/be/src/vec/functions/function_java_udf.h
index 7ffa456d82..ad3335b384 100644
--- a/be/src/vec/functions/function_java_udf.h
+++ b/be/src/vec/functions/function_java_udf.h
@@ -85,6 +85,7 @@ private:
         JavaFunctionCall* parent = nullptr;
 
         jobject executor = nullptr;
+        bool is_closed = false;
 
         std::unique_ptr<int64_t[]> input_values_buffer_ptr;
         std::unique_ptr<int64_t[]> input_nulls_buffer_ptr;
@@ -119,16 +120,23 @@ private:
                   batch_size_ptr(new int32_t()),
                   output_intermediate_state_ptr(new IntermediateState()) {}
 
-        ~JniContext() {
+        void close() {
+            if (is_closed) {
+                return;
+            }
             VLOG_DEBUG << "Free resources for JniContext";
             JNIEnv* env;
-            Status status;
-            RETURN_IF_STATUS_ERROR(status, JniUtil::GetJNIEnv(&env));
+            Status status = JniUtil::GetJNIEnv(&env);
+            if (!status.ok()) {
+                LOG(WARNING) << "errors while get jni env " << status;
+                return;
+            }
             env->CallNonvirtualVoidMethodA(executor, parent->executor_cl_,
                                            parent->executor_close_id_, NULL);
             Status s = JniUtil::GetJniExceptionMsg(env);
             if (!s.ok()) LOG(WARNING) << s;
             env->DeleteGlobalRef(executor);
+            is_closed = true;
         }
 
         /// These functions are cross-compiled to IR and used by codegen.
diff --git a/be/src/vec/functions/function_regexp.cpp 
b/be/src/vec/functions/function_regexp.cpp
index 7bfe48c765..7ff07b9f09 100644
--- a/be/src/vec/functions/function_regexp.cpp
+++ b/be/src/vec/functions/function_regexp.cpp
@@ -51,13 +51,14 @@ struct RegexpReplaceImpl {
             if (re == nullptr) {
                 std::string error_str;
                 const auto& pattern = 
pattern_col->get_data_at(i).to_string_val();
-                re = StringFunctions::compile_regex(pattern, &error_str, 
StringVal::null());
-                if (re == nullptr) {
+                bool st = StringFunctions::compile_regex(pattern, &error_str, 
StringVal::null(),
+                                                         scoped_re);
+                if (!st) {
                     context->add_warning(error_str.c_str());
                     StringOP::push_null_string(i, result_data, result_offset, 
null_map);
                     continue;
                 }
-                scoped_re.reset(re);
+                re = scoped_re.get();
             }
 
             re2::StringPiece replace_str =
@@ -94,13 +95,14 @@ struct RegexpReplaceOneImpl {
             if (re == nullptr) {
                 std::string error_str;
                 const auto& pattern = 
pattern_col->get_data_at(i).to_string_val();
-                re = StringFunctions::compile_regex(pattern, &error_str, 
StringVal::null());
-                if (re == nullptr) {
+                bool st = StringFunctions::compile_regex(pattern, &error_str, 
StringVal::null(),
+                                                         scoped_re);
+                if (!st) {
                     context->add_warning(error_str.c_str());
                     StringOP::push_null_string(i, result_data, result_offset, 
null_map);
                     continue;
                 }
-                scoped_re.reset(re);
+                re = scoped_re.get();
             }
 
             re2::StringPiece replace_str =
@@ -142,13 +144,14 @@ struct RegexpExtractImpl {
             if (re == nullptr) {
                 std::string error_str;
                 const auto& pattern = 
pattern_col->get_data_at(i).to_string_val();
-                re = StringFunctions::compile_regex(pattern, &error_str, 
StringVal::null());
-                if (re == nullptr) {
+                bool st = StringFunctions::compile_regex(pattern, &error_str, 
StringVal::null(),
+                                                         scoped_re);
+                if (!st) {
                     context->add_warning(error_str.c_str());
                     StringOP::push_null_string(i, result_data, result_offset, 
null_map);
                     continue;
                 }
-                scoped_re.reset(re);
+                re = scoped_re.get();
             }
             const auto& str = str_col->get_data_at(i);
             re2::StringPiece str_sp = re2::StringPiece(str.data, str.size);
@@ -196,13 +199,14 @@ struct RegexpExtractAllImpl {
             if (re == nullptr) {
                 std::string error_str;
                 const auto& pattern = 
pattern_col->get_data_at(i).to_string_val();
-                re = StringFunctions::compile_regex(pattern, &error_str, 
StringVal::null());
-                if (re == nullptr) {
+                bool st = StringFunctions::compile_regex(pattern, &error_str, 
StringVal::null(),
+                                                         scoped_re);
+                if (!st) {
                     context->add_warning(error_str.c_str());
                     StringOP::push_null_string(i, result_data, result_offset, 
null_map);
                     continue;
                 }
-                scoped_re.reset(re);
+                re = scoped_re.get();
             }
             if (re->NumberOfCapturingGroups() == 0) {
                 StringOP::push_empty_string(i, result_data, result_offset);
@@ -282,12 +286,14 @@ public:
                 }
 
                 std::string error_str;
-                re2::RE2* re =
-                        StringFunctions::compile_regex(pattern, &error_str, 
StringVal::null());
-                if (re == nullptr) {
+                std::unique_ptr<re2::RE2> scoped_re;
+                bool st = StringFunctions::compile_regex(pattern, &error_str, 
StringVal::null(),
+                                                         scoped_re);
+                if (!st) {
                     context->set_error(error_str.c_str());
                     return Status::InvalidArgument(error_str);
                 }
+                std::shared_ptr<re2::RE2> re(scoped_re.release());
                 context->set_function_state(scope, re);
             }
         }
@@ -324,14 +330,6 @@ public:
     }
 
     Status close(FunctionContext* context, FunctionContext::FunctionStateScope 
scope) override {
-        if (scope == FunctionContext::THREAD_LOCAL) {
-            if (context->is_col_constant(1)) {
-                re2::RE2* re = 
reinterpret_cast<re2::RE2*>(context->get_function_state(scope));
-                DCHECK(re);
-                delete re;
-                context->set_function_state(scope, nullptr);
-            }
-        }
         return Status::OK();
     }
 };
diff --git a/be/src/vec/functions/function_string.h 
b/be/src/vec/functions/function_string.h
index 2e3eacf031..d230c9a60c 100644
--- a/be/src/vec/functions/function_string.h
+++ b/be/src/vec/functions/function_string.h
@@ -2473,6 +2473,14 @@ struct SubReplaceFourImpl {
     }
 };
 
+// Wrap iconv_open and iconv_close to a shared ptr call
+class IconvWrapper {
+public:
+    iconv_t cd_;
+    IconvWrapper(iconv_t cd) : cd_(cd) {}
+    ~IconvWrapper() { iconv_close(cd_); }
+};
+
 class FunctionConvertTo : public IFunction {
 public:
     static constexpr auto name = "convert_to";
@@ -2504,7 +2512,9 @@ public:
                 return Status::RuntimeError("function {} is convert to gbk 
failed in iconv_open",
                                             get_name());
             }
-            context->set_function_state(scope, cd);
+            // IconvWrapper will call iconv_close during deconstructor
+            std::shared_ptr<IconvWrapper> cd_wrapper = 
std::make_shared<IconvWrapper>(cd);
+            context->set_function_state(scope, cd_wrapper);
         } else {
             return Status::RuntimeError(
                     "Illegal second argument column of function convert. now 
only support "
@@ -2525,8 +2535,9 @@ public:
         auto& res_offset = col_res->get_offsets();
         auto& res_chars = col_res->get_chars();
         res_offset.resize(input_rows_count);
-        iconv_t cd = reinterpret_cast<iconv_t>(
-                context->get_function_state(FunctionContext::THREAD_LOCAL));
+        iconv_t cd = reinterpret_cast<IconvWrapper*>(
+                             
context->get_function_state(FunctionContext::THREAD_LOCAL))
+                             ->cd_;
         DCHECK(cd != nullptr);
 
         size_t in_len = 0, out_len = 0;
@@ -2549,12 +2560,6 @@ public:
     }
 
     Status close(FunctionContext* context, FunctionContext::FunctionStateScope 
scope) override {
-        if (scope == FunctionContext::THREAD_LOCAL) {
-            iconv_t cd = reinterpret_cast<iconv_t>(
-                    
context->get_function_state(FunctionContext::THREAD_LOCAL));
-            iconv_close(cd);
-            context->set_function_state(FunctionContext::THREAD_LOCAL, 
nullptr);
-        }
         return Status::OK();
     }
 };
diff --git a/be/src/vec/functions/functions_geo.cpp 
b/be/src/vec/functions/functions_geo.cpp
index cff645de6b..f51715c19d 100644
--- a/be/src/vec/functions/functions_geo.cpp
+++ b/be/src/vec/functions/functions_geo.cpp
@@ -273,7 +273,7 @@ struct StCircle {
             return Status::OK();
         }
 
-        auto state = new StConstructState();
+        std::shared_ptr<StConstructState> state = 
std::make_shared<StConstructState>();
         DoubleVal* lng = 
reinterpret_cast<DoubleVal*>(context->get_constant_arg(0));
         DoubleVal* lat = 
reinterpret_cast<DoubleVal*>(context->get_constant_arg(1));
         DoubleVal* radius = 
reinterpret_cast<DoubleVal*>(context->get_constant_arg(2));
@@ -295,12 +295,6 @@ struct StCircle {
     }
 
     static Status close(FunctionContext* context, 
FunctionContext::FunctionStateScope scope) {
-        if (scope != FunctionContext::FRAGMENT_LOCAL) {
-            return Status::OK();
-        }
-        StConstructState* state =
-                
reinterpret_cast<StConstructState*>(context->get_function_state(scope));
-        delete state;
         return Status::OK();
     }
 };
@@ -365,7 +359,7 @@ struct StContains {
             return Status::OK();
         }
 
-        auto contains_ctx = new StContainsState();
+        std::shared_ptr<StContainsState> contains_ctx = 
std::make_shared<StContainsState>();
         for (int i = 0; !contains_ctx->is_null && i < 2; ++i) {
             if (context->is_arg_constant(i)) {
                 StringVal* str = 
reinterpret_cast<StringVal*>(context->get_constant_arg(i));
@@ -386,12 +380,6 @@ struct StContains {
     }
 
     static Status close(FunctionContext* context, 
FunctionContext::FunctionStateScope scope) {
-        if (scope != FunctionContext::FRAGMENT_LOCAL) {
-            return Status::OK();
-        }
-        StContainsState* state =
-                
reinterpret_cast<StContainsState*>(context->get_function_state(scope));
-        delete state;
         return Status::OK();
     }
 };
@@ -486,7 +474,7 @@ struct StGeoFromText {
             return Status::OK();
         }
 
-        auto state = new StConstructState();
+        std::shared_ptr<StConstructState> state = 
std::make_shared<StConstructState>();
         auto str_value = 
reinterpret_cast<StringVal*>(context->get_constant_arg(0));
         if (str_value->is_null) {
             state->is_null = true;
@@ -507,11 +495,6 @@ struct StGeoFromText {
     }
 
     static Status close(FunctionContext* context, 
FunctionContext::FunctionStateScope scope) {
-        if (scope == FunctionContext::FRAGMENT_LOCAL) {
-            StConstructState* state =
-                    
reinterpret_cast<StConstructState*>(context->get_function_state(scope));
-            delete state;
-        }
         return Status::OK();
     }
 };
diff --git a/be/src/vec/functions/in.h b/be/src/vec/functions/in.h
index b5f3364ae7..97e299bdef 100644
--- a/be/src/vec/functions/in.h
+++ b/be/src/vec/functions/in.h
@@ -66,7 +66,7 @@ public:
         if (scope == FunctionContext::THREAD_LOCAL) {
             return Status::OK();
         }
-        auto* state = new InState();
+        std::shared_ptr<InState> state = std::make_shared<InState>();
         context->set_function_state(scope, state);
         if (context->get_arg_type(0)->type == FunctionContext::Type::TYPE_CHAR 
||
             context->get_arg_type(0)->type == 
FunctionContext::Type::TYPE_VARCHAR ||
@@ -223,10 +223,6 @@ public:
     }
 
     Status close(FunctionContext* context, FunctionContext::FunctionStateScope 
scope) override {
-        if (scope == FunctionContext::FRAGMENT_LOCAL) {
-            delete reinterpret_cast<InState*>(
-                    
context->get_function_state(FunctionContext::FRAGMENT_LOCAL));
-        }
         return Status::OK();
     }
 };
diff --git a/be/src/vec/functions/like.cpp b/be/src/vec/functions/like.cpp
index e8b0ad6321..84e8600008 100644
--- a/be/src/vec/functions/like.cpp
+++ b/be/src/vec/functions/like.cpp
@@ -391,11 +391,6 @@ Status FunctionLikeBase::execute_impl(FunctionContext* 
context, Block& block,
 
 Status FunctionLikeBase::close(FunctionContext* context,
                                FunctionContext::FunctionStateScope scope) {
-    if (scope == FunctionContext::THREAD_LOCAL) {
-        auto* state = reinterpret_cast<LikeState*>(
-                context->get_function_state(FunctionContext::THREAD_LOCAL));
-        delete state;
-    }
     return Status::OK();
 }
 
@@ -540,7 +535,7 @@ Status FunctionLike::prepare(FunctionContext* context, 
FunctionContext::Function
     if (scope != FunctionContext::THREAD_LOCAL) {
         return Status::OK();
     }
-    auto* state = new LikeState();
+    std::shared_ptr<LikeState> state = std::make_shared<LikeState>();
     context->set_function_state(scope, state);
     state->function = like_fn;
     state->predicate_like_function = like_fn_predicate;
@@ -600,7 +595,7 @@ Status FunctionRegexp::prepare(FunctionContext* context,
     if (scope != FunctionContext::THREAD_LOCAL) {
         return Status::OK();
     }
-    auto* state = new LikeState();
+    std::shared_ptr<LikeState> state = std::make_shared<LikeState>();
     context->set_function_state(scope, state);
     state->function = regexp_fn;
     state->predicate_like_function = regexp_fn_predicate;
diff --git a/be/src/vec/functions/random.cpp b/be/src/vec/functions/random.cpp
index 7ae38b4b29..976b4340a8 100644
--- a/be/src/vec/functions/random.cpp
+++ b/be/src/vec/functions/random.cpp
@@ -41,14 +41,8 @@ public:
     }
 
     Status prepare(FunctionContext* context, 
FunctionContext::FunctionStateScope scope) override {
-        std::mt19937_64* generator =
-                
reinterpret_cast<std::mt19937_64*>(context->allocate(sizeof(std::mt19937_64)));
-        if (UNLIKELY(generator == nullptr)) {
-            return Status::MemoryAllocFailed("allocate random seed generator 
failed.");
-        }
-
+        std::shared_ptr<std::mt19937_64> generator(new std::mt19937_64());
         context->set_function_state(scope, generator);
-        new (generator) std::mt19937_64();
         if (scope == FunctionContext::THREAD_LOCAL) {
             if (context->get_num_args() == 1) {
                 // This is a call to RandSeed, initialize the seed
@@ -90,12 +84,6 @@ public:
     }
 
     Status close(FunctionContext* context, FunctionContext::FunctionStateScope 
scope) override {
-        if (scope == FunctionContext::THREAD_LOCAL) {
-            uint8_t* generator = reinterpret_cast<uint8_t*>(
-                    
context->get_function_state(FunctionContext::THREAD_LOCAL));
-            context->free(generator);
-            context->set_function_state(FunctionContext::THREAD_LOCAL, 
nullptr);
-        }
         return Status::OK();
     }
 };


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

Reply via email to