提交 0cd740c2 编写于 作者: O obdev 提交者: wangzelin.wzl

[CP] fix T_OP_STACK_OVERFLOW_CHECK reset child ptr leads core

上级 543ec6c9
...@@ -1260,28 +1260,6 @@ int ObStaticEngineExprCG::alloc_so_check_exprs(const ObIArray<ObRawExpr *> &raw_ ...@@ -1260,28 +1260,6 @@ int ObStaticEngineExprCG::alloc_so_check_exprs(const ObIArray<ObRawExpr *> &raw_
if (OB_SUCC(ret) && stack_check_expr_cnt > 0) { if (OB_SUCC(ret) && stack_check_expr_cnt > 0) {
LOG_TRACE("stack check expr needed", LOG_TRACE("stack check expr needed",
K(exprs.count()), K(stack_check_expr_cnt), K(max_call_depth)); K(exprs.count()), K(stack_check_expr_cnt), K(max_call_depth));
ObExpr *ori_base = exprs.get_data();
OZ(exprs.reserve(exprs.count() + stack_check_expr_cnt));
ObExpr *base = exprs.get_data();
// relocate expr ptr
if (OB_SUCC(ret) && ori_base != base) {
const int64_t offset = reinterpret_cast<char *>(base) - reinterpret_cast<char *>(ori_base);
FOREACH_CNT(e, raw_exprs) {
(*e)->set_rt_expr(reinterpret_cast<ObExpr *>(
reinterpret_cast<char *>(get_rt_expr(**e)) + offset));
}
FOREACH_CNT(e, exprs_call_depth) {
*reinterpret_cast<char **>(&e->expr_) += offset;
}
FOREACH_CNT(e, exprs) {
for (int64_t i = 0; i < e->parent_cnt_; i++) {
*reinterpret_cast<char **>(&e->parents_[i]) += offset;
}
for (int64_t i = 0; i < e->arg_cnt_; i++) {
*reinterpret_cast<char **>(&e->args_[i]) += offset;
}
}
}
FOREACH_CNT_X(ecd, exprs_call_depth, OB_SUCC(ret)) { FOREACH_CNT_X(ecd, exprs_call_depth, OB_SUCC(ret)) {
if (ecd->need_stack_check_) { if (ecd->need_stack_check_) {
...@@ -1295,7 +1273,7 @@ int ObStaticEngineExprCG::alloc_so_check_exprs(const ObIArray<ObRawExpr *> &raw_ ...@@ -1295,7 +1273,7 @@ int ObStaticEngineExprCG::alloc_so_check_exprs(const ObIArray<ObRawExpr *> &raw_
} }
} }
if (OB_SUCC(ret) && e->parent_cnt_ > 0) { if (OB_SUCC(ret) && e->parent_cnt_ > 0) {
OZ(add_so_check_expr_above(exprs, e)); e->need_stack_check_ = true;
} }
} }
} // END FOREACH_CNT_X } // END FOREACH_CNT_X
...@@ -1304,52 +1282,6 @@ int ObStaticEngineExprCG::alloc_so_check_exprs(const ObIArray<ObRawExpr *> &raw_ ...@@ -1304,52 +1282,6 @@ int ObStaticEngineExprCG::alloc_so_check_exprs(const ObIArray<ObRawExpr *> &raw_
return ret; return ret;
} }
int ObStaticEngineExprCG::add_so_check_expr_above(ObIArray<ObExpr> &exprs, ObExpr *e)
{
int ret = OB_SUCCESS;
ObExpr *base = exprs.get_data();
CK(NULL != e);
CK(e->parent_cnt_ > 0 && e->arg_cnt_ > 0);
OZ(exprs.push_back(*e));
CK(base == exprs.get_data());
if (OB_SUCC(ret)) {
// stack overflow check expr point to the same ObDatum of child.
ObExpr *so = &exprs.at(exprs.count() - 1);
so->type_ = T_OP_STACK_OVERFLOW_CHECK;
so->extra_ = 0;
so->inner_functions_ = 0;
so->inner_func_cnt_ = 0;
ObExpr **parents = static_cast<ObExpr **>(allocator_.alloc(sizeof(ObExpr *) * 2));
if (NULL == parents) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("allocate memory failed", K(ret));
} else {
ObExpr **args = parents + 1;
parents[0] = so;
args[0] = e;
e->parents_ = parents;
e->parent_cnt_ = 1;
so->args_ = args;
so->arg_cnt_ = 1;
for (int64_t i = 0; i < so->parent_cnt_; i++) {
ObExpr *p = so->parents_[i];
for (int64_t j = 0; j < p->arg_cnt_; j++) {
if (p->args_[j] == e) {
p->args_[j] = so;
}
}
}
so->eval_func_ = ObExprUtil::eval_stack_overflow_check;
so->eval_batch_func_ = ObExprUtil::eval_batch_stack_overflow_check;
}
}
return ret;
}
int ObStaticEngineExprCG::calc_exprs_res_buf_len(const ObIArray<ObRawExpr *> &raw_exprs) int ObStaticEngineExprCG::calc_exprs_res_buf_len(const ObIArray<ObRawExpr *> &raw_exprs)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
......
...@@ -196,9 +196,6 @@ private: ...@@ -196,9 +196,6 @@ private:
// alloc stack overflow check exprs. // alloc stack overflow check exprs.
int alloc_so_check_exprs(const common::ObIArray<ObRawExpr *> &raw_exprs, int alloc_so_check_exprs(const common::ObIArray<ObRawExpr *> &raw_exprs,
ObExprFrameInfo &expr_info); ObExprFrameInfo &expr_info);
// add stack overflow check expr above %e
int add_so_check_expr_above(common::ObIArray<ObExpr> &exprs,
ObExpr *e);
// calculate res_buf_len_ for exprs' datums // calculate res_buf_len_ for exprs' datums
int calc_exprs_res_buf_len(const common::ObIArray<ObRawExpr *> &raw_exprs); int calc_exprs_res_buf_len(const common::ObIArray<ObRawExpr *> &raw_exprs);
......
...@@ -609,16 +609,20 @@ int ObExpr::eval_one_datum_of_batch(ObEvalCtx &ctx, common::ObDatum *&datum) con ...@@ -609,16 +609,20 @@ int ObExpr::eval_one_datum_of_batch(ObEvalCtx &ctx, common::ObDatum *&datum) con
} }
datum = reinterpret_cast<ObDatum *>(frame + datum_off_) + ctx.get_batch_idx(); datum = reinterpret_cast<ObDatum *>(frame + datum_off_) + ctx.get_batch_idx();
if (need_evaluate) { if (need_evaluate) {
reset_datum_ptr(frame, ctx.get_batch_size(), ctx.get_batch_idx()); if (OB_UNLIKELY(need_stack_check_) && OB_FAIL(check_stack_overflow())) {
ret = eval_func_(*this, ctx, *datum); SQL_LOG(WARN, "failed to check stack overflow", K(ret));
if (OB_SUCC(ret)) {
ObBitVector *evaluated_flags = to_bit_vector(frame + eval_flags_off_);
evaluated_flags->set(ctx.get_batch_idx());
} else { } else {
datum->set_null(); reset_datum_ptr(frame, ctx.get_batch_size(), ctx.get_batch_idx());
} ret = eval_func_(*this, ctx, *datum);
if (datum->is_null()) { if (OB_SUCC(ret)) {
info->notnull_ = false; ObBitVector *evaluated_flags = to_bit_vector(frame + eval_flags_off_);
evaluated_flags->set(ctx.get_batch_idx());
} else {
datum->set_null();
}
if (datum->is_null()) {
info->notnull_ = false;
}
} }
} }
...@@ -655,17 +659,21 @@ int ObExpr::do_eval_batch(ObEvalCtx &ctx, ...@@ -655,17 +659,21 @@ int ObExpr::do_eval_batch(ObEvalCtx &ctx,
info->notnull_ = false; info->notnull_ = false;
info->point_to_frame_ = true; info->point_to_frame_ = true;
} }
ret = (*eval_batch_func_)(*this, ctx, skip, size); if (OB_UNLIKELY(need_stack_check_) && OB_FAIL(check_stack_overflow())) {
if (OB_SUCC(ret)) { SQL_LOG(WARN, "failed to check stack overflow", K(ret));
if (!info->evaluated_) {
info->cnt_ = size;
info->evaluated_ = true;
}
} else { } else {
ObDatum *datum = reinterpret_cast<ObDatum *>(frame + datum_off_); ret = (*eval_batch_func_)(*this, ctx, skip, size);
ObDatum *datum_end = datum + size; if (OB_SUCC(ret)) {
for (; datum < datum_end; datum += 1) { if (!info->evaluated_) {
datum->set_null(); info->cnt_ = size;
info->evaluated_ = true;
}
} else {
ObDatum *datum = reinterpret_cast<ObDatum *>(frame + datum_off_);
ObDatum *datum_end = datum + size;
for (; datum < datum_end; datum += 1) {
datum->set_null();
}
} }
} }
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "sql/engine/ob_serializable_function.h" #include "sql/engine/ob_serializable_function.h"
#include "objit/common/ob_item_type.h" #include "objit/common/ob_item_type.h"
#include "sql/engine/ob_bit_vector.h" #include "sql/engine/ob_bit_vector.h"
#include "common/ob_common_utility.h"
namespace oceanbase namespace oceanbase
{ {
...@@ -610,6 +611,7 @@ public: ...@@ -610,6 +611,7 @@ public:
uint64_t is_static_const_:1; // is const during the whole execution uint64_t is_static_const_:1; // is const during the whole execution
uint64_t is_boolean_:1; // to distinguish result of this expr between and int tc uint64_t is_boolean_:1; // to distinguish result of this expr between and int tc
uint64_t is_dynamic_const_:1; // is const during the subplan execution, including exec param uint64_t is_dynamic_const_:1; // is const during the subplan execution, including exec param
uint64_t need_stack_check_:1; // the expression tree depth needs to check whether the stack overflows
}; };
uint64_t flag_; uint64_t flag_;
}; };
...@@ -976,7 +978,6 @@ OB_INLINE int ObExpr::eval(ObEvalCtx &ctx, common::ObDatum *&datum) const ...@@ -976,7 +978,6 @@ OB_INLINE int ObExpr::eval(ObEvalCtx &ctx, common::ObDatum *&datum) const
OB_ASSERT(NULL != frame); OB_ASSERT(NULL != frame);
datum = (ObDatum *)(frame + datum_off_); datum = (ObDatum *)(frame + datum_off_);
ObEvalInfo *eval_info = (ObEvalInfo *)(frame + eval_info_off_); ObEvalInfo *eval_info = (ObEvalInfo *)(frame + eval_info_off_);
if (is_batch_result()) { if (is_batch_result()) {
if (NULL == eval_func_ || eval_info->projected_) { if (NULL == eval_func_ || eval_info->projected_) {
datum = datum + ctx.get_batch_idx(); datum = datum + ctx.get_batch_idx();
...@@ -985,14 +986,18 @@ OB_INLINE int ObExpr::eval(ObEvalCtx &ctx, common::ObDatum *&datum) const ...@@ -985,14 +986,18 @@ OB_INLINE int ObExpr::eval(ObEvalCtx &ctx, common::ObDatum *&datum) const
} }
} else if (NULL != eval_func_ && !eval_info->evaluated_) { } else if (NULL != eval_func_ && !eval_info->evaluated_) {
// do nothing for const/column reference expr or already evaluated expr // do nothing for const/column reference expr or already evaluated expr
if (datum->ptr_ != frame + res_buf_off_) { if (OB_UNLIKELY(need_stack_check_) && OB_FAIL(check_stack_overflow())) {
datum->ptr_ = frame + res_buf_off_; SQL_LOG(WARN, "failed to check stack overflow", K(ret));
}
ret = eval_func_(*this, ctx, *datum);
if (OB_LIKELY(common::OB_SUCCESS == ret)) {
eval_info->evaluated_ = true;
} else { } else {
datum->set_null(); if (datum->ptr_ != frame + res_buf_off_) {
datum->ptr_ = frame + res_buf_off_;
}
ret = eval_func_(*this, ctx, *datum);
if (OB_LIKELY(common::OB_SUCCESS == ret)) {
eval_info->evaluated_ = true;
} else {
datum->set_null();
}
} }
} }
return ret; return ret;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册