diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2013-10-15 11:51:41 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2013-10-15 11:51:41 +0400 |
commit | 1e36cbfa391ac80297958a4cc72d676e15eb1b37 (patch) | |
tree | 2304f70f5fd0d810ae7690360c65283015f08b5c /sql/sql_parse.cc | |
parent | eb2c6f451392396ef2ca74f1dba761fc4459d171 (diff) | |
parent | 25d0175fde2bff7397628d91c30aac8ba9d56301 (diff) | |
download | mariadb-git-1e36cbfa391ac80297958a4cc72d676e15eb1b37.tar.gz |
MDEV-3798: [SHOW] EXPLAIN UPDATE/DELETE
- Merge with 10.0-base
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r-- | sql/sql_parse.cc | 115 |
1 files changed, 80 insertions, 35 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index da245c2d508..d7d2358e5d5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -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))) - { - 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; + if (!thd->is_fatal_error) + { + 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 |