Bug #80942 select query returns rows it shouldnt
Submitted: 3 Apr 2016 22:19 Modified: 4 Apr 2016 16:48
Reporter: Mr Jay Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S2 (Serious)
Version:5.6.24 OS:Linux (x64)
Assigned to: CPU Architecture:Any
Tags: access, query, SELECT

[3 Apr 2016 22:19] Mr Jay
Description:
Both innodb and myisam engines return content in the table room when it shouldnt

Query 1:
select ra.room_id, r.id, count(rmcount.account_id)  from room_access ra left join room r on r.id=ra.room_id left join room_member rmcount on rmcount.room_id=ra.room_id
  where ra.account_id in (0, 26412) and ra.domain_id in (0, 2602) and ra.group_id in (0) and ra.room_id=2;

OK, expected data in return:
+---------+------+---------------------------+
| room_id | id   | count(rmcount.account_id) |
+---------+------+---------------------------+
|    NULL | NULL |                         0 |
+---------+------+---------------------------+

Query 2:
select ra.room_id, r.id, count(rmcount.account_id)  from room_access ra left join room r on r.id=ra.room_id left join room_member rmcount on rmcount.room_id=ra.room_id
  where ra.account_id in (0, 26412) and ra.domain_id in (0, 2602) and ra.group_id in (0) and ra.room_id=2  and ra.room_id=r.id;

Illegal room row data in return:
+---------+----+---------------------------+
| room_id | id | count(rmcount.account_id) |
+---------+----+---------------------------+
|    NULL |  2 |                         0 |
+---------+----+---------------------------+

How to repeat:
CREATE TABLE `room` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `account_id` bigint(20) unsigned NOT NULL,
  `domain_id` bigint(20) unsigned NOT NULL,
  `server_database_id` int(10) unsigned NOT NULL DEFAULT '3',
  `name` varchar(64) NOT NULL,
  `description` tinytext,
  `last_message_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `moderated` tinyint(1) NOT NULL DEFAULT '0',
  `securitylevel` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `enabled` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`),
  UNIQUE KEY `domain_id` (`domain_id`,`name`),
  KEY `account_id` (`account_id`),
  KEY `account_id_2` (`account_id`,`domain_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

CREATE TABLE `room_access` (
  `room_id` bigint(20) unsigned NOT NULL,
  `account_id` bigint(20) unsigned NOT NULL,
  `domain_id` bigint(20) unsigned NOT NULL,
  `group_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `is_admin` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`room_id`,`account_id`,`domain_id`,`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `room_member` (
  `room_id` bigint(20) unsigned NOT NULL,
  `account_id` bigint(20) unsigned NOT NULL,
  `last_message_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `last_online` datetime NOT NULL,
  `is_admin` tinyint(1) NOT NULL DEFAULT '0',
  `is_moderator` tinyint(1) NOT NULL DEFAULT '0',
  `notification_sound` tinyint(1) NOT NULL DEFAULT '0',
  `notification_desktop` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`room_id`,`account_id`),
  KEY `room_id` (`room_id`),
  KEY `account_id` (`account_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

select * from room where id=2;
+----+------------+-----------+--------------------+----------+-------------------------+-----------------+-----------+---------------+---------+
| id | account_id | domain_id | server_database_id | name     | description             | last_message_id | moderated | securitylevel | enabled |
+----+------------+-----------+--------------------+----------+-------------------------+-----------------+-----------+---------------+---------+
|  2 |          1 |         4 |                  3 | Test-room |   |              46 |         0 |             0 |       1 |
+----+------------+-----------+--------------------+----------+-------------------------+-----------------+-----------+---------------+---------+

select * from room_access where account_id in (0, 26412) and domain_id in (0, 2602) and group_id in (0) and room_id=2;            
Empty set (0.00 sec)

select count(*) from room_member where room_id=2;
+----------+
| count(*) |
+----------+
|        5 |
+----------+

Suggested fix:
Since no rows match room_access, the join on room should not return any rows (Second column id should be NULL).
However, it does, but only if ra.room_id=r.id is applied to the where-query.
Ra.room_id is null, so this doesnt make any sense..
[4 Apr 2016 12:02] MySQL Verification Team
Hello Jay,

Thank you for the report.
Could you please provide exact repeatable test case( I see you have provided table DDL but also need subset of data to reproduce this issue at our end)? You may want to mark it as private after uploading the data.

If you can provide more information, feel free to add it to this bug and change the status back to 'Open'.

Thank you for your interest in MySQL.

Thanks,
Umesh
[4 Apr 2016 16:48] Mr Jay
attached the dump of the 3 tables