diff --git a/src/sql/engine/expr/ob_datum_cast.cpp b/src/sql/engine/expr/ob_datum_cast.cpp index 631df07d5d..2ca98d66d9 100644 --- a/src/sql/engine/expr/ob_datum_cast.cpp +++ b/src/sql/engine/expr/ob_datum_cast.cpp @@ -515,16 +515,10 @@ static int common_copy_string(const ObExpr &expr, int ret = OB_SUCCESS; char *out_ptr = NULL; int64_t len = align_offset + src.length(); - if (expr.res_buf_len_ < len) { - if (OB_ISNULL(out_ptr = expr.get_str_res_mem(ctx, len))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("allocate memory failed", K(ret)); - } + if (OB_ISNULL(out_ptr = expr.get_str_res_mem(ctx, len))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", K(ret)); } else { - out_ptr = const_cast(res_datum.ptr_); - } - - if (OB_SUCC(ret)) { MEMMOVE(out_ptr + align_offset, src.ptr(), len - align_offset); MEMSET(out_ptr, 0, align_offset); res_datum.set_string(out_ptr, len); @@ -552,16 +546,10 @@ static int common_copy_string_zf(const ObExpr &expr, } else if (CM_IS_ZERO_FILL(expr.extra_) && out_len > src.length()) { char *out_ptr = NULL; // out_ptr may overlap with src, so memmove is used. - if (expr.res_buf_len_ < out_len) { - if (OB_ISNULL(out_ptr = expr.get_str_res_mem(ctx, out_len))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("allocate memory failed", K(ret)); - } + if (OB_ISNULL(out_ptr = expr.get_str_res_mem(ctx, out_len))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", K(ret)); } else { - out_ptr = const_cast(res_datum.ptr_); - } - - if (OB_SUCC(ret)) { int64_t zf_len = out_len - src.length(); if (0 < zf_len) { MEMMOVE(out_ptr + zf_len, src.ptr(), src.length()); diff --git a/src/sql/engine/expr/ob_expr.cpp b/src/sql/engine/expr/ob_expr.cpp index e6f6d07560..cc02245651 100644 --- a/src/sql/engine/expr/ob_expr.cpp +++ b/src/sql/engine/expr/ob_expr.cpp @@ -574,6 +574,16 @@ void ObExpr::reset_datums_ptr(char *frame, const int64_t size) const } } +void ObExpr::reset_datum_ptr(char *frame, const int64_t size, const int64_t idx) const +{ + ObDatum *datum = reinterpret_cast(frame + datum_off_); + datum += idx; + char *ptr = frame + res_buf_off_ + (batch_idx_mask_ & idx) * res_buf_len_; + if (datum->ptr_ != ptr && idx < size) { + datum->ptr_ = ptr; + } +} + int ObExpr::eval_one_datum_of_batch(ObEvalCtx &ctx, common::ObDatum *&datum) const { int ret = OB_SUCCESS; @@ -599,6 +609,7 @@ int ObExpr::eval_one_datum_of_batch(ObEvalCtx &ctx, common::ObDatum *&datum) con } datum = reinterpret_cast(frame + datum_off_) + ctx.get_batch_idx(); if (need_evaluate) { + reset_datum_ptr(frame, ctx.get_batch_size(), ctx.get_batch_idx()); ret = eval_func_(*this, ctx, *datum); if (OB_SUCC(ret)) { ObBitVector *evaluated_flags = to_bit_vector(frame + eval_flags_off_); diff --git a/src/sql/engine/expr/ob_expr.h b/src/sql/engine/expr/ob_expr.h index cf0458d352..23b4815e76 100644 --- a/src/sql/engine/expr/ob_expr.h +++ b/src/sql/engine/expr/ob_expr.h @@ -571,6 +571,7 @@ private: char *alloc_str_res_mem(ObEvalCtx &ctx, const int64_t size, const int64_t idx) const; // reset datums pointer to reserved buffer. void reset_datums_ptr(char *frame, const int64_t size) const; + void reset_datum_ptr(char *frame, const int64_t size, const int64_t idx) const; int eval_one_datum_of_batch(ObEvalCtx &ctx, common::ObDatum *&datum) const; int do_eval_batch(ObEvalCtx &ctx, const ObBitVector &skip, const int64_t size) const;