1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

MDEV-3798: [SHOW] EXPLAIN UPDATE/DELETE

- Merge with 10.0-base
This commit is contained in:
Sergey Petrunya
2013-10-15 11:51:41 +04:00
71 changed files with 8292 additions and 713 deletions

View File

@ -598,6 +598,7 @@ static void handle_bootstrap_impl(THD *thd)
#if defined(ENABLED_PROFILING)
thd->profiling.finish_current_query();
#endif
delete_explain_query(thd->lex);
if (bootstrap_error)
break;
@ -807,7 +808,9 @@ bool do_command(THD *thd)
my_net_set_read_timeout(net, thd->variables.net_read_timeout);
DBUG_ASSERT(packet_length);
DBUG_ASSERT(!thd->apc_target.is_enabled());
return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1));
DBUG_ASSERT(!thd->apc_target.is_enabled());
out:
DBUG_RETURN(return_value);
@ -1117,6 +1120,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
ulong length= (ulong)(packet_end - beginning_of_next_stmt);
log_slow_statement(thd);
DBUG_ASSERT(!thd->apc_target.is_enabled());
/* Remove garbage at start of query */
while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
@ -1520,10 +1524,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
/*
@note
This function must call delete_explain_query().
*/
void log_slow_statement(THD *thd)
{
DBUG_ENTER("log_slow_statement");
/*
The following should never be true with our current code base,
but better to keep this here so we don't accidently try to log a
@ -1532,11 +1541,15 @@ void log_slow_statement(THD *thd)
if (unlikely(thd->in_sub_stmt))
DBUG_VOID_RETURN; // Don't set time for sub stmt
/* Follow the slow log filter configuration. */
if (!thd->enable_slow_log ||
(thd->variables.log_slow_filter
&& !(thd->variables.log_slow_filter & thd->query_plan_flags)))
{
delete_explain_query(thd->lex);
DBUG_VOID_RETURN;
}
if (((thd->server_status & SERVER_QUERY_WAS_SLOW) ||
((thd->server_status &
@ -1559,6 +1572,8 @@ void log_slow_statement(THD *thd)
thd->utime_after_query);
thd_proc_info(thd, 0);
}
delete_explain_query(thd->lex);
DBUG_VOID_RETURN;
}
@ -2185,6 +2200,8 @@ mysql_execute_command(THD *thd)
/* Release metadata locks acquired in this transaction. */
thd->mdl_context.release_transactional_locks();
}
create_explain_query(thd->lex, thd->mem_root);
#ifndef DBUG_OFF
if (lex->sql_command != SQLCOM_SET_OPTION)
@ -3156,6 +3173,7 @@ end_with_restore_list:
case SQLCOM_INSERT_SELECT:
{
select_result *sel_result;
bool explain= test(lex->describe);
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if ((res= insert_precheck(thd, all_tables)))
break;
@ -3225,6 +3243,10 @@ end_with_restore_list:
}
delete sel_result;
}
if (!res && explain)
res= thd->lex->explain->send_explain(thd);
/* revert changes for SP */
MYSQL_INSERT_SELECT_DONE(res, (ulong) thd->get_row_count_func());
select_lex->table_list.first= first_table;
@ -3265,7 +3287,8 @@ end_with_restore_list:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
multi_delete *del_result;
bool explain= test(lex->describe);
select_result *result;
if ((res= multi_delete_precheck(thd, all_tables)))
break;
@ -3287,25 +3310,34 @@ end_with_restore_list:
goto error;
}
if (!thd->is_fatal_error &&
(del_result= new multi_delete(aux_tables, lex->table_count)))
if (!thd->is_fatal_error)
{
res= mysql_select(thd, &select_lex->ref_pointer_array,
select_lex->get_table_list(),
select_lex->with_wild,
select_lex->item_list,
select_lex->where,
0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
(ORDER *)NULL,
(select_lex->options | thd->variables.option_bits |
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
OPTION_SETUP_TABLES_DONE) & ~OPTION_BUFFER_RESULT,
del_result, unit, select_lex);
res|= thd->is_error();
MYSQL_MULTI_DELETE_DONE(res, del_result->num_deleted());
if (res)
del_result->abort_result_set();
delete del_result;
result= new multi_delete(aux_tables, lex->table_count);
if (result)
{
res= mysql_select(thd, &select_lex->ref_pointer_array,
select_lex->get_table_list(),
select_lex->with_wild,
select_lex->item_list,
select_lex->where,
0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
(ORDER *)NULL,
(select_lex->options | thd->variables.option_bits |
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
OPTION_SETUP_TABLES_DONE) & ~OPTION_BUFFER_RESULT,
result, unit, select_lex);
res|= thd->is_error();
MYSQL_MULTI_DELETE_DONE(res, del_result->num_deleted());
if (res)
result->abort_result_set(); /* for both DELETE and EXPLAIN DELETE */
else
{
if (explain)
res= thd->lex->explain->send_explain(thd);
}
delete result;
}
}
else
{
@ -4743,8 +4775,8 @@ finish:
ha_maria::implicit_commit(thd, FALSE);
#endif
}
lex->unit.cleanup();
/* Free tables */
thd_proc_info(thd, "closing tables");
close_thread_tables(thd);
@ -4819,24 +4851,37 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
if (!(result= new select_send()))
return 1; /* purecov: inspected */
thd->send_explain_fields(result);
res= mysql_explain_union(thd, &thd->lex->unit, result);
/*
The code which prints the extended description is not robust
against malformed queries, so skip it if we have an error.
This will call optimize() for all parts of query. The query plan is
printed out below.
*/
if (!res && (lex->describe & DESCRIBE_EXTENDED))
res= mysql_explain_union(thd, &thd->lex->unit, result);
/* Print EXPLAIN only if we don't have an error */
if (!res)
{
char buff[1024];
String str(buff,(uint32) sizeof(buff), system_charset_info);
str.length(0);
/*
The warnings system requires input in utf8, @see
mysqld_show_warnings().
*/
thd->lex->unit.print(&str, QT_TO_SYSTEM_CHARSET);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_YES, str.c_ptr_safe());
/*
Do like the original select_describe did: remove OFFSET from the
top-level LIMIT
*/
result->reset_offset_limit();
thd->lex->explain->print_explain(result, thd->lex->describe);
if (lex->describe & DESCRIBE_EXTENDED)
{
char buff[1024];
String str(buff,(uint32) sizeof(buff), system_charset_info);
str.length(0);
/*
The warnings system requires input in utf8, @see
mysqld_show_warnings().
*/
thd->lex->unit.print(&str, QT_TO_SYSTEM_CHARSET);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_YES, str.c_ptr_safe());
}
}
if (res)
result->abort_result_set();
else