Commit 21d25739 authored by Sergey Petrunya's avatar Sergey Petrunya

MWL#17: Table elimination

- Correctly handle the case where we have multi-table DELETE and a table
  that we're deleting from looks like it could be eliminated.
parent f3d0b1c0
...@@ -278,3 +278,32 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -278,3 +278,32 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 10 NULL 2 Using index 1 SIMPLE t1 index NULL PRIMARY 10 NULL 2 Using index
1 SIMPLE t2 ref a a 3 test.t1.a 2 1 SIMPLE t2 ref a a 3 test.t1.a 2
drop table t1, t2; drop table t1, t2;
#
# check UPDATE/DELETE that look like they could be eliminated
#
create table t1 (a int primary key, b int);
insert into t1 values (1,1),(2,2),(3,3);
create table t2 like t1;
insert into t2 select * from t1;
update t1 left join t2 using (a) set t2.a=t2.a+100;
select * from t1;
a b
1 1
2 2
3 3
select * from t2;
a b
101 1
102 2
103 3
delete from t2;
insert into t2 select * from t1;
delete t2 from t1 left join t2 using (a);
select * from t1;
a b
1 1
2 2
3 3
select * from t2;
a b
drop table t1, t2;
...@@ -229,3 +229,23 @@ explain select t1.* from t1 left join t2 on t2.a=t1.a; ...@@ -229,3 +229,23 @@ explain select t1.* from t1 left join t2 on t2.a=t1.a;
drop table t1, t2; drop table t1, t2;
--echo #
--echo # check UPDATE/DELETE that look like they could be eliminated
--echo #
create table t1 (a int primary key, b int);
insert into t1 values (1,1),(2,2),(3,3);
create table t2 like t1;
insert into t2 select * from t1;
update t1 left join t2 using (a) set t2.a=t2.a+100;
select * from t1;
select * from t2;
delete from t2;
insert into t2 select * from t1;
delete t2 from t1 left join t2 using (a);
select * from t1;
select * from t2;
drop table t1, t2;
...@@ -1069,16 +1069,26 @@ void eliminate_tables(JOIN *join) ...@@ -1069,16 +1069,26 @@ void eliminate_tables(JOIN *join)
if (join->select_lex == &thd->lex->select_lex) if (join->select_lex == &thd->lex->select_lex)
{ {
/* Multi-table UPDATE and DELETE: don't eliminate the tables we modify: */
used_tables |= thd->table_map_for_update;
/* Multi-table UPDATE: don't eliminate tables referred from SET statement */ /* Multi-table UPDATE: don't eliminate tables referred from SET statement */
if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI) if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI)
{ {
/* Multi-table UPDATE and DELETE: don't eliminate the tables we modify: */
used_tables |= thd->table_map_for_update;
List_iterator<Item> it2(thd->lex->value_list); List_iterator<Item> it2(thd->lex->value_list);
while ((item= it2++)) while ((item= it2++))
used_tables |= item->used_tables(); used_tables |= item->used_tables();
} }
if (thd->lex->sql_command == SQLCOM_DELETE_MULTI)
{
TABLE_LIST *tbl;
for (tbl= (TABLE_LIST*)thd->lex->auxiliary_table_list.first;
tbl; tbl= tbl->next_local)
{
used_tables |= tbl->table->map;
}
}
} }
table_map all_tables= join->all_tables_map(); table_map all_tables= join->all_tables_map();
......
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