[bug](function) fix milliseconds_diff function return wrong result (#32897)
* [bug](function) fix milliseconds_diff function return wrong result
This commit is contained in:
@ -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<const DateValueType1&>(t0);
|
||||
const auto& ts1 = reinterpret_cast<const DateValueType2&>(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() {
|
||||
|
||||
@ -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 <typename RHS>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user