From 9e297b88eaed65cd433e8bd99974e29421dc595c Mon Sep 17 00:00:00 2001 From: AntiTopQuark Date: Sat, 28 Jan 2023 15:29:36 +0800 Subject: [PATCH] refresh mysqltest of weight_string expr --- src/sql/engine/expr/ob_expr_weight_string.cpp | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/sql/engine/expr/ob_expr_weight_string.cpp b/src/sql/engine/expr/ob_expr_weight_string.cpp index 4789f2aa00..c2c5528c11 100644 --- a/src/sql/engine/expr/ob_expr_weight_string.cpp +++ b/src/sql/engine/expr/ob_expr_weight_string.cpp @@ -62,7 +62,7 @@ int ObExprWeightString::calc_result_typeN(ObExprResType &type, if (types_stack[0].get_type() > ObUNumberType && types_stack[0].get_type() != ObBitType && types_stack[0].get_type() != ObYearType) { - // 输入不是数字类型时 + // When the input is not a numeric type, convert to a varchar type type_ctx.set_cast_mode(type_ctx.get_cast_mode() | CM_NULL_ON_WARN); types_stack[0].set_calc_type(ObVarcharType); } @@ -73,18 +73,17 @@ int ObExprWeightString::calc_result_typeN(ObExprResType &type, types_stack[0].get_type() == ObTimestampType || types_stack[0].get_type() == ObDateType || types_stack[0].get_type() == ObTimeType ) { - // 日期、时间等类型,max_lenght是输入的类型的长度 + // For types such as date, time, etc., the max_lenght is the length of the type entered max_length = types_stack[0].get_length(); } else if (result_length > 0) { max_length = result_length; } else if (as_binary) { - // as_binary的情况下,以nweight作为输出结果的max_length + // In the case of as_binary, the max_length with nweight as the output result max_length = nweight; } else { - // 输入为 char的情况下,使用cs->mbmaxlen计算max_length + // If the input is others, use cs->mbmaxlen to calculate the max_length max_length = cs->mbmaxlen * MAX(nweight, types_stack[0].get_length()*cs->mbmaxlen); } - // 推导结果 type.set_varchar(); type.set_collation_type(CS_TYPE_BINARY); type.set_collation_level(coll_level); @@ -121,7 +120,6 @@ int ObExprWeightString::eval_weight_string(const ObExpr &expr, ObEvalCtx &ctx, O int64_t max_allowed_packet = 0; ObSQLSessionInfo *session = ctx.exec_ctx_.get_my_session(); if (arg->is_null()) { - // The input string is NULL res_datum.set_null(); } else if (!as_binary && (expr.args_[0]->datum_meta_.type_ <= ObUNumberType || expr.args_[0]->datum_meta_.type_ == ObBitType || @@ -156,6 +154,7 @@ int ObExprWeightString::eval_weight_string(const ObExpr &expr, ObEvalCtx &ctx, O tmp_length = cs->coll->strnxfrmlen(cs, cs->mbmaxlen*MAX(str.length() , nweights)); } if (tmp_length >= max_allowed_packet) { + // The return result exceeds the maximum limit and returns NULL. res_datum.set_null(); } else { int used_nweights = nweights; @@ -169,14 +168,27 @@ int ObExprWeightString::eval_weight_string(const ObExpr &expr, ObEvalCtx &ctx, O } bool is_valid_unicode_tmp = 1; char *out_buf = expr.get_str_res_mem(ctx, tmp_length); + // For the case where the input is an empty string but the nweight is not 0, + // the weight_string function will call strnxfrm() to padding the result + // eg: + // mysql> select HEX(WEIGHT_STRING('' as char(3))); + // +-----------------------------------+ + // | HEX(WEIGHT_STRING('' as char(3))) | + // +-----------------------------------+ + // | 002000200020 | + // +-----------------------------------+ + // However, the strnxfrm requires that the input cannot be a null ptr, + // so an empty string is set as the input. + const char* tmp_empty_str = ""; if (OB_ISNULL(out_buf)) { ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc output buf",K(ret)); } else { frm_length = cs->coll->strnxfrm(cs, reinterpret_cast(out_buf), tmp_length, used_nweights, - reinterpret_cast(str.ptr()), + str.ptr() != NULL? reinterpret_cast(str.ptr()) : reinterpret_cast(tmp_empty_str), input_length, flags, &is_valid_unicode_tmp);