diff --git a/src/observer/mysql/ob_query_driver.cpp b/src/observer/mysql/ob_query_driver.cpp index e78617038b..cd4f453cfd 100644 --- a/src/observer/mysql/ob_query_driver.cpp +++ b/src/observer/mysql/ob_query_driver.cpp @@ -698,8 +698,9 @@ int ObQueryDriver::process_lob_locator_results(ObObj& value, LOG_WARN("Lob: handle lob locator v1 failed", K(value), K(GET_MIN_CLUSTER_VERSION())); } } else { // lob locator v2 + ObArenaAllocator tmp_alloc("ObLobRead", OB_MALLOC_NORMAL_BLOCK_SIZE, session_info->get_effective_tenant_id()); ObTextStringIter instr_iter(value); - if (OB_FAIL(instr_iter.init(0, session_info, allocator))) { + if (OB_FAIL(instr_iter.init(0, session_info, allocator, &tmp_alloc))) { LOG_WARN("init lob str inter failed", K(ret), K(value)); } else if (OB_FAIL(instr_iter.get_full_data(data))) { LOG_WARN("Lob: init lob str iter failed ", K(value)); diff --git a/src/share/ob_lob_access_utils.cpp b/src/share/ob_lob_access_utils.cpp index 490cba1ad4..5bde900211 100644 --- a/src/share/ob_lob_access_utils.cpp +++ b/src/share/ob_lob_access_utils.cpp @@ -65,8 +65,8 @@ ObTextStringIter::~ObTextStringIter() int ObTextStringIter::init(uint32_t buffer_len, const sql::ObBasicSessionInfo *session, - ObIAllocator *allocator, - bool clone_remote /* false */) + ObIAllocator *res_allocator, + ObIAllocator *tmp_allocator) { int ret = OB_SUCCESS; if (is_init_) { @@ -80,6 +80,7 @@ int ObTextStringIter::init(uint32_t buffer_len, } else { ObLobLocatorV2 locator(datum_str_, has_lob_header_); is_lob_ = true; + tmp_alloc_ = tmp_allocator; if (!has_lob_header_) { is_outrow_ = false; @@ -88,17 +89,18 @@ int ObTextStringIter::init(uint32_t buffer_len, COMMON_LOG(WARN,"Lob: invalid lob", K(ret)); } else if (FALSE_IT(is_outrow_ = !locator.has_inrow_data())) { } else if (!is_outrow_) { // inrow lob always get full data, no need ctx_ - } else if (OB_ISNULL(allocator)) { + } else if (OB_ISNULL(res_allocator)) { ret = OB_INVALID_ARGUMENT; COMMON_LOG(WARN, "Lob: iter with null allocator", K(ret)); } else { // outrow lob + ObIAllocator *allocator = (tmp_allocator == nullptr) ? res_allocator : tmp_allocator; char *ctx_buffer = static_cast(allocator->alloc(sizeof(ObLobTextIterCtx))); if (OB_ISNULL(ctx_buffer)) { ret = OB_ALLOCATE_MEMORY_FAILED; COMMON_LOG(WARN,"Lob: failed to alloc output buffer", K(ret), KP(ctx_buffer)); } else { - ctx_ = new (ctx_buffer) ObLobTextIterCtx(locator, session, allocator, buffer_len); - ctx_ ->init(clone_remote); + ctx_ = new (ctx_buffer) ObLobTextIterCtx(locator, session, res_allocator, buffer_len); + ctx_ ->init(); } } } @@ -194,7 +196,7 @@ int ObTextStringIter::get_outrow_lob_full_data(ObIAllocator *allocator /*nullptr COMMON_LOG(WARN, "Lob: get lob manager failed.", K(ret)); } else { // outrow persist lob storage::ObLobAccessParam param; - if (OB_SUCC(init_lob_access_param(param, ctx_, cs_type_, allocator))) { + if (OB_SUCC(init_lob_access_param(param, ctx_, cs_type_, tmp_alloc_))) { param.len_ = (ctx_->total_access_len_ == 0 ? param.byte_size_ : ctx_->total_access_len_); if (!param.ls_id_.is_valid() || !param.tablet_id_.is_valid()) { @@ -249,7 +251,7 @@ int ObTextStringIter::get_outrow_prefix_data(uint32_t prefix_char_len) COMMON_LOG(WARN, "Lob: get lob manager failed.", K(ret)); } else { // outrow persist lob storage::ObLobAccessParam param; - if (OB_SUCC(init_lob_access_param(param, ctx_, cs_type_))) { + if (OB_SUCC(init_lob_access_param(param, ctx_, cs_type_, tmp_alloc_))) { param.len_ = prefix_char_len; if (!param.ls_id_.is_valid() || !param.tablet_id_.is_valid()) { @@ -298,7 +300,7 @@ int ObTextStringIter::get_current_block(ObString &str) return ret; } -int ObTextStringIter::get_full_data(ObString &data_str, ObIAllocator *allocator) +int ObTextStringIter::get_full_data(ObString &data_str) { int ret = OB_SUCCESS; if (!is_init_ || state_ != TEXTSTRING_ITER_INIT) { @@ -316,7 +318,7 @@ int ObTextStringIter::get_full_data(ObString &data_str, ObIAllocator *allocator) } } else { // outrow lob, read full data into a inrow local tmp lob currently - if (OB_FAIL(get_outrow_lob_full_data(allocator))) { + if (OB_FAIL(get_outrow_lob_full_data())) { COMMON_LOG(WARN, "Lob: get lob outrow data failed", K(ret)); } else { data_str.assign_ptr(ctx_->buff_, ctx_->content_byte_len_); @@ -391,7 +393,7 @@ int ObTextStringIter::get_first_block(ObString &str) COMMON_LOG(WARN, "Lob: get lob manager failed.", K(ret)); } else { storage::ObLobAccessParam param; - if (OB_SUCC(init_lob_access_param(param, ctx_, cs_type_))) { + if (OB_SUCC(init_lob_access_param(param, ctx_, cs_type_, tmp_alloc_))) { param.scan_backward_ = ctx_->is_backward_; param.offset_ = ctx_->start_offset_; param.len_ = (ctx_->total_access_len_ == 0 ? param.byte_size_ : ctx_->total_access_len_); @@ -830,7 +832,7 @@ int ObTextStringIter::get_char_len(int64_t &char_length) COMMON_LOG(WARN, "Lob: get lob manager failed.", K(ret)); } else { storage::ObLobAccessParam param; - if (OB_SUCC(init_lob_access_param(param, ctx_, cs_type_))) { + if (OB_SUCC(init_lob_access_param(param, ctx_, cs_type_, tmp_alloc_))) { uint64_t length = 0; if (!param.ls_id_.is_valid() || !param.tablet_id_.is_valid()) { ret = OB_INVALID_ARGUMENT; @@ -911,10 +913,12 @@ int ObTextStringIter::append_outrow_lob_fulldata(ObObj &obj, mem_loc_extern->payload_size_ = static_cast(lob_data_byte_len); // copy inrow data + int64_t tenant_id = (session == nullptr) ? MTL_ID() : session->get_effective_tenant_id(); + ObArenaAllocator tmp_alloc("ObLobRead", OB_MALLOC_NORMAL_BLOCK_SIZE, tenant_id); ObTextStringIterState state; ObString src_block_data; ObTextStringIter instr_iter(obj); - if (OB_FAIL(instr_iter.init(0, session, &allocator))) { + if (OB_FAIL(instr_iter.init(0, session, &allocator, &tmp_alloc))) { COMMON_LOG(WARN, "Lob: init text string iter failed", K(instr_iter)); } else { while (OB_SUCC(ret) diff --git a/src/share/ob_lob_access_utils.h b/src/share/ob_lob_access_utils.h index a132758ae8..01c93511dc 100644 --- a/src/share/ob_lob_access_utils.h +++ b/src/share/ob_lob_access_utils.h @@ -116,7 +116,7 @@ public: bool has_lob_header) : type_(type), cs_type_(cs_type), is_init_(false), is_lob_(false), is_outrow_(false), has_lob_header_(has_lob_header), state_(TEXTSTRING_ITER_INVALID), datum_str_(datum_str), - ctx_(nullptr), err_ret_(OB_SUCCESS) + ctx_(nullptr), err_ret_(OB_SUCCESS), tmp_alloc_(nullptr) { if (is_lob_storage(type)) { validate_has_lob_header(has_lob_header_); @@ -126,7 +126,7 @@ public: ObTextStringIter(const ObObj &obj) : type_(obj.get_type()), cs_type_(obj.get_collation_type()), is_init_(false), is_lob_(false), is_outrow_(false), has_lob_header_(obj.has_lob_header()), state_(TEXTSTRING_ITER_INVALID), - datum_str_(obj.get_string()), ctx_(nullptr), err_ret_(OB_SUCCESS) + datum_str_(obj.get_string()), ctx_(nullptr), err_ret_(OB_SUCCESS), tmp_alloc_(nullptr) { if (is_lob_storage(obj.get_type())) { validate_has_lob_header(has_lob_header_); @@ -139,14 +139,14 @@ public: int init(uint32_t buffer_len, const sql::ObBasicSessionInfo *session = NULL, - ObIAllocator *allocator = NULL, - bool clone_remote = false); + ObIAllocator *res_allocator = NULL, + ObIAllocator *tmp_allocator = NULL); ObTextStringIterState get_next_block(ObString &str); int get_current_block(ObString &str); - int get_full_data(ObString &data_str, ObIAllocator *allocator = nullptr); + int get_full_data(ObString &data_str); int get_inrow_or_outrow_prefix_data(ObString &data_str, uint32_t prefix_char_len = DEAFULT_LOB_PREFIX_CHAR_LEN); @@ -207,6 +207,7 @@ private: const ObString datum_str_; ObLobTextIterCtx *ctx_; int err_ret_; + ObIAllocator *tmp_alloc_; }; // wrapper class to handle templob output(including string types) diff --git a/src/sql/engine/expr/ob_datum_cast.cpp b/src/sql/engine/expr/ob_datum_cast.cpp index 614705c5f2..8cd19af8ba 100644 --- a/src/sql/engine/expr/ob_datum_cast.cpp +++ b/src/sql/engine/expr/ob_datum_cast.cpp @@ -3851,9 +3851,10 @@ CAST_FUNC_NAME(text, string) ObExprStrResAlloc res_alloc(expr, ctx); ObTextStringIter instr_iter(in_type, in_cs_type, child_res->get_string(), has_lob_header); if (OB_FAIL(instr_iter.init(0, ctx.exec_ctx_.get_my_session(), - is_same_charset ? reinterpret_cast(&res_alloc) : &temp_allocator))) { + is_same_charset ? reinterpret_cast(&res_alloc) : &temp_allocator, + &temp_allocator))) { LOG_WARN("init lob str iter failed ", K(ret), K(in_type)); - } else if (OB_FAIL(instr_iter.get_full_data(data, &temp_allocator))) { + } else if (OB_FAIL(instr_iter.get_full_data(data))) { LOG_WARN("init lob str iter failed ", K(ret), K(in_type)); } else if (lib::is_oracle_mode() && ob_is_clob(in_type, in_cs_type)