Commit 47ced655 authored by Sergei Petrunia's avatar Sergei Petrunia

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).
parent d3bdc142
...@@ -2951,7 +2951,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, ...@@ -2951,7 +2951,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
{ {
StringBuffer<128> buf; StringBuffer<128> buf;
DBUG_ASSERT(!thd->free_list); 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()); my_b_printf(&log_file, "%s", buf.c_ptr_safe());
thd->free_items(); thd->free_items();
} }
......
...@@ -2367,10 +2367,10 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length) ...@@ -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<Item> field_list; List<Item> field_list;
make_explain_field_list(field_list); make_explain_field_list(field_list, explain_flags, is_analyze);
result->prepare(field_list, NULL); result->prepare(field_list, NULL);
return (result->send_result_set_metadata(field_list, return (result->send_result_set_metadata(field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_NUM_ROWS |
...@@ -2386,7 +2386,8 @@ int THD::send_explain_fields(select_result *result) ...@@ -2386,7 +2386,8 @@ int THD::send_explain_fields(select_result *result)
Explain_query::print_explain and co. Explain_query::print_explain and co.
*/ */
void THD::make_explain_field_list(List<Item> &field_list) void THD::make_explain_field_list(List<Item> &field_list, uint8 explain_flags,
bool is_analyze)
{ {
Item *item; Item *item;
CHARSET_INFO *cs= system_charset_info; CHARSET_INFO *cs= system_charset_info;
...@@ -2395,7 +2396,7 @@ void THD::make_explain_field_list(List<Item> &field_list) ...@@ -2395,7 +2396,7 @@ void THD::make_explain_field_list(List<Item> &field_list)
field_list.push_back(new Item_empty_string("select_type", 19, cs)); 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)); field_list.push_back(item= new Item_empty_string("table", NAME_CHAR_LEN, cs));
item->maybe_null= 1; 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 */ /* Maximum length of string that make_used_partitions_str() can produce */
item= new Item_empty_string("partitions", MAX_PARTITIONS * (1 + FN_LEN), item= new Item_empty_string("partitions", MAX_PARTITIONS * (1 + FN_LEN),
...@@ -2419,20 +2420,20 @@ void THD::make_explain_field_list(List<Item> &field_list) ...@@ -2419,20 +2420,20 @@ void THD::make_explain_field_list(List<Item> &field_list)
item->maybe_null=1; item->maybe_null=1;
field_list.push_back(item= new Item_return_int("rows", 10, field_list.push_back(item= new Item_return_int("rows", 10,
MYSQL_TYPE_LONGLONG)); MYSQL_TYPE_LONGLONG));
if (lex->analyze_stmt) if (is_analyze)
{ {
field_list.push_back(item= new Item_return_int("r_rows", 10, field_list.push_back(item= new Item_return_int("r_rows", 10,
MYSQL_TYPE_LONGLONG)); MYSQL_TYPE_LONGLONG));
item->maybe_null=1; 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)); field_list.push_back(item= new Item_float("filtered", 0.1234, 2, 4));
item->maybe_null=1; 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)); field_list.push_back(item= new Item_float("r_filtered", 0.1234, 2, 4));
item->maybe_null=1; item->maybe_null=1;
......
...@@ -3083,8 +3083,10 @@ class THD :public Statement, ...@@ -3083,8 +3083,10 @@ class THD :public Statement,
void add_changed_table(TABLE *table); void add_changed_table(TABLE *table);
void add_changed_table(const char *key, long key_length); void add_changed_table(const char *key, long key_length);
CHANGED_TABLE_LIST * changed_table_dup(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); int send_explain_fields(select_result *result, uint8 explain_flags,
void make_explain_field_list(List<Item> &field_list); bool is_analyze);
void make_explain_field_list(List<Item> &field_list, uint8 explain_flags,
bool is_analyze);
/** /**
Clear the current error, if any. Clear the current error, if any.
We do not clear is_fatal_error or is_fatal_sub_stmt_error since we We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
......
...@@ -136,7 +136,7 @@ int Explain_query::send_explain(THD *thd) ...@@ -136,7 +136,7 @@ int Explain_query::send_explain(THD *thd)
LEX *lex= thd->lex; LEX *lex= thd->lex;
if (!(result= new select_send()) || if (!(result= new select_send()) ||
thd->send_explain_fields(result)) thd->send_explain_fields(result, lex->describe, lex->analyze_stmt))
return 1; return 1;
int res; int res;
...@@ -177,9 +177,9 @@ int Explain_query::print_explain(select_result_sink *output, ...@@ -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) ...@@ -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) bool Explain_query::print_explain_str(THD *thd, String *out_str, bool is_analyze)
{ {
List<Item> fields; List<Item> 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); select_result_text_buffer output_buf(thd);
output_buf.send_result_set_metadata(fields, thd->lex->describe); output_buf.send_result_set_metadata(fields, thd->lex->describe);
......
...@@ -541,7 +541,7 @@ class Explain_query; ...@@ -541,7 +541,7 @@ class Explain_query;
void delete_explain_query(LEX *lex); void delete_explain_query(LEX *lex);
void create_explain_query(LEX *lex, MEM_ROOT *mem_root); void create_explain_query(LEX *lex, MEM_ROOT *mem_root);
void create_explain_query_if_not_exists(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 { class st_select_lex_unit: public st_select_lex_node {
protected: protected:
......
...@@ -5618,7 +5618,7 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) ...@@ -5618,7 +5618,7 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
*/ */
if (!(result= new select_send())) if (!(result= new select_send()))
return 1; /* purecov: inspected */ 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 This will call optimize() for all parts of query. The query plan is
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment