[Commits] 3d5f97f: Merge ../10.1-explain-json-r4 into 10.1

Sergei Petrunia psergey at askmonty.org
Wed Nov 26 23:51:54 EET 2014


revision-id: 3d5f97fd708e12201636179baee2c8bc0093c109
parent(s): 55e99b29339dae833448ded6d0ca3d31f673d02a 3c5ce8a0a32a74cd8e0ddc81bcfacf7c85f0d90a
committer: Sergei Petrunia
branch nick: 10.1-merge-explain-json
timestamp: 2014-11-27 00:51:54 +0300
message:

Merge ../10.1-explain-json-r4 into 10.1


 libmysqld/CMakeLists.txt         |    1 +
 mysql-test/r/explain_json.result |  178 ++++++++++++
 mysql-test/t/explain_json.test   |   42 +++
 sql/CMakeLists.txt               |    1 +
 sql/item.cc                      |    8 +-
 sql/lex.h                        |    1 +
 sql/my_json_writer.cc            |  310 +++++++++++++++++++++
 sql/my_json_writer.h             |  118 ++++++++
 sql/mysqld.h                     |    6 +-
 sql/opt_range.cc                 |    4 +-
 sql/sql_class.cc                 |   13 +-
 sql/sql_class.h                  |    2 +
 sql/sql_explain.cc               |  559 ++++++++++++++++++++++++++++++++------
 sql/sql_explain.h                |   79 ++++--
 sql/sql_lex.cc                   |    1 +
 sql/sql_lex.h                    |    1 +
 sql/sql_parse.cc                 |   34 ++-
 sql/sql_select.cc                |   78 +++---
 sql/sql_select.h                 |    9 +-
 sql/sql_yacc.yy                  |   39 ++-
 sql/table.h                      |    6 +
 21 files changed, 1335 insertions(+), 155 deletions(-)

diff --cc sql/sql_class.cc
index 90c550d,d41c7e5..a9eec4f
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@@ -2367,10 -2368,13 +2367,14 @@@ CHANGED_TABLE_LIST* THD::changed_table_
  }
  
  
 -int THD::send_explain_fields(select_result *result)
 +int THD::send_explain_fields(select_result *result, uint8 explain_flags, bool is_analyze)
  {
    List<Item> field_list;
-   make_explain_field_list(field_list, explain_flags, is_analyze);
+   if (lex->explain_json)
+     make_explain_json_field_list(field_list);
+   else
 -    make_explain_field_list(field_list);
++    make_explain_field_list(field_list, explain_flags, is_analyze);
++
    result->prepare(field_list, NULL);
    return (result->send_result_set_metadata(field_list,
                                             Protocol::SEND_NUM_ROWS | 
diff --cc sql/sql_class.h
index 7a34960,e153607..51fd1cb
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@@ -3083,10 -3071,9 +3083,12 @@@ public
    void add_changed_table(TABLE *table);
    void add_changed_table(const char *key, long key_length);
    CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length);
 -  int send_explain_fields(select_result *result);
 -  void make_explain_field_list(List<Item> &field_list);
 +  int send_explain_fields(select_result *result, uint8 explain_flags,
 +                          bool is_analyze);
 +  void make_explain_field_list(List<Item> &field_list, uint8 explain_flags,
 +                               bool is_analyze);
+   void make_explain_json_field_list(List<Item> &field_list);
++
    /**
      Clear the current error, if any.
      We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
diff --cc sql/sql_explain.cc
index 7bab96e,e8bc907..ecc406b
--- a/sql/sql_explain.cc
+++ b/sql/sql_explain.cc
@@@ -136,11 -136,16 +136,16 @@@ int Explain_query::send_explain(THD *th
    LEX *lex= thd->lex;
   
    if (!(result= new select_send()) || 
 -      thd->send_explain_fields(result))
 +      thd->send_explain_fields(result, lex->describe, lex->analyze_stmt))
      return 1;
  
-   int res;
-   if ((res= print_explain(result, lex->describe, lex->analyze_stmt)))
+   int res= 0;
+   if (thd->lex->explain_json)
+     print_explain_json(result, thd->lex->analyze_stmt);
+   else
+     res= print_explain(result, lex->describe, thd->lex->analyze_stmt);
+ 
+   if (res)
      result->abort_result_set();
    else
      result->send_eof();
@@@ -177,9 -182,43 +182,43 @@@ int Explain_query::print_explain(select
  }
  
  
+ void Explain_query::print_explain_json(select_result_sink *output, bool is_analyze)
+ {
+   Json_writer writer;
+   writer.start_object();
+ 
+   if (upd_del_plan)
+   {
+     //upd_del_plan->print_explain(this, output, explain_flags, is_analyze);
+     DBUG_ASSERT(0);
+   }
+   else if (insert_plan)
+   {
+     //insert_plan->print_explain(this, output, explain_flags, is_analyze);
+     DBUG_ASSERT(0);
+   }
+   else
+   {
+     /* Start printing from node with id=1 */
+     Explain_node *node= get_node(1);
+     if (!node)
+       return; /* No query plan */
+     node->print_explain_json(this, &writer, is_analyze);
+   }
+ 
+   writer.end_object();
+ 
+   const CHARSET_INFO *cs= system_charset_info;
+   List<Item> item_list;
+   String *buf= &writer.output;
+   item_list.push_back(new Item_string(buf->ptr(), buf->length(), cs));
+   output->send_data(item_list);
+ }
+ 
+ 
 -bool print_explain_query(LEX *lex, THD *thd, String *str)
 +bool print_explain_for_slow_log(LEX *lex, THD *thd, String *str)
  {
 -  return lex->explain->print_explain_str(thd, str, false);
 +  return lex->explain->print_explain_str(thd, str, /*is_analyze*/ true);
  }
  
  
@@@ -209,9 -249,56 +248,55 @@@ static void push_str(List<Item> *item_l
  
  static void push_string(List<Item> *item_list, String *str)
  {
 -  item_list->push_back(new Item_string(str->ptr(), str->length(),
 -                       system_charset_info));
 +  item_list->push_back(new Item_string_sys(str->ptr(), str->length()));
  }
  
+ static void push_string_list(List<Item> *item_list, String_list &lines, 
+                              String *buf)
+ {
+   List_iterator_fast<char> it(lines);
+   char *line;
+   bool first= true;
+   while ((line= it++))
+   {
+     if (first)
+       first= false;
+     else
+       buf->append(',');
+ 
+     buf->append(line);
+   }
+   push_string(item_list, buf);
+ }
+ 
+ 
+ uint Explain_union::make_union_table_name(char *buf)
+ {
+   uint childno= 0;
+   uint len= 6, lastop= 0;
+   memcpy(buf, STRING_WITH_LEN("<union"));
+ 
+   for (; childno < union_members.elements() && len + lastop + 5 < NAME_LEN;
+        childno++)
+   {
+     len+= lastop;
+     lastop= my_snprintf(buf + len, NAME_LEN - len,
+                         "%u,", union_members.at(childno));
+   }
+ 
+   if (childno < union_members.elements() || len + lastop >= NAME_LEN)
+   {
+     memcpy(buf + len, STRING_WITH_LEN("...>") + 1);
+     len+= 4;
+   }
+   else
+   {
+     len+= lastop;
+     buf[len - 1]= '>';  // change ',' to '>'
+   }
+   return len;
+ }
+ 
  
  int Explain_union::print_explain(Explain_query *query, 
                                   select_result_sink *output,
@@@ -241,31 -326,8 +327,8 @@@
    push_str(&item_list, fake_select_type);
  
    /* `table` column: something like "<union1,2>" */
-   {
-     uint childno= 0;
-     uint len= 6, lastop= 0;
-     memcpy(table_name_buffer, STRING_WITH_LEN("<union"));
- 
-     for (; childno < union_members.elements() && len + lastop + 5 < NAME_LEN;
-          childno++)
-     {
-       len+= lastop;
-       lastop= my_snprintf(table_name_buffer + len, NAME_LEN - len,
-                           "%u,", union_members.at(childno));
-     }
- 
-     if (childno < union_members.elements() || len + lastop >= NAME_LEN)
-     {
-       memcpy(table_name_buffer + len, STRING_WITH_LEN("...>") + 1);
-       len+= 4;
-     }
-     else
-     {
-       len+= lastop;
-       table_name_buffer[len - 1]= '>';  // change ',' to '>'
-     }
-     item_list.push_back(new Item_string_sys(table_name_buffer, len));
-   }
+   uint len= make_union_table_name(table_name_buffer);
 -  item_list.push_back(new Item_string(table_name_buffer, len, cs));
++  item_list.push_back(new Item_string_sys(table_name_buffer, len));
    
    /* `partitions` column */
    if (explain_flags & DESCRIBE_PARTITIONS)


More information about the commits mailing list