fix pre calc constraint bug
This commit is contained in:
		@ -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,
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
@ -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");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user