From f1b9bf699eeec11d7d619683d74c01d6172a7e5f Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 8 Nov 2004 01:54:23 +0200 Subject: 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 --- sql/item.cc | 17 +++++++++++++++++ sql/item.h | 1 + sql/sql_update.cc | 42 +++++++++++++++++++++++++++++++++++++++--- sql/table.cc | 18 ++++++++++++++++++ sql/table.h | 1 + 5 files changed, 76 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 6730b0dd4a2..4c738c9a4c5 100644 --- a/sql/item.cc +++ b/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), diff --git a/sql/item.h b/sql/item.h index d3e53af1523..eed0b065a83 100644 --- a/sql/item.h +++ b/sql/item.h @@ -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; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 46b7f0252e8..7bd445088cf 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -575,6 +575,7 @@ static table_map get_table_map(List *items) int mysql_multi_update_prepare(THD *thd) { LEX *lex= thd->lex; + ulong opened_tables; TABLE_LIST *table_list= lex->query_tables; List *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 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); } diff --git a/sql/table.cc b/sql/table.cc index 0116cf180c1..8c58c5296ad 100644 --- a/sql/table.cc +++ b/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 diff --git a/sql/table.h b/sql/table.h index 0250d713a56..af7d90a8291 100644 --- a/sql/table.h +++ b/sql/table.h @@ -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() -- cgit v1.2.1