patch 4.0
This commit is contained in:
@ -16,83 +16,24 @@
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/engine/expr/ob_i_expr_extra_info.h"
|
||||
#include "sql/engine/expr/ob_expr_extra_info_factory.h"
|
||||
#include "sql/engine/expr/ob_expr_operator.h"
|
||||
#include "sql/engine/px/ob_px_util.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace oceanbase
|
||||
{
|
||||
using namespace common;
|
||||
namespace sql {
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObFrameInfo, expr_cnt_, frame_idx_, frame_size_);
|
||||
|
||||
int ObExprFrameInfo::pre_alloc_exec_memory(ObExecContext& exec_ctx) const
|
||||
namespace sql
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
uint64_t frame_cnt = 0;
|
||||
char** frames = NULL;
|
||||
char** expr_ctx_arr = NULL;
|
||||
ObPhysicalPlanCtx* phy_ctx = NULL;
|
||||
if (NULL == (phy_ctx = exec_ctx.get_physical_plan_ctx())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(phy_ctx), K(ret));
|
||||
} else if (OB_FAIL(alloc_frame(exec_ctx.get_allocator(), *phy_ctx, frame_cnt, frames))) {
|
||||
LOG_WARN("fail to alloc frame", K(ret));
|
||||
} else {
|
||||
exec_ctx.set_frame_cnt(frame_cnt);
|
||||
exec_ctx.set_frames(frames);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
OB_SERIALIZE_MEMBER(ObFrameInfo,
|
||||
expr_cnt_,
|
||||
frame_idx_,
|
||||
frame_size_,
|
||||
zero_init_pos_,
|
||||
zero_init_size_);
|
||||
|
||||
#define ALLOC_FRAME_MEM(frame_info_arr) \
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < frame_info_arr.count(); i++) { \
|
||||
char* frame_mem = static_cast<char*>(exec_allocator.alloc(frame_info_arr.at(i).frame_size_)); \
|
||||
if (OB_ISNULL(frame_mem)) { \
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED; \
|
||||
LOG_WARN("alloc memory failed", K(ret), K(frame_info_arr.at(i).frame_size_)); \
|
||||
} else { \
|
||||
memset(frame_mem, 0, frame_info_arr.at(i).frame_size_); \
|
||||
frames[frame_idx++] = frame_mem; \
|
||||
} \
|
||||
}
|
||||
|
||||
int ObExprFrameInfo::alloc_frame(
|
||||
common::ObIAllocator& exec_allocator, ObPhysicalPlanCtx& phy_ctx, uint64_t& frame_cnt, char**& frames) const
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
frame_cnt = const_frame_ptrs_.count() + param_frame_.count() + dynamic_frame_.count() + datum_frame_.count();
|
||||
if (frame_cnt == 0) {
|
||||
// do nothing
|
||||
} else if (NULL == (frames = static_cast<char**>(exec_allocator.alloc(frame_cnt * sizeof(char*))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("alloc memory failed", K(ret), K(frame_cnt));
|
||||
} else {
|
||||
int64_t frame_idx = 0; // frame idx
|
||||
OB_ASSERT(const_frame_ptrs_.count() == const_frame_.count());
|
||||
OB_ASSERT(phy_ctx.get_param_frame_ptrs().count() == param_frame_.count());
|
||||
for (int64_t i = 0; i < const_frame_ptrs_.count(); i++) {
|
||||
frames[frame_idx++] = const_frame_ptrs_.at(i);
|
||||
}
|
||||
for (int64_t i = 0; i < phy_ctx.get_param_frame_ptrs().count(); i++) {
|
||||
frames[frame_idx++] = phy_ctx.get_param_frame_ptrs().at(i);
|
||||
}
|
||||
int64_t begin_idx = frame_idx;
|
||||
const int64_t datum_eval_info_size = sizeof(ObDatum) + sizeof(ObEvalInfo);
|
||||
ALLOC_FRAME_MEM(dynamic_frame_);
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < dynamic_frame_.count(); ++i) {
|
||||
char* cur_frame = frames[begin_idx + i];
|
||||
for (int64_t j = 0; j < dynamic_frame_.at(i).expr_cnt_; ++j) {
|
||||
ObDatum* datum = reinterpret_cast<ObDatum*>(cur_frame + j * datum_eval_info_size);
|
||||
datum->set_null();
|
||||
}
|
||||
}
|
||||
ALLOC_FRAME_MEM(datum_frame_);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#undef ALLOC_FRAME_MEM
|
||||
|
||||
int ObPreCalcExprFrameInfo::assign(const ObPreCalcExprFrameInfo& other, common::ObIAllocator& allocator)
|
||||
int ObExprFrameInfo::assign(const ObExprFrameInfo &other,
|
||||
common::ObIAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
need_ctx_cnt_ = other.need_ctx_cnt_;
|
||||
@ -110,9 +51,9 @@ int ObPreCalcExprFrameInfo::assign(const ObPreCalcExprFrameInfo& other, common::
|
||||
} else if (const_frame_ptrs_.prepare_allocate(other.const_frame_ptrs_.count())) {
|
||||
LOG_WARN("failed to prepare allocate array", K(ret));
|
||||
} else {
|
||||
char* frame_mem = NULL;
|
||||
char *frame_mem = NULL;
|
||||
for (int i = 0; OB_SUCC(ret) && i < other.const_frame_.count(); i++) {
|
||||
if (OB_ISNULL(frame_mem = (char*)allocator.alloc(other.const_frame_.at(i).frame_size_))) {
|
||||
if (OB_ISNULL(frame_mem = (char *)allocator.alloc(other.const_frame_.at(i).frame_size_))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else {
|
||||
@ -121,124 +62,46 @@ int ObPreCalcExprFrameInfo::assign(const ObPreCalcExprFrameInfo& other, common::
|
||||
}
|
||||
// set datum ptr
|
||||
for (int j = 0; OB_SUCC(ret) && j < other.const_frame_.at(i).expr_cnt_; j++) {
|
||||
char* other_frame_mem = other.const_frame_ptrs_.at(i);
|
||||
int64_t other_frame_size = other.const_frame_.at(i).frame_size_;
|
||||
const int64_t datum_eval_info_size = sizeof(ObDatum) + sizeof(ObEvalInfo);
|
||||
ObDatum* other_expr_datum = reinterpret_cast<ObDatum*>(other_frame_mem + j * datum_eval_info_size);
|
||||
ObDatum* expr_datum = reinterpret_cast<ObDatum*>(frame_mem + j * datum_eval_info_size);
|
||||
if (NULL == other_expr_datum->ptr_) {
|
||||
// do nothing
|
||||
} else if ((other_expr_datum->ptr_ < other_frame_mem ||
|
||||
other_expr_datum->ptr_ >= other_frame_mem + other_frame_size)) {
|
||||
// if datum's ptr_ does not locate in frame_mem, it must be deep copied separately
|
||||
void* extra_buf = NULL;
|
||||
if (0 == other_expr_datum->len_) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("length is null and ptr not null", K(ret), K(*other_expr_datum));
|
||||
} else if (OB_ISNULL(extra_buf = allocator.alloc(other_expr_datum->len_))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else {
|
||||
MEMCPY(extra_buf, other_expr_datum->ptr_, other_expr_datum->len_);
|
||||
expr_datum->ptr_ = static_cast<char*>(extra_buf);
|
||||
}
|
||||
} else {
|
||||
expr_datum->ptr_ = frame_mem + (other_expr_datum->ptr_ - other.const_frame_ptrs_.at(i));
|
||||
}
|
||||
} // end for
|
||||
} // for end
|
||||
// init pre calc expr ptrs
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(pre_calc_rt_exprs_.prepare_allocate(other.pre_calc_rt_exprs_.count()))) {
|
||||
LOG_WARN("failed to prepare allocate rt exprs", K(ret));
|
||||
} else {
|
||||
// allocate args memory for all rt exprs
|
||||
for (int i = 0; OB_SUCC(ret) && i < rt_exprs_.count(); i++) {
|
||||
if (rt_exprs_.at(i).arg_cnt_ > 0) {
|
||||
ObExpr** arg_buf = NULL;
|
||||
int64_t buf_size = rt_exprs_.at(i).arg_cnt_ * sizeof(ObExpr*);
|
||||
if (OB_ISNULL(arg_buf = (ObExpr**)allocator.alloc(buf_size))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else {
|
||||
MEMSET(arg_buf, 0, buf_size);
|
||||
rt_exprs_.at(i).args_ = arg_buf;
|
||||
}
|
||||
}
|
||||
|
||||
// allocate parents memory for all rt exprs
|
||||
if (rt_exprs_.at(i).parent_cnt_ > 0) {
|
||||
ObExpr** parent_buf = NULL;
|
||||
int64_t buf_size = rt_exprs_.at(i).parent_cnt_ * sizeof(ObExpr*);
|
||||
if (OB_ISNULL(parent_buf = (ObExpr**)allocator.alloc(buf_size))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else {
|
||||
MEMSET(parent_buf, 0, buf_size);
|
||||
rt_exprs_.at(i).parents_ = parent_buf;
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
hash::ObHashMap<int64_t, int64_t> expr_to_pos;
|
||||
bool rt_exprs_empty = (0 == other.rt_exprs_.count());
|
||||
if (OB_SUCC(ret) && !rt_exprs_empty &&
|
||||
OB_FAIL(expr_to_pos.create(other.rt_exprs_.count(), ObModIds::OB_SQL_EXPR_CALC))) {
|
||||
LOG_WARN("failed to init hashmap", K(ret));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !rt_exprs_empty && i < other.rt_exprs_.count(); i++) {
|
||||
if (OB_FAIL(expr_to_pos.set_refactored(reinterpret_cast<int64_t>(&other.rt_exprs_.at(i)), i))) {
|
||||
LOG_WARN("failed to insert into map", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; OB_SUCC(ret) && !rt_exprs_empty && i < other.pre_calc_rt_exprs_.count(); i++) {
|
||||
int64_t pos = -1;
|
||||
if (OB_FAIL(expr_to_pos.get_refactored(reinterpret_cast<int64_t>(other.pre_calc_rt_exprs_.at(i)), pos))) {
|
||||
if (OB_HASH_NOT_EXIST == ret) {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
pre_calc_rt_exprs_.at(i) = &rt_exprs_.at(pos);
|
||||
}
|
||||
} // for end
|
||||
|
||||
// replace arg ptrs and parent ptrs for all rt exprs
|
||||
for (int i = 0; OB_SUCC(ret) && i < other.rt_exprs_.count(); i++) {
|
||||
if (other.rt_exprs_.at(i).arg_cnt_ > 0) {
|
||||
for (int j = 0; j < other.rt_exprs_.at(i).arg_cnt_; j++) {
|
||||
int64_t pos = -1;
|
||||
if (OB_FAIL(expr_to_pos.get_refactored(reinterpret_cast<int64_t>(other.rt_exprs_.at(i).args_[j]), pos))) {
|
||||
if (OB_HASH_NOT_EXIST == ret) {
|
||||
ret = OB_SUCCESS;
|
||||
char *other_frame_mem = other.const_frame_ptrs_.at(i);
|
||||
int64_t other_frame_size = other.const_frame_.at(i).frame_size_;
|
||||
const int64_t datum_eval_info_size = sizeof(ObDatum) + sizeof(ObEvalInfo);
|
||||
ObDatum *other_expr_datum = reinterpret_cast<ObDatum *>
|
||||
(other_frame_mem + j * datum_eval_info_size);
|
||||
ObDatum *expr_datum = reinterpret_cast<ObDatum *>
|
||||
(frame_mem + j * datum_eval_info_size);
|
||||
// 在mysql模式下, 空串len为0, 且ptr = NULL, 当ptr为NULL时, copy时不需要再改变ptr值
|
||||
if (NULL == other_expr_datum->ptr_) {
|
||||
// do nothing
|
||||
} else if ((other_expr_datum->ptr_ < other_frame_mem
|
||||
|| other_expr_datum->ptr_ >= other_frame_mem + other_frame_size)) {
|
||||
// if datum's ptr_ does not locate in frame_mem, it must be deep copied separately
|
||||
void *extra_buf = NULL;
|
||||
if (0 == other_expr_datum->len_) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("length is null and ptr not null", K(ret), K(*other_expr_datum));
|
||||
} else if (OB_ISNULL(extra_buf = allocator.alloc(other_expr_datum->len_))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else {
|
||||
MEMCPY(extra_buf, other_expr_datum->ptr_, other_expr_datum->len_);
|
||||
expr_datum->ptr_ = static_cast<char *>(extra_buf);
|
||||
}
|
||||
} else {
|
||||
rt_exprs_.at(i).args_[j] = &rt_exprs_.at(pos);
|
||||
expr_datum->ptr_
|
||||
= frame_mem + (other_expr_datum->ptr_ - other.const_frame_ptrs_.at(i));
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
} // end for
|
||||
} // for end
|
||||
|
||||
if (other.rt_exprs_.at(i).parent_cnt_ > 0) {
|
||||
for (int j = 0; j < other.rt_exprs_.at(i).parent_cnt_; j++) {
|
||||
int64_t pos = -1;
|
||||
if (OB_FAIL(expr_to_pos.get_refactored(reinterpret_cast<int64_t>(other.rt_exprs_.at(i).parents_[j]), pos))) {
|
||||
if (OB_HASH_NOT_EXIST == ret) {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
rt_exprs_.at(i).parents_[j] = &rt_exprs_.at(pos);
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
} // end for
|
||||
if (OB_SUCC(ret)) {
|
||||
// deep copy extra info & inner function ptrs
|
||||
for (int i = 0; OB_SUCC(ret) && i < other.rt_exprs_.count(); i++) {
|
||||
if (ObExprExtraInfoFactory::is_registered(other.rt_exprs_.at(i).type_)) {
|
||||
if (OB_ISNULL(other.rt_exprs_.at(i).extra_info_)) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(other.rt_exprs_.at(i).extra_info_->deep_copy(
|
||||
allocator, other.rt_exprs_.at(i).type_, rt_exprs_.at(i).extra_info_))) {
|
||||
} else if (OB_FAIL(other.rt_exprs_.at(i).extra_info_->deep_copy(allocator,
|
||||
other.rt_exprs_.at(i).type_,
|
||||
rt_exprs_.at(i).extra_info_))) {
|
||||
LOG_WARN("failed to deep copy extra info", K(ret));
|
||||
}
|
||||
}
|
||||
@ -246,20 +109,568 @@ int ObPreCalcExprFrameInfo::assign(const ObPreCalcExprFrameInfo& other, common::
|
||||
// copy inner function ptrs
|
||||
if (other.rt_exprs_.at(i).inner_func_cnt_ > 0) {
|
||||
int64_t func_cnt = other.rt_exprs_.at(i).inner_func_cnt_;
|
||||
void* funcs_buf = NULL;
|
||||
if (OB_ISNULL(funcs_buf = allocator.alloc(sizeof(void*) * func_cnt))) {
|
||||
void *funcs_buf = NULL;
|
||||
if (OB_ISNULL(funcs_buf = allocator.alloc(sizeof(void *) * func_cnt))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else {
|
||||
MEMCPY(funcs_buf, other.rt_exprs_.at(i).inner_functions_, func_cnt * sizeof(void*));
|
||||
rt_exprs_.at(i).inner_functions_ = (void**)funcs_buf;
|
||||
MEMCPY(funcs_buf, other.rt_exprs_.at(i).inner_functions_, func_cnt * sizeof(void *));
|
||||
rt_exprs_.at(i).inner_functions_ = (void **)funcs_buf;
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
} // end for
|
||||
}
|
||||
}
|
||||
// allocate args memory for all rt exprs
|
||||
if (OB_SUCC(ret)) {
|
||||
for (int i = 0; OB_SUCC(ret) && i < rt_exprs_.count(); i++) {
|
||||
if (rt_exprs_.at(i).arg_cnt_ > 0) {
|
||||
ObExpr **arg_buf = NULL;
|
||||
int64_t buf_size = rt_exprs_.at(i).arg_cnt_ * sizeof(ObExpr *);
|
||||
if (OB_ISNULL(arg_buf = (ObExpr **)allocator.alloc(buf_size))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else {
|
||||
MEMSET(arg_buf, 0, buf_size);
|
||||
rt_exprs_.at(i).args_ = arg_buf;
|
||||
}
|
||||
}
|
||||
|
||||
// allocate parents memory for all rt exprs
|
||||
if (rt_exprs_.at(i).parent_cnt_ > 0) {
|
||||
ObExpr **parent_buf = NULL;
|
||||
int64_t buf_size = rt_exprs_.at(i).parent_cnt_ * sizeof(ObExpr *);
|
||||
if (OB_ISNULL(parent_buf = (ObExpr **)allocator.alloc(buf_size))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else {
|
||||
MEMSET(parent_buf, 0, buf_size);
|
||||
rt_exprs_.at(i).parents_ = parent_buf;
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
// replace arg ptrs and parent ptrs for all rt exprs
|
||||
for (int i = 0; OB_SUCC(ret) && i < other.rt_exprs_.count(); i++) {
|
||||
if (other.rt_exprs_.at(i).arg_cnt_ > 0) {
|
||||
for (int j = 0; OB_SUCC(ret) && j < other.rt_exprs_.at(i).arg_cnt_; j++) {
|
||||
int64_t pos = other.rt_exprs_.at(i).args_[j] - &(other.rt_exprs_.at(0));
|
||||
if (pos >= rt_exprs_.count() || pos < 0) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("rt expr pos is invalid", K(pos), KP(&other.rt_exprs_.at(0)),
|
||||
KP(other.rt_exprs_.at(i).args_[j]));
|
||||
} else {
|
||||
rt_exprs_.at(i).args_[j] = &rt_exprs_.at(pos);
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
if (other.rt_exprs_.at(i).parent_cnt_ > 0) {
|
||||
for (int j = 0; OB_SUCC(ret) && j < other.rt_exprs_.at(i).parent_cnt_; j++) {
|
||||
int64_t pos = other.rt_exprs_.at(i).parents_[j] - &(other.rt_exprs_.at(0));
|
||||
if (pos >= rt_exprs_.count() || pos < 0) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("rt expr pos is invalid", K(pos), KP(&other.rt_exprs_.at(0)),
|
||||
KP(other.rt_exprs_.at(i).args_[j]));
|
||||
} else {
|
||||
rt_exprs_.at(i).parents_[j] = &rt_exprs_.at(pos);
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
} // end for
|
||||
if (OB_SUCC(ret)) {
|
||||
// deep copy extra info & inner function ptrs
|
||||
for (int i = 0; OB_SUCC(ret) && i < other.rt_exprs_.count(); i++) {
|
||||
if (ObExprExtraInfoFactory::is_registered(other.rt_exprs_.at(i).type_)) {
|
||||
if (OB_ISNULL(other.rt_exprs_.at(i).extra_info_)) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(other.rt_exprs_.at(i).extra_info_->deep_copy(allocator,
|
||||
other.rt_exprs_.at(i).type_,
|
||||
rt_exprs_.at(i).extra_info_))) {
|
||||
LOG_WARN("failed to deep copy extra info", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
// copy inner function ptrs
|
||||
if (OB_SUCC(ret) && other.rt_exprs_.at(i).inner_func_cnt_ > 0) {
|
||||
int64_t func_cnt = other.rt_exprs_.at(i).inner_func_cnt_;
|
||||
void *funcs_buf = NULL;
|
||||
if (OB_ISNULL(funcs_buf = allocator.alloc(sizeof(void *) * func_cnt))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else {
|
||||
MEMCPY(funcs_buf, other.rt_exprs_.at(i).inner_functions_, func_cnt * sizeof(void *));
|
||||
rt_exprs_.at(i).inner_functions_ = (void **)funcs_buf;
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprFrameInfo::pre_alloc_exec_memory(ObExecContext &exec_ctx) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
uint64_t frame_cnt = 0;
|
||||
char **frames = NULL;
|
||||
ObPhysicalPlanCtx *phy_ctx = NULL;
|
||||
if (NULL == (phy_ctx = exec_ctx.get_physical_plan_ctx())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(phy_ctx), K(ret));
|
||||
} else if (OB_FAIL(alloc_frame(exec_ctx.get_allocator(),
|
||||
phy_ctx->get_param_frame_ptrs(),
|
||||
frame_cnt,
|
||||
frames))) {
|
||||
LOG_WARN("fail to alloc frame", K(ret));
|
||||
} else {
|
||||
exec_ctx.set_frame_cnt(frame_cnt);
|
||||
exec_ctx.set_frames(frames);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define ALLOC_FRAME_MEM(frame_info_arr) \
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < frame_info_arr.count(); i++) { \
|
||||
const ObFrameInfo &frame_info = frame_info_arr.at(i); \
|
||||
char *frame_mem = static_cast<char *>(exec_allocator.alloc(frame_info.frame_size_)); \
|
||||
if (OB_ISNULL(frame_mem)) { \
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED; \
|
||||
LOG_WARN("alloc memory failed", K(ret), K(frame_info.frame_size_)); \
|
||||
} else if (frame_info.zero_init_size_ > 0) { \
|
||||
MEMSET(frame_mem + frame_info.zero_init_pos_, 0, frame_info.zero_init_size_);\
|
||||
} \
|
||||
frames[frame_idx++] = frame_mem; \
|
||||
} \
|
||||
|
||||
// 分配frame内存, 并将所有frame指针按每个frame idx的序存放到frames数组中
|
||||
// 1. const frame内存来自plan中共享的内存, 直接将plan中存放的指针拿来使用
|
||||
// 2. param frame内存来自编译期参数化后生成, 这里可直接获取
|
||||
// 3. dynamic frame和datum frame内存在这里进行预分配
|
||||
int ObExprFrameInfo::alloc_frame(ObIAllocator &exec_allocator,
|
||||
const ObIArray<char *> ¶m_frame_ptrs,
|
||||
uint64_t &frame_cnt,
|
||||
char **&frames) const
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
frame_cnt = const_frame_ptrs_.count()
|
||||
+ param_frame_.count()
|
||||
+ dynamic_frame_.count()
|
||||
+ datum_frame_.count();
|
||||
if (frame_cnt == 0) {
|
||||
// do nothing
|
||||
} else if (NULL == (frames = static_cast<char **>(exec_allocator.alloc(
|
||||
frame_cnt * sizeof(char *))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("alloc memory failed", K(ret), K(frame_cnt));
|
||||
} else {
|
||||
int64_t frame_idx = 0; //frame idx
|
||||
OB_ASSERT(const_frame_ptrs_.count() == const_frame_.count());
|
||||
// Param frame size maybe small than param frame ptrs, because the pre-calculated
|
||||
// exprs may be evaluate again in plan cache constraints check after param store extended.
|
||||
// After param_frame_ptrs from physical_plan_ctx is reset in ObPlanCacheValue::choose_plan,
|
||||
// can check OB_ASSERT(param_frame_.empty() || param_frame_ptrs.count() == param_frame_.count());
|
||||
OB_ASSERT(param_frame_.empty()
|
||||
|| param_frame_ptrs.count() >= param_frame_.count());
|
||||
for (int64_t i = 0 ; i < const_frame_ptrs_.count(); i++) {
|
||||
frames[frame_idx++] = const_frame_ptrs_.at(i);
|
||||
}
|
||||
if (!param_frame_.empty()) {
|
||||
for (int64_t i = 0 ; i < param_frame_.count(); i++) {
|
||||
frames[frame_idx++] = param_frame_ptrs.at(i);
|
||||
}
|
||||
}
|
||||
int64_t begin_idx = frame_idx;
|
||||
const int64_t datum_eval_info_size = sizeof(ObDatum) + sizeof(ObEvalInfo);
|
||||
ALLOC_FRAME_MEM(dynamic_frame_);
|
||||
//for subquery core https://work.aone.alibaba-inc.com/issue/31403714
|
||||
//提前将frame中的datum置为null
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < dynamic_frame_.count(); ++i) {
|
||||
char *cur_frame = frames[begin_idx + i];
|
||||
for (int64_t j = 0; j < dynamic_frame_.at(i).expr_cnt_; ++j) {
|
||||
ObDatum *datum = reinterpret_cast<ObDatum *>(cur_frame + j * datum_eval_info_size);
|
||||
datum->set_null();
|
||||
}
|
||||
}
|
||||
ALLOC_FRAME_MEM(datum_frame_);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#undef ALLOC_FRAME_MEM
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObEmptyExpr);
|
||||
|
||||
int ObExprFrameInfo::get_expr_idx_in_frame(ObExpr *expr, int64_t &expr_idx) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("frame info is null or expr is null", K(ret));
|
||||
} else {
|
||||
const ObIArray<ObExpr> *array = &rt_exprs_;
|
||||
int64_t idx = 0;
|
||||
if (OB_UNLIKELY(NULL == array || array->empty() || expr < &array->at(0)
|
||||
|| (idx = expr - &array->at(0) + 1) > array->count())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_LOG(WARN, "expr not in array", K(ret), KP(array), KP(idx), KP(expr));
|
||||
} else {
|
||||
expr_idx = idx;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
OB_DEF_SERIALIZE(ObExprFrameInfo)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
LOG_TRACE("serialize expr frame info", KP(buf), K(buf_len), K(pos), K(*this));
|
||||
OB_UNIS_ENCODE(need_ctx_cnt_);
|
||||
ObIArray<ObExpr> *seri_arr_bak = ObExpr::get_serialize_array();
|
||||
ObExpr::get_serialize_array() = const_cast<ObArray<ObExpr> *>(&rt_exprs_);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(serialization::encode_i32(buf, buf_len, pos, rt_exprs_.count()))) {
|
||||
LOG_WARN("fail to encode op type", K(ret));
|
||||
} else if (nullptr == ObExpr::get_serialize_array()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("serialize array is null", K(ret), K(pos), K(rt_exprs_.count()));
|
||||
} else {
|
||||
LOG_TRACE("get serialize array", K(ObExpr::get_serialize_array()), K(rt_exprs_.count()));
|
||||
for (int64_t i = 0; i < rt_exprs_.count() && OB_SUCC(ret); ++i) {
|
||||
const ObExpr &expr = rt_exprs_.at(i);
|
||||
if (OB_FAIL(expr.serialize(buf, buf_len, pos))) {
|
||||
LOG_WARN("failed to serialize expr", K(ret), K(i), K(rt_exprs_.count()));
|
||||
}
|
||||
}
|
||||
}
|
||||
OB_UNIS_ENCODE(const_frame_ptrs_.count());
|
||||
OZ(ObPxTreeSerializer::serialize_frame_info(buf, buf_len, pos, const_frame_,
|
||||
const_frame_ptrs_.get_data(),
|
||||
const_frame_ptrs_.count()));
|
||||
OB_UNIS_ENCODE(param_frame_);
|
||||
OB_UNIS_ENCODE(datum_frame_);
|
||||
OB_UNIS_ENCODE(dynamic_frame_);
|
||||
ObExpr::get_serialize_array() = seri_arr_bak;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_DESERIALIZE(ObExprFrameInfo)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int32_t expr_cnt = 0;
|
||||
OB_UNIS_DECODE(need_ctx_cnt_);
|
||||
ObIArray<ObExpr> &exprs = const_cast<ObArray<ObExpr> &>(rt_exprs_);
|
||||
ObIArray<ObExpr> *seri_arr_bak = ObExpr::get_serialize_array();
|
||||
ObExpr::get_serialize_array() = &exprs;
|
||||
if (OB_FAIL(serialization::decode_i32(buf, data_len, pos, &expr_cnt))) {
|
||||
LOG_WARN("fail to encode op type", K(ret));
|
||||
} else if (OB_FAIL(exprs.prepare_allocate(expr_cnt))) {
|
||||
LOG_WARN("failed to prepare allocator expr", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; i < expr_cnt && OB_SUCC(ret); ++i) {
|
||||
ObExpr &expr = exprs.at(i);
|
||||
if (OB_FAIL(expr.deserialize(buf, data_len, pos))) {
|
||||
LOG_WARN("failed to serialize expr", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int64_t const_frame_cnt = 0;
|
||||
char **frames = NULL;
|
||||
OB_UNIS_DECODE(const_frame_cnt);
|
||||
if (0 != const_frame_cnt) {
|
||||
CK(OB_NOT_NULL(frames = static_cast<char**>(
|
||||
allocator_.alloc(sizeof(char*) * const_frame_cnt))));
|
||||
OX(MEMSET(frames, 0, sizeof(char*) * const_frame_cnt));
|
||||
}
|
||||
OZ(ObPxTreeSerializer::deserialize_frame_info(buf, data_len, pos,
|
||||
allocator_, const_frame_, &const_frame_ptrs_, frames, const_frame_cnt));
|
||||
|
||||
OB_UNIS_DECODE(param_frame_);
|
||||
OB_UNIS_DECODE(datum_frame_);
|
||||
OB_UNIS_DECODE(dynamic_frame_);
|
||||
ObExpr::get_serialize_array() = seri_arr_bak;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE_SIZE(ObExprFrameInfo)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t len = 0;
|
||||
OB_UNIS_ADD_LEN(need_ctx_cnt_);
|
||||
ObIArray<ObExpr> &exprs = const_cast<ObArray<ObExpr> &>(rt_exprs_);
|
||||
int32_t expr_cnt = exprs.count();
|
||||
ObIArray<ObExpr> *seri_arr_bak = ObExpr::get_serialize_array();
|
||||
ObExpr::get_serialize_array() = &exprs;
|
||||
len += serialization::encoded_length_i32(expr_cnt);
|
||||
for (int64_t i = 0; i < exprs.count(); ++i) {
|
||||
ObExpr &expr = exprs.at(i);
|
||||
len += expr.get_serialize_size();
|
||||
}
|
||||
|
||||
OB_UNIS_ADD_LEN(const_frame_ptrs_.count());
|
||||
len += ObPxTreeSerializer::get_serialize_frame_info_size(
|
||||
const_frame_, const_frame_ptrs_.get_data(), const_frame_ptrs_.count());
|
||||
LOG_DEBUG("trace end get ser expr frame info size", K(ret), K(len));
|
||||
|
||||
OB_UNIS_ADD_LEN(param_frame_);
|
||||
OB_UNIS_ADD_LEN(datum_frame_);
|
||||
OB_UNIS_ADD_LEN(dynamic_frame_);
|
||||
ObExpr::get_serialize_array() = seri_arr_bak;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int ObPreCalcExprFrameInfo::assign(const ObPreCalcExprFrameInfo &other,
|
||||
common::ObIAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_FAIL(ObExprFrameInfo::assign(other, allocator))) {
|
||||
LOG_WARN("fail to assign expr frame info", K(ret), K(other));
|
||||
} else if (OB_FAIL(pre_calc_rt_exprs_.prepare_allocate(other.pre_calc_rt_exprs_.count()))) {
|
||||
LOG_WARN("failed to prepare allocate rt exprs", K(ret));
|
||||
}
|
||||
for (int i = 0; OB_SUCC(ret) && i < other.pre_calc_rt_exprs_.count(); i++) {
|
||||
int64_t pos = other.pre_calc_rt_exprs_.at(i) - &(other.rt_exprs_.at(0));
|
||||
if (pos >= rt_exprs_.count() || pos < 0) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("rt expr pos is invalid", K(pos), KP(&other.rt_exprs_.at(0)),
|
||||
KP(other.pre_calc_rt_exprs_.at(i)));
|
||||
} else {
|
||||
pre_calc_rt_exprs_.at(i) = &rt_exprs_.at(pos);
|
||||
}
|
||||
} // for end
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPreCalcExprFrameInfo::eval(ObExecContext &exec_ctx,
|
||||
ObIArray<ObDatumObjParam> &res_datum_params)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
res_datum_params.reuse();
|
||||
if (pre_calc_rt_exprs_.empty()) {
|
||||
/* do nothing */
|
||||
} else if (OB_FAIL(pre_alloc_exec_memory(exec_ctx))) {
|
||||
LOG_WARN("failed to pre alloc exec memory", K(ret));
|
||||
} else if (OB_FAIL(exec_ctx.init_expr_op(need_ctx_cnt_))) {
|
||||
LOG_WARN("failed to init expr op ctx", K(ret));
|
||||
} else if (OB_FAIL(do_normal_eval(exec_ctx, res_datum_params))) {
|
||||
LOG_WARN("do normal eval failed", K(ret));
|
||||
}
|
||||
// reset expr op anyway
|
||||
exec_ctx.reset_expr_op();
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_INLINE int ObPreCalcExprFrameInfo::do_normal_eval(ObExecContext &exec_ctx,
|
||||
ObIArray<ObDatumObjParam> &res_datum_params)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObEvalCtx eval_ctx(exec_ctx);
|
||||
ObDatum *res_datum = NULL;
|
||||
ObDatumObjParam datum_param;
|
||||
ObExpr *rt_expr = NULL;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < pre_calc_rt_exprs_.count(); ++i) {
|
||||
if (OB_ISNULL(rt_expr = pre_calc_rt_exprs_.at(i))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null rt exprs", K(ret));
|
||||
} else if (OB_FAIL(rt_expr->eval(eval_ctx, res_datum))) {
|
||||
LOG_WARN("failed to eval", K(ret));
|
||||
} else {
|
||||
datum_param.set_datum(*res_datum);
|
||||
datum_param.set_meta(rt_expr->datum_meta_);
|
||||
if (OB_FAIL(res_datum_params.push_back(datum_param))) {
|
||||
LOG_WARN("failed to push back obj param", K(ret));
|
||||
}
|
||||
} // else end
|
||||
} // for end
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_NOINLINE int ObPreCalcExprFrameInfo::do_batch_stmt_eval(ObExecContext &exec_ctx,
|
||||
ObIArray<ObDatumObjParam> &res_datum_params)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObEvalCtx eval_ctx(exec_ctx);
|
||||
ObDatum *res_datum = NULL;
|
||||
ObDatumObjParam datum_param;
|
||||
int64_t group_cnt = exec_ctx.get_sql_ctx()->multi_stmt_item_.get_batched_stmt_cnt();
|
||||
ObSqlDatumArray *datum_array = nullptr;
|
||||
//construct sql array obj
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < pre_calc_rt_exprs_.count(); ++i) {
|
||||
ObExpr *rt_expr = NULL;
|
||||
if (OB_ISNULL(rt_expr = pre_calc_rt_exprs_.at(i))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null rt exprs", K(ret));
|
||||
} else if (OB_ISNULL(datum_array = ObSqlDatumArray::alloc(exec_ctx.get_allocator(), group_cnt))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("allocate array buffer failed", K(ret), K(group_cnt));
|
||||
} else {
|
||||
datum_array->element_.set_obj_type(rt_expr->datum_meta_.type_);
|
||||
datum_array->element_.set_collation_type(rt_expr->datum_meta_.cs_type_);
|
||||
datum_array->element_.set_scale(rt_expr->datum_meta_.scale_);
|
||||
const ObObjTypeClass &dst_tc = ob_obj_type_class(rt_expr->datum_meta_.type_);
|
||||
if (ObStringTC == dst_tc || ObTextTC == dst_tc) {
|
||||
datum_array->element_.set_length_semantics(rt_expr->datum_meta_.length_semantics_);
|
||||
} else {
|
||||
datum_array->element_.set_precision(rt_expr->datum_meta_.precision_);
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
datum_param.meta_.type_ = ObExtendType;
|
||||
datum_param.meta_.scale_ = T_EXT_SQL_ARRAY;
|
||||
if (OB_FAIL(datum_param.alloc_datum_reserved_buff(datum_param.meta_,
|
||||
exec_ctx.get_allocator()))) {
|
||||
LOG_WARN("alloc datum reserved buffer failed", K(ret));
|
||||
} else if (FALSE_IT(datum_param.set_sql_array_datum(datum_array))) {
|
||||
//always false, do nothing
|
||||
} else if (OB_FAIL(res_datum_params.push_back(datum_param))) {
|
||||
LOG_WARN("failed to push back obj param", K(ret));
|
||||
}
|
||||
} // else end
|
||||
} // for end
|
||||
//replace array param to the real param and eval the pre calc expr
|
||||
for (int64_t group_id = 0; OB_SUCC(ret) && group_id < group_cnt; ++group_id) {
|
||||
if (OB_FAIL(exec_ctx.get_physical_plan_ctx()->replace_batch_param_datum(group_id))) {
|
||||
LOG_WARN("replace batch param frame failed", K(ret));
|
||||
}
|
||||
//params of each group need to clear the datum evaluted flags before calc the pre_calc_expr
|
||||
//otherwise, the result of pre_calc_expr will be the result of the last group param
|
||||
clear_datum_evaluted_flags(exec_ctx.get_frames());
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < pre_calc_rt_exprs_.count(); ++i) {
|
||||
ObExpr *rt_expr = pre_calc_rt_exprs_.at(i);
|
||||
datum_array = res_datum_params.at(i).get_sql_datum_array();
|
||||
if (OB_FAIL(rt_expr->eval(eval_ctx, res_datum))) {
|
||||
LOG_WARN("failed to eval", K(ret));
|
||||
} else if (OB_FAIL(datum_array->data_[group_id].deep_copy(*res_datum,
|
||||
exec_ctx.get_allocator()))) {
|
||||
LOG_WARN("deep copy datum failed", K(ret));
|
||||
} else {
|
||||
LOG_DEBUG("do batch stmt eval", K(datum_array->data_[group_id]), KPC(res_datum), KPC(rt_expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObPreCalcExprFrameInfo::clear_datum_evaluted_flags(char **frames)
|
||||
{
|
||||
int64_t datum_frame_idx = const_frame_ptrs_.count() + param_frame_.count() + dynamic_frame_.count();
|
||||
const int64_t datum_eval_info_size = sizeof(ObDatum) + sizeof(ObEvalInfo);
|
||||
for (int64_t i = 0; i < datum_frame_.count(); ++i) {
|
||||
char *cur_frame = frames[datum_frame_idx + i];
|
||||
for (int64_t j = 0; j < datum_frame_.at(i).expr_cnt_; ++j) {
|
||||
char *datum_ptr = cur_frame + j * datum_eval_info_size;
|
||||
ObEvalInfo *eval_info = reinterpret_cast<ObEvalInfo *>(datum_ptr + sizeof(ObDatum));
|
||||
eval_info->clear_evaluated_flag();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ObPreCalcExprFrameInfo::eval_expect_err(ObExecContext &exec_ctx,
|
||||
bool &all_eval_err)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
all_eval_err = true;
|
||||
if (pre_calc_rt_exprs_.empty()) {
|
||||
/* do nothing */
|
||||
} else if (OB_FAIL(pre_alloc_exec_memory(exec_ctx))) {
|
||||
LOG_WARN("failed to pre alloc exec memory", K(ret));
|
||||
} else if (OB_FAIL(exec_ctx.init_expr_op(need_ctx_cnt_))) {
|
||||
LOG_WARN("failed to init expr op ctx", K(ret));
|
||||
} else {
|
||||
ObEvalCtx eval_ctx(exec_ctx);
|
||||
ObDatum *res_datum = NULL;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && all_eval_err && i < pre_calc_rt_exprs_.count(); ++i) {
|
||||
if (OB_ISNULL(pre_calc_rt_exprs_.at(i))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null rt exprs", K(ret));
|
||||
} else if (OB_LIKELY(OB_SUCCESS != pre_calc_rt_exprs_.at(i)->eval(eval_ctx, res_datum))) {
|
||||
// eval error is expected
|
||||
} else {
|
||||
all_eval_err = false;
|
||||
}// else end
|
||||
} // for end
|
||||
// reset expr op anyway
|
||||
exec_ctx.reset_expr_op();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObTempExprCtx::~ObTempExprCtx()
|
||||
{
|
||||
if (expr_op_ctx_store_ != NULL) {
|
||||
ObExprOperatorCtx **it = expr_op_ctx_store_;
|
||||
ObExprOperatorCtx **it_end = &expr_op_ctx_store_[expr_op_size_];
|
||||
for (; it != it_end; ++it) {
|
||||
if (NULL != (*it)) {
|
||||
(*it)->~ObExprOperatorCtx();
|
||||
}
|
||||
}
|
||||
expr_op_ctx_store_ = NULL;
|
||||
expr_op_size_ = 0;
|
||||
frame_cnt_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int ObTempExpr::eval(ObExecContext &exec_ctx, const ObNewRow &row, ObObj &result) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObDatum *res_datum = NULL;
|
||||
char **frames = NULL;
|
||||
ObTempExprCtx *temp_expr_ctx = NULL;
|
||||
OZ(exec_ctx.get_temp_expr_eval_ctx(*this, temp_expr_ctx));
|
||||
CK(OB_NOT_NULL(temp_expr_ctx));
|
||||
OX(ObSQLUtils::clear_expr_eval_flags(rt_exprs_.at(expr_idx_), *temp_expr_ctx));
|
||||
OZ(row_to_frame(row, *temp_expr_ctx));
|
||||
if (OB_SUCC(ret)) {
|
||||
ObTempExprCtxReplaceGuard exec_ctx_backup_guard(exec_ctx, *temp_expr_ctx);
|
||||
OZ(rt_exprs_.at(expr_idx_).eval(*temp_expr_ctx, res_datum));
|
||||
OZ(res_datum->to_obj(result, rt_exprs_.at(expr_idx_).obj_meta_));
|
||||
LOG_TRACE("temp expr result", K(result), K(row), K(rt_exprs_));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObTempExpr::row_to_frame(const ObNewRow &row, ObTempExprCtx &temp_expr_ctx) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < idx_col_arr_.count(); i++) {
|
||||
const RowIdxColumnPair &idx_col = idx_col_arr_.at(i);
|
||||
ObObj &v = row.cells_[idx_col.idx_];
|
||||
ObExpr &expr = rt_exprs_.at(idx_col.expr_pos_);
|
||||
ObDatum &expr_datum = expr.locate_datum_for_write(temp_expr_ctx);
|
||||
if (v.get_type() != expr.datum_meta_.type_ && !v.is_null()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("obj type miss match", K(ret), K(v), K(idx_col), K(row));
|
||||
} else if (OB_FAIL(expr_datum.from_obj(v, expr.obj_datum_map_))) {
|
||||
LOG_WARN("fail to from obj", K(v), K(idx_col), K(row), K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObTempExpr::deep_copy(ObIAllocator &allocator, ObTempExpr *&dst) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
char *buf = static_cast<char *>(allocator.alloc(sizeof(ObTempExpr)));
|
||||
CK(OB_NOT_NULL(buf));
|
||||
OX(dst = new(buf)ObTempExpr(allocator));
|
||||
OZ(dst->assign(*this, allocator));
|
||||
OX(dst->expr_idx_ = expr_idx_);
|
||||
OZ(dst->idx_col_arr_.assign(this->idx_col_arr_));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_SERIALIZE_MEMBER(RowIdxColumnPair, idx_, expr_pos_);
|
||||
OB_SERIALIZE_MEMBER((ObTempExpr, ObExprFrameInfo), expr_idx_, idx_col_arr_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user