summaryrefslogtreecommitdiff
path: root/sql/sql_delete.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_delete.cc')
-rw-r--r--sql/sql_delete.cc71
1 files changed, 23 insertions, 48 deletions
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index f4cad88124f..bef77e1a2e9 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -30,7 +30,6 @@
#include "lock.h" // unlock_table_name
#include "sql_view.h" // check_key_in_view, mysql_frm_type
#include "sql_parse.h" // mysql_init_select
-#include "sql_acl.h" // *_ACL
#include "filesort.h" // filesort
#include "sql_handler.h" // mysql_ha_rm_tables
#include "sql_select.h"
@@ -199,23 +198,12 @@ bool Update_plan::save_explain_data_intern(MEM_ROOT *mem_root,
&explain->mrr_type);
}
- bool skip= updating_a_view;
-
/* Save subquery children */
for (SELECT_LEX_UNIT *unit= select_lex->first_inner_unit();
unit;
unit= unit->next_unit())
{
- if (skip)
- {
- skip= false;
- continue;
- }
- /*
- Display subqueries only if they are not parts of eliminated WHERE/ON
- clauses.
- */
- if (!(unit->item && unit->item->eliminated))
+ if (unit->explainable())
explain->add_child(unit->first_select()->select_number);
}
return 0;
@@ -322,10 +310,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
ORDER *order= (ORDER *) ((order_list && order_list->elements) ?
order_list->first : NULL);
SELECT_LEX *select_lex= thd->lex->first_select_lex();
+ SELECT_LEX *returning= thd->lex->has_returning() ? thd->lex->returning() : 0;
killed_state killed_status= NOT_KILLED;
THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE;
bool binlog_is_row;
- bool with_select= !select_lex->item_list.is_empty();
Explain_delete *explain;
Delete_plan query_plan(thd->mem_root);
Unique * deltempfile= NULL;
@@ -365,18 +353,15 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
table->map=1;
query_plan.select_lex= thd->lex->first_select_lex();
query_plan.table= table;
- query_plan.updating_a_view= MY_TEST(table_list->view);
- if (mysql_prepare_delete(thd, table_list, select_lex->with_wild,
- select_lex->item_list, &conds,
- &delete_while_scanning))
+ if (mysql_prepare_delete(thd, table_list, &conds, &delete_while_scanning))
DBUG_RETURN(TRUE);
if (delete_history)
table->vers_write= false;
- if (with_select)
- (void) result->prepare(select_lex->item_list, NULL);
+ if (returning)
+ (void) result->prepare(returning->item_list, NULL);
if (thd->lex->current_select->first_cond_optimization)
{
@@ -441,9 +426,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
has_triggers= table->triggers && table->triggers->has_delete_triggers();
- if (!with_select && !using_limit && const_cond_result &&
- (!thd->is_current_stmt_binlog_format_row() &&
- !has_triggers)
+ if (!returning && !using_limit && const_cond_result &&
+ (!thd->is_current_stmt_binlog_format_row() && !has_triggers)
&& !table->versioned(VERS_TIMESTAMP) && !table_list->has_period())
{
/* Update the table->file->stats.records number */
@@ -585,7 +569,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (!(explain= query_plan.save_explain_delete_data(thd->mem_root, thd)))
goto got_error;
- ANALYZE_START_TRACKING(&explain->command_tracker);
+ ANALYZE_START_TRACKING(thd, &explain->command_tracker);
DBUG_EXECUTE_IF("show_explain_probe_delete_exec_start",
dbug_serve_apcs(thd, 1););
@@ -614,7 +598,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
*/
if ((table->file->ha_table_flags() & HA_CAN_DIRECT_UPDATE_AND_DELETE) &&
- !has_triggers && !binlog_is_row && !with_select &&
+ !has_triggers && !binlog_is_row && !returning &&
!table_list->has_period())
{
table->mark_columns_needed_for_delete();
@@ -664,7 +648,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DELETE ... RETURNING we can't, because the RETURNING part may have
a subquery in it)
*/
- if (!with_select)
+ if (!returning)
free_underlaid_joins(thd, select_lex);
select= 0;
}
@@ -699,11 +683,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
!table->prepare_triggers_for_delete_stmt_or_event())
will_batch= !table->file->start_bulk_delete();
- if (with_select)
+ if (returning)
{
- if (unlikely(result->send_result_set_metadata(select_lex->item_list,
- Protocol::SEND_NUM_ROWS |
- Protocol::SEND_EOF)))
+ if (result->send_result_set_metadata(returning->item_list,
+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
goto cleanup;
}
@@ -785,7 +768,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
break;
}
- if (with_select && result->send_data(select_lex->item_list) < 0)
+ // no LIMIT / OFFSET
+ if (returning && result->send_data(returning->item_list) < 0)
{
error=1;
break;
@@ -863,7 +847,7 @@ terminate_delete:
table->file->ha_release_auto_increment();
if (options & OPTION_QUICK)
(void) table->file->extra(HA_EXTRA_NORMAL);
- ANALYZE_STOP_TRACKING(&explain->command_tracker);
+ ANALYZE_STOP_TRACKING(thd, &explain->command_tracker);
cleanup:
/*
@@ -929,7 +913,7 @@ cleanup:
if (thd->lex->analyze_stmt)
goto send_nothing_and_leave;
- if (with_select)
+ if (returning)
result->send_eof();
else
my_ok(thd, deleted);
@@ -979,16 +963,13 @@ got_error:
mysql_prepare_delete()
thd - thread handler
table_list - global/local table list
- wild_num - number of wildcards used in optional SELECT clause
- field_list - list of items in optional SELECT clause
conds - conditions
RETURN VALUE
FALSE OK
TRUE error
*/
-int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list,
- uint wild_num, List<Item> &field_list, Item **conds,
+int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds,
bool *delete_while_scanning)
{
Item *fake_conds= 0;
@@ -998,12 +979,9 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list,
*delete_while_scanning= true;
thd->lex->allow_sum_func.clear_all();
- if (setup_tables_and_check_access(thd,
- &thd->lex->first_select_lex()->context,
- &thd->lex->first_select_lex()->
- top_join_list,
- table_list,
- select_lex->leaf_tables, FALSE,
+ if (setup_tables_and_check_access(thd, &select_lex->context,
+ &select_lex->top_join_list, table_list,
+ select_lex->leaf_tables, FALSE,
DELETE_ACL, SELECT_ACL, TRUE))
DBUG_RETURN(TRUE);
@@ -1034,10 +1012,7 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list,
*conds= select_lex->where;
- if ((wild_num && setup_wild(thd, table_list, field_list, NULL, wild_num,
- &select_lex->hidden_bit_fields)) ||
- setup_fields(thd, Ref_ptr_array(),
- field_list, MARK_COLUMNS_READ, NULL, NULL, 0) ||
+ if (setup_returning_fields(thd, table_list) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
setup_ftfuncs(select_lex))
DBUG_RETURN(TRUE);
@@ -1061,7 +1036,7 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list,
fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
DBUG_RETURN(TRUE);
- select_lex->fix_prepare_information(thd, conds, &fake_conds);
+ select_lex->fix_prepare_information(thd, conds, &fake_conds);
DBUG_RETURN(FALSE);
}