From 3fff5f39a0070057d4581fe89b15d17d12e537a2 Mon Sep 17 00:00:00 2001 From: obdev Date: Fri, 19 May 2023 10:41:38 +0000 Subject: [PATCH] bugfix : xml/json deep copy in pl && xmltype define but not init in pl --- deps/oblib/src/lib/json_type/ob_json_tree.cpp | 126 +++++++++++++++--- deps/oblib/src/lib/json_type/ob_json_tree.h | 32 ++--- src/pl/ob_pl_user_type.h | 1 + 3 files changed, 121 insertions(+), 38 deletions(-) diff --git a/deps/oblib/src/lib/json_type/ob_json_tree.cpp b/deps/oblib/src/lib/json_type/ob_json_tree.cpp index 082bc8759c..53b693af6a 100644 --- a/deps/oblib/src/lib/json_type/ob_json_tree.cpp +++ b/deps/oblib/src/lib/json_type/ob_json_tree.cpp @@ -540,7 +540,7 @@ void ObJsonObject::update_serialize_size(int64_t change_size) } } -ObJsonNode *ObJsonObject::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonObject::clone(ObIAllocator* allocator, bool is_deep_copy) const { INIT_SUCC(ret); @@ -551,14 +551,32 @@ ObJsonNode *ObJsonObject::clone(ObIAllocator* allocator) const } else { ObJsonObject *new_obj = static_cast(new_node); uint64_t len = element_count(); + ObString key_str; for (uint64_t i = 0; i < len && OB_SUCC(ret); i++) { - ObJsonNode *old_value = object_array_[i].get_value(); - if (OB_FAIL(new_obj->add(object_array_[i].get_key(), old_value->clone(allocator)))) { - LOG_WARN("add obj failed", K(ret), K(object_array_[i].get_key())); + if (is_deep_copy) { + char* str_buf = NULL; + if (OB_ISNULL(str_buf = static_cast(allocator->alloc(object_array_[i].get_key().length())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", K(ret), K(object_array_[i].get_key().length())); + } else { + key_str.assign_buffer(str_buf, object_array_[i].get_key().length()); + if (object_array_[i].get_key().length() != + key_str.write(object_array_[i].get_key().ptr(), object_array_[i].get_key().length())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get text from expr", K(ret), K(key_str)); + } + } + } else { + key_str.assign_ptr(object_array_[i].get_key().ptr(), object_array_[i].get_key().length()); + } + if (OB_SUCC(ret)) { + ObJsonNode *old_value = object_array_[i].get_value(); + if (OB_FAIL(new_obj->add(key_str, old_value->clone(allocator, is_deep_copy)))) { + LOG_WARN("add obj failed", K(ret), K(object_array_[i].get_key())); + } } } } - return ret != OB_SUCCESS ? NULL : new_node; } @@ -865,7 +883,7 @@ void ObJsonArray::update_serialize_size(int64_t change_size) } } -ObJsonNode *ObJsonArray::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonArray::clone(ObIAllocator* allocator, bool is_deep_copy) const { INIT_SUCC(ret); @@ -877,7 +895,7 @@ ObJsonNode *ObJsonArray::clone(ObIAllocator* allocator) const ObJsonArray *new_array = static_cast(new_node); uint64_t size = element_count(); for (uint64_t i = 0; i < size && OB_SUCC(ret); i++) { - if (OB_FAIL(new_array->append(node_vector_[i]->clone(allocator)))) { + if (OB_FAIL(new_array->append(node_vector_[i]->clone(allocator, is_deep_copy)))) { LOG_WARN("array append clone failed", K(ret), K(i), K(size)); } } @@ -1078,67 +1096,131 @@ int ObJsonOInterval::parse() return ret; } -ObJsonNode *ObJsonDecimal::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonDecimal::clone(ObIAllocator* allocator, bool is_deep_copy) const { return ObJsonTreeUtil::clone_new_node(allocator, value(), get_precision(), get_scale()); } -ObJsonNode *ObJsonDouble::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonDouble::clone(ObIAllocator* allocator, bool is_deep_copy) const { return ObJsonTreeUtil::clone_new_node(allocator, value()); } -ObJsonNode *ObJsonOFloat::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonOFloat::clone(ObIAllocator* allocator, bool is_deep_copy) const { return ObJsonTreeUtil::clone_new_node(allocator, value()); } -ObJsonNode *ObJsonInt::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonInt::clone(ObIAllocator* allocator, bool is_deep_copy) const { return ObJsonTreeUtil::clone_new_node(allocator, value()); } -ObJsonNode *ObJsonUint::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonUint::clone(ObIAllocator* allocator, bool is_deep_copy) const { return ObJsonTreeUtil::clone_new_node(allocator, value()); } -ObJsonNode *ObJsonString::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonString::clone(ObIAllocator* allocator, bool is_deep_copy) const { ObJsonNode* str_node = ObJsonTreeUtil::clone_new_node(allocator, value().ptr(), length()); if (OB_NOT_NULL(str_node)) { (static_cast(str_node))->set_ext(ext_); } + if (is_deep_copy) { + char* str_buf =NULL; + if (OB_ISNULL(str_buf = static_cast(allocator->alloc(length())))) { + LOG_WARN_RET(OB_ALLOCATE_MEMORY_FAILED, "fail to alloc memory for string"); + } else { + ObString key_str(length(), 0, str_buf); + if (length() != key_str.write(value().ptr(), length())) { + LOG_WARN_RET(OB_ALLOCATE_MEMORY_FAILED, "fail to alloc memory for string"); + } else { + ObJsonString *json_str = static_cast(str_node); + json_str->set_value(key_str.ptr(), key_str.length()); + str_node = json_str; + } + } + } return str_node; } -ObJsonNode *ObJsonORawString::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonORawString::clone(ObIAllocator* allocator, bool is_deep_copy) const { - return ObJsonTreeUtil::clone_new_node(allocator, value().ptr(), length(), json_type_); + ObJsonNode* str_node = ObJsonTreeUtil::clone_new_node(allocator, value().ptr(), length(), json_type_); + int ret = OB_SUCCESS; + if (is_deep_copy) { + char* str_buf =NULL; + if (OB_ISNULL(str_buf = static_cast(allocator->alloc(length())))) { + LOG_WARN_RET(OB_ALLOCATE_MEMORY_FAILED, "fail to alloc memory for string"); + } else { + ObString key_str(length(), 0, str_buf); + if (length() != key_str.write(value().ptr(), length())) { + LOG_WARN_RET(OB_ALLOCATE_MEMORY_FAILED, "fail to alloc memory for string"); + } else { + ObJsonORawString *json_str = static_cast(str_node); + json_str->set_value(key_str.ptr(), key_str.length()); + str_node = json_str; + } + } + } + return str_node; } -ObJsonNode *ObJsonOInterval::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonOInterval::clone(ObIAllocator* allocator, bool is_deep_copy) const { - return ObJsonTreeUtil::clone_new_node(allocator, value().ptr(), length(), field_type_); + ObJsonNode* str_node = ObJsonTreeUtil::clone_new_node(allocator, value().ptr(), length(), field_type_); + if (is_deep_copy) { + char* str_buf =NULL; + if (OB_ISNULL(str_buf = static_cast(allocator->alloc(length())))) { + LOG_WARN_RET(OB_ALLOCATE_MEMORY_FAILED, "fail to alloc memory for string"); + } else { + ObString key_str(length(), 0, str_buf); + if (length() != key_str.write(value().ptr(), length())) { + LOG_WARN_RET(OB_ALLOCATE_MEMORY_FAILED, "fail to alloc memory for string"); + } else { + ObJsonOInterval *json_str = static_cast(str_node); + json_str->set_value(key_str.ptr(), key_str.length()); + str_node = json_str; + } + } + } + return str_node; } -ObJsonNode *ObJsonNull::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonNull::clone(ObIAllocator* allocator, bool is_deep_copy) const { return ObJsonTreeUtil::clone_new_node(allocator, is_not_null_); } -ObJsonNode *ObJsonDatetime::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonDatetime::clone(ObIAllocator* allocator, bool is_deep_copy) const { return ObJsonTreeUtil::clone_new_node(allocator, json_type(), value_); } -ObJsonNode *ObJsonOpaque::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonOpaque::clone(ObIAllocator* allocator, bool is_deep_copy) const { ObString content(value_.length(), value_.ptr()); - return ObJsonTreeUtil::clone_new_node(allocator, content, field_type_); + ObJsonNode* str_node = ObJsonTreeUtil::clone_new_node(allocator, content, field_type_); + if (is_deep_copy) { + char* str_buf =NULL; + if (OB_ISNULL(str_buf = static_cast(allocator->alloc(content.length())))) { + LOG_WARN_RET(OB_ALLOCATE_MEMORY_FAILED, "fail to alloc memory for string"); + } else { + ObString key_str(content.length(), 0, str_buf); + if (content.length() != key_str.write(content.ptr(), content.length())) { + LOG_WARN_RET(OB_ALLOCATE_MEMORY_FAILED, "fail to alloc memory for string"); + } else { + ObJsonOpaque *json_str = static_cast(str_node); + json_str->set_value(key_str); + str_node = json_str; + } + } + } + return str_node; } -ObJsonNode *ObJsonBoolean::clone(ObIAllocator* allocator) const +ObJsonNode *ObJsonBoolean::clone(ObIAllocator* allocator, bool is_deep_copy) const { return ObJsonTreeUtil::clone_new_node(allocator, value()); } diff --git a/deps/oblib/src/lib/json_type/ob_json_tree.h b/deps/oblib/src/lib/json_type/ob_json_tree.h index 065e733bdd..a8d6707d83 100644 --- a/deps/oblib/src/lib/json_type/ob_json_tree.h +++ b/deps/oblib/src/lib/json_type/ob_json_tree.h @@ -80,7 +80,7 @@ public: virtual bool is_number() const { return false; } virtual uint32_t depth() const = 0; virtual uint64_t get_serialize_size() = 0; - virtual ObJsonNode *clone(ObIAllocator* allocator) const = 0; + virtual ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const = 0; OB_INLINE void set_serialize_size(uint64_t size) { serialize_size_ = size; } OB_INLINE void set_serialize_delta_size(int64_t size) { @@ -218,7 +218,7 @@ public: update_serialize_size_cascade(size); } void update_serialize_size(int64_t change_size = 0); - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; // Get json node by key. // @@ -347,7 +347,7 @@ public: update_serialize_size_cascade(size); } void update_serialize_size(int64_t change_size = 0); - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; // Removes the array element by index. // @@ -457,7 +457,7 @@ public: return value_.get_serialize_size() + serialization::encoded_length_i16(prec_) + serialization::encoded_length_i16(scale_); } - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; private: number::ObNumber value_; ObPrecision prec_; @@ -484,7 +484,7 @@ public: OB_INLINE void set_value(double value) { value_ = value; } OB_INLINE double value() const { return value_; } OB_INLINE uint64_t get_serialize_size() { return sizeof(double); } - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; private: double value_; DISALLOW_COPY_AND_ASSIGN(ObJsonDouble); @@ -512,7 +512,7 @@ public: { return serialization::encoded_length_vi64(value_); } - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; private: int64_t value_; DISALLOW_COPY_AND_ASSIGN(ObJsonInt); @@ -543,7 +543,7 @@ public: { return serialization::encoded_length_vi64(value_); } - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; private: uint64_t value_; bool is_string_length_; @@ -578,7 +578,7 @@ public: { return serialization::encoded_length_vi64(length()) + length(); } - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; void set_ext(uint64_t type) { ext_ = type; } uint64_t get_ext() { return ext_; } private: @@ -611,7 +611,7 @@ public: OB_INLINE ObJsonNodeType json_type() const override { return ObJsonNodeType::J_NULL; } OB_INLINE uint64_t get_serialize_size() { return sizeof(char); } OB_INLINE bool is_not_null() { return is_not_null_;} - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; private: DISALLOW_COPY_AND_ASSIGN(ObJsonNull); bool is_not_null_; @@ -647,7 +647,7 @@ public: } return size; } - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; private: ObTime value_; ObObjType field_type_; @@ -683,7 +683,7 @@ public: { return sizeof(uint16_t) + sizeof(uint64_t) + size(); // [field_type][length][value]; } - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; private: ObObjType field_type_; common::ObString value_; @@ -713,7 +713,7 @@ public: return bool_ret; } OB_INLINE uint64_t get_serialize_size() { return sizeof(char); } - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; private: bool value_; DISALLOW_COPY_AND_ASSIGN(ObJsonBoolean); @@ -746,7 +746,7 @@ public: OB_INLINE void set_value(float value) { value_ = value; } OB_INLINE float value() const { return value_; } OB_INLINE uint64_t get_serialize_size() { return sizeof(float); } - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; private: float value_; DISALLOW_COPY_AND_ASSIGN(ObJsonOFloat); @@ -810,14 +810,14 @@ public: { return field_type_ == ObIntervalYMType ? ObJsonNodeType::J_OYEARMONTH : ObJsonNodeType::J_ODAYSECOND; } - + OB_INLINE void set_value(const char *str, uint64_t length) { str_val_.assign_ptr(str, length); } OB_INLINE const common::ObString &value() const { return str_val_; } OB_INLINE uint64_t length() const { return str_val_.length(); } OB_INLINE uint64_t get_serialize_size() { return serialization::encoded_length_vi64(length()) + length(); } - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; private: ObString str_val_; @@ -872,7 +872,7 @@ public: { return serialization::encoded_length_vi64(length()) + length(); } - ObJsonNode *clone(ObIAllocator* allocator) const; + ObJsonNode *clone(ObIAllocator* allocator, bool is_deep_copy = false) const; private: ObString str_val_; ObJsonNodeType json_type_; diff --git a/src/pl/ob_pl_user_type.h b/src/pl/ob_pl_user_type.h index 85fd824335..bcc2871558 100644 --- a/src/pl/ob_pl_user_type.h +++ b/src/pl/ob_pl_user_type.h @@ -17,6 +17,7 @@ #include "lib/hash/ob_array_index_hash_set.h" #include "lib/container/ob_array_wrap.h" #include "lib/json_type/ob_json_tree.h" +#include "share/rc/ob_tenant_base.h" namespace oceanbase {