Bug #43668 | Server returns wrong MAX() value with year(2) type and no index | ||
---|---|---|---|
Submitted: | 16 Mar 2009 8:59 | Modified: | 12 Mar 2010 17:43 |
Reporter: | Nidhi Shrotriya | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Data Types | Severity: | S3 (Non-critical) |
Version: | 6.0.11,5.4,5.1 | OS: | Any |
Assigned to: | Evgeny Potemkin | CPU Architecture: | Any |
[16 Mar 2009 8:59]
Nidhi Shrotriya
[16 Mar 2009 8:59]
Nidhi Shrotriya
Test Case
Attachment: insert_year_bug_falcon.test (application/octet-stream, text), 1.19 KiB.
[16 Mar 2009 10:17]
Sveta Smirnova
Thank you for the report. Verified as described.
[28 Apr 2009 14:50]
Lars-Erik Bjørk
When testing this on other engines, such as MyISAM and InnoDB, the engines implement a handler function called ::index_last. This positions on the last entry in the index. Falcon does not implement this function. When the server compares the record(s) returned from the engine to see which record is the maximum, it looks only at one record (the last in the index) for MyISAM and InnoDB, whereas for falcon it iteratively looks at all the records. This is done in Item_sum_max::add, in sql/item_sum.cc, by the following code: case INT_RESULT: { longlong nr=args[0]->val_int(); if (!args[0]->null_value && (null_value || (unsigned_flag && (ulonglong) nr > (ulonglong) sum_int) || (!unsigned_flag && nr > sum_int))) { sum_int=nr; null_value=0; } because this is YEAR(2), val_int() does a %100 on the value, and only the last two digits are compared. There does not seem to be any special handling of the fact that the year 01 is greater than the year 99 (2001 vs 1999). Retrying the case for MyISAM and InnoDB without having an index on the column, results in the same problem, as the ::index_last is not longer available. mysql> CREATE TABLE t3 (c1 YEAR(2)) engine=innodb; Query OK, 0 rows affected (0.01 sec) mysql> insert into t3 values (98),(99),(00),(01),(02); Query OK, 5 rows affected (0.00 sec) Records: 5 Duplicates: 0 Warnings: 0 mysql> select * from t3; +------+ | c1 | +------+ | 98 | | 99 | | 00 | | 01 | | 02 | +------+ 5 rows in set (0.00 sec) mysql> select max(c1) from t3; +---------+ | max(c1) | +---------+ | 99 | +---------+ 1 row in set (0.00 sec) This does not seem to be a Falcon bug, but a server bug. I am reclassifying the bug and removing myself as the responsible engineer. I am also asking for a new triage, since the bug applies to all engines (the server)
[8 Sep 2009 12:24]
Guilhem Bichot
Here is a testcase which shows how the result is good (55, i.e. 2055) with an index and bad without an index (99 i.e. 1999). It works the same for myisam, innodb, 5.1, the 6.0 code base. So it's not a regression introduced in 6.0. -- source include/have_innodb.inc set storage_engine=myisam; CREATE TABLE t2(c1 YEAR(2) NOT NULL, c2 YEAR(2) NULL, c3 DATE, c4 DATETIME, PRIMARY KEY(c1,c2)); INSERT INTO t2 VALUES('1901','1901','98-12-31','98.12.31 11:30:45'),('1999','1999','98-12-30','98.12.30 11:30:45'),('2000','2000','98-12-29','98.12.29 11:30:45'),('2001','2001','98-12-28','98.12.28 11:30:45'),('2099','2099','98-12-27','98.12.27 11:30:45'),('2100','2100','98-12-26','98.12.26 11:30:45'),('2155','2155','98-12-26','98.12.26 11:30:45'); INSERT INTO t2 VALUES('00','10','98-12-17','98.12.17 11:30:45'),('20','20','98-12-16','98.12.16 11:30:45'),('40','40','98-12-15','98.12.15 11:30:45'),('60','60','98-12-14','98.12.14 11:30:45'),('69','69','98-12-13','98.12.13 11:30:45'),('70','70','98-12-12','98.12.12 11:30:45'),('90','90','98-12-11','98.12.11 11:30:45'),('99','98','98-12-10','98.12.10 11:30:45'); SET TIMESTAMP=1233216687; INSERT INTO t2 VALUES(NOW(),CURRENT_DATE,NOW(),CURRENT_DATE); INSERT INTO t2(c1) VALUES('5'); INSERT INTO t2 VALUES(1900,2156,'08-01-06','08/01/07'); INSERT INTO t2 VALUES('20','30','98-12-16','98.12.16 11:30:45'),('40','20','98-12-15','98.12.15 11:30:45'); --sorted_result SELECT * FROM t2; SELECT count(*) as total_rows, min(c1) as min_value, max(c1) FROM t2; alter table t2 drop primary key; --sorted_result SELECT * FROM t2; SELECT count(*) as total_rows, min(c1) as min_value, max(c1) FROM t2; DROP TABLE t2; results: set storage_engine=myisam; CREATE TABLE t2(c1 YEAR(2) NOT NULL, c2 YEAR(2) NULL, c3 DATE, c4 DATETIME, PRIMARY KEY(c1,c2)); INSERT INTO t2 VALUES('1901','1901','98-12-31','98.12.31 11:30:45'),('1999','1999','98-12-30','98.12.30 11:30:45'),('2000','2000','98-12-29','98.12.29 11:30:45'),('2001','2001','98-12-28','98.12.28 11:30:45'),('2099','2099','98-12-27','98.12.27 11:30:45'),('2100','2100','98-12-26','98.12.26 11:30:45'),('2155','2155','98-12-26','98.12.26 11:30:45'); INSERT INTO t2 VALUES('00','10','98-12-17','98.12.17 11:30:45'),('20','20','98-12-16','98.12.16 11:30:45'),('40','40','98-12-15','98.12.15 11:30:45'),('60','60','98-12-14','98.12.14 11:30:45'),('69','69','98-12-13','98.12.13 11:30:45'),('70','70','98-12-12','98.12.12 11:30:45'),('90','90','98-12-11','98.12.11 11:30:45'),('99','98','98-12-10','98.12.10 11:30:45'); SET TIMESTAMP=1233216687; INSERT INTO t2 VALUES(NOW(),CURRENT_DATE,NOW(),CURRENT_DATE); Warnings: Warning 1265 Data truncated for column 'c1' at row 1 Warning 1265 Data truncated for column 'c2' at row 1 Note 1265 Data truncated for column 'c3' at row 1 INSERT INTO t2(c1) VALUES('5'); INSERT INTO t2 VALUES(1900,2156,'08-01-06','08/01/07'); Warnings: Warning 1264 Out of range value for column 'c1' at row 1 Warning 1264 Out of range value for column 'c2' at row 1 INSERT INTO t2 VALUES('20','30','98-12-16','98.12.16 11:30:45'),('40','20','98-12-15','98.12.15 11:30:45'); SELECT * FROM t2; c1 c2 c3 c4 00 00 1998-12-26 1998-12-26 11:30:45 00 00 1998-12-29 1998-12-29 11:30:45 00 00 2008-01-06 2008-01-07 00:00:00 00 10 1998-12-17 1998-12-17 11:30:45 01 01 1998-12-28 1998-12-28 11:30:45 01 01 1998-12-31 1998-12-31 11:30:45 05 00 NULL NULL 09 09 2009-01-29 2009-01-29 00:00:00 20 20 1998-12-16 1998-12-16 11:30:45 20 30 1998-12-16 1998-12-16 11:30:45 40 20 1998-12-15 1998-12-15 11:30:45 40 40 1998-12-15 1998-12-15 11:30:45 55 55 1998-12-26 1998-12-26 11:30:45 60 60 1998-12-14 1998-12-14 11:30:45 69 69 1998-12-13 1998-12-13 11:30:45 70 70 1998-12-12 1998-12-12 11:30:45 90 90 1998-12-11 1998-12-11 11:30:45 99 98 1998-12-10 1998-12-10 11:30:45 99 99 1998-12-27 1998-12-27 11:30:45 99 99 1998-12-30 1998-12-30 11:30:45 SELECT count(*) as total_rows, min(c1) as min_value, max(c1) FROM t2; total_rows min_value max(c1) 20 0 55 alter table t2 drop primary key; SELECT * FROM t2; c1 c2 c3 c4 00 00 1998-12-26 1998-12-26 11:30:45 00 00 1998-12-29 1998-12-29 11:30:45 00 00 2008-01-06 2008-01-07 00:00:00 00 10 1998-12-17 1998-12-17 11:30:45 01 01 1998-12-28 1998-12-28 11:30:45 01 01 1998-12-31 1998-12-31 11:30:45 05 00 NULL NULL 09 09 2009-01-29 2009-01-29 00:00:00 20 20 1998-12-16 1998-12-16 11:30:45 20 30 1998-12-16 1998-12-16 11:30:45 40 20 1998-12-15 1998-12-15 11:30:45 40 40 1998-12-15 1998-12-15 11:30:45 55 55 1998-12-26 1998-12-26 11:30:45 60 60 1998-12-14 1998-12-14 11:30:45 69 69 1998-12-13 1998-12-13 11:30:45 70 70 1998-12-12 1998-12-12 11:30:45 90 90 1998-12-11 1998-12-11 11:30:45 99 98 1998-12-10 1998-12-10 11:30:45 99 99 1998-12-27 1998-12-27 11:30:45 99 99 1998-12-30 1998-12-30 11:30:45 SELECT count(*) as total_rows, min(c1) as min_value, max(c1) FROM t2; total_rows min_value max(c1) 20 0 99 DROP TABLE t2;
[8 Sep 2009 12:41]
Guilhem Bichot
as this is seen in 5.1 too, it may need a new triage.
[13 Oct 2009 17:05]
Sergei Golubchik
Using test case of Lars-Erik: mysql> select t1.c1, t2.c1 from t3 as t1, t3 as t2 where t1.c1 > t2.c1; +------+------+ | c1 | c1 | +------+------+ | 99 | 98 | | 98 | 00 | | 99 | 00 | | 01 | 00 | | 02 | 00 | | 98 | 01 | | 99 | 01 | | 02 | 01 | | 98 | 02 | | 99 | 02 | +------+------+ which shows that YEAR(2) > YEAR(2) doesn't work correctly either
[16 Oct 2009 13:47]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/87137 3165 Evgeny Potemkin 2009-10-16 Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) MySQL manual describes values of the YEAR(2) field type as follows: values 00 - 69 mean 2000 - 2069 years and values 70 - 99 mean 1970 - 1999 years. MIN/MAX and comparison functions was comparing them as int values thus producing wrong result. The Arg_comparator class is extended with compare_year function which performs correct comparison of the YEAR type. The Item_sum_hybrid class now uses Item_cache and Arg_comparator objects to correctly calculate its value. Now Item_cache_int returns the type of cached item. Now the Arg_comparator class allows owner function to be omited. @ mysql-test/r/func_group.result Added a test case for the bug#43668. @ mysql-test/t/func_group.test Added a test case for the bug#43668. @ sql/item.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) Now Item_cache_int returns the type of cached item. @ sql/item_cmpfunc.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The Arg_comparator class is extended with compare_year function which performs correct comparison of the YEAR type. Now the Arg_comparator class allows owner function to be omited. @ sql/item_cmpfunc.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) @ sql/item_sum.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The Item_sum_hybrid class now uses Item_cache and Arg_comparator objects to correctly calculate its value. @ sql/item_sum.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The Item_sum_hybrid class now uses Item_cache and Arg_comparator objects to correctly calculate its value.
[27 Oct 2009 15:30]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/88396 3165 Evgeny Potemkin 2009-10-27 Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) MySQL manual describes values of the YEAR(2) field type as follows: values 00 - 69 mean 2000 - 2069 years and values 70 - 99 mean 1970 - 1999 years. MIN/MAX and comparison functions was comparing them as int values thus producing wrong result. Now the Arg_comparator class is extended with compare_year function which performs correct comparison of the YEAR type. The Item_sum_hybrid class now uses Item_cache and Arg_comparator objects to correctly calculate its value. To allow Arg_comparator to use func_name() function for Item_func and Item_sum objects the func_name declaration is moved to the Item_result_field class. A helper function is_owner_equal_func is added to the Arg_comparator class. It checks whether the Arg_comparator object owner is the <=> function or not. A helper function setup is added to the Item_sum_hybrid class. It sets up cache item and comparator. @ mysql-test/r/func_group.result Added a test case for the bug#43668. @ mysql-test/t/func_group.test Added a test case for the bug#43668. @ sql/item.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) Now Item_cache_int returns the type of cached item. @ sql/item.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) To allow Arg_comparator to use func_name() function for Item_func and Item_sum objects the func_name declaration is moved to the Item_result_field class. @ sql/item_cmpfunc.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The Arg_comparator class is extended with compare_year function which performs correct comparison of the YEAR type. @ sql/item_cmpfunc.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) @ sql/item_subselect.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) Added an implementation of the virtual func_name function. @ sql/item_sum.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The Item_sum_hybrid class now uses Item_cache and Arg_comparator objects to correctly calculate its value. A helper function setup is added to the Item_sum_hybrid class. It sets up cache item and comparator. @ sql/item_sum.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The Item_sum_hybrid class now uses Item_cache and Arg_comparator objects to correctly calculate its value. Added an implementation of the virtual func_name function.
[15 Nov 2009 16:56]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/90461 3165 Evgeny Potemkin 2009-11-15 Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) MySQL manual describes values of the YEAR(2) field type as follows: values 00 - 69 mean 2000 - 2069 years and values 70 - 99 mean 1970 - 1999 years. MIN/MAX and comparison functions was comparing them as int values thus producing wrong result. Now the Arg_comparator class is extended with compare_year function which performs correct comparison of the YEAR type. The Item_sum_hybrid class now uses Item_cache and Arg_comparator objects to correctly calculate its value. To allow Arg_comparator to use func_name() function for Item_func and Item_sum objects the func_name declaration is moved to the Item_result_field class. A helper function is_owner_equal_func is added to the Arg_comparator class. It checks whether the Arg_comparator object owner is the <=> function or not. A helper function setup is added to the Item_sum_hybrid class. It sets up cache item and comparator. @ mysql-test/r/func_group.result Added a test case for the bug#43668. @ mysql-test/t/func_group.test Added a test case for the bug#43668. @ sql/item.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) Now Item_cache_int returns the type of cached item. @ sql/item.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) To allow Arg_comparator to use func_name() function for Item_func and Item_sum objects the func_name declaration is moved to the Item_result_field class. @ sql/item_cmpfunc.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The Arg_comparator class is extended with compare_year function which performs correct comparison of the YEAR type. @ sql/item_cmpfunc.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The year_as_datetime variable is added to the Arg_comparator class. It's set to TRUE when YEAR value should be converted to the YYYY-00-00 00:00:00 format for correct YEAR-DATETIME comparison. @ sql/item_geofunc.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) Item_func_spatial_rel::val_int chenged to use Arg_comparator's string buffers. @ sql/item_subselect.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) Added an implementation of the virtual func_name function. @ sql/item_sum.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The Item_sum_hybrid class now uses Item_cache and Arg_comparator objects to correctly calculate its value. A helper function setup is added to the Item_sum_hybrid class. It sets up cache item and comparator. @ sql/item_sum.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The Item_sum_hybrid class now uses Item_cache and Arg_comparator objects to correctly calculate its value. Added an implementation of the virtual func_name function.
[17 Nov 2009 14:07]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/90673 3165 Evgeny Potemkin 2009-11-17 Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) MySQL manual describes values of the YEAR(2) field type as follows: values 00 - 69 mean 2000 - 2069 years and values 70 - 99 mean 1970 - 1999 years. MIN/MAX and comparison functions was comparing them as int values thus producing wrong result. Now the Arg_comparator class is extended with compare_year function which performs correct comparison of the YEAR type. The Item_sum_hybrid class now uses Item_cache and Arg_comparator objects to correctly calculate its value. To allow Arg_comparator to use func_name() function for Item_func and Item_sum objects the func_name declaration is moved to the Item_result_field class. A helper function is_owner_equal_func is added to the Arg_comparator class. It checks whether the Arg_comparator object owner is the <=> function or not. A helper function setup is added to the Item_sum_hybrid class. It sets up cache item and comparator. @ mysql-test/r/func_group.result Added a test case for the bug#43668. @ mysql-test/t/func_group.test Added a test case for the bug#43668. @ sql/item.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) Now Item_cache_int returns the type of cached item. @ sql/item.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) To allow Arg_comparator to use func_name() function for Item_func and Item_sum objects the func_name declaration is moved to the Item_result_field class. @ sql/item_cmpfunc.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The Arg_comparator class is extended with compare_year function which performs correct comparison of the YEAR type. @ sql/item_cmpfunc.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The year_as_datetime variable is added to the Arg_comparator class. It's set to TRUE when YEAR value should be converted to the YYYY-00-00 00:00:00 format for correct YEAR-DATETIME comparison. @ sql/item_geofunc.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) Item_func_spatial_rel::val_int chenged to use Arg_comparator's string buffers. @ sql/item_subselect.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) Added an implementation of the virtual func_name function. @ sql/item_sum.cc Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The Item_sum_hybrid class now uses Item_cache and Arg_comparator objects to correctly calculate its value. A helper function setup is added to the Item_sum_hybrid class. It sets up cache item and comparator. @ sql/item_sum.h Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) The Item_sum_hybrid class now uses Item_cache and Arg_comparator objects to correctly calculate its value. Added an implementation of the virtual func_name function.
[24 Nov 2009 15:29]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/91433 3219 Evgeny Potemkin 2009-11-24 [merge] Manual merge of the fix for bug#43668.
[25 Nov 2009 9:53]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/91551 3221 Evgeny Potemkin 2009-11-25 Additional fix for the bug#43668. Arg_comparator now takes into account that some of optimizations aren't done in the PREPARE stmt.
[2 Dec 2009 8:07]
Bugs System
Pushed into 5.1.42 (revid:joro@sun.com-20091202080033-mndu4sxwx19lz2zs) (version source revid:davi.arnaut@sun.com-20091125130912-d7hrln14ef7y5d7i) (merge vers: 5.1.42) (pib:13)
[2 Dec 2009 21:35]
Paul DuBois
Noted in 5.1.42 changelog. For YEAR(2) values, MIN(), MAX(), and comparisons could yield incorrect results. Setting report to NDI pending push to 5.6.x+.
[9 Dec 2009 14:11]
Evgeny Potemkin
Bug#40171 was marked as a duplicate of this one.
[16 Dec 2009 8:37]
Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20091216083311-xorsasf5kopjxshf) (version source revid:alik@sun.com-20091214191830-wznm8245ku8xo702) (merge vers: 6.0.14-alpha) (pib:14)
[16 Dec 2009 8:44]
Bugs System
Pushed into 5.5.0-beta (revid:alik@sun.com-20091216082430-s0gtzibcgkv4pqul) (version source revid:alexey.kopytov@sun.com-20091126114659-f3imubfuye9fn7qp) (merge vers: 5.5.0-beta) (pib:14)
[16 Dec 2009 8:50]
Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20091216083231-rp8ecpnvkkbhtb27) (version source revid:alik@sun.com-20091212203859-fx4rx5uab47wwuzd) (merge vers: 5.6.0-beta) (pib:14)
[16 Dec 2009 15:54]
Paul DuBois
Noted in 5.5.1, 6.0.14 changelogs.
[12 Mar 2010 14:09]
Bugs System
Pushed into 5.1.44-ndb-7.0.14 (revid:jonas@mysql.com-20100312135944-t0z8s1da2orvl66x) (version source revid:jonas@mysql.com-20100312115609-woou0te4a6s4ae9y) (merge vers: 5.1.44-ndb-7.0.14) (pib:16)
[12 Mar 2010 14:25]
Bugs System
Pushed into 5.1.44-ndb-6.2.19 (revid:jonas@mysql.com-20100312134846-tuqhd9w3tv4xgl3d) (version source revid:jonas@mysql.com-20100312060623-mx6407w2vx76h3by) (merge vers: 5.1.44-ndb-6.2.19) (pib:16)
[12 Mar 2010 14:39]
Bugs System
Pushed into 5.1.44-ndb-6.3.33 (revid:jonas@mysql.com-20100312135724-xcw8vw2lu3mijrhn) (version source revid:jonas@mysql.com-20100312103652-snkltsd197l7q2yg) (merge vers: 5.1.44-ndb-6.3.33) (pib:16)