diff options
Diffstat (limited to 'sql/sql_update.cc')
-rw-r--r-- | sql/sql_update.cc | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/sql/sql_update.cc b/sql/sql_update.cc index db4edff4fa1..b6cd0d967e9 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -490,9 +490,8 @@ int mysql_multi_update(THD *thd, table->grant.want_privilege= (UPDATE_ACL & ~table->grant.privilege); } - if (thd->lex->derived_tables) + /* Assign table map values to check updatability of derived tables */ { - // Assign table map values to check updatability of derived tables uint tablenr=0; for (TABLE_LIST *table_list= update_list; table_list; @@ -501,11 +500,12 @@ int mysql_multi_update(THD *thd, table_list->table->map= (table_map) 1 << tablenr; } } + if (setup_fields(thd, 0, update_list, *fields, 1, 0, 0)) DBUG_RETURN(-1); - if (thd->lex->derived_tables) + + /* Find tables used in items */ { - // Find tables used in items List_iterator_fast<Item> it(*fields); Item *item; while ((item= it++)) @@ -527,7 +527,23 @@ int mysql_multi_update(THD *thd, if (table->timestamp_field && table->timestamp_field->query_id == thd->query_id) table->timestamp_on_update_now= 0; - + + /* if table will be updated then check that it is unique */ + if (table->map & item_tables) + { + /* + Multi-update can't be constructed over-union => we always have + single SELECT on top and have to check underlaying SELECTs of it + */ + if (select_lex->check_updateable_in_subqueries(tl->db, + tl->real_name)) + { + my_error(ER_UPDATE_TABLE_USED, MYF(0), + tl->real_name); + DBUG_RETURN(-1); + } + } + if (tl->derived) derived_tables|= table->map; } |