Commit c64fda36 authored by Igor Babaev's avatar Igor Babaev

Fixed LP bug #900469.

The execution plan cannot use sorting on the first table from the
sequence of the joined tables if it plans to employ the block-based
hash join algorithm.
parent 42db50ca
......@@ -5264,4 +5264,53 @@ a
SET SESSION join_cache_level = DEFAULT;
SET optimizer_switch=@tmp_optimizer_switch;
DROP TABLE t1,t2,t3;
#
# Bug #900469: semijoin + BNLH + ORDER BY
#
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (8,10);
CREATE TABLE t2 (c int, d int);
INSERT INTO t2 VALUES (8,10);
INSERT INTO t2 VALUES (9,11);
CREATE TABLE t3 (c int, d int);
INSERT INTO t3 VALUES (8,10);
INSERT INTO t3 VALUES (9,11);
SET @tmp_optimizer_switch=@@optimizer_switch;
set @@optimizer_switch='semijoin_with_cache=on';
SET join_cache_level=1;
EXPLAIN
SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
a b c d
8 10 8 10
8 10 9 11
SET join_cache_level=3;
EXPLAIN
SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
1 PRIMARY t3 hash_ALL NULL #hash#$hj 5 const 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNLH join)
SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c);
a b c d
8 10 8 10
8 10 9 11
SET join_cache_level=3;
EXPLAIN
SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
1 PRIMARY t3 hash_ALL NULL #hash#$hj 5 const 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNLH join)
SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
a b c d
8 10 8 10
8 10 9 11
SET SESSION join_cache_level = DEFAULT;
SET optimizer_switch=@tmp_optimizer_switch;
DROP TABLE t1,t2,t3;
set @@optimizer_switch=@save_optimizer_switch;
......@@ -3323,5 +3323,43 @@ SET optimizer_switch=@tmp_optimizer_switch;
DROP TABLE t1,t2,t3;
--echo #
--echo # Bug #900469: semijoin + BNLH + ORDER BY
--echo #
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (8,10);
CREATE TABLE t2 (c int, d int);
INSERT INTO t2 VALUES (8,10);
INSERT INTO t2 VALUES (9,11);
CREATE TABLE t3 (c int, d int);
INSERT INTO t3 VALUES (8,10);
INSERT INTO t3 VALUES (9,11);
SET @tmp_optimizer_switch=@@optimizer_switch;
set @@optimizer_switch='semijoin_with_cache=on';
SET join_cache_level=1;
EXPLAIN
SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
SET join_cache_level=3;
EXPLAIN
SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c);
SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c);
SET join_cache_level=3;
EXPLAIN
SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
SET SESSION join_cache_level = DEFAULT;
SET optimizer_switch=@tmp_optimizer_switch;
DROP TABLE t1,t2,t3;
# this must be the last command in the file
set @@optimizer_switch=@save_optimizer_switch;
......@@ -1448,7 +1448,7 @@ JOIN::optimize()
order=0;
// Can't use sort on head table if using join buffering
if (full_join)
if (full_join || hash_join)
{
TABLE *stable= (sort_by_table == (TABLE *) 1 ?
join_tab[const_tables].table : sort_by_table);
......@@ -7036,6 +7036,7 @@ get_best_combination(JOIN *join)
DBUG_RETURN(TRUE);
join->full_join=0;
join->hash_join= FALSE;
used_tables= OUTER_REF_TABLE_BIT; // Outer row is already read
......@@ -7125,6 +7126,11 @@ get_best_combination(JOIN *join)
}
else if (create_ref_for_key(join, j, keyuse, used_tables))
DBUG_RETURN(TRUE); // Something went wrong
if ((j->type == JT_REF || j->type == JT_EQ_REF) &&
is_hash_join_key_no(j->ref.key))
join->hash_join= TRUE;
loop_end:
/*
Save records_read in JOIN_TAB so that select_describe()/etc don't have
......
......@@ -912,6 +912,7 @@ class JOIN :public Sql_alloc
*/
bool sort_and_group;
bool first_record,full_join, no_field_update;
bool hash_join;
bool do_send_rows;
/**
TRUE when we want to resume nested loop iterations when
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment