Commit f1d42ec9 authored by Igor Babaev's avatar Igor Babaev

Applied the fix for bug #54235 taken from one of the mysql trees.

The fix aligns join_null_complements() with join_matching_records()
making both call generate_full_extensions().
There should not be any difference between how the WHERE clause
is applied to NULL-complemented records from a partial join and how
it is applied to other partially joined records:the latter happens in
join_matching_records(), precisely in generate_full_extensions().
parent e49cb8a7
......@@ -5330,4 +5330,44 @@ a
9
set join_cache_level = default;
DROP TABLE t1;
#
# Bug#54235 Extra rows with join_cache_level=6,8 and two LEFT JOINs
#
CREATE TABLE t1 (a int);
CREATE TABLE t2 (a int);
CREATE TABLE t3 (a int);
CREATE TABLE t4 (a int);
INSERT INTO t1 VALUES (null), (2), (null), (1);
set join_cache_level = 6;
EXPLAIN
SELECT t1.a
FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a) ON 0
WHERE t1.a OR t3.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where; Using join buffer
1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where; Using join buffer
SELECT t1.a
FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a) ON 0
WHERE t1.a OR t3.a;
a
2
1
EXPLAIN
SELECT t1.a
FROM t1 LEFT JOIN (t2 LEFT JOIN (t3 LEFT JOIN t4 ON 1) ON t2.a) ON 0
WHERE t1.a OR t4.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where; Using join buffer
1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where; Using join buffer
1 SIMPLE t4 ALL NULL NULL NULL NULL 0 Using where; Using join buffer
SELECT t1.a
FROM t1 LEFT JOIN (t2 LEFT JOIN (t3 LEFT JOIN t4 ON 1) ON t2.a) ON 0
WHERE t1.a OR t4.a;
a
2
1
set join_cache_level = default;
DROP TABLE t1,t2,t3,t4;
set @@optimizer_switch=@save_optimizer_switch;
......@@ -2104,5 +2104,37 @@ SELECT t.a FROM t1 t, t1 s FORCE INDEX(idx)
set join_cache_level = default;
DROP TABLE t1;
--echo #
--echo # Bug#54235 Extra rows with join_cache_level=6,8 and two LEFT JOINs
--echo #
CREATE TABLE t1 (a int);
CREATE TABLE t2 (a int);
CREATE TABLE t3 (a int);
CREATE TABLE t4 (a int);
INSERT INTO t1 VALUES (null), (2), (null), (1);
set join_cache_level = 6;
EXPLAIN
SELECT t1.a
FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a) ON 0
WHERE t1.a OR t3.a;
SELECT t1.a
FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a) ON 0
WHERE t1.a OR t3.a;
EXPLAIN
SELECT t1.a
FROM t1 LEFT JOIN (t2 LEFT JOIN (t3 LEFT JOIN t4 ON 1) ON t2.a) ON 0
WHERE t1.a OR t4.a;
SELECT t1.a
FROM t1 LEFT JOIN (t2 LEFT JOIN (t3 LEFT JOIN t4 ON 1) ON t2.a) ON 0
WHERE t1.a OR t4.a;
set join_cache_level = default;
DROP TABLE t1,t2,t3,t4;
# this must be the last command in the file
set @@optimizer_switch=@save_optimizer_switch;
......@@ -2295,35 +2295,11 @@ enum_nested_loop_state JOIN_CACHE::join_null_complements(bool skip_last)
/* The outer row is complemented by nulls for each inner table */
restore_record(join_tab->table, s->default_values);
mark_as_null_row(join_tab->table);
/* Check all pushdown conditions attached to the inner table */
join_tab->first_unmatched->found= 1;
if (join_tab->select && join_tab->select->skip_record(join->thd) <= 0)
continue;
if (is_last_inner)
{
JOIN_TAB *first_upper= join_tab->first_unmatched->first_upper;
while (first_upper && first_upper->last_inner == join_tab)
{
set_match_flag_if_none(first_upper, get_curr_rec());
for (JOIN_TAB* tab= first_upper; tab <= join_tab; tab++)
{
if (tab->select && tab->select->skip_record(join->thd) <= 0)
goto next;
}
first_upper= first_upper->first_upper;
}
}
/* Find all matches for the remaining join tables */
rc= (*join_tab->next_select)(join, join_tab+1, 0);
rc= generate_full_extensions(get_curr_rec());
if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
{
reset(TRUE);
goto finish;
}
}
next:
;
}
finish:
return rc;
......
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