maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #02608
Rev 2777: Apply fix by Roy Lyseng: in file:///home/psergey/dev/maria-5.3-subqueries-r7-rel/
At file:///home/psergey/dev/maria-5.3-subqueries-r7-rel/
------------------------------------------------------------
revno: 2777
revision-id: psergey@xxxxxxxxxxxx-20100315063254-z1ctm7srl0573s5c
parent: psergey@xxxxxxxxxxxx-20100314182543-4t3ehit7df20adu8
committer: Sergey Petrunya <psergey@xxxxxxxxxxxx>
branch nick: maria-5.3-subqueries-r7-rel
timestamp: Mon 2010-03-15 09:32:54 +0300
message:
Apply fix by Roy Lyseng:
Bug#48623: Multiple subqueries are optimized incorrectly
The function setup_semijoin_dups_elimination() has a major loop that
goes through every table in the JOIN object. Usually, there is a normal
"plus one" increment in the for loop that implements this, but each semijoin
nest is treated as one entity and there is another increment that skips past
the semijoin nest to the next table in the JOIN object. However, when
combining these two increments, the next joined table is skipped, and if that
happens to be the start of another semijoin nest, the correct processing
for that nest will not be carried out.
=== modified file 'mysql-test/r/subselect_sj.result'
--- a/mysql-test/r/subselect_sj.result 2010-03-14 18:25:43 +0000
+++ b/mysql-test/r/subselect_sj.result 2010-03-15 06:32:54 +0000
@@ -1079,3 +1079,36 @@
partner_id
partner2
drop table t1,t2,t3,t4;
+#
+# Bug#48623 Multiple subqueries are optimized incorrectly
+#
+CREATE TABLE t1(val VARCHAR(10));
+CREATE TABLE t2(val VARCHAR(10));
+CREATE TABLE t3(val VARCHAR(10));
+INSERT INTO t1 VALUES('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+INSERT INTO t2 VALUES('aaa'), ('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+INSERT INTO t3 VALUES('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+EXPLAIN
+SELECT *
+FROM t1
+WHERE t1.val IN (SELECT t2.val FROM t2
+WHERE t2.val LIKE 'a%' OR t2.val LIKE 'e%')
+AND t1.val IN (SELECT t3.val FROM t3
+WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5
+1 PRIMARY t3 ALL NULL NULL NULL NULL 5 Using where; FirstMatch(t1)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; FirstMatch(t3)
+SELECT *
+FROM t1
+WHERE t1.val IN (SELECT t2.val FROM t2
+WHERE t2.val LIKE 'a%' OR t2.val LIKE 'e%')
+AND t1.val IN (SELECT t3.val FROM t3
+WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
+val
+aaa
+eee
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+# End of Bug#48623
=== modified file 'mysql-test/r/subselect_sj_jcl6.result'
--- a/mysql-test/r/subselect_sj_jcl6.result 2010-03-14 18:25:43 +0000
+++ b/mysql-test/r/subselect_sj_jcl6.result 2010-03-15 06:32:54 +0000
@@ -1083,6 +1083,39 @@
partner_id
partner2
drop table t1,t2,t3,t4;
+#
+# Bug#48623 Multiple subqueries are optimized incorrectly
+#
+CREATE TABLE t1(val VARCHAR(10));
+CREATE TABLE t2(val VARCHAR(10));
+CREATE TABLE t3(val VARCHAR(10));
+INSERT INTO t1 VALUES('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+INSERT INTO t2 VALUES('aaa'), ('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+INSERT INTO t3 VALUES('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+EXPLAIN
+SELECT *
+FROM t1
+WHERE t1.val IN (SELECT t2.val FROM t2
+WHERE t2.val LIKE 'a%' OR t2.val LIKE 'e%')
+AND t1.val IN (SELECT t3.val FROM t3
+WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5
+1 PRIMARY t3 ALL NULL NULL NULL NULL 5 Using where; FirstMatch(t1); Using join buffer
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; FirstMatch(t3); Using join buffer
+SELECT *
+FROM t1
+WHERE t1.val IN (SELECT t2.val FROM t2
+WHERE t2.val LIKE 'a%' OR t2.val LIKE 'e%')
+AND t1.val IN (SELECT t3.val FROM t3
+WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
+val
+aaa
+eee
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+# End of Bug#48623
#
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
#
=== modified file 'mysql-test/t/subselect_sj.test'
--- a/mysql-test/t/subselect_sj.test 2010-03-14 18:25:43 +0000
+++ b/mysql-test/t/subselect_sj.test 2010-03-15 06:32:54 +0000
@@ -943,5 +943,35 @@
execute stmt;
drop table t1,t2,t3,t4;
-
-
+--echo #
+--echo # Bug#48623 Multiple subqueries are optimized incorrectly
+--echo #
+
+CREATE TABLE t1(val VARCHAR(10));
+CREATE TABLE t2(val VARCHAR(10));
+CREATE TABLE t3(val VARCHAR(10));
+
+INSERT INTO t1 VALUES('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+INSERT INTO t2 VALUES('aaa'), ('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+INSERT INTO t3 VALUES('aaa'), ('bbb'), ('eee'), ('mmm'), ('ppp');
+
+EXPLAIN
+SELECT *
+FROM t1
+WHERE t1.val IN (SELECT t2.val FROM t2
+ WHERE t2.val LIKE 'a%' OR t2.val LIKE 'e%')
+ AND t1.val IN (SELECT t3.val FROM t3
+ WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
+
+SELECT *
+FROM t1
+WHERE t1.val IN (SELECT t2.val FROM t2
+ WHERE t2.val LIKE 'a%' OR t2.val LIKE 'e%')
+ AND t1.val IN (SELECT t3.val FROM t3
+ WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+
+--echo # End of Bug#48623
=== modified file 'sql/opt_subselect.cc'
--- a/sql/opt_subselect.cc 2010-03-14 18:25:43 +0000
+++ b/sql/opt_subselect.cc 2010-03-15 06:32:54 +0000
@@ -3030,7 +3030,7 @@
THD *thd= join->thd;
DBUG_ENTER("setup_semijoin_dups_elimination");
- for (i= join->const_tables ; i < join->tables ; i++)
+ for (i= join->const_tables ; i < join->tables; )
{
JOIN_TAB *tab=join->join_tab + i;
POSITION *pos= join->best_positions + i;
@@ -3039,7 +3039,7 @@
case SJ_OPT_MATERIALIZE:
case SJ_OPT_MATERIALIZE_SCAN:
/* Do nothing */
- i += pos->n_sj_tables;
+ i+= pos->n_sj_tables;
break;
case SJ_OPT_LOOSE_SCAN:
{
@@ -3055,7 +3055,7 @@
tab->loosescan_key_len= keylen;
if (pos->n_sj_tables > 1)
tab[pos->n_sj_tables - 1].do_firstmatch= tab;
- i += pos->n_sj_tables;
+ i+= pos->n_sj_tables;
break;
}
case SJ_OPT_DUPS_WEEDOUT:
@@ -3152,7 +3152,7 @@
join->join_tab[first_table].flush_weedout_table= sjtbl;
join->join_tab[i + pos->n_sj_tables - 1].check_weed_out_table= sjtbl;
- i += pos->n_sj_tables;
+ i+= pos->n_sj_tables;
break;
}
case SJ_OPT_FIRST_MATCH:
@@ -3174,10 +3174,11 @@
}
}
j[-1].do_firstmatch= jump_to;
- i += pos->n_sj_tables;
+ i+= pos->n_sj_tables;
break;
}
case SJ_OPT_NONE:
+ i++;
break;
}
}