~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Eric Day
  • Date: 2009-10-31 21:53:33 UTC
  • mfrom: (1200 staging)
  • mto: This revision was merged to the branch mainline in revision 1202.
  • Revision ID: eday@oddments.org-20091031215333-j94bjoanwmi68p6f
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include <drizzled/table_proto.h>
36
36
#include <drizzled/plugin/client.h>
37
37
 
38
 
#include "drizzled/statement/alter_table.h" /* for mysql_create_like_schema_frm, which will die soon */
 
38
#include "drizzled/statement/alter_table.h" /* for drizzled::create_like_schema_frm, which will die soon */
39
39
 
40
40
#include <algorithm>
41
41
 
340
340
  string built_query;
341
341
 
342
342
  if (if_exists)
343
 
    built_query.append("DROP Table IF EXISTS ");
 
343
    built_query.append("DROP TABLE IF EXISTS ");
344
344
  else
345
 
    built_query.append("DROP Table ");
 
345
    built_query.append("DROP TABLE ");
346
346
 
347
347
  built_query.append("`");
348
348
  if (session->db == NULL || strcmp(db_name ,session->db) != 0)
420
420
 
421
421
  SYNOPSIS
422
422
    mysql_rm_table_part2()
423
 
    session                     Thread handler
 
423
    session                     Thread Cursor
424
424
    tables              Tables to drop
425
425
    if_exists           If set, don't give an error if table doesn't exists.
426
426
                        In this case we give an warning of level 'NOTE'
427
427
    drop_temporary      Only drop temporary tables
428
428
    dont_log_query      Don't write query to log files. This will also not
429
 
                        generate warnings if the handler files doesn't exists
 
429
                        generate warnings if the Cursor files doesn't exists
430
430
 
431
431
  TODO:
432
432
    When logging to the binary log, we should log
524
524
 
525
525
    if (drop_temporary ||
526
526
        ((table_type == NULL
527
 
          && (plugin::StorageEngine::getTableProto(path, NULL) != EEXIST))))
 
527
          && (plugin::StorageEngine::getTableDefinition(*session, 
 
528
                                                        path, 
 
529
                                                        db, 
 
530
                                                        table->table_name, 
 
531
                                                        table->internal_tmp_table) != EEXIST))))
528
532
    {
529
533
      // Table was not found on disk and table can't be created from engine
530
534
      if (if_exists)
536
540
    }
537
541
    else
538
542
    {
539
 
      error= plugin::StorageEngine::deleteTable(session, path, db,
 
543
      error= plugin::StorageEngine::dropTable(*session, path, db,
540
544
                                                table->table_name,
541
545
                                                ! dont_log_query);
542
546
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists)
605
609
    != 0        Error
606
610
*/
607
611
 
608
 
bool quick_rm_table(plugin::StorageEngine *, const char *db,
 
612
bool quick_rm_table(Session& session, const char *db,
609
613
                    const char *table_name, bool is_tmp)
610
614
{
611
615
  char path[FN_REFLEN];
613
617
 
614
618
  build_table_filename(path, sizeof(path), db, table_name, is_tmp);
615
619
 
616
 
  return (plugin::StorageEngine::deleteTable(current_session, path, db,
617
 
                                             table_name, 0)
 
620
  return (plugin::StorageEngine::dropTable(session, path, db,
 
621
                                           table_name, 0)
618
622
          || error);
619
623
}
620
624
 
828
832
 
829
833
int mysql_prepare_create_table(Session *session,
830
834
                               HA_CREATE_INFO *create_info,
 
835
                               message::Table *create_proto,
831
836
                               AlterInfo *alter_info,
832
837
                               bool tmp_table,
833
838
                               uint32_t *db_options,
834
 
                               handler *file,
 
839
                               Cursor *file,
835
840
                               KEY **key_info_buffer,
836
841
                               uint32_t *key_count,
837
842
                               int select_field_count)
1245
1250
    */
1246
1251
    key_info->block_size= (key->key_create_info.block_size ?
1247
1252
                           key->key_create_info.block_size :
1248
 
                           create_info->key_block_size);
 
1253
                           create_proto->options().key_block_size());
1249
1254
 
1250
1255
    if (key_info->block_size)
1251
1256
      key_info->flags|= HA_USES_BLOCK_SIZE;
1597
1602
  uint32_t          path_length;
1598
1603
  uint          db_options, key_count;
1599
1604
  KEY           *key_info_buffer;
1600
 
  handler       *file;
 
1605
  Cursor        *file;
1601
1606
  bool          error= true;
1602
1607
  /* Check for duplicate fields and check type of table to create */
1603
1608
  if (!alter_info->create_list.elements)
1612
1617
  db_options= create_info->table_options;
1613
1618
  if (create_info->row_type == ROW_TYPE_DYNAMIC)
1614
1619
    db_options|=HA_OPTION_PACK_RECORD;
1615
 
  if (!(file= get_new_handler((TableShare*) 0, session->mem_root,
1616
 
                              create_info->db_type)))
 
1620
  if (!(file= create_info->db_type->getCursor((TableShare*) 0, session->mem_root)))
1617
1621
  {
1618
 
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
 
1622
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(Cursor));
1619
1623
    return true;
1620
1624
  }
1621
1625
 
1622
1626
  set_table_default_charset(create_info, (char*) db);
1623
1627
 
1624
 
  if (mysql_prepare_create_table(session, create_info, alter_info,
 
1628
  if (mysql_prepare_create_table(session, create_info, table_proto, alter_info,
1625
1629
                                 internal_tmp_table,
1626
1630
                                 &db_options, file,
1627
1631
                                 &key_info_buffer, &key_count,
1666
1670
  pthread_mutex_lock(&LOCK_open); /* CREATE TABLE (some confussion on naming, double check) */
1667
1671
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1668
1672
  {
1669
 
    if (plugin::StorageEngine::getTableProto(path, NULL)==EEXIST)
 
1673
    if (plugin::StorageEngine::getTableDefinition(*session, path, db, table_name, internal_tmp_table)==EEXIST)
1670
1674
    {
1671
1675
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1672
1676
      {
1716
1720
    table_path_length= build_table_filename(table_path, sizeof(table_path),
1717
1721
                                            db, table_name, false);
1718
1722
 
1719
 
    int retcode= plugin::StorageEngine::getTableProto(table_path, NULL);
 
1723
    int retcode= plugin::StorageEngine::getTableDefinition(*session, table_path, db, table_name, false);
1720
1724
    switch (retcode)
1721
1725
    {
1722
1726
      case ENOENT:
1923
1927
  build_table_filename(to, sizeof(to), new_db, new_name,
1924
1928
                       flags & FN_TO_IS_TMP);
1925
1929
 
1926
 
  if (!(error=base->renameTable(session, from_base, to_base)))
 
1930
  if (!(error= base->renameTable(session, from_base, to_base)))
1927
1931
  {
1928
1932
    if(!(flags & NO_FRM_RENAME)
1929
1933
       && base->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == 0
1947
1951
 
1948
1952
  SYNOPSIS
1949
1953
    wait_while_table_is_used()
1950
 
    session                     Thread handler
 
1954
    session                     Thread Cursor
1951
1955
    table               Table to remove from cache
1952
1956
    function            HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
1953
1957
                        HA_EXTRA_FORCE_REOPEN if table is not be used
1982
1986
 
1983
1987
  SYNOPSIS
1984
1988
    close_cached_table()
1985
 
    session                     Thread handler
 
1989
    session                     Thread Cursor
1986
1990
    table               Table to remove from cache
1987
1991
 
1988
1992
  NOTES
2026
2030
                              uint32_t extra_open_options,
2027
2031
                              int (*prepare_func)(Session *, TableList *,
2028
2032
                                                  HA_CHECK_OPT *),
2029
 
                              int (handler::*operator_func)(Session *,
 
2033
                              int (Cursor::*operator_func)(Session *,
2030
2034
                                                            HA_CHECK_OPT *))
2031
2035
{
2032
2036
  TableList *table;
2156
2160
      open_for_modify= 0;
2157
2161
    }
2158
2162
 
2159
 
    if (table->table->s->crashed && operator_func == &handler::ha_check)
 
2163
    if (table->table->s->crashed && operator_func == &Cursor::ha_check)
2160
2164
    {
2161
2165
      session->client->store(table_name);
2162
2166
      session->client->store(operator_name);
2351
2355
{
2352
2356
  return(mysql_admin_table(session, tables, check_opt,
2353
2357
                           "optimize", TL_WRITE, 1,0,0,0,
2354
 
                           &handler::ha_optimize));
 
2358
                           &Cursor::ha_optimize));
2355
2359
}
2356
2360
 
2357
2361
/*
2387
2391
    By opening source table we guarantee that it exists and no concurrent
2388
2392
    DDL operation will mess with it. Later we also take an exclusive
2389
2393
    name-lock on target table name, which makes copying of .frm file,
2390
 
    call to StorageEngine::createTable() and binlogging atomic against concurrent DML
2391
 
    and DDL operations on target table. Thus by holding both these "locks"
2392
 
    we ensure that our statement is properly isolated from all concurrent
2393
 
    operations which matter.
 
2394
    call to plugin::StorageEngine::createTable() and binlogging atomic
 
2395
    against concurrent DML and DDL operations on target table.
 
2396
    Thus by holding both these "locks" we ensure that our statement is
 
2397
    properly isolated from all concurrent operations which matter.
2394
2398
  */
2395
2399
  if (session->open_tables_from_list(&src_table, &not_used))
2396
2400
    return true;
2416
2420
      goto table_exists;
2417
2421
    dst_path_length= build_table_filename(dst_path, sizeof(dst_path),
2418
2422
                                          db, table_name, false);
2419
 
    if (plugin::StorageEngine::getTableProto(dst_path, NULL) == EEXIST)
 
2423
    if (plugin::StorageEngine::getTableDefinition(*session, dst_path, db, table_name, false) == EEXIST)
2420
2424
      goto table_exists;
2421
2425
  }
2422
2426
 
2425
2429
 
2426
2430
    Altough exclusive name-lock on target table protects us from concurrent
2427
2431
    DML and DDL operations on it we still want to wrap .FRM creation and call
2428
 
    to StorageEngine::createTable() in critical section protected by LOCK_open in order
2429
 
    to provide minimal atomicity against operations which disregard name-locks,
2430
 
    like I_S implementation, for example. This is a temporary and should not
2431
 
    be copied. Instead we should fix our code to always honor name-locks.
 
2432
    to plugin::StorageEngine::createTable() in critical section protected by
 
2433
    LOCK_open in order to provide minimal atomicity against operations which
 
2434
    disregard name-locks, like I_S implementation, for example. This is a
 
2435
    temporary and should not be copied. Instead we should fix our code to
 
2436
    always honor name-locks.
2432
2437
 
2433
2438
    Also some engines (e.g. NDB cluster) require that LOCK_open should be held
2434
 
    during the call to StorageEngine::createTable(). See bug #28614 for more info.
 
2439
    during the call to plugin::StorageEngine::createTable().
 
2440
    See bug #28614 for more info.
2435
2441
  */
2436
2442
  pthread_mutex_lock(&LOCK_open); /* We lock for CREATE TABLE LIKE to copy table definition */
2437
2443
  {
2439
2445
 
2440
2446
    if (src_table->schema_table)
2441
2447
    {
2442
 
      if (mysql_create_like_schema_frm(session, src_table, create_info,
2443
 
                                       &src_proto))
 
2448
      if (create_like_schema_frm(session, src_table, create_info, &src_proto))
2444
2449
      {
2445
2450
        pthread_mutex_unlock(&LOCK_open);
2446
2451
        goto err;
2448
2453
    }
2449
2454
    else
2450
2455
    {
2451
 
      protoerr= plugin::StorageEngine::getTableProto(src_path, &src_proto);
 
2456
      protoerr= plugin::StorageEngine::getTableDefinition(*session,
 
2457
                                                          src_path,
 
2458
                                                          db,
 
2459
                                                          table_name,
 
2460
                                                          false,
 
2461
                                                          &src_proto);
2452
2462
    }
2453
2463
 
2454
2464
    message::Table new_proto(src_proto);
2468
2478
 
2469
2479
    if (protoerr == EEXIST)
2470
2480
    {
2471
 
      plugin::StorageEngine* engine= plugin::StorageEngine::findByName(session,
 
2481
      plugin::StorageEngine* engine= plugin::StorageEngine::findByName(*session,
2472
2482
                                                                       new_proto.engine().name());
2473
2483
 
2474
2484
      if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == false)
2492
2502
      creation, instead create the table directly (for both normal
2493
2503
      and temporary tables).
2494
2504
    */
2495
 
    err= plugin::StorageEngine::createTable(session, dst_path, db, table_name, create_info, 
2496
 
                                            true, &new_proto);
 
2505
    err= plugin::StorageEngine::createTable(*session, dst_path, db, table_name, *create_info, 
 
2506
                                            true, new_proto);
2497
2507
  }
2498
2508
  pthread_mutex_unlock(&LOCK_open);
2499
2509
 
2507
2517
  }
2508
2518
  else if (err)
2509
2519
  {
2510
 
    (void) quick_rm_table(create_info->db_type, db,
 
2520
    (void) quick_rm_table(*session, db,
2511
2521
                          table_name, false);
2512
2522
    goto err;
2513
2523
  }
2598
2608
 
2599
2609
  return(mysql_admin_table(session, tables, check_opt,
2600
2610
                                "analyze", lock_type, 1, 0, 0, 0,
2601
 
                                &handler::ha_analyze));
 
2611
                                &Cursor::ha_analyze));
2602
2612
}
2603
2613
 
2604
2614
 
2609
2619
  return(mysql_admin_table(session, tables, check_opt,
2610
2620
                                "check", lock_type,
2611
2621
                                0, 0, HA_OPEN_FOR_REPAIR, 0,
2612
 
                                &handler::ha_check));
 
2622
                                &Cursor::ha_check));
2613
2623
}
2614
2624
 
2615
2625
/*
2616
 
  Recreates tables by calling mysql_alter_table().
 
2626
  Recreates tables by calling drizzled::alter_table().
2617
2627
 
2618
2628
  SYNOPSIS
2619
2629
    mysql_recreate_table()
2620
 
    session                     Thread handler
 
2630
    session                     Thread Cursor
2621
2631
    tables              Tables to recreate
2622
2632
 
2623
2633
 RETURN
2624
 
    Like mysql_alter_table().
 
2634
    Like drizzled::alter_table().
2625
2635
*/
2626
2636
bool mysql_recreate_table(Session *session, TableList *table_list)
2627
2637
{
2642
2652
  /* Force alter table to recreate table */
2643
2653
  alter_info.flags.set(ALTER_CHANGE_COLUMN);
2644
2654
  alter_info.flags.set(ALTER_RECREATE);
2645
 
  return(mysql_alter_table(session, NULL, NULL, &create_info, &table_proto,
2646
 
                           table_list, &alter_info, 0,
2647
 
                           (order_st *) 0, 0));
 
2655
  return(alter_table(session, NULL, NULL, &create_info, &table_proto,
 
2656
                     table_list, &alter_info, 0,
 
2657
                     (order_st *) 0, 0));
2648
2658
}
2649
2659
 
2650
2660