From 39ee25b3742188026dcc0bcee60951668a4a2275 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Jan 2005 14:26:40 +0300 Subject: [PATCH 1/2] Fix for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB mode". Changed grammar rule for "type" token. Now we have one branch with optional length specification for TIMESTAMP type instead of two separate branches. mysql-test/r/type_timestamp.result: Added test case for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB mode". mysql-test/t/type_timestamp.test: Added test case for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB mode". sql/sql_yacc.yy: Changed rule for "type" token. Now we have one branch with optional length specification for TIMESTAMP type instead of two separate branches. This also gives us consistent behavior for TIMETSAMP in MAXDB mode. --- mysql-test/r/type_timestamp.result | 10 ++++++++++ mysql-test/t/type_timestamp.test | 12 ++++++++++++ sql/sql_yacc.yy | 9 +-------- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index 42fdc7e50c6..6c46d308e7e 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -422,3 +422,13 @@ max(t) 2004-01-01 01:00:00 2004-02-01 00:00:00 drop table t1; +set sql_mode='maxdb'; +create table t1 (a timestamp, b timestamp(19)); +show create table t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" datetime default NULL, + "b" datetime default NULL +) +set sql_mode=''; +drop table t1; diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index a8a0cf8703c..783e310f02d 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -286,3 +286,15 @@ insert into t1 values ('a', '2004-01-01 00:00:00'), ('a', '2004-01-01 01:00:00') ('b', '2004-02-01 00:00:00'); select max(t) from t1 group by a; drop table t1; + +# +# Test for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB +# mode". TIMESTAMP columns should be converted DATETIME columns in MAXDB +# mode regardless of whether a display width is given. +# +set sql_mode='maxdb'; +create table t1 (a timestamp, b timestamp(19)); +show create table t1; +# restore default mode +set sql_mode=''; +drop table t1; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a09694ee1e6..66f7882c4e7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1415,7 +1415,7 @@ type: | YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; } | DATE_SYM { $$=FIELD_TYPE_DATE; } | TIME_SYM { $$=FIELD_TYPE_TIME; } - | TIMESTAMP + | TIMESTAMP opt_len { if (YYTHD->variables.sql_mode & MODE_MAXDB) $$=FIELD_TYPE_DATETIME; @@ -1428,13 +1428,6 @@ type: $$=FIELD_TYPE_TIMESTAMP; } } - | TIMESTAMP '(' NUM ')' - { - LEX *lex= Lex; - lex->length= $3.str; - lex->type|= NOT_NULL_FLAG; - $$= FIELD_TYPE_TIMESTAMP; - } | DATETIME { $$=FIELD_TYPE_DATETIME; } | TINYBLOB { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_TINY_BLOB; } From d853e732b9f598671283064fef6d11ea9db1d8ca Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Jan 2005 12:18:36 +0300 Subject: [PATCH 2/2] Fix for bug #7586 "TIMEDIFF for sec+microsec not working properly". mysql-test/r/func_sapdb.result: Added test for bug #7586 "TIMEDIFF for sec+microsec not working properly". Corrected previously wrong results of couple other statements. mysql-test/t/func_sapdb.test: Added test for bug #7586 "TIMEDIFF for sec+microsec not working properly". sql/item_timefunc.cc: Item_func_timediff::val_str(): Use simplier and less error-prone implementation. Now we are counting difference between time values in microseconds and convert it to time value (instead of using seconds and taking difference in "second_part"s into account). --- mysql-test/r/func_sapdb.result | 7 +++++-- mysql-test/t/func_sapdb.test | 1 + sql/item_timefunc.cc | 30 ++++++++++-------------------- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index cf2bd687115..c74d6fc5a4e 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -97,13 +97,16 @@ timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") 46:58:57.999999 select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002"); timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") --23:59:59.999999 +-24:00:00.000001 select timediff("1997-12-31 23:59:59.000001","23:59:59.000001"); timediff("1997-12-31 23:59:59.000001","23:59:59.000001") NULL select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001"); timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001") -00:00:00.000001 +select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50"); +timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50") +-00:00:00.000001 select maketime(10,11,12); maketime(10,11,12) 10:11:12 @@ -175,7 +178,7 @@ f8 date YES NULL f9 time YES NULL select * from t1; f1 f2 f3 f4 f5 f6 f7 f8 f9 -1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -23:59:59 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59 +1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -24:00:00 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59 create table test(t1 datetime, t2 time, t3 time, t4 datetime); insert into test values ('2001-01-01 01:01:01', '01:01:01', null, '2001-02-01 01:01:01'), diff --git a/mysql-test/t/func_sapdb.test b/mysql-test/t/func_sapdb.test index 2ae3c438243..de433485fca 100644 --- a/mysql-test/t/func_sapdb.test +++ b/mysql-test/t/func_sapdb.test @@ -54,6 +54,7 @@ select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002"); select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002"); select timediff("1997-12-31 23:59:59.000001","23:59:59.000001"); select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001"); +select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50"); --enable_ps_protocol select maketime(10,11,12); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 0d652a431cb..f9c9d1f013d 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2432,8 +2432,7 @@ void Item_func_add_time::print(String *str) String *Item_func_timediff::val_str(String *str) { DBUG_ASSERT(fixed == 1); - longlong seconds; - long microseconds; + longlong microseconds; long days; int l_sign= 1; TIME l_time1 ,l_time2, l_time3; @@ -2457,32 +2456,23 @@ String *Item_func_timediff::val_str(String *str) (uint) l_time2.month, (uint) l_time2.day)); - microseconds= l_time1.second_part - l_sign*l_time2.second_part; - seconds= ((longlong) days*86400L + l_time1.hour*3600L + - l_time1.minute*60L + l_time1.second + microseconds/1000000L - - (longlong)l_sign*(l_time2.hour*3600L+l_time2.minute*60L+ - l_time2.second)); + microseconds= ((longlong)days*86400L + + l_time1.hour*3600L + l_time1.minute*60L + l_time1.second - + (longlong)l_sign*(l_time2.hour*3600L + l_time2.minute*60L + + l_time2.second))*1000000 + + l_time1.second_part - l_sign*l_time2.second_part; l_time3.neg= 0; - if (seconds < 0) - { - seconds= -seconds; - l_time3.neg= 1; - } - else if (seconds == 0 && microseconds < 0) + if (microseconds < 0) { microseconds= -microseconds; l_time3.neg= 1; } - if (microseconds < 0) - { - microseconds+= 1000000L; - seconds--; - } - if ((l_time2.neg == l_time1.neg) && l_time1.neg) + if ((l_time2.neg == l_time1.neg) && l_time1.neg && microseconds) l_time3.neg= l_time3.neg ? 0 : 1; - calc_time_from_sec(&l_time3, (long) seconds, microseconds); + calc_time_from_sec(&l_time3, (long)(microseconds/1000000), + (long)(microseconds%1000000)); if (!make_datetime(l_time1.second_part || l_time2.second_part ? TIME_MICROSECOND : TIME_ONLY,