bool Explain_format_JSON::begin_context()

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