fix some bugs

This commit is contained in:
sdc
2024-05-06 02:46:46 +00:00
committed by ob-robot
parent 8a3aead006
commit 40d1a1ecc1
7 changed files with 51 additions and 70 deletions

View File

@ -1802,6 +1802,9 @@ int ObTimeConverter::int_to_ob_time_without_date(int64_t time_second, ObTime &ob
} else { } else {
parts[DT_HOUR] = TIME_MAX_HOUR + 1; parts[DT_HOUR] = TIME_MAX_HOUR + 1;
} }
if (OB_SUCC(ret)) {
adjust_ob_time(ob_time);
}
UNUSED(mode); UNUSED(mode);
return ret; return ret;
} }
@ -1990,6 +1993,7 @@ int ObTimeConverter::str_to_ob_time_with_date(const ObString &str, ObTime &ob_ti
LOG_WARN("datetime is invalid or out of range", LOG_WARN("datetime is invalid or out of range",
K(ret), K(str), K(ob_time), K(date_sql_mode), KCSTRING(lbt())); K(ret), K(str), K(ob_time), K(date_sql_mode), KCSTRING(lbt()));
} else { } else {
adjust_ob_time(ob_time);
ob_time.parts_[DT_DATE] = ob_time_to_date(ob_time); ob_time.parts_[DT_DATE] = ob_time_to_date(ob_time);
} }
if (NULL != scale) { if (NULL != scale) {
@ -2152,17 +2156,11 @@ int ObTimeConverter::str_to_ob_time_without_date(const ObString &str, ObTime &ob
} }
if (OB_SUCC(ret) && OB_FAIL(validate_time(ob_time))) { if (OB_SUCC(ret) && OB_FAIL(validate_time(ob_time))) {
LOG_WARN("time value is invalid or out of range", K(ret), K(str)); LOG_WARN("time value is invalid or out of range", K(ret), K(str));
} else {
// '2:59:59.9999999' ---> '03:00:00.000000'
const int64_t *part_max = DT_PART_BASE;
for (int i = DATETIME_PART_CNT - 1; OB_SUCC(ret) && i > DATE_PART_CNT; i--) {
if (ob_time.parts_[i] == part_max[i]) {
ob_time.parts_[i] = 0;
ob_time.parts_[i - 1]++;
}
}
} }
} }
if (OB_SUCC(ret)) {
adjust_ob_time(ob_time);
}
} }
} }
return ret; return ret;
@ -3136,6 +3134,26 @@ int ObTimeConverter::data_fmt_s(char *buffer, int64_t buf_len, int64_t &pos, con
return ret; return ret;
} }
void ObTimeConverter::adjust_ob_time(ObTime &ob_time)
{
// '2:59:59.9999995' ---> '03:00:00.000000'
for (int i = DATETIME_PART_CNT - 1; i > DT_MDAY; i--) {
if (ob_time.parts_[i] == DT_PART_BASE[i]) {
ob_time.parts_[i] -= DT_PART_BASE[i];
ob_time.parts_[i - 1]++;
}
}
int32_t days = DAYS_PER_MON[IS_LEAP_YEAR(ob_time.parts_[DT_YEAR])][ob_time.parts_[DT_MON]];
if (ob_time.parts_[DT_MDAY] > days) {
ob_time.parts_[DT_MDAY] -= days;
ob_time.parts_[DT_MON]++;
}
if (ob_time.parts_[DT_MON] > 12) {
ob_time.parts_[DT_MON] -= 12;
ob_time.parts_[DT_YEAR]++;
}
}
/** /**
* @brief ObTimeConverter::str_to_ob_time_oracle_strict * @brief ObTimeConverter::str_to_ob_time_oracle_strict
* convert str to ob_time according to oracle literal format of DATE or TIMESTAMP * convert str to ob_time according to oracle literal format of DATE or TIMESTAMP

View File

@ -581,6 +581,8 @@ public:
static int data_fmt_nd(char *buffer, int64_t buf_len, int64_t &pos, const int64_t n, int64_t target, bool has_fm_flag = false); static int data_fmt_nd(char *buffer, int64_t buf_len, int64_t &pos, const int64_t n, int64_t target, bool has_fm_flag = false);
static int data_fmt_d(char *buffer, int64_t buf_len, int64_t &pos, int64_t target); static int data_fmt_d(char *buffer, int64_t buf_len, int64_t &pos, int64_t target);
static int data_fmt_s(char *buffer, int64_t buf_len, int64_t &pos, const char *ptr); static int data_fmt_s(char *buffer, int64_t buf_len, int64_t &pos, const char *ptr);
// check each part of ObTime and carry if necessary.
static void adjust_ob_time(ObTime &ot);
public: public:
// other functions. // other functions.

View File

@ -2396,7 +2396,7 @@ TEST(ObTimeConvertTest, str_to_ob_time)
STR_TO_OB_TIME_FAIL("2015-05-30 24:12:13.1415", DT_TYPE_DATETIME); STR_TO_OB_TIME_FAIL("2015-05-30 24:12:13.1415", DT_TYPE_DATETIME);
STR_TO_OB_TIME_FAIL("2015-05-30 11:60:13.1415", DT_TYPE_DATETIME); STR_TO_OB_TIME_FAIL("2015-05-30 11:60:13.1415", DT_TYPE_DATETIME);
STR_TO_OB_TIME_FAIL("2015-05-30 11:12:60.1415", DT_TYPE_DATETIME); STR_TO_OB_TIME_FAIL("2015-05-30 11:12:60.1415", DT_TYPE_DATETIME);
STR_TO_OB_TIME_SUCC("2015-12-31 23:59:59.9999999", DT_TYPE_DATETIME, 2015, 12, 31, 23, 59, 59, 1000000); STR_TO_OB_TIME_SUCC("2015-12-31 23:59:59.9999999", DT_TYPE_DATETIME, 2016, 1, 1, 00, 00, 00, 000000);
STR_TO_OB_TIME_FAIL("10", DT_TYPE_DATETIME); STR_TO_OB_TIME_FAIL("10", DT_TYPE_DATETIME);
STR_TO_OB_TIME_FAIL("101", DT_TYPE_DATETIME); STR_TO_OB_TIME_FAIL("101", DT_TYPE_DATETIME);
STR_TO_OB_TIME_FAIL("1011", DT_TYPE_DATETIME); STR_TO_OB_TIME_FAIL("1011", DT_TYPE_DATETIME);
@ -2596,7 +2596,7 @@ TEST(ObTimeConvertTest, str_to_ob_time)
STR_TO_OB_TIME_FAIL("2015-05-30 24:12:13.1415", DT_TYPE_DATE); STR_TO_OB_TIME_FAIL("2015-05-30 24:12:13.1415", DT_TYPE_DATE);
STR_TO_OB_TIME_FAIL("2015-05-30 11:60:13.1415", DT_TYPE_DATE); STR_TO_OB_TIME_FAIL("2015-05-30 11:60:13.1415", DT_TYPE_DATE);
STR_TO_OB_TIME_FAIL("2015-05-30 11:12:60.1415", DT_TYPE_DATE); STR_TO_OB_TIME_FAIL("2015-05-30 11:12:60.1415", DT_TYPE_DATE);
STR_TO_OB_TIME_SUCC("2015-12-31 23:59:59.9999999", DT_TYPE_DATE, 2015, 12, 31, -1, -1, -1, -1); STR_TO_OB_TIME_SUCC("2015-12-31 23:59:59.9999999", DT_TYPE_DATE, 2016, 1, 1, -1, -1, -1, -1);
STR_TO_OB_TIME_FAIL("10", DT_TYPE_DATE); STR_TO_OB_TIME_FAIL("10", DT_TYPE_DATE);
STR_TO_OB_TIME_FAIL("101", DT_TYPE_DATE); STR_TO_OB_TIME_FAIL("101", DT_TYPE_DATE);
STR_TO_OB_TIME_FAIL("1011", DT_TYPE_DATE); STR_TO_OB_TIME_FAIL("1011", DT_TYPE_DATE);
@ -2796,7 +2796,7 @@ TEST(ObTimeConvertTest, str_to_ob_time)
STR_TO_OB_TIME_FAIL("2015-05-30 24:12:13.1415", DT_TYPE_TIME); STR_TO_OB_TIME_FAIL("2015-05-30 24:12:13.1415", DT_TYPE_TIME);
STR_TO_OB_TIME_FAIL("2015-05-30 11:60:13.1415", DT_TYPE_TIME); STR_TO_OB_TIME_FAIL("2015-05-30 11:60:13.1415", DT_TYPE_TIME);
STR_TO_OB_TIME_FAIL("2015-05-30 11:12:60.1415", DT_TYPE_TIME); STR_TO_OB_TIME_FAIL("2015-05-30 11:12:60.1415", DT_TYPE_TIME);
STR_TO_OB_TIME_SUCC("2015-12-31 23:59:59.9999999", DT_TYPE_TIME, -1, -1, -1, 23, 59, 59, 1000000); STR_TO_OB_TIME_SUCC("2015-12-31 23:59:59.9999999", DT_TYPE_TIME, -1, -1, -1, 0, 0, 0, 000000);
STR_TO_OB_TIME_SUCC("10", DT_TYPE_TIME, -1, -1, -1, 0, 0, 10, 0); STR_TO_OB_TIME_SUCC("10", DT_TYPE_TIME, -1, -1, -1, 0, 0, 10, 0);
STR_TO_OB_TIME_SUCC("101", DT_TYPE_TIME, -1, -1, -1, 0, 1, 1, 0); STR_TO_OB_TIME_SUCC("101", DT_TYPE_TIME, -1, -1, -1, 0, 1, 1, 0);
STR_TO_OB_TIME_SUCC("1011", DT_TYPE_TIME, -1, -1, -1, 0, 10, 11, 0); STR_TO_OB_TIME_SUCC("1011", DT_TYPE_TIME, -1, -1, -1, 0, 10, 11, 0);

View File

@ -159,6 +159,7 @@ int ob_datum_to_ob_time_with_date(const T &datum,
ret = ObTimeConverter::int_to_ob_time_with_date(int_part, ob_time, date_sql_mode); ret = ObTimeConverter::int_to_ob_time_with_date(int_part, ob_time, date_sql_mode);
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
ob_time.parts_[DT_USEC] = (dec_part + 500) / 1000; ob_time.parts_[DT_USEC] = (dec_part + 500) / 1000;
ObTimeConverter::adjust_ob_time(ob_time);
} }
} }
break; break;

View File

@ -54,27 +54,18 @@ inline int ObExprDateFormat::calc_result_type2(ObExprResType &type,
UNUSED(date); UNUSED(date);
UNUSED(format); UNUSED(format);
int ret = common::OB_SUCCESS; int ret = common::OB_SUCCESS;
// common::ObCollationType collation_connection = common::CS_TYPE_INVALID;
type.set_varchar(); type.set_varchar();
type.set_collation_type(type_ctx.get_coll_type()); type.set_collation_type(type_ctx.get_coll_type());
type.set_collation_level(common::CS_LEVEL_COERCIBLE); type.set_collation_level(common::CS_LEVEL_COERCIBLE);
type.set_length(DATETIME_MAX_LENGTH); type.set_length(DATETIME_MAX_LENGTH);
date.set_calc_collation_type(type.get_collation_type()); //for enum or set obj, we need calc type
format.set_calc_collation_type(type.get_collation_type()); if (ob_is_enum_or_set_type(date.get_type()) || ob_is_string_type(date.get_type())) {
date.set_calc_type_default_varchar();
if (OB_SUCC(ret)) { } else if (ob_is_double_tc(date.get_type()) || ob_is_float_tc(date.get_type())) {
//for enum or set obj, we need calc type date.set_calc_type(common::ObNumberType);
if (ob_is_enum_or_set_type(date.get_type())) {
date.set_calc_type(common::ObVarcharType);
} else if (ob_is_double_tc(date.get_type()) || ob_is_float_tc(date.get_type())) {
date.set_calc_type(common::ObNumberType);
}
if (ob_is_enum_or_set_type(format.get_type())) {
format.set_calc_type(common::ObVarcharType);
}
} }
format.set_calc_type_default_varchar();
return ret; return ret;
} }

View File

@ -319,10 +319,17 @@ int ObExprFromUnixTime::get_usec_from_datum(const common::ObDatum &param_datum,
LOG_WARN("failed to get number", K(ret)); LOG_WARN("failed to get number", K(ret));
} else if (OB_FAIL(param1.mul(param2, res, alloc))) { } else if (OB_FAIL(param1.mul(param2, res, alloc))) {
LOG_WARN("failed to mul", K(ret)); LOG_WARN("failed to mul", K(ret));
} else if (OB_LIKELY(res.is_valid_int64(tmp))) { } else if (OB_FAIL(res.extract_valid_int64_with_round(tmp))) {
usec_val = tmp; if (OB_DATA_OUT_OF_RANGE == ret) {
ret = OB_ERR_TRUNCATED_WRONG_VALUE;
ObString dec("DECIMAL");
const char *num_str = param2_tmp.format();
LOG_USER_ERROR(OB_ERR_TRUNCATED_WRONG_VALUE, dec.length(), dec.ptr(),
static_cast<int>(strlen(num_str)), num_str);
}
LOG_WARN("extract valid int64 with round failed", K(ret), K(res));
} else { } else {
ret = OB_ERR_TRUNCATED_WRONG_VALUE; usec_val = tmp;
} }
return ret; return ret;
} }

View File

@ -66,10 +66,10 @@ inline int ObExprTimeBase::calc_result_type1(ObExprResType &type,
type.set_precision(4); type.set_precision(4);
type.set_scale(0); type.set_scale(0);
common::ObObjTypeClass tc1 = ob_obj_type_class(type1.get_type()); common::ObObjTypeClass tc1 = ob_obj_type_class(type1.get_type());
if (common::ObEnumSetTC == tc1) { if (ob_is_enum_or_set_type(type1.get_type()) || ob_is_string_type(type1.get_type())) {
type1.set_calc_type_default_varchar(); type1.set_calc_type_default_varchar();
} else if ((common::ObFloatTC == tc1) || (common::ObDoubleTC == tc1)) { } else if ((common::ObFloatTC == tc1) || (common::ObDoubleTC == tc1)) {
type1.set_calc_type(common::ObIntType); type1.set_calc_type(common::ObNumberType);
} }
return common::OB_SUCCESS; return common::OB_SUCCESS;
} }
@ -102,60 +102,22 @@ public:
ObExprSecond(); ObExprSecond();
explicit ObExprSecond(common::ObIAllocator &alloc); explicit ObExprSecond(common::ObIAllocator &alloc);
virtual ~ObExprSecond(); virtual ~ObExprSecond();
virtual int calc_result_type1(ObExprResType &type,
ObExprResType &type1,
common::ObExprTypeCtx &type_ctx) const;
static int calc_second(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum); static int calc_second(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum);
private: private:
DISALLOW_COPY_AND_ASSIGN(ObExprSecond); DISALLOW_COPY_AND_ASSIGN(ObExprSecond);
}; };
inline int ObExprSecond::calc_result_type1(ObExprResType &type,
ObExprResType &type1,
common::ObExprTypeCtx &type_ctx) const
{
type.set_int32();
type.set_precision(4);
type.set_scale(0);
common::ObObjTypeClass tc1 = ob_obj_type_class(type1.get_type());
if ((common::ObEnumSetTC == tc1)) {
type1.set_calc_type_default_varchar();
} else if ((common::ObFloatTC == tc1) || (common::ObDoubleTC == tc1)) {
type1.set_calc_type(common::ObNumberType);
}
return common::OB_SUCCESS;
}
class ObExprMicrosecond: public ObExprTimeBase class ObExprMicrosecond: public ObExprTimeBase
{ {
public: public:
ObExprMicrosecond(); ObExprMicrosecond();
explicit ObExprMicrosecond(common::ObIAllocator &alloc); explicit ObExprMicrosecond(common::ObIAllocator &alloc);
virtual ~ObExprMicrosecond(); virtual ~ObExprMicrosecond();
virtual int calc_result_type1(ObExprResType &type,
ObExprResType &type1,
common::ObExprTypeCtx &type_ctx) const;
static int calc_microsecond(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum); static int calc_microsecond(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum);
private: private:
DISALLOW_COPY_AND_ASSIGN(ObExprMicrosecond); DISALLOW_COPY_AND_ASSIGN(ObExprMicrosecond);
}; };
inline int ObExprMicrosecond::calc_result_type1(ObExprResType &type,
ObExprResType &type1,
common::ObExprTypeCtx &type_ctx) const
{
type.set_int32();
type.set_precision(4);
type.set_scale(0);
common::ObObjTypeClass tc1 = ob_obj_type_class(type1.get_type());
if ((common::ObEnumSetTC == tc1)) {
type1.set_calc_type_default_varchar();
} else if ((common::ObFloatTC == tc1) || (common::ObDoubleTC == tc1)) {
type1.set_calc_type(common::ObNumberType);
}
return common::OB_SUCCESS;
}
class ObExprYear: public ObExprTimeBase class ObExprYear: public ObExprTimeBase
{ {
public: public: