~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#include <drizzled/unireg.h>
33
33
#include <drizzled/item/int.h>
34
34
#include <drizzled/item/empty_string.h>
35
 
#include <drizzled/replication_services.h>
 
35
#include <drizzled/transaction_services.h>
36
36
#include "drizzled/transaction_services.h"
37
37
#include <drizzled/table_proto.h>
38
38
#include <drizzled/plugin/client.h>
106
106
void write_bin_log(Session *session,
107
107
                   char const *query)
108
108
{
109
 
  ReplicationServices &replication_services= ReplicationServices::singleton();
110
 
  replication_services.rawStatement(session, query);
 
109
  TransactionServices &transaction_services= TransactionServices::singleton();
 
110
  transaction_services.rawStatement(session, query);
111
111
}
112
112
 
113
113
 
114
114
/* Should should be refactored to go away */
115
115
void write_bin_log_drop_table(Session *session, bool if_exists, const char *db_name, const char *table_name)
116
116
{
117
 
  ReplicationServices &replication_services= ReplicationServices::singleton();
 
117
  TransactionServices &transaction_services= TransactionServices::singleton();
118
118
  string built_query;
119
119
 
120
120
  if (if_exists)
131
131
 
132
132
  built_query.append(table_name);
133
133
  built_query.append("`");
134
 
  replication_services.rawStatement(session, built_query);
 
134
  transaction_services.rawStatement(session, built_query);
135
135
}
136
136
 
137
137
/*
263
263
 
264
264
    if (error == 0 || (if_exists && foreign_key_error == false))
265
265
    {
266
 
      ReplicationServices &replication_services= ReplicationServices::singleton();
267
 
      replication_services.dropTable(session, string(db), string(table->table_name), if_exists);
 
266
      TransactionServices &transaction_services= TransactionServices::singleton();
 
267
      transaction_services.dropTable(session, string(db), string(table->table_name), if_exists);
268
268
    }
269
269
 
270
270
    if (error)
529
529
  return 0;
530
530
}
531
531
 
532
 
int mysql_prepare_create_table(Session *session,
533
 
                               HA_CREATE_INFO *create_info,
534
 
                               message::Table *create_proto,
535
 
                               AlterInfo *alter_info,
536
 
                               bool tmp_table,
537
 
                               uint32_t *db_options,
538
 
                               Cursor *cursor,
539
 
                               KEY **key_info_buffer,
540
 
                               uint32_t *key_count,
541
 
                               int select_field_count)
 
532
static int mysql_prepare_create_table(Session *session,
 
533
                                      HA_CREATE_INFO *create_info,
 
534
                                      message::Table &create_proto,
 
535
                                      AlterInfo *alter_info,
 
536
                                      bool tmp_table,
 
537
                                      uint32_t *db_options,
 
538
                                      KEY **key_info_buffer,
 
539
                                      uint32_t *key_count,
 
540
                                      int select_field_count)
542
541
{
543
542
  const char    *key_name;
544
543
  CreateField   *sql_field,*dup_field;
553
552
  List_iterator<CreateField> it2(alter_info->create_list);
554
553
  uint32_t total_uneven_bit_length= 0;
555
554
 
 
555
  plugin::StorageEngine *engine= plugin::StorageEngine::findByName(create_proto.engine().name());
 
556
 
556
557
  select_field_pos= alter_info->create_list.elements - select_field_count;
557
558
  null_fields=blob_columns=0;
558
 
  max_key_length= cursor->getEngine()->max_key_length();
 
559
  max_key_length= engine->max_key_length();
559
560
 
560
561
  for (field_no=0; (sql_field=it++) ; field_no++)
561
562
  {
763
764
    }
764
765
 
765
766
    /** @todo Get rid of this MyISAM-specific crap. */
766
 
    if (create_info->db_type == myisam_engine &&
 
767
    if (not create_proto.engine().name().compare("MyISAM") &&
767
768
        ((sql_field->flags & BLOB_FLAG) ||
768
769
         (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED)))
769
770
      (*db_options)|= HA_OPTION_PACK_RECORD;
798
799
    return(true);
799
800
  }
800
801
  if (auto_increment &&
801
 
      (cursor->getEngine()->check_flag(HTON_BIT_NO_AUTO_INCREMENT)))
 
802
      (engine->check_flag(HTON_BIT_NO_AUTO_INCREMENT)))
802
803
  {
803
804
    my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
804
805
               ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
805
806
    return(true);
806
807
  }
807
808
 
808
 
  if (blob_columns && (cursor->getEngine()->check_flag(HTON_BIT_NO_BLOBS)))
 
809
  if (blob_columns && (engine->check_flag(HTON_BIT_NO_BLOBS)))
809
810
  {
810
811
    my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
811
812
               MYF(0));
846
847
      continue;
847
848
    }
848
849
    (*key_count)++;
849
 
    tmp=cursor->getEngine()->max_key_parts();
 
850
    tmp= engine->max_key_parts();
850
851
    if (key->columns.elements > tmp)
851
852
    {
852
853
      my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
895
896
      return(true);
896
897
    }
897
898
  }
898
 
  tmp=cursor->getEngine()->max_keys();
 
899
  tmp= engine->max_keys();
899
900
  if (*key_count > tmp)
900
901
  {
901
902
    my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
950
951
    */
951
952
    key_info->block_size= (key->key_create_info.block_size ?
952
953
                           key->key_create_info.block_size :
953
 
                           create_proto->options().key_block_size());
 
954
                           create_proto.options().key_block_size());
954
955
 
955
956
    if (key_info->block_size)
956
957
      key_info->flags|= HA_USES_BLOCK_SIZE;
1010
1011
      }
1011
1012
      cols2.rewind();
1012
1013
 
1013
 
      if (create_proto->field_size() > 0)
1014
 
        protofield= create_proto->mutable_field(proto_field_nr - 1);
 
1014
      if (create_proto.field_size() > 0)
 
1015
        protofield= create_proto.mutable_field(proto_field_nr - 1);
1015
1016
 
1016
1017
      {
1017
1018
        column->length*= sql_field->charset->mbmaxlen;
1018
1019
 
1019
1020
        if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
1020
1021
        {
1021
 
          if (! (cursor->getEngine()->check_flag(HTON_BIT_CAN_INDEX_BLOBS)))
 
1022
          if (! (engine->check_flag(HTON_BIT_CAN_INDEX_BLOBS)))
1022
1023
          {
1023
1024
            my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str);
1024
1025
            return true;
1048
1049
          else
1049
1050
          {
1050
1051
            key_info->flags|= HA_NULL_PART_KEY;
1051
 
            if (! (cursor->getEngine()->check_flag(HTON_BIT_NULL_IN_KEY)))
 
1052
            if (! (engine->check_flag(HTON_BIT_NULL_IN_KEY)))
1052
1053
            {
1053
1054
              my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.str);
1054
1055
              return true;
1057
1058
        }
1058
1059
        if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
1059
1060
        {
1060
 
          if (column_nr == 0 || (cursor->getEngine()->check_flag(HTON_BIT_AUTO_PART_KEY)))
 
1061
          if (column_nr == 0 || (engine->check_flag(HTON_BIT_AUTO_PART_KEY)))
1061
1062
            auto_increment--;                   // Field is used
1062
1063
        }
1063
1064
      }
1072
1073
        if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
1073
1074
        {
1074
1075
          if ((length=column->length) > max_key_length ||
1075
 
              length > cursor->getEngine()->max_key_part_length())
 
1076
              length > engine->max_key_part_length())
1076
1077
          {
1077
 
            length= min(max_key_length, cursor->getEngine()->max_key_part_length());
 
1078
            length= min(max_key_length, engine->max_key_part_length());
1078
1079
            if (key->type == Key::MULTIPLE)
1079
1080
            {
1080
1081
              /* not a critical problem */
1099
1100
          my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
1100
1101
          return(true);
1101
1102
        }
1102
 
        else if (! (cursor->getEngine()->check_flag(HTON_BIT_NO_PREFIX_CHAR_KEYS)))
 
1103
        else if (! (engine->check_flag(HTON_BIT_NO_PREFIX_CHAR_KEYS)))
1103
1104
        {
1104
1105
          length=column->length;
1105
1106
        }
1109
1110
        my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.str);
1110
1111
          return(true);
1111
1112
      }
1112
 
      if (length > cursor->getEngine()->max_key_part_length())
 
1113
      if (length > engine->max_key_part_length())
1113
1114
      {
1114
 
        length= cursor->getEngine()->max_key_part_length();
 
1115
        length= engine->max_key_part_length();
1115
1116
        if (key->type == Key::MULTIPLE)
1116
1117
        {
1117
1118
          /* not a critical problem */
1191
1192
    key_info++;
1192
1193
  }
1193
1194
  if (!unique_key && !primary_key &&
1194
 
      (cursor->getEngine()->check_flag(HTON_BIT_REQUIRE_PRIMARY_KEY)))
 
1195
      (engine->check_flag(HTON_BIT_REQUIRE_PRIMARY_KEY)))
1195
1196
  {
1196
1197
    my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
1197
1198
    return(true);
1310
1311
bool mysql_create_table_no_lock(Session *session,
1311
1312
                                TableIdentifier &identifier,
1312
1313
                                HA_CREATE_INFO *create_info,
1313
 
                                message::Table *table_proto,
 
1314
                                message::Table &table_proto,
1314
1315
                                AlterInfo *alter_info,
1315
1316
                                bool internal_tmp_table,
1316
1317
                                uint32_t select_field_count,
1318
1319
{
1319
1320
  uint          db_options, key_count;
1320
1321
  KEY           *key_info_buffer;
1321
 
  Cursor        *cursor;
1322
1322
  bool          error= true;
1323
1323
  TableShare share;
1324
1324
  bool lex_identified_temp_table=
1325
 
    (table_proto->type() == message::Table::TEMPORARY);
 
1325
    (table_proto.type() == message::Table::TEMPORARY);
1326
1326
 
1327
1327
  /* Check for duplicate fields and check type of table to create */
1328
 
  if (!alter_info->create_list.elements)
 
1328
  if (not alter_info->create_list.elements)
1329
1329
  {
1330
1330
    my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
1331
1331
               MYF(0));
1332
1332
    return true;
1333
1333
  }
1334
 
  assert(strcmp(identifier.getTableName(), table_proto->name().c_str())==0);
 
1334
  assert(strcmp(identifier.getTableName(), table_proto.name().c_str())==0);
1335
1335
  db_options= create_info->table_options;
 
1336
 
1336
1337
  if (create_info->row_type == ROW_TYPE_DYNAMIC)
1337
1338
    db_options|=HA_OPTION_PACK_RECORD;
1338
 
  if (!(cursor= create_info->db_type->getCursor(share, session->mem_root)))
1339
 
  {
1340
 
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(Cursor));
1341
 
    return true;
1342
 
  }
1343
1339
 
1344
1340
  set_table_default_charset(create_info, identifier.getDBName());
1345
1341
 
1346
1342
  /* Check if table exists */
1347
1343
  if (mysql_prepare_create_table(session, create_info, table_proto, alter_info,
1348
1344
                                 internal_tmp_table,
1349
 
                                 &db_options, cursor,
 
1345
                                 &db_options,
1350
1346
                                 &key_info_buffer, &key_count,
1351
1347
                                 select_field_count))
1352
1348
    goto err;
1452
1448
    /* Open table and put in temporary table list */
1453
1449
    if (not (session->open_temporary_table(identifier)))
1454
1450
    {
1455
 
      (void) session->rm_temporary_table(create_info->db_type, identifier);
 
1451
      (void) session->rm_temporary_table(identifier);
1456
1452
      goto unlock_and_end;
1457
1453
    }
1458
1454
  }
1459
1455
 
1460
1456
  if (not internal_tmp_table && not lex_identified_temp_table)
1461
1457
  {
1462
 
    ReplicationServices &replication_services= ReplicationServices::singleton();
1463
 
    replication_services.createTable(session, *table_proto);
 
1458
    TransactionServices &transaction_services= TransactionServices::singleton();
 
1459
    transaction_services.createTable(session, table_proto);
1464
1460
  }
1465
1461
  error= false;
1466
1462
unlock_and_end:
1468
1464
 
1469
1465
err:
1470
1466
  session->set_proc_info("After create");
1471
 
  delete cursor;
1472
1467
 
1473
1468
  return(error);
1474
1469
}
1481
1476
bool mysql_create_table(Session *session,
1482
1477
                        TableIdentifier &identifier,
1483
1478
                        HA_CREATE_INFO *create_info,
1484
 
                        message::Table *table_proto,
 
1479
                        message::Table &table_proto,
1485
1480
                        AlterInfo *alter_info,
1486
1481
                        bool internal_tmp_table,
1487
1482
                        uint32_t select_field_count,
1490
1485
  Table *name_lock= NULL;
1491
1486
  bool result;
1492
1487
  bool lex_identified_temp_table=
1493
 
    (table_proto->type() == message::Table::TEMPORARY);
 
1488
    (table_proto.type() == message::Table::TEMPORARY);
1494
1489
 
1495
 
  if (! lex_identified_temp_table)
 
1490
  if (not lex_identified_temp_table)
1496
1491
  {
1497
1492
    if (session->lock_table_name_if_not_cached(identifier.getDBName(),
1498
1493
                                               identifier.getTableName(),
1670
1665
  mysql_lock_abort(session, table);     /* end threads waiting on lock */
1671
1666
 
1672
1667
  /* Wait until all there are no other threads that has this table open */
1673
 
  remove_table_from_cache(session, table->s->db.str,
 
1668
  remove_table_from_cache(session, table->s->getSchemaName(),
1674
1669
                          table->s->table_name.str,
1675
1670
                          RTFC_WAIT_OTHER_THREAD_FLAG);
1676
1671
}
1824
1819
      const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
1825
1820
                                              "Waiting to get writelock");
1826
1821
      mysql_lock_abort(session,table->table);
1827
 
      remove_table_from_cache(session, table->table->s->db.str,
 
1822
      remove_table_from_cache(session, table->table->s->getSchemaName(),
1828
1823
                              table->table->s->table_name.str,
1829
1824
                              RTFC_WAIT_OTHER_THREAD_FLAG |
1830
1825
                              RTFC_CHECK_KILLED_FLAG);
1924
1919
        else
1925
1920
        {
1926
1921
          pthread_mutex_lock(&LOCK_open);
1927
 
          remove_table_from_cache(session, table->table->s->db.str,
 
1922
          remove_table_from_cache(session, table->table->s->getSchemaName(),
1928
1923
                                  table->table->s->table_name.str, RTFC_NO_FLAG);
1929
1924
          pthread_mutex_unlock(&LOCK_open);
1930
1925
        }
2051
2046
    protoengine->set_name(create_table_proto.engine().name());
2052
2047
  }
2053
2048
 
2054
 
  if (protoerr == EEXIST)
2055
 
  {
2056
 
    plugin::StorageEngine* engine= plugin::StorageEngine::findByName(session,
2057
 
                                                                     new_proto.engine().name());
2058
 
 
2059
 
    if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == false)
2060
 
    {
2061
 
      string dst_proto_path(destination_identifier.getPath());
2062
 
      dst_proto_path.append(".dfe");
2063
 
 
2064
 
      protoerr= drizzle_write_proto_file(dst_proto_path.c_str(), &new_proto);
2065
 
    }
2066
 
    else
2067
 
    {
2068
 
      protoerr= 0;
2069
 
    }
2070
 
  }
2071
 
 
2072
 
  if (protoerr)
 
2049
  if (protoerr && protoerr != EEXIST)
2073
2050
  {
2074
2051
    if (errno == ENOENT)
2075
2052
      my_error(ER_BAD_DB_ERROR,MYF(0), destination_identifier.getSchemaName());
2106
2083
    true  error
2107
2084
*/
2108
2085
 
2109
 
bool mysql_create_like_table(Session* session, TableList* table, TableList* src_table,
 
2086
bool mysql_create_like_table(Session* session,
 
2087
                             TableIdentifier &destination_identifier,
 
2088
                             TableList* table, TableList* src_table,
2110
2089
                             message::Table& create_table_proto,
2111
 
                             plugin::StorageEngine *engine_arg,
2112
2090
                             bool is_if_not_exists,
2113
2091
                             bool is_engine_set)
2114
2092
{
2133
2111
  if (session->open_tables_from_list(&src_table, &not_used))
2134
2112
    return true;
2135
2113
 
2136
 
  TableIdentifier destination_identifier(db, table_name,
2137
 
                                         lex_identified_temp_table ? TEMP_TABLE : STANDARD_TABLE);
2138
 
 
2139
 
  TableIdentifier src_identifier(src_table->table->s->db.str,
 
2114
  TableIdentifier src_identifier(src_table->table->s->getSchemaName(),
2140
2115
                                 src_table->table->s->table_name.str, src_table->table->s->tmp_table);
2141
2116
 
2142
2117
 
2206
2181
    {
2207
2182
      if (lex_identified_temp_table)
2208
2183
      {
2209
 
        (void) session->rm_temporary_table(engine_arg, destination_identifier);
 
2184
        (void) session->rm_temporary_table(destination_identifier);
2210
2185
      }
2211
2186
      else
2212
2187
      {
2213
 
        TableIdentifier identifier(db, table_name, STANDARD_TABLE);
2214
 
        quick_rm_table(*session, identifier);
 
2188
        quick_rm_table(*session, destination_identifier);
2215
2189
      }
2216
2190
    } 
2217
2191
    else if (lex_identified_temp_table && not session->open_temporary_table(destination_identifier))
2218
2192
    {
2219
2193
      // We created, but we can't open... also, a hack.
2220
 
      (void) session->rm_temporary_table(engine_arg, destination_identifier);
 
2194
      (void) session->rm_temporary_table(destination_identifier);
2221
2195
    }
2222
2196
    else
2223
2197
    {