Commit f1b9bf69 authored by unknown's avatar unknown

postreview fixes


mysql-test/r/multi_update.result:
  test with multiupdate reopening tables
mysql-test/t/multi_update.test:
  test with multiupdate reopening tables
sql/item.cc:
  processor for cleunuping items in item tree
sql/item.h:
  processor for cleunuping items in item tree
sql/sql_update.cc:
  fixed case when lock reopened tables
sql/table.cc:
  methos for cleunup view itema of table if they are present
sql/table.h:
  methos for cleunup view itema of table if they are present
parent 8b0ece5e
......@@ -490,3 +490,24 @@ insert into t2 select * from t1;
delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
set @@storage_engine=@ttype_save;
drop table t1,t2;
create table t1 (a int, b int);
insert into t1 values (1, 2), (2, 3), (3, 4);
create table t2 (a int);
insert into t2 values (10), (20), (30);
create view v1 as select a as b, a/10 as a from t2;
lock table t1 write;
alter table t1 add column c int default 100 after a;
update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a;
unlock tables;
select * from t1;
a c b
1 100 13
2 100 25
3 100 37
select * from t2;
a
10
20
30
drop view v1;
drop table t1, t2;
......@@ -477,3 +477,35 @@ delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
set @@storage_engine=@ttype_save;
drop table t1,t2;
create table t1 (a int, b int);
insert into t1 values (1, 2), (2, 3), (3, 4);
create table t2 (a int);
insert into t2 values (10), (20), (30);
create view v1 as select a as b, a/10 as a from t2;
connect (locker,localhost,root,,test);
connection locker;
lock table t1 write;
connect (changer,localhost,root,,test);
connection changer;
send alter table t1 add column c int default 100 after a;
connect (updater,localhost,root,,test);
connection updater;
send update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a;
connection locker;
sleep 2;
unlock tables;
connection changer;
reap;
connection updater;
reap;
select * from t1;
select * from t2;
drop view v1;
drop table t1, t2;
......@@ -117,6 +117,23 @@ void Item::cleanup()
DBUG_VOID_RETURN;
}
/*
cleanup() item if it is 'fixed'
SYNOPSIS
cleanup_processor()
arg - a dummy parameter, is not used here
*/
bool Item::cleanup_processor(byte *arg)
{
if (fixed)
cleanup();
return FALSE;
}
Item_ident::Item_ident(const char *db_name_par,const char *table_name_par,
const char *field_name_par)
:orig_db_name(db_name_par), orig_table_name(table_name_par),
......
......@@ -283,6 +283,7 @@ class Item {
virtual bool remove_dependence_processor(byte * arg) { return 0; }
virtual bool remove_fixed(byte * arg) { fixed= 0; return 0; }
virtual bool cleanup_processor(byte *arg);
virtual bool collect_item_field_processor(byte * arg) { return 0; }
virtual Item *equal_fields_propagator(byte * arg) { return this; }
virtual Item *set_no_const_sub(byte *arg) { return this; }
......
......@@ -575,6 +575,7 @@ static table_map get_table_map(List<Item> *items)
int mysql_multi_update_prepare(THD *thd)
{
LEX *lex= thd->lex;
ulong opened_tables;
TABLE_LIST *table_list= lex->query_tables;
List<Item> *fields= &lex->select_lex.item_list;
TABLE_LIST *tl;
......@@ -682,10 +683,45 @@ int mysql_multi_update_prepare(THD *thd)
if (!using_lock_tables)
tl->table->reginfo.lock_type= tl->lock_type;
}
opened_tables= thd->status_var.opened_tables;
/* now lock and fill tables */
if (lock_tables(thd, table_list, table_count) ||
(thd->fill_derived_tables() &&
mysql_handle_derived(lex, &mysql_derived_filling)))
if (lock_tables(thd, table_list, table_count))
DBUG_RETURN(thd->net.report_error ? -1 : 1);
/*
we have to re-call fixfields for fixed items, because lock maybe
reopened tables
*/
if (opened_tables != thd->status_var.opened_tables)
{
/*
Fields items cleanup(). There are only Item_fields in the list, so we
do not do Item tree walking
*/
List_iterator_fast<Item> it(*fields);
Item *item;
while (item= it++)
{
item->cleanup();
}
/* We have to cleunup translation tables of views. */
for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global)
tbl->cleanup_items();
/* undone setup_tables() */
table_list->setup_is_done= 0;
if (setup_tables(thd, table_list, &lex->select_lex.where) ||
(lex->select_lex.no_wrap_view_item= 1,
res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0),
lex->select_lex.no_wrap_view_item= 0,
res))
DBUG_RETURN(-1);
}
if (thd->fill_derived_tables() &&
mysql_handle_derived(lex, &mysql_derived_filling))
DBUG_RETURN(thd->net.report_error ? -1 : 1);
DBUG_RETURN (0);
}
......
......@@ -1735,6 +1735,24 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
}
/*
cleunup items belonged to view fields translation table
SYNOPSIS
st_table_list::cleanup_items()
*/
void st_table_list::cleanup_items()
{
if (!field_translation)
return;
Item **end= field_translation + view->select_lex.item_list.elements;
for (Item **item= field_translation; item < end; item++)
(*item)->walk(&Item::cleanup_processor, 0);
}
/*
check CHECK OPTION condition
......
......@@ -312,6 +312,7 @@ typedef struct st_table_list
void set_ancestor();
int view_check_option(THD *thd, bool ignore_failure);
bool setup_ancestor(THD *thd, Item **conds, uint8 check_option);
void cleanup_items();
bool placeholder() {return derived || view; }
void print(THD *thd, String *str);
inline st_table_list *next_independent()
......
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