diff --git a/be/src/vec/functions/function_date_or_datetime_computation.h b/be/src/vec/functions/function_date_or_datetime_computation.h index dc119821be..6c707c4b1c 100644 --- a/be/src/vec/functions/function_date_or_datetime_computation.h +++ b/be/src/vec/functions/function_date_or_datetime_computation.h @@ -289,15 +289,25 @@ struct TimeDiffImpl { static constexpr auto name = "timediff"; static constexpr auto is_nullable = false; + static constexpr int64_t limit_value = 3020399000000; // 838:59:59 convert to microsecond static inline ReturnType::FieldType execute(const ArgType1& t0, const ArgType2& t1, bool& is_null) { const auto& ts0 = reinterpret_cast(t0); const auto& ts1 = reinterpret_cast(t1); is_null = !ts0.is_valid_date() || !ts1.is_valid_date(); if constexpr (UsingTimev2) { - return ts0.microsecond_diff(ts1); + // refer to https://dev.mysql.com/doc/refman/5.7/en/time.html + // the time type value between '-838:59:59' and '838:59:59', so the return value should limited + int64_t diff_m = ts0.microsecond_diff(ts1); + if (diff_m > limit_value) { + return (double)limit_value; + } else if (diff_m < -1 * limit_value) { + return (double)(-1 * limit_value); + } else { + return (double)diff_m; + } } else { - return (1000 * 1000) * ts0.second_diff(ts1); + return (double)((1000 * 1000) * ts0.second_diff(ts1)); } } static DataTypes get_variadic_argument_types() { diff --git a/be/src/vec/runtime/vdatetime_value.h b/be/src/vec/runtime/vdatetime_value.h index 7b138b2bc3..54dc368f62 100644 --- a/be/src/vec/runtime/vdatetime_value.h +++ b/be/src/vec/runtime/vdatetime_value.h @@ -1119,13 +1119,13 @@ public: return (daynr() - rhs.daynr()) * SECOND_PER_HOUR * HOUR_PER_DAY + time_part_diff(rhs); } + // used by INT microseconds_diff(DATETIME enddate, DATETIME startdate) + // return it's int type, so shouldn't have any limit. + // when used by TIME TIMEDIFF(DATETIME expr1, DATETIME expr2), it's return time type, should have limited. template - double microsecond_diff(const RHS& rhs) const { + int64_t microsecond_diff(const RHS& rhs) const { int64_t diff_m = (daynr() - rhs.daynr()) * SECOND_PER_HOUR * HOUR_PER_DAY * 1000 * 1000 + time_part_diff_microsecond(rhs); - if (diff_m > (int64_t)3020399 * 1000 * 1000) { - diff_m = (int64_t)3020399 * 1000 * 1000; - } return diff_m; } diff --git a/docs/en/docs/sql-manual/sql-functions/date-time-functions/timediff.md b/docs/en/docs/sql-manual/sql-functions/date-time-functions/timediff.md index 156fb49de7..505b2197b4 100644 --- a/docs/en/docs/sql-manual/sql-functions/date-time-functions/timediff.md +++ b/docs/en/docs/sql-manual/sql-functions/date-time-functions/timediff.md @@ -34,8 +34,8 @@ under the License. TIMEDIFF returns the difference between two DATETIMEs The TIMEDIFF function returns the result of expr1 - expr2 expressed as a time value, with a return value of TIME type - -The results are limited to TIME values ranging from - 838:59:59 to 838:59:59. +Due to the valid range of TIME type being '-838:59:59' to '838:59:59', +So when the return value of the calculation result is less than the left boundary or greater than the right boundary, the corresponding boundary value will be taken. #### example @@ -60,6 +60,13 @@ mysql> SELECT TIMEDIFF('2019-01-01 00:00:00', NULL); +---------------------------------------+ | NULL | +---------------------------------------+ + +mysql >SELECT timediff('2020-02-02 15:30:00', '1951-02-16 15:27:00') as res; ++-----------+ +| res | ++-----------+ +| 838:59:59 | ++-----------+ ``` ### keywords TIMEDIFF diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/date-time-functions/timediff.md b/docs/zh-CN/docs/sql-manual/sql-functions/date-time-functions/timediff.md index c1d1a107d5..7fd018a3f4 100644 --- a/docs/zh-CN/docs/sql-manual/sql-functions/date-time-functions/timediff.md +++ b/docs/zh-CN/docs/sql-manual/sql-functions/date-time-functions/timediff.md @@ -33,7 +33,8 @@ under the License. TIMEDIFF返回两个DATETIME之间的差值 -TIMEDIFF函数返回表示为时间值的expr1 - expr2的结果,返回值为TIME类型 +TIMEDIFF函数返回表示为时间值的expr1 - expr2的结果,返回值为TIME类型, 由于TIME类型的合法有效范围为'-838:59:59' to '838:59:59', +所以当计算结果的返回值小于左边界或大于右边界时,会取对应的边界值. ### example @@ -58,6 +59,13 @@ mysql> SELECT TIMEDIFF('2019-01-01 00:00:00', NULL); +---------------------------------------+ | NULL | +---------------------------------------+ + +mysql >SELECT timediff('2020-02-02 15:30:00', '1951-02-16 15:27:00') as res; ++-----------+ +| res | ++-----------+ +| 838:59:59 | ++-----------+ ``` ### keywords diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java index bfc32cc33e..07357d9852 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java @@ -1795,12 +1795,6 @@ public class SessionVariable implements Serializable, Writable { default: break; } - randomInt = random.nextInt(2); - if (randomInt % 2 == 0) { - this.enableFoldConstantByBe = false; - } else { - this.enableFoldConstantByBe = true; - } switch (Config.pull_request_id % 3) { case 0: @@ -1838,8 +1832,10 @@ public class SessionVariable implements Serializable, Writable { if (Config.pull_request_id > 0) { if (Config.pull_request_id % 2 == 1) { this.batchSize = 4064; + this.enableFoldConstantByBe = true; } else { this.batchSize = 50; + this.enableFoldConstantByBe = false; } } }