diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2012-05-16 19:20:00 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2012-05-16 19:20:00 +0400 |
commit | dfbd777fd83d236cc559750048f0cabee87d93a0 (patch) | |
tree | fb6cb698aa6f12c54e5a3d67835b9112ea07291d /sql/sql_lex.cc | |
parent | ddd3e261b253856720bd9dc2343a655ecc297e81 (diff) | |
parent | 404a1565bfe02e3ce06843f6c5bf243503a2fe99 (diff) | |
download | mariadb-git-dfbd777fd83d236cc559750048f0cabee87d93a0.tar.gz |
MWL#182: SHOW EXPLAIN: Merge 5.3->5.5
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r-- | sql/sql_lex.cc | 92 |
1 files changed, 89 insertions, 3 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 6fd6e53424f..4c19217a99d 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1872,6 +1872,7 @@ void st_select_lex::init_query() nest_level= 0; link_next= 0; is_prep_leaf_list_saved= FALSE; + have_merged_subqueries= FALSE; bzero((char*) expr_cache_may_be_used, sizeof(expr_cache_may_be_used)); m_non_agg_field_used= false; m_agg_func_used= false; @@ -3440,7 +3441,7 @@ bool st_select_lex::optimize_unflattened_subqueries() if (options & SELECT_DESCRIBE) { /* Optimize the subquery in the context of EXPLAIN. */ - sl->set_explain_type(); + sl->set_explain_type(FALSE); sl->options|= SELECT_DESCRIBE; inner_join->select_options|= SELECT_DESCRIBE; } @@ -3832,7 +3833,7 @@ void SELECT_LEX::update_used_tables() Set the EXPLAIN type for this subquery. */ -void st_select_lex::set_explain_type() +void st_select_lex::set_explain_type(bool on_the_fly) { bool is_primary= FALSE; if (next_select()) @@ -3854,6 +3855,9 @@ void st_select_lex::set_explain_type() } } + if (on_the_fly && !is_primary && have_merged_subqueries) + is_primary= TRUE; + SELECT_LEX *first= master_unit()->first_select(); /* drop UNCACHEABLE_EXPLAIN, because it is for internal usage only */ uint8 is_uncacheable= (uncacheable & ~UNCACHEABLE_EXPLAIN); @@ -3906,10 +3910,15 @@ void st_select_lex::set_explain_type() else { type= is_uncacheable ? "UNCACHEABLE UNION": "UNION"; + if (this == master_unit()->fake_select_lex) + type= "UNION RESULT"; + } } } - options|= SELECT_DESCRIBE; + + if (!on_the_fly) + options|= SELECT_DESCRIBE; } @@ -4056,6 +4065,83 @@ bool st_select_lex::is_merged_child_of(st_select_lex *ancestor) } +int print_explain_message_line(select_result_sink *result, + SELECT_LEX *select_lex, + bool on_the_fly, + uint8 options, + const char *message); + + +int st_select_lex::print_explain(select_result_sink *output) +{ + int res; + if (join && join->have_query_plan == JOIN::QEP_AVAILABLE) + { + res= join->print_explain(output, TRUE, + FALSE, // need_tmp_table, + FALSE, // bool need_order, + FALSE, // bool distinct, + NULL); //const char *message + if (res) + goto err; + + 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)) + { + unit->print_explain(output); + } + } + } + else + { + const char *msg; + if (!join) + DBUG_ASSERT(0); // psergey: TODO: can this happen or not? + if (join->have_query_plan == JOIN::QEP_NOT_PRESENT_YET) + msg= "Not yet optimized"; + else + { + DBUG_ASSERT(join->have_query_plan == JOIN::QEP_DELETED); + msg= "Query plan already deleted"; + } + res= print_explain_message_line(output, this, TRUE /* on_the_fly */, + 0, msg); + } +err: + return 0; +} + + +int st_select_lex_unit::print_explain(select_result_sink *output) +{ + int res= 0; + SELECT_LEX *first= first_select(); + + for (SELECT_LEX *sl= first; sl; sl= sl->next_select()) + { + if ((res= sl->print_explain(output))) + break; + } + + /* + Note: it could be that fake_select_lex->join == NULL still at this point + */ + if (fake_select_lex && !fake_select_lex->join) + { + res= print_fake_select_lex_join(output, TRUE /* on the fly */, + fake_select_lex, 0 /* flags */); + } + return res; +} + + /** A routine used by the parser to decide whether we are specifying a full partitioning or if only partitions to add or to split. |