Bug#19844: time_format in Union truncates values

time_format() claimed %H and %k would return at most two digits
(hours 0-23), but this coincided neither with actual behaviour
nor with docs.  this is not visible in simple queries; forcing
a temp-table is probably the easiest way to see this.  adjusted
the return-length appropriately; the alternative would be to
adjust the docs to say that behaviour for > 99 hours is undefined.
---
Bug#19844: time_format in Union truncates values

time_format() claimed %H and %k would return at most two digits
(hours 0-23), but this coincided neither with actual behaviour
nor with docs.  this is not visible in simple queries; forcing
a temp-table is probably the easiest way to see this.  adjusted
the return-length appropriately; the alternative would be to
adjust the docs to say that behaviour for > 99 hours is undefined.
parent 820f14b1
...@@ -695,3 +695,24 @@ t1 CREATE TABLE `t1` ( ...@@ -695,3 +695,24 @@ t1 CREATE TABLE `t1` (
`from_unixtime(1) + 0` double(23,6) default NULL `from_unixtime(1) + 0` double(23,6) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H)
union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H);
H
120
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%k') As H)
union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%k') As H);
H
120
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%H') As H)
union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%H') As H);
H
05
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H)
union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H);
H
5
End of 4.1 tests
...@@ -368,4 +368,22 @@ create table t1 select now() - now(), curtime() - curtime(), ...@@ -368,4 +368,22 @@ create table t1 select now() - now(), curtime() - curtime(),
show create table t1; show create table t1;
drop table t1; drop table t1;
# End of 4.1 tests #
# Bug #19844 time_format in Union truncates values
#
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H)
union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H);
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%k') As H)
union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%k') As H);
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%H') As H)
union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%H') As H);
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H)
union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H);
--echo End of 4.1 tests
...@@ -1600,14 +1600,12 @@ uint Item_func_date_format::format_length(const String *format) ...@@ -1600,14 +1600,12 @@ uint Item_func_date_format::format_length(const String *format)
case 'u': /* week (00..52), where week starts with Monday */ case 'u': /* week (00..52), where week starts with Monday */
case 'V': /* week 1..53 used with 'x' */ case 'V': /* week 1..53 used with 'x' */
case 'v': /* week 1..53 used with 'x', where week starts with Monday */ case 'v': /* week 1..53 used with 'x', where week starts with Monday */
case 'H': /* hour (00..23) */
case 'y': /* year, numeric, 2 digits */ case 'y': /* year, numeric, 2 digits */
case 'm': /* month, numeric */ case 'm': /* month, numeric */
case 'd': /* day (of the month), numeric */ case 'd': /* day (of the month), numeric */
case 'h': /* hour (01..12) */ case 'h': /* hour (01..12) */
case 'I': /* --||-- */ case 'I': /* --||-- */
case 'i': /* minutes, numeric */ case 'i': /* minutes, numeric */
case 'k': /* hour ( 0..23) */
case 'l': /* hour ( 1..12) */ case 'l': /* hour ( 1..12) */
case 'p': /* locale's AM or PM */ case 'p': /* locale's AM or PM */
case 'S': /* second (00..61) */ case 'S': /* second (00..61) */
...@@ -1616,6 +1614,10 @@ uint Item_func_date_format::format_length(const String *format) ...@@ -1616,6 +1614,10 @@ uint Item_func_date_format::format_length(const String *format)
case 'e': /* day (0..31) */ case 'e': /* day (0..31) */
size += 2; size += 2;
break; break;
case 'k': /* hour ( 0..23) */
case 'H': /* hour (00..23; value > 23 OK, padding always 2-digit) */
size += 7; /* docs allow > 23, range depends on sizeof(unsigned int) */
break;
case 'r': /* time, 12-hour (hh:mm:ss [AP]M) */ case 'r': /* time, 12-hour (hh:mm:ss [AP]M) */
size += 11; size += 11;
break; break;
......
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