Below is the list of changes that have just been committed into a local
5.0 repository of alexi. When alexi does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1979 05/09/08 20:58:59 aivanov@stripped +3 -0
Fix for BUG #11655 Time values are not always checked to lie in
the TIME range
sql/item_timefunc.cc
1.94 05/09/08 20:58:50 aivanov@stripped +136 -0
Added check_time_range().
Modified Item_func_time_to_sec::val_int(),
Item_func_sec_to_time::val_str(),
Item_func_sec_to_time::val_int(),
Item_func_add_time::val_str(),
Item_func_make_time::val_str()
mysql-test/t/func_time.test
1.38 05/09/08 20:58:50 aivanov@stripped +20 -0
Added testcases for bug #11655
mysql-test/r/func_time.result
1.46 05/09/08 20:58:50 aivanov@stripped +42 -0
Fixed some testcases results (bug #11655)
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: aivanov
# Host: mysql.creware.com
# Root: /home/alexi/dev/mysql-5.0-0
--- 1.93/sql/item_timefunc.cc 2005-08-25 02:50:54 +04:00
+++ 1.94/sql/item_timefunc.cc 2005-09-08 20:58:50 +04:00
@@ -49,6 +49,130 @@
/*
+ Check (hour,minute,second) triplet to lie in the TIME range
+
+ SYNOPSIS:
+ check_time_range()
+ hour pointer to hours value
+ minute pointer to minutes value
+ second pointer to seconds value
+ warn true if out of the TIME range warning should be produced
+
+ DESCRIPTION
+ If the triplet lies outside the range [-838:59:59, 838:59:59]
+ the function sets it to the closest endpoint of the range and
+ in case of warn=true produces warning.
+
+ RETURN
+ 0 the triplet lies in the range
+ 1 the triplet lies outside the range and is set to new value
+*/
+
+inline int check_time_range(long *hour, long *minute, long *second, bool warn)
+{
+ if (abs(*hour) < 839)
+ return 0;
+
+ if (warn)
+ {
+ char buf[3*sizeof(long)+8];
+ my_snprintf(buf, sizeof(buf)-1, "%d:%02u:%02u", *hour, *minute, *second);
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE, ER(ER_TRUNCATED_WRONG_VALUE), "TIME", buf);
+ }
+
+ *hour= (*hour < 0) ? -838 : 838;
+ *minute= 59;
+ *second= 59;
+ return 1;
+}
+
+
+/*
+ Check TIME value to lie in the TIME range
+
+ SYNOPSIS:
+ check_time_range()
+ time pointer to TIME value
+ warn true if out of the TIME range warning should be produced
+
+ DESCRIPTION
+ If the time value lies outside the range [-838:59:59, 838:59:59]
+ the function sets it to the closest endpoint of the range and
+ in case of warn=true produces warning.
+
+ RETURN
+ 0 the time value lies in the range
+ 1 the time value lies outside the range and is set to new value
+*/
+
+inline int check_time_range(TIME *time, bool warn)
+{
+ if (time->time_type != MYSQL_TIMESTAMP_TIME)
+ return 0;
+
+ long hour= time->hour + (24*time->day);
+ if ((hour < 839) &&
+ (hour != 838 || time->minute != 59 || time->second != 59 ||
+ !time->second_part))
+ return 0;
+
+ if (warn)
+ {
+ char buf[9*sizeof(long) + 11];
+ my_snprintf(buf, sizeof(buf)-1, "%s%u %u:%02u:%02u.%u",
+ time->neg ? "- " : "", time->day, time->hour,
+ time->minute, time->second, time->second_part);
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE, ER(ER_TRUNCATED_WRONG_VALUE), "TIME", buf);
+ }
+
+ time->day= 0;
+ time->hour= 838;
+ time->minute= 59;
+ time->second= 59;
+ time->second_part= 0;
+ return 1;
+}
+
+
+/*
+ Check seconds to lie in the TIME range
+
+ SYNOPSIS:
+ check_time_range()
+ seconds pointer to seconds value
+ warn true if out of the TIME range warning should be produced
+
+ DESCRIPTION
+ If the seconds value lies outside the range [-838:59:59, 838:59:59]
+ the function sets it to the closest endpoint of the range and
+ in case of warn=true produces warning.
+
+ RETURN
+ 0 the seconds value lies in the range
+ 1 the seconds value lies outside the range and is set to new value
+*/
+
+inline int check_time_range(longlong *seconds, bool warn)
+{
+ if (abs(*seconds) <= 3020399) /*[-838:59:59, 838:59:59]*/
+ return 0;
+
+ if (warn)
+ {
+ char buf[22];
+ longlong10_to_str(*seconds, buf, -10);
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE, ER(ER_TRUNCATED_WRONG_VALUE), "TIME", buf);
+ }
+
+ *seconds= (*seconds < 0) ? -3020399 : 3020399;
+ return 0;
+}
+
+
+/*
OPTIMIZATION TODO:
- Replace the switch with a function that should be called for each
date type.
@@ -1103,6 +1227,7 @@
TIME ltime;
longlong seconds;
(void) get_arg0_time(<ime);
+ check_time_range(<ime, 1);
seconds=ltime.hour*3600L+ltime.minute*60+ltime.second;
return ltime.neg ? -seconds : seconds;
}
@@ -1568,6 +1693,8 @@
return (String*) 0;
}
+ check_time_range(&seconds, 1);
+
ltime.neg= 0;
if (seconds < 0)
{
@@ -1593,6 +1720,7 @@
longlong sign=1;
if ((null_value=args[0]->null_value))
return 0;
+ check_time_range(&seconds, 1);
if (seconds < 0)
{
seconds= -seconds;
@@ -2535,6 +2663,9 @@
goto null_date;
is_time= (l_time1.time_type == MYSQL_TIMESTAMP_TIME);
}
+ check_time_range(&l_time1, 1);
+ check_time_range(&l_time2, 1);
+
if (l_time1.neg != l_time2.neg)
l_sign= -l_sign;
@@ -2566,6 +2697,9 @@
}
l_time3.hour+= days*24;
+ l_time3.day= 0;
+ l_time3.time_type= MYSQL_TIMESTAMP_TIME;
+ check_time_range(&l_time3, 1);
if (!make_datetime(l_time1.second_part || l_time2.second_part ?
TIME_MICROSECOND : TIME_ONLY,
&l_time3, str))
@@ -2668,6 +2802,8 @@
second > 59 || second < 0 ||
str->alloc(19))))
return 0;
+
+ check_time_range(&hour, &minute, &second, 1);
ltime.neg= 0;
if (hour < 0)
--- 1.45/mysql-test/r/func_time.result 2005-08-25 02:50:54 +04:00
+++ 1.46/mysql-test/r/func_time.result 2005-09-08 20:58:50 +04:00
@@ -760,3 +760,45 @@
@a != @b
1
drop procedure t_sysdate;
+SELECT SEC_TO_TIME(3020399);
+SEC_TO_TIME(3020399)
+838:59:59
+SELECT SEC_TO_TIME(3300000);
+SEC_TO_TIME(3300000)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect TIME value: '3300000'
+SELECT TIME_TO_SEC('838:59:59');
+TIME_TO_SEC('838:59:59')
+3020399
+SELECT TIME_TO_SEC('916:40:00');
+TIME_TO_SEC('916:40:00')
+3020399
+Warnings:
+Warning 1292 Truncated incorrect TIME value: '0 916:40:00.0'
+SELECT MAKETIME(916,40,00);
+MAKETIME(916,40,00)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect TIME value: '916:40:00'
+SELECT ADDTIME('500:00:00', '416:40:00');
+ADDTIME('500:00:00', '416:40:00')
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect TIME value: '0 916:40:00.0'
+SELECT ADDTIME('838:59:59', '-416:40:00');
+ADDTIME('838:59:59', '-416:40:00')
+422:19:59
+SELECT ADDTIME('916:40:00', '-416:40:00');
+ADDTIME('916:40:00', '-416:40:00')
+422:19:59
+Warnings:
+Warning 1292 Truncated incorrect TIME value: '0 916:40:00.0'
+SELECT SUBTIME('838:59:59', '416:40:00');
+SUBTIME('838:59:59', '416:40:00')
+422:19:59
+SELECT SUBTIME('916:40:00', '416:40:00');
+SUBTIME('916:40:00', '416:40:00')
+422:19:59
+Warnings:
+Warning 1292 Truncated incorrect TIME value: '0 916:40:00.0'
--- 1.37/mysql-test/t/func_time.test 2005-08-25 02:50:54 +04:00
+++ 1.38/mysql-test/t/func_time.test 2005-09-08 20:58:50 +04:00
@@ -404,4 +404,24 @@
call t_sysdate();
drop procedure t_sysdate;
+#
+# Test for bug #11655: time is not always checked to lie in the TIME range
+#
+
+SELECT SEC_TO_TIME(3020399);
+SELECT SEC_TO_TIME(3300000);
+
+SELECT TIME_TO_SEC('838:59:59');
+SELECT TIME_TO_SEC('916:40:00');
+
+SELECT MAKETIME(916,40,00);
+
+SELECT ADDTIME('500:00:00', '416:40:00');
+
+SELECT ADDTIME('838:59:59', '-416:40:00');
+SELECT ADDTIME('916:40:00', '-416:40:00');
+
+SELECT SUBTIME('838:59:59', '416:40:00');
+SELECT SUBTIME('916:40:00', '416:40:00');
+
# End of 5.0 tests
| Thread |
|---|
| • bk commit into 5.0 tree (aivanov:1.1979) BUG#11655 | Alex Ivanov | 8 Sep |