diff options
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r-- | sql/sql_base.cc | 64 |
1 files changed, 33 insertions, 31 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4750fe1386f..28235ba48a3 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -680,33 +680,12 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, const char *db_name, const char *table_name) { - if (lower_case_table_names) + for (; table; table= *(TABLE_LIST **) ((char*) table + offset)) { - for (; table; table= *(TABLE_LIST **) ((char*) table + offset)) - { - if ((table->table == 0 || table->table->s->tmp_table == NO_TMP_TABLE) && - ((!strcmp(table->db, db_name) && - !strcmp(table->table_name, table_name)) || - (table->view && - !my_strcasecmp(table_alias_charset, - table->db, db_name) && - !my_strcasecmp(table_alias_charset, - table->table->alias, table_name)))) - break; - } - } - else - { - for (; table; table= *(TABLE_LIST **) ((char*) table + offset)) - { - if ((table->table == 0 || table->table->s->tmp_table == NO_TMP_TABLE) && - ((!strcmp(table->db, db_name) && - !strcmp(table->table_name, table_name)) || - (table->view && - !strcmp(table->table->s->db, db_name) && - !strcmp(table->table->alias, table_name)))) - break; - } + if ((table->table == 0 || table->table->s->tmp_table == NO_TMP_TABLE) && + strcmp(table->db, db_name) == 0 && + strcmp(table->table_name, table_name) == 0) + break; } return table; } @@ -717,8 +696,25 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, SYNOPSIS unique_table() - table table which should be chaked - table_list list of tables + table table which should be chaked + table_list list of tables + + NOTE: to exclude derived tables from check we use following mechanism: + a) during derived table processing set THD::derived_tables_processing + b) JOIN::prepare set SELECT::exclude_from_table_unique_test if + THD::derived_tables_processing set. (we can't use JOIN::execute + because for PS we perform only JOIN::prepare, but we can't set this + flag in JOIN::prepare if we are not sure that we are in derived table + processing loop, because multi-update call fix_fields() for some its + items (which mean JOIN::prepare for subqueries) before unique_table + call to detect which tables should be locked for write). + c) unique_table skip all tables which belong to SELECT with + SELECT::exclude_from_table_unique_test set. + Also SELECT::exclude_from_table_unique_test used to exclude from check + tables of main SELECT of multi-delete and multi-update + + TODO: when we will have table/view change detection we can do this check + only once for PS/SP RETURN found duplicate @@ -758,11 +754,17 @@ TABLE_LIST* unique_table(TABLE_LIST *table, TABLE_LIST *table_list) for(;;) { if (!(res= find_table_in_global_list(table_list, d_name, t_name)) || - !res->table || res->table != table->table) + (!res->table || res->table != table->table) && + (res->select_lex && !res->select_lex->exclude_from_table_unique_test)) break; - /* if we found entry of this table try again. */ + /* + If we found entry of this table or or table of SELECT which already + processed in derived table or top select of multi-update/multi-delete + (exclude_from_table_unique_test). + */ table_list= res->next_global; - DBUG_PRINT("info", ("found same copy of table")); + DBUG_PRINT("info", + ("found same copy of table or table which we should skip")); } DBUG_RETURN(res); } |