fix lob text string iter use res allocator for tmp case

This commit is contained in:
obdev
2024-02-06 20:05:42 +00:00
committed by ob-robot
parent c44a356b58
commit 56db6c235a
4 changed files with 27 additions and 20 deletions

View File

@ -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));

View File

@ -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<char *>(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<uint32_t>(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)

View File

@ -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)

View File

@ -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<ObIAllocator *>(&res_alloc) : &temp_allocator))) {
is_same_charset ? reinterpret_cast<ObIAllocator *>(&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)