~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/db.cc

  • Committer: Brian Aker
  • Date: 2010-09-09 21:45:53 UTC
  • mto: (1756.1.2 build) (1768.2.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 1757.
  • Revision ID: brian@tangent.org-20100909214553-e687rmf5zk9478on
Force unique to just use memory and let the OS handle paging.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/* create and drop of databases */
59
59
 
60
60
static long drop_tables_via_filenames(Session *session,
61
61
                                 SchemaIdentifier &schema_identifier,
62
 
                                 TableIdentifier::vector &dropped_tables);
 
62
                                 TableIdentifiers &dropped_tables);
63
63
static void mysql_change_db_impl(Session *session);
64
64
static void mysql_change_db_impl(Session *session, SchemaIdentifier &schema_identifier);
65
65
 
101
101
    has the global read lock and refuses the operation with
102
102
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
103
103
  */
104
 
  if (session->wait_if_global_read_lock(false, true))
 
104
  if (wait_if_global_read_lock(session, 0, 1))
105
105
  {
106
106
    return false;
107
107
  }
141
141
      session->my_ok(1);
142
142
    }
143
143
  }
144
 
  session->startWaitingGlobalReadLock();
 
144
  start_waiting_global_read_lock(session);
145
145
 
146
146
  return error;
147
147
}
165
165
    has the global read lock and refuses the operation with
166
166
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
167
167
  */
168
 
  if ((session->wait_if_global_read_lock(false, true)))
 
168
  if ((wait_if_global_read_lock(session, 0, 1)))
169
169
    return false;
170
170
 
171
171
  bool success;
184
184
 
185
185
    if (success)
186
186
    {
187
 
      transaction_services.rawStatement(session, *session->getQueryString());
 
187
      transaction_services.rawStatement(session, session->getQueryString());
188
188
      session->my_ok(1);
189
189
    }
190
190
    else
192
192
      my_error(ER_ALTER_SCHEMA, MYF(0), schema_message.name().c_str());
193
193
    }
194
194
  }
195
 
  session->startWaitingGlobalReadLock();
 
195
  start_waiting_global_read_lock(session);
196
196
 
197
197
  return success;
198
198
}
219
219
{
220
220
  long deleted=0;
221
221
  int error= false;
222
 
  TableIdentifier::vector dropped_tables;
 
222
  TableIdentifiers dropped_tables;
223
223
  message::Schema schema_proto;
224
224
 
225
225
  /*
234
234
    has the global read lock and refuses the operation with
235
235
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
236
236
  */
237
 
  if (session->wait_if_global_read_lock(false, true))
 
237
  if (wait_if_global_read_lock(session, 0, 1))
238
238
  {
239
239
    return -1;
240
240
  }
256
256
    /* See if the schema exists */
257
257
    if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
258
258
    {
259
 
      std::string path;
260
 
      schema_identifier.getSQLPath(path);
261
 
 
262
259
      if (if_exists)
263
260
      {
264
261
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
265
262
                            ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
266
 
                            path.c_str());
 
263
                            schema_identifier.getSQLPath().c_str());
267
264
      }
268
265
      else
269
266
      {
270
267
        error= -1;
271
 
        my_error(ER_DB_DROP_EXISTS, MYF(0), path.c_str());
 
268
        my_error(ER_DB_DROP_EXISTS, MYF(0), schema_identifier.getSQLPath().c_str());
272
269
        goto exit;
273
270
      }
274
271
    }
275
272
    else
276
273
    {
277
 
      /* After deleting database, remove all cache entries related to schema */
278
 
      table::Cache::singleton().removeSchema(schema_identifier);
 
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();
279
277
 
280
278
 
281
279
      error= -1;
287
285
    }
288
286
    if (deleted >= 0)
289
287
    {
290
 
      assert(not session->getQueryString()->empty());
 
288
      assert(! session->query.empty());
291
289
 
292
290
      TransactionServices &transaction_services= TransactionServices::singleton();
293
291
      transaction_services.dropSchema(session, schema_identifier.getSchemaName());
306
304
      query_end= query + MAX_DROP_TABLE_Q_LEN;
307
305
 
308
306
      TransactionServices &transaction_services= TransactionServices::singleton();
309
 
      for (TableIdentifier::vector::iterator it= dropped_tables.begin();
 
307
      for (TableIdentifiers::iterator it= dropped_tables.begin();
310
308
           it != dropped_tables.end();
311
309
           it++)
312
310
      {
341
339
      SELECT DATABASE() in the future). For this we free() session->db and set
342
340
      it to 0.
343
341
    */
344
 
    if (schema_identifier.compare(*session->schema()))
 
342
    if (schema_identifier.compare(session->db))
345
343
      mysql_change_db_impl(session);
346
344
  }
347
345
 
348
 
  session->startWaitingGlobalReadLock();
 
346
  start_waiting_global_read_lock(session);
349
347
 
350
348
  return error;
351
349
}
353
351
 
354
352
static int rm_table_part2(Session *session, TableList *tables)
355
353
{
356
 
  TransactionServices &transaction_services= TransactionServices::singleton();
357
 
 
358
354
  TableList *table;
359
355
  String wrong_tables;
360
356
  int error= 0;
361
357
  bool foreign_key_error= false;
362
358
 
363
 
  {
364
 
    table::Cache::singleton().mutex().lock(); /* Part 2 of rm a table */
365
 
 
366
 
    if (session->lock_table_names_exclusively(tables))
367
 
    {
368
 
      table::Cache::singleton().mutex().unlock();
369
 
      return 1;
370
 
    }
371
 
 
372
 
    /* Don't give warnings for not found errors, as we already generate notes */
373
 
    session->no_warnings_for_error= 1;
374
 
 
375
 
    for (table= tables; table; table= table->next_local)
376
 
    {
377
 
      const char *db=table->getSchemaName();
378
 
      TableIdentifier identifier(table->getSchemaName(), table->getTableName());
379
 
 
380
 
      plugin::StorageEngine *table_type;
381
 
 
382
 
      error= session->drop_temporary_table(identifier);
383
 
 
384
 
      switch (error) {
385
 
      case  0:
386
 
        // removed temporary table
387
 
        continue;
388
 
      case -1:
389
 
        error= 1;
390
 
        tables->unlock_table_names();
391
 
        table::Cache::singleton().mutex().unlock();
 
359
  LOCK_open.lock(); /* Part 2 of rm a table */
 
360
 
 
361
  /*
 
362
    If we have the table in the definition cache, we don't have to check the
 
363
    .frm cursor to find if the table is a normal table (not view) and what
 
364
    engine to use.
 
365
  */
 
366
 
 
367
  for (table= tables; table; table= table->next_local)
 
368
  {
 
369
    TableIdentifier identifier(table->db, table->table_name);
 
370
    TableShare *share;
 
371
    table->setDbType(NULL);
 
372
    if ((share= TableShare::getShare(identifier)))
 
373
    {
 
374
      table->setDbType(share->db_type());
 
375
    }
 
376
  }
 
377
 
 
378
  if (lock_table_names_exclusively(session, tables))
 
379
  {
 
380
    LOCK_open.unlock();
 
381
    return 1;
 
382
  }
 
383
 
 
384
  /* Don't give warnings for not found errors, as we already generate notes */
 
385
  session->no_warnings_for_error= 1;
 
386
 
 
387
  for (table= tables; table; table= table->next_local)
 
388
  {
 
389
    char *db=table->db;
 
390
    plugin::StorageEngine *table_type;
 
391
 
 
392
    error= session->drop_temporary_table(table);
 
393
 
 
394
    switch (error) {
 
395
    case  0:
 
396
      // removed temporary table
 
397
      continue;
 
398
    case -1:
 
399
      error= 1;
 
400
      unlock_table_names(tables, NULL);
 
401
      LOCK_open.unlock();
 
402
      session->no_warnings_for_error= 0;
 
403
 
 
404
      return(error);
 
405
    default:
 
406
      // temporary table not found
 
407
      error= 0;
 
408
    }
 
409
 
 
410
    table_type= table->getDbType();
 
411
 
 
412
    TableIdentifier identifier(db, table->table_name);
 
413
 
 
414
    {
 
415
      Table *locked_table;
 
416
      abort_locked_tables(session, identifier);
 
417
      remove_table_from_cache(session, identifier,
 
418
                              RTFC_WAIT_OTHER_THREAD_FLAG |
 
419
                              RTFC_CHECK_KILLED_FLAG);
 
420
      /*
 
421
        If the table was used in lock tables, remember it so that
 
422
        unlock_table_names can free it
 
423
      */
 
424
      if ((locked_table= drop_locked_tables(session, identifier)))
 
425
        table->table= locked_table;
 
426
 
 
427
      if (session->killed)
 
428
      {
 
429
        error= -1;
 
430
        unlock_table_names(tables, NULL);
 
431
        LOCK_open.unlock();
392
432
        session->no_warnings_for_error= 0;
393
433
 
394
434
        return(error);
395
 
      default:
396
 
        // temporary table not found
397
 
        error= 0;
398
 
      }
399
 
 
400
 
      table_type= table->getDbType();
401
 
 
402
 
      {
403
 
        Table *locked_table;
404
 
        abort_locked_tables(session, identifier);
405
 
        table::Cache::singleton().removeTable(session, identifier,
406
 
                                              RTFC_WAIT_OTHER_THREAD_FLAG |
407
 
                                              RTFC_CHECK_KILLED_FLAG);
408
 
        /*
409
 
          If the table was used in lock tables, remember it so that
410
 
          unlock_table_names can free it
411
 
        */
412
 
        if ((locked_table= drop_locked_tables(session, identifier)))
413
 
          table->table= locked_table;
414
 
 
415
 
        if (session->getKilled())
416
 
        {
417
 
          error= -1;
418
 
          tables->unlock_table_names();
419
 
          table::Cache::singleton().mutex().unlock();
420
 
          session->no_warnings_for_error= 0;
421
 
 
422
 
          return(error);
423
 
        }
424
 
      }
425
 
      identifier.getPath();
426
 
 
427
 
      if (table_type == NULL && not plugin::StorageEngine::doesTableExist(*session, identifier))
428
 
      {
429
 
        // Table was not found on disk and table can't be created from engine
430
 
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
431
 
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
432
 
                            table->getTableName());
433
 
      }
434
 
      else
435
 
      {
436
 
        error= plugin::StorageEngine::dropTable(*session, identifier);
437
 
 
438
 
        if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
439
 
        {
440
 
          error= 0;
441
 
          session->clear_error();
442
 
        }
443
 
 
444
 
        if (error == HA_ERR_ROW_IS_REFERENCED)
445
 
        {
446
 
          /* the table is referenced by a foreign key constraint */
447
 
          foreign_key_error= true;
448
 
        }
449
 
      }
450
 
 
451
 
      if (error == 0 || (foreign_key_error == false))
452
 
      {
453
 
        transaction_services.dropTable(session, string(db), string(table->getTableName()), true);
454
 
      }
455
 
 
456
 
      if (error)
457
 
      {
458
 
        if (wrong_tables.length())
459
 
          wrong_tables.append(',');
460
 
        wrong_tables.append(String(table->getTableName(),system_charset_info));
461
 
      }
462
 
    }
463
 
    /*
464
 
      It's safe to unlock table::Cache::singleton().mutex(): we have an exclusive lock
465
 
      on the table name.
466
 
    */
467
 
    table::Cache::singleton().mutex().unlock();
 
435
      }
 
436
    }
 
437
    identifier.getPath();
 
438
 
 
439
    if (table_type == NULL && not plugin::StorageEngine::doesTableExist(*session, identifier))
 
440
    {
 
441
      // Table was not found on disk and table can't be created from engine
 
442
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
443
                          ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
 
444
                          table->table_name);
 
445
    }
 
446
    else
 
447
    {
 
448
      error= plugin::StorageEngine::dropTable(*session, identifier);
 
449
 
 
450
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
 
451
      {
 
452
        error= 0;
 
453
        session->clear_error();
 
454
      }
 
455
 
 
456
      if (error == HA_ERR_ROW_IS_REFERENCED)
 
457
      {
 
458
        /* the table is referenced by a foreign key constraint */
 
459
        foreign_key_error= true;
 
460
      }
 
461
    }
 
462
 
 
463
    if (error == 0 || (foreign_key_error == false))
 
464
        write_bin_log_drop_table(session, true, db, table->table_name);
 
465
 
 
466
    if (error)
 
467
    {
 
468
      if (wrong_tables.length())
 
469
        wrong_tables.append(',');
 
470
      wrong_tables.append(String(table->table_name,system_charset_info));
 
471
    }
468
472
  }
469
 
 
 
473
  /*
 
474
    It's safe to unlock LOCK_open: we have an exclusive lock
 
475
    on the table name.
 
476
  */
 
477
  LOCK_open.unlock();
470
478
  error= 0;
471
479
  if (wrong_tables.length())
472
480
  {
480
488
    error= 1;
481
489
  }
482
490
 
483
 
  {
484
 
    boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* final bit in rm table lock */
485
 
    tables->unlock_table_names();
486
 
  }
 
491
  LOCK_open.lock(); /* final bit in rm table lock */
 
492
  unlock_table_names(tables, NULL);
 
493
  LOCK_open.unlock();
487
494
  session->no_warnings_for_error= 0;
488
495
 
489
496
  return(error);
496
503
 
497
504
static long drop_tables_via_filenames(Session *session,
498
505
                                      SchemaIdentifier &schema_identifier,
499
 
                                      TableIdentifier::vector &dropped_tables)
 
506
                                      TableIdentifiers &dropped_tables)
500
507
{
501
508
  long deleted= 0;
502
509
  TableList *tot_list= NULL, **tot_list_next;
505
512
 
506
513
  plugin::StorageEngine::getIdentifiers(*session, schema_identifier, dropped_tables);
507
514
 
508
 
  for (TableIdentifier::vector::iterator it= dropped_tables.begin();
 
515
  for (TableIdentifiers::iterator it= dropped_tables.begin();
509
516
       it != dropped_tables.end();
510
517
       it++)
511
518
  {
520
527
    if (not table_list)
521
528
      return -1;
522
529
 
523
 
    table_list->setSchemaName((char*) (table_list+1));
524
 
    table_list->setTableName(strcpy((char*) (table_list+1), schema_identifier.getSchemaName().c_str()) + db_len + 1);
525
 
    TableIdentifier::filename_to_tablename((*it).getTableName().c_str(), const_cast<char *>(table_list->getTableName()), (*it).getTableName().size() + 1);
526
 
    table_list->alias= table_list->getTableName();  // If lower_case_table_names=2
 
530
    table_list->db= (char*) (table_list+1);
 
531
    table_list->table_name= strcpy(table_list->db, schema_identifier.getSchemaName().c_str()) + db_len + 1;
 
532
    TableIdentifier::filename_to_tablename((*it).getTableName().c_str(), table_list->table_name, (*it).getTableName().size() + 1);
 
533
    table_list->alias= table_list->table_name;  // If lower_case_table_names=2
527
534
    table_list->setInternalTmpTable((strncmp((*it).getTableName().c_str(),
528
535
                                             TMP_FILE_PREFIX,
529
536
                                             strlen(TMP_FILE_PREFIX)) == 0));
532
539
    tot_list_next= &table_list->next_local;
533
540
    deleted++;
534
541
  }
535
 
  if (session->getKilled())
 
542
  if (session->killed)
536
543
    return -1;
537
544
 
538
545
  if (tot_list)
544
551
 
545
552
  if (not plugin::StorageEngine::dropSchema(schema_identifier))
546
553
  {
547
 
    std::string path;
548
 
    schema_identifier.getSQLPath(path);
549
 
    my_error(ER_DROP_SCHEMA, MYF(0), path.c_str());
550
 
 
 
554
    my_error(ER_DROP_SCHEMA, MYF(0), schema_identifier.getSQLPath().c_str());
551
555
    return -1;
552
556
  }
553
557
 
627
631
 
628
632
  if (not check_db_name(session, schema_identifier))
629
633
  {
630
 
    std::string path;
631
 
    schema_identifier.getSQLPath(path);
632
 
    my_error(ER_WRONG_DB_NAME, MYF(0), path.c_str());
 
634
    my_error(ER_WRONG_DB_NAME, MYF(0), schema_identifier.getSQLPath().c_str());
633
635
 
634
636
    return true;
635
637
  }
637
639
  if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
638
640
  {
639
641
    /* Report an error and free new_db_file_name. */
640
 
    std::string path;
641
 
    schema_identifier.getSQLPath(path);
642
642
 
643
 
    my_error(ER_BAD_DB_ERROR, MYF(0), path.c_str());
 
643
    my_error(ER_BAD_DB_ERROR, MYF(0), schema_identifier.getSQLPath().c_str());
644
644
 
645
645
    /* The operation failed. */
646
646