| Bug #16603 | Row subquery gives different result when index is added | ||
|---|---|---|---|
| Submitted: | 18 Jan 2006 12:31 | Modified: | 28 Feb 2006 1:05 |
| Reporter: | Sid Gargate | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
| Version: | 5.0.16-nt/5.0.19/5.1.6 BK | OS: | Windows (Windows XP/Linux) |
| Assigned to: | Igor Babaev | CPU Architecture: | Any |
[18 Jan 2006 12:31]
Sid Gargate
[18 Jan 2006 13:22]
MySQL Verification Team
Thank you for the bug report.
This bug not affects 4.1.
mysql> select version();
+------------------+
| version() |
+------------------+
| 4.1.17-debug-log |
+------------------+
1 row in set (0.03 sec)
mysql> create database db15;
Query OK, 1 row affected (0.00 sec)
mysql> use db15
Database changed
mysql> Create Table demo (name varchar(20),
-> login datetime,
-> logout datetime) engine=MyISAM;
Query OK, 0 rows affected (0.02 sec)
mysql> Insert Into demo values
-> ('AAA','2006-01-18 17:02:00','2006-01-18 18:03:03'),
-> ('AAA','2006-01-18 17:02:10','2006-01-18 19:03:16'),
-> ('AAA','2006-01-18 17:02:19','2006-01-18 17:09:25'),
-> ('BBB','2006-01-18 17:02:28','2006-01-18 17:32:34'),
-> ('BBB','2006-01-18 17:02:42','2006-01-18 18:32:42'),
-> ('BBB','2006-01-18 17:02:51','2006-01-18 17:38:51'),
-> ('AAA','2006-01-18 17:02:59','2006-01-18 19:04:05'),
-> ('BBB','2006-01-18 17:03:05','2006-01-18 20:39:05'),
-> ('CCC','2006-01-18 17:03:24','2006-01-18 17:33:30'),
-> ('CCC','2006-01-18 17:03:32','2006-01-18 17:10:38'),
-> ('AAA','2006-01-18 17:03:32','2006-01-18 17:36:33');
Query OK, 11 rows affected (0.01 sec)
Records: 11 Duplicates: 0 Warnings: 0
mysql> select * from demo where (name,login) = any (select name,max(login) from
-> demo group by name);
+------+---------------------+---------------------+
| name | login | logout |
+------+---------------------+---------------------+
| BBB | 2006-01-18 17:03:05 | 2006-01-18 20:39:05 |
| CCC | 2006-01-18 17:03:32 | 2006-01-18 17:10:38 |
| AAA | 2006-01-18 17:03:32 | 2006-01-18 17:36:33 |
+------+---------------------+---------------------+
3 rows in set (0.08 sec)
mysql> alter table demo add index(name);
Query OK, 11 rows affected (0.01 sec)
Records: 11 Duplicates: 0 Warnings: 0
mysql> select * from demo where (name,login) = any (select name,max(login) from
-> demo group by name);
+------+---------------------+---------------------+
| name | login | logout |
+------+---------------------+---------------------+
| BBB | 2006-01-18 17:03:05 | 2006-01-18 20:39:05 |
| CCC | 2006-01-18 17:03:32 | 2006-01-18 17:10:38 |
| AAA | 2006-01-18 17:03:32 | 2006-01-18 17:36:33 |
+------+---------------------+---------------------+
3 rows in set (0.09 sec)
mysql> select version();
+--------------+
| version() |
+--------------+
| 5.0.19-debug |
+--------------+
1 row in set (0.00 sec)
mysql> create database db15;
Query OK, 1 row affected (0.00 sec)
mysql> use db15
Database changed
mysql> Create Table demo (name varchar(20),
-> login datetime,
-> logout datetime) engine=MyISAM;
Query OK, 0 rows affected (0.01 sec)
mysql> Insert Into demo values
-> ('AAA','2006-01-18 17:02:00','2006-01-18 18:03:03'),
-> ('AAA','2006-01-18 17:02:10','2006-01-18 19:03:16'),
-> ('AAA','2006-01-18 17:02:19','2006-01-18 17:09:25'),
-> ('BBB','2006-01-18 17:02:28','2006-01-18 17:32:34'),
-> ('BBB','2006-01-18 17:02:42','2006-01-18 18:32:42'),
-> ('BBB','2006-01-18 17:02:51','2006-01-18 17:38:51'),
-> ('AAA','2006-01-18 17:02:59','2006-01-18 19:04:05'),
-> ('BBB','2006-01-18 17:03:05','2006-01-18 20:39:05'),
-> ('CCC','2006-01-18 17:03:24','2006-01-18 17:33:30'),
-> ('CCC','2006-01-18 17:03:32','2006-01-18 17:10:38'),
-> ('AAA','2006-01-18 17:03:32','2006-01-18 17:36:33');
Query OK, 11 rows affected (0.00 sec)
Records: 11 Duplicates: 0 Warnings: 0
mysql> select * from demo where (name,login) = any (select name,max(login) from
-> demo group by name);
+------+---------------------+---------------------+
| name | login | logout |
+------+---------------------+---------------------+
| BBB | 2006-01-18 17:03:05 | 2006-01-18 20:39:05 |
| CCC | 2006-01-18 17:03:32 | 2006-01-18 17:10:38 |
| AAA | 2006-01-18 17:03:32 | 2006-01-18 17:36:33 |
+------+---------------------+---------------------+
3 rows in set (0.05 sec)
mysql> alter table demo add index(name);
Query OK, 11 rows affected (0.02 sec)
Records: 11 Duplicates: 0 Warnings: 0
mysql> select * from demo where (name,login) = any (select name,max(login) from
-> demo group by name);
+------+---------------------+---------------------+
| name | login | logout |
+------+---------------------+---------------------+
| CCC | 2006-01-18 17:03:32 | 2006-01-18 17:10:38 |
+------+---------------------+---------------------+
1 row in set (0.01 sec)
mysql> select version();
+-------------------+
| version() |
+-------------------+
| 5.1.6-alpha-debug |
+-------------------+
1 row in set (0.03 sec)
mysql> create database db15;
Query OK, 1 row affected (0.01 sec)
mysql> use db15
Database changed
mysql> Create Table demo (name varchar(20),
-> login datetime,
-> logout datetime) engine=MyISAM;
Query OK, 0 rows affected (0.01 sec)
mysql> Insert Into demo values
-> ('AAA','2006-01-18 17:02:00','2006-01-18 18:03:03'),
-> ('AAA','2006-01-18 17:02:10','2006-01-18 19:03:16'),
-> ('AAA','2006-01-18 17:02:19','2006-01-18 17:09:25'),
-> ('BBB','2006-01-18 17:02:28','2006-01-18 17:32:34'),
-> ('BBB','2006-01-18 17:02:42','2006-01-18 18:32:42'),
-> ('BBB','2006-01-18 17:02:51','2006-01-18 17:38:51'),
-> ('AAA','2006-01-18 17:02:59','2006-01-18 19:04:05'),
-> ('BBB','2006-01-18 17:03:05','2006-01-18 20:39:05'),
-> ('CCC','2006-01-18 17:03:24','2006-01-18 17:33:30'),
-> ('CCC','2006-01-18 17:03:32','2006-01-18 17:10:38'),
-> ('AAA','2006-01-18 17:03:32','2006-01-18 17:36:33');
Query OK, 11 rows affected (0.02 sec)
Records: 11 Duplicates: 0 Warnings: 0
mysql> select * from demo where (name,login) = any (select name,max(login) from
-> demo group by name);
+------+---------------------+---------------------+
| name | login | logout |
+------+---------------------+---------------------+
| BBB | 2006-01-18 17:03:05 | 2006-01-18 20:39:05 |
| CCC | 2006-01-18 17:03:32 | 2006-01-18 17:10:38 |
| AAA | 2006-01-18 17:03:32 | 2006-01-18 17:36:33 |
+------+---------------------+---------------------+
3 rows in set (0.04 sec)
mysql> alter table demo add index(name);
Query OK, 11 rows affected (0.03 sec)
Records: 11 Duplicates: 0 Warnings: 0
mysql> select * from demo where (name,login) = any (select name,max(login) from
-> demo group by name);
+------+---------------------+---------------------+
| name | login | logout |
+------+---------------------+---------------------+
| CCC | 2006-01-18 17:03:32 | 2006-01-18 17:10:38 |
+------+---------------------+---------------------+
1 row in set (0.01 sec)
[10 Feb 2006 4:08]
Igor Babaev
I succeeded to demonstrate the same problem with a slightly more simple test case:
mysql> CREATE TABLE t1 (a varchar(5), b varchar(10));
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO t1 VALUES
-> ('AAA', 5), ('BBB', 4), ('BBB', 1), ('CCC', 2),
-> ('CCC', 7), ('AAA', 2), ('AAA', 4), ('BBB', 3), ('AAA', 8);
Query OK, 9 rows affected (0.00 sec)
Records: 9 Duplicates: 0 Warnings: 0
mysql>
mysql> SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+------+------+
| a | b |
+------+------+
| BBB | 4 |
| CCC | 7 |
| AAA | 8 |
+------+------+
3 rows in set (0.01 sec)
mysql> EXPLAIN
-> SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+----+--------------------+-------+------+---------------+------+---------+------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+------+---------------+------+---------+------+------+---------------------------------+
| 1 | PRIMARY | t1 | ALL | NULL | NULL | NULL | NULL | 9 | Using where |
| 2 | DEPENDENT SUBQUERY | t1 | ALL | NULL | NULL | NULL | NULL | 9 | Using temporary; Using filesort |
+----+--------------------+-------+------+---------------+------+---------+------+------+---------------------------------+
2 rows in set (0.00 sec)
mysql>
mysql> ALTER TABLE t1 ADD INDEX(a);
Query OK, 9 rows affected (0.27 sec)
Records: 9 Duplicates: 0 Warnings: 0
mysql>
mysql> SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+------+------+
| a | b |
+------+------+
| CCC | 7 |
+------+------+
1 row in set (0.01 sec)
mysql> EXPLAIN
-> SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+----+--------------------+-------+-------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+-------+---------------+------+---------+------+------+----------------+
| 1 | PRIMARY | t1 | ALL | NULL | NULL | NULL | NULL | 9 | Using where |
| 2 | DEPENDENT SUBQUERY | t1 | index | NULL | a | 8 | NULL | 9 | Using filesort |
+----+--------------------+-------+-------+---------------+------+---------+------+------+----------------+
2 rows in set (0.00 sec)
Pay attention to the fact that the above two queries use different access method to get rows in the subquery,
[14 Feb 2006 2:50]
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/2564
[20 Feb 2006 7:47]
Igor Babaev
ChangeSet 1.2048 06/02/13 18:50:06 igor@rurik.mysql.com +3 -0 Fixed bug #16603. A subquery transformation changes the HAVING clause of the embedding query if the subquery contains a GROUP BY clause. Yet the split_sum_func2 function was not applied to the modified HAVING clause. This could result in wrong answers. sql/sql_select.cc 1.394 06/02/13 18:50:00 igor@rurik.mysql.com +15 -14 Fixed bug #16603. A subquery transformation changes the HAVING clause of the embedding query if the subquery contains a GROUP BY clause. Yet the split_sum_func2 function was not applied to the modified HAVING clause. This could result in wrong answers. mysql-test/t/subselect.test 1.113 06/02/13 18:50:00 igor@rurik.mysql.com +22 -0 Added a test case for bug #16603. mysql-test/r/subselect.result 1.133 06/02/13 18:50:00 igor@rurik.mysql.com +29 -3 Added a test case for bug #16603. The fix will appear in 5.0.19 and 5.1.8
[28 Feb 2006 1:05]
Paul DuBois
Noted in 5.0.19, 5.1.7 changelogs. If the query optimizer transformed a <literal>GROUP BY</literal> clause in a subquery, it did not also transform the <literal>HAVING</literal> clause if there was one, producing incorrect results. (Bug #16603)
