Bugfix for ObDecimalIntType

This commit is contained in:
obdev
2024-02-07 10:43:37 +00:00
committed by ob-robot
parent 7fc78f5b9d
commit b414155cd5
11 changed files with 258 additions and 83 deletions

View File

@ -1010,7 +1010,9 @@ bool ObConstRawExpr::inner_same_as(
//what are you doing ?
if (NULL != check_context) {
if (expr.is_const_raw_expr()) {
if (T_QUESTIONMARK == expr.get_expr_type()) {
if (check_context->ora_numeric_compare_ && T_FUN_SYS_CAST == expr.get_expr_type() && lib::is_oracle_mode()) {
bool_ret = check_context->compare_ora_numeric_consts(*this, static_cast<const ObSysFunRawExpr&>(expr));
} else if (T_QUESTIONMARK == expr.get_expr_type()) {
bool_ret = true;
const ObConstRawExpr *c_expr = static_cast<const ObConstRawExpr *>(&expr);
int64_t param_idx = -1;
@ -1082,6 +1084,58 @@ bool ObExprEqualCheckContext::compare_const(const ObConstRawExpr &left,
return result;
}
bool ObExprEqualCheckContext::compare_ora_numeric_consts(const ObConstRawExpr &left,
const ObSysFunRawExpr &right)
{
int &ret = err_code_;
bool result = false;
if (OB_LIKELY(lib::is_oracle_mode() && right.is_const_expr() && right.get_expr_type() == T_FUN_SYS_CAST)) {
ObCastMode cm = right.get_extra();
const ObRawExpr *real_right = nullptr;
bool is_lossless = false;
if (CM_IS_IMPLICIT_CAST(cm) && !CM_IS_CONST_TO_DECIMAL_INT(cm)) {
if (OB_FAIL(ObOptimizerUtil::is_lossless_column_cast(&right, is_lossless))) {
LOG_WARN("check lossless cast failed", K(ret));
} else if (is_lossless) {
real_right = right.get_param_expr(0);
if (OB_ISNULL(real_right)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid null param expr", K(ret));
} else {
result = left.same_as(*real_right, this);
}
}
}
}
return result;
}
bool ObExprEqualCheckContext::compare_ora_numeric_consts(const ObSysFunRawExpr &left, const ObConstRawExpr &right)
{
int &ret = err_code_;
LOG_INFO("debug test");
bool result = false;
if (OB_LIKELY(lib::is_oracle_mode() && left.get_expr_type()== T_FUN_SYS_CAST && left.is_const_expr())) {
ObCastMode cm = left.get_extra();
const ObRawExpr *real_left = nullptr;
bool is_lossless = false;
if (CM_IS_IMPLICIT_CAST(cm) && !CM_IS_CONST_TO_DECIMAL_INT(cm)) {
if (OB_FAIL(ObOptimizerUtil::is_lossless_column_cast(&left, is_lossless))) {
LOG_WARN("check lossless cast failed", K(ret));
} else if (is_lossless) {
real_left = left.get_param_expr(0);
if (OB_ISNULL(real_left)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid null param expr", K(ret));
} else {
result = real_left->same_as(right, this);
}
}
}
}
return result;
}
int ObConstRawExpr::do_visit(ObRawExprVisitor &visitor)
{
return visitor.visit(*this);
@ -3721,6 +3775,10 @@ bool ObSysFunRawExpr::inner_same_as(
{
bool bool_ret = false;
if (get_expr_type() != expr.get_expr_type()) {
if (check_context != NULL && check_context->ora_numeric_compare_ && expr.is_const_raw_expr()
&& T_FUN_SYS_CAST == get_expr_type() && lib::is_oracle_mode()) {
bool_ret = check_context->compare_ora_numeric_consts(*this, static_cast<const ObConstRawExpr &>(expr));
}
} else if (T_FUN_SYS_RAND == get_expr_type() ||
T_FUN_SYS_RANDOM == get_expr_type() ||
T_FUN_SYS_GUID == get_expr_type() ||

View File

@ -1371,7 +1371,8 @@ struct ObExprEqualCheckContext
err_code_(common::OB_SUCCESS),
param_expr_(),
need_check_deterministic_(false),
ignore_param_(false)
ignore_param_(false),
ora_numeric_compare_(false)
{ }
ObExprEqualCheckContext(bool need_check_deterministic)
: override_const_compare_(false),
@ -1383,7 +1384,8 @@ struct ObExprEqualCheckContext
err_code_(common::OB_SUCCESS),
param_expr_(),
need_check_deterministic_(need_check_deterministic),
ignore_param_(false)
ignore_param_(false),
ora_numeric_compare_(false)
{ }
virtual ~ObExprEqualCheckContext() {}
struct ParamExprPair
@ -1419,6 +1421,9 @@ struct ObExprEqualCheckContext
virtual bool compare_set_op_expr(const ObSetOpRawExpr& left,
const ObSetOpRawExpr& right);
virtual bool compare_ora_numeric_consts(const ObConstRawExpr &left, const ObSysFunRawExpr &right);
virtual bool compare_ora_numeric_consts(const ObSysFunRawExpr &right, const ObConstRawExpr &left);
void reset() {
override_const_compare_ = false;
override_column_compare_ = false;
@ -1442,6 +1447,7 @@ struct ObExprEqualCheckContext
common::ObSEArray<ParamExprPair, 3, common::ModulePageAllocator, true> param_expr_;
bool need_check_deterministic_;
bool ignore_param_; // only compare structure of expr
bool ora_numeric_compare_;
};
struct ObExprParamCheckContext : ObExprEqualCheckContext
@ -1565,7 +1571,8 @@ struct ObResolveContext
is_for_dbms_sql_(false),
tg_timing_event_(TG_TIMING_EVENT_INVALID),
view_ref_id_(OB_INVALID_ID),
is_variable_allowed_(true)
is_variable_allowed_(true),
is_expanding_view_(false)
{
}
@ -1611,6 +1618,7 @@ struct ObResolveContext
TgTimingEvent tg_timing_event_; // for mysql trigger
uint64_t view_ref_id_;
bool is_variable_allowed_;
bool is_expanding_view_;
};
typedef ObResolveContext<ObRawExprFactory> ObExprResolveContext;

View File

@ -162,10 +162,10 @@ int ObRawExprResolverImpl::try_negate_const(ObRawExpr *&expr,
ObObj new_val;
if (const_expr->get_value().is_decimal_int()) {
ObDecimalInt *neg_dec = nullptr;
if (is_odd
&& OB_FAIL(wide::negate(const_expr->get_value().get_decimal_int(),
const_expr->get_value().get_int_bytes(), neg_dec,
ctx_.expr_factory_.get_allocator()))) {
if (!is_odd) {// do nothing
} else if (OB_FAIL(wide::negate(const_expr->get_value().get_decimal_int(),
const_expr->get_value().get_int_bytes(), neg_dec,
ctx_.expr_factory_.get_allocator()))) {
LOG_WARN("negate decimal int failed", K(ret));
} else {
new_val.set_decimal_int(const_expr->get_value().get_int_bytes(),
@ -2522,6 +2522,9 @@ int ObRawExprResolverImpl::process_datatype_or_questionmark(const ParseNode &nod
LOG_WARN("get sys variables failed", K(ret));
} else if (OB_FAIL(ObSQLUtils::check_enable_decimalint(session_info, enable_decimal_int))) {
LOG_WARN("fail to check enable decimal int", K(ret));
} else if (lib::is_oracle_mode() && ctx_.is_expanding_view_) {
// numeric constants should parsed with ObNumber in view expansion for oracle mode
enable_decimal_int = false;
}
if (OB_FAIL(ret)) { // do nothing