mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
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).
This commit is contained in:
@ -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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@ public:
|
|||||||
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)
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
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;
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
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
|
||||||
|
Reference in New Issue
Block a user