Bug #17816 SELECT and CREATE TEMP TABLE results differ
Submitted: 1 Mar 2006 5:52 Modified: 17 Apr 2006 4:34
Reporter: Stewart Smith Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S2 (Serious)
Version:5.0.11, 5.0.18 OS:Linux (Linux)
Assigned to: Igor Babaev CPU Architecture:Any

[1 Mar 2006 5:52] Stewart Smith
Description:
I've finally tracked down a bug to a MySQL bug and not an application one :)

This has shown up in porting an application from postgresql to mysql.

How to repeat:
table definitions:
mysql> show create table election_vote\G
*************************** 1. row ***************************
       Table: election_vote
Create Table: CREATE TABLE `election_vote` (
  `member_id` int(11) NOT NULL,
  `candidate_id` int(11) NOT NULL,
  `preference` int(11) NOT NULL,
  PRIMARY KEY  (`member_id`,`candidate_id`),
  UNIQUE KEY `election_vote_uniq` (`member_id`,`candidate_id`,`preference`),
  KEY `election_vote_candidate_id_fkey` (`candidate_id`),
  CONSTRAINT `election_vote_candidate_id_fkey` FOREIGN KEY (`candidate_id`) REFERENCES `election_candidate` (`id`),
  CONSTRAINT `election_vote_member_id_fkey` FOREIGN KEY (`member_id`) REFERENCES `members` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.03 sec)

mysql> show create table election_candidate\G
*************************** 1. row ***************************
       Table: election_candidate
Create Table: CREATE TABLE `election_candidate` (
  `id` int(11) NOT NULL auto_increment,
  `election_position_id` int(11) NOT NULL,
  `member_id` int(11) NOT NULL,
  `spiel` text,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `election_candidate_pkey` (`election_position_id`,`member_id`),
  KEY `election_candidate_member_id` (`member_id`),
  CONSTRAINT `election_candidate_election_position_id_fkey` FOREIGN KEY (`election_position_id`) REFERENCES `election_position` (`id`),
  CONSTRAINT `election_candidate_member_id` FOREIGN KEY (`member_id`) REFERENCES `members` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.06 sec)

mysql> select distinct member_id from election_vote where candidate_id in (select id from election_candidate where election_position_id=5);
+-----------+
| member_id |
+-----------+
|       XXX |
|       XXX |
+-----------+
2 rows in set (0.00 sec)

mysql> create temporary table t1 as select distinct member_id from election_vote where candidate_id in (select id from election_candidate where election_position_id=5);
Query OK, 53 rows affected (0.05 sec)
Records: 53  Duplicates: 0  Warnings: 0

mysql> select count(*) from t1;
+----------+
| count(*) |
+----------+
|       53 |
+----------+
1 row in set (0.00 sec)

NOTE: the second result is correct.

mysql> explain select distinct member_id from election_vote where candidate_id in (select id from election_candidate where election_position_id=5)\G *************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: election_vote
         type: range
possible_keys: NULL
          key: election_vote_uniq
      key_len: 4
          ref: NULL
         rows: 199
        Extra: Using where; Using index for group-by
*************************** 2. row ***************************
           id: 2
  select_type: DEPENDENT SUBQUERY
        table: election_candidate
         type: unique_subquery
possible_keys: PRIMARY,election_candidate_pkey
          key: PRIMARY
      key_len: 4
          ref: func
         rows: 1
        Extra: Using index; Using where
2 rows in set (0.00 sec)

So, let's look at the subquery:

mysql> select id from election_candidate where election_position_id=5;
 +----+
| id |
+----+
|  7 |
|  5 |
+----+
2 rows in set (0.00 sec)

To further add to the fun:

mysql> select count(distinct member_id) from election_vote where candidate_id in (select id from election_candidate where election_position_id=5); +---------------------------+
| count(distinct member_id) |
+---------------------------+
|                        53 |
+---------------------------+
1 row in set (0.01 sec)

mysql> select distinct member_id from election_vote where candidate_id in (select id from election_candidate where election_position_id=5);
+-----------+
| member_id |
+-----------+
|       XXX |
|       XXX |
+-----------+
2 rows in set (0.00 sec)

mysql>

So let's explain it:

mysql> explain select count(distinct member_id) from election_vote where candidate_id in (select id from election_candidate where election_position_id=5);
+----+--------------------+--------------------+-----------------+---------------------------------+---------------------------------+---------+------+------+--------------------------+
| id | select_type        | table              | type            | possible_keys                   | key                             | key_len | ref  | rows | Extra                    |
+----+--------------------+--------------------+-----------------+---------------------------------+---------------------------------+---------+------+------+--------------------------+
|  1 | PRIMARY            | election_vote      | index           | NULL                    | election_vote_candidate_id_fkey | 4       | NULL | 2181 | Using where; Using index |
|  2 | DEPENDENT SUBQUERY | election_candidate | unique_subquery | PRIMARY,election_candidate_pkey | PRIMARY                         | 4       | func |    1 | Using index; Using where |
+----+--------------------+--------------------+-----------------+---------------------------------+---------------------------------+---------+------+------+--------------------------+
2 rows in set (0.00 sec)

mysql> explain select distinct member_id from election_vote where candidate_id in (select id from election_candidate where election_position_id=5);
+----+--------------------+--------------------+-----------------+---------------------------------+--------------------+---------+------+------+---------------------------------------+
| id | select_type        | table              | type            | possible_keys                   | key                | key_len | ref  | rows | Extra                         |
+----+--------------------+--------------------+-----------------+---------------------------------+--------------------+---------+------+------+---------------------------------------+
|  1 | PRIMARY            | election_vote      | range           | NULL                    | election_vote_uniq | 4       | NULL |  199 | Using where; Using index for group-by |
|  2 | DEPENDENT SUBQUERY | election_candidate | unique_subquery | PRIMARY,election_candidate_pkey | PRIMARY            | 4       | func |    1 | Using index; Using where              |
+----+--------------------+--------------------+-----------------+---------------------------------+--------------------+---------+------+------+---------------------------------------+
2 rows in set (0.00 sec)

Suggested fix:
use the correct index and get the correct result.
[11 Mar 2006 22:08] Evgeny Potemkin
Can you provide example of data on which the bug occurs?
[11 Apr 2006 23:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".