[Commits] Rev 3766: Fixed bug mdev-5686. in file:///home/igor/maria/maria-5.3/

Igor Babaev igor at askmonty.org
Thu Mar 6 23:56:35 EET 2014


At file:///home/igor/maria/maria-5.3/

------------------------------------------------------------
revno: 3766
revision-id: igor at askmonty.org-20140306215634-4gm5hv023ynkxfzq
parent: igor at askmonty.org-20140221052733-ypg4dpfcmy5l0b3q
committer: Igor Babaev <igor at askmonty.org>
branch nick: maria-5.3
timestamp: Thu 2014-03-06 13:56:34 -0800
message:
  Fixed bug mdev-5686.
  The calls of the function remove_eq_conds() may change the and/or structure
  of the where conditions. So JOIN::equal_cond should be updated for non-recursive
  calls of remove_eq_conds(). 
-------------- next part --------------
=== modified file 'mysql-test/r/subselect4.result'
--- a/mysql-test/r/subselect4.result	2014-02-06 01:47:38 +0000
+++ b/mysql-test/r/subselect4.result	2014-03-06 21:56:34 +0000
@@ -2375,5 +2375,27 @@
 id	a2	a3	id	a2	a3
 DROP VIEW v2;
 DROP TABLE t1,t2;
+#
+# MDEV-5686: degenerate disjunct in NOT IN subquery
+#
+CREATE TABLE t1 (a int, b int, c varchar(3)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,1,'CAN'),(2,2,'AUS');
+CREATE TABLE t2 (f int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (3);
+EXPLAIN EXTENDED
+SELECT * FROM t2 
+WHERE f NOT IN (SELECT b FROM t1
+WHERE 0 OR (c IN ('USA') OR c NOT IN ('USA')) AND a = b);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	PRIMARY	t2	system	NULL	NULL	NULL	NULL	1	100.00	
+2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
+Warnings:
+Note	1003	select 3 AS `f` from `test`.`t2` where (not(<expr_cache><3>(<in_optimizer>(3,<exists>(select `test`.`t1`.`b` from `test`.`t1` where (((`test`.`t1`.`c` = 'USA') or (`test`.`t1`.`c` <> 'USA')) and trigcond(((<cache>(3) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`))) and (`test`.`t1`.`b` = `test`.`t1`.`a`)) having trigcond(<is_not_null_test>(`test`.`t1`.`b`)))))))
+SELECT * FROM t2 
+WHERE f NOT IN (SELECT b FROM t1
+WHERE 0 OR (c IN ('USA') OR c NOT IN ('USA')) AND a = b);
+f
+3
+DROP TABLE t1,t2;
 SET optimizer_switch= @@global.optimizer_switch;
 set @@tmp_table_size= @@global.tmp_table_size;

=== modified file 'mysql-test/t/subselect4.test'
--- a/mysql-test/t/subselect4.test	2014-02-06 01:47:38 +0000
+++ b/mysql-test/t/subselect4.test	2014-03-06 21:56:34 +0000
@@ -1970,5 +1970,26 @@
 DROP VIEW v2;
 DROP TABLE t1,t2;
 
+--echo #
+--echo # MDEV-5686: degenerate disjunct in NOT IN subquery
+--echo #
+
+CREATE TABLE t1 (a int, b int, c varchar(3)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,1,'CAN'),(2,2,'AUS');
+
+CREATE TABLE t2 (f int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (3);
+
+EXPLAIN EXTENDED
+SELECT * FROM t2 
+  WHERE f NOT IN (SELECT b FROM t1
+                    WHERE 0 OR (c IN ('USA') OR c NOT IN ('USA')) AND a = b);
+
+SELECT * FROM t2 
+  WHERE f NOT IN (SELECT b FROM t1
+                    WHERE 0 OR (c IN ('USA') OR c NOT IN ('USA')) AND a = b);
+
+DROP TABLE t1,t2;
+
 SET optimizer_switch= @@global.optimizer_switch;
 set @@tmp_table_size= @@global.tmp_table_size;

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2014-02-21 05:27:33 +0000
+++ b/sql/sql_select.cc	2014-03-06 21:56:34 +0000
@@ -3530,6 +3530,9 @@
   { 
     conds->update_used_tables();
     conds= remove_eq_conds(join->thd, conds, &join->cond_value);
+    if (conds && conds->type() == Item::COND_ITEM &&
+        ((Item_cond*) conds)->functype() == Item_func::COND_AND_FUNC)
+      join->cond_equal= &((Item_cond_and*) conds)->cond_equal;
     join->select_lex->where= conds;
     if (join->cond_value == Item::COND_FALSE)
     {
@@ -13228,7 +13231,10 @@
       Remove all and-levels where CONST item != CONST item
     */
     DBUG_EXECUTE("where",print_where(conds,"after const change", QT_ORDINARY););
-    conds= remove_eq_conds(thd, conds, cond_value) ;
+    conds= remove_eq_conds(thd, conds, cond_value);
+    if (conds && conds->type() == Item::COND_ITEM &&
+        ((Item_cond*) conds)->functype() == Item_func::COND_AND_FUNC)
+      join->cond_equal= &((Item_cond_and*) conds)->cond_equal;
     DBUG_EXECUTE("info",print_where(conds,"after remove", QT_ORDINARY););
   }
   DBUG_RETURN(conds);



More information about the commits mailing list