~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/db.cc

  • Committer: Andrew Hutchings
  • Date: 2011-01-21 11:23:19 UTC
  • mto: (2100.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 2101.
  • Revision ID: andrew@linuxjedi.co.uk-20110121112319-nj1cvg0yt3nnf2rr
Add errors page to drizzle client docs
Add link to specific error in migration docs
Minor changes to migration docs

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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
16
 
17
17
/* create and drop of databases */
25
25
#include <string>
26
26
#include <fstream>
27
27
 
28
 
#include <drizzled/message/schema.pb.h>
29
28
#include "drizzled/error.h"
30
29
#include <drizzled/gettext.h>
31
30
#include <drizzled/my_hash.h>
44
43
#include "drizzled/pthread_globals.h"
45
44
#include "drizzled/charset.h"
46
45
 
 
46
#include <boost/thread/mutex.hpp>
 
47
 
47
48
#include "drizzled/internal/my_sys.h"
48
49
 
49
50
#define MAX_DROP_TABLE_Q_LEN      1024
53
54
namespace drizzled
54
55
{
55
56
 
56
 
static long mysql_rm_known_files(Session *session,
57
 
                                 SchemaIdentifier &schema_identifier,
58
 
                                 plugin::TableNameList &dropped_tables);
59
 
static void mysql_change_db_impl(Session *session);
60
 
static void mysql_change_db_impl(Session *session, SchemaIdentifier &schema_identifier);
 
57
static void change_db_impl(Session *session);
 
58
static void change_db_impl(Session *session, identifier::Schema &schema_identifier);
61
59
 
62
60
/*
63
61
  Create a database
64
62
 
65
63
  SYNOPSIS
66
 
  mysql_create_db()
 
64
  create_db()
67
65
  session               Thread handler
68
66
  db            Name of database to create
69
67
                Function assumes that this is already validated.
80
78
 
81
79
*/
82
80
 
83
 
bool mysql_create_db(Session *session, const message::Schema &schema_message, const bool is_if_not_exists)
 
81
bool create_db(Session *session, const message::Schema &schema_message, const bool is_if_not_exists)
84
82
{
85
83
  TransactionServices &transaction_services= TransactionServices::singleton();
86
84
  bool error= false;
87
85
 
88
86
  /*
89
87
    Do not create database if another thread is holding read lock.
90
 
    Wait for global read lock before acquiring LOCK_create_db.
 
88
    Wait for global read lock before acquiring session->catalog()->schemaLock().
91
89
    After wait_if_global_read_lock() we have protection against another
92
 
    global read lock. If we would acquire LOCK_create_db first,
 
90
    global read lock. If we would acquire session->catalog()->schemaLock() first,
93
91
    another thread could step in and get the global read lock before we
94
92
    reach wait_if_global_read_lock(). If this thread tries the same as we
95
 
    (admin a db), it would then go and wait on LOCK_create_db...
 
93
    (admin a db), it would then go and wait on session->catalog()->schemaLock()...
96
94
    Furthermore wait_if_global_read_lock() checks if the current thread
97
95
    has the global read lock and refuses the operation with
98
96
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
99
97
  */
100
 
  if (wait_if_global_read_lock(session, 0, 1))
 
98
  if (session->wait_if_global_read_lock(false, true))
101
99
  {
102
100
    return false;
103
101
  }
106
104
  assert(schema_message.has_collation());
107
105
 
108
106
  // @todo push this lock down into the engine
109
 
  pthread_mutex_lock(&LOCK_create_db);
 
107
  {
 
108
    boost::mutex::scoped_lock scopedLock(session->catalog().schemaLock());
110
109
 
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());
 
110
    // Check to see if it exists already.  
 
111
    identifier::Schema schema_identifier(schema_message.name());
 
112
    if (plugin::StorageEngine::doesSchemaExist(schema_identifier))
 
113
    {
 
114
      if (not is_if_not_exists)
 
115
      {
 
116
        my_error(ER_DB_CREATE_EXISTS, schema_identifier);
 
117
        error= true;
 
118
      }
 
119
      else
 
120
      {
 
121
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
122
                            ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
 
123
                            schema_message.name().c_str());
 
124
        session->my_ok();
 
125
      }
 
126
    }
 
127
    else if (not plugin::StorageEngine::createSchema(schema_message)) // Try to create it 
 
128
    {
 
129
      my_error(ER_CANT_CREATE_DB, MYF(0), schema_message.name().c_str(), errno);
118
130
      error= true;
119
131
    }
120
 
    else
 
132
    else // Created !
121
133
    {
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();
 
134
      transaction_services.createSchema(session, schema_message);
 
135
      session->my_ok(1);
126
136
    }
127
137
  }
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
 
  start_waiting_global_read_lock(session);
 
138
  session->startWaitingGlobalReadLock();
141
139
 
142
140
  return error;
143
141
}
145
143
 
146
144
/* db-name is already validated when we come here */
147
145
 
148
 
bool mysql_alter_db(Session *session, const message::Schema &schema_message)
 
146
bool alter_db(Session *session,
 
147
              const message::Schema &schema_message,
 
148
              const message::schema::shared_ptr &original_schema)
149
149
{
150
150
  TransactionServices &transaction_services= TransactionServices::singleton();
151
151
 
152
152
  /*
153
153
    Do not alter database if another thread is holding read lock.
154
 
    Wait for global read lock before acquiring LOCK_create_db.
 
154
    Wait for global read lock before acquiring session->catalog()->schemaLock().
155
155
    After wait_if_global_read_lock() we have protection against another
156
 
    global read lock. If we would acquire LOCK_create_db first,
 
156
    global read lock. If we would acquire session->catalog()->schemaLock() first,
157
157
    another thread could step in and get the global read lock before we
158
158
    reach wait_if_global_read_lock(). If this thread tries the same as we
159
 
    (admin a db), it would then go and wait on LOCK_create_db...
 
159
    (admin a db), it would then go and wait on session->catalog()->schemaLock()...
160
160
    Furthermore wait_if_global_read_lock() checks if the current thread
161
161
    has the global read lock and refuses the operation with
162
162
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
163
163
  */
164
 
  if ((wait_if_global_read_lock(session, 0, 1)))
165
 
    return false;
166
 
 
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);
190
 
  start_waiting_global_read_lock(session);
 
164
  if ((session->wait_if_global_read_lock(false, true)))
 
165
    return false;
 
166
 
 
167
  bool success;
 
168
  {
 
169
    boost::mutex::scoped_lock scopedLock(session->catalog().schemaLock());
 
170
 
 
171
    identifier::Schema schema_idenifier(schema_message.name());
 
172
    if (not plugin::StorageEngine::doesSchemaExist(schema_idenifier))
 
173
    {
 
174
      my_error(ER_SCHEMA_DOES_NOT_EXIST, schema_idenifier);
 
175
      return false;
 
176
    }
 
177
 
 
178
    /* Change options if current database is being altered. */
 
179
    success= plugin::StorageEngine::alterSchema(schema_message);
 
180
 
 
181
    if (success)
 
182
    {
 
183
      transaction_services.alterSchema(session, original_schema, schema_message);
 
184
      session->my_ok(1);
 
185
    }
 
186
    else
 
187
    {
 
188
      my_error(ER_ALTER_SCHEMA, schema_idenifier);
 
189
    }
 
190
  }
 
191
  session->startWaitingGlobalReadLock();
191
192
 
192
193
  return success;
193
194
}
197
198
  Drop all tables in a database and the database itself
198
199
 
199
200
  SYNOPSIS
200
 
    mysql_rm_db()
 
201
    rm_db()
201
202
    session                     Thread handle
202
203
    db                  Database name in the case given by user
203
204
                        It's already validated and set to lower case
210
211
    ERROR Error
211
212
*/
212
213
 
213
 
bool mysql_rm_db(Session *session, SchemaIdentifier &schema_identifier, const bool if_exists)
 
214
bool rm_db(Session *session, identifier::Schema &schema_identifier, const bool if_exists)
214
215
{
215
 
  long deleted=0;
216
 
  int error= false;
217
 
  plugin::TableNameList dropped_tables;
218
 
  message::Schema schema_proto;
 
216
  bool error= false;
219
217
 
220
218
  /*
221
219
    Do not drop database if another thread is holding read lock.
222
 
    Wait for global read lock before acquiring LOCK_create_db.
 
220
    Wait for global read lock before acquiring session->catalog()->schemaLock().
223
221
    After wait_if_global_read_lock() we have protection against another
224
 
    global read lock. If we would acquire LOCK_create_db first,
 
222
    global read lock. If we would acquire session->catalog()->schemaLock() first,
225
223
    another thread could step in and get the global read lock before we
226
224
    reach wait_if_global_read_lock(). If this thread tries the same as we
227
 
    (admin a db), it would then go and wait on LOCK_create_db...
 
225
    (admin a db), it would then go and wait on session->catalog()->schemaLock()...
228
226
    Furthermore wait_if_global_read_lock() checks if the current thread
229
227
    has the global read lock and refuses the operation with
230
228
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
231
229
  */
232
 
  if (wait_if_global_read_lock(session, 0, 1))
233
 
  {
234
 
    return -1;
235
 
  }
236
 
 
237
 
  // Lets delete the temporary tables first outside of locks.  
238
 
  set<string> set_of_names;
239
 
  session->doGetTableNames(schema_identifier, set_of_names);
240
 
 
241
 
  for (set<string>::iterator iter= set_of_names.begin(); iter != set_of_names.end(); iter++)
242
 
  {
243
 
    TableIdentifier identifier(schema_identifier, *iter, message::Table::TEMPORARY);
244
 
    Table *table= session->find_temporary_table(identifier);
245
 
    session->close_temporary_table(table);
246
 
  }
247
 
 
248
 
  pthread_mutex_lock(&LOCK_create_db);
249
 
 
250
 
 
251
 
  /* See if the schema exists */
252
 
  if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
253
 
  {
254
 
    if (if_exists)
 
230
  if (session->wait_if_global_read_lock(false, true))
 
231
  {
 
232
    return true;
 
233
  }
 
234
 
 
235
  do
 
236
  {
 
237
    boost::mutex::scoped_lock scopedLock(session->catalog().schemaLock());
 
238
 
 
239
    /* See if the schema exists */
 
240
    if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
255
241
    {
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());
 
242
      std::string path;
 
243
      schema_identifier.getSQLPath(path);
 
244
 
 
245
      if (if_exists)
 
246
      {
 
247
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
248
                            ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
 
249
                            path.c_str());
 
250
      }
 
251
      else
 
252
      {
 
253
        error= true;
 
254
        my_error(ER_DB_DROP_EXISTS, schema_identifier);
 
255
        break;
 
256
      }
259
257
    }
260
258
    else
261
259
    {
262
 
      error= -1;
263
 
      my_error(ER_DB_DROP_EXISTS, MYF(0), schema_identifier.getSQLPath().c_str());
264
 
      goto exit;
265
 
    }
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
 
    if (deleted >= 0)
277
 
    {
278
 
      error= 0;
279
 
    }
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++)
305
 
    {
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)
311
 
      {
312
 
        /* These DDL methods and logging protected with LOCK_create_db */
313
 
        transaction_services.rawStatement(session, query);
314
 
        query_pos= query_data_start;
315
 
      }
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
 
  }
329
 
 
330
 
exit:
 
260
      error= plugin::StorageEngine::dropSchema(*session, schema_identifier);
 
261
    }
 
262
 
 
263
  } while (0);
 
264
 
331
265
  /*
332
266
    If this database was the client's selected database, we silently
333
267
    change the client's selected database to nothing (to have an empty
334
268
    SELECT DATABASE() in the future). For this we free() session->db and set
335
269
    it to 0.
336
270
  */
337
 
  if (schema_identifier.compare(session->db))
338
 
    mysql_change_db_impl(session);
339
 
  pthread_mutex_unlock(&LOCK_create_db);
340
 
  start_waiting_global_read_lock(session);
 
271
  if (not error and schema_identifier.compare(*session->schema()))
 
272
    change_db_impl(session);
 
273
 
 
274
  session->startWaitingGlobalReadLock();
341
275
 
342
276
  return error;
343
277
}
344
278
 
345
 
 
346
 
static int rm_table_part2(Session *session, TableList *tables)
347
 
{
348
 
  TableList *table;
349
 
  String wrong_tables;
350
 
  int error= 0;
351
 
  bool foreign_key_error= false;
352
 
 
353
 
  pthread_mutex_lock(&LOCK_open); /* Part 2 of rm a table */
354
 
 
355
 
  /*
356
 
    If we have the table in the definition cache, we don't have to check the
357
 
    .frm cursor to find if the table is a normal table (not view) and what
358
 
    engine to use.
359
 
  */
360
 
 
361
 
  for (table= tables; table; table= table->next_local)
362
 
  {
363
 
    TableIdentifier identifier(table->db, table->table_name);
364
 
    TableShare *share;
365
 
    table->db_type= NULL;
366
 
    if ((share= TableShare::getShare(identifier)))
367
 
    {
368
 
      table->db_type= share->db_type();
369
 
    }
370
 
  }
371
 
 
372
 
  if (lock_table_names_exclusively(session, tables))
373
 
  {
374
 
    pthread_mutex_unlock(&LOCK_open);
375
 
    return 1;
376
 
  }
377
 
 
378
 
  /* Don't give warnings for not found errors, as we already generate notes */
379
 
  session->no_warnings_for_error= 1;
380
 
 
381
 
  for (table= tables; table; table= table->next_local)
382
 
  {
383
 
    char *db=table->db;
384
 
    plugin::StorageEngine *table_type;
385
 
 
386
 
    error= session->drop_temporary_table(table);
387
 
 
388
 
    switch (error) {
389
 
    case  0:
390
 
      // removed temporary table
391
 
      continue;
392
 
    case -1:
393
 
      error= 1;
394
 
      goto err_with_placeholders;
395
 
    default:
396
 
      // temporary table not found
397
 
      error= 0;
398
 
    }
399
 
 
400
 
    table_type= table->db_type;
401
 
 
402
 
    {
403
 
      Table *locked_table;
404
 
      abort_locked_tables(session, db, table->table_name);
405
 
      remove_table_from_cache(session, db, table->table_name,
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, db, table->table_name)))
413
 
        table->table= locked_table;
414
 
 
415
 
      if (session->killed)
416
 
      {
417
 
        error= -1;
418
 
        goto err_with_placeholders;
419
 
      }
420
 
    }
421
 
 
422
 
    TableIdentifier identifier(db, table->table_name);
423
 
    identifier.getPath();
424
 
 
425
 
    if (table_type == NULL && not plugin::StorageEngine::doesTableExist(*session, identifier))
426
 
    {
427
 
      // Table was not found on disk and table can't be created from engine
428
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
429
 
                          ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
430
 
                          table->table_name);
431
 
    }
432
 
    else
433
 
    {
434
 
      error= plugin::StorageEngine::dropTable(*session, identifier);
435
 
 
436
 
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
437
 
      {
438
 
        error= 0;
439
 
        session->clear_error();
440
 
      }
441
 
 
442
 
      if (error == HA_ERR_ROW_IS_REFERENCED)
443
 
      {
444
 
        /* the table is referenced by a foreign key constraint */
445
 
        foreign_key_error= true;
446
 
      }
447
 
    }
448
 
 
449
 
    if (error == 0 || (foreign_key_error == false))
450
 
        write_bin_log_drop_table(session, true, db, table->table_name);
451
 
 
452
 
    if (error)
453
 
    {
454
 
      if (wrong_tables.length())
455
 
        wrong_tables.append(',');
456
 
      wrong_tables.append(String(table->table_name,system_charset_info));
457
 
    }
458
 
  }
459
 
  /*
460
 
    It's safe to unlock LOCK_open: we have an exclusive lock
461
 
    on the table name.
462
 
  */
463
 
  pthread_mutex_unlock(&LOCK_open);
464
 
  error= 0;
465
 
  if (wrong_tables.length())
466
 
  {
467
 
    if (not foreign_key_error)
468
 
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
469
 
                      wrong_tables.c_ptr());
470
 
    else
471
 
    {
472
 
      my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
473
 
    }
474
 
    error= 1;
475
 
  }
476
 
 
477
 
  pthread_mutex_lock(&LOCK_open); /* final bit in rm table lock */
478
 
err_with_placeholders:
479
 
  unlock_table_names(tables, NULL);
480
 
  pthread_mutex_unlock(&LOCK_open);
481
 
  session->no_warnings_for_error= 0;
482
 
 
483
 
  return(error);
484
 
}
485
 
 
486
 
/*
487
 
  Removes files with known extensions plus.
488
 
  session MUST be set when calling this function!
489
 
*/
490
 
 
491
 
static long mysql_rm_known_files(Session *session,
492
 
                                 SchemaIdentifier &schema_identifier,
493
 
                                 plugin::TableNameList &dropped_tables)
494
 
{
495
 
  long deleted= 0;
496
 
  TableList *tot_list= NULL, **tot_list_next;
497
 
 
498
 
  tot_list_next= &tot_list;
499
 
 
500
 
  plugin::StorageEngine::getTableNames(*session, schema_identifier, dropped_tables);
501
 
 
502
 
  for (plugin::TableNameList::iterator it= dropped_tables.begin();
503
 
       it != dropped_tables.end();
504
 
       it++)
505
 
  {
506
 
    size_t db_len= schema_identifier.getSchemaName().size();
507
 
 
508
 
    /* Drop the table nicely */
509
 
    TableList *table_list=(TableList*)
510
 
      session->calloc(sizeof(*table_list) +
511
 
                      db_len + 1 +
512
 
                      (*it).length() + 1);
513
 
 
514
 
    if (not table_list)
515
 
      return -1;
516
 
 
517
 
    table_list->db= (char*) (table_list+1);
518
 
    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);
521
 
    table_list->alias= table_list->table_name;  // If lower_case_table_names=2
522
 
    table_list->internal_tmp_table= (strncmp((*it).c_str(),
523
 
                                             TMP_FILE_PREFIX,
524
 
                                             strlen(TMP_FILE_PREFIX)) == 0);
525
 
    /* Link into list */
526
 
    (*tot_list_next)= table_list;
527
 
    tot_list_next= &table_list->next_local;
528
 
    deleted++;
529
 
  }
530
 
  if (session->killed)
531
 
    return -1;
532
 
 
533
 
  if (tot_list)
534
 
  {
535
 
    if (rm_table_part2(session, tot_list))
536
 
      return -1;
537
 
  }
538
 
 
539
 
 
540
 
  if (not plugin::StorageEngine::dropSchema(schema_identifier))
541
 
  {
542
 
    my_error(ER_DROP_SCHEMA, MYF(0), schema_identifier.getSQLPath().c_str());
543
 
    return -1;
544
 
  }
545
 
 
546
 
  return deleted;
547
 
}
548
 
 
549
279
/**
550
280
  @brief Change the current database and its attributes unconditionally.
551
281
 
608
338
    @retval true  Error
609
339
*/
610
340
 
611
 
bool mysql_change_db(Session *session, SchemaIdentifier &schema_identifier)
 
341
bool change_db(Session *session, identifier::Schema &schema_identifier)
612
342
{
613
343
 
614
 
  if (not plugin::Authorization::isAuthorized(session->getSecurityContext(), schema_identifier))
 
344
  if (not plugin::Authorization::isAuthorized(session->user(), schema_identifier))
615
345
  {
616
346
    /* Error message is set in isAuthorized */
617
347
    return true;
618
348
  }
619
349
 
620
 
  if (not check_db_name(schema_identifier))
 
350
  if (not check_db_name(session, schema_identifier))
621
351
  {
622
 
    my_error(ER_WRONG_DB_NAME, MYF(0), schema_identifier.getSQLPath().c_str());
 
352
    std::string path;
 
353
    schema_identifier.getSQLPath(path);
 
354
    my_error(ER_WRONG_DB_NAME, schema_identifier);
623
355
 
624
356
    return true;
625
357
  }
626
358
 
627
359
  if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
628
360
  {
629
 
    /* Report an error and free new_db_file_name. */
630
 
 
631
 
    my_error(ER_BAD_DB_ERROR, MYF(0), schema_identifier.getSQLPath().c_str());
 
361
    my_error(ER_BAD_DB_ERROR, schema_identifier);
632
362
 
633
363
    /* The operation failed. */
634
364
 
635
365
    return true;
636
366
  }
637
367
 
638
 
  mysql_change_db_impl(session, schema_identifier);
 
368
  change_db_impl(session, schema_identifier);
639
369
 
640
370
  return false;
641
371
}
651
381
  @param new_db_charset Character set of the new database.
652
382
*/
653
383
 
654
 
static void mysql_change_db_impl(Session *session, SchemaIdentifier &schema_identifier)
 
384
static void change_db_impl(Session *session, identifier::Schema &schema_identifier)
655
385
{
656
386
  /* 1. Change current database in Session. */
657
387
 
674
404
      the previous database name, we should do it explicitly.
675
405
    */
676
406
 
677
 
    session->set_db(schema_identifier.getLower());
 
407
    session->set_db(schema_identifier.getSchemaName());
678
408
  }
679
409
}
680
410
 
681
 
static void mysql_change_db_impl(Session *session)
 
411
static void change_db_impl(Session *session)
682
412
{
683
413
  session->set_db(string());
684
414
}