1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

fixed mechanism of detection selection from table wich we update

(BUG##9398, BUG#8703)
fixed wrong join view detection in multi-delete which lead to server crash
This commit is contained in:
bell@sanja.is.com.ua
2005-03-28 15:13:31 +03:00
parent eeeedd31b9
commit 1659dacab1
15 changed files with 561 additions and 165 deletions

View File

@ -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);
}