From: Sergey Glukhov Date: March 3 2011 11:12am Subject: bzr commit into mysql-trunk branch (sergey.glukhov:3711) WL#5585 List-Archive: http://lists.mysql.com/commits/132366 Message-Id: <201103031103.p238prGP032544@rcsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6876494504023316211==" --===============6876494504023316211== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/gluh/MySQL/mysql-trunk-5585/ based on revid:serge.kozlov@stripped 3711 Sergey Glukhov 2011-03-03 WL#5585 Factor EXPLAIN handling out of JOIN::exec @ sql/sql_select.cc -Added new method JOIN::explain() -removed unnecessary code -Added new function join_prepare_result() which holds common code for JOIN::explain() and JOIN::exec(). @ sql/sql_select.h Added new method JOIN::explain() @ sql/sql_union.cc WL#5585 Factor EXPLAIN handling out of JOIN::exec modified: sql/sql_select.cc sql/sql_select.h sql/sql_union.cc === modified file 'sql/sql_select.cc' --- a/sql/sql_select.cc 2011-02-22 14:24:33 +0000 +++ b/sql/sql_select.cc 2011-03-03 11:12:52 +0000 @@ -2738,6 +2738,90 @@ JOIN::save_join_tab() } +/* + Common code for ::explain() and ::exec() +*/ + +static bool join_prepare_result(THD *thd, JOIN *join, List **columns_list) +{ + join->error= 0; + if (join->procedure) + { + join->procedure_fields_list= join->fields_list; + if (join->procedure->change_columns(join->procedure_fields_list) || + join->result->prepare(join->procedure_fields_list, join->unit)) + { + thd->limit_found_rows= thd->examined_row_count= 0; + return TRUE; + } + *columns_list= &join->procedure_fields_list; + } + (void) join->result->prepare2(); // Currently, this cannot fail. + + if ((join->select_lex->options & OPTION_SCHEMA_TABLE) && + get_schema_tables_result(join, PROCESSED_BY_JOIN_EXEC)) + return TRUE; + + return FALSE; +} + + +/** + Explain select. +*/ + +void +JOIN::explain() +{ + List *columns_list= &fields_list; + DBUG_ENTER("JOIN::explain"); + + thd_proc_info(thd, "executing"); + + if (join_prepare_result(thd, this, &columns_list)) + DBUG_VOID_RETURN; + + if ((!tables_list && (tables || !select_lex->with_sum_func)) || + zero_result_cause) + { // Only test of functions + select_describe(this, FALSE, FALSE, FALSE, + (zero_result_cause ? zero_result_cause : "No tables used")); + DBUG_VOID_RETURN; + } + + /* + Check if we managed to optimize ORDER BY away and don't use temporary + table to resolve ORDER BY: in that case, we only may need to do + filesort for GROUP BY. + */ + if (!order && !no_order && (!skip_sort_order || !need_tmp)) + { + /* + Reset 'order' to 'group_list' and reinit variables describing + 'order' + */ + order= group_list; + simple_order= simple_group; + skip_sort_order= 0; + } + if (order && + (order != group_list || !(select_options & SELECT_BIG_RESULT)) && + (const_tables == tables || + ((simple_order || skip_sort_order) && + test_if_skip_sort_order(&join_tab[const_tables], order, + m_select_limit, 0, + &join_tab[const_tables].table-> + keys_in_use_for_query)))) + order=0; + having= tmp_having; + select_describe(this, need_tmp, + order != 0 && !skip_sort_order, + select_distinct, + !tables ? "No tables used" : NullS); + DBUG_VOID_RETURN; +} + + /** Exec select. @@ -2755,67 +2839,53 @@ JOIN::exec() List *columns_list= &fields_list; int tmp_error; DBUG_ENTER("JOIN::exec"); + DBUG_ASSERT(!(select_options & SELECT_DESCRIBE)); const bool has_group_by= this->group; thd_proc_info(thd, "executing"); - error= 0; - if (procedure) - { - procedure_fields_list= fields_list; - if (procedure->change_columns(procedure_fields_list) || - result->prepare(procedure_fields_list, unit)) - { - thd->limit_found_rows= thd->examined_row_count= 0; - DBUG_VOID_RETURN; - } - columns_list= &procedure_fields_list; - } - (void) result->prepare2(); // Currently, this cannot fail. + + if (join_prepare_result(thd, this, &columns_list)) + DBUG_VOID_RETURN; if (!tables_list && (tables || !select_lex->with_sum_func)) { // Only test of functions - if (select_options & SELECT_DESCRIBE) - select_describe(this, FALSE, FALSE, FALSE, - (zero_result_cause?zero_result_cause:"No tables used")); - else + if (result->send_result_set_metadata(*columns_list, + Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) { - if (result->send_result_set_metadata(*columns_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - { - DBUG_VOID_RETURN; - } - /* - We have to test for 'conds' here as the WHERE may not be constant - even if we don't have any tables for prepared statements or if - conds uses something like 'rand()'. - If the HAVING clause is either impossible or always true, then - JOIN::having is set to NULL by optimize_cond. - In this case JOIN::exec must check for JOIN::having_value, in the - same way it checks for JOIN::cond_value. - */ - if (select_lex->cond_value != Item::COND_FALSE && - select_lex->having_value != Item::COND_FALSE && - (!conds || conds->val_int()) && - (!having || having->val_int())) - { - if (do_send_rows && - (procedure ? (procedure->send_row(procedure_fields_list) || - procedure->end_of_records()) : result->send_data(fields_list))) - error= 1; - else - { - error= (int) result->send_eof(); - send_records= ((select_options & OPTION_FOUND_ROWS) ? 1 : - thd->sent_row_count); - } - } + DBUG_VOID_RETURN; + } + /* + We have to test for 'conds' here as the WHERE may not be constant + even if we don't have any tables for prepared statements or if + conds uses something like 'rand()'. + If the HAVING clause is either impossible or always true, then + JOIN::having is set to NULL by optimize_cond. + In this case JOIN::exec must check for JOIN::having_value, in the + same way it checks for JOIN::cond_value. + */ + if (select_lex->cond_value != Item::COND_FALSE && + select_lex->having_value != Item::COND_FALSE && + (!conds || conds->val_int()) && + (!having || having->val_int())) + { + if (do_send_rows && + (procedure ? (procedure->send_row(procedure_fields_list) || + procedure->end_of_records()) : result->send_data(fields_list))) + error= 1; else { - error=(int) result->send_eof(); - send_records= 0; + error= (int) result->send_eof(); + send_records= ((select_options & OPTION_FOUND_ROWS) ? 1 : + thd->sent_row_count); } } + else + { + error=(int) result->send_eof(); + send_records= 0; + } + /* Single select (without union) always returns 0 or 1 row */ thd->limit_found_rows= send_records; thd->examined_row_count= 0; @@ -2840,44 +2910,6 @@ JOIN::exec() DBUG_VOID_RETURN; } - if ((this->select_lex->options & OPTION_SCHEMA_TABLE) && - get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC)) - DBUG_VOID_RETURN; - - if (select_options & SELECT_DESCRIBE) - { - /* - Check if we managed to optimize ORDER BY away and don't use temporary - table to resolve ORDER BY: in that case, we only may need to do - filesort for GROUP BY. - */ - if (!order && !no_order && (!skip_sort_order || !need_tmp)) - { - /* - Reset 'order' to 'group_list' and reinit variables describing - 'order' - */ - order= group_list; - simple_order= simple_group; - skip_sort_order= 0; - } - if (order && - (order != group_list || !(select_options & SELECT_BIG_RESULT)) && - (const_tables == tables || - ((simple_order || skip_sort_order) && - test_if_skip_sort_order(&join_tab[const_tables], order, - m_select_limit, 0, - &join_tab[const_tables].table-> - keys_in_use_for_query)))) - order=0; - having= tmp_having; - select_describe(this, need_tmp, - order != 0 && !skip_sort_order, - select_distinct, - !tables ? "No tables used" : NullS); - DBUG_VOID_RETURN; - } - JOIN *curr_join= this; List *curr_all_fields= &all_fields; List *curr_fields_list= &fields_list; @@ -3576,22 +3608,28 @@ mysql_select(THD *thd, Item ***rref_poin goto err; // 1 } - if (thd->lex->describe & DESCRIBE_EXTENDED) - { - join->conds_history= join->conds; - join->having_history= (join->having?join->having:join->tmp_having); - } - if (thd->is_error()) goto err; - join->exec(); - if (thd->lex->describe & DESCRIBE_EXTENDED) + if (select_options & SELECT_DESCRIBE) { - select_lex->where= join->conds_history; - select_lex->having= join->having_history; + if (thd->lex->describe & DESCRIBE_EXTENDED) + { + join->conds_history= join->conds; + join->having_history= (join->having?join->having:join->tmp_having); + } + + join->explain(); + + if (thd->lex->describe & DESCRIBE_EXTENDED) + { + select_lex->where= join->conds_history; + select_lex->having= join->having_history; + } } + else + join->exec(); err: if (free_join) @@ -11903,12 +11941,6 @@ return_zero_rows(JOIN *join, select_resu { DBUG_ENTER("return_zero_rows"); - if (select_options & SELECT_DESCRIBE) - { - select_describe(join, FALSE, FALSE, FALSE, info); - DBUG_RETURN(0); - } - join->join_free(); if (send_row) === modified file 'sql/sql_select.h' --- a/sql/sql_select.h 2011-02-08 15:49:51 +0000 +++ b/sql/sql_select.h 2011-03-03 11:12:52 +0000 @@ -1920,6 +1920,7 @@ public: int optimize(); int reinit(); void exec(); + void explain(); int destroy(); void restore_tmp(); bool alloc_func_list(); === modified file 'sql/sql_union.cc' --- a/sql/sql_union.cc 2010-11-11 09:40:06 +0000 +++ b/sql/sql_union.cc 2011-03-03 11:12:52 +0000 @@ -525,7 +525,10 @@ bool st_select_lex_unit::exec() if (!saved_error) { records_at_start= table->file->stats.records; - sl->join->exec(); + if (sl->join->select_options & SELECT_DESCRIBE) + sl->join->explain(); + else + sl->join->exec(); if (sl == union_distinct) { if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL)) --===============6876494504023316211== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/sergey.glukhov@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: sergey.glukhov@stripped\ # ef1tdyn1ijtwfwu1 # target_branch: file:///home/gluh/MySQL/mysql-trunk-5585/ # testament_sha1: a5aa60d1d0f9649a318bb2579568792bf86643ed # timestamp: 2011-03-03 14:12:57 +0300 # base_revision_id: serge.kozlov@stripped\ # wyfcwdwjo611n3we # # Begin bundle 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 WA== --===============6876494504023316211==--