Fixed bug lp:900375

The range optimizer incorrectly chose a loose scan for group by
when there is a correlated WHERE condition. This range access
method cannot be executed for correlated conditions also with the
"range checked for each record" because generally the range access
method can change for each outer record. Loose scan destructively
changes the query plan and removes the GROUP operation, which will
result in wrong query plans if another range access is chosen
dynamically.
This commit is contained in:
unknown 2011-12-12 12:36:46 +02:00
parent 314c377422
commit 6404504d0c
3 changed files with 255 additions and 1 deletions

View file

@ -2790,11 +2790,240 @@ INSERT INTO t2 VALUES (1),(1),(1),(4),(4),(5),(5),(8),(8),(9);
explain select (select t2.a from t2 where t2.a >= t1.a group by t2.a) from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
2 DEPENDENT SUBQUERY t2 range a a 5 NULL 6 Using where; Using index for group-by
2 DEPENDENT SUBQUERY t2 index a a 5 NULL 10 Using where; Using index
select (select t2.a from t2 where t2.a >= t1.a group by t2.a) from t1;
(select t2.a from t2 where t2.a >= t1.a group by t2.a)
NULL
NULL
9
drop table t1, t2;
#
# LP BUG#900375 Wrong result with derived_merge=ON, DISTINCT or GROUP BY, EXISTS
#
CREATE TABLE t1 ( a INT, b INT, KEY (b) );
INSERT INTO t1 VALUES
(100,10),(101,11),(102,12),(103,13),(104,14),
(105,15),(106,16),(107,17),(108,18),(109,19);
EXPLAIN
SELECT alias1.* FROM t1, (SELECT * FROM t1) AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL b 5 NULL 10 Using index
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10 Using where; Using join buffer
3 DEPENDENT SUBQUERY t1 index b b 5 NULL 10 Using where; Using index; Using temporary
2 DERIVED t1 ALL NULL NULL NULL NULL 10
SELECT alias1.* FROM t1, (SELECT * FROM t1) AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
a b
100 10
100 10
100 10
100 10
100 10
100 10
100 10
100 10
100 10
100 10
101 11
101 11
101 11
101 11
101 11
101 11
101 11
101 11
101 11
101 11
102 12
102 12
102 12
102 12
102 12
102 12
102 12
102 12
102 12
102 12
103 13
103 13
103 13
103 13
103 13
103 13
103 13
103 13
103 13
103 13
104 14
104 14
104 14
104 14
104 14
104 14
104 14
104 14
104 14
104 14
105 15
105 15
105 15
105 15
105 15
105 15
105 15
105 15
105 15
105 15
106 16
106 16
106 16
106 16
106 16
106 16
106 16
106 16
106 16
106 16
107 17
107 17
107 17
107 17
107 17
107 17
107 17
107 17
107 17
107 17
108 18
108 18
108 18
108 18
108 18
108 18
108 18
108 18
108 18
108 18
109 19
109 19
109 19
109 19
109 19
109 19
109 19
109 19
109 19
109 19
EXPLAIN
SELECT alias1.* FROM t1, t1 AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL b 5 NULL 10 Using index
1 PRIMARY alias1 ALL NULL NULL NULL NULL 10 Using where; Using join buffer
2 DEPENDENT SUBQUERY t1 index b b 5 NULL 10 Using where; Using index; Using temporary
SELECT alias1.* FROM t1, t1 AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
a b
100 10
100 10
100 10
100 10
100 10
100 10
100 10
100 10
100 10
100 10
101 11
101 11
101 11
101 11
101 11
101 11
101 11
101 11
101 11
101 11
102 12
102 12
102 12
102 12
102 12
102 12
102 12
102 12
102 12
102 12
103 13
103 13
103 13
103 13
103 13
103 13
103 13
103 13
103 13
103 13
104 14
104 14
104 14
104 14
104 14
104 14
104 14
104 14
104 14
104 14
105 15
105 15
105 15
105 15
105 15
105 15
105 15
105 15
105 15
105 15
106 16
106 16
106 16
106 16
106 16
106 16
106 16
106 16
106 16
106 16
107 17
107 17
107 17
107 17
107 17
107 17
107 17
107 17
107 17
107 17
108 18
108 18
108 18
108 18
108 18
108 18
108 18
108 18
108 18
108 18
109 19
109 19
109 19
109 19
109 19
109 19
109 19
109 19
109 19
109 19
drop table t1;
End of 5.1 tests

View file

@ -1114,4 +1114,27 @@ select (select t2.a from t2 where t2.a >= t1.a group by t2.a) from t1;
drop table t1, t2;
--echo #
--echo # LP BUG#900375 Wrong result with derived_merge=ON, DISTINCT or GROUP BY, EXISTS
--echo #
CREATE TABLE t1 ( a INT, b INT, KEY (b) );
INSERT INTO t1 VALUES
(100,10),(101,11),(102,12),(103,13),(104,14),
(105,15),(106,16),(107,17),(108,18),(109,19);
EXPLAIN
SELECT alias1.* FROM t1, (SELECT * FROM t1) AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
SELECT alias1.* FROM t1, (SELECT * FROM t1) AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
EXPLAIN
SELECT alias1.* FROM t1, t1 AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
SELECT alias1.* FROM t1, t1 AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
drop table t1;
--echo End of 5.1 tests

View file

@ -9337,6 +9337,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
DBUG_RETURN(NULL);
if (table->s->keys == 0) /* There are no indexes to use. */
DBUG_RETURN(NULL);
if (join->conds && join->conds->used_tables() & OUTER_REF_TABLE_BIT)
DBUG_RETURN(NULL); /* Cannot execute with correlated conditions. */
/* Analyze the query in more detail. */
List_iterator<Item> select_items_it(join->fields_list);