~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/db.cc

  • Committer: Andrew Hutchings
  • Date: 2010-11-09 13:38:01 UTC
  • mto: (1919.1.2 trunk)
  • mto: This revision was merged to the branch mainline in revision 1920.
  • Revision ID: andrew@linuxjedi.co.uk-20101109133801-byjzsao76346395x
Add FLUSH GLOBAL STATUS; command
Clears the global status variables for the server

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 */
 
274
      LOCK_open.lock(); /* After deleting database, remove all cache entries related to schema */
278
275
      table::Cache::singleton().removeSchema(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
}
360
358
  int error= 0;
361
359
  bool foreign_key_error= false;
362
360
 
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;
 
361
  LOCK_open.lock(); /* Part 2 of rm a table */
 
362
 
 
363
  if (lock_table_names_exclusively(session, tables))
 
364
  {
 
365
    LOCK_open.unlock();
 
366
    return 1;
 
367
  }
 
368
 
 
369
  /* Don't give warnings for not found errors, as we already generate notes */
 
370
  session->no_warnings_for_error= 1;
 
371
 
 
372
  for (table= tables; table; table= table->next_local)
 
373
  {
 
374
    const char *db=table->getSchemaName();
 
375
    TableIdentifier identifier(table->getSchemaName(), table->getTableName());
 
376
 
 
377
    plugin::StorageEngine *table_type;
 
378
 
 
379
    error= session->drop_temporary_table(identifier);
 
380
 
 
381
    switch (error) {
 
382
    case  0:
 
383
      // removed temporary table
 
384
      continue;
 
385
    case -1:
 
386
      error= 1;
 
387
      unlock_table_names(tables, NULL);
 
388
      LOCK_open.unlock();
 
389
      session->no_warnings_for_error= 0;
 
390
 
 
391
      return(error);
 
392
    default:
 
393
      // temporary table not found
 
394
      error= 0;
370
395
    }
371
396
 
372
 
    /* Don't give warnings for not found errors, as we already generate notes */
373
 
    session->no_warnings_for_error= 1;
 
397
    table_type= table->getDbType();
374
398
 
375
 
    for (table= tables; table; table= table->next_local)
376
399
    {
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();
 
400
      Table *locked_table;
 
401
      abort_locked_tables(session, identifier);
 
402
      table::Cache::singleton().removeTable(session, identifier,
 
403
                                            RTFC_WAIT_OTHER_THREAD_FLAG |
 
404
                                            RTFC_CHECK_KILLED_FLAG);
 
405
      /*
 
406
        If the table was used in lock tables, remember it so that
 
407
        unlock_table_names can free it
 
408
      */
 
409
      if ((locked_table= drop_locked_tables(session, identifier)))
 
410
        table->table= locked_table;
 
411
 
 
412
      if (session->killed)
 
413
      {
 
414
        error= -1;
 
415
        unlock_table_names(tables, NULL);
 
416
        LOCK_open.unlock();
392
417
        session->no_warnings_for_error= 0;
393
418
 
394
419
        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();
 
420
      }
 
421
    }
 
422
    identifier.getPath();
 
423
 
 
424
    if (table_type == NULL && not plugin::StorageEngine::doesTableExist(*session, identifier))
 
425
    {
 
426
      // Table was not found on disk and table can't be created from engine
 
427
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
428
                          ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
 
429
                          table->getTableName());
 
430
    }
 
431
    else
 
432
    {
 
433
      error= plugin::StorageEngine::dropTable(*session, identifier);
 
434
 
 
435
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
 
436
      {
 
437
        error= 0;
 
438
        session->clear_error();
 
439
      }
 
440
 
 
441
      if (error == HA_ERR_ROW_IS_REFERENCED)
 
442
      {
 
443
        /* the table is referenced by a foreign key constraint */
 
444
        foreign_key_error= true;
 
445
      }
 
446
    }
 
447
 
 
448
    if (error == 0 || (foreign_key_error == false))
 
449
    {
 
450
      transaction_services.dropTable(session, string(db), string(table->getTableName()), true);
 
451
    }
 
452
 
 
453
    if (error)
 
454
    {
 
455
      if (wrong_tables.length())
 
456
        wrong_tables.append(',');
 
457
      wrong_tables.append(String(table->getTableName(),system_charset_info));
 
458
    }
468
459
  }
469
 
 
 
460
  /*
 
461
    It's safe to unlock LOCK_open: we have an exclusive lock
 
462
    on the table name.
 
463
  */
 
464
  LOCK_open.unlock();
470
465
  error= 0;
471
466
  if (wrong_tables.length())
472
467
  {
480
475
    error= 1;
481
476
  }
482
477
 
483
 
  {
484
 
    boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* final bit in rm table lock */
485
 
    tables->unlock_table_names();
486
 
  }
 
478
  LOCK_open.lock(); /* final bit in rm table lock */
 
479
  unlock_table_names(tables, NULL);
 
480
  LOCK_open.unlock();
487
481
  session->no_warnings_for_error= 0;
488
482
 
489
483
  return(error);
496
490
 
497
491
static long drop_tables_via_filenames(Session *session,
498
492
                                      SchemaIdentifier &schema_identifier,
499
 
                                      TableIdentifier::vector &dropped_tables)
 
493
                                      TableIdentifiers &dropped_tables)
500
494
{
501
495
  long deleted= 0;
502
496
  TableList *tot_list= NULL, **tot_list_next;
505
499
 
506
500
  plugin::StorageEngine::getIdentifiers(*session, schema_identifier, dropped_tables);
507
501
 
508
 
  for (TableIdentifier::vector::iterator it= dropped_tables.begin();
 
502
  for (TableIdentifiers::iterator it= dropped_tables.begin();
509
503
       it != dropped_tables.end();
510
504
       it++)
511
505
  {
532
526
    tot_list_next= &table_list->next_local;
533
527
    deleted++;
534
528
  }
535
 
  if (session->getKilled())
 
529
  if (session->killed)
536
530
    return -1;
537
531
 
538
532
  if (tot_list)
544
538
 
545
539
  if (not plugin::StorageEngine::dropSchema(schema_identifier))
546
540
  {
547
 
    std::string path;
548
 
    schema_identifier.getSQLPath(path);
549
 
    my_error(ER_DROP_SCHEMA, MYF(0), path.c_str());
550
 
 
 
541
    my_error(ER_DROP_SCHEMA, MYF(0), schema_identifier.getSQLPath().c_str());
551
542
    return -1;
552
543
  }
553
544
 
627
618
 
628
619
  if (not check_db_name(session, schema_identifier))
629
620
  {
630
 
    std::string path;
631
 
    schema_identifier.getSQLPath(path);
632
 
    my_error(ER_WRONG_DB_NAME, MYF(0), path.c_str());
 
621
    my_error(ER_WRONG_DB_NAME, MYF(0), schema_identifier.getSQLPath().c_str());
633
622
 
634
623
    return true;
635
624
  }
637
626
  if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
638
627
  {
639
628
    /* Report an error and free new_db_file_name. */
640
 
    std::string path;
641
 
    schema_identifier.getSQLPath(path);
642
629
 
643
 
    my_error(ER_BAD_DB_ERROR, MYF(0), path.c_str());
 
630
    my_error(ER_BAD_DB_ERROR, MYF(0), schema_identifier.getSQLPath().c_str());
644
631
 
645
632
    /* The operation failed. */
646
633