Commit 4f1dbac6 authored by Sergei Golubchik's avatar Sergei Golubchik

lp:731815 Crash/valgrind warning Item::send with 5.1-micro

Two problems:
* Item_func_convert_tz() did not tell args[0] that it needs
  TIME_NO_ZERO_IN_DATE result
* Item_func_timediff did not respect fuzzy_date limitations,
  truncated seconds when casting to signed long, resulting in
  invalid time value (hours, seconds = (uint)-1).
parent 3a0774b1
...@@ -1468,3 +1468,11 @@ Warnings: ...@@ -1468,3 +1468,11 @@ Warnings:
Warning 1292 Incorrect datetime value: '0' Warning 1292 Incorrect datetime value: '0'
Warning 1292 Incorrect datetime value: '0' Warning 1292 Incorrect datetime value: '0'
drop table t1; drop table t1;
select timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' as datetime));
timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' as datetime))
-838:59:59.999999
Warnings:
Warning 1292 Truncated incorrect time value: '-596523:14:07'
select convert_tz(timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' as datetime)), 'UTC', 'Europe/Moscow');
convert_tz(timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' as datetime)), 'UTC', 'Europe/Moscow')
NULL
...@@ -910,3 +910,9 @@ select last_day(f2) from t1; ...@@ -910,3 +910,9 @@ select last_day(f2) from t1;
select last_day(f2) from t1 where last_day(f2) is null; select last_day(f2) from t1 where last_day(f2) is null;
select * from t1 order by last_day (f2); select * from t1 order by last_day (f2);
drop table t1; drop table t1;
#
# lp:731815 Crash/valgrind warning Item::send with 5.1-micro
#
select timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' as datetime));
select convert_tz(timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' as datetime)), 'UTC', 'Europe/Moscow');
...@@ -1872,7 +1872,8 @@ bool Item_func_convert_tz::get_date(MYSQL_TIME *ltime, ...@@ -1872,7 +1872,8 @@ bool Item_func_convert_tz::get_date(MYSQL_TIME *ltime,
to_tz_cached= args[2]->const_item(); to_tz_cached= args[2]->const_item();
} }
if (from_tz==0 || to_tz==0 || get_arg0_date(ltime, TIME_NO_ZERO_DATE)) if (from_tz==0 || to_tz==0 ||
get_arg0_date(ltime, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE))
{ {
null_value= 1; null_value= 1;
return 1; return 1;
...@@ -2534,6 +2535,9 @@ bool Item_func_timediff::get_date(MYSQL_TIME *ltime, uint fuzzy_date) ...@@ -2534,6 +2535,9 @@ bool Item_func_timediff::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
l_time1.time_type != l_time2.time_type) l_time1.time_type != l_time2.time_type)
goto null_date; goto null_date;
if (fuzzy_date & TIME_NO_ZERO_IN_DATE)
goto null_date;
if (l_time1.neg != l_time2.neg) if (l_time1.neg != l_time2.neg)
l_sign= -l_sign; l_sign= -l_sign;
...@@ -2550,8 +2554,12 @@ bool Item_func_timediff::get_date(MYSQL_TIME *ltime, uint fuzzy_date) ...@@ -2550,8 +2554,12 @@ bool Item_func_timediff::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
if (l_time1.neg && (seconds || microseconds)) if (l_time1.neg && (seconds || microseconds))
l_time3.neg= 1-l_time3.neg; // Swap sign of result l_time3.neg= 1-l_time3.neg; // Swap sign of result
set_if_smaller(seconds, INT_MAX32);
calc_time_from_sec(&l_time3, (long) seconds, microseconds); calc_time_from_sec(&l_time3, (long) seconds, microseconds);
if ((fuzzy_date & TIME_NO_ZERO_DATE) && (seconds == 0) && (microseconds == 0))
goto null_date;
*ltime= l_time3; *ltime= l_time3;
check_time_range(ltime, &was_cut); check_time_range(ltime, &was_cut);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment