Bugfix for dynamic evaluated questionmark

This commit is contained in:
obdev 2024-02-07 12:57:25 +00:00 committed by ob-robot
parent bc0159e02d
commit b45b692d2d
4 changed files with 43 additions and 32 deletions

View File

@ -309,9 +309,7 @@ int ObStaticEngineExprCG::cg_expr_basic(const ObIArray<ObRawExpr *> &raw_exprs)
// do nothing.
} else {
// init arg_cnt_
bool is_dyn_qm = (raw_expr->is_static_const_expr()
&& raw_expr->get_expr_type() == T_QUESTIONMARK
&& static_cast<ObConstRawExpr *>(raw_expr)->is_dynamic_eval_questionmark());
bool is_dyn_qm = is_dynamic_eval_qm(*raw_expr);
rt_expr->arg_cnt_ = raw_expr->get_param_count();
if (is_dyn_qm) {
rt_expr->arg_cnt_ = 1;
@ -456,19 +454,15 @@ int ObStaticEngineExprCG::cg_expr_by_operator(const ObIArray<ObRawExpr *> &raw_e
&eval_assign_question_mark_func:
&eval_question_mark_func;
}
} else if (T_QUESTIONMARK == rt_expr->type_ && raw_expr->is_static_const_expr()
&& static_cast<ObConstRawExpr *>(raw_expr)->is_dynamic_eval_questionmark()) {
} else if (is_dynamic_eval_qm(*raw_expr)) {
ObConstRawExpr *c_expr = static_cast<ObConstRawExpr*>(raw_expr);
int64_t param_idx = 0;
OZ(c_expr->get_value().get_unknown(param_idx));
QuestionmarkDynEvalInfo dyn_info;
if (OB_SUCC(ret)) {
dyn_info.param_idx_ = static_cast<int32_t>(param_idx);
rt_expr->extra_ = param_idx;
if (c_expr->get_orig_qm_type().is_decimal_int() && ob_is_number_tc(rt_expr->datum_meta_.type_)) {
const ObExprResType &orig_type = c_expr->get_orig_qm_type();
rt_expr->eval_func_ = eval_questionmark_decint2nmb;
dyn_info.in_scale_ = orig_type.get_accuracy().get_scale();
dyn_info.in_precision_ = orig_type.get_accuracy().get_precision();
} else if (c_expr->get_orig_qm_type().is_number() && ob_is_decimal_int(rt_expr->datum_meta_.type_)) {
ObCastMode cm = c_expr->get_result_type().get_cast_mode();
if ((cm & CM_CONST_TO_DECIMAL_INT_EQ) != 0) {
@ -480,8 +474,6 @@ int ObStaticEngineExprCG::cg_expr_by_operator(const ObIArray<ObRawExpr *> &raw_e
} else if (c_expr->get_orig_qm_type().is_decimal_int() && ob_is_decimal_int(rt_expr->datum_meta_.type_)) {
const ObExprResType &orig_type = c_expr->get_orig_qm_type();
ObCastMode cm = c_expr->get_result_type().get_cast_mode();
dyn_info.in_precision_ = orig_type.get_accuracy().get_precision();
dyn_info.in_scale_ = orig_type.get_accuracy().get_scale();
if ((cm & CM_CONST_TO_DECIMAL_INT_EQ) != 0) {
rt_expr->eval_func_ = eval_questionmark_decint2decint_eqcast;
} else if (OB_UNLIKELY(CM_IS_CONST_TO_DECIMAL_INT(cm))) {
@ -492,9 +484,6 @@ int ObStaticEngineExprCG::cg_expr_by_operator(const ObIArray<ObRawExpr *> &raw_e
}
}
}
if (OB_SUCC(ret)) {
rt_expr->extra_ = static_cast<int64_t>(dyn_info);
}
} else if (!IS_EXPR_OP(rt_expr->type_) || IS_AGGR_FUN(rt_expr->type_)) {
// do nothing
} else if (OB_FAIL(expr_cg_impl.generate_expr_operator(*raw_expr, expr_op_fetcher))) {
@ -606,9 +595,7 @@ int ObStaticEngineExprCG::classify_exprs(const ObIArray<ObRawExpr *> &raw_exprs,
int ret = OB_SUCCESS;
for (int64_t i = 0; OB_SUCC(ret) && i < raw_exprs.count(); i++) {
ObItemType type = raw_exprs.at(i)->get_expr_type();
bool is_dyn_qm = raw_exprs.at(i)->is_static_const_expr()
&& raw_exprs.at(i)->get_expr_type() == T_QUESTIONMARK
&& static_cast<ObConstRawExpr *>(raw_exprs.at(i))->is_dynamic_eval_questionmark();
bool is_dyn_qm = is_dynamic_eval_qm(*raw_exprs.at(i));
if (T_QUESTIONMARK == type && !rt_question_mark_eval_
&& !raw_exprs.at(i)->has_flag(IS_TABLE_ASSIGN) && !is_dyn_qm) {
if (raw_exprs.at(i)->has_flag(IS_DYNAMIC_PARAM)) {
@ -708,8 +695,7 @@ int ObStaticEngineExprCG::cg_param_frame_layout(const ObIArray<ObRawExpr *> &par
// datum_param_store中存放的信息,
// 当前使用场景是在ObExprValuesOp中进行动态cast时,
// 可以通过该下标最终获取参数化后原始参数值的类型;
if (param_exprs.at(i)->is_const_expr()
&& static_cast<const ObConstRawExpr *>(param_exprs.at(i))->is_dynamic_eval_questionmark()) {
if (is_dynamic_eval_qm(*param_exprs.at(i))) {
// already set in `cg_expr_by_operator`
} else {
rt_expr->extra_ = param_idx;
@ -1605,15 +1591,21 @@ int ObStaticEngineExprCG::gen_expr_with_row_desc(const ObRawExpr *expr,
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("failed to allocate memory for temp expr", K(ret));
}
CK(OB_NOT_NULL(expr));
if (OB_SUCC(ret)) {
LOG_TRACE("generate temp expr", K(*expr), K(row_desc));
int64_t param_cnt =
(session->get_cur_exec_ctx() != NULL
&& session->get_cur_exec_ctx()->get_physical_plan_ctx() != NULL) ?
session->get_cur_exec_ctx()->get_physical_plan_ctx()->get_param_store().count() :
0;
temp_expr = new(buf)ObTempExpr(allocator);
ObStaticEngineExprCG expr_cg(allocator,
session,
schema_guard,
0,
0,
param_cnt,
GET_MIN_CLUSTER_VERSION()); // ?
expr_cg.set_rt_question_mark_eval(true);
expr_cg.set_need_flatten_gen_col(false);
@ -1851,7 +1843,9 @@ int ObStaticEngineExprCG::compute_max_batch_size(const ObRawExpr *raw_expr)
int ObStaticEngineExprCG::generate_extra_questionmarks(ObRawExprUniqueSet &flattened_raw_exprs)
{
int ret = OB_SUCCESS;
if (OB_FAIL(gen_questionmarks_.prepare_allocate(param_cnt_))) {
if (OB_UNLIKELY(param_cnt_ <= 0)) {
// do nothing
} else if (OB_FAIL(gen_questionmarks_.prepare_allocate(param_cnt_))) {
LOG_WARN("prepare allocate elements failed", K(ret));
} else {
for (int i = 0; i < param_cnt_; i++) {
@ -1863,11 +1857,10 @@ int ObStaticEngineExprCG::generate_extra_questionmarks(ObRawExprUniqueSet &flatt
if (OB_ISNULL(all_exprs.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null raw expr", K(ret), K(i));
} else if (all_exprs.at(i)->is_static_const_expr()
&& all_exprs.at(i)->get_expr_type() == T_QUESTIONMARK
&& static_cast<const ObConstRawExpr *>(all_exprs.at(i))->is_dynamic_eval_questionmark()) {
} else if (is_dynamic_eval_qm(*all_exprs.at(i))) {
ObRawExpr *gen_questionmark = all_exprs.at(i);
int64_t param_idx = 0;
ObExprResType orig_qm_type = static_cast<const ObConstRawExpr *>(all_exprs.at(i))->get_orig_qm_type();
ret = static_cast<ObConstRawExpr *>(all_exprs.at(i))->get_value().get_unknown(param_idx);
if (OB_FAIL(ret)) {
LOG_WARN("get param index failed", K(ret));
@ -1876,6 +1869,7 @@ int ObStaticEngineExprCG::generate_extra_questionmarks(ObRawExprUniqueSet &flatt
} else if (OB_UNLIKELY(param_idx >= param_cnt_)) {
LOG_WARN("unexpected param idx", K(ret), K(param_idx), K(param_cnt_));
} else {
gen_questionmark->set_result_type(orig_qm_type);
gen_questionmarks_.at(param_idx) = gen_questionmark;
}
}
@ -1892,5 +1886,12 @@ int ObStaticEngineExprCG::generate_extra_questionmarks(ObRawExprUniqueSet &flatt
return ret;
}
bool ObStaticEngineExprCG::is_dynamic_eval_qm(const ObRawExpr &raw_expr) const
{
return raw_expr.is_static_const_expr() && raw_expr.get_expr_type() == T_QUESTIONMARK
&& static_cast<const ObConstRawExpr &>(raw_expr).is_dynamic_eval_questionmark()
&& param_cnt_ > 0;
}
} // end namespace sql
} // end namespace oceanbase

View File

@ -410,6 +410,7 @@ private:
private:
int generate_extra_questionmarks(ObRawExprUniqueSet &flattened_raw_exprs);
bool is_dynamic_eval_qm(const ObRawExpr &raw_expr) const;
private:
// disallow copy
DISALLOW_COPY_AND_ASSIGN(ObStaticEngineExprCG);

View File

@ -1225,10 +1225,10 @@ int eval_questionmark_decint2nmb(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &ex
int ret = OB_SUCCESS;
// child is questionmark, do not need evaluation.
const ObDatum &child = expr.args_[0]->locate_expr_datum(ctx);
QuestionmarkDynEvalInfo dyn_info(expr.extra_);
ObScale in_scale = expr.args_[0]->datum_meta_.scale_;
ObNumStackOnceAlloc tmp_alloc;
number::ObNumber out_nmb;
if (OB_FAIL(wide::to_number(child.get_decimal_int(), child.get_int_bytes(), dyn_info.in_scale_,
if (OB_FAIL(wide::to_number(child.get_decimal_int(), child.get_int_bytes(), in_scale,
tmp_alloc, out_nmb))) {
LOG_WARN("to_number failed", K(ret));
} else {
@ -1266,8 +1266,7 @@ static int _eval_questionmark_decint2decint(const ObExpr &expr, ObEvalCtx &ctx,
int ret = OB_SUCCESS;
ObScale out_scale = expr.datum_meta_.scale_;
ObPrecision out_prec = expr.datum_meta_.precision_;
QuestionmarkDynEvalInfo dyn_info(expr.extra_);
ObScale in_scale = dyn_info.in_scale_;
ObScale in_scale = expr.args_[0]->datum_meta_.scale_;
ObDecimalIntBuilder res_val;
const ObDatum &child = expr.args_[0]->locate_expr_datum(ctx);
if (OB_FAIL(ObDatumCast::common_scale_decimalint(child.get_decimal_int(), child.get_int_bytes(),

View File

@ -3772,7 +3772,7 @@ int ObRawExprDeduceType::try_replace_casts_with_questionmarks_ora(ObRawExpr *row
return ret;
}
int ObRawExprDeduceType::try_replace_cast_with_questionmark_ora(ObRawExpr &parent, ObRawExpr *cast_expr, int param_idx)
int ObRawExprDeduceType::try_replace_cast_with_questionmark_ora(ObRawExpr &parent, ObRawExpr *cast_expr, int child_idx)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(cast_expr)) {
@ -3791,14 +3791,24 @@ int ObRawExprDeduceType::try_replace_cast_with_questionmark_ora(ObRawExpr &paren
bool is_nmb2decint = param_expr->get_result_type().is_number() && cast_expr->get_result_type().is_decimal_int();
bool is_decint2decint = param_expr->get_result_type().is_decimal_int() && cast_expr->get_result_type().is_decimal_int();
if (param_expr->is_static_const_expr() && param_expr->get_expr_type() == T_QUESTIONMARK
&& !static_cast<ObConstRawExpr *>(param_expr)->is_dynamic_eval_questionmark() // already replaced
&& (is_decint2nmb || is_nmb2decint || is_decint2decint)) {
ObConstRawExpr *c_expr = static_cast<ObConstRawExpr *>(param_expr);
ObExprResType res_type = cast_expr->get_result_type();
res_type.add_cast_mode(cast_expr->get_extra());
ret = static_cast<ObConstRawExpr *>(param_expr)->set_dynamic_eval_questionmark(res_type);
if (OB_FAIL(ret)) {
int64_t param_idx = 0;
if (OB_ISNULL(expr_factory_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null raw expr", K(ret));
} else if (OB_FAIL(c_expr->get_value().get_unknown(param_idx))) {
LOG_WARN("get param idx failed", K(ret));
} else if (OB_FAIL(ObRawExprUtils::create_param_expr(*expr_factory_, param_idx, param_expr))) {
// create new param store to avoid unexpected problem
LOG_WARN("create param expr failed", K(ret));
} else if (OB_FAIL(static_cast<ObConstRawExpr *>(param_expr)->set_dynamic_eval_questionmark(res_type))){
LOG_WARN("set dynamic eval question mark failed", K(ret));
} else {
parent.get_param_expr(param_idx) = param_expr;
parent.get_param_expr(child_idx) = param_expr;
}
}
LOG_DEBUG("replace cast with questionmark", K(*cast_expr), K(is_decint2nmb), K(is_nmb2decint),