fix pre calc constraint bug

This commit is contained in:
chimyue
2023-11-29 11:16:33 +00:00
committed by ob-robot
parent 6ffa1c9889
commit 5bc6db2579
3 changed files with 104 additions and 9 deletions

View File

@ -183,6 +183,95 @@ int ObPlanCacheObject::check_pre_calc_cons(const bool is_ignore_stmt,
return ret;
}
// used for add plan
int ObPlanCacheObject::match_pre_calc_cons(common::ObDList<ObPreCalcExprConstraint> &cached_cons,
const ObPlanCacheCtx &pc_ctx,
const bool is_ignore_stmt,
bool &is_matched)
{
int ret = OB_SUCCESS;
is_matched = false;
const ObDList<ObPreCalcExprConstraint> *cur_cons = pc_ctx.sql_ctx_.all_pre_calc_constraints_;
if (OB_ISNULL(cur_cons)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(pc_ctx.sql_ctx_.all_pre_calc_constraints_));
} else if (cached_cons.get_size() != cur_cons->get_size()) {
is_matched = false;
} else {
is_matched = true;
bool finish = false;
ObPreCalcExprConstraint *cached_con = cached_cons.get_first();
const ObPreCalcExprConstraint *cur_con = cur_cons->get_first();
while (!finish && is_matched && OB_SUCC(ret)) {
if (cached_cons.get_header() == cached_con || cur_cons->get_header() == cur_con) {
finish = true;
is_matched = (cached_cons.get_header() == cached_con) && (cur_cons->get_header() == cur_con);
} else if (OB_ISNULL(cached_con) || OB_ISNULL(cur_con)) {
is_matched = false;
} else if (OB_FAIL(check_pre_calc_cons(is_ignore_stmt, is_matched, *cached_con, pc_ctx.exec_ctx_))) {
LOG_WARN("failed to pre calculate expression and match constraint", K(ret));
} else if (!is_matched) {
} else if (OB_FAIL(is_same_pre_calc_cons(*cached_con, *cur_con, is_matched))) {
LOG_WARN("failed to check is same pre calc cons", K(ret));
} else if (!is_matched) {
} else {
cached_con = cached_con->get_next();
cur_con = cur_con->get_next();
}
}
}
return ret;
}
// check two pre calc expr constraint is same
int ObPlanCacheObject::is_same_pre_calc_cons(const ObPreCalcExprConstraint &cons1,
const ObPreCalcExprConstraint &cons2,
bool &is_same)
{
int ret = OB_SUCCESS;
is_same = false;
const ObIArray<ObExpr*> &rt_exprs1 = cons1.pre_calc_expr_info_.pre_calc_rt_exprs_;
const ObIArray<ObExpr*> &rt_exprs2 = cons2.pre_calc_expr_info_.pre_calc_rt_exprs_;
if (cons1.expect_result_ != cons2.expect_result_
|| rt_exprs1.count() != rt_exprs2.count()) {
is_same = false;
} else {
is_same = true;
for (int64_t i = 0; is_same && OB_SUCC(ret) && i < rt_exprs1.count(); ++i) {
if (OB_FAIL(is_same_expr(rt_exprs1.at(i), rt_exprs2.at(i), is_same))) {
LOG_WARN("failed to check is is_same_expr", K(ret));
}
}
}
return ret;
}
// just recursively check ObExpr count and type now
// todo: compare more informations for ObExpr tree
int ObPlanCacheObject::is_same_expr(const ObExpr *expr1,
const ObExpr *expr2,
bool &is_same)
{
int ret = OB_SUCCESS;
is_same = false;
if (NULL == expr1 || NULL == expr2) {
is_same = (expr1 == expr2);
} else if (expr1->type_ != expr2->type_ || expr1->arg_cnt_ != expr2->arg_cnt_) {
is_same = false;
} else if (T_QUESTIONMARK == expr1->type_) {
// check param_idx is same
is_same = expr1->extra_ == expr2->extra_;
} else {
is_same = true;
for (int64_t i = 0; is_same && OB_SUCC(ret) && i < expr1->arg_cnt_; ++i) {
if (OB_FAIL(SMART_CALL(is_same_expr(expr1->args_[i], expr2->args_[i], is_same)))) {
LOG_WARN("failed to smart call check is is_same_expr", K(ret));
}
}
}
return ret;
}
int ObPlanCacheObject::pre_calculation(const bool is_ignore_stmt,
ObPreCalcExprFrameInfo &pre_calc_frame,
ObExecContext &exec_ctx,

View File

@ -187,6 +187,16 @@ public:
inline stmt::StmtType get_stmt_type() const { return stmt_type_; }
inline void set_need_param(bool need_param) { need_param_ = need_param; }
inline bool need_param() const { return need_param_; }
static int match_pre_calc_cons(common::ObDList<ObPreCalcExprConstraint> &cached_cons,
const ObPlanCacheCtx &pc_ctx,
const bool is_ignore_stmt,
bool &is_matched);
static int is_same_pre_calc_cons(const ObPreCalcExprConstraint &cons1,
const ObPreCalcExprConstraint &cons2,
bool &is_same);
static int is_same_expr(const ObExpr *expr1,
const ObExpr *expr2,
bool &is_same);
static int check_pre_calc_cons(const bool is_ignore_stmt,
bool &is_match,
ObPreCalcExprConstraint &pre_calc_con,

View File

@ -538,15 +538,11 @@ int ObPlanSet::match_params_info(const Ob2DArray<ObParamInfo,
}
}
if (OB_SUCC(ret) && is_same) {
DLIST_FOREACH(pre_calc_con, all_pre_calc_constraints_) {
if (OB_FAIL(ObPlanCacheObject::check_pre_calc_cons(is_ignore_stmt_,
is_same,
*pre_calc_con,
pc_ctx.exec_ctx_))) {
LOG_WARN("failed to pre calculate expression", K(ret));
} else if (!is_same) {
break;
}
if (OB_FAIL(ObPlanCacheObject::match_pre_calc_cons(all_pre_calc_constraints_, pc_ctx,
is_ignore_stmt_, is_same))) {
LOG_WARN("failed to match pre calc cons", K(ret));
} else if (!is_same) {
LOG_TRACE("pre calc constraints for plan set and cur plan not match");
}
}