diff --git a/deps/oblib/src/lib/timezone/ob_time_convert.cpp b/deps/oblib/src/lib/timezone/ob_time_convert.cpp index 4baf006bee..5ab3e95282 100644 --- a/deps/oblib/src/lib/timezone/ob_time_convert.cpp +++ b/deps/oblib/src/lib/timezone/ob_time_convert.cpp @@ -5308,6 +5308,11 @@ int ObTimeConverter::check_dfm_deterministic(const ObString format, return ret; } +int32_t ObTimeConverter::get_days_of_month(int32_t year, int32_t month) +{ + return DAYS_PER_MON[IS_LEAP_YEAR(year)][month]; +} + int ObTimeConverter::set_ob_time_part_directly(ObTime &ob_time, int64_t &conflict_bitset, const int64_t part_offset, const int32_t part_value) { int ret = OB_SUCCESS; diff --git a/deps/oblib/src/lib/timezone/ob_time_convert.h b/deps/oblib/src/lib/timezone/ob_time_convert.h index 337e759ed4..14a51a4d59 100644 --- a/deps/oblib/src/lib/timezone/ob_time_convert.h +++ b/deps/oblib/src/lib/timezone/ob_time_convert.h @@ -585,7 +585,7 @@ public: static int check_dfm_deterministic(const ObString format, const ObCollationType format_coll_type, const bool need_tz, bool &complete); - + static int32_t get_days_of_month(int32_t year, int32_t month); struct ObTimeDigits { ObTimeDigits() : ptr_(NULL), len_(0), value_(0) diff --git a/src/sql/engine/expr/ob_expr_timestamp_add.cpp b/src/sql/engine/expr/ob_expr_timestamp_add.cpp index 9a0abff224..ec9df2632f 100644 --- a/src/sql/engine/expr/ob_expr_timestamp_add.cpp +++ b/src/sql/engine/expr/ob_expr_timestamp_add.cpp @@ -138,6 +138,10 @@ int ObExprTimeStampAdd::calc(const int64_t unit_value, } else { ot.parts_[DT_YEAR] = month / 12; ot.parts_[DT_MON] = month % 12 + 1; + int32_t days = ObTimeConverter::get_days_of_month(ot.parts_[DT_YEAR], ot.parts_[DT_MON]); + if (ot.parts_[DT_MDAY] > days) { + ot.parts_[DT_MDAY] = days; + } ot.parts_[DT_DATE] = ObTimeConverter::ob_time_to_date(ot); if (OB_FAIL(ObTimeConverter::ob_time_to_datetime(ot, cvrt_ctx, value))) { LOG_WARN("ob time to datetime failed", K(ret));