Commit d97ca5f5 authored by Sergey Petrunya's avatar Sergey Petrunya

[SHOW] EXPLAIN UPDATE/DELETE, code reordering

- Add further details, the goal is to pass the testsuite
- SJM-nests are not printed correctly yet.
parent 03691a77
...@@ -17,6 +17,16 @@ QPF_query::QPF_query() ...@@ -17,6 +17,16 @@ QPF_query::QPF_query()
} }
QPF_query::~QPF_query()
{
uint i;
for (i=0 ; i < MAX_TABLES; i++)
delete unions[i];
for (i=0 ; i < MAX_TABLES; i++)
delete selects[i];
}
QPF_node *QPF_query::get_node(uint select_id) QPF_node *QPF_query::get_node(uint select_id)
{ {
if (unions[select_id]) if (unions[select_id])
...@@ -178,6 +188,17 @@ int QPF_union::print_explain(QPF_query *query, select_result_sink *output, ...@@ -178,6 +188,17 @@ int QPF_union::print_explain(QPF_query *query, select_result_sink *output,
} }
QPF_select::~QPF_select()
{
if (join_tabs)
{
for (uint i= 0; i< n_join_tabs; i++)
delete join_tabs[i];
my_free(join_tabs);
}
}
int QPF_select::print_explain(QPF_query *query, select_result_sink *output, int QPF_select::print_explain(QPF_query *query, select_result_sink *output,
uint8 explain_flags) uint8 explain_flags)
{ {
...@@ -222,6 +243,13 @@ int QPF_select::print_explain(QPF_query *query, select_result_sink *output, ...@@ -222,6 +243,13 @@ int QPF_select::print_explain(QPF_query *query, select_result_sink *output,
} }
} }
} }
//psergey-TODO: print children here...
for (int i= 0; i < (int) children.elements(); i++)
{
QPF_node *node= query->get_node(children.at(i));
node->print_explain(query, output, explain_flags);
}
return 0; return 0;
} }
...@@ -259,7 +287,10 @@ int QPF_table_access::print_explain(select_result_sink *output, uint8 explain_fl ...@@ -259,7 +287,10 @@ int QPF_table_access::print_explain(select_result_sink *output, uint8 explain_fl
/* `possible_keys` column */ /* `possible_keys` column */
//push_str(item_list, "TODO"); //push_str(item_list, "TODO");
item_list.push_back(item_null); if (possible_keys_str.length() > 0)
push_string(&item_list, &possible_keys_str);
else
item_list.push_back(item_null);
/* `key` */ /* `key` */
if (key_set) if (key_set)
......
...@@ -48,33 +48,19 @@ class QPF_select : public QPF_node ...@@ -48,33 +48,19 @@ class QPF_select : public QPF_node
public: public:
enum qpf_node_type get_type() { return QPF_SELECT; } enum qpf_node_type get_type() { return QPF_SELECT; }
#if 0
/* Constructs a finished degenerate join plan */
QPF_select(int select_id_arg, const char *select_type_arg, const char* msg) :
select_id(select_id_arg),
select_type(select_type_arg),
message(msg),
join_tabs(NULL), n_join_tabs(0)
{}
/* Constructs an un-finished, non degenerate join plan. */
QPF_select(int select_id_arg, const char *select_type_arg) :
select_id(select_id_arg),
select_type(select_type_arg),
message(NULL),
join_tabs(NULL), n_join_tabs(0)
{}
#endif
QPF_select() : QPF_select() :
message(NULL), join_tabs(NULL), message(NULL), join_tabs(NULL),
using_temporary(false), using_filesort(false) using_temporary(false), using_filesort(false)
{} {}
~QPF_select();
bool add_table(QPF_table_access *tab) bool add_table(QPF_table_access *tab)
{ {
if (!join_tabs) if (!join_tabs)
{ {
join_tabs= (QPF_table_access**) malloc(sizeof(QPF_table_access*) * MAX_TABLES); join_tabs= (QPF_table_access**) my_malloc(sizeof(QPF_table_access*) *
MAX_TABLES, MYF(0));
n_join_tabs= 0; n_join_tabs= 0;
} }
join_tabs[n_join_tabs++]= tab; join_tabs[n_join_tabs++]= tab;
...@@ -103,6 +89,13 @@ public: ...@@ -103,6 +89,13 @@ public:
/* Global join attributes. In tabular form, they are printed on the first row */ /* Global join attributes. In tabular form, they are printed on the first row */
bool using_temporary; bool using_temporary;
bool using_filesort; bool using_filesort;
/* Child selects. TODO: join this with QPF_union's children? */
Dynamic_array<int> children;
void add_child(int select_no)
{
children.append(select_no);
}
void print_tabular(select_result_sink *output, uint8 explain_flags//, void print_tabular(select_result_sink *output, uint8 explain_flags//,
//bool *printed_anything //bool *printed_anything
...@@ -143,10 +136,11 @@ public: ...@@ -143,10 +136,11 @@ public:
This is the whole query. This is the whole query.
*/ */
class QPF_query class QPF_query : public Sql_alloc
{ {
public: public:
QPF_query(); QPF_query();
~QPF_query();
void add_node(QPF_node *node); void add_node(QPF_node *node);
int print_explain(select_result_sink *output, uint8 explain_flags); int print_explain(select_result_sink *output, uint8 explain_flags);
...@@ -203,7 +197,7 @@ enum Extra_tag ...@@ -203,7 +197,7 @@ enum Extra_tag
}; };
class QPF_table_access class QPF_table_access : public Sql_alloc
{ {
public: public:
void push_extra(enum Extra_tag extra_tag); void push_extra(enum Extra_tag extra_tag);
...@@ -220,6 +214,7 @@ public: ...@@ -220,6 +214,7 @@ public:
bool used_partitions_set; bool used_partitions_set;
key_map possible_keys; key_map possible_keys;
StringBuffer<256> possible_keys_str;
uint key_no; uint key_no;
uint key_length; uint key_length;
......
...@@ -4814,7 +4814,12 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) ...@@ -4814,7 +4814,12 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
thd->lex->query_plan_footprint= new QPF_query; thd->lex->query_plan_footprint= new QPF_query;
res= mysql_explain_union(thd, &thd->lex->unit, result); res= mysql_explain_union(thd, &thd->lex->unit, result);
thd->lex->query_plan_footprint->print_explain(result, thd->lex->describe); if (!res)
{
thd->lex->query_plan_footprint->print_explain(result, thd->lex->describe);
}
delete thd->lex->query_plan_footprint;
thd->lex->query_plan_footprint= NULL;
//psergey-todo: here, produce the EXPLAIN output. //psergey-todo: here, produce the EXPLAIN output.
// mysql_explain_union() itself is only responsible for calling // mysql_explain_union() itself is only responsible for calling
......
...@@ -22903,6 +22903,21 @@ void QPF_table_access::push_extra(enum Extra_tag extra_tag) ...@@ -22903,6 +22903,21 @@ void QPF_table_access::push_extra(enum Extra_tag extra_tag)
extra_tags.append(extra_tag); extra_tags.append(extra_tag);
} }
void append_possible_keys(String *str, TABLE *table, key_map possible_keys)
{
uint j;
for (j=0 ; j < table->s->keys ; j++)
{
if (possible_keys.is_set(j))
{
if (str->length())
str->append(',');
str->append(table->key_info[j].name,
strlen(table->key_info[j].name),
system_charset_info);
}
}
}
/* /*
Save Query Plan Footprint Save Query Plan Footprint
...@@ -22982,9 +22997,6 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order, ...@@ -22982,9 +22997,6 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order,
for (JOIN_TAB *tab= first_breadth_first_tab(join, WALK_OPTIMIZATION_TABS); tab; for (JOIN_TAB *tab= first_breadth_first_tab(join, WALK_OPTIMIZATION_TABS); tab;
tab= next_breadth_first_tab(join, WALK_OPTIMIZATION_TABS, tab)) tab= next_breadth_first_tab(join, WALK_OPTIMIZATION_TABS, tab))
{ {
QPF_table_access *qpt= new QPF_table_access;
qp_sel->add_table(qpt);
if (tab->bush_root_tab) if (tab->bush_root_tab)
{ {
JOIN_TAB *first_sibling= tab->bush_root_tab->bush_children->start; JOIN_TAB *first_sibling= tab->bush_root_tab->bush_children->start;
...@@ -23020,7 +23032,6 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order, ...@@ -23020,7 +23032,6 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order,
continue; continue;
} }
if (join->table_access_tabs == join->join_tab && if (join->table_access_tabs == join->join_tab &&
tab == (first_top_tab + join->const_tables) && pre_sort_join_tab) tab == (first_top_tab + join->const_tables) && pre_sort_join_tab)
{ {
...@@ -23028,8 +23039,12 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order, ...@@ -23028,8 +23039,12 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order,
tab= pre_sort_join_tab; tab= pre_sort_join_tab;
} }
QPF_table_access *qpt= new QPF_table_access;
qp_sel->add_table(qpt);
/* id */ /* id */
qp_sel->select_id= select_id; // TODO: this can be '2' in case of SJM nests..
//qp_sel->select_id= select_id;
/* select_type */ /* select_type */
//const char* stype= printing_materialize_nest? "MATERIALIZED" : //const char* stype= printing_materialize_nest? "MATERIALIZED" :
...@@ -23099,6 +23114,7 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order, ...@@ -23099,6 +23114,7 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order,
/* Build "possible_keys" value */ /* Build "possible_keys" value */
qpt->possible_keys= tab->keys; qpt->possible_keys= tab->keys;
append_possible_keys(&qpt->possible_keys_str, table, tab->keys);
/* Build "key", "key_len", and "ref" */ /* Build "key", "key_len", and "ref" */
...@@ -23379,9 +23395,10 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order, ...@@ -23379,9 +23395,10 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order,
*/ */
if (quick_type == QUICK_SELECT_I::QS_TYPE_RANGE) if (quick_type == QUICK_SELECT_I::QS_TYPE_RANGE)
{ {
qpt->push_extra(ET_USING_MRR);
explain_append_mrr_info((QUICK_RANGE_SELECT*)(tab->select->quick), explain_append_mrr_info((QUICK_RANGE_SELECT*)(tab->select->quick),
&qpt->mrr_type); &qpt->mrr_type);
if (qpt->mrr_type.length() > 0)
qpt->push_extra(ET_USING_MRR);
} }
if (need_tmp_table) if (need_tmp_table)
...@@ -23463,6 +23480,23 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order, ...@@ -23463,6 +23480,23 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order,
} }
output->add_node(qp_sel); output->add_node(qp_sel);
} }
///
for (SELECT_LEX_UNIT *unit= join->select_lex->first_inner_unit();
unit;
unit= unit->next_unit())
{
/*
Display subqueries only if they are not parts of eliminated WHERE/ON
clauses.
*/
if (!(unit->item && unit->item->eliminated))
{
qp_sel->add_child(unit->first_select()->select_number);
}
}
DBUG_RETURN(error); DBUG_RETURN(error);
} }
......
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