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()
}
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)
{
if (unions[select_id])
......@@ -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,
uint8 explain_flags)
{
......@@ -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;
}
......@@ -259,7 +287,10 @@ int QPF_table_access::print_explain(select_result_sink *output, uint8 explain_fl
/* `possible_keys` column */
//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` */
if (key_set)
......
......@@ -48,33 +48,19 @@ class QPF_select : public QPF_node
public:
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() :
message(NULL), join_tabs(NULL),
using_temporary(false), using_filesort(false)
{}
~QPF_select();
bool add_table(QPF_table_access *tab)
{
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;
}
join_tabs[n_join_tabs++]= tab;
......@@ -103,6 +89,13 @@ class QPF_select : public QPF_node
/* Global join attributes. In tabular form, they are printed on the first row */
bool using_temporary;
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//,
//bool *printed_anything
......@@ -143,10 +136,11 @@ class QPF_union : public QPF_node
This is the whole query.
*/
class QPF_query
class QPF_query : public Sql_alloc
{
public:
QPF_query();
~QPF_query();
void add_node(QPF_node *node);
int print_explain(select_result_sink *output, uint8 explain_flags);
......@@ -203,7 +197,7 @@ enum Extra_tag
};
class QPF_table_access
class QPF_table_access : public Sql_alloc
{
public:
void push_extra(enum Extra_tag extra_tag);
......@@ -220,6 +214,7 @@ class QPF_table_access
bool used_partitions_set;
key_map possible_keys;
StringBuffer<256> possible_keys_str;
uint key_no;
uint key_length;
......
......@@ -4814,7 +4814,12 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
thd->lex->query_plan_footprint= new QPF_query;
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.
// mysql_explain_union() itself is only responsible for calling
......
......@@ -22903,6 +22903,21 @@ void QPF_table_access::push_extra(enum Extra_tag 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
......@@ -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;
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)
{
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,
continue;
}
if (join->table_access_tabs == join->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,
tab= pre_sort_join_tab;
}
QPF_table_access *qpt= new QPF_table_access;
qp_sel->add_table(qpt);
/* 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 */
//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,
/* Build "possible_keys" value */
qpt->possible_keys= tab->keys;
append_possible_keys(&qpt->possible_keys_str, table, tab->keys);
/* Build "key", "key_len", and "ref" */
......@@ -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)
{
qpt->push_extra(ET_USING_MRR);
explain_append_mrr_info((QUICK_RANGE_SELECT*)(tab->select->quick),
&qpt->mrr_type);
if (qpt->mrr_type.length() > 0)
qpt->push_extra(ET_USING_MRR);
}
if (need_tmp_table)
......@@ -23463,6 +23480,23 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order,
}
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);
}
......
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