diff options
author | unknown <bell@sanja.is.com.ua> | 2004-07-16 01:15:55 +0300 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2004-07-16 01:15:55 +0300 |
commit | 8790b1e65c3e1b2ae2ad9aedfe064c20d48bd096 (patch) | |
tree | 7a8e815ca26d9138de3bc77a619aa8103e037911 /sql/sql_delete.cc | |
parent | b0df20349d5e6ed2fc1527c3bd1db66a7d4ff311 (diff) | |
download | mariadb-git-8790b1e65c3e1b2ae2ad9aedfe064c20d48bd096.tar.gz |
VIEW
two TABLE_LIST copy eliminated
include/mysqld_error.h:
errors of view
libmysqld/Makefile.am:
new view file
mysql-test/r/connect.result:
SHOW TABLE show type of table
mysql-test/r/ctype_recoding.result:
SHOW TABLE show type of table
mysql-test/r/drop.result:
SHOW TABLE show type of table
mysql-test/r/grant.result:
new two privileges (CRETEA|SHOW VIEW)
mysql-test/r/lowercase_table.result:
SHOW TABLE show type of table
mysql-test/r/ps_1general.result:
SHOW TABLE show type of table
mysql-test/r/rename.result:
SHOW TABLE show type of table
mysql-test/r/rpl000009.result:
SHOW TABLE show type of table
mysql-test/r/rpl_error_ignored_table.result:
SHOW TABLE show type of table
mysql-test/r/select.result:
SHOW TABLE show type of table
mysql-test/r/system_mysql_db.result:
SHOW TABLE show type of table
new two privileges (CRETEA|SHOW VIEW)
mysql-test/t/system_mysql_db_fix.test:
removing all system tables
scripts/mysql_fix_privilege_tables.sql:
new two privileges (CRETEA|SHOW VIEW)
sql/Makefile.am:
new VIEW related file
sql/ha_myisammrg.cc:
two TABLE_LIST copy eliminated
sql/item.cc:
VIEW
sql/item.h:
VIEW
sql/item_subselect.cc:
VIEW
sql/item_subselect.h:
VIEW
sql/lex.h:
VIEW
sql/lock.cc:
VIEW
sql/mysql_priv.h:
VIEW
sql/mysqld.cc:
VIEW
new parameter - sql_updatable_view_key
sql/opt_sum.cc:
two TABLE_LIST copy eliminated
sql/set_var.cc:
new parameter - sql_updatable_view_key
sql/share/czech/errmsg.txt:
errors messages of views
sql/share/danish/errmsg.txt:
errors messages of views
sql/share/dutch/errmsg.txt:
errors messages of views
sql/share/english/errmsg.txt:
errors messages of views
sql/share/estonian/errmsg.txt:
errors messages of views
sql/share/french/errmsg.txt:
errors messages of views
sql/share/german/errmsg.txt:
errors messages of views
sql/share/greek/errmsg.txt:
errors messages of views
sql/share/hungarian/errmsg.txt:
errors messages of views
sql/share/italian/errmsg.txt:
errors messages of views
sql/share/japanese/errmsg.txt:
errors messages of views
sql/share/korean/errmsg.txt:
errors messages of views
sql/share/norwegian-ny/errmsg.txt:
errors messages of views
sql/share/norwegian/errmsg.txt:
errors messages of views
sql/share/polish/errmsg.txt:
errors messages of views
sql/share/portuguese/errmsg.txt:
errors messages of views
sql/share/romanian/errmsg.txt:
errors messages of views
sql/share/russian/errmsg.txt:
errors messages of views
sql/share/serbian/errmsg.txt:
errors messages of views
sql/share/slovak/errmsg.txt:
errors messages of views
sql/share/spanish/errmsg.txt:
errors messages of views
sql/share/swedish/errmsg.txt:
errors messages of views
sql/share/ukrainian/errmsg.txt:
errors messages of views
sql/slave.cc:
two TABLE_LIST copy eliminated
sql/sp.cc:
VIEW
sql/sql_acl.cc:
VIEW
sql/sql_acl.h:
VIEW
sql/sql_base.cc:
VIEW
sql/sql_cache.cc:
two TABLE_LIST copy eliminated
sql/sql_class.h:
VIEW
sql/sql_db.cc:
two TABLE_LIST copy eliminated
sql/sql_delete.cc:
VIEW
sql/sql_derived.cc:
VIEW
sql/sql_handler.cc:
two TABLE_LIST copy eliminated
sql/sql_help.cc:
two TABLE_LIST copy eliminated
sql/sql_insert.cc:
VIEW
sql/sql_lex.cc:
VIEW
sql/sql_lex.h:
VIEW
sql/sql_load.cc:
VIEW
sql/sql_olap.cc:
VIEW
sql/sql_parse.cc:
two TABLE_LIST copy eliminated
VIEW
sql/sql_prepare.cc:
VIEW
sql/sql_rename.cc:
two TABLE_LIST copy eliminated
sql/sql_select.cc:
VIEW
sql/sql_show.cc:
VIEW
sql/sql_table.cc:
VIEW
sql/sql_union.cc:
VIEW
sql/sql_update.cc:
VIEW
sql/sql_yacc.yy:
VIEW
sql/table.cc:
VIEW
sql/table.h:
VIEW
sql/tztime.cc:
two TABLE_LIST copy eliminated
sql/unireg.h:
VIEW
tests/client_test.c:
VIEW
Diffstat (limited to 'sql/sql_delete.cc')
-rw-r--r-- | sql/sql_delete.cc | 118 |
1 files changed, 93 insertions, 25 deletions
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 9e425f86579..910b673dc32 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -260,7 +260,7 @@ cleanup: SYNOPSIS mysql_prepare_delete() thd - thread handler - table_list - global table list + table_list - global/local table list conds - conditions RETURN VALUE @@ -270,25 +270,25 @@ cleanup: */ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) { - TABLE_LIST *delete_table_list= ((TABLE_LIST*) thd->lex-> - select_lex.table_list.first); SELECT_LEX *select_lex= &thd->lex->select_lex; DBUG_ENTER("mysql_prepare_delete"); - if (setup_conds(thd, delete_table_list, conds) || + if (setup_tables(thd, table_list, conds) || + setup_conds(thd, table_list, conds) || setup_ftfuncs(select_lex)) DBUG_RETURN(-1); - if (find_real_table_in_list(table_list->next, - table_list->db, table_list->real_name)) + if (!table_list->updatable || check_key_in_view(thd, table_list)) { - my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); DBUG_RETURN(-1); } - if (thd->current_arena && select_lex->first_execution) + if (find_real_table_in_list(table_list->next_global, + table_list->db, table_list->real_name)) { - select_lex->prep_where= select_lex->where; - select_lex->first_execution= 0; + my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); + DBUG_RETURN(-1); } + select_lex->fix_prepare_information(thd, conds); DBUG_RETURN(0); } @@ -305,6 +305,73 @@ extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b) return file->cmp_ref((const byte*)a, (const byte*)b); } +/* + make delete specific preparation and checks after opening tables + + SYNOPSIS + mysql_multi_delete_prepare() + thd thread handler + + RETURN + 0 OK + -1 Error +*/ + +int mysql_multi_delete_prepare(THD *thd) +{ + LEX *lex= thd->lex; + TABLE_LIST *aux_tables= (TABLE_LIST *)lex->auxilliary_table_list.first; + TABLE_LIST *target_tbl; + int res= 0; + DBUG_ENTER("mysql_multi_delete_prepare"); + + /* + setup_tables() need for VIEWs. JOIN::prepare() will not do it second + time. + + lex->query_tables also point on local list of DELETE SELECT_LEX + */ + if (setup_tables(thd, lex->query_tables, &lex->select_lex.where)) + DBUG_RETURN(-1); + + /* Fix tables-to-be-deleted-from list to point at opened tables */ + for (target_tbl= (TABLE_LIST*) aux_tables; + target_tbl; + target_tbl= target_tbl->next_local) + { + target_tbl->table= target_tbl->correspondent_table->table; + if (!target_tbl->correspondent_table->updatable || + check_key_in_view(thd, target_tbl->correspondent_table)) + { + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), target_tbl->real_name, + "DELETE"); + DBUG_RETURN(-1); + } + /* + Check are deleted table used somewhere inside subqueries. + + Multi-delete can't be constructed over-union => we always have + single SELECT on top and have to check underlaying SELECTs of it + */ + for (SELECT_LEX_UNIT *un= lex->select_lex.first_inner_unit(); + un; + un= un->next_unit()) + { + if (un->first_select()->linkage != DERIVED_TABLE_TYPE && + un->check_updateable(target_tbl->correspondent_table->db, + target_tbl->correspondent_table->real_name)) + { + my_error(ER_UPDATE_TABLE_USED, MYF(0), + target_tbl->correspondent_table->real_name); + res= -1; + break; + } + } + } + DBUG_RETURN(res); +} + + multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, uint num_of_tables_arg) : delete_tables(dt), thd(thd_arg), deleted(0), found(0), @@ -337,7 +404,7 @@ multi_delete::initialize_tables(JOIN *join) DBUG_RETURN(1); table_map tables_to_delete_from=0; - for (walk= delete_tables ; walk ; walk=walk->next) + for (walk= delete_tables; walk; walk= walk->next_local) tables_to_delete_from|= walk->table->map; walk= delete_tables; @@ -349,7 +416,7 @@ multi_delete::initialize_tables(JOIN *join) { /* We are going to delete from this table */ TABLE *tbl=walk->table=tab->table; - walk=walk->next; + walk= walk->next_local; /* Don't use KEYREAD optimization on this table */ tbl->no_keyread=1; tbl->used_keys.clear_all(); @@ -363,7 +430,7 @@ multi_delete::initialize_tables(JOIN *join) } walk= delete_tables; tempfiles_ptr= tempfiles; - for (walk=walk->next ; walk ; walk=walk->next) + for (walk= walk->next_local ;walk ;walk= walk->next_local) { TABLE *table=walk->table; *tempfiles_ptr++= new Unique (refpos_order_cmp, @@ -378,9 +445,9 @@ multi_delete::initialize_tables(JOIN *join) multi_delete::~multi_delete() { - for (table_being_deleted=delete_tables ; - table_being_deleted ; - table_being_deleted=table_being_deleted->next) + for (table_being_deleted= delete_tables; + table_being_deleted; + table_being_deleted= table_being_deleted->next_local) { TABLE *t=table_being_deleted->table; free_io_cache(t); // Alloced by unique @@ -400,9 +467,9 @@ bool multi_delete::send_data(List<Item> &values) int secure_counter= -1; DBUG_ENTER("multi_delete::send_data"); - for (table_being_deleted=delete_tables ; - table_being_deleted ; - table_being_deleted=table_being_deleted->next, secure_counter++) + for (table_being_deleted= delete_tables; + table_being_deleted; + table_being_deleted= table_being_deleted->next_local, secure_counter++) { TABLE *table=table_being_deleted->table; @@ -419,7 +486,8 @@ bool multi_delete::send_data(List<Item> &values) table->status|= STATUS_DELETED; if (!(error=table->file->delete_row(table->record[0]))) deleted++; - else if (!table_being_deleted->next || table_being_deleted->table->file->has_transactions()) + else if (!table_being_deleted->next_local || + table_being_deleted->table->file->has_transactions()) { table->file->print_error(error,MYF(0)); DBUG_RETURN(1); @@ -489,9 +557,9 @@ int multi_delete::do_deletes(bool from_send_error) if (from_send_error) { /* Found out table number for 'table_being_deleted*/ - for (TABLE_LIST *aux=delete_tables; + for (TABLE_LIST *aux= delete_tables; aux != table_being_deleted; - aux=aux->next) + aux= aux->next_local) counter++; } else @@ -500,9 +568,9 @@ int multi_delete::do_deletes(bool from_send_error) do_delete= 0; if (!found) DBUG_RETURN(0); - for (table_being_deleted=table_being_deleted->next; - table_being_deleted ; - table_being_deleted=table_being_deleted->next, counter++) + for (table_being_deleted= table_being_deleted->next_local; + table_being_deleted; + table_being_deleted= table_being_deleted->next_local, counter++) { TABLE *table = table_being_deleted->table; if (tempfiles[counter]->get(table)) |