17 #include "opt_explain_json.h" 
   24 static const char *json_extra_tags[ET_total]=
 
   27   "using_temporary_table",              
 
   31   "range_checked_for_each_record",      
 
   37   "full_scan_on_NULL_key",              
 
   42   "using_index_for_group_by",           
 
   53   "const_row_not_found",                
 
   54   "unique_row_not_found",               
 
   55   "impossible_on_condition",            
 
   61 static const char K_ACCESS_TYPE[]=                  
"access_type";
 
   62 static const char K_ATTACHED_CONDITION[]=           
"attached_condition";
 
   63 static const char K_ATTACHED_SUBQUERIES[]=          
"attached_subqueries";
 
   64 static const char K_BUFFER_RESULT[]=                
"buffer_result";
 
   65 static const char K_CACHEABLE[]=                    
"cacheable";
 
   66 static const char K_DEPENDENT[]=                    
"dependent";
 
   67 static const char K_DUPLICATES_REMOVAL[]=           
"duplicates_removal";
 
   68 static const char K_FILTERED[]=                     
"filtered";
 
   69 static const char K_GROUPING_OPERATION[]=           
"grouping_operation";
 
   70 static const char K_GROUP_BY_SUBQUERIES[]=          
"group_by_subqueries";
 
   71 static const char K_HAVING_SUBQUERIES[]=            
"having_subqueries";
 
   72 static const char K_KEY[]=                          
"key";
 
   73 static const char K_KEY_LENGTH[]=                   
"key_length";
 
   74 static const char K_MATERIALIZED_FROM_SUBQUERY[]=   
"materialized_from_subquery";
 
   75 static const char K_MESSAGE[]=                      
"message";
 
   76 static const char K_NESTED_LOOP[]=                  
"nested_loop";
 
   77 static const char K_OPTIMIZATION_TIME_SUBQUERIES[]= 
"optimized_away_subqueries";
 
   78 static const char K_ORDERING_OPERATION[]=           
"ordering_operation";
 
   79 static const char K_ORDER_BY_SUBQUERIES[]=          
"order_by_subqueries";
 
   80 static const char K_PARTITIONS[]=                   
"partitions";
 
   81 static const char K_POSSIBLE_KEYS[]=                
"possible_keys";
 
   82 static const char K_QUERY_BLOCK[]=                  
"query_block";
 
   83 static const char K_QUERY_SPECIFICATIONS[]=         
"query_specifications";
 
   84 static const char K_REF[]=                          
"ref";
 
   85 static const char K_ROWS[]=                         
"rows";
 
   86 static const char K_SELECT_ID[]=                    
"select_id";
 
   87 static const char K_SELECT_LIST_SUBQUERIES[]=       
"select_list_subqueries";
 
   88 static const char K_TABLE[]=                        
"table";
 
   89 static const char K_TABLE_NAME[]=                   
"table_name";
 
   90 static const char K_UNION_RESULT[]=                 
"union_result";
 
   91 static const char K_UPDATE_VALUE_SUBQUERIES[]=      
"update_value_subqueries";
 
   92 static const char K_USED_KEY_PARTS[]=               
"used_key_parts";
 
   93 static const char K_USING_FILESORT[]=               
"using_filesort";
 
   94 static const char K_USING_TMP_TABLE[]=              
"using_temporary_table";
 
  100 namespace opt_explain_json_namespace
 
  106 class union_result_ctx;
 
  111 enum subquery_list_enum
 
  129 static const char *list_names[SQ_total]=
 
  131   K_SELECT_LIST_SUBQUERIES,
 
  132   K_UPDATE_VALUE_SUBQUERIES,
 
  134   K_OPTIMIZATION_TIME_SUBQUERIES,
 
  136   K_ORDER_BY_SUBQUERIES,
 
  137   K_GROUP_BY_SUBQUERIES,
 
  153   context(Explain_context_enum type_arg, 
const char *name_arg,
 
  175     return format_body(json, &obj);
 
  178   bool is_query_block()
 const { 
return name == K_QUERY_BLOCK; }
 
  202   virtual size_t id(
bool hide= 
false)= 0;
 
  204   virtual bool cacheable() { DBUG_ASSERT(0); 
return true; }
 
  205   virtual bool dependent() { DBUG_ASSERT(0); 
return false; }
 
  207   virtual class qep_row *
entry() { DBUG_ASSERT(0); 
return NULL; }
 
  239   { DBUG_ASSERT(0); 
return true; }
 
  294                                   SELECT_LEX_UNIT *subquery)
 
  329                const char *name_arg, 
context *parent_arg)
 
  330   : 
context(type_arg, name_arg, parent_arg),
 
  343   virtual bool cacheable()
 
  345     return is_materialized_from_subquery ? is_cacheable : subquery->cacheable();
 
  347   virtual bool dependent()
 
  349     return is_materialized_from_subquery ? is_dependent : subquery->dependent();
 
  363       return format_body(json, &anonymous_wrapper);
 
  370     if (
type == CTX_DERIVED)
 
  372       obj->add(K_USING_TMP_TABLE, 
true);
 
  373       obj->add(K_DEPENDENT, dependent());
 
  374       obj->add(K_CACHEABLE, cacheable());
 
  375       return subquery->
format(json);
 
  377     else if (using_temporary)
 
  379       if (!is_materialized_from_subquery)
 
  381         obj->add(K_USING_TMP_TABLE, 
true);
 
  382         obj->add(K_DEPENDENT, dependent());
 
  383         obj->add(K_CACHEABLE, cacheable());
 
  394           tmp_table.add_utf8(K_KEY, 
col_key.str);
 
  398           tmp_table.add(K_ROWS, 
col_rows.value);
 
  400         if (is_materialized_from_subquery)
 
  403           obj->add(K_USING_TMP_TABLE, 
true);
 
  404           obj->add(K_DEPENDENT, dependent());
 
  405           obj->add(K_CACHEABLE, cacheable());
 
  406           return format_query_block(json);
 
  409       return format_query_block(json);
 
  413       obj->add(K_DEPENDENT, dependent());
 
  414       obj->add(K_CACHEABLE, cacheable());
 
  415       return subquery->
format(json);
 
  421     if (subquery->is_query_block())
 
  422       return subquery->
format(json);
 
  425     return subquery->
format(json);
 
  432     DBUG_ASSERT(subquery == NULL);
 
  433     DBUG_ASSERT(child->
type == CTX_JOIN || child->
type == CTX_UNION);
 
  437   virtual size_t id(
bool hide) { 
return subquery->
id(hide); }
 
  455   if (!subqueries.is_empty())
 
  480   unit_ctx(Explain_context_enum type_arg, 
const char *name_arg,
 
  482   : 
context(type_arg, name_arg, parent_arg)
 
  493     for (
size_t i= 0; 
i < SQ_toplevel; 
i++)
 
  495       if (!subquery_lists[
i].is_empty())
 
  503     for (
size_t i= 0; 
i < SQ_toplevel; 
i++)
 
  505       if (format_list(json, subquery_lists[
i], list_names[i]))
 
  514     DBUG_ASSERT(subquery_type < SQ_toplevel);
 
  515     return subquery_lists[subquery_type].push_back(ctx);
 
  527                  const char *name_arg, 
context *parent_arg)
 
  528   : 
context(type_arg, name_arg, parent_arg), is_hidden_id(
false)
 
  537   virtual size_t id(
bool hide)
 
  542   virtual bool cacheable() { 
return is_cacheable; }
 
  543   virtual bool dependent() { 
return is_dependent; }
 
  550   if (!strings.is_empty())
 
  566     obj->add(
"update", 
true);
 
  569     obj->add(
"delete", 
true);
 
  571   if (!
col_id.is_empty() && !is_hidden_id)
 
  572     obj->add(K_SELECT_ID, 
col_id.value);
 
  585     obj->add_utf8(K_KEY, 
col_key.str);
 
  593   add_string_array(json, K_REF, 
col_ref);
 
  607       DBUG_ASSERT(json_extra_tags[e->
tag] != NULL);
 
  609         obj->add_utf8(json_extra_tags[e->
tag], e->
data);
 
  611         obj->add(json_extra_tags[e->
tag], 
true);
 
  643   : 
context(CTX_UNION_RESULT, K_UNION_RESULT, parent_arg),
 
  645     unit_ctx(CTX_UNION_RESULT, K_UNION_RESULT, parent_arg)
 
  650   virtual bool cacheable()     { 
return table_base_ctx::cacheable(); }
 
  651   virtual bool dependent()     { 
return table_base_ctx::dependent(); }
 
  652   virtual qep_row *
entry()     { 
return table_base_ctx::entry(); }
 
  656   void push_down_query_specs(
List<context> *specs) { query_specs= specs; } 
 
  661     switch (subquery_type) {
 
  663       return order_by_subqueries.push_back(ctx);
 
  665       return homeless_subqueries.push_back(ctx);
 
  667       DBUG_ASSERT(!
"Unknown query type!");
 
  674     if (order_by_subqueries.is_empty() && homeless_subqueries.is_empty())
 
  679     order_by.add(K_USING_FILESORT, !order_by_subqueries.is_empty());
 
  684     if (!order_by_subqueries.is_empty() && 
 
  685         format_list(json, order_by_subqueries, K_ORDER_BY_SUBQUERIES))
 
  688     if (!homeless_subqueries.is_empty() &&
 
  689         format_list(json, homeless_subqueries, K_OPTIMIZATION_TIME_SUBQUERIES))
 
  697     obj->add(K_USING_TMP_TABLE, 
true);
 
  729                                  const char *name_arg, 
context *parent_arg)
 
  730   : 
context(type_arg, name_arg, parent_arg),
 
  734   virtual size_t id(
bool hide)
 
  779   joinable_ctx(Explain_context_enum type_arg, 
const char *name_arg,
 
  781   : 
context(type_arg, name_arg, parent_arg)
 
  802   : 
context(CTX_MESSAGE, K_TABLE, parent_arg),
 
  810   virtual size_t id(
bool hide)
 
  812   virtual bool cacheable()     { 
return table_base_ctx::cacheable(); }
 
  813   virtual bool dependent()     { 
return table_base_ctx::dependent(); }
 
  814   virtual qep_row *
entry()     { 
return table_base_ctx::entry(); }
 
  833                                   SELECT_LEX_UNIT *subquery)
 
  856   : 
context(type_arg, K_TABLE, parent_arg),
 
  864   virtual size_t id(
bool hide)
 
  866   virtual bool cacheable()     { 
return table_base_ctx::cacheable(); }
 
  867   virtual bool dependent()     { 
return table_base_ctx::dependent(); }
 
  868   virtual qep_row *
entry()     { 
return table_base_ctx::entry(); }
 
  888     where_subquery_units.push_back(subquery);
 
  892                                   SELECT_LEX_UNIT *subquery)
 
  929   const bool using_tmptable; 
 
  930   const bool using_filesort; 
 
  936                   Explain_sort_clause clause)
 
  937   : 
context(type_arg, name_arg, parent_arg),
 
  940     using_tmptable(flags->
get(clause, ESP_USING_TMPTABLE)),
 
  941     using_filesort(flags->
get(clause, ESP_USING_FILESORT))
 
  951                                   SELECT_LEX_UNIT *subquery)
 
  961   virtual size_t id(
bool hide) { 
return join_tab->
id(hide); }
 
  962   virtual bool cacheable() { 
return join_tab->cacheable(); }
 
  963   virtual bool dependent() { 
return join_tab->dependent(); }
 
  969       obj->add(K_USING_TMP_TABLE, 
true);
 
  970     obj->add(K_USING_FILESORT, using_filesort);
 
  971     return join_tab->
format(json);
 
  985   const subquery_list_enum subquery_type; 
 
  990                                   const char *name_arg,
 
  992                                   subquery_list_enum subquery_type_arg,
 
  994                                   Explain_sort_clause clause)
 
  995   : 
context(type_arg, name_arg, parent_arg),
 
  997     subquery_type(subquery_type_arg)
 
 1003     if (subquery_type != subquery_type_arg)
 
 1006       return subqueries.push_back(ctx);
 
 1013             (format_list(json, subqueries, list_names[subquery_type])));
 
 1029   join_ctx(Explain_context_enum type_arg, 
const char *name_arg,
 
 1031   : 
context(type_arg, name_arg, parent_arg),
 
 1032     unit_ctx(type_arg, name_arg, parent_arg),
 
 1054   virtual bool add_subquery(subquery_list_enum subquery_type,
 
 1061   virtual size_t id(
bool hide);
 
 1062   virtual bool cacheable();
 
 1063   virtual bool dependent();
 
 1065                                   SELECT_LEX_UNIT *subquery);
 
 1107   const bool using_tmptable; 
 
 1108   const bool using_filesort; 
 
 1111   sort_ctx(Explain_context_enum type_arg, 
const char *name_arg,
 
 1114            Explain_sort_clause clause)
 
 1115   : 
context(type_arg, name_arg, parent_arg),
 
 1116     join_ctx(type_arg, name_arg, parent_arg),
 
 1117     using_tmptable(flags->
get(clause, ESP_USING_TMPTABLE)),
 
 1118     using_filesort(flags->
get(clause, ESP_USING_FILESORT))
 
 1124     DBUG_ASSERT(!sort || 
join_tabs.is_empty());
 
 1127       obj->add(K_USING_TMP_TABLE, 
true);
 
 1128     if (
type != CTX_BUFFER_RESULT)
 
 1129       obj->add(K_USING_FILESORT, using_filesort);
 
 1138   const subquery_list_enum subquery_type; 
 
 1144                            subquery_list_enum subquery_type_arg,
 
 1146                            Explain_sort_clause clause)
 
 1147   : 
context(type_arg, name_arg, parent_arg),
 
 1148     sort_ctx(type_arg, name_arg, parent_arg, flags, clause),
 
 1149     subquery_type(subquery_type_arg)
 
 1155     if (subquery_type_arg != subquery_type)
 
 1158       return subqueries.push_back(ctx);
 
 1166              format_list(json, subqueries, list_names[subquery_type]));
 
 1173   DBUG_ASSERT(subquery->
id() != 0);
 
 1194    if (subquery_type > SQ_toplevel)
 
 1204        case CTX_SIMPLE_ORDER_BY:
 
 1205        case CTX_SIMPLE_DISTINCT:
 
 1206        case CTX_SIMPLE_GROUP_BY:
 
 1209          DBUG_ASSERT(subquery_type == SQ_ORDER_BY || subquery_type == SQ_GROUP_BY);
 
 1228   DBUG_ASSERT(!sort || 
join_tabs.is_empty());
 
 1229   if (
type == CTX_JOIN)
 
 1230     obj->add(K_SELECT_ID, 
id(
true));
 
 1272 template<
typename T>
 
 1273 static size_t get_id(
List<T> &list, 
bool hide)
 
 1276     return list.head()->id();
 
 1289   return sort ? sort->
id(hide) : get_id(
join_tabs, hide);
 
 1293 bool join_ctx::cacheable()
 
 1295   return sort ? sort->cacheable() : 
join_tabs.head()->cacheable();
 
 1299 bool join_ctx::dependent()
 
 1301   return sort ? sort->dependent() : 
join_tabs.head()->dependent();
 
 1306                                   SELECT_LEX_UNIT *subquery)
 
 1309     return sort->join_ctx::add_where_subquery(ctx, subquery);
 
 1331   : 
context(CTX_MATERIALIZATION, K_TABLE, parent_arg),
 
 1332     joinable_ctx(CTX_MATERIALIZATION, K_TABLE, parent_arg),
 
 1333     join_ctx(CTX_MATERIALIZATION, K_TABLE, parent_arg),
 
 1338   virtual bool cacheable() { 
return join_ctx::cacheable(); }
 
 1339   virtual bool dependent() { 
return join_ctx::dependent(); }
 
 1342   virtual qep_row *
entry()     { 
return table_base_ctx::entry(); }
 
 1369       obj->add_utf8(K_KEY, 
col_key.str);
 
 1374     add_string_array(json, K_REF, 
col_ref);
 
 1392     obj->add(K_USING_TMP_TABLE, 
true);
 
 1407   : 
context(CTX_DUPLICATES_WEEDOUT, K_DUPLICATES_REMOVAL, parent_arg),
 
 1408     joinable_ctx(CTX_DUPLICATES_WEEDOUT, K_DUPLICATES_REMOVAL, parent_arg),
 
 1409     join_ctx(CTX_DUPLICATES_WEEDOUT, K_DUPLICATES_REMOVAL, parent_arg)
 
 1413   virtual bool cacheable() { 
return join_ctx::cacheable(); }
 
 1414   virtual bool dependent() { 
return join_ctx::dependent(); }
 
 1435     obj->add(K_USING_TMP_TABLE, 
true);
 
 1452   : 
context(CTX_UNION, K_QUERY_BLOCK, parent_arg),
 
 1453     unit_ctx(CTX_UNION, K_QUERY_BLOCK, parent_arg),
 
 1464   virtual size_t id(
bool hide) { 
return get_id(query_specs, hide); }
 
 1465   virtual bool cacheable() { 
return query_specs.head()->cacheable(); }
 
 1466   virtual bool dependent() { 
return query_specs.head()->dependent(); }
 
 1470     DBUG_ASSERT(union_result == NULL);
 
 1472     union_result->push_down_query_specs(&query_specs);
 
 1475   { 
return query_specs.push_back(ctx); }
 
 1483   return current_context->entry();
 
 1488                                         SELECT_LEX_UNIT *subquery,
 
 1491   using namespace opt_explain_json_namespace;
 
 1493   context *prev_context= current_context;
 
 1496     DBUG_ASSERT(current_context == NULL ||
 
 1498                 current_context->type == CTX_SELECT_LIST ||
 
 1499                 current_context->type == CTX_UPDATE_VALUE_LIST ||
 
 1500                 current_context->type == CTX_DERIVED ||
 
 1501                 current_context->type == CTX_OPTIMIZED_AWAY_SUBQUERY ||
 
 1502                 current_context->type == CTX_WHERE ||
 
 1503                 current_context->type == CTX_HAVING ||
 
 1504                 current_context->type == CTX_ORDER_BY_SQ ||
 
 1505                 current_context->type == CTX_GROUP_BY_SQ ||
 
 1506                 current_context->type == CTX_QUERY_SPEC);
 
 1507     if ((current_context=
 
 1508          new join_ctx(CTX_JOIN, K_QUERY_BLOCK, current_context)) == NULL)
 
 1513       DBUG_ASSERT(current_context->type == CTX_JOIN);
 
 1515                                                   K_ORDERING_OPERATION,
 
 1521       current_context->set_sort(ctx);
 
 1522       current_context= ctx;
 
 1527       DBUG_ASSERT(current_context->type == CTX_JOIN ||
 
 1528                   current_context->type == CTX_ORDER_BY ||
 
 1529                   current_context->type == CTX_DISTINCT);
 
 1531                                                   K_GROUPING_OPERATION,
 
 1537       current_context->set_sort(ctx);
 
 1538       current_context= ctx;
 
 1543       DBUG_ASSERT(current_context->type == CTX_JOIN ||
 
 1544                   current_context->type == CTX_ORDER_BY);
 
 1546                                   current_context, flags, ESC_DISTINCT);
 
 1549       current_context->set_sort(ctx);
 
 1550       current_context= ctx;
 
 1553   case CTX_BUFFER_RESULT:
 
 1555       DBUG_ASSERT(current_context->type == CTX_JOIN ||
 
 1556                   current_context->type == CTX_ORDER_BY ||
 
 1557                   current_context->type == CTX_DISTINCT ||
 
 1558                   current_context->type == CTX_GROUP_BY);
 
 1560                                   current_context, flags, ESC_BUFFER_RESULT);
 
 1563       current_context->set_sort(ctx);
 
 1564       current_context= ctx;
 
 1569       DBUG_ASSERT(current_context->type == CTX_JOIN ||
 
 1570                   current_context->type == CTX_MATERIALIZATION ||
 
 1571                   current_context->type == CTX_DUPLICATES_WEEDOUT ||
 
 1572                   current_context->type == CTX_GROUP_BY ||
 
 1573                   current_context->type == CTX_ORDER_BY ||
 
 1574                   current_context->type == CTX_DISTINCT ||
 
 1575                   current_context->type == CTX_BUFFER_RESULT ||
 
 1576                   current_context->type == CTX_SIMPLE_GROUP_BY ||
 
 1577                   current_context->type == CTX_SIMPLE_ORDER_BY ||
 
 1578                   current_context->type == CTX_SIMPLE_DISTINCT);
 
 1580       if (ctx == NULL || current_context->add_join_tab(ctx))
 
 1582       current_context= ctx;
 
 1585   case CTX_SIMPLE_ORDER_BY:
 
 1587       DBUG_ASSERT(current_context->type == CTX_JOIN ||
 
 1588                   current_context->type == CTX_MATERIALIZATION ||
 
 1589                   current_context->type == CTX_DUPLICATES_WEEDOUT ||
 
 1590                   current_context->type == CTX_GROUP_BY ||
 
 1591                   current_context->type == CTX_ORDER_BY ||
 
 1592                   current_context->type == CTX_BUFFER_RESULT ||
 
 1593                   current_context->type == CTX_DISTINCT);
 
 1596                                             K_ORDERING_OPERATION,
 
 1597                                             current_context, SQ_ORDER_BY, flags,
 
 1600       if (ctx == NULL || current_context->add_join_tab(ctx))
 
 1602       current_context= ctx;
 
 1605   case CTX_SIMPLE_GROUP_BY:
 
 1607       DBUG_ASSERT(current_context->type == CTX_JOIN ||
 
 1608                   current_context->type == CTX_MATERIALIZATION ||
 
 1609                   current_context->type == CTX_DUPLICATES_WEEDOUT ||
 
 1610                   current_context->type == CTX_GROUP_BY ||
 
 1611                   current_context->type == CTX_ORDER_BY ||
 
 1612                   current_context->type == CTX_DISTINCT ||
 
 1613                   current_context->type == CTX_BUFFER_RESULT ||
 
 1614                   current_context->type == CTX_SIMPLE_ORDER_BY ||
 
 1615                   current_context->type == CTX_SIMPLE_DISTINCT);
 
 1618                                             K_GROUPING_OPERATION,
 
 1619                                             current_context, SQ_GROUP_BY, flags,
 
 1621       if (ctx == NULL || current_context->add_join_tab(ctx))
 
 1623       current_context= ctx;
 
 1626   case CTX_SIMPLE_DISTINCT:
 
 1628       DBUG_ASSERT(current_context->type == CTX_JOIN ||
 
 1629                   current_context->type == CTX_MATERIALIZATION ||
 
 1630                   current_context->type == CTX_DUPLICATES_WEEDOUT ||
 
 1631                   current_context->type == CTX_GROUP_BY ||
 
 1632                   current_context->type == CTX_ORDER_BY ||
 
 1633                   current_context->type == CTX_DISTINCT ||
 
 1634                   current_context->type == CTX_BUFFER_RESULT ||
 
 1635                   current_context->type == CTX_SIMPLE_ORDER_BY);
 
 1638                             current_context, flags, ESC_DISTINCT);
 
 1639       if (ctx == NULL || current_context->add_join_tab(ctx))
 
 1641       current_context= ctx;
 
 1644   case CTX_MATERIALIZATION:
 
 1646       DBUG_ASSERT(current_context->type == CTX_JOIN ||
 
 1647                   current_context->type == CTX_GROUP_BY ||
 
 1648                   current_context->type == CTX_ORDER_BY ||
 
 1649                   current_context->type == CTX_DISTINCT ||
 
 1650                   current_context->type == CTX_BUFFER_RESULT ||
 
 1651                   current_context->type == CTX_DUPLICATES_WEEDOUT);
 
 1653       if (ctx == NULL || current_context->add_join_tab(ctx))
 
 1655       current_context= ctx;
 
 1658   case CTX_DUPLICATES_WEEDOUT:
 
 1660       DBUG_ASSERT(current_context->type == CTX_JOIN ||
 
 1661                   current_context->type == CTX_GROUP_BY ||
 
 1662                   current_context->type == CTX_ORDER_BY ||
 
 1663                   current_context->type == CTX_DISTINCT ||
 
 1664                   current_context->type == CTX_BUFFER_RESULT ||
 
 1665                   current_context->type == CTX_MATERIALIZATION);
 
 1668       if (ctx == NULL || current_context->add_join_tab(ctx))
 
 1670       current_context= ctx;
 
 1673   case CTX_SELECT_LIST:
 
 1678           current_context->add_subquery(SQ_SELECT_LIST, ctx))
 
 1680       current_context= ctx;
 
 1683   case CTX_UPDATE_VALUE_LIST:
 
 1688           current_context->add_subquery(SQ_UPDATE_VALUE, ctx))
 
 1690       current_context= ctx;
 
 1696                                         K_MATERIALIZED_FROM_SUBQUERY,
 
 1698       if (current_context == NULL)
 
 1702   case CTX_OPTIMIZED_AWAY_SUBQUERY:
 
 1706       if (ctx == NULL || current_context->add_subquery(SQ_HOMELESS, ctx))
 
 1708       current_context= ctx;
 
 1713       DBUG_ASSERT(subquery != NULL);
 
 1716           current_context->add_where_subquery(ctx, subquery))
 
 1718       current_context= ctx;
 
 1724       if (ctx == NULL || current_context->add_subquery(SQ_HAVING, ctx))
 
 1726       current_context= ctx;
 
 1729   case CTX_ORDER_BY_SQ:
 
 1733       if (ctx == NULL || current_context->add_subquery(SQ_ORDER_BY, ctx))
 
 1735       current_context= ctx;
 
 1738   case CTX_GROUP_BY_SQ:
 
 1742       if (ctx == NULL || current_context->add_subquery(SQ_GROUP_BY, ctx))
 
 1744       current_context= ctx;
 
 1748     DBUG_ASSERT(current_context == NULL ||
 
 1750                 current_context->type == CTX_SELECT_LIST ||
 
 1751                 current_context->type == CTX_UPDATE_VALUE_LIST ||
 
 1752                 current_context->type == CTX_DERIVED ||
 
 1753                 current_context->type == CTX_OPTIMIZED_AWAY_SUBQUERY ||
 
 1754                 current_context->type == CTX_WHERE ||
 
 1755                 current_context->type == CTX_HAVING ||
 
 1756                 current_context->type == CTX_ORDER_BY_SQ ||
 
 1757                 current_context->type == CTX_GROUP_BY_SQ ||
 
 1758                 current_context->type == CTX_QUERY_SPEC);
 
 1759     current_context= 
new union_ctx(current_context);
 
 1760     if (current_context == NULL)
 
 1763   case CTX_UNION_RESULT:
 
 1765       DBUG_ASSERT(current_context->type == CTX_UNION);
 
 1769       current_context->set_union_result(ctx);
 
 1770       current_context= ctx;
 
 1773   case CTX_QUERY_SPEC:
 
 1775       DBUG_ASSERT(current_context->type == CTX_UNION);
 
 1778       if (ctx == NULL || current_context->add_query_spec(ctx))
 
 1780       current_context= ctx;
 
 1788       DBUG_ASSERT(current_context->type == CTX_JOIN ||
 
 1789                   current_context->type == CTX_MATERIALIZATION ||
 
 1790                   current_context->type == CTX_DUPLICATES_WEEDOUT ||
 
 1791                   current_context->type == CTX_GROUP_BY ||
 
 1792                   current_context->type == CTX_ORDER_BY ||
 
 1793                   current_context->type == CTX_DISTINCT ||
 
 1794                   current_context->type == CTX_BUFFER_RESULT ||
 
 1795                   current_context->type == CTX_SIMPLE_GROUP_BY ||
 
 1796                   current_context->type == CTX_SIMPLE_ORDER_BY ||
 
 1797                   current_context->type == CTX_SIMPLE_DISTINCT);
 
 1799       if (ctx == NULL || current_context->add_join_tab(ctx))
 
 1801       current_context= ctx;
 
 1805     DBUG_ASSERT(!
"Unknown EXPLAIN context!");
 
 1810     prev_context->set_child(current_context);
 
 1818   DBUG_ASSERT(current_context->
type == ctx);
 
 1821   if (current_context->
parent == NULL)
 
 1824 #ifdef OPTIMIZER_TRACE 
 1826     const size_t max_size= ULONG_MAX;
 
 1827     if (json.start(
true,           
 
 1829                    current_thd->variables.end_markers_in_json, 
 
 1834                    Opt_trace_context::MISC))
 
 1840       if (current_context->
format(&json))
 
 1845     Opt_trace_iterator it(&json);
 
 1848       Opt_trace_info info;
 
 1849       it.get_value(&info);
 
 1851                             static_cast<uint>(info.trace_length),
 
 1852                             system_charset_info);
 
 1859     ret= (item == NULL ||
 
 1860           field_list.push_back(item) ||
 
 1861           output->send_data(field_list));
 
 1863   else if (ctx == CTX_DERIVED)
 
 1867       DBUG_ASSERT(!
"No derived table found!");
 
 1872   current_context= current_context->
parent;
 
 1885   if (item == NULL || field_list.push_back(item))
 
 1887   return result->send_result_set_metadata(field_list,
 
 1888                                           Protocol::SEND_NUM_ROWS |
 
 1889                                           Protocol::SEND_EOF);