Wrong result with view + outer join + uncorrelated subquery (non-semijoin)
| Affects | Status | Importance | Assigned to | Milestone | |
|---|---|---|---|---|---|
| MariaDB |
Fix Released
|
High
|
Sergey Petrunia | ||
Bug Description
If the following query:
SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM t3 ) AND t1.b IS NULL ;
is run without semijoin, it returns no rows whereas if a base table is used insted of the view, the query returns:
+------
| a | b | a | b |
+------
| NULL | NULL | 1 | 0 |
| NULL | NULL | 1 | 0 |
+------
explain:
MariaDB [test]> explain SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM t3 ) AND t1.b IS NULL ;
+----+-
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-
| 1 | PRIMARY | t1 | ALL | NULL | NULL | NULL | NULL | 2 | Using where |
| 1 | PRIMARY | t2 | ALL | NULL | NULL | NULL | NULL | 2 | Using where; Using join buffer (flat, BNL join) |
| 2 | DEPENDENT SUBQUERY | t3 | ALL | NULL | NULL | NULL | NULL | 2 | Using where |
+----+-
minimal optimizer_
full optimizer switch:
index_merge=
test case:
CREATE TABLE t1 ( a int, b int );
INSERT INTO t1 VALUES (0,0),(0,0);
CREATE TABLE t2 ( a int, b int );
INSERT IGNORE INTO t2 VALUES (1,0),(1,0);
CREATE TABLE t3 ( b int );
INSERT IGNORE INTO t3 VALUES (0),(0);
CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2;
SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM t3 ) AND t1.b IS NULL ;
Repeatable in maria-5.3. Not repeatable in maria-5.2,mysql-5.5
| Changed in maria: | |
| milestone: | none → 5.3 |
| Changed in maria: | |
| assignee: | nobody → Sergey Petrunia (sergefp) |
| Changed in maria: | |
| importance: | Undecided → High |
| Changed in maria: | |
| importance: | High → Low |
| importance: | Low → High |
| Changed in maria: | |
| status: | New → Confirmed |
| Changed in maria: | |
| status: | Confirmed → Fix Committed |
| Changed in maria: | |
| status: | Fix Committed → Fix Released |

* The bug disappears if RIGHT JOIN is changed to equivalent LEFT JOIN.
EXPLAINs are different: ------- ------- -----+- ------+ ------+ ------- ------- -+----- -+----- ----+-- ----+-- ----+-- ------- -+----- ------- ------- ------- ------- ------- ------- --+ ------- ------- -----+- ------+ ------+ ------- ------- -+----- -+----- ----+-- ----+-- ----+-- ------- -+----- ------- ------- ------- ------- ------- ------- --+ ------- ------- -----+- ------+ ------+ ------- ------- -+----- -+----- ----+-- ----+-- ----+-- ------- -+----- ------- ------- ------- ------- ------- ------- --+
MariaDB [bug833600]> explain extended SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM t3 ) AND t1.b IS NULL ;
+----+-
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-
| 1 | PRIMARY | t1 | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | Using where |
| 1 | PRIMARY | t2 | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | Using where; Using join buffer (flat, BNL join) |
| 2 | DEPENDENT SUBQUERY | t3 | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | Using where |
+----+-
3 rows in set, 1 warning (0.02 sec)
MariaDB [bug833600]> explain extended SELECT * FROM t1 RIGHT JOIN t2 ON ( t2.a = t1.a ) WHERE t2.b IN ( SELECT b FROM t3 ) AND t1.b IS NULL ; ------- ------- -----+- ------+ ------+ ------- ------- -+----- -+----- ----+-- ----+-- ----+-- ------- -+----- ------- -+ ------- ------- -----+- ------+ ------+ ------- ------- -+----- -+----- ----+-- ----+-- ----+-- ------- -+----- ------- -+ ------- ------- -----+- ------+ ------+ ------- ------- -+----- -+----- ----+-- ----+-- ----+-- ------- -+----- ------- -+
+----+-
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-
| 1 | PRIMARY | t2 | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | Using where |
| 1 | PRIMARY | t1 | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | Using where |
| 2 | DEPENDENT SUBQUERY | t3 | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | Using where |
+----+-
3 rows in set, 1 warning (0.01 sec)