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);