in sql/opt_explain_json.cc [1652:2033]
bool Explain_format_JSON::begin_context(enum_parsing_context ctx_arg,
Query_expression *subquery,
const Explain_format_flags *flags) {
using namespace opt_explain_json_namespace;
context *prev_context = current_context;
switch (ctx_arg) {
case CTX_JOIN:
assert(current_context == nullptr || current_context->type == CTX_UNION ||
current_context->type == CTX_INTERSECT ||
current_context->type == CTX_EXCEPT ||
current_context->type == CTX_UNARY ||
// subqueries:
current_context->type == CTX_SELECT_LIST ||
current_context->type == CTX_UPDATE_VALUE ||
current_context->type == CTX_INSERT_VALUES ||
current_context->type == CTX_INSERT_UPDATE ||
current_context->type == CTX_DERIVED ||
current_context->type == CTX_OPTIMIZED_AWAY_SUBQUERY ||
current_context->type == CTX_WHERE ||
current_context->type == CTX_HAVING ||
current_context->type == CTX_QUALIFY ||
current_context->type == CTX_ORDER_BY_SQ ||
current_context->type == CTX_GROUP_BY_SQ ||
current_context->type == CTX_QUERY_SPEC);
if ((current_context = new (*THR_MALLOC)
join_ctx(CTX_JOIN, K_QUERY_BLOCK, current_context)) == nullptr)
return true;
break;
case CTX_ORDER_BY: {
assert(current_context->type == CTX_JOIN);
sort_ctx *ctx = new (*THR_MALLOC) sort_with_subqueries_ctx(
CTX_ORDER_BY, K_ORDERING_OPERATION, current_context, SQ_ORDER_BY,
flags, ESC_ORDER_BY);
if (ctx == nullptr) return true;
current_context->set_sort(ctx);
current_context = ctx;
break;
}
case CTX_GROUP_BY: {
assert(current_context->type == CTX_JOIN ||
current_context->type == CTX_ORDER_BY ||
current_context->type == CTX_DISTINCT ||
current_context->type == CTX_WINDOW);
sort_ctx *ctx = new (*THR_MALLOC) sort_with_subqueries_ctx(
CTX_GROUP_BY, K_GROUPING_OPERATION, current_context, SQ_GROUP_BY,
flags, ESC_GROUP_BY);
if (ctx == nullptr) return true;
current_context->set_sort(ctx);
current_context = ctx;
break;
}
case CTX_DISTINCT: {
assert(current_context->type == CTX_JOIN ||
current_context->type == CTX_ORDER_BY);
sort_ctx *ctx =
new (*THR_MALLOC) sort_ctx(CTX_DISTINCT, K_DUPLICATES_REMOVAL,
current_context, flags, ESC_DISTINCT);
if (ctx == nullptr) return true;
current_context->set_sort(ctx);
current_context = ctx;
break;
}
case CTX_BUFFER_RESULT: {
assert(current_context->type == CTX_JOIN ||
current_context->type == CTX_ORDER_BY ||
current_context->type == CTX_DISTINCT ||
current_context->type == CTX_WINDOW ||
current_context->type == CTX_GROUP_BY);
sort_ctx *ctx =
new (*THR_MALLOC) sort_ctx(CTX_BUFFER_RESULT, K_BUFFER_RESULT,
current_context, flags, ESC_BUFFER_RESULT);
if (ctx == nullptr) return true;
current_context->set_sort(ctx);
current_context = ctx;
break;
}
case CTX_QEP_TAB: {
assert(current_context->type == CTX_JOIN ||
current_context->type == CTX_MATERIALIZATION ||
current_context->type == CTX_DUPLICATES_WEEDOUT ||
current_context->type == CTX_GROUP_BY ||
current_context->type == CTX_ORDER_BY ||
current_context->type == CTX_DISTINCT ||
current_context->type == CTX_WINDOW ||
current_context->type == CTX_BUFFER_RESULT ||
current_context->type == CTX_SIMPLE_GROUP_BY ||
current_context->type == CTX_SIMPLE_ORDER_BY ||
current_context->type == CTX_SIMPLE_DISTINCT);
join_tab_ctx *ctx =
new (*THR_MALLOC) join_tab_ctx(CTX_QEP_TAB, current_context);
if (ctx == nullptr || current_context->add_join_tab(ctx)) return true;
current_context = ctx;
break;
}
case CTX_SIMPLE_ORDER_BY: {
assert(current_context->type == CTX_JOIN ||
current_context->type == CTX_MATERIALIZATION ||
current_context->type == CTX_DUPLICATES_WEEDOUT ||
current_context->type == CTX_GROUP_BY ||
current_context->type == CTX_ORDER_BY ||
current_context->type == CTX_BUFFER_RESULT ||
current_context->type == CTX_WINDOW ||
current_context->type == CTX_DISTINCT);
simple_sort_ctx *ctx = new (*THR_MALLOC) simple_sort_with_subqueries_ctx(
CTX_SIMPLE_ORDER_BY, K_ORDERING_OPERATION, current_context,
SQ_ORDER_BY, flags, ESC_ORDER_BY);
if (ctx == nullptr || current_context->add_join_tab(ctx)) return true;
current_context = ctx;
break;
}
case CTX_SIMPLE_GROUP_BY: {
assert(current_context->type == CTX_JOIN ||
current_context->type == CTX_MATERIALIZATION ||
current_context->type == CTX_DUPLICATES_WEEDOUT ||
current_context->type == CTX_GROUP_BY ||
current_context->type == CTX_ORDER_BY ||
current_context->type == CTX_DISTINCT ||
current_context->type == CTX_WINDOW ||
current_context->type == CTX_BUFFER_RESULT ||
current_context->type == CTX_SIMPLE_ORDER_BY ||
current_context->type == CTX_SIMPLE_DISTINCT);
simple_sort_ctx *ctx = new (*THR_MALLOC) simple_sort_with_subqueries_ctx(
CTX_SIMPLE_GROUP_BY, K_GROUPING_OPERATION, current_context,
SQ_GROUP_BY, flags, ESC_GROUP_BY);
if (ctx == nullptr || current_context->add_join_tab(ctx)) return true;
current_context = ctx;
break;
}
case CTX_SIMPLE_DISTINCT: {
assert(current_context->type == CTX_JOIN ||
current_context->type == CTX_MATERIALIZATION ||
current_context->type == CTX_DUPLICATES_WEEDOUT ||
current_context->type == CTX_GROUP_BY ||
current_context->type == CTX_ORDER_BY ||
current_context->type == CTX_DISTINCT ||
current_context->type == CTX_WINDOW ||
current_context->type == CTX_BUFFER_RESULT ||
current_context->type == CTX_SIMPLE_ORDER_BY);
simple_sort_ctx *ctx = new (*THR_MALLOC)
simple_sort_ctx(CTX_SIMPLE_DISTINCT, K_DUPLICATES_REMOVAL,
current_context, flags, ESC_DISTINCT);
if (ctx == nullptr || current_context->add_join_tab(ctx)) return true;
current_context = ctx;
break;
}
case CTX_MATERIALIZATION: {
assert(current_context->type == CTX_JOIN ||
current_context->type == CTX_GROUP_BY ||
current_context->type == CTX_ORDER_BY ||
current_context->type == CTX_DISTINCT ||
current_context->type == CTX_WINDOW ||
current_context->type == CTX_BUFFER_RESULT ||
current_context->type == CTX_DUPLICATES_WEEDOUT);
materialize_ctx *ctx = new (*THR_MALLOC) materialize_ctx(current_context);
if (ctx == nullptr || current_context->add_join_tab(ctx)) return true;
current_context = ctx;
break;
}
case CTX_DUPLICATES_WEEDOUT: {
assert(current_context->type == CTX_JOIN ||
current_context->type == CTX_GROUP_BY ||
current_context->type == CTX_ORDER_BY ||
current_context->type == CTX_DISTINCT ||
current_context->type == CTX_WINDOW ||
current_context->type == CTX_BUFFER_RESULT ||
current_context->type == CTX_MATERIALIZATION);
duplication_weedout_ctx *ctx =
new (*THR_MALLOC) duplication_weedout_ctx(current_context);
if (ctx == nullptr || current_context->add_join_tab(ctx)) return true;
current_context = ctx;
break;
}
case CTX_SELECT_LIST: {
subquery_ctx *ctx = new (*THR_MALLOC)
subquery_ctx(CTX_SELECT_LIST, nullptr, current_context);
if (ctx == nullptr || current_context->add_subquery(SQ_SELECT_LIST, ctx))
return true;
current_context = ctx;
break;
}
case CTX_UPDATE_VALUE: {
subquery_ctx *ctx = new (*THR_MALLOC)
subquery_ctx(CTX_UPDATE_VALUE, nullptr, current_context);
if (ctx == nullptr || current_context->add_subquery(SQ_UPDATE_VALUE, ctx))
return true;
current_context = ctx;
break;
}
case CTX_INSERT_VALUES: {
subquery_ctx *ctx = new (*THR_MALLOC)
subquery_ctx(CTX_INSERT_VALUES, nullptr, current_context);
if (ctx == nullptr ||
current_context->add_subquery(SQ_INSERT_VALUES, ctx))
return true;
current_context = ctx;
break;
}
case CTX_INSERT_UPDATE: {
subquery_ctx *ctx = new (*THR_MALLOC)
subquery_ctx(CTX_INSERT_UPDATE, nullptr, current_context);
if (ctx == nullptr ||
current_context->add_subquery(SQ_INSERT_UPDATE, ctx))
return true;
current_context = ctx;
break;
}
case CTX_DERIVED: {
current_context = new (*THR_MALLOC) subquery_ctx(
CTX_DERIVED, K_MATERIALIZED_FROM_SUBQUERY, current_context);
if (current_context == nullptr) return true;
break;
}
case CTX_OPTIMIZED_AWAY_SUBQUERY: {
subquery_ctx *ctx = new (*THR_MALLOC)
subquery_ctx(CTX_OPTIMIZED_AWAY_SUBQUERY, nullptr, current_context);
if (ctx == nullptr ||
current_context->add_subquery(SQ_OPTIMIZED_AWAY, ctx))
return true;
current_context = ctx;
break;
}
case CTX_WHERE: {
assert(subquery != nullptr);
subquery_ctx *ctx =
new (*THR_MALLOC) subquery_ctx(CTX_WHERE, nullptr, current_context);
if (ctx == nullptr || current_context->add_where_subquery(ctx, subquery))
return true;
current_context = ctx;
break;
}
case CTX_HAVING: {
subquery_ctx *ctx =
new (*THR_MALLOC) subquery_ctx(CTX_HAVING, nullptr, current_context);
if (ctx == nullptr || current_context->add_subquery(SQ_HAVING, ctx))
return true;
current_context = ctx;
break;
}
case CTX_ORDER_BY_SQ: {
subquery_ctx *ctx = new (*THR_MALLOC)
subquery_ctx(CTX_ORDER_BY_SQ, nullptr, current_context);
if (ctx == nullptr || current_context->add_subquery(SQ_ORDER_BY, ctx))
return true;
current_context = ctx;
break;
}
case CTX_GROUP_BY_SQ: {
subquery_ctx *ctx = new (*THR_MALLOC)
subquery_ctx(CTX_GROUP_BY_SQ, nullptr, current_context);
if (ctx == nullptr || current_context->add_subquery(SQ_GROUP_BY, ctx))
return true;
current_context = ctx;
break;
}
case CTX_UNION: {
assert(current_context == nullptr || current_context->type == CTX_UNION ||
current_context->type == CTX_INTERSECT ||
current_context->type == CTX_EXCEPT ||
current_context->type == CTX_UNARY ||
// subqueries:
current_context->type == CTX_SELECT_LIST ||
current_context->type == CTX_UPDATE_VALUE ||
current_context->type == CTX_INSERT_VALUES ||
current_context->type == CTX_DERIVED ||
current_context->type == CTX_OPTIMIZED_AWAY_SUBQUERY ||
current_context->type == CTX_WHERE ||
current_context->type == CTX_HAVING ||
current_context->type == CTX_QUALIFY ||
current_context->type == CTX_ORDER_BY_SQ ||
current_context->type == CTX_GROUP_BY_SQ ||
current_context->type == CTX_QUERY_SPEC);
setop_ctx *ctx = new (*THR_MALLOC)
setop_ctx(current_context, CTX_UNION, K_QUERY_BLOCK);
if (ctx == nullptr) return true;
if (current_context != nullptr) current_context->add_query_spec(ctx);
current_context = ctx;
break;
}
case CTX_INTERSECT: {
setop_ctx *ctx = new (*THR_MALLOC)
setop_ctx(current_context, CTX_INTERSECT, K_QUERY_BLOCK);
if (ctx == nullptr) return true;
if (current_context != nullptr) current_context->add_query_spec(ctx);
current_context = ctx;
break;
}
case CTX_EXCEPT: {
setop_ctx *ctx = new (*THR_MALLOC)
setop_ctx(current_context, CTX_EXCEPT, K_QUERY_BLOCK);
if (ctx == nullptr) return true;
if (current_context != nullptr) current_context->add_query_spec(ctx);
current_context = ctx;
break;
}
case CTX_UNARY: {
setop_ctx *ctx = new (*THR_MALLOC)
setop_ctx(current_context, CTX_UNARY, K_QUERY_BLOCK);
if (ctx == nullptr) return true;
if (current_context != nullptr) current_context->add_query_spec(ctx);
current_context = ctx;
break;
}
case CTX_UNION_RESULT: {
setop_result_ctx *ctx = new (*THR_MALLOC)
setop_result_ctx(current_context, CTX_UNION_RESULT, K_UNION_RESULT);
if (ctx == nullptr) return true;
current_context->set_setop_result(ctx);
current_context = ctx;
break;
}
case CTX_INTERSECT_RESULT: {
setop_result_ctx *ctx = new (*THR_MALLOC) setop_result_ctx(
current_context, CTX_INTERSECT_RESULT, K_INTERSECT_RESULT);
if (ctx == nullptr) return true;
current_context->set_setop_result(ctx);
current_context = ctx;
break;
}
case CTX_EXCEPT_RESULT: {
setop_result_ctx *ctx = new (*THR_MALLOC)
setop_result_ctx(current_context, CTX_EXCEPT_RESULT, K_EXCEPT_RESULT);
if (ctx == nullptr) return true;
current_context->set_setop_result(ctx);
current_context = ctx;
break;
}
case CTX_UNARY_RESULT: {
setop_result_ctx *ctx = new (*THR_MALLOC)
setop_result_ctx(current_context, CTX_UNARY_RESULT, K_UNARY_RESULT);
if (ctx == nullptr) return true;
current_context->set_setop_result(ctx);
current_context = ctx;
break;
}
case CTX_QUERY_SPEC: {
subquery_ctx *ctx = new (*THR_MALLOC)
subquery_ctx(CTX_QUERY_SPEC, nullptr, current_context);
if (ctx == nullptr || current_context->add_query_spec(ctx)) return true;
current_context = ctx;
break;
}
case CTX_MESSAGE: {
/*
Like CTX_QEP_TAB:
*/
assert(current_context->type == CTX_JOIN ||
current_context->type == CTX_MATERIALIZATION ||
current_context->type == CTX_DUPLICATES_WEEDOUT ||
current_context->type == CTX_GROUP_BY ||
current_context->type == CTX_ORDER_BY ||
current_context->type == CTX_DISTINCT ||
current_context->type == CTX_WINDOW ||
current_context->type == CTX_BUFFER_RESULT ||
current_context->type == CTX_SIMPLE_GROUP_BY ||
current_context->type == CTX_SIMPLE_ORDER_BY ||
current_context->type == CTX_SIMPLE_DISTINCT ||
current_context->type == CTX_UNION_RESULT ||
current_context->type == CTX_INTERSECT_RESULT ||
current_context->type == CTX_EXCEPT_RESULT);
joinable_ctx *ctx = new (*THR_MALLOC) message_ctx(current_context);
if (ctx == nullptr || current_context->add_join_tab(ctx)) return true;
current_context = ctx;
break;
}
case CTX_WINDOW: {
window_ctx *ctx = new (*THR_MALLOC) window_ctx(current_context);
if (ctx == nullptr) return true;
current_context->set_window(ctx);
current_context = ctx;
break;
}
default:
assert(!"Unknown EXPLAIN context!");
return true;
}
if (prev_context) prev_context->set_child(current_context);
return false;
}