summaryrefslogtreecommitdiff
path: root/sql/sql_delete.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2011-05-20 12:47:39 -0700
committerIgor Babaev <igor@askmonty.org>2011-05-20 12:47:39 -0700
commit89cf840cd9709c875bb6494398970624c85e4ab0 (patch)
treeb6926318d94f0bcd733468587a4bed4101c81612 /sql/sql_delete.cc
parentbe6d6e1b3eb0d243dfa9f1d0de108069df5774e4 (diff)
parentd015b8fa0ad2bfb853da174c1c959374a24a5063 (diff)
downloadmariadb-git-89cf840cd9709c875bb6494398970624c85e4ab0.tar.gz
Merge
Diffstat (limited to 'sql/sql_delete.cc')
-rw-r--r--sql/sql_delete.cc57
1 files changed, 42 insertions, 15 deletions
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 5b5565000da..67eb7bc328d 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -60,10 +60,18 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
- if (!(table= table_list->table))
+
+ if (mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) ||
+ mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE))
+ DBUG_RETURN(TRUE);
+
+ if (!(table= table_list->table) || !table->created)
{
- my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
- table_list->view_db.str, table_list->view_name.str);
+ if (!table_list->updatable)
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE");
+ else
+ my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
+ table_list->view_db.str, table_list->view_name.str);
DBUG_RETURN(TRUE);
}
thd_proc_info(thd, "init");
@@ -72,6 +80,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (mysql_prepare_delete(thd, table_list, &conds))
DBUG_RETURN(TRUE);
+ if (thd->lex->current_select->first_cond_optimization)
+ {
+ thd->lex->current_select->save_leaf_tables(thd);
+ thd->lex->current_select->first_cond_optimization= 0;
+ }
/* check ORDER BY even if it can be ignored */
if (order && order->elements)
{
@@ -405,6 +418,12 @@ cleanup:
query_cache_invalidate3(thd, table_list, 1);
}
+ if (thd->lex->current_select->first_cond_optimization)
+ {
+ thd->lex->current_select->save_leaf_tables(thd);
+ thd->lex->current_select->first_cond_optimization= 0;
+ }
+
delete select;
transactional_table= table->file->has_transactions();
@@ -506,8 +525,8 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list,
table_list,
- &select_lex->leaf_tables, FALSE,
- DELETE_ACL, SELECT_ACL) ||
+ select_lex->leaf_tables, FALSE,
+ DELETE_ACL, SELECT_ACL, TRUE) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
setup_ftfuncs(select_lex))
DBUG_RETURN(TRUE);
@@ -565,6 +584,11 @@ int mysql_multi_delete_prepare(THD *thd)
TABLE_LIST *target_tbl;
DBUG_ENTER("mysql_multi_delete_prepare");
+ TABLE_LIST *tables= lex->query_tables;
+ if (mysql_handle_derived(lex, DT_INIT) ||
+ mysql_handle_list_of_derived(lex, tables, DT_MERGE_FOR_INSERT) ||
+ mysql_handle_list_of_derived(lex, tables, DT_PREPARE))
+ DBUG_RETURN(TRUE);
/*
setup_tables() need for VIEWs. JOIN::prepare() will not do it second
time.
@@ -574,8 +598,8 @@ int mysql_multi_delete_prepare(THD *thd)
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list,
lex->query_tables,
- &lex->select_lex.leaf_tables, FALSE,
- DELETE_ACL, SELECT_ACL))
+ lex->select_lex.leaf_tables, FALSE,
+ DELETE_ACL, SELECT_ACL, TRUE))
DBUG_RETURN(TRUE);
@@ -589,16 +613,13 @@ int mysql_multi_delete_prepare(THD *thd)
target_tbl;
target_tbl= target_tbl->next_local)
{
+
if (!(target_tbl->table= target_tbl->correspondent_table->table))
{
- DBUG_ASSERT(target_tbl->correspondent_table->view &&
- target_tbl->correspondent_table->merge_underlying_list &&
- target_tbl->correspondent_table->merge_underlying_list->
- next_local);
- my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
- target_tbl->correspondent_table->view_db.str,
- target_tbl->correspondent_table->view_name.str);
- DBUG_RETURN(TRUE);
+ my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
+ target_tbl->correspondent_table->view_db.str,
+ target_tbl->correspondent_table->view_name.str);
+ DBUG_RETURN(TRUE);
}
if (!target_tbl->correspondent_table->updatable ||
@@ -648,6 +669,12 @@ multi_delete::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
unit= u;
do_delete= 1;
thd_proc_info(thd, "deleting from main table");
+ SELECT_LEX *select_lex= u->first_select();
+ if (select_lex->first_cond_optimization)
+ {
+ if (select_lex->handle_derived(thd->lex, DT_MERGE))
+ DBUG_RETURN(TRUE);
+ }
DBUG_RETURN(0);
}