diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 28235ba48a3..02978ba0c30 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -724,31 +724,34 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, TABLE_LIST* unique_table(TABLE_LIST *table, TABLE_LIST *table_list) { TABLE_LIST *res; - const char *d_name= table->db, *t_name= table->table_name; - char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME]; + const char *d_name, *t_name; DBUG_ENTER("unique_table"); DBUG_PRINT("enter", ("table alias: %s", table->alias)); - /* temporary table is always unique */ - if (table->table && table->table->s->tmp_table != NO_TMP_TABLE) - DBUG_RETURN(0); - if (table->view) + + /* + If this function called for query which update table (INSERT/UPDATE/...) + then we have in table->table pointer to TABLE object which we are + updating even if it is VIEW so we need TABLE_LIST of this TABLE object + to get right names (even if lower_case_table_names used). + + If this function called for CREATE command that we have not opened table + (table->table equal to 0) and right names is in current TABLE_LIST + object. + */ + if (table->table) { - /* it is view and table opened */ - if (lower_case_table_names) - { - strmov(t_name_buff, table->table->alias); - my_casedn_str(files_charset_info, t_name_buff); - t_name= t_name_buff; - strmov(d_name_buff, table->table->s->db); - my_casedn_str(files_charset_info, d_name_buff); - d_name= d_name_buff; - } - else - { - d_name= table->table->s->db; - t_name= table->table->alias; - } + /* temporary table is always unique */ + if (table->table && table->table->s->tmp_table != NO_TMP_TABLE) + DBUG_RETURN(0); + table= table->find_underlying_table(table->table); + /* + as far as we have table->table we have to find real TABLE_LIST of + it in underlying tables + */ + DBUG_ASSERT(table); } + d_name= table->db; + t_name= table->table_name; DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name)); for(;;) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index e4f30f72443..24fa1659f76 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -755,17 +755,17 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) table->ancestor= view_tables; - /* next table should include SELECT_LEX under this table SELECT_LEX */ - table->ancestor->select_lex= table->select_lex; - /* Process upper level tables of view. As far as we do noy suport union here we can go through local tables of view most upper SELECT */ - for(tbl= (TABLE_LIST*)view_select->table_list.first; + for(tbl= view_tables; tbl; tbl= tbl->next_local) { + /* next table should include SELECT_LEX under this table SELECT_LEX */ + tbl->select_lex= table->select_lex; + /* move lock type (TODO: should we issue error in case of TMPTABLE algorithm and non-read locking)? diff --git a/sql/table.cc b/sql/table.cc index 9238d8aa68e..e1f15926c03 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1716,7 +1716,7 @@ void st_table_list::restore_want_privilege() check_opt_type - WHITH CHECK OPTION type (VIEW_CHECK_NONE, VIEW_CHECK_LOCAL, VIEW_CHECK_CASCADED) NOTES - ancestor is list of tables and views used by view + ancestor is list of tables and views used by view (underlying tables/views) DESCRIPTION It is: @@ -1750,6 +1750,9 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds, bool res= FALSE; DBUG_ENTER("st_table_list::setup_ancestor"); + if (check_stack_overrun(thd, (char *)&res)) + return TRUE; + for (tbl= ancestor; tbl; tbl= tbl->next_local) { if (tbl->ancestor && @@ -1986,6 +1989,34 @@ ok: } +/* + Find underlying base tables (TABLE_LIST) which represent given + table_to_find (TABLE) + + SYNOPSIS + st_table_list::find_underlying_table() + table_to_find table to find + + RETURN + 0 table is not found + found table reference +*/ + +st_table_list *st_table_list::find_underlying_table(TABLE *table_to_find) +{ + /* is this real table and table which we are looking for? */ + if (table == table_to_find && ancestor == 0) + return this; + + for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local) + { + TABLE_LIST *result; + if ((result= tbl->find_underlying_table(table_to_find))) + return result; + } + return 0; +} + /* cleunup items belonged to view fields translation table diff --git a/sql/table.h b/sql/table.h index fd299759678..270ec313240 100644 --- a/sql/table.h +++ b/sql/table.h @@ -376,7 +376,7 @@ typedef struct st_table_list st_select_lex *select_lex; st_lex *view; /* link on VIEW lex for merging */ Field_translator *field_translation; /* array of VIEW fields */ - /* ancestor of this table (VIEW merge algorithm) */ + /* list of ancestor(s) of this table (underlying table(s)/view(s) */ st_table_list *ancestor; /* most upper view this table belongs to */ st_table_list *belong_to_view; @@ -448,6 +448,7 @@ typedef struct st_table_list void restore_want_privilege(); bool check_single_table(st_table_list **table, table_map map); bool set_insert_values(MEM_ROOT *mem_root); + st_table_list *find_underlying_table(TABLE *table); } TABLE_LIST; class Item;