mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Fixed LP bug #925985.
If the flag 'optimize_join_buffer_size' is set to 'off' and the value of the system variable 'join_buffer_size' is greater than the value of the system variable 'join_buffer_space_limit' than no join cache can be employed to join tables of the executed query. A bug in the function JOIN_CACHE::alloc_buffer allowed to use join buffer even in this case while another bug in the function revise_cache_usage could cause a crash of the server in this case if the chosen execution plan for the query contained outer join or semi-join operation.
This commit is contained in:
@ -5534,4 +5534,39 @@ we
|
|||||||
set join_cache_level = default;
|
set join_cache_level = default;
|
||||||
set optimizer_switch=@tmp_optimizer_switch;
|
set optimizer_switch=@tmp_optimizer_switch;
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
|
#
|
||||||
|
# Bug #925985: LEFT JOIN with optimize_join_buffer_size=off +
|
||||||
|
# join_buffer_size > join_buffer_space_limit
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a int);
|
||||||
|
INSERT INTO t1 VALUES (5), (3);
|
||||||
|
CREATE TABLE t2 (a int, b int);
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
(3,30), (1,10), (7,70), (2,20),
|
||||||
|
(3,31), (1,11), (7,71), (2,21),
|
||||||
|
(3,32), (1,12), (7,72), (2,22);
|
||||||
|
CREATE TABLE t3 (b int, c int);
|
||||||
|
INSERT INTO t3 VALUES (32, 302), (42,400), (30,300);
|
||||||
|
set @tmp_optimizer_switch=@@optimizer_switch;
|
||||||
|
set optimizer_switch='optimize_join_buffer_size=off';
|
||||||
|
set join_buffer_space_limit=4096;
|
||||||
|
set join_buffer_size=4096*2;
|
||||||
|
set join_cache_level=2;
|
||||||
|
set optimizer_switch='outer_join_with_cache=on';
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
|
||||||
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||||
|
1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (incremental, BNL join)
|
||||||
|
SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a;
|
||||||
|
a a b b c
|
||||||
|
3 3 30 30 300
|
||||||
|
3 3 31 NULL NULL
|
||||||
|
3 3 32 32 302
|
||||||
|
set join_buffer_space_limit=default;
|
||||||
|
set join_buffer_size=default;
|
||||||
|
set join_cache_level=default;
|
||||||
|
set optimizer_switch=@tmp_optimizer_switch;
|
||||||
|
DROP TABLE t1,t2,t3;
|
||||||
set @@optimizer_switch=@save_optimizer_switch;
|
set @@optimizer_switch=@save_optimizer_switch;
|
||||||
|
@ -3547,5 +3547,40 @@ set optimizer_switch=@tmp_optimizer_switch;
|
|||||||
|
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #925985: LEFT JOIN with optimize_join_buffer_size=off +
|
||||||
|
--echo # join_buffer_size > join_buffer_space_limit
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a int);
|
||||||
|
INSERT INTO t1 VALUES (5), (3);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (a int, b int);
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
(3,30), (1,10), (7,70), (2,20),
|
||||||
|
(3,31), (1,11), (7,71), (2,21),
|
||||||
|
(3,32), (1,12), (7,72), (2,22);
|
||||||
|
|
||||||
|
CREATE TABLE t3 (b int, c int);
|
||||||
|
INSERT INTO t3 VALUES (32, 302), (42,400), (30,300);
|
||||||
|
|
||||||
|
set @tmp_optimizer_switch=@@optimizer_switch;
|
||||||
|
set optimizer_switch='optimize_join_buffer_size=off';
|
||||||
|
set join_buffer_space_limit=4096;
|
||||||
|
set join_buffer_size=4096*2;
|
||||||
|
set join_cache_level=2;
|
||||||
|
set optimizer_switch='outer_join_with_cache=on';
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a;
|
||||||
|
SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a;
|
||||||
|
|
||||||
|
set join_buffer_space_limit=default;
|
||||||
|
set join_buffer_size=default;
|
||||||
|
set join_cache_level=default;
|
||||||
|
set optimizer_switch=@tmp_optimizer_switch;
|
||||||
|
|
||||||
|
DROP TABLE t1,t2,t3;
|
||||||
|
|
||||||
# this must be the last command in the file
|
# this must be the last command in the file
|
||||||
set @@optimizer_switch=@save_optimizer_switch;
|
set @@optimizer_switch=@save_optimizer_switch;
|
||||||
|
@ -898,6 +898,8 @@ int JOIN_CACHE::alloc_buffer()
|
|||||||
curr_buff_space_sz+= cache->get_join_buffer_size();
|
curr_buff_space_sz+= cache->get_join_buffer_size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
curr_min_buff_space_sz+= min_buff_size;
|
||||||
|
curr_buff_space_sz+= buff_size;
|
||||||
|
|
||||||
if (curr_min_buff_space_sz > join_buff_space_limit ||
|
if (curr_min_buff_space_sz > join_buff_space_limit ||
|
||||||
(curr_buff_space_sz > join_buff_space_limit &&
|
(curr_buff_space_sz > join_buff_space_limit &&
|
||||||
|
@ -8903,7 +8903,7 @@ void revise_cache_usage(JOIN_TAB *join_tab)
|
|||||||
first_inner;
|
first_inner;
|
||||||
first_inner= first_inner->first_upper)
|
first_inner= first_inner->first_upper)
|
||||||
{
|
{
|
||||||
for (tab= end_tab-1; tab >= first_inner; tab--)
|
for (tab= end_tab; tab >= first_inner; tab--)
|
||||||
set_join_cache_denial(tab);
|
set_join_cache_denial(tab);
|
||||||
end_tab= first_inner;
|
end_tab= first_inner;
|
||||||
}
|
}
|
||||||
@ -8911,7 +8911,7 @@ void revise_cache_usage(JOIN_TAB *join_tab)
|
|||||||
else if (join_tab->first_sj_inner_tab)
|
else if (join_tab->first_sj_inner_tab)
|
||||||
{
|
{
|
||||||
first_inner= join_tab->first_sj_inner_tab;
|
first_inner= join_tab->first_sj_inner_tab;
|
||||||
for (tab= join_tab-1; tab >= first_inner; tab--)
|
for (tab= join_tab; tab >= first_inner; tab--)
|
||||||
{
|
{
|
||||||
set_join_cache_denial(tab);
|
set_join_cache_denial(tab);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user