cherry-pick bugfix from 3.1 to open source branch
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user