bool Explain_format_JSON::begin_context()

in sql/opt_explain_json.cc [1835:2194]


bool Explain_format_JSON::begin_context(enum_parsing_context ctx,
                                        SELECT_LEX_UNIT *subquery,
                                        const Explain_format_flags *flags)
{
  using namespace opt_explain_json_namespace;

  context *prev_context= current_context;
  switch(ctx) {
  case CTX_JOIN:
    DBUG_ASSERT(current_context == NULL ||
                // subqueries:
                current_context->type == CTX_SELECT_LIST ||
                current_context->type == CTX_UPDATE_VALUE_LIST ||
                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_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)) == NULL)
      return true;
    break;
  case CTX_ORDER_BY:
    { 
      DBUG_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 == NULL)
        return true;
      current_context->set_sort(ctx);
      current_context= ctx;
      break;
    }
  case CTX_GROUP_BY:
    { 
      DBUG_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 == NULL)
        return true;
      current_context->set_sort(ctx);
      current_context= ctx;
      break;
    }
  case CTX_DISTINCT:
    { 
      DBUG_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 == NULL)
        return true;
      current_context->set_sort(ctx);
      current_context= ctx;
      break;
    }
  case CTX_BUFFER_RESULT:
    { 
      DBUG_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 == NULL)
        return true;
      current_context->set_sort(ctx);
      current_context= ctx;
      break;
    }
  case CTX_QEP_TAB:
    {
      DBUG_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 == NULL || current_context->add_join_tab(ctx))
        return true;
      current_context= ctx;
      break;
    }
  case CTX_SIMPLE_ORDER_BY:
    {
      DBUG_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 == NULL || current_context->add_join_tab(ctx))
        return true;
      current_context= ctx;
      break;
    }
  case CTX_SIMPLE_GROUP_BY:
    {
      DBUG_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 == NULL || current_context->add_join_tab(ctx))
        return true;
      current_context= ctx;
      break;
    }
  case CTX_SIMPLE_DISTINCT:
    {
      DBUG_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 == NULL || current_context->add_join_tab(ctx))
        return true;
      current_context= ctx;
      break;
    }
  case CTX_MATERIALIZATION:
    {
      DBUG_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 == NULL || current_context->add_join_tab(ctx))
        return true;
      current_context= ctx;
      break;
    }
  case CTX_DUPLICATES_WEEDOUT:
    {
      DBUG_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 == NULL || 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, NULL, current_context);
      if (ctx == NULL ||
          current_context->add_subquery(SQ_SELECT_LIST, ctx))
        return true;
      current_context= ctx;
      break;
    }
  case CTX_UPDATE_VALUE_LIST:
    {
      subquery_ctx *ctx= new (*THR_MALLOC) subquery_ctx(CTX_UPDATE_VALUE_LIST,
                                                        NULL, current_context);
      if (ctx == NULL ||
          current_context->add_subquery(SQ_UPDATE_VALUE, 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 == NULL)
        return true;
      break;
    }
  case CTX_OPTIMIZED_AWAY_SUBQUERY:
    {
      subquery_ctx *ctx=
        new (*THR_MALLOC) subquery_ctx(CTX_OPTIMIZED_AWAY_SUBQUERY, NULL,
                                       current_context);
      if (ctx == NULL ||
          current_context->add_subquery(SQ_OPTIMIZED_AWAY, ctx))
        return true;
      current_context= ctx;
      break;
    }
  case CTX_WHERE:
    {
      DBUG_ASSERT(subquery != NULL);
      subquery_ctx *ctx= new (*THR_MALLOC) subquery_ctx(CTX_WHERE, NULL,
                                                        current_context);
      if (ctx == NULL ||
          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, NULL,
                                                        current_context);
      if (ctx == NULL || 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, NULL,
                                       current_context);
      if (ctx == NULL || 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, NULL, current_context);
      if (ctx == NULL || current_context->add_subquery(SQ_GROUP_BY, ctx))
        return true;
      current_context= ctx;
      break;
    }
  case CTX_UNION:
    DBUG_ASSERT(current_context == NULL ||
                // subqueries:
                current_context->type == CTX_SELECT_LIST ||
                current_context->type == CTX_UPDATE_VALUE_LIST ||
                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_ORDER_BY_SQ ||
                current_context->type == CTX_GROUP_BY_SQ ||
                current_context->type == CTX_QUERY_SPEC);
    current_context= new (*THR_MALLOC) union_ctx(current_context);
    if (current_context == NULL)
      return true;
    break;
  case CTX_UNION_RESULT:
    {
      DBUG_ASSERT(current_context->type == CTX_UNION);
      union_result_ctx *ctx= new (*THR_MALLOC) union_result_ctx(current_context);
      if (ctx == NULL)
        return true;
      current_context->set_union_result(ctx);
      current_context= ctx;
      break;
    }
  case CTX_QUERY_SPEC:
    {
      DBUG_ASSERT(current_context->type == CTX_UNION);
      subquery_ctx *ctx=
        new (*THR_MALLOC) subquery_ctx(CTX_QUERY_SPEC, NULL, current_context);
      if (ctx == NULL || current_context->add_query_spec(ctx))
        return true;
      current_context= ctx;
      break;
    }
  case CTX_MESSAGE:
    {
      /*
        Like CTX_QEP_TAB:
      */
      DBUG_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);
      joinable_ctx *ctx= new (*THR_MALLOC) message_ctx(current_context);
      if (ctx == NULL || 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 == NULL)
          return true;
        current_context->set_window(ctx);
        current_context= ctx;
        break;
      }
  default:
    DBUG_ASSERT(!"Unknown EXPLAIN context!");
    return true;
  }

  if (prev_context)
    prev_context->set_child(current_context);

  return false;
}