diff options
-rw-r--r-- | mysql-test/r/date_formats.result | 10 | ||||
-rw-r--r-- | mysql-test/r/distinct.result | 13 | ||||
-rw-r--r-- | mysql-test/r/func_sapdb.result | 18 | ||||
-rw-r--r-- | mysql-test/r/func_time_hires.result | 4 | ||||
-rw-r--r-- | mysql-test/t/distinct.test | 9 | ||||
-rw-r--r-- | sql/field.h | 27 | ||||
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 7 | ||||
-rw-r--r-- | sql/item_create.cc | 2 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 2 | ||||
-rw-r--r-- | sql/item_timefunc.h | 2 |
11 files changed, 64 insertions, 32 deletions
diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 386f2246530..dd346cb94dc 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -196,16 +196,16 @@ date format datetime 0003-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 0003-01-02 08:11:02 03-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02 2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12 -2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450 -2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450 -2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450 +2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12 +2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12 +2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12 2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12 10:20:10 %H:%i:%s 0000-00-00 10:20:10 10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10 10:20:10 %T 0000-00-00 10:20:10 10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10 10:20:10AM %r 0000-00-00 10:20:10 -10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000 +10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10 15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58 15 September 2001 %d %M %Y 2001-09-15 00:00:00 15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00 @@ -487,7 +487,7 @@ str_to_date(a,b) create table t2 select str_to_date(a,b) from t1; describe t2; Field Type Null Key Default Extra -str_to_date(a,b) datetime YES NULL +str_to_date(a,b) datetime(6) YES NULL select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1, str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S") as f2, str_to_date("2003-01-02", "%Y-%m-%d") as f3, diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 4bef07b9906..f0de0e68c28 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -805,3 +805,16 @@ a 2010-10-10 20101010 drop table t1; +create table t1 (f1 varchar(40)); +insert into t1 values ('2010-10-10 00:00:00.0001'),('2010-10-10 00:00:00.0002'),('2010-10-10 00:00:00.0003'); +select time(f1) from t1 ; +time(f1) +00:00:00.000100 +00:00:00.000200 +00:00:00.000300 +select distinct time(f1) from t1 ; +time(f1) +00:00:00.000100 +00:00:00.000200 +00:00:00.000300 +drop table t1; diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index c2d9a5c5ffa..f7a388237e8 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -195,17 +195,17 @@ time("1997-12-31 23:59:59.000001") as f9; describe t1; Field Type Null Key Default Extra f1 date YES NULL -f2 datetime YES NULL -f3 time YES NULL -f4 time YES NULL -f5 time YES NULL +f2 datetime(6) YES NULL +f3 time(6) YES NULL +f4 time(6) YES NULL +f5 time(6) YES NULL f6 time YES NULL -f7 datetime YES NULL +f7 datetime(6) YES NULL f8 date YES NULL -f9 time YES NULL +f9 time(6) 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 -24:00:00 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59 +1997-01-01 1998-01-02 01:01:00.000003 49:01:01.000001 46:58:57.999999 8275:29:36.710655 10:11:12 2001-12-01 01:01:01.000000 1997-12-31 23:59:59.000001 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'), @@ -230,8 +230,8 @@ SELECT TIMEDIFF(t1, t4) As ttt, TIMEDIFF(t2, t3) As qqq, TIMEDIFF(t3, t2) As eee, TIMEDIFF(t2, t4) As rrr from test; ttt qqq eee rrr -744:00:00 NULL NULL NULL -838:59:59.999999 22:58:58 -22:58:58 NULL --838:59:59.999999 -22:58:58 22:58:58 NULL +838:59:59 22:58:58 -22:58:58 NULL +-838:59:59 -22:58:58 22:58:58 NULL NULL 26:02:02 -26:02:02 NULL 00:00:00 -26:02:02 26:02:02 NULL NULL NULL NULL NULL diff --git a/mysql-test/r/func_time_hires.result b/mysql-test/r/func_time_hires.result index 06ad9374725..0fe79c65882 100644 --- a/mysql-test/r/func_time_hires.result +++ b/mysql-test/r/func_time_hires.result @@ -37,7 +37,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `sec_to_time(12345)` time DEFAULT NULL, `sec_to_time(12345.6789)` time(4) DEFAULT NULL, - `sec_to_time(1234567e-2)` time DEFAULT NULL, + `sec_to_time(1234567e-2)` time(6) DEFAULT NULL, `now()` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `curtime(0)` time NOT NULL DEFAULT '00:00:00', `utc_timestamp(1)` datetime(1) NOT NULL DEFAULT '0000-00-00 00:00:00.0', @@ -52,7 +52,7 @@ t1 CREATE TABLE `t1` ( select * from t1; sec_to_time(12345) 03:25:45 sec_to_time(12345.6789) 03:25:45.6789 -sec_to_time(1234567e-2) 03:25:45 +sec_to_time(1234567e-2) 03:25:45.670000 now() 2011-01-01 01:01:01 curtime(0) 01:01:01 utc_timestamp(1) 2010-12-31 22:01:01.1 diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index 9cc5dce6754..89d3f85a38d 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -624,3 +624,12 @@ select * from t1 where a = DATE('2010-10-10'); select distinct a from t1 where a = DATE('2010-10-10'); drop table t1; +# +# lp:731124 Loss of precision on DISTINCT +# +create table t1 (f1 varchar(40)); +insert into t1 values ('2010-10-10 00:00:00.0001'),('2010-10-10 00:00:00.0002'),('2010-10-10 00:00:00.0003'); +select time(f1) from t1 ; +select distinct time(f1) from t1 ; +drop table t1; + diff --git a/sql/field.h b/sql/field.h index 9475e28bc0f..c955981531a 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1501,12 +1501,13 @@ new_Field_timestamp(uchar *ptr, uchar *null_ptr, uchar null_bit, enum Field::utype unireg_check, const char *field_name, TABLE_SHARE *share, uint dec, CHARSET_INFO *cs) { - if (dec==0 || dec == NOT_FIXED_DEC) + if (dec==0) return new Field_timestamp(ptr, MAX_DATETIME_WIDTH, null_ptr, null_bit, unireg_check, field_name, share, cs); - else - return new Field_timestamp_hires(ptr, null_ptr, null_bit, unireg_check, - field_name, share, dec, cs); + if (dec == NOT_FIXED_DEC) + dec= MAX_DATETIME_PRECISION; + return new Field_timestamp_hires(ptr, null_ptr, null_bit, unireg_check, + field_name, share, dec, cs); } static inline Field_time * @@ -1514,12 +1515,13 @@ new_Field_time(uchar *ptr, uchar *null_ptr, uchar null_bit, enum Field::utype unireg_check, const char *field_name, uint dec, CHARSET_INFO *cs) { - if (dec == 0 || dec == NOT_FIXED_DEC) + if (dec == 0) return new Field_time(ptr, MIN_TIME_WIDTH, null_ptr, null_bit, unireg_check, field_name, cs); - else - return new Field_time_hires(ptr, null_ptr, null_bit, - unireg_check, field_name, dec, cs); + if (dec == NOT_FIXED_DEC) + dec= MAX_DATETIME_PRECISION; + return new Field_time_hires(ptr, null_ptr, null_bit, + unireg_check, field_name, dec, cs); } static inline Field_datetime * @@ -1527,12 +1529,13 @@ new_Field_datetime(uchar *ptr, uchar *null_ptr, uchar null_bit, enum Field::utype unireg_check, const char *field_name, uint dec, CHARSET_INFO *cs) { - if (dec == 0 || dec == NOT_FIXED_DEC) + if (dec == 0) return new Field_datetime(ptr, MAX_DATETIME_WIDTH, null_ptr, null_bit, unireg_check, field_name, cs); - else - return new Field_datetime_hires(ptr, null_ptr, null_bit, - unireg_check, field_name, dec, cs); + if (dec == NOT_FIXED_DEC) + dec= MAX_DATETIME_PRECISION; + return new Field_datetime_hires(ptr, null_ptr, null_bit, + unireg_check, field_name, dec, cs); } class Field_string :public Field_longstr { diff --git a/sql/item.h b/sql/item.h index 0be8312750d..af0f3d1c024 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2075,7 +2075,7 @@ public: enum_field_types field_type_arg) :Item_partition_func_safe_string(name_arg, length_arg, &my_charset_bin), date_time_field_type(field_type_arg) - { } + { decimals= 0; } enum_field_types field_type() const { return date_time_field_type; } }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index dd47e4ab89f..2749270112d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2920,6 +2920,13 @@ void Item_func_coalesce::fix_length_and_dec() { cached_field_type= agg_field_type(args, arg_count); agg_result_type(&hybrid_type, args, arg_count); + Item_result cmp_type; + agg_cmp_type(&cmp_type, args, arg_count); + if (cmp_type == TIME_RESULT) + { + count_real_length(); + return; + } switch (hybrid_type) { case STRING_RESULT: count_only_length(); diff --git a/sql/item_create.cc b/sql/item_create.cc index ac1102fabbb..abf32543494 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -5091,7 +5091,7 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, } } else - len= NOT_FIXED_DEC; + len= 0; if (cast_type == ITEM_CAST_TIME) res= new (thd->mem_root) Item_time_typecast(a, len); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 7ec41299ed7..813f4d61f2f 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2379,7 +2379,7 @@ void Item_func_add_time::fix_length_and_dec() { enum_field_types arg0_field_type; max_length= MAX_DATETIME_WIDTH; - decimals= NOT_FIXED_DEC; + decimals= max(args[0]->decimals, args[1]->decimals); maybe_null= 1; /* diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 36be86cd89c..b28daed202b 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -765,7 +765,7 @@ public: const char *func_name() const { return "timediff"; } void fix_length_and_dec() { - decimals= NOT_FIXED_DEC; + decimals= max(args[0]->decimals, args[1]->decimals); Item_timefunc::fix_length_and_dec(); maybe_null= 1; } |