summaryrefslogtreecommitdiff
path: root/sql/sql_base.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r--sql/sql_base.cc64
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);
}