cherry-pick bugfix from 3.1 to open source branch

This commit is contained in:
obdev
2021-07-14 17:48:15 +08:00
committed by wangzelin.wzl
parent 131c2cf658
commit a997b23808
19 changed files with 14233 additions and 14190 deletions

View File

@ -813,6 +813,14 @@ static OB_INLINE int common_string_year(const ObExpr& expr, const ObString& in_s
tmp_res.pack_ = sizeof(tmp_int);
if (OB_FAIL(common_string_int(expr, extra, in_str, is_str_int_cast, tmp_res, warning))) {
LOG_WARN("common_string_int failed", K(ret), K(in_str));
} else if (0 == tmp_int) {
// cast '0000' to year, result is 0. cast '0'/'00'/'00000' to year, result is 2000.
if (4 == in_str.length()) {
SET_RES_YEAR(ObTimeConverter::ZERO_YEAR);
} else {
const uint8_t base_year = 100;
SET_RES_YEAR(base_year);
}
} else {
if (CAST_FAIL(common_int_year(expr, tmp_int, res_datum, warning))) {
LOG_WARN("common_int_year failed", K(ret), K(tmp_int));
@ -1493,13 +1501,13 @@ static int common_number_datetime(
int64_t int_part = 0;
int64_t dec_part = 0;
if (nmb.is_negative()) {
ret = OB_INVALID_DATE_FORMAT;
LOG_WARN("invalid date format", K(ret), K(nmb));
ret = OB_INVALID_DATE_VALUE;
LOG_WARN("invalid datetime value", K(ret), K(nmb));
} else if ((ObTimestampType == out_type && nmb.is_decimal())) {
ret = OB_INVALID_DATE_FORMAT;
ret = OB_INVALID_DATE_VALUE;
LOG_WARN("invalid date format", K(ret), K(nmb));
} else if (!nmb.is_int_parts_valid_int64(int_part, dec_part)) {
ret = OB_INVALID_DATE_FORMAT;
ret = OB_INVALID_DATE_VALUE;
LOG_WARN("invalid date format", K(ret), K(nmb));
} else {
ret = ObTimeConverter::int_to_datetime(int_part, dec_part, cvrt_ctx, out_val);
@ -2236,20 +2244,32 @@ CAST_FUNC_NAME(number, date)
{
EVAL_ARG()
{
int64_t int_value = 0;
int32_t out_val = 0;
int warning = OB_SUCCESS;
const number::ObNumber nmb(child_res->get_number());
// Converting number to date should do trunc to number, rounding down the decimal place
if (OB_FAIL(nmb.extract_valid_int64_with_trunc(int_value))) {
if (OB_DATA_OUT_OF_RANGE == ret) {
ret = OB_SUCCESS;
int_value = INT64_MAX;
} else {
LOG_WARN("extract valid int64 failed", K(ret), K(nmb));
int64_t int_part = 0;
int64_t dec_part = 0;
if (nmb.is_negative()) {
ret = OB_INVALID_DATE_VALUE;
LOG_WARN("invalid date value", K(ret), K(nmb));
} else if (!nmb.is_int_parts_valid_int64(int_part, dec_part)) {
ret = OB_INVALID_DATE_VALUE;
LOG_WARN("invalid date format", K(ret), K(nmb));
} else {
ret = ObTimeConverter::int_to_date(int_part, out_val);
if (OB_SUCC(ret) && OB_UNLIKELY(dec_part > 0)) {
LOG_WARN("invalid date value with decimal part", K(ret));
if (!CM_IS_WARN_ON_FAIL(expr.extra_)) {
ret = OB_INVALID_DATE_VALUE;
}
}
LOG_DEBUG("stt, end common number date", K(int_part), K(dec_part), K(out_val), K(ret));
}
if (OB_SUCC(ret) && CAST_FAIL(common_int_date(expr, int_value, res_datum))) {
LOG_WARN("common_in_date failed", K(ret), K(int_value));
if (CAST_FAIL(ret)) {
} else {
SET_RES_DATE(out_val);
LOG_DEBUG("stt, number to date", K(nmb), K(out_val), K(ret), K(warning));
}
}
return ret;
@ -2762,23 +2782,15 @@ CAST_FUNC_NAME(datetime, datetime)
{
GET_SESSION()
{
int warning = OB_SUCCESS;
int64_t in_val = child_res->get_int();
int64_t out_val = in_val;
ObObjType in_type = expr.args_[0]->datum_meta_.type_;
ObObjType out_type = expr.datum_meta_.type_;
if (ObDateTimeType == in_type && ObTimestampType == out_type) {
if (OB_FAIL(ObTimeConverter::datetime_to_timestamp(in_val, session->get_timezone_info(), out_val))) {
LOG_WARN("datetime to timestamp failed", K(ret), K(in_val), K(out_val));
if (OB_ERR_UNEXPECTED_TZ_TRANSITION == ret) {
ret = OB_INVALID_DATE_VALUE;
} else if (OB_INVALID_DATE_VALUE == ret) {
if (CM_IS_WARN_ON_FAIL(expr.extra_)) {
warning = OB_INVALID_DATE_VALUE;
ret = OB_SUCCESS;
}
}
}
ret = ObTimeConverter::datetime_to_timestamp(in_val,
session->get_timezone_info(),
out_val);
ret = OB_ERR_UNEXPECTED_TZ_TRANSITION == ret ? OB_INVALID_DATE_VALUE : ret;
} else if (ObTimestampType == in_type && ObDateTimeType == out_type) {
ret = ObTimeConverter::timestamp_to_datetime(out_val, session->get_timezone_info(), out_val);
}
@ -3227,6 +3239,21 @@ CAST_FUNC_NAME(year, string)
return ret;
}
CAST_FUNC_NAME(year, date)
{
EVAL_ARG()
{
uint8_t in_val = child_res->get_uint8();
int64_t val_int = 0;
if (OB_FAIL(common_year_int(expr, ObIntType, in_val, val_int))) {
LOG_WARN("common_year_int failed", K(ret), K(in_val));
} else if (OB_FAIL(common_int_date(expr, val_int, res_datum))) {
LOG_WARN("common_int_date failed", K(ret), K(val_int));
}
}
return ret;
}
CAST_FUNC_NAME(year, bit)
{
EVAL_ARG()
@ -3814,6 +3841,26 @@ CAST_FUNC_NAME(time, datetime)
return ret;
}
CAST_FUNC_NAME(time, date)
{
EVAL_ARG()
{
GET_SESSION()
{
int32_t out_val = 0;
ObPhysicalPlanCtx *phy_plan_ctx = ctx.exec_ctx_.get_physical_plan_ctx();
int64_t cur_time = phy_plan_ctx ? phy_plan_ctx->get_cur_time().get_datetime() : 0;
if (OB_FAIL(ObTimeConverter::datetime_to_date(cur_time, session->get_timezone_info(),
out_val))) {
LOG_WARN("datetime_to_date failed", K(ret), K(cur_time));
} else {
res_datum.set_date(out_val);
}
}
}
return ret;
}
CAST_FUNC_NAME(time, string)
{
EVAL_ARG()
@ -7021,7 +7068,7 @@ ObExpr::EvalFunc OB_DATUM_CAST_MYSQL_IMPLICIT[ObMaxTC][ObMaxTC] = {
time_double, /*double*/
time_number, /*number*/
time_datetime, /*datetime*/
cast_not_support, /*date*/
time_date, /*date*/
cast_eval_arg, /*time*/
cast_not_support, /*year*/
time_string, /*string*/
@ -7046,7 +7093,7 @@ ObExpr::EvalFunc OB_DATUM_CAST_MYSQL_IMPLICIT[ObMaxTC][ObMaxTC] = {
year_double, /*double*/
year_number, /*number*/
cast_not_support, /*datetime*/
cast_not_support, /*date*/
year_date, /*date*/
cast_not_support, /*time*/
cast_eval_arg, /*year*/
year_string, /*string*/
@ -7522,10 +7569,29 @@ int ob_datum_to_ob_time_with_date(const ObDatum& datum, const ObObjType type, co
ret = ObTimeConverter::str_to_ob_time_with_date(datum.get_string(), ob_time, &res_scale, is_dayofmonth);
break;
}
case ObNumberTC: {
int64_t int_part = 0;
int64_t dec_part = 0;
const number::ObNumber num(datum.get_number());
if (num.is_negative()) {
ret = OB_INVALID_DATE_FORMAT;
LOG_WARN("invalid date format", K(ret), K(num));
} else if (!num.is_int_parts_valid_int64(int_part, dec_part)) {
ret = OB_INVALID_DATE_FORMAT;
LOG_WARN("invalid date format", K(ret), K(num));
} else {
ret = ObTimeConverter::int_to_ob_time_with_date(int_part, ob_time, is_dayofmonth);
if (OB_SUCC(ret)) {
ob_time.parts_[DT_USEC] = (dec_part + 500) / 1000;
}
}
break;
}
default: {
ret = OB_NOT_SUPPORTED;
}
}
LOG_DEBUG("end ob_datum_to_ob_time_with_date", K(type), K(cur_ts_value), K(ob_time), K(ret));
return ret;
}
@ -7583,10 +7649,32 @@ int ob_datum_to_ob_time_without_date(
}
break;
}
case ObNumberTC: {
number::ObNumber num(datum.get_number());
const char *num_format = num.format();
if (OB_ISNULL(num_format)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("number format value is null", K(ret));
} else {
ObString num_str(num_format);
if (OB_FAIL(ObTimeConverter::str_to_ob_time_without_date(num_str, ob_time))) {
LOG_WARN("str to obtime without date failed", K(ret));
} else {
int64_t value = ObTimeConverter::ob_time_to_time(ob_time);
int64_t tmp_value = value;
ObTimeConverter::time_overflow_trunc(value);
if (value != tmp_value) {
ObTimeConverter::time_to_ob_time(value, ob_time);
}
}
}
break;
}
default: {
ret = OB_NOT_SUPPORTED;
}
}
LOG_DEBUG("end ob_datum_to_ob_time_without_date", K(type), K(ob_time), K(ret));
return ret;
}