List:Commits« Previous MessageNext Message »
From:Sergey Glukhov Date:March 3 2011 11:12am
Subject:bzr commit into mysql-trunk branch (sergey.glukhov:3711) WL#5585
View as plain text  
#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#5585Sergey Glukhov3 Mar