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;
|
delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
|
||||||
set @@storage_engine=@ttype_save;
|
set @@storage_engine=@ttype_save;
|
||||||
drop table t1,t2;
|
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;
|
set @@storage_engine=@ttype_save;
|
||||||
drop table t1,t2;
|
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;
|
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,
|
Item_ident::Item_ident(const char *db_name_par,const char *table_name_par,
|
||||||
const char *field_name_par)
|
const char *field_name_par)
|
||||||
:orig_db_name(db_name_par), orig_table_name(table_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_dependence_processor(byte * arg) { return 0; }
|
||||||
virtual bool remove_fixed(byte * arg) { fixed= 0; 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 bool collect_item_field_processor(byte * arg) { return 0; }
|
||||||
virtual Item *equal_fields_propagator(byte * arg) { return this; }
|
virtual Item *equal_fields_propagator(byte * arg) { return this; }
|
||||||
virtual Item *set_no_const_sub(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)
|
int mysql_multi_update_prepare(THD *thd)
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
|
ulong opened_tables;
|
||||||
TABLE_LIST *table_list= lex->query_tables;
|
TABLE_LIST *table_list= lex->query_tables;
|
||||||
List<Item> *fields= &lex->select_lex.item_list;
|
List<Item> *fields= &lex->select_lex.item_list;
|
||||||
TABLE_LIST *tl;
|
TABLE_LIST *tl;
|
||||||
@ -682,10 +683,45 @@ int mysql_multi_update_prepare(THD *thd)
|
|||||||
if (!using_lock_tables)
|
if (!using_lock_tables)
|
||||||
tl->table->reginfo.lock_type= tl->lock_type;
|
tl->table->reginfo.lock_type= tl->lock_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opened_tables= thd->status_var.opened_tables;
|
||||||
/* now lock and fill tables */
|
/* now lock and fill tables */
|
||||||
if (lock_tables(thd, table_list, table_count) ||
|
if (lock_tables(thd, table_list, table_count))
|
||||||
(thd->fill_derived_tables() &&
|
DBUG_RETURN(thd->net.report_error ? -1 : 1);
|
||||||
mysql_handle_derived(lex, &mysql_derived_filling)))
|
|
||||||
|
/*
|
||||||
|
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(thd->net.report_error ? -1 : 1);
|
||||||
DBUG_RETURN (0);
|
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
|
check CHECK OPTION condition
|
||||||
|
|
||||||
|
@ -312,6 +312,7 @@ typedef struct st_table_list
|
|||||||
void set_ancestor();
|
void set_ancestor();
|
||||||
int view_check_option(THD *thd, bool ignore_failure);
|
int view_check_option(THD *thd, bool ignore_failure);
|
||||||
bool setup_ancestor(THD *thd, Item **conds, uint8 check_option);
|
bool setup_ancestor(THD *thd, Item **conds, uint8 check_option);
|
||||||
|
void cleanup_items();
|
||||||
bool placeholder() {return derived || view; }
|
bool placeholder() {return derived || view; }
|
||||||
void print(THD *thd, String *str);
|
void print(THD *thd, String *str);
|
||||||
inline st_table_list *next_independent()
|
inline st_table_list *next_independent()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user