~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/db.cc

Remove dead memset call.

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
#include "drizzled/pthread_globals.h"
45
45
#include "drizzled/charset.h"
46
46
 
 
47
#include <boost/thread/mutex.hpp>
 
48
 
 
49
boost::mutex LOCK_create_db;
 
50
 
47
51
#include "drizzled/internal/my_sys.h"
48
52
 
49
53
#define MAX_DROP_TABLE_Q_LEN      1024
53
57
namespace drizzled
54
58
{
55
59
 
56
 
static long mysql_rm_known_files(Session *session,
 
60
static long drop_tables_via_filenames(Session *session,
57
61
                                 SchemaIdentifier &schema_identifier,
58
 
                                 plugin::TableNameList &dropped_tables);
 
62
                                 TableIdentifiers &dropped_tables);
59
63
static void mysql_change_db_impl(Session *session);
60
64
static void mysql_change_db_impl(Session *session, SchemaIdentifier &schema_identifier);
61
65
 
106
110
  assert(schema_message.has_collation());
107
111
 
108
112
  // @todo push this lock down into the engine
109
 
  pthread_mutex_lock(&LOCK_create_db);
 
113
  {
 
114
    boost::mutex::scoped_lock scopedLock(LOCK_create_db);
110
115
 
111
 
  // Check to see if it exists already.  
112
 
  SchemaIdentifier schema_identifier(schema_message.name());
113
 
  if (plugin::StorageEngine::doesSchemaExist(schema_identifier))
114
 
  {
115
 
    if (not is_if_not_exists)
116
 
    {
117
 
      my_error(ER_DB_CREATE_EXISTS, MYF(0), schema_message.name().c_str());
 
116
    // Check to see if it exists already.  
 
117
    SchemaIdentifier schema_identifier(schema_message.name());
 
118
    if (plugin::StorageEngine::doesSchemaExist(schema_identifier))
 
119
    {
 
120
      if (not is_if_not_exists)
 
121
      {
 
122
        my_error(ER_DB_CREATE_EXISTS, MYF(0), schema_message.name().c_str());
 
123
        error= true;
 
124
      }
 
125
      else
 
126
      {
 
127
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
128
                            ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
 
129
                            schema_message.name().c_str());
 
130
        session->my_ok();
 
131
      }
 
132
    }
 
133
    else if (not plugin::StorageEngine::createSchema(schema_message)) // Try to create it 
 
134
    {
 
135
      my_error(ER_CANT_CREATE_DB, MYF(0), schema_message.name().c_str(), errno);
118
136
      error= true;
119
137
    }
120
 
    else
 
138
    else // Created !
121
139
    {
122
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
123
 
                          ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
124
 
                          schema_message.name().c_str());
125
 
      session->my_ok();
 
140
      transaction_services.createSchema(session, schema_message);
 
141
      session->my_ok(1);
126
142
    }
127
143
  }
128
 
  else if (not plugin::StorageEngine::createSchema(schema_message)) // Try to create it 
129
 
  {
130
 
    my_error(ER_CANT_CREATE_DB, MYF(0), schema_message.name().c_str(), errno);
131
 
    error= true;
132
 
  }
133
 
  else // Created !
134
 
  {
135
 
    transaction_services.createSchema(session, schema_message);
136
 
    session->my_ok(1);
137
 
  }
138
 
 
139
 
  pthread_mutex_unlock(&LOCK_create_db);
140
144
  start_waiting_global_read_lock(session);
141
145
 
142
146
  return error;
164
168
  if ((wait_if_global_read_lock(session, 0, 1)))
165
169
    return false;
166
170
 
167
 
  pthread_mutex_lock(&LOCK_create_db);
168
 
 
169
 
  SchemaIdentifier schema_idenifier(schema_message.name());
170
 
  if (not plugin::StorageEngine::doesSchemaExist(schema_idenifier))
171
 
  {
172
 
    my_error(ER_SCHEMA_DOES_NOT_EXIST, MYF(0), schema_message.name().c_str());
173
 
    return false;
174
 
  }
175
 
 
176
 
  /* Change options if current database is being altered. */
177
 
  bool success= plugin::StorageEngine::alterSchema(schema_message);
178
 
 
179
 
  if (success)
180
 
  {
181
 
    transaction_services.rawStatement(session, session->getQueryString());
182
 
    session->my_ok(1);
183
 
  }
184
 
  else
185
 
  {
186
 
    my_error(ER_ALTER_SCHEMA, MYF(0), schema_message.name().c_str());
187
 
  }
188
 
 
189
 
  pthread_mutex_unlock(&LOCK_create_db);
 
171
  bool success;
 
172
  {
 
173
    boost::mutex::scoped_lock scopedLock(LOCK_create_db);
 
174
 
 
175
    SchemaIdentifier schema_idenifier(schema_message.name());
 
176
    if (not plugin::StorageEngine::doesSchemaExist(schema_idenifier))
 
177
    {
 
178
      my_error(ER_SCHEMA_DOES_NOT_EXIST, MYF(0), schema_message.name().c_str());
 
179
      return false;
 
180
    }
 
181
 
 
182
    /* Change options if current database is being altered. */
 
183
    success= plugin::StorageEngine::alterSchema(schema_message);
 
184
 
 
185
    if (success)
 
186
    {
 
187
      transaction_services.rawStatement(session, session->getQueryString());
 
188
      session->my_ok(1);
 
189
    }
 
190
    else
 
191
    {
 
192
      my_error(ER_ALTER_SCHEMA, MYF(0), schema_message.name().c_str());
 
193
    }
 
194
  }
190
195
  start_waiting_global_read_lock(session);
191
196
 
192
197
  return success;
214
219
{
215
220
  long deleted=0;
216
221
  int error= false;
217
 
  plugin::TableNameList dropped_tables;
 
222
  TableIdentifiers dropped_tables;
218
223
  message::Schema schema_proto;
219
224
 
220
225
  /*
245
250
    session->close_temporary_table(table);
246
251
  }
247
252
 
248
 
  pthread_mutex_lock(&LOCK_create_db);
249
 
 
250
 
 
251
 
  /* See if the schema exists */
252
 
  if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
253
253
  {
254
 
    if (if_exists)
 
254
    boost::mutex::scoped_lock scopedLock(LOCK_create_db);
 
255
 
 
256
    /* See if the schema exists */
 
257
    if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
255
258
    {
256
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
257
 
                          ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
258
 
                          schema_identifier.getSQLPath().c_str());
 
259
      if (if_exists)
 
260
      {
 
261
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
262
                            ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
 
263
                            schema_identifier.getSQLPath().c_str());
 
264
      }
 
265
      else
 
266
      {
 
267
        error= -1;
 
268
        my_error(ER_DB_DROP_EXISTS, MYF(0), schema_identifier.getSQLPath().c_str());
 
269
        goto exit;
 
270
      }
259
271
    }
260
272
    else
261
273
    {
 
274
      LOCK_open.lock(); /* After deleting database, remove all cache entries related to schema */
 
275
      remove_db_from_cache(schema_identifier);
 
276
      LOCK_open.unlock();
 
277
 
 
278
 
262
279
      error= -1;
263
 
      my_error(ER_DB_DROP_EXISTS, MYF(0), schema_identifier.getSQLPath().c_str());
264
 
      goto exit;
 
280
      deleted= drop_tables_via_filenames(session, schema_identifier, dropped_tables);
 
281
      if (deleted >= 0)
 
282
      {
 
283
        error= 0;
 
284
      }
265
285
    }
266
 
  }
267
 
  else
268
 
  {
269
 
    pthread_mutex_lock(&LOCK_open); /* After deleting database, remove all cache entries related to schema */
270
 
    remove_db_from_cache(schema_identifier);
271
 
    pthread_mutex_unlock(&LOCK_open);
272
 
 
273
 
 
274
 
    error= -1;
275
 
    deleted= mysql_rm_known_files(session, schema_identifier, dropped_tables);
276
286
    if (deleted >= 0)
277
287
    {
278
 
      error= 0;
 
288
      assert(! session->query.empty());
 
289
 
 
290
      TransactionServices &transaction_services= TransactionServices::singleton();
 
291
      transaction_services.dropSchema(session, schema_identifier.getSchemaName());
 
292
      session->clear_error();
 
293
      session->server_status|= SERVER_STATUS_DB_DROPPED;
 
294
      session->my_ok((uint32_t) deleted);
 
295
      session->server_status&= ~SERVER_STATUS_DB_DROPPED;
279
296
    }
280
 
  }
281
 
  if (deleted >= 0)
282
 
  {
283
 
    assert(! session->query.empty());
284
 
 
285
 
    TransactionServices &transaction_services= TransactionServices::singleton();
286
 
    transaction_services.dropSchema(session, schema_identifier.getSchemaName());
287
 
    session->clear_error();
288
 
    session->server_status|= SERVER_STATUS_DB_DROPPED;
289
 
    session->my_ok((uint32_t) deleted);
290
 
    session->server_status&= ~SERVER_STATUS_DB_DROPPED;
291
 
  }
292
 
  else
293
 
  {
294
 
    char *query, *query_pos, *query_end, *query_data_start;
295
 
 
296
 
    if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
297
 
      goto exit; /* not much else we can do */
298
 
    query_pos= query_data_start= strcpy(query,"drop table ")+11;
299
 
    query_end= query + MAX_DROP_TABLE_Q_LEN;
300
 
 
301
 
    TransactionServices &transaction_services= TransactionServices::singleton();
302
 
    for (plugin::TableNameList::iterator it= dropped_tables.begin();
303
 
         it != dropped_tables.end();
304
 
         it++)
 
297
    else
305
298
    {
306
 
      uint32_t tbl_name_len;
307
 
 
308
 
      /* 3 for the quotes and the comma*/
309
 
      tbl_name_len= (*it).length() + 3;
310
 
      if (query_pos + tbl_name_len + 1 >= query_end)
 
299
      char *query, *query_pos, *query_end, *query_data_start;
 
300
 
 
301
      if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
 
302
        goto exit; /* not much else we can do */
 
303
      query_pos= query_data_start= strcpy(query,"drop table ")+11;
 
304
      query_end= query + MAX_DROP_TABLE_Q_LEN;
 
305
 
 
306
      TransactionServices &transaction_services= TransactionServices::singleton();
 
307
      for (TableIdentifiers::iterator it= dropped_tables.begin();
 
308
           it != dropped_tables.end();
 
309
           it++)
 
310
      {
 
311
        uint32_t tbl_name_len;
 
312
 
 
313
        /* 3 for the quotes and the comma*/
 
314
        tbl_name_len= (*it).getTableName().length() + 3;
 
315
        if (query_pos + tbl_name_len + 1 >= query_end)
 
316
        {
 
317
          /* These DDL methods and logging protected with LOCK_create_db */
 
318
          transaction_services.rawStatement(session, query);
 
319
          query_pos= query_data_start;
 
320
        }
 
321
 
 
322
        *query_pos++ = '`';
 
323
        query_pos= strcpy(query_pos, (*it).getTableName().c_str()) + (tbl_name_len-3);
 
324
        *query_pos++ = '`';
 
325
        *query_pos++ = ',';
 
326
      }
 
327
 
 
328
      if (query_pos != query_data_start)
311
329
      {
312
330
        /* These DDL methods and logging protected with LOCK_create_db */
313
331
        transaction_services.rawStatement(session, query);
314
 
        query_pos= query_data_start;
315
332
      }
316
 
 
317
 
      *query_pos++ = '`';
318
 
      query_pos= strcpy(query_pos, (*it).c_str()) + (tbl_name_len-3);
319
 
      *query_pos++ = '`';
320
 
      *query_pos++ = ',';
321
 
    }
322
 
 
323
 
    if (query_pos != query_data_start)
324
 
    {
325
 
      /* These DDL methods and logging protected with LOCK_create_db */
326
 
      transaction_services.rawStatement(session, query);
327
 
    }
328
 
  }
 
333
    }
329
334
 
330
335
exit:
331
 
  /*
332
 
    If this database was the client's selected database, we silently
333
 
    change the client's selected database to nothing (to have an empty
334
 
    SELECT DATABASE() in the future). For this we free() session->db and set
335
 
    it to 0.
336
 
  */
337
 
  if (schema_identifier.compare(session->db))
338
 
    mysql_change_db_impl(session);
339
 
  pthread_mutex_unlock(&LOCK_create_db);
 
336
    /*
 
337
      If this database was the client's selected database, we silently
 
338
      change the client's selected database to nothing (to have an empty
 
339
      SELECT DATABASE() in the future). For this we free() session->db and set
 
340
      it to 0.
 
341
    */
 
342
    if (schema_identifier.compare(session->db))
 
343
      mysql_change_db_impl(session);
 
344
  }
 
345
 
340
346
  start_waiting_global_read_lock(session);
341
347
 
342
348
  return error;
345
351
 
346
352
static int rm_table_part2(Session *session, TableList *tables)
347
353
{
 
354
  TransactionServices &transaction_services= TransactionServices::singleton();
 
355
 
348
356
  TableList *table;
349
357
  String wrong_tables;
350
358
  int error= 0;
351
359
  bool foreign_key_error= false;
352
360
 
353
 
  pthread_mutex_lock(&LOCK_open); /* Part 2 of rm a table */
 
361
  LOCK_open.lock(); /* Part 2 of rm a table */
354
362
 
355
363
  /*
356
364
    If we have the table in the definition cache, we don't have to check the
362
370
  {
363
371
    TableIdentifier identifier(table->db, table->table_name);
364
372
    TableShare *share;
365
 
    table->db_type= NULL;
 
373
    table->setDbType(NULL);
366
374
    if ((share= TableShare::getShare(identifier)))
367
375
    {
368
 
      table->db_type= share->db_type();
 
376
      table->setDbType(share->db_type());
369
377
    }
370
378
  }
371
379
 
372
380
  if (lock_table_names_exclusively(session, tables))
373
381
  {
374
 
    pthread_mutex_unlock(&LOCK_open);
 
382
    LOCK_open.unlock();
375
383
    return 1;
376
384
  }
377
385
 
391
399
      continue;
392
400
    case -1:
393
401
      error= 1;
394
 
      goto err_with_placeholders;
 
402
      unlock_table_names(tables, NULL);
 
403
      LOCK_open.unlock();
 
404
      session->no_warnings_for_error= 0;
 
405
 
 
406
      return(error);
395
407
    default:
396
408
      // temporary table not found
397
409
      error= 0;
398
410
    }
399
411
 
400
 
    table_type= table->db_type;
 
412
    table_type= table->getDbType();
 
413
 
 
414
    TableIdentifier identifier(db, table->table_name);
401
415
 
402
416
    {
403
417
      Table *locked_table;
404
 
      abort_locked_tables(session, db, table->table_name);
405
 
      remove_table_from_cache(session, db, table->table_name,
 
418
      abort_locked_tables(session, identifier);
 
419
      remove_table_from_cache(session, identifier,
406
420
                              RTFC_WAIT_OTHER_THREAD_FLAG |
407
421
                              RTFC_CHECK_KILLED_FLAG);
408
422
      /*
409
423
        If the table was used in lock tables, remember it so that
410
424
        unlock_table_names can free it
411
425
      */
412
 
      if ((locked_table= drop_locked_tables(session, db, table->table_name)))
 
426
      if ((locked_table= drop_locked_tables(session, identifier)))
413
427
        table->table= locked_table;
414
428
 
415
429
      if (session->killed)
416
430
      {
417
431
        error= -1;
418
 
        goto err_with_placeholders;
 
432
        unlock_table_names(tables, NULL);
 
433
        LOCK_open.unlock();
 
434
        session->no_warnings_for_error= 0;
 
435
 
 
436
        return(error);
419
437
      }
420
438
    }
421
 
 
422
 
    TableIdentifier identifier(db, table->table_name);
423
439
    identifier.getPath();
424
440
 
425
441
    if (table_type == NULL && not plugin::StorageEngine::doesTableExist(*session, identifier))
447
463
    }
448
464
 
449
465
    if (error == 0 || (foreign_key_error == false))
450
 
        write_bin_log_drop_table(session, true, db, table->table_name);
 
466
    {
 
467
      transaction_services.dropTable(session, string(db), string(table->table_name), true);
 
468
    }
451
469
 
452
470
    if (error)
453
471
    {
460
478
    It's safe to unlock LOCK_open: we have an exclusive lock
461
479
    on the table name.
462
480
  */
463
 
  pthread_mutex_unlock(&LOCK_open);
 
481
  LOCK_open.unlock();
464
482
  error= 0;
465
483
  if (wrong_tables.length())
466
484
  {
474
492
    error= 1;
475
493
  }
476
494
 
477
 
  pthread_mutex_lock(&LOCK_open); /* final bit in rm table lock */
478
 
err_with_placeholders:
 
495
  LOCK_open.lock(); /* final bit in rm table lock */
479
496
  unlock_table_names(tables, NULL);
480
 
  pthread_mutex_unlock(&LOCK_open);
 
497
  LOCK_open.unlock();
481
498
  session->no_warnings_for_error= 0;
482
499
 
483
500
  return(error);
488
505
  session MUST be set when calling this function!
489
506
*/
490
507
 
491
 
static long mysql_rm_known_files(Session *session,
492
 
                                 SchemaIdentifier &schema_identifier,
493
 
                                 plugin::TableNameList &dropped_tables)
 
508
static long drop_tables_via_filenames(Session *session,
 
509
                                      SchemaIdentifier &schema_identifier,
 
510
                                      TableIdentifiers &dropped_tables)
494
511
{
495
512
  long deleted= 0;
496
513
  TableList *tot_list= NULL, **tot_list_next;
497
514
 
498
515
  tot_list_next= &tot_list;
499
516
 
500
 
  plugin::StorageEngine::getTableNames(*session, schema_identifier, dropped_tables);
 
517
  plugin::StorageEngine::getIdentifiers(*session, schema_identifier, dropped_tables);
501
518
 
502
 
  for (plugin::TableNameList::iterator it= dropped_tables.begin();
 
519
  for (TableIdentifiers::iterator it= dropped_tables.begin();
503
520
       it != dropped_tables.end();
504
521
       it++)
505
522
  {
509
526
    TableList *table_list=(TableList*)
510
527
      session->calloc(sizeof(*table_list) +
511
528
                      db_len + 1 +
512
 
                      (*it).length() + 1);
 
529
                      (*it).getTableName().length() + 1);
513
530
 
514
531
    if (not table_list)
515
532
      return -1;
516
533
 
517
534
    table_list->db= (char*) (table_list+1);
518
535
    table_list->table_name= strcpy(table_list->db, schema_identifier.getSchemaName().c_str()) + db_len + 1;
519
 
    filename_to_tablename((*it).c_str(), table_list->table_name,
520
 
                          (*it).size() + 1);
 
536
    TableIdentifier::filename_to_tablename((*it).getTableName().c_str(), table_list->table_name, (*it).getTableName().size() + 1);
521
537
    table_list->alias= table_list->table_name;  // If lower_case_table_names=2
522
 
    table_list->internal_tmp_table= (strncmp((*it).c_str(),
 
538
    table_list->setInternalTmpTable((strncmp((*it).getTableName().c_str(),
523
539
                                             TMP_FILE_PREFIX,
524
 
                                             strlen(TMP_FILE_PREFIX)) == 0);
 
540
                                             strlen(TMP_FILE_PREFIX)) == 0));
525
541
    /* Link into list */
526
542
    (*tot_list_next)= table_list;
527
543
    tot_list_next= &table_list->next_local;
617
633
    return true;
618
634
  }
619
635
 
620
 
  if (not check_db_name(schema_identifier))
 
636
  if (not check_db_name(session, schema_identifier))
621
637
  {
622
638
    my_error(ER_WRONG_DB_NAME, MYF(0), schema_identifier.getSQLPath().c_str());
623
639
 
674
690
      the previous database name, we should do it explicitly.
675
691
    */
676
692
 
677
 
    session->set_db(schema_identifier.getLower());
 
693
    session->set_db(schema_identifier.getSchemaName());
678
694
  }
679
695
}
680
696