~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: devananda
  • Date: 2009-06-30 14:27:54 UTC
  • mfrom: (1030.2.4 trunk)
  • mto: (1093.1.7 captain)
  • mto: This revision was merged to the branch mainline in revision 1095.
  • Revision ID: devananda.vdv@gmail.com-20090630142754-vm9w374yxkf1pikc
mergeĀ fromĀ lp

Show diffs side-by-side

added added

removed removed

Lines of Context:
2154
2154
  broadcast_refresh();
2155
2155
}
2156
2156
 
2157
 
static int send_check_errmsg(Session *session, TableList* table,
2158
 
                             const char* operator_name, const char* errmsg)
2159
 
 
2160
 
{
2161
 
  Protocol *protocol= session->protocol;
2162
 
  protocol->prepareForResend();
2163
 
  protocol->store(table->alias);
2164
 
  protocol->store((char*) operator_name);
2165
 
  protocol->store(STRING_WITH_LEN("error"));
2166
 
  protocol->store(errmsg);
2167
 
  session->clear_error();
2168
 
  if (protocol->write())
2169
 
    return -1;
2170
 
  return 1;
2171
 
}
2172
 
 
2173
 
 
2174
 
static int prepare_for_repair(Session *session, TableList *table_list,
2175
 
                              HA_CHECK_OPT *check_opt)
2176
 
{
2177
 
  int error= 0;
2178
 
  Table tmp_table, *table;
2179
 
  TableShare *share;
2180
 
  char from[FN_REFLEN],tmp[FN_REFLEN+32];
2181
 
  const char **ext;
2182
 
  struct stat stat_info;
2183
 
 
2184
 
  if (!(check_opt->use_frm))
2185
 
    return 0;
2186
 
 
2187
 
  if (!(table= table_list->table))              /* if open_ltable failed */
2188
 
  {
2189
 
    char key[MAX_DBKEY_LENGTH];
2190
 
    uint32_t key_length;
2191
 
 
2192
 
    key_length= table_list->create_table_def_key(key);
2193
 
    pthread_mutex_lock(&LOCK_open); /* Lock table for repair */
2194
 
    if (!(share= (get_table_share(session, table_list, key, key_length, 0,
2195
 
                                  &error))))
2196
 
    {
2197
 
      pthread_mutex_unlock(&LOCK_open);
2198
 
 
2199
 
      return 0;                         // Can't open frm file
2200
 
    }
2201
 
 
2202
 
    if (open_table_from_share(session, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2203
 
    {
2204
 
      release_table_share(share);
2205
 
      pthread_mutex_unlock(&LOCK_open);
2206
 
 
2207
 
      return 0;                           // Out of memory
2208
 
    }
2209
 
    table= &tmp_table;
2210
 
    pthread_mutex_unlock(&LOCK_open);
2211
 
  }
2212
 
 
2213
 
  /*
2214
 
    REPAIR Table ... USE_FRM for temporary tables makes little sense.
2215
 
  */
2216
 
  if (table->s->tmp_table)
2217
 
  {
2218
 
    error= send_check_errmsg(session, table_list, "repair",
2219
 
                             "Cannot repair temporary table from .frm file");
2220
 
    goto end;
2221
 
  }
2222
 
 
2223
 
  /*
2224
 
    User gave us USE_FRM which means that the header in the index file is
2225
 
    trashed.
2226
 
    In this case we will try to fix the table the following way:
2227
 
    - Rename the data file to a temporary name
2228
 
    - Truncate the table
2229
 
    - Replace the new data file with the old one
2230
 
    - Run a normal repair using the new index file and the old data file
2231
 
  */
2232
 
 
2233
 
  /*
2234
 
    Check if this is a table type that stores index and data separately,
2235
 
    like ISAM or MyISAM. We assume fixed order of engine file name
2236
 
    extentions array. First element of engine file name extentions array
2237
 
    is meta/index file extention. Second element - data file extention.
2238
 
  */
2239
 
  ext= table->file->engine->bas_ext();
2240
 
  if (!ext[0] || !ext[1])
2241
 
    goto end;                                   // No data file
2242
 
 
2243
 
  // Name of data file
2244
 
  sprintf(from,"%s%s", table->s->normalized_path.str, ext[1]);
2245
 
  if (stat(from, &stat_info))
2246
 
    goto end;                           // Can't use USE_FRM flag
2247
 
 
2248
 
  snprintf(tmp, sizeof(tmp), "%s-%lx_%"PRIx64,
2249
 
           from, (unsigned long)current_pid, session->thread_id);
2250
 
 
2251
 
  /* If we could open the table, close it */
2252
 
  if (table_list->table)
2253
 
  {
2254
 
    pthread_mutex_lock(&LOCK_open); /* Close for repair table */
2255
 
    session->close_cached_table(table);
2256
 
    pthread_mutex_unlock(&LOCK_open);
2257
 
  }
2258
 
  if (lock_and_wait_for_table_name(session,table_list))
2259
 
  {
2260
 
    error= -1;
2261
 
    goto end;
2262
 
  }
2263
 
  if (my_rename(from, tmp, MYF(MY_WME)))
2264
 
  {
2265
 
    pthread_mutex_lock(&LOCK_open); /* Lock during rename of table (aka we go to unlock ) */
2266
 
    unlock_table_name(table_list);
2267
 
    pthread_mutex_unlock(&LOCK_open);
2268
 
    error= send_check_errmsg(session, table_list, "repair",
2269
 
                             "Failed renaming data file");
2270
 
    goto end;
2271
 
  }
2272
 
  if (mysql_truncate(session, table_list, 1))
2273
 
  {
2274
 
    pthread_mutex_lock(&LOCK_open); /* Lock during truncate of table during repair operation. */
2275
 
    unlock_table_name(table_list);
2276
 
    pthread_mutex_unlock(&LOCK_open);
2277
 
    error= send_check_errmsg(session, table_list, "repair",
2278
 
                             "Failed generating table from .frm file");
2279
 
    goto end;
2280
 
  }
2281
 
  if (my_rename(tmp, from, MYF(MY_WME)))
2282
 
  {
2283
 
    pthread_mutex_lock(&LOCK_open); /* Final repair of table for rename */
2284
 
    unlock_table_name(table_list);
2285
 
    pthread_mutex_unlock(&LOCK_open);
2286
 
    error= send_check_errmsg(session, table_list, "repair",
2287
 
                             "Failed restoring .MYD file");
2288
 
    goto end;
2289
 
  }
2290
 
 
2291
 
  /*
2292
 
    Now we should be able to open the partially repaired table
2293
 
    to finish the repair in the handler later on.
2294
 
  */
2295
 
  pthread_mutex_lock(&LOCK_open); /* Lock for opening partially repaired table */
2296
 
  if (session->reopen_name_locked_table(table_list, true))
2297
 
  {
2298
 
    unlock_table_name(table_list);
2299
 
    pthread_mutex_unlock(&LOCK_open);
2300
 
    error= send_check_errmsg(session, table_list, "repair",
2301
 
                             "Failed to open partially repaired table");
2302
 
    goto end;
2303
 
  }
2304
 
  pthread_mutex_unlock(&LOCK_open);
2305
 
 
2306
 
end:
2307
 
  if (table == &tmp_table)
2308
 
  {
2309
 
    pthread_mutex_lock(&LOCK_open); /* Lock to close table after repair operation */
2310
 
    table->closefrm(true);                              // Free allocated memory
2311
 
    pthread_mutex_unlock(&LOCK_open);
2312
 
  }
2313
 
  return(error);
2314
 
}
2315
 
 
2316
 
 
2317
 
 
2318
2157
/*
2319
2158
  RETURN VALUES
2320
2159
    false Message sent to net (admin operation went ok)
2480
2319
      /* purecov: end */
2481
2320
    }
2482
2321
 
2483
 
    if (operator_func == &handler::ha_repair && !(check_opt->use_frm))
2484
 
    {
2485
 
      if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER))
2486
 
      {
2487
 
        ha_autocommit_or_rollback(session, 1);
2488
 
        session->close_thread_tables();
2489
 
        result_code= mysql_recreate_table(session, table);
2490
 
        /*
2491
 
          mysql_recreate_table() can push OK or ERROR.
2492
 
          Clear 'OK' status. If there is an error, keep it:
2493
 
          we will store the error message in a result set row
2494
 
          and then clear.
2495
 
        */
2496
 
        if (session->main_da.is_ok())
2497
 
          session->main_da.reset_diagnostics_area();
2498
 
        goto send_result;
2499
 
      }
2500
 
    }
2501
 
 
2502
2322
    result_code = (table->table->file->*operator_func)(session, check_opt);
2503
2323
 
2504
2324
send_result:
2690
2510
  return(true);
2691
2511
}
2692
2512
 
2693
 
 
2694
 
bool mysql_repair_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2695
 
{
2696
 
  return(mysql_admin_table(session, tables, check_opt,
2697
 
                           "repair", TL_WRITE, 1,
2698
 
                           check_opt->use_frm,
2699
 
                           HA_OPEN_FOR_REPAIR,
2700
 
                           &prepare_for_repair,
2701
 
                           &handler::ha_repair));
2702
 
}
2703
 
 
2704
 
 
2705
2513
bool mysql_optimize_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2706
2514
{
2707
2515
  return(mysql_admin_table(session, tables, check_opt,
2827
2635
  else
2828
2636
    table_proto.set_type(drizzled::message::Table::STANDARD);
2829
2637
 
 
2638
  {
 
2639
    drizzled::message::Table::StorageEngine *protoengine;
 
2640
    protoengine= table_proto.mutable_engine();
 
2641
 
 
2642
    StorageEngine *engine= local_create_info.db_type;
 
2643
 
 
2644
    protoengine->set_name(engine->getName());
 
2645
  }
 
2646
 
2830
2647
  if (rea_create_table(session, dst_path, "system_tmp", "system_stupid_i_s_fix_nonsense",
2831
2648
                       &table_proto,
2832
2649
                       &local_create_info, alter_info.create_list,
2944
2761
    and temporary tables).
2945
2762
  */
2946
2763
 
2947
 
  if (session->variables.keep_files_on_create)
2948
 
    create_info->options|= HA_CREATE_KEEP_FILES;
2949
2764
  err= ha_create_table(session, dst_path, db, table_name, create_info, 1);
2950
2765
  pthread_mutex_unlock(&LOCK_open);
2951
2766
 
3273
3088
  drizzled::message::Table table_proto;
3274
3089
  table_proto.set_name(tmp_name);
3275
3090
  table_proto.set_type(drizzled::message::Table::TEMPORARY);
 
3091
 
 
3092
  drizzled::message::Table::StorageEngine *protoengine;
 
3093
  protoengine= table_proto.mutable_engine();
 
3094
  protoengine->set_name(new_db_type->getName());
 
3095
 
3276
3096
  error= mysql_create_table(session, new_db, tmp_name,
3277
3097
                            create_info, &table_proto, alter_info, 1, 0);
3278
3098
 
3851
3671
    create_info->db_type= old_db_type;
3852
3672
  }
3853
3673
 
 
3674
  if(table->s->tmp_table != NO_TMP_TABLE)
 
3675
    create_info->options|= HA_LEX_CREATE_TMP_TABLE;
 
3676
 
3854
3677
  if (check_engine(session, new_name, create_info))
3855
3678
    goto err;
3856
3679
  new_db_type= create_info->db_type;
4675
4498
    }
4676
4499
    *new_engine= myisam_engine;
4677
4500
  }
 
4501
  if(!(create_info->options & HA_LEX_CREATE_TMP_TABLE)
 
4502
     && (*new_engine)->check_flag(HTON_BIT_TEMPORARY_ONLY))
 
4503
  {
 
4504
    my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
 
4505
             ha_resolve_storage_engine_name(*new_engine).c_str(),
 
4506
             "non-TEMPORARY");
 
4507
    *new_engine= 0;
 
4508
    return true;
 
4509
  }
 
4510
 
4678
4511
  return false;
4679
4512
}