bool Explain_format_JSON::begin_context()

in sql/opt_explain_json.cc [1508:1834]


bool Explain_format_JSON::begin_context(Explain_context_enum 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 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 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);
      sort_ctx *ctx= new 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 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_GROUP_BY);
      sort_ctx *ctx= new 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_JOIN_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_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 join_tab_ctx(CTX_JOIN_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_DISTINCT);
      simple_sort_ctx *ctx=
        new 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_BUFFER_RESULT ||
                  current_context->type == CTX_SIMPLE_ORDER_BY ||
                  current_context->type == CTX_SIMPLE_DISTINCT);
      simple_sort_ctx *ctx=
        new 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_BUFFER_RESULT ||
                  current_context->type == CTX_SIMPLE_ORDER_BY);
      simple_sort_ctx *ctx=
        new 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_BUFFER_RESULT ||
                  current_context->type == CTX_DUPLICATES_WEEDOUT);
      materialize_ctx *ctx= new 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_BUFFER_RESULT ||
                  current_context->type == CTX_MATERIALIZATION);
      duplication_weedout_ctx *ctx=
        new 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 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 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 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 subquery_ctx(CTX_OPTIMIZED_AWAY_SUBQUERY, NULL,
                                          current_context);
      if (ctx == NULL || current_context->add_subquery(SQ_HOMELESS, ctx))
        return true;
      current_context= ctx;
      break;
    }
  case CTX_WHERE:
    {
      DBUG_ASSERT(subquery != NULL);
      subquery_ctx *ctx= new 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 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 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 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 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 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 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_JOIN_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_BUFFER_RESULT ||
                  current_context->type == CTX_SIMPLE_GROUP_BY ||
                  current_context->type == CTX_SIMPLE_ORDER_BY ||
                  current_context->type == CTX_SIMPLE_DISTINCT);
      joinable_ctx *ctx= new message_ctx(current_context);
      if (ctx == NULL || current_context->add_join_tab(ctx))
        return true;
      current_context= ctx;
      break;
    }
  default:
    DBUG_ASSERT(!"Unknown EXPLAIN context!");
    return true;
  }

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

  return false;
}