From 47ced6556652beb39cee0f280c3cfb3e39ba74e5 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 17 Oct 2014 22:47:06 +0400 Subject: [PATCH] MDEV-6388: ANALYZE $stmt output in the slow query log Make log_slow_verbosity=explain actually print ANALYZE (that is, EXPLAIN otuput with two extra columns). --- sql/log.cc | 2 +- sql/sql_class.cc | 15 ++++++++------- sql/sql_class.h | 6 ++++-- sql/sql_explain.cc | 8 ++++---- sql/sql_lex.h | 2 +- sql/sql_parse.cc | 2 +- 6 files changed, 19 insertions(+), 16 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 4e50f57e656..ff04105b43d 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2951,7 +2951,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, { StringBuffer<128> buf; DBUG_ASSERT(!thd->free_list); - if (!print_explain_query(thd->lex, thd, &buf)) + if (!print_explain_for_slow_log(thd->lex, thd, &buf)) my_b_printf(&log_file, "%s", buf.c_ptr_safe()); thd->free_items(); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index e51203c7d20..34fa0308f7d 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2367,10 +2367,10 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length) } -int THD::send_explain_fields(select_result *result) +int THD::send_explain_fields(select_result *result, uint8 explain_flags, bool is_analyze) { List field_list; - make_explain_field_list(field_list); + make_explain_field_list(field_list, explain_flags, is_analyze); result->prepare(field_list, NULL); return (result->send_result_set_metadata(field_list, Protocol::SEND_NUM_ROWS | @@ -2386,7 +2386,8 @@ int THD::send_explain_fields(select_result *result) Explain_query::print_explain and co. */ -void THD::make_explain_field_list(List &field_list) +void THD::make_explain_field_list(List &field_list, uint8 explain_flags, + bool is_analyze) { Item *item; CHARSET_INFO *cs= system_charset_info; @@ -2395,7 +2396,7 @@ void THD::make_explain_field_list(List &field_list) field_list.push_back(new Item_empty_string("select_type", 19, cs)); field_list.push_back(item= new Item_empty_string("table", NAME_CHAR_LEN, cs)); item->maybe_null= 1; - if (lex->describe & DESCRIBE_PARTITIONS) + if (explain_flags & DESCRIBE_PARTITIONS) { /* Maximum length of string that make_used_partitions_str() can produce */ item= new Item_empty_string("partitions", MAX_PARTITIONS * (1 + FN_LEN), @@ -2419,20 +2420,20 @@ void THD::make_explain_field_list(List &field_list) item->maybe_null=1; field_list.push_back(item= new Item_return_int("rows", 10, MYSQL_TYPE_LONGLONG)); - if (lex->analyze_stmt) + if (is_analyze) { field_list.push_back(item= new Item_return_int("r_rows", 10, MYSQL_TYPE_LONGLONG)); item->maybe_null=1; } - if (lex->analyze_stmt || lex->describe & DESCRIBE_EXTENDED) + if (is_analyze || (explain_flags & DESCRIBE_EXTENDED)) { field_list.push_back(item= new Item_float("filtered", 0.1234, 2, 4)); item->maybe_null=1; } - if (lex->analyze_stmt) + if (is_analyze) { field_list.push_back(item= new Item_float("r_filtered", 0.1234, 2, 4)); item->maybe_null=1; diff --git a/sql/sql_class.h b/sql/sql_class.h index 4c83de2767b..b1881db49e9 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3083,8 +3083,10 @@ public: void add_changed_table(TABLE *table); void add_changed_table(const char *key, long key_length); CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length); - int send_explain_fields(select_result *result); - void make_explain_field_list(List &field_list); + int send_explain_fields(select_result *result, uint8 explain_flags, + bool is_analyze); + void make_explain_field_list(List &field_list, uint8 explain_flags, + bool is_analyze); /** Clear the current error, if any. We do not clear is_fatal_error or is_fatal_sub_stmt_error since we diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index ce266a723c2..7bab96e8ea5 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -136,7 +136,7 @@ int Explain_query::send_explain(THD *thd) LEX *lex= thd->lex; if (!(result= new select_send()) || - thd->send_explain_fields(result)) + thd->send_explain_fields(result, lex->describe, lex->analyze_stmt)) return 1; int res; @@ -177,9 +177,9 @@ int Explain_query::print_explain(select_result_sink *output, } -bool print_explain_query(LEX *lex, THD *thd, String *str) +bool print_explain_for_slow_log(LEX *lex, THD *thd, String *str) { - return lex->explain->print_explain_str(thd, str, false); + return lex->explain->print_explain_str(thd, str, /*is_analyze*/ true); } @@ -190,7 +190,7 @@ bool print_explain_query(LEX *lex, THD *thd, String *str) bool Explain_query::print_explain_str(THD *thd, String *out_str, bool is_analyze) { List fields; - thd->make_explain_field_list(fields); + thd->make_explain_field_list(fields, thd->lex->describe, is_analyze); select_result_text_buffer output_buf(thd); output_buf.send_result_set_metadata(fields, thd->lex->describe); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 27c78eb1be9..deb476296fd 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -541,7 +541,7 @@ class Explain_query; void delete_explain_query(LEX *lex); void create_explain_query(LEX *lex, MEM_ROOT *mem_root); void create_explain_query_if_not_exists(LEX *lex, MEM_ROOT *mem_root); -bool print_explain_query(LEX *lex, THD *thd, String *str); +bool print_explain_for_slow_log(LEX *lex, THD *thd, String *str); class st_select_lex_unit: public st_select_lex_node { protected: diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ccaef9d0fcc..b905d8b0bd6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5618,7 +5618,7 @@ 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); + thd->send_explain_fields(result, lex->describe, lex->analyze_stmt); /* This will call optimize() for all parts of query. The query plan is