adjust locate expr behaviors when null is used as the third param

This commit is contained in:
chimyue
2024-08-08 04:12:09 +00:00
committed by ob-robot
parent 043bb26862
commit 372a785c8e
4 changed files with 42 additions and 4 deletions

View File

@ -33,4 +33,9 @@ DEF_COMPAT_CONTROL_FEATURE(VAR_NAME_LENGTH,
"MySQL will limit the length of user-defined variable names to within 64 characters",
MOCK_CLUSTER_VERSION_4_2_3_0, CLUSTER_VERSION_4_3_0_0,
CLUSTER_VERSION_4_3_2_0)
DEF_COMPAT_CONTROL_FEATURE(FUNC_LOCATE_NULL,
"The result of REPLACE('x', 'abc', null) is different in MySQL 5.7 and 8.0",
MOCK_CLUSTER_VERSION_4_2_5_0, CLUSTER_VERSION_4_3_0_0,
CLUSTER_VERSION_4_3_3_0)
#endif

View File

@ -61,5 +61,12 @@ int ObExprLocate::calc_result_typeN(ObExprResType &type,
return ret;
}
DEF_SET_LOCAL_SESSION_VARS(ObExprLocate, raw_expr) {
int ret = OB_SUCCESS;
SET_LOCAL_SYSVAR_CAPACITY(1);
EXPR_ADD_LOCAL_SYSVAR(share::SYS_VAR_OB_COMPATIBILITY_VERSION);
return ret;
}
} //namespace sql
} //namespace oceanbase

View File

@ -27,6 +27,9 @@ public:
ObExprResType *types_array,
int64_t param_num,
common::ObExprTypeCtx &type_ctx) const;
DECLARE_SET_LOCAL_SESSION_VARS;
private:
static const int8_t PARAM_NUM_TWO = 2;
static const int8_t PARAM_NUM_THREE = 3;

View File

@ -5912,13 +5912,36 @@ int ObLocationExprOperator::calc_(const ObExpr &expr, const ObExpr &sub_arg,
if (OB_SUCC(ret) && !has_result && 3 == expr.arg_cnt_) {
if (OB_FAIL(expr.args_[2]->eval(ctx, pos))) {
LOG_WARN("eval arg 2 failed", K(ret));
} else if (pos->is_null()) {
res_datum.set_int(0);
has_result = true;
} else {
} else if (!pos->is_null()) {
// TODO: 验证MySQL下uint64超过int64值域范围,隐式cast的结果
//
pos_int = pos->get_int();
} else if (lib::is_oracle_mode()) {
res_datum.set_int(0);
has_result = true;
} else {
has_result = true;
ObSolidifiedVarsGetter helper(expr, ctx, ctx.exec_ctx_.get_my_session());
const ObSQLSessionInfo *session = ctx.exec_ctx_.get_my_session();
uint64_t compat_version = 0;
ObCompatType compat_type = COMPAT_MYSQL57;
bool is_enable = false;
if (OB_ISNULL(session)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("session info is null", K(ret));
} else if (OB_FAIL(helper.get_compat_version(compat_version))) {
LOG_WARN("failed to get compat version", K(ret));
} else if (OB_FAIL(ObCompatControl::check_feature_enable(compat_version,
ObCompatFeatureType::FUNC_LOCATE_NULL,
is_enable))) {
LOG_WARN("failed to check feature enable", K(ret));
} else if (OB_FAIL(session->get_compatibility_control(compat_type))) {
LOG_WARN("failed to get compat type", K(ret));
} else if (is_enable && COMPAT_MYSQL8 == compat_type) {
res_datum.set_null();
} else {
res_datum.set_int(0);
}
}
}