| Bug #20792 | Incorrect results from aggregate subquery | ||
|---|---|---|---|
| Submitted: | 30 Jun 2006 13:20 | Modified: | 9 Aug 2006 19:53 |
| Reporter: | Jack Christensen | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: InnoDB storage engine | Severity: | S2 (Serious) |
| Version: | 5.0.22/4.1BK/5.0BK/5.1BK | OS: | Linux (Linux) |
| Assigned to: | Georgi Kodinov | CPU Architecture: | Any |
[30 Jun 2006 14:11]
MySQL Verification Team
Thank you for the bug report.
------------------------------------------------------------
mysql> select version();
+--------------+
| version() |
+--------------+
| 4.1.21-debug |
+--------------+
1 row in set (0.00 sec)
mysql>
mysql> SELECT a.*
-> FROM a
-> WHERE (SELECT (SUM(d.num_to_sum))
-> FROM d
-> INNER JOIN b ON d.b_id=b.id
-> INNER JOIN c ON b.c_id=c.id
-> WHERE c.id='1' AND a.id=d.a_id) > 0;
Empty set (0.00 sec)
mysql>
mysql> SELECT a.*
-> FROM a
-> WHERE (SELECT (SUM(d.num_to_sum))
-> FROM d
-> INNER JOIN b ON d.b_id=b.id
-> INNER JOIN c ON b.c_id=c.id
-> WHERE c.id=1 AND a.id=d.a_id) > 0;
+----+
| id |
+----+
| 2 |
+----+
1 row in set (0.00 sec)
mysql>
mysql> UPDATE a
-> SET id=3
-> WHERE id=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql>
mysql>
mysql> SELECT a.*
-> FROM a
-> WHERE (SELECT (SUM(d.num_to_sum))
-> FROM d
-> INNER JOIN b ON d.b_id=b.id
-> INNER JOIN c ON b.c_id=c.id
-> WHERE c.id='1' AND a.id=d.a_id) > 0;
+----+
| id |
+----+
| 2 |
+----+
1 row in set (0.01 sec)
mysql>
mysql> SELECT a.*
-> FROM a
-> WHERE (SELECT (SUM(d.num_to_sum))
-> FROM d
-> INNER JOIN b ON d.b_id=b.id
-> INNER JOIN c ON b.c_id=c.id
-> WHERE c.id='1' AND a.id=d.a_id) > 0;
Empty set (0.00 sec)
mysql> alter table a engine=MyISAM;
Query OK, 2 rows affected (0.03 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> alter table b engine=MyISAM;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> alter table c engine=MyISAM;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> alter table d engine=MyISAM;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SELECT a.*
-> FROM a
-> WHERE (SELECT (SUM(d.num_to_sum))
-> FROM d
-> INNER JOIN b ON d.b_id=b.id
-> INNER JOIN c ON b.c_id=c.id
-> WHERE c.id='1' AND a.id=d.a_id) > 0;
+----+
| id |
+----+
| 2 |
+----+
1 row in set (0.01 sec)
mysql>
------------------------------------------------------------
mysql> select version();
+--------------+
| version() |
+--------------+
| 5.0.23-debug |
+--------------+
1 row in set (0.00 sec)
mysql>
mysql> SELECT a.*
-> FROM a
-> WHERE (SELECT (SUM(d.num_to_sum))
-> FROM d
-> INNER JOIN b ON d.b_id=b.id
-> INNER JOIN c ON b.c_id=c.id
-> WHERE c.id='1' AND a.id=d.a_id) > 0;
Empty set (0.01 sec)
mysql>
mysql> alter table a engine=MyISAM;
Query OK, 2 rows affected (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> alter table b engine=MyISAM;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> alter table c engine=MyISAM;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> alter table d engine=MyISAM;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql>
mysql> SELECT a.*
-> FROM a
-> WHERE (SELECT (SUM(d.num_to_sum))
-> FROM d
-> INNER JOIN b ON d.b_id=b.id
-> INNER JOIN c ON b.c_id=c.id
-> WHERE c.id='1' AND a.id=d.a_id) > 0;
+----+
| id |
+----+
| 2 |
+----+
1 row in set (0.00 sec)
mysql>
------------------------------------------------------------
mysql> select version();
+-------------------+
| version() |
+-------------------+
| 5.1.12-beta-debug |
+-------------------+
1 row in set (0.00 sec)
mysql>
mysql> SELECT a.*
-> FROM a
-> WHERE (SELECT (SUM(d.num_to_sum))
-> FROM d
-> INNER JOIN b ON d.b_id=b.id
-> INNER JOIN c ON b.c_id=c.id
-> WHERE c.id='1' AND a.id=d.a_id) > 0;
Empty set (0.02 sec)
mysql>
mysql> alter table a engine=MyISAM;
Query OK, 2 rows affected (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> alter table b engine=MyISAM;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> alter table c engine=MyISAM;
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> alter table d engine=MyISAM;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql>
mysql> SELECT a.*
-> FROM a
-> WHERE (SELECT (SUM(d.num_to_sum))
-> FROM d
-> INNER JOIN b ON d.b_id=b.id
-> INNER JOIN c ON b.c_id=c.id
-> WHERE c.id='1' AND a.id=d.a_id) > 0;
+----+
| id |
+----+
| 2 |
+----+
1 row in set (0.01 sec)
mysql>
[20 Jul 2006 7:43]
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/9365
[25 Jul 2006 9:59]
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/9531
[26 Jul 2006 16:19]
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/9608
[2 Aug 2006 18:33]
Evgeny Potemkin
The problem was in that opt_sum_query() replaced MIN/MAX functions with the corresponding constant found in a key, but due to imprecise representation of float numbers, when evaluating the where clause, this comparison failed. Fixed in 4.1.22, 5.0.25, 5.1.12
[9 Aug 2006 19:53]
Paul DuBois
Noted in 4.1.22, 5.0.25, 5.1.12 changelogs.

Description: Under certain circumstances subqueries are inaccurate, it appears that the problem can be caused by a string not being automicatally cast to a number. However, it appears that this error also only occurs after a row is rejected by the where condition. All following rows will then be rejected. How to repeat: Sample table setup: DROP TABLE IF EXISTS `a`; CREATE TABLE `a` ( `id` int(10) unsigned NOT NULL auto_increment, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO `a` VALUES (1),(2); DROP TABLE IF EXISTS `b`; CREATE TABLE `b` ( `id` int(10) unsigned NOT NULL auto_increment, `c_id` int(10) unsigned NOT NULL default '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO `b` VALUES (1,1); DROP TABLE IF EXISTS `c`; CREATE TABLE `c` ( `id` int(10) unsigned NOT NULL auto_increment, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO `c` VALUES (1); DROP TABLE IF EXISTS `d`; CREATE TABLE `d` ( `id` int(10) unsigned NOT NULL auto_increment, `a_id` int(10) unsigned NOT NULL default '0', `b_id` int(10) unsigned default NULL, `num_to_sum` float NOT NULL default '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO `d` VALUES (1,2,1,1); mysql> SELECT a.* -> FROM a -> WHERE (SELECT (SUM(d.num_to_sum)) -> FROM d -> INNER JOIN b ON d.b_id=b.id -> INNER JOIN c ON b.c_id=c.id -> WHERE c.id='1' AND a.id=d.a_id) > 0; Empty set (0.00 sec) mysql> SELECT a.* -> FROM a -> WHERE (SELECT (SUM(d.num_to_sum)) -> FROM d -> INNER JOIN b ON d.b_id=b.id -> INNER JOIN c ON b.c_id=c.id -> WHERE c.id=1 AND a.id=d.a_id) > 0; +----+ | id | +----+ | 2 | +----+ 1 row in set (0.00 sec) Only difference is c.id='1' or c.id=1. Both should return one row. Also note that if a rejected row does not come first, the test succeeds even with the quoted number: mysql> UPDATE a -> SET id=3 -> WHERE id=1; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> SELECT a.* -> FROM a -> WHERE (SELECT (SUM(d.num_to_sum)) -> FROM d -> INNER JOIN b ON d.b_id=b.id -> INNER JOIN c ON b.c_id=c.id -> WHERE c.id='1' AND a.id=d.a_id) > 0; +----+ | id | +----+ | 2 | +----+ 1 row in set (0.00 sec)