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
This commit is contained in:
parent
8b0ece5e88
commit
f1b9bf699e
@ -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;
|
||||
|
17
sql/item.cc
17
sql/item.cc
@ -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 @@ public:
|
||||
|
||||
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);
|
||||
}
|
||||
|
18
sql/table.cc
18
sql/table.cc
@ -1735,6 +1735,24 @@ err:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user