summaryrefslogtreecommitdiff
path: root/sql/sql_delete.cc
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2004-07-16 01:15:55 +0300
committerunknown <bell@sanja.is.com.ua>2004-07-16 01:15:55 +0300
commit8790b1e65c3e1b2ae2ad9aedfe064c20d48bd096 (patch)
tree7a8e815ca26d9138de3bc77a619aa8103e037911 /sql/sql_delete.cc
parentb0df20349d5e6ed2fc1527c3bd1db66a7d4ff311 (diff)
downloadmariadb-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.cc118
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))