int bootstrap(MYSQL_FILE *file)
{
  int bootstrap_error= 0;
  DBUG_ENTER("handle_bootstrap");

  THD *thd= new THD(next_thread_id());
#ifdef WITH_WSREP
  thd->variables.wsrep_on= 0;
#endif
  thd->bootstrap=1;
  my_net_init(&thd->net,(st_vio*) 0, thd, MYF(0));
  thd->max_client_packet_length= thd->net.max_packet;
  thd->security_ctx->master_access= ~(ulong)0;

#ifndef EMBEDDED_LIBRARY
  mysql_thread_set_psi_id(thd->thread_id);
#else
  thd->mysql= 0;
#endif

  /* The following must be called before DBUG_ENTER */
  thd->thread_stack= (char*) &thd;
  thd->store_globals();

  thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
  thd->security_ctx->priv_user[0]= thd->security_ctx->priv_host[0]=
    thd->security_ctx->priv_role[0]= 0;
  /*
    Make the "client" handle multiple results. This is necessary
    to enable stored procedures with SELECTs and Dynamic SQL
    in init-file.
  */
  thd->client_capabilities|= CLIENT_MULTI_RESULTS;

  thd->init_for_queries();

  for ( ; ; )
  {
    char buffer[MAX_BOOTSTRAP_QUERY_SIZE] = "";
    int rc, length;
    char *query;
    int error= 0;

    rc= read_bootstrap_query(buffer, &length, file, fgets_fn, &error);

    if (rc == READ_BOOTSTRAP_EOF)
      break;
    /*
      Check for bootstrap file errors. SQL syntax errors will be
      caught below.
    */
    if (rc != READ_BOOTSTRAP_SUCCESS)
    {
      /*
        mysql_parse() may have set a successful error status for the previous
        query. We must clear the error status to report the bootstrap error.
      */
      thd->get_stmt_da()->reset_diagnostics_area();

      /* Get the nearest query text for reference. */
      char *err_ptr= buffer + (length <= MAX_BOOTSTRAP_ERROR_LEN ?
                                        0 : (length - MAX_BOOTSTRAP_ERROR_LEN));
      switch (rc)
      {
      case READ_BOOTSTRAP_ERROR:
        my_printf_error(ER_UNKNOWN_ERROR, "Bootstrap file error, return code (%d). "
                        "Nearest query: '%s'", MYF(0), error, err_ptr);
        break;

      case READ_BOOTSTRAP_QUERY_SIZE:
        my_printf_error(ER_UNKNOWN_ERROR, "Boostrap file error. Query size "
                        "exceeded %d bytes near '%s'.", MYF(0),
                        MAX_BOOTSTRAP_LINE_SIZE, err_ptr);
        break;

      default:
        DBUG_ASSERT(false);
        break;
      }

      thd->protocol->end_statement();
      bootstrap_error= 1;
      break;
    }

    query= (char *) thd->memdup_w_gap(buffer, length + 1,
                                      thd->db.length + 1 +
                                      QUERY_CACHE_DB_LENGTH_SIZE +
                                      QUERY_CACHE_FLAGS_SIZE);
    size_t db_len= 0;
    memcpy(query + length + 1, (char *) &db_len, sizeof(size_t));
    thd->set_query_and_id(query, length, thd->charset(), next_query_id());
    int2store(query + length + 1, 0);           // No db in bootstrap
    DBUG_PRINT("query",("%-.4096s",thd->query()));
#if defined(ENABLED_PROFILING)
    thd->profiling.start_new_query();
    thd->profiling.set_query_source(thd->query(), length);
#endif

    thd->set_time();
    Parser_state parser_state;
    if (parser_state.init(thd, thd->query(), length))
    {
      thd->protocol->end_statement();
      bootstrap_error= 1;
      break;
    }

    mysql_parse(thd, thd->query(), length, &parser_state, FALSE, FALSE);

    bootstrap_error= thd->is_error();
    thd->protocol->end_statement();

#if defined(ENABLED_PROFILING)
    thd->profiling.finish_current_query();
#endif
    delete_explain_query(thd->lex);

    if (unlikely(bootstrap_error))
      break;

    thd->reset_kill_query();  /* Ensure that killed_errmsg is released */
    free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
    thd->lex->restore_set_statement_var();
  }
  delete thd;
  DBUG_RETURN(bootstrap_error);
}