#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<Item> **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<Item> *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<Item> *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<Item> *curr_all_fields= &all_fields;
List<Item> *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))
Attachment: [text/bzr-bundle] bzr/sergey.glukhov@oracle.com-20110303111252-ef1tdyn1ijtwfwu1.bundle
| Thread |
|---|
| • bzr commit into mysql-trunk branch (sergey.glukhov:3711) WL#5585 | Sergey Glukhov | 3 Mar |