Commit 1e1a8a7f authored by Igor Babaev's avatar Igor Babaev

Fixed bug mdev-6705.

After constant row substitution the WHERE condition may be simplified and its multiple equality
may be changed. In this case the references to these multiple equalities from the COND_EQUAL
objects associated with ON expressions must be updated.
Also we have to take into account that this simplification may lead to equalities of the form
field=const that are mutually exclusive with some of the equalities in ON expressions. 
parent 5023bb89
...@@ -1920,4 +1920,27 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -1920,4 +1920,27 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings: Warnings:
Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t2`.`i2` AS `i2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`d3` AS `d3` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`i2` = `test`.`t1`.`i1`) and (`test`.`t3`.`i3` = `test`.`t1`.`i1`))) where ((`test`.`t3`.`d3` = 0) or isnull(`test`.`t3`.`d3`)) Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t2`.`i2` AS `i2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`d3` AS `d3` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`i2` = `test`.`t1`.`i1`) and (`test`.`t3`.`i3` = `test`.`t1`.`i1`))) where ((`test`.`t3`.`d3` = 0) or isnull(`test`.`t3`.`d3`))
DROP TABLE t1,t2,t3; DROP TABLE t1,t2,t3;
#
# Bug mdev-6705: wrong on expression after constant row substitution
# that triggers a simplification of WHERE condition
#
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
INSERT INTO t1 VALUES (10,8);
CREATE TABLE t2 (c int) ENGINE=MyISAM;
INSERT INTO t2 VALUES (8),(9);
CREATE TABLE t3 (d int) ENGINE=MyISAM;
INSERT INTO t3 VALUES (3),(8);
EXPLAIN EXTENDED
SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
WHERE b IN (1,2,3) OR b = d;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select 10 AS `a`,8 AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on((`test`.`t3`.`d` = 10)) where ((`test`.`t2`.`c` = 8) and (`test`.`t3`.`d` = 8))
SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
WHERE b IN (1,2,3) OR b = d;
a b c d
DROP TABLE t1,t2,t3;
SET optimizer_switch=@save_optimizer_switch; SET optimizer_switch=@save_optimizer_switch;
...@@ -1931,6 +1931,29 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -1931,6 +1931,29 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings: Warnings:
Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t2`.`i2` AS `i2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`d3` AS `d3` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`i2` = `test`.`t1`.`i1`) and (`test`.`t3`.`i3` = `test`.`t1`.`i1`))) where ((`test`.`t3`.`d3` = 0) or isnull(`test`.`t3`.`d3`)) Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t2`.`i2` AS `i2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`d3` AS `d3` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`i2` = `test`.`t1`.`i1`) and (`test`.`t3`.`i3` = `test`.`t1`.`i1`))) where ((`test`.`t3`.`d3` = 0) or isnull(`test`.`t3`.`d3`))
DROP TABLE t1,t2,t3; DROP TABLE t1,t2,t3;
#
# Bug mdev-6705: wrong on expression after constant row substitution
# that triggers a simplification of WHERE condition
#
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
INSERT INTO t1 VALUES (10,8);
CREATE TABLE t2 (c int) ENGINE=MyISAM;
INSERT INTO t2 VALUES (8),(9);
CREATE TABLE t3 (d int) ENGINE=MyISAM;
INSERT INTO t3 VALUES (3),(8);
EXPLAIN EXTENDED
SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
WHERE b IN (1,2,3) OR b = d;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select 10 AS `a`,8 AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on((`test`.`t3`.`d` = 10)) where ((`test`.`t2`.`c` = 8) and (`test`.`t3`.`d` = 8))
SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
WHERE b IN (1,2,3) OR b = d;
a b c d
DROP TABLE t1,t2,t3;
SET optimizer_switch=@save_optimizer_switch; SET optimizer_switch=@save_optimizer_switch;
set join_cache_level=default; set join_cache_level=default;
show variables like 'join_cache_level'; show variables like 'join_cache_level';
......
...@@ -1463,4 +1463,28 @@ SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON i2 = i3 ON i1 = i3 ...@@ -1463,4 +1463,28 @@ SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON i2 = i3 ON i1 = i3
DROP TABLE t1,t2,t3; DROP TABLE t1,t2,t3;
--echo #
--echo # Bug mdev-6705: wrong on expression after constant row substitution
--echo # that triggers a simplification of WHERE condition
--echo #
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
INSERT INTO t1 VALUES (10,8);
CREATE TABLE t2 (c int) ENGINE=MyISAM;
INSERT INTO t2 VALUES (8),(9);
CREATE TABLE t3 (d int) ENGINE=MyISAM;
INSERT INTO t3 VALUES (3),(8);
EXPLAIN EXTENDED
SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
WHERE b IN (1,2,3) OR b = d;
SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
WHERE b IN (1,2,3) OR b = d;
DROP TABLE t1,t2,t3;
SET optimizer_switch=@save_optimizer_switch; SET optimizer_switch=@save_optimizer_switch;
...@@ -3530,6 +3530,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, ...@@ -3530,6 +3530,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
join->impossible_where= false; join->impossible_where= false;
if (conds && const_count) if (conds && const_count)
{ {
COND_EQUAL *orig_cond_equal = join->cond_equal;
conds->update_used_tables(); conds->update_used_tables();
conds= remove_eq_conds(join->thd, conds, &join->cond_value); conds= remove_eq_conds(join->thd, conds, &join->cond_value);
if (conds && conds->type() == Item::COND_ITEM && if (conds && conds->type() == Item::COND_ITEM &&
...@@ -3556,7 +3557,21 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, ...@@ -3556,7 +3557,21 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
join->cond_equal->current_level.empty(); join->cond_equal->current_level.empty();
join->cond_equal->current_level.push_back((Item_equal*) conds); join->cond_equal->current_level.push_back((Item_equal*) conds);
} }
} }
if (orig_cond_equal != join->cond_equal)
{
/*
If join->cond_equal has changed all references to it from COND_EQUAL
objects associated with ON expressions must be updated.
*/
for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++)
{
if (*s->on_expr_ref && s->cond_equal &&
s->cond_equal->upper_levels == orig_cond_equal)
s->cond_equal->upper_levels= join->cond_equal;
}
}
} }
/* Calc how many (possible) matched records in each table */ /* Calc how many (possible) matched records in each table */
...@@ -11999,10 +12014,18 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, ...@@ -11999,10 +12014,18 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
if (upper) if (upper)
{ {
TABLE_LIST *native_sjm= embedding_sjm(item_equal->context_field); TABLE_LIST *native_sjm= embedding_sjm(item_equal->context_field);
if (item_const && upper->get_const()) Item *upper_const= upper->get_const();
if (item_const && upper_const)
{ {
/* Upper item also has "field_item=const". Don't produce equality here */ /*
item= 0; Upper item also has "field_item=const".
Don't produce equality if const is equal to item_const.
*/
Item_func_eq *func= new Item_func_eq(item_const, upper_const);
func->set_cmp_func();
func->quick_fix_field();
if (func->val_int())
item= 0;
} }
else else
{ {
......
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