diff --git a/src/share/object/ob_obj_cast.cpp b/src/share/object/ob_obj_cast.cpp index 42a6d3432..9947f872e 100644 --- a/src/share/object/ob_obj_cast.cpp +++ b/src/share/object/ob_obj_cast.cpp @@ -4422,25 +4422,36 @@ static int bit_datetime( int ret = OB_SUCCESS; uint64_t bit_value = in.get_bit(); int64_t value = 0; - ObScale scale = in.get_scale(); ObScale res_scale = -1; - const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; - int64_t pos = 0; - char buf[BUF_LEN]; - MEMSET(buf, 0, BUF_LEN); if (OB_UNLIKELY((ObBitTC != in.get_type_class() || ObDateTimeTC != ob_obj_type_class(expect_type)))) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type)); - } else if (OB_FAIL(bit_to_char_array(bit_value, scale, buf, BUF_LEN, pos))) { - LOG_WARN("fail to store val", KP(buf), K(BUF_LEN), K(bit_value), K(pos)); - } else { - ObString str(pos, buf); + } else if (CM_IS_COLUMN_CONVERT(cast_mode)) { + // if cast mode is column convert, using bit as int64 to do cast. ObTimeConvertCtx cvrt_ctx(params.dtc_params_.tz_info_, ObTimestampType == expect_type); - if (CAST_FAIL(ObTimeConverter::str_to_datetime(str, cvrt_ctx, value, &res_scale))) { - } else { - SET_RES_DATETIME(out); - SET_RES_ACCURACY(DEFAULT_PRECISION_FOR_TEMPORAL, res_scale, DEFAULT_LENGTH_FOR_TEMPORAL); + if (CAST_FAIL(ObTimeConverter::int_to_datetime(bit_value, 0, cvrt_ctx, value))) { + LOG_WARN("int_to_datetime failed", K(ret), K(bit_value)); } + } else { + // using bit as char array to do cast. + ObScale scale = in.get_scale(); + const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; + int64_t pos = 0; + char buf[BUF_LEN]; + MEMSET(buf, 0, BUF_LEN); + if (OB_FAIL(bit_to_char_array(bit_value, scale, buf, BUF_LEN, pos))) { + LOG_WARN("fail to store val", KP(buf), K(BUF_LEN), K(bit_value), K(pos)); + } else { + ObString str(pos, buf); + ObTimeConvertCtx cvrt_ctx(params.dtc_params_.tz_info_, ObTimestampType == expect_type); + if (CAST_FAIL(ObTimeConverter::str_to_datetime(str, cvrt_ctx, value, &res_scale))) { + LOG_WARN("int_to_datetime failed", K(ret), K(bit_value), K(str)); + } + } + } + if (OB_SUCC(ret)) { + SET_RES_DATETIME(out); + SET_RES_ACCURACY(DEFAULT_PRECISION_FOR_TEMPORAL, res_scale, DEFAULT_LENGTH_FOR_TEMPORAL); } return ret; } @@ -4451,24 +4462,34 @@ static int bit_date( int ret = OB_SUCCESS; uint64_t bit_value = in.get_bit(); int32_t value = 0; - ObScale scale = in.get_scale(); ObScale res_scale = -1; - const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; - int64_t pos = 0; - char buf[BUF_LEN]; - MEMSET(buf, 0, BUF_LEN); if (OB_UNLIKELY((ObBitTC != in.get_type_class() || ObDateTC != ob_obj_type_class(expect_type)))) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type)); - } else if (OB_FAIL(bit_to_char_array(bit_value, scale, buf, BUF_LEN, pos))) { - LOG_WARN("fail to store val", KP(buf), K(BUF_LEN), K(bit_value), K(pos)); - } else { - ObString str(pos, buf); - if (CAST_FAIL(ObTimeConverter::str_to_date(str, value))) { - } else { - SET_RES_DATE(out); - SET_RES_ACCURACY(DEFAULT_PRECISION_FOR_TEMPORAL, res_scale, DEFAULT_LENGTH_FOR_TEMPORAL); + } else if (CM_IS_COLUMN_CONVERT(cast_mode)) { + // if cast mode is column convert, using bit as int64 to do cast. + if (CAST_FAIL(ObTimeConverter::int_to_date(bit_value, value))) { + LOG_WARN("int_to_date failed", K(ret), K(bit_value)); } + } else { + // using bit as char array to do cast. + ObScale scale = in.get_scale(); + const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; + int64_t pos = 0; + char buf[BUF_LEN]; + MEMSET(buf, 0, BUF_LEN); + if (OB_FAIL(bit_to_char_array(bit_value, scale, buf, BUF_LEN, pos))) { + LOG_WARN("fail to store val", KP(buf), K(BUF_LEN), K(bit_value), K(pos)); + } else { + ObString str(pos, buf); + if (CAST_FAIL(ObTimeConverter::str_to_date(str, value))) { + LOG_WARN("str_to_date failed", K(ret), K(bit_value), K(str)); + } + } + } + if (OB_SUCC(ret)) { + SET_RES_DATE(out); + SET_RES_ACCURACY(DEFAULT_PRECISION_FOR_TEMPORAL, res_scale, DEFAULT_LENGTH_FOR_TEMPORAL); } return ret; } @@ -4479,24 +4500,34 @@ static int bit_time( int ret = OB_SUCCESS; uint64_t bit_value = in.get_bit(); int64_t value = 0; - ObScale scale = in.get_scale(); ObScale res_scale = -1; - const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; - int64_t pos = 0; - char buf[BUF_LEN]; - MEMSET(buf, 0, BUF_LEN); if (OB_UNLIKELY((ObBitTC != in.get_type_class() || ObTimeTC != ob_obj_type_class(expect_type)))) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type)); - } else if (OB_FAIL(bit_to_char_array(bit_value, scale, buf, BUF_LEN, pos))) { - LOG_WARN("fail to store val", KP(buf), K(BUF_LEN), K(bit_value), K(pos)); - } else { - ObString str(pos, buf); - if (CAST_FAIL(ObTimeConverter::str_to_time(str, value, &res_scale))) { - } else { - SET_RES_TIME(out); - SET_RES_ACCURACY(DEFAULT_PRECISION_FOR_TEMPORAL, res_scale, DEFAULT_LENGTH_FOR_TEMPORAL); + } else if (CM_IS_COLUMN_CONVERT(cast_mode)) { + // if cast mode is column convert, using bit as int64 to do cast. + if (CAST_FAIL(ObTimeConverter::int_to_time(bit_value, value))) { + LOG_WARN("int_to_time failed", K(ret), K(bit_value)); } + } else { + // using bit as char array to do cast. + ObScale scale = in.get_scale(); + const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; + int64_t pos = 0; + char buf[BUF_LEN]; + MEMSET(buf, 0, BUF_LEN); + if (OB_FAIL(bit_to_char_array(bit_value, scale, buf, BUF_LEN, pos))) { + LOG_WARN("fail to store val", KP(buf), K(BUF_LEN), K(bit_value), K(pos)); + } else { + ObString str(pos, buf); + if (CAST_FAIL(ObTimeConverter::str_to_time(str, value, &res_scale))) { + LOG_WARN("str_to_date failed", K(ret), K(bit_value), K(str)); + } + } + } + if (OB_SUCC(ret)) { + SET_RES_TIME(out); + SET_RES_ACCURACY(DEFAULT_PRECISION_FOR_TEMPORAL, res_scale, DEFAULT_LENGTH_FOR_TEMPORAL); } return ret; } @@ -4507,24 +4538,15 @@ static int bit_year( int ret = OB_SUCCESS; uint64_t bit_value = in.get_bit(); uint8_t value = 0; - ObScale scale = in.get_scale(); ObScale res_scale = -1; - const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; - int64_t pos = 0; - char buf[BUF_LEN]; - MEMSET(buf, 0, BUF_LEN); if (OB_UNLIKELY((ObBitTC != in.get_type_class() || ObYearTC != ob_obj_type_class(expect_type)))) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type)); - } else if (OB_FAIL(bit_to_char_array(bit_value, scale, buf, BUF_LEN, pos))) { - LOG_WARN("fail to store val", KP(buf), K(BUF_LEN), K(bit_value), K(pos)); + } else if (CAST_FAIL(ObTimeConverter::int_to_year(bit_value, value))) { + LOG_WARN("int_to_year faile", K(ret), K(bit_value)); } else { - ObString str(pos, buf); - if (CAST_FAIL(ObTimeConverter::str_to_year(str, value))) { - } else { - SET_RES_YEAR(out); - SET_RES_ACCURACY(DEFAULT_PRECISION_FOR_TEMPORAL, res_scale, DEFAULT_LENGTH_FOR_TEMPORAL); - } + SET_RES_YEAR(out); + SET_RES_ACCURACY(DEFAULT_PRECISION_FOR_TEMPORAL, res_scale, DEFAULT_LENGTH_FOR_TEMPORAL); } return ret; } @@ -4533,24 +4555,45 @@ static int bit_string( const ObObjType expect_type, ObObjCastParams& params, const ObObj& in, ObObj& out, const ObCastMode cast_mode) { int ret = OB_SUCCESS; - UNUSED(cast_mode); - ObLength res_length = -1; - int32_t bytes_length = 0; - const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; - ObScale scale = in.get_scale(); - int64_t pos = 0; - char buf[BUF_LEN]; - MEMSET(buf, 0, BUF_LEN); uint64_t value = in.get_bit(); + ObLength res_length = -1; + char *res_buf; + int32_t bytes_length = 0; if (OB_UNLIKELY((ObBitTC != in.get_type_class() || (ObStringTC != ob_obj_type_class(expect_type) && ObTextTC != ob_obj_type_class(expect_type))))) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type)); + } else if (CM_IS_COLUMN_CONVERT(cast_mode)) { + // if cast mode is column convert, using bit as int64 to do cast. + ObFastFormatInt ffi(value); + ObString tmp_str; + if (OB_FAIL(convert_string_collation(ObString(ffi.length(), ffi.ptr()), + ObCharset::get_system_collation(), + tmp_str, + params.dest_collation_, + params))) { + LOG_WARN("fail to convert string collation", K(ret)); + } else { + res_buf = tmp_str.ptr(); + bytes_length = tmp_str.length(); + } } else { - if (OB_FAIL(bit_to_char_array(value, scale, buf, BUF_LEN, pos))) { - LOG_WARN("fail to store val", KP(buf), K(BUF_LEN), K(value), K(pos)); - } else if (OB_FAIL(copy_string(params, expect_type, buf, pos, out))) { - LOG_WARN("fail to copy string", KP(buf), K(bytes_length), K(value), K(out), K(expect_type)); + // using bit as char array to do cast. + ObScale scale = in.get_scale(); + const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; + int64_t pos = 0; + char tmp_buf[BUF_LEN]; + MEMSET(tmp_buf, 0, BUF_LEN); + if (OB_FAIL(bit_to_char_array(value, scale, tmp_buf, BUF_LEN, pos))) { + LOG_WARN("fail to store val", KP(tmp_buf), K(BUF_LEN), K(value), K(pos)); + } else { + res_buf = tmp_buf; + bytes_length = pos; + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(copy_string(params, expect_type, res_buf, bytes_length, out))) { + LOG_WARN("fail to copy string", KP(res_buf), K(bytes_length), K(value), K(out), K(expect_type)); } else { res_length = static_cast(out.get_string_len()); SET_RES_ACCURACY(DEFAULT_PRECISION_FOR_STRING, DEFAULT_SCALE_FOR_STRING, res_length); diff --git a/src/sql/engine/expr/ob_datum_cast.cpp b/src/sql/engine/expr/ob_datum_cast.cpp index e4a623943..b1932a45e 100644 --- a/src/sql/engine/expr/ob_datum_cast.cpp +++ b/src/sql/engine/expr/ob_datum_cast.cpp @@ -3359,28 +3359,41 @@ CAST_FUNC_NAME(bit, datetime) { GET_SESSION() { - const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; - int64_t pos = 0; - char buf[BUF_LEN] = {0}; - uint64_t in_val = child_res->get_uint(); - ObLengthSemantics length = expr.args_[0]->datum_meta_.length_semantics_; - if (OB_FAIL(bit_to_char_array(in_val, length, buf, BUF_LEN, pos))) { - LOG_WARN("fail to store val", K(buf), K(BUF_LEN), K(in_val), K(pos)); - } else if (OB_ISNULL(session)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("session is NULL", K(ret)); - } else { - int warning = OB_SUCCESS; - ObObjType out_type = expr.datum_meta_.type_; - ObString str(pos, buf); - ObTimeConvertCtx cvrt_ctx(session->get_timezone_info(), ObTimestampType == out_type); - ObScale res_scale; - int64_t out_val = 0; - if (CAST_FAIL(ObTimeConverter::str_to_datetime(str, cvrt_ctx, out_val, &res_scale))) { - LOG_WARN("str_to_datetime failed", K(ret)); + DEF_IN_OUT_VAL(uint64_t, int64_t, 0); + if (CM_IS_COLUMN_CONVERT(expr.extra_)) { + // if cast mode is column convert, using bit as int64 to do cast. + int64_t int64 = 0; + if (OB_FAIL(common_uint_int(expr, ObIntType, in_val, ctx, int64))) { + LOG_WARN("common_uint_int failed", K(ret)); + } else if (OB_UNLIKELY(0 > int64)) { + ret = OB_INVALID_DATE_FORMAT; + LOG_WARN("invalid date", K(ret), K(int64)); } else { - SET_RES_DATETIME(out_val); + ObTimeConvertCtx cvrt_ctx(session->get_timezone_info(), ObTimestampType == expr.datum_meta_.type_); + if (CAST_FAIL(ObTimeConverter::int_to_datetime(int64, 0, cvrt_ctx, out_val))) { + LOG_WARN("int_datetime failed", K(ret), K(int64)); + } } + } else { + // using bit as char array to do cast. + const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; + int64_t pos = 0; + char buf[BUF_LEN] = {0}; + ObLengthSemantics length = expr.args_[0]->datum_meta_.length_semantics_; + if (OB_FAIL(bit_to_char_array(in_val, length, buf, BUF_LEN, pos))) { + LOG_WARN("fail to store val", K(buf), K(BUF_LEN), K(in_val), K(pos)); + } else { + ObObjType out_type = expr.datum_meta_.type_; + ObString str(pos, buf); + ObTimeConvertCtx cvrt_ctx(session->get_timezone_info(), ObTimestampType == out_type); + ObScale res_scale; + if (CAST_FAIL(ObTimeConverter::str_to_datetime(str, cvrt_ctx, out_val, &res_scale))) { + LOG_WARN("str_to_datetime failed", K(ret)); + } + } + } + if (OB_SUCC(ret)) { + SET_RES_DATETIME(out_val); } } } @@ -3391,20 +3404,32 @@ CAST_FUNC_NAME(bit, date) { EVAL_ARG() { - const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; - int64_t pos = 0; - char buf[BUF_LEN] = {0}; DEF_IN_OUT_VAL(uint64_t, int32_t, 0); - ObLengthSemantics length = expr.args_[0]->datum_meta_.length_semantics_; - if (OB_FAIL(bit_to_char_array(in_val, length, buf, BUF_LEN, pos))) { - LOG_WARN("fail to store val", K(buf), K(BUF_LEN), K(in_val), K(pos)); - } else { - ObString str(pos, buf); - if (CAST_FAIL(ObTimeConverter::str_to_date(str, out_val))) { - LOG_WARN("str_to_datetime failed", K(ret)); - } else { - SET_RES_DATE(out_val); + if (CM_IS_COLUMN_CONVERT(expr.extra_)) { + // if cast mode is column convert, using bit as int64 to do cast. + int64_t int64 = 0; + if (OB_FAIL(common_uint_int(expr, ObIntType, in_val, ctx, int64))) { + LOG_WARN("common_uint_int failed", K(ret)); + } else if (CAST_FAIL(ObTimeConverter::int_to_date(int64, out_val))) { + LOG_WARN("int_to_date failed", K(ret), K(int64), K(out_val)); } + } else { + // using bit as char array to do cast. + const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; + int64_t pos = 0; + char buf[BUF_LEN] = {0}; + ObLengthSemantics length = expr.args_[0]->datum_meta_.length_semantics_; + if (OB_FAIL(bit_to_char_array(in_val, length, buf, BUF_LEN, pos))) { + LOG_WARN("fail to store val", K(buf), K(BUF_LEN), K(in_val), K(pos)); + } else { + ObString str(pos, buf); + if (CAST_FAIL(ObTimeConverter::str_to_date(str, out_val))) { + LOG_WARN("str_to_datetime failed", K(ret)); + } + } + } + if (OB_SUCC(ret)) { + SET_RES_DATE(out_val); } } return ret; @@ -3414,20 +3439,31 @@ CAST_FUNC_NAME(bit, time) { EVAL_ARG() { - const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; - int64_t pos = 0; - char buf[BUF_LEN] = {0}; DEF_IN_OUT_VAL(uint64_t, int64_t, 0); - ObLengthSemantics length = expr.args_[0]->datum_meta_.length_semantics_; - if (OB_FAIL(bit_to_char_array(in_val, length, buf, BUF_LEN, pos))) { - LOG_WARN("fail to store val", K(buf), K(BUF_LEN), K(in_val), K(pos)); + if (CM_IS_COLUMN_CONVERT(expr.extra_)) { + // if cast mode is column convert, using bit as int64 to do cast. + int64_t int64 = 0; + if (OB_FAIL(common_uint_int(expr, ObIntType, in_val, ctx, int64))) { + LOG_WARN("common_uint_int failed", K(ret), K(in_val)); + } else if (OB_FAIL(common_int_time(expr, int64, res_datum))) { + LOG_WARN("common_int_time failed", K(ret), K(out_val)); + } } else { - ObString str(pos, buf); - ObScale res_scale; - if (CAST_FAIL(ObTimeConverter::str_to_time(str, out_val, &res_scale))) { - LOG_WARN("str_to_datetime failed", K(ret)); + // using bit as char array to do cast. + const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; + int64_t pos = 0; + char buf[BUF_LEN] = {0}; + ObLengthSemantics length = expr.args_[0]->datum_meta_.length_semantics_; + if (OB_FAIL(bit_to_char_array(in_val, length, buf, BUF_LEN, pos))) { + LOG_WARN("fail to store val", K(buf), K(BUF_LEN), K(in_val), K(pos)); } else { - SET_RES_TIME(out_val); + ObString str(pos, buf); + ObScale res_scale; + if (CAST_FAIL(ObTimeConverter::str_to_time(str, out_val, &res_scale))) { + LOG_WARN("str_to_datetime failed", K(ret)); + } else { + SET_RES_TIME(out_val); + } } } } @@ -3438,20 +3474,13 @@ CAST_FUNC_NAME(bit, year) { EVAL_ARG() { - DEF_IN_OUT_VAL(uint64_t, uint8_t, 0); - const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; - int64_t pos = 0; - char buf[BUF_LEN] = {0}; - ObLengthSemantics length = expr.args_[0]->datum_meta_.length_semantics_; - if (OB_FAIL(bit_to_char_array(in_val, length, buf, BUF_LEN, pos))) { - LOG_WARN("fail to store val", K(buf), K(BUF_LEN), K(in_val), K(pos)); - } else { - ObString str(pos, buf); - if (CAST_FAIL(ObTimeConverter::str_to_year(str, out_val))) { - LOG_WARN("str_to_datetime failed", K(ret)); - } else { - SET_RES_YEAR(out_val); - } + // same as uint to year + uint64_t in_val = child_res->get_uint(); + int64_t out_val = 0; + if (OB_FAIL(common_uint_int(expr, ObIntType, in_val, ctx, out_val))) { + LOG_WARN("common_uint_int failed", K(ret), K(in_val)); + } else if (OB_FAIL(common_int_year(expr, out_val, res_datum))) { + LOG_WARN("common_int_year failed", K(ret), K(out_val)); } } return ret; @@ -3461,17 +3490,26 @@ CAST_FUNC_NAME(bit, string) { EVAL_ARG() { - const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; - int64_t pos = 0; - char buf[BUF_LEN] = {0}; uint64_t in_val = child_res->get_uint(); - ObLengthSemantics length = expr.args_[0]->datum_meta_.length_semantics_; - if (OB_FAIL(bit_to_char_array(in_val, length, buf, BUF_LEN, pos))) { - LOG_WARN("fail to store val", K(buf), K(BUF_LEN), K(in_val), K(pos)); + if (CM_IS_COLUMN_CONVERT(expr.extra_)) { + // if cast mode is column convert, using bit as int64 to do cast. + ObFastFormatInt ffi(in_val); + if (OB_FAIL(common_copy_string_zf(expr, ObString(ffi.length(), ffi.ptr()), ctx, res_datum))) { + LOG_WARN("common_copy_string_zf failed", K(ret), K(ObString(ffi.length(), ffi.ptr()))); + } } else { - ObString str(pos, buf); - if (OB_FAIL(common_copy_string(expr, str, ctx, res_datum))) { - LOG_WARN("common_copy_string failed", K(ret)); + // using bit as char array to do cast. + const int32_t BUF_LEN = (OB_MAX_BIT_LENGTH + 7) / 8; + int64_t pos = 0; + char buf[BUF_LEN] = {0}; + ObLengthSemantics length = expr.args_[0]->datum_meta_.length_semantics_; + if (OB_FAIL(bit_to_char_array(in_val, length, buf, BUF_LEN, pos))) { + LOG_WARN("fail to store val", K(ret), K(in_val), K(length), K(buf), K(BUF_LEN), K(pos)); + } else { + ObString str(pos, buf); + if (OB_FAIL(common_copy_string(expr, str, ctx, res_datum))) { + LOG_WARN("common_copy_string failed", K(ret)); + } } } } diff --git a/src/sql/engine/expr/ob_expr_operator.cpp b/src/sql/engine/expr/ob_expr_operator.cpp index 5f97887d9..605cee606 100644 --- a/src/sql/engine/expr/ob_expr_operator.cpp +++ b/src/sql/engine/expr/ob_expr_operator.cpp @@ -202,6 +202,14 @@ int OB_INLINE ObExprOperator::cast_operand_type( LOG_DEBUG( "need cast operand", K(res_type), K(res_type.get_calc_meta().get_scale()), K(res_obj), K(res_obj.get_scale())); ObCastMode cast_mode = get_cast_mode(); + // In PAD expression, we need add COLUMN_CONVERT to cast mode when cast is + // from bit to binary and column convert is set in column_conv_ctx_. The COLUMN_CONVERT + // cast mode is used in bit_to_string to decide which cast way is appropriate. + if (OB_UNLIKELY(T_FUN_PAD == get_type() && ob_is_bit_tc(param_type) && + ob_is_varbinary_type(calc_type, calc_collation_type) && + CM_IS_COLUMN_CONVERT(expr_ctx.column_conv_ctx_.cast_mode_))) { + cast_mode |= CM_COLUMN_CONVERT; + } if (ob_is_string_or_lob_type(res_type.get_calc_type()) && res_type.is_zerofill()) { // For zerofilled string diff --git a/src/sql/engine/expr/ob_infix_expression.cpp b/src/sql/engine/expr/ob_infix_expression.cpp index 142390b25..ed3fd9408 100644 --- a/src/sql/engine/expr/ob_infix_expression.cpp +++ b/src/sql/engine/expr/ob_infix_expression.cpp @@ -390,7 +390,7 @@ int ObInfixExpression::eval( const int64_t idx = item.get_column(); if (OB_LIKELY(idx >= 0 && OB_LIKELY(idx < row.count_) && OB_LIKELY(NULL != row.cells_))) { stack[pos] = row.cells_[idx]; - if (OB_UNLIKELY(ObBitType == stack[pos].get_type())) { + if (OB_UNLIKELY(ObBitType == stack[pos].get_type() && -1 != item.get_accuracy().get_precision())) { // use object scale to store bit length stack[pos].set_scale(item.get_accuracy().get_precision()); } else if (OB_UNLIKELY(ob_is_text_tc(stack[pos].get_type()))) { @@ -401,7 +401,7 @@ int ObInfixExpression::eval( } else if (NULL != ctx.row2_ && NULL != ctx.row2_->cells_ && idx >= row.count_ && idx - row.count_ < ctx.row2_->count_) { stack[pos] = ctx.row2_->cells_[idx - row.count_]; - if (OB_UNLIKELY(ObBitType == stack[pos].get_type())) { + if (OB_UNLIKELY(ObBitType == stack[pos].get_type() && -1 != item.get_accuracy().get_precision())) { // use object scale to store bit length stack[pos].set_scale(item.get_accuracy().get_precision()); } else if (-1 != item.get_accuracy().get_scale()) { @@ -435,6 +435,12 @@ int ObInfixExpression::eval( item.get_item_type(), "type_name", get_type_name(item.get_item_type())); + } else { + // For expression op, we need set scale info after it has been evaluated. + if (OB_UNLIKELY(ObBitType == stack[pos].get_type() && -1 != item.get_accuracy().get_precision())) { + // use object scale to store bit length + stack[pos].set_scale(item.get_accuracy().get_precision()); + } } } else { ret = OB_ERR_UNEXPECTED;