~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/db.cc

  • Committer: Monty Taylor
  • Date: 2009-09-30 07:01:32 UTC
  • mto: This revision was merged to the branch mainline in revision 1184.
  • Revision ID: mordred@inaugust.com-20090930070132-b1ol1xu1rpajdddy
Small namespace cleanup.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
 
17
17
/* create and drop of databases */
18
 
#include <config.h>
 
18
#include <drizzled/global.h>
19
19
#include CSTDINT_H
20
20
#include CINTTYPES_H
21
21
#include <string>
22
22
#include <fstream>
23
 
#include <drizzled/serialize/serialize.h>
 
23
#include <drizzled/message/schema.pb.h>
24
24
using namespace std;
25
25
#include <drizzled/server_includes.h>
26
26
#include <mysys/mysys_err.h>
27
27
#include <mysys/my_dir.h>
28
 
#include "log.h"
29
28
#include <drizzled/error.h>
30
29
#include <drizzled/gettext.h>
31
 
 
32
 
 
 
30
#include <mysys/hash.h>
 
31
#include <drizzled/session.h>
 
32
#include <drizzled/db.h>
 
33
#include <drizzled/sql_base.h>
 
34
#include <drizzled/lock.h>
 
35
#include <drizzled/errmsg_print.h>
 
36
#include <drizzled/replication_services.h>
 
37
#include <drizzled/message/schema.pb.h>
 
38
 
 
39
using namespace drizzled;
 
40
 
 
41
#define MY_DB_OPT_FILE "db.opt"
33
42
#define MAX_DROP_TABLE_Q_LEN      1024
34
43
 
35
 
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NULL};
 
44
const char *del_exts[]= {".dfe", ".BAK", ".TMD",".opt", NULL};
36
45
static TYPELIB deletable_extentions=
37
46
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
38
47
 
39
48
static long mysql_rm_known_files(Session *session, MY_DIR *dirp,
40
 
                                 const char *db, const char *path, uint32_t level, 
 
49
                                 const char *db, const char *path,
41
50
                                 TableList **dropped_tables);
42
 
         
43
 
static bool rm_dir_w_symlink(const char *org_path, bool send_error);
44
 
static void mysql_change_db_impl(Session *session,
45
 
                                 LEX_STRING *new_db_name,
46
 
                                 const CHARSET_INFO * const new_db_charset);
47
 
 
48
 
 
49
 
/* Database lock hash */
50
 
HASH lock_db_cache;
51
 
pthread_mutex_t LOCK_lock_db;
52
 
int creating_database= 0;  // how many database locks are made
53
 
 
54
 
 
55
 
/* Structure for database lock */
56
 
typedef struct my_dblock_st
57
 
{
58
 
  char *name;        /* Database name        */
59
 
  uint32_t name_length;  /* Database length name */
60
 
} my_dblock_t;
61
 
 
62
 
 
63
 
/*
64
 
  lock_db key.
65
 
*/
66
 
 
67
 
extern "C" unsigned char* lock_db_get_key(my_dblock_t *, size_t *, bool not_used);
68
 
 
69
 
unsigned char* lock_db_get_key(my_dblock_t *ptr, size_t *length,
70
 
                       bool not_used __attribute__((unused)))
71
 
{
72
 
  *length= ptr->name_length;
73
 
  return (unsigned char*) ptr->name;
74
 
}
75
 
 
76
 
 
77
 
/*
78
 
  Free lock_db hash element.
79
 
*/
80
 
 
81
 
extern "C" void lock_db_free_element(void *ptr);
82
 
 
83
 
void lock_db_free_element(void *ptr)
84
 
{
85
 
  free(ptr);
86
 
}
87
 
 
88
 
 
89
 
/*
90
 
  Delete a database lock entry from hash.
91
 
*/
92
 
 
93
 
void lock_db_delete(const char *name, uint32_t length)
94
 
{
95
 
  my_dblock_t *opt;
96
 
  safe_mutex_assert_owner(&LOCK_lock_db);
97
 
  if ((opt= (my_dblock_t *)hash_search(&lock_db_cache,
98
 
                                       (const unsigned char*) name, length)))
99
 
    hash_delete(&lock_db_cache, (unsigned char*) opt);
100
 
}
101
 
 
102
 
 
103
 
/* Database options hash */
104
 
static HASH dboptions;
105
 
static bool dboptions_init= 0;
106
 
static rw_lock_t LOCK_dboptions;
107
 
 
108
 
/* Structure for database options */
109
 
typedef struct my_dbopt_st
110
 
{
111
 
  char *name;                   /* Database name                  */
112
 
  uint32_t name_length;         /* Database length name           */
113
 
  const CHARSET_INFO *charset;  /* Database default character set */
114
 
} my_dbopt_t;
115
 
 
116
 
 
117
 
/*
118
 
  Function we use in the creation of our hash to get key.
119
 
*/
120
 
 
121
 
extern "C" unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
122
 
                                    bool not_used);
123
 
 
124
 
unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
125
 
                         bool not_used __attribute__((unused)))
126
 
{
127
 
  *length= opt->name_length;
128
 
  return (unsigned char*) opt->name;
129
 
}
130
 
 
131
 
 
132
 
/*
133
 
  Helper function to write a query to binlog used by mysql_rm_db()
134
 
*/
135
 
 
136
 
static inline void write_to_binlog(Session *session, char *query, uint32_t q_len,
137
 
                                   char *db, uint32_t db_len)
138
 
{
139
 
  Query_log_event qinfo(session, query, q_len, 0, 0);
140
 
  qinfo.error_code= 0;
141
 
  qinfo.db= db;
142
 
  qinfo.db_len= db_len;
143
 
  mysql_bin_log.write(&qinfo);
144
 
}  
145
 
 
146
 
 
147
 
/*
148
 
  Function to free dboptions hash element
149
 
*/
150
 
 
151
 
extern "C" void free_dbopt(void *dbopt);
152
 
 
153
 
void free_dbopt(void *dbopt)
154
 
{
155
 
  free((unsigned char*) dbopt);
156
 
}
157
 
 
158
 
 
159
 
/* 
160
 
  Initialize database option hash and locked database hash.
161
 
 
162
 
  SYNOPSIS
163
 
    my_database_names()
164
 
 
165
 
  NOTES
166
 
    Must be called before any other database function is called.
167
 
 
168
 
  RETURN
169
 
    0   ok
170
 
    1   Fatal error
171
 
*/
172
 
 
173
 
bool my_database_names_init(void)
174
 
{
175
 
  bool error= false;
176
 
  (void) my_rwlock_init(&LOCK_dboptions, NULL);
177
 
  if (!dboptions_init)
178
 
  {
179
 
    dboptions_init= 1;
180
 
    error= hash_init(&dboptions, lower_case_table_names ? 
181
 
                     &my_charset_bin : system_charset_info,
182
 
                     32, 0, 0, (hash_get_key) dboptions_get_key,
183
 
                     free_dbopt,0) ||
184
 
           hash_init(&lock_db_cache, lower_case_table_names ? 
185
 
                     &my_charset_bin : system_charset_info,
186
 
                     32, 0, 0, (hash_get_key) lock_db_get_key,
187
 
                     lock_db_free_element,0);
188
 
 
189
 
  }
190
 
  return error;
191
 
}
192
 
 
193
 
 
194
 
 
195
 
/* 
196
 
  Free database option hash and locked databases hash.
197
 
*/
198
 
 
199
 
void my_database_names_free(void)
200
 
{
201
 
  if (dboptions_init)
202
 
  {
203
 
    dboptions_init= 0;
204
 
    hash_free(&dboptions);
205
 
    (void) rwlock_destroy(&LOCK_dboptions);
206
 
    hash_free(&lock_db_cache);
207
 
  }
208
 
}
209
 
 
210
 
 
211
 
/*
212
 
  Cleanup cached options
213
 
*/
214
 
 
215
 
void my_dbopt_cleanup(void)
216
 
{
217
 
  rw_wrlock(&LOCK_dboptions);
218
 
  hash_free(&dboptions);
219
 
  hash_init(&dboptions, lower_case_table_names ? 
220
 
            &my_charset_bin : system_charset_info,
221
 
            32, 0, 0, (hash_get_key) dboptions_get_key,
222
 
            free_dbopt,0);
223
 
  rw_unlock(&LOCK_dboptions);
224
 
}
225
 
 
226
 
 
227
 
/*
228
 
  Find database options in the hash.
229
 
  
230
 
  DESCRIPTION
231
 
    Search a database options in the hash, usings its path.
232
 
    Fills "create" on success.
233
 
  
234
 
  RETURN VALUES
235
 
    0 on success.
236
 
    1 on error.
237
 
*/
238
 
 
239
 
static bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
240
 
{
241
 
  my_dbopt_t *opt;
242
 
  uint32_t length;
243
 
  bool error= true;
244
 
  
245
 
  length= (uint) strlen(dbname);
246
 
  
247
 
  rw_rdlock(&LOCK_dboptions);
248
 
  if ((opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
249
 
  {
250
 
    create->default_table_charset= opt->charset;
251
 
    error= true;
252
 
  }
253
 
  rw_unlock(&LOCK_dboptions);
254
 
  return error;
255
 
}
256
 
 
257
 
 
258
 
/*
259
 
  Writes database options into the hash.
260
 
  
261
 
  DESCRIPTION
262
 
    Inserts database options into the hash, or updates
263
 
    options if they are already in the hash.
264
 
  
265
 
  RETURN VALUES
266
 
    0 on success.
267
 
    1 on error.
268
 
*/
269
 
 
270
 
static bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
271
 
{
272
 
  my_dbopt_t *opt;
273
 
  uint32_t length;
274
 
  bool error= false;
275
 
 
276
 
  length= (uint) strlen(dbname);
277
 
  
278
 
  rw_wrlock(&LOCK_dboptions);
279
 
  if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
280
 
  { 
281
 
    /* Options are not in the hash, insert them */
282
 
    char *tmp_name;
283
 
    if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
284
 
                         &opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
285
 
                         NULL))
286
 
    {
287
 
      error= true;
288
 
      goto end;
289
 
    }
290
 
    
291
 
    opt->name= tmp_name;
292
 
    my_stpcpy(opt->name, dbname);
293
 
    opt->name_length= length;
294
 
    
295
 
    if ((error= my_hash_insert(&dboptions, (unsigned char*) opt)))
296
 
    {
297
 
      free(opt);
298
 
      goto end;
299
 
    }
300
 
  }
301
 
 
302
 
  /* Update / write options in hash */
303
 
  opt->charset= create->default_table_charset;
304
 
 
305
 
end:
306
 
  rw_unlock(&LOCK_dboptions);  
307
 
  return(error);
308
 
}
309
 
 
310
 
 
311
 
/*
312
 
  Deletes database options from the hash.
313
 
*/
314
 
 
315
 
void del_dbopt(const char *path)
316
 
{
317
 
  my_dbopt_t *opt;
318
 
  rw_wrlock(&LOCK_dboptions);
319
 
  if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const unsigned char*) path,
320
 
                                      strlen(path))))
321
 
    hash_delete(&dboptions, (unsigned char*) opt);
322
 
  rw_unlock(&LOCK_dboptions);
323
 
}
324
 
 
325
 
 
326
 
/*
327
 
  Create database options file:
328
 
 
329
 
  DESCRIPTION
330
 
    Currently database default charset is only stored there.
331
 
 
332
 
  RETURN VALUES
333
 
  0     ok
334
 
  1     Could not create file or write to it.  Error sent through my_error()
335
 
*/
336
 
 
337
 
static bool write_db_opt(Session *session, const char *path, const char *name, HA_CREATE_INFO *create)
338
 
{
339
 
  bool error= true;
340
 
  drizzle::Schema db;
341
 
 
 
51
 
 
52
static void mysql_change_db_impl(Session *session, LEX_STRING *new_db_name);
 
53
            
 
54
 
 
55
/**
 
56
  Return default database collation.
 
57
 
 
58
  @param session     Thread context.
 
59
  @param db_name Database name.
 
60
 
 
61
  @return CHARSET_INFO object. The operation always return valid character
 
62
    set, even if the database does not exist.
 
63
*/
 
64
 
 
65
const CHARSET_INFO *get_default_db_collation(const char *db_name)
 
66
{
 
67
  message::Schema db;
 
68
 
 
69
  get_database_metadata(db_name, &db);
 
70
 
 
71
  /* If for some reason the db.opt file lacks a collation,
 
72
     we just return the default */
 
73
 
 
74
  if (db.has_collation())
 
75
  {
 
76
    const string buffer= db.collation();
 
77
    const CHARSET_INFO* cs= get_charset_by_name(buffer.c_str());
 
78
 
 
79
    if (!cs)
 
80
    {
 
81
      errmsg_printf(ERRMSG_LVL_ERROR,
 
82
                    _("Error while loading database options: '%s':"),db_name);
 
83
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
 
84
 
 
85
      return default_charset_info;
 
86
    }
 
87
 
 
88
    return cs;
 
89
  }
 
90
 
 
91
  return default_charset_info;
 
92
}
 
93
 
 
94
/* path is path to database, not schema file */
 
95
static int write_schema_file(Session *session,
 
96
                             const char *path, const char *name,
 
97
                             HA_CREATE_INFO *create)
 
98
{
 
99
  message::Schema db;
 
100
  char schema_file_tmp[FN_REFLEN];
 
101
  string schema_file(path);
 
102
 
 
103
  assert(path);
342
104
  assert(name);
 
105
  assert(create);
 
106
 
 
107
  snprintf(schema_file_tmp, FN_REFLEN, "%s%c%s.tmpXXXXXX", path, FN_LIBCHAR, MY_DB_OPT_FILE);
 
108
 
 
109
  schema_file.append(1, FN_LIBCHAR);
 
110
  schema_file.append(MY_DB_OPT_FILE);
 
111
 
 
112
  int fd= mkstemp(schema_file_tmp);
 
113
 
 
114
  if (fd==-1)
 
115
    return errno;
343
116
 
344
117
  if (!create->default_table_charset)
345
118
    create->default_table_charset= session->variables.collation_server;
346
119
 
347
 
  if (put_dbopt(path, create))
348
 
    return 1;
349
 
 
350
120
  db.set_name(name);
351
 
  db.set_characterset(create->default_table_charset->csname);
352
121
  db.set_collation(create->default_table_charset->name);
353
122
 
354
 
  fstream output(path, ios::out | ios::trunc | ios::binary);
355
 
  if (!db.SerializeToOstream(&output)) 
356
 
    error= false;
357
 
 
358
 
  return error;
359
 
}
360
 
 
361
 
 
362
 
/*
363
 
  Load database options file
364
 
 
365
 
  load_db_opt()
366
 
  path          Path for option file
367
 
  create        Where to store the read options
368
 
 
369
 
  DESCRIPTION
370
 
 
371
 
  RETURN VALUES
372
 
  0     File found
373
 
  1     No database file or could not open it
374
 
 
375
 
*/
376
 
 
377
 
bool load_db_opt(Session *session, const char *path, HA_CREATE_INFO *create)
378
 
{
379
 
  bool error=1;
380
 
  drizzle::Schema db;
381
 
  string buffer;
382
 
 
383
 
  memset(create, 0, sizeof(*create));
384
 
  create->default_table_charset= session->variables.collation_server;
385
 
 
386
 
  /* Check if options for this database are already in the hash */
387
 
  if (!get_dbopt(path, create))
388
 
    return(0);
389
 
 
390
 
  fstream input(path, ios::in | ios::binary);
391
 
  if (!input)
392
 
    goto err1;
393
 
  else if (!db.ParseFromIstream(&input))
394
 
    goto err1;
395
 
 
396
 
  buffer= db.characterset();
397
 
  if (!(create->default_table_charset= get_charset_by_csname(buffer.c_str(), MY_CS_PRIMARY, MYF(0))))
398
 
  {
399
 
    sql_print_error(_("Error while loading database options: '%s':"),path);
400
 
    sql_print_error(ER(ER_UNKNOWN_COLLATION), buffer.c_str());
401
 
    create->default_table_charset= default_charset_info;
402
 
  }
403
 
 
404
 
  buffer= db.collation();
405
 
  if (!(create->default_table_charset= get_charset_by_name(buffer.c_str(), MYF(0))))
406
 
  {
407
 
    sql_print_error(_("Error while loading database options: '%s':"),path);
408
 
    sql_print_error(ER(ER_UNKNOWN_COLLATION), buffer.c_str());
409
 
    create->default_table_charset= default_charset_info;
410
 
  }
411
 
 
412
 
  /*
413
 
    Put the loaded value into the hash.
414
 
    Note that another thread could've added the same
415
 
    entry to the hash after we called get_dbopt(),
416
 
    but it's not an error, as put_dbopt() takes this
417
 
    possibility into account.
418
 
  */
419
 
  error= put_dbopt(path, create);
420
 
 
421
 
err1:
422
 
  return(error);
423
 
}
424
 
 
425
 
 
426
 
/*
427
 
  Retrieve database options by name. Load database options file or fetch from
428
 
  cache.
429
 
 
430
 
  SYNOPSIS
431
 
    load_db_opt_by_name()
432
 
    db_name         Database name
433
 
    db_create_info  Where to store the database options
434
 
 
435
 
  DESCRIPTION
436
 
    load_db_opt_by_name() is a shortcut for load_db_opt().
437
 
 
438
 
  NOTE
439
 
    Although load_db_opt_by_name() (and load_db_opt()) returns status of
440
 
    the operation, it is useless usually and should be ignored. The problem
441
 
    is that there are 1) system databases ("mysql") and 2) virtual
442
 
    databases ("information_schema"), which do not contain options file.
443
 
    So, load_db_opt[_by_name]() returns false for these databases, but this
444
 
    is not an error.
445
 
 
446
 
    load_db_opt[_by_name]() clears db_create_info structure in any case, so
447
 
    even on failure it contains valid data. So, common use case is just
448
 
    call load_db_opt[_by_name]() without checking return value and use
449
 
    db_create_info right after that.
450
 
 
451
 
  RETURN VALUES (read NOTE!)
452
 
    false   Success
453
 
    true    Failed to retrieve options
454
 
*/
455
 
 
456
 
bool load_db_opt_by_name(Session *session, const char *db_name,
457
 
                         HA_CREATE_INFO *db_create_info)
 
123
  if (!db.SerializeToFileDescriptor(fd))
 
124
  {
 
125
    close(fd);
 
126
    unlink(schema_file_tmp);
 
127
    return -1;
 
128
  }
 
129
 
 
130
  if (rename(schema_file_tmp, schema_file.c_str()) == -1)
 
131
  {
 
132
    close(fd);
 
133
    return errno;
 
134
  }
 
135
 
 
136
  close(fd);
 
137
  return 0;
 
138
}
 
139
 
 
140
int get_database_metadata(const char *dbname, message::Schema *db)
458
141
{
459
142
  char db_opt_path[FN_REFLEN];
 
143
  size_t length;
460
144
 
461
145
  /*
462
146
    Pass an empty file name, and the database options file name as extension
463
147
    to avoid table name to file name encoding.
464
148
  */
465
 
  (void) build_table_filename(db_opt_path, sizeof(db_opt_path),
466
 
                              db_name, "", MY_DB_OPT_FILE, 0);
467
 
 
468
 
  return load_db_opt(session, db_opt_path, db_create_info);
469
 
}
470
 
 
471
 
 
472
 
/**
473
 
  Return default database collation.
474
 
 
475
 
  @param session     Thread context.
476
 
  @param db_name Database name.
477
 
 
478
 
  @return CHARSET_INFO object. The operation always return valid character
479
 
    set, even if the database does not exist.
480
 
*/
481
 
 
482
 
const CHARSET_INFO *get_default_db_collation(Session *session, const char *db_name)
483
 
{
484
 
  HA_CREATE_INFO db_info;
485
 
 
486
 
  if (session->db != NULL && strcmp(db_name, session->db) == 0)
487
 
    return session->db_charset;
488
 
 
489
 
  load_db_opt_by_name(session, db_name, &db_info);
490
 
 
491
 
  /*
492
 
    NOTE: even if load_db_opt_by_name() fails,
493
 
    db_info.default_table_charset contains valid character set
494
 
    (collation_server). We should not fail if load_db_opt_by_name() fails,
495
 
    because it is valid case. If a database has been created just by
496
 
    "mkdir", it does not contain db.opt file, but it is valid database.
497
 
  */
498
 
 
499
 
  return db_info.default_table_charset;
500
 
}
501
 
 
 
149
  length= build_table_filename(db_opt_path, sizeof(db_opt_path),
 
150
                              dbname, "", false);
 
151
  strcpy(db_opt_path + length, MY_DB_OPT_FILE);
 
152
 
 
153
  int fd= open(db_opt_path, O_RDONLY);
 
154
 
 
155
  if (fd == -1)
 
156
    return errno;
 
157
 
 
158
  if (!db->ParseFromFileDescriptor(fd))
 
159
  {
 
160
    close(fd);
 
161
    return -1;
 
162
  }
 
163
  close(fd);
 
164
 
 
165
  return 0;
 
166
}
502
167
 
503
168
/*
504
169
  Create a database
509
174
  db            Name of database to create
510
175
                Function assumes that this is already validated.
511
176
  create_info   Database create options (like character set)
512
 
  silent        Used by replication when internally creating a database.
513
 
                In this case the entry should not be logged.
514
177
 
515
178
  SIDE-EFFECTS
516
179
   1. Report back to client that command succeeded (my_ok)
517
180
   2. Report errors to client
518
181
   3. Log event to binary log
519
 
   (The 'silent' flags turns off 1 and 3.)
520
182
 
521
183
  RETURN VALUES
522
184
  false ok
524
186
 
525
187
*/
526
188
 
527
 
int mysql_create_db(Session *session, char *db, HA_CREATE_INFO *create_info, bool silent)
 
189
bool mysql_create_db(Session *session, const char *db, HA_CREATE_INFO *create_info)
528
190
{
 
191
  ReplicationServices &replication_services= ReplicationServices::singleton();
529
192
  char   path[FN_REFLEN+16];
530
 
  char   tmp_query[FN_REFLEN+16];
531
193
  long result= 1;
532
 
  int error= 0;
533
 
  struct stat stat_info;
 
194
  int error_erno;
 
195
  bool error= false;
534
196
  uint32_t create_options= create_info ? create_info->options : 0;
535
197
  uint32_t path_len;
536
198
 
537
199
  /* do not create 'information_schema' db */
538
 
  if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.str))
 
200
  if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.c_str()))
539
201
  {
540
202
    my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
541
203
    return(-1);
543
205
 
544
206
  /*
545
207
    Do not create database if another thread is holding read lock.
546
 
    Wait for global read lock before acquiring LOCK_mysql_create_db.
 
208
    Wait for global read lock before acquiring LOCK_create_db.
547
209
    After wait_if_global_read_lock() we have protection against another
548
 
    global read lock. If we would acquire LOCK_mysql_create_db first,
 
210
    global read lock. If we would acquire LOCK_create_db first,
549
211
    another thread could step in and get the global read lock before we
550
212
    reach wait_if_global_read_lock(). If this thread tries the same as we
551
 
    (admin a db), it would then go and wait on LOCK_mysql_create_db...
 
213
    (admin a db), it would then go and wait on LOCK_create_db...
552
214
    Furthermore wait_if_global_read_lock() checks if the current thread
553
215
    has the global read lock and refuses the operation with
554
216
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
555
217
  */
556
218
  if (wait_if_global_read_lock(session, 0, 1))
557
219
  {
558
 
    error= -1;
 
220
    error= true;
559
221
    goto exit2;
560
222
  }
561
223
 
562
 
  pthread_mutex_lock(&LOCK_mysql_create_db);
 
224
  pthread_mutex_lock(&LOCK_create_db);
563
225
 
564
226
  /* Check directory */
565
 
  path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
 
227
  path_len= build_table_filename(path, sizeof(path), db, "", false);
566
228
  path[path_len-1]= 0;                    // Remove last '/' from path
567
229
 
568
 
  if (!stat(path,&stat_info))
 
230
  if (mkdir(path,0777) == -1)
569
231
  {
570
 
    if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
 
232
    if (errno == EEXIST)
571
233
    {
572
 
      my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
573
 
      error= -1;
 
234
      if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
 
235
      {
 
236
        my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
 
237
        error= true;
 
238
        goto exit;
 
239
      }
 
240
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
241
                          ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
 
242
      session->my_ok();
 
243
      error= false;
574
244
      goto exit;
575
245
    }
576
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
577
 
                        ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
578
 
    if (!silent)
579
 
      my_ok(session);
580
 
    error= 0;
 
246
 
 
247
    my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
 
248
    error= true;
581
249
    goto exit;
582
250
  }
583
 
  else
584
 
  {
585
 
    if (errno != ENOENT)
586
 
    {
587
 
      my_error(EE_STAT, MYF(0), path, errno);
588
 
      goto exit;
589
 
    }
590
 
    if (my_mkdir(path,0777,MYF(0)) < 0)
591
 
    {
592
 
      my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
593
 
      error= -1;
594
 
      goto exit;
595
 
    }
596
 
  }
597
251
 
598
 
  path[path_len-1]= FN_LIBCHAR;
599
 
  strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
600
 
  if (write_db_opt(session, path, db, create_info))
 
252
  error_erno= write_schema_file(session, path, db, create_info);
 
253
  if (error_erno && error_erno != EEXIST)
601
254
  {
602
 
    /*
603
 
      Could not create options file.
604
 
      Restore things to beginning.
605
 
    */
606
 
    path[path_len]= 0;
607
255
    if (rmdir(path) >= 0)
608
256
    {
609
 
      error= -1;
 
257
      error= true;
610
258
      goto exit;
611
259
    }
612
 
    /*
613
 
      We come here when we managed to create the database, but not the option
614
 
      file.  In this case it's best to just continue as if nothing has
615
 
      happened.  (This is a very unlikely senario)
616
 
    */
617
 
  }
618
 
  
619
 
  if (!silent)
620
 
  {
621
 
    char *query;
622
 
    uint32_t query_length;
623
 
 
624
 
    if (!session->query)                                // Only in replication
625
 
    {
626
 
      query=         tmp_query;
627
 
      query_length= (uint) (strxmov(tmp_query,"create database `",
628
 
                                    db, "`", NULL) - tmp_query);
629
 
    }
630
 
    else
631
 
    {
632
 
      query=        session->query;
633
 
      query_length= session->query_length;
634
 
    }
635
 
 
636
 
    if (mysql_bin_log.is_open())
637
 
    {
638
 
      Query_log_event qinfo(session, query, query_length, 0, 
639
 
                            /* suppress_use */ true);
640
 
 
641
 
      /*
642
 
        Write should use the database being created as the "current
643
 
        database" and not the threads current database, which is the
644
 
        default. If we do not change the "current database" to the
645
 
        database being created, the CREATE statement will not be
646
 
        replicated when using --binlog-do-db to select databases to be
647
 
        replicated. 
648
 
 
649
 
        An example (--binlog-do-db=sisyfos):
650
 
       
651
 
          CREATE DATABASE bob;        # Not replicated
652
 
          USE bob;                    # 'bob' is the current database
653
 
          CREATE DATABASE sisyfos;    # Not replicated since 'bob' is
654
 
                                      # current database.
655
 
          USE sisyfos;                # Will give error on slave since
656
 
                                      # database does not exist.
657
 
      */
658
 
      qinfo.db     = db;
659
 
      qinfo.db_len = strlen(db);
660
 
 
661
 
      /* These DDL methods and logging protected with LOCK_mysql_create_db */
662
 
      mysql_bin_log.write(&qinfo);
663
 
    }
664
 
    my_ok(session, result);
665
 
  }
 
260
  }
 
261
  else if (error_erno)
 
262
    error= true;
 
263
 
 
264
  replication_services.rawStatement(session, session->query, session->query_length);
 
265
  session->my_ok(result);
666
266
 
667
267
exit:
668
 
  pthread_mutex_unlock(&LOCK_mysql_create_db);
 
268
  pthread_mutex_unlock(&LOCK_create_db);
669
269
  start_waiting_global_read_lock(session);
670
270
exit2:
671
 
  return(error);
 
271
  return error;
672
272
}
673
273
 
674
274
 
676
276
 
677
277
bool mysql_alter_db(Session *session, const char *db, HA_CREATE_INFO *create_info)
678
278
{
679
 
  char path[FN_REFLEN+16];
 
279
  ReplicationServices &replication_services= ReplicationServices::singleton();
680
280
  long result=1;
681
 
  int error= false;
 
281
  int error= 0;
 
282
  char   path[FN_REFLEN+16];
 
283
  uint32_t path_len;
682
284
 
683
285
  /*
684
286
    Do not alter database if another thread is holding read lock.
685
 
    Wait for global read lock before acquiring LOCK_mysql_create_db.
 
287
    Wait for global read lock before acquiring LOCK_create_db.
686
288
    After wait_if_global_read_lock() we have protection against another
687
 
    global read lock. If we would acquire LOCK_mysql_create_db first,
 
289
    global read lock. If we would acquire LOCK_create_db first,
688
290
    another thread could step in and get the global read lock before we
689
291
    reach wait_if_global_read_lock(). If this thread tries the same as we
690
 
    (admin a db), it would then go and wait on LOCK_mysql_create_db...
 
292
    (admin a db), it would then go and wait on LOCK_create_db...
691
293
    Furthermore wait_if_global_read_lock() checks if the current thread
692
294
    has the global read lock and refuses the operation with
693
295
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
694
296
  */
695
297
  if ((error=wait_if_global_read_lock(session,0,1)))
696
 
    goto exit2;
697
 
 
698
 
  pthread_mutex_lock(&LOCK_mysql_create_db);
699
 
 
700
 
  /* 
701
 
     Recreate db options file: /dbpath/.db.opt
702
 
     We pass MY_DB_OPT_FILE as "extension" to avoid
703
 
     "table name to file name" encoding.
704
 
  */
705
 
  build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0);
706
 
  if ((error=write_db_opt(session, path, db, create_info)))
707
298
    goto exit;
708
299
 
 
300
  pthread_mutex_lock(&LOCK_create_db);
 
301
 
709
302
  /* Change options if current database is being altered. */
710
 
 
711
 
  if (session->db && !strcmp(session->db,db))
712
 
  {
713
 
    session->db_charset= create_info->default_table_charset ?
714
 
                     create_info->default_table_charset :
715
 
                     session->variables.collation_server;
716
 
    session->variables.collation_database= session->db_charset;
717
 
  }
718
 
 
719
 
  if (mysql_bin_log.is_open())
720
 
  {
721
 
    Query_log_event qinfo(session, session->query, session->query_length, 0,
722
 
                          /* suppress_use */ true);
723
 
 
724
 
    /*
725
 
      Write should use the database being created as the "current
726
 
      database" and not the threads current database, which is the
727
 
      default.
728
 
    */
729
 
    qinfo.db     = db;
730
 
    qinfo.db_len = strlen(db);
731
 
 
732
 
    session->clear_error();
733
 
    /* These DDL methods and logging protected with LOCK_mysql_create_db */
734
 
    mysql_bin_log.write(&qinfo);
735
 
  }
736
 
  my_ok(session, result);
737
 
 
 
303
  path_len= build_table_filename(path, sizeof(path), db, "", false);
 
304
  path[path_len-1]= 0;                    // Remove last '/' from path
 
305
 
 
306
  error= write_schema_file(session, path, db, create_info);
 
307
  if (error && error != EEXIST)
 
308
  {
 
309
    /* TODO: find some witty way of getting back an error message */
 
310
    pthread_mutex_unlock(&LOCK_create_db);
 
311
    goto exit;
 
312
  }
 
313
 
 
314
  replication_services.rawStatement(session, session->getQueryString(), session->getQueryLength());
 
315
  session->my_ok(result);
 
316
 
 
317
  pthread_mutex_unlock(&LOCK_create_db);
 
318
  start_waiting_global_read_lock(session);
738
319
exit:
739
 
  pthread_mutex_unlock(&LOCK_mysql_create_db);
740
 
  start_waiting_global_read_lock(session);
741
 
exit2:
742
 
  return(error);
 
320
  return error ? true : false;
743
321
}
744
322
 
745
323
 
760
338
    ERROR Error
761
339
*/
762
340
 
763
 
bool mysql_rm_db(Session *session,char *db,bool if_exists, bool silent)
 
341
bool mysql_rm_db(Session *session,char *db,bool if_exists)
764
342
{
765
343
  long deleted=0;
766
344
  int error= false;
767
345
  char  path[FN_REFLEN+16];
768
346
  MY_DIR *dirp;
769
347
  uint32_t length;
770
 
  TableList* dropped_tables= 0;
 
348
  TableList *dropped_tables= NULL;
771
349
 
772
350
  if (db && (strcmp(db, "information_schema") == 0))
773
351
  {
774
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
775
 
    return(true);
 
352
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
 
353
    return true;
776
354
  }
777
355
 
778
356
  /*
779
357
    Do not drop database if another thread is holding read lock.
780
 
    Wait for global read lock before acquiring LOCK_mysql_create_db.
 
358
    Wait for global read lock before acquiring LOCK_create_db.
781
359
    After wait_if_global_read_lock() we have protection against another
782
 
    global read lock. If we would acquire LOCK_mysql_create_db first,
 
360
    global read lock. If we would acquire LOCK_create_db first,
783
361
    another thread could step in and get the global read lock before we
784
362
    reach wait_if_global_read_lock(). If this thread tries the same as we
785
 
    (admin a db), it would then go and wait on LOCK_mysql_create_db...
 
363
    (admin a db), it would then go and wait on LOCK_create_db...
786
364
    Furthermore wait_if_global_read_lock() checks if the current thread
787
365
    has the global read lock and refuses the operation with
788
366
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
793
371
    goto exit2;
794
372
  }
795
373
 
796
 
  pthread_mutex_lock(&LOCK_mysql_create_db);
797
 
 
798
 
  /*
799
 
    This statement will be replicated as a statement, even when using
800
 
    row-based replication. The flag will be reset at the end of the
801
 
    statement.
802
 
  */
803
 
  session->clear_current_stmt_binlog_row_based();
804
 
 
805
 
  length= build_table_filename(path, sizeof(path), db, "", "", 0);
806
 
  my_stpcpy(path+length, MY_DB_OPT_FILE);               // Append db option file name
807
 
  del_dbopt(path);                              // Remove dboption hash entry
 
374
  pthread_mutex_lock(&LOCK_create_db);
 
375
 
 
376
  length= build_table_filename(path, sizeof(path), db, "", false);
 
377
  strcpy(path+length, MY_DB_OPT_FILE);         // Append db option file name
 
378
  unlink(path);
808
379
  path[length]= '\0';                           // Remove file name
809
380
 
810
381
  /* See if the directory exists */
822
393
  }
823
394
  else
824
395
  {
825
 
    pthread_mutex_lock(&LOCK_open);
 
396
    pthread_mutex_lock(&LOCK_open); /* After deleting database, remove all cache entries related to schema */
826
397
    remove_db_from_cache(db);
827
398
    pthread_mutex_unlock(&LOCK_open);
828
399
 
829
 
    
 
400
 
830
401
    error= -1;
831
 
    if ((deleted= mysql_rm_known_files(session, dirp, db, path, 0,
832
 
                                       &dropped_tables)) >= 0)
 
402
    if ((deleted= mysql_rm_known_files(session, dirp, db, path, &dropped_tables)) >= 0)
833
403
    {
834
404
      ha_drop_database(path);
835
405
      error = 0;
836
406
    }
837
407
  }
838
 
  if (!silent && deleted>=0)
 
408
  if (deleted >= 0)
839
409
  {
840
410
    const char *query;
841
411
    uint32_t query_length;
843
413
    {
844
414
      /* The client used the old obsolete mysql_drop_db() call */
845
415
      query= path;
846
 
      query_length= (uint) (strxmov(path, "drop database `", db, "`",
847
 
                                     NULL) - path);
 
416
      query_length= sprintf(path, "drop database `%s`", db);
848
417
    }
849
418
    else
850
419
    {
851
 
      query =session->query;
 
420
      query= session->query;
852
421
      query_length= session->query_length;
853
422
    }
854
 
    if (mysql_bin_log.is_open())
855
 
    {
856
 
      Query_log_event qinfo(session, query, query_length, 0, 
857
 
                            /* suppress_use */ true);
858
 
      /*
859
 
        Write should use the database being created as the "current
860
 
        database" and not the threads current database, which is the
861
 
        default.
862
 
      */
863
 
      qinfo.db     = db;
864
 
      qinfo.db_len = strlen(db);
865
 
 
866
 
      session->clear_error();
867
 
      /* These DDL methods and logging protected with LOCK_mysql_create_db */
868
 
      mysql_bin_log.write(&qinfo);
869
 
    }
 
423
    ReplicationServices &replication_services= ReplicationServices::singleton();
 
424
    replication_services.rawStatement(session, session->getQueryString(), session->getQueryLength());
870
425
    session->clear_error();
871
426
    session->server_status|= SERVER_STATUS_DB_DROPPED;
872
 
    my_ok(session, (uint32_t) deleted);
 
427
    session->my_ok((uint32_t) deleted);
873
428
    session->server_status&= ~SERVER_STATUS_DB_DROPPED;
874
429
  }
875
 
  else if (mysql_bin_log.is_open())
 
430
  else
876
431
  {
877
432
    char *query, *query_pos, *query_end, *query_data_start;
878
433
    TableList *tbl;
880
435
 
881
436
    if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
882
437
      goto exit; /* not much else we can do */
883
 
    query_pos= query_data_start= my_stpcpy(query,"drop table ");
 
438
    query_pos= query_data_start= strcpy(query,"drop table ")+11;
884
439
    query_end= query + MAX_DROP_TABLE_Q_LEN;
885
440
    db_len= strlen(db);
886
441
 
 
442
    ReplicationServices &replication_services= ReplicationServices::singleton();
887
443
    for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
888
444
    {
889
445
      uint32_t tbl_name_len;
892
448
      tbl_name_len= strlen(tbl->table_name) + 3;
893
449
      if (query_pos + tbl_name_len + 1 >= query_end)
894
450
      {
895
 
        /* These DDL methods and logging protected with LOCK_mysql_create_db */
896
 
        write_to_binlog(session, query, query_pos -1 - query, db, db_len);
 
451
        /* These DDL methods and logging protected with LOCK_create_db */
 
452
        replication_services.rawStatement(session, query, (size_t) (query_pos -1 - query));
897
453
        query_pos= query_data_start;
898
454
      }
899
455
 
900
456
      *query_pos++ = '`';
901
 
      query_pos= my_stpcpy(query_pos,tbl->table_name);
 
457
      query_pos= strcpy(query_pos,tbl->table_name) + (tbl_name_len-3);
902
458
      *query_pos++ = '`';
903
459
      *query_pos++ = ',';
904
460
    }
905
461
 
906
462
    if (query_pos != query_data_start)
907
463
    {
908
 
      /* These DDL methods and logging protected with LOCK_mysql_create_db */
909
 
      write_to_binlog(session, query, query_pos -1 - query, db, db_len);
 
464
      /* These DDL methods and logging protected with LOCK_create_db */
 
465
      replication_services.rawStatement(session, query, (size_t) (query_pos -1 - query));
910
466
    }
911
467
  }
912
468
 
918
474
    it to 0.
919
475
  */
920
476
  if (session->db && !strcmp(session->db, db))
921
 
    mysql_change_db_impl(session, NULL, session->variables.collation_server);
922
 
  pthread_mutex_unlock(&LOCK_mysql_create_db);
 
477
    mysql_change_db_impl(session, NULL);
 
478
  pthread_mutex_unlock(&LOCK_create_db);
923
479
  start_waiting_global_read_lock(session);
924
480
exit2:
925
481
  return(error);
931
487
*/
932
488
 
933
489
static long mysql_rm_known_files(Session *session, MY_DIR *dirp, const char *db,
934
 
                                 const char *org_path, uint32_t level,
 
490
                                 const char *org_path,
935
491
                                 TableList **dropped_tables)
936
492
{
937
 
  long deleted=0;
938
 
  uint32_t found_other_files=0;
 
493
  long deleted= 0;
939
494
  char filePath[FN_REFLEN];
940
 
  TableList *tot_list=0, **tot_list_next;
 
495
  TableList *tot_list= NULL, **tot_list_next;
941
496
 
942
497
  tot_list_next= &tot_list;
943
498
 
944
 
  for (uint32_t idx=0 ;
945
 
       idx < (uint) dirp->number_off_files && !session->killed ;
 
499
  for (uint32_t idx= 0;
 
500
       idx < (uint32_t) dirp->number_off_files && !session->killed ;
946
501
       idx++)
947
502
  {
948
503
    FILEINFO *file=dirp->dir_entry+idx;
957
512
      extension= strchr(file->name, '\0');
958
513
    if (find_type(extension, &deletable_extentions,1+2) <= 0)
959
514
    {
960
 
      if (find_type(extension, ha_known_exts(),1+2) <= 0)
961
 
        found_other_files++;
 
515
      /*
 
516
        ass ass ass.
 
517
 
 
518
        strange checking for magic extensions that are then deleted if
 
519
        not reg_ext (i.e. .frm).
 
520
 
 
521
        and (previously) we'd err out on drop database if files not matching
 
522
        engine ha_known_exts() or deletable_extensions were present.
 
523
 
 
524
        presumably this was to avoid deleting other user data... except if that
 
525
        data happened to be in files ending in .BAK, .opt or .TMD. *fun*
 
526
       */
962
527
      continue;
963
528
    }
964
529
    /* just for safety we use files_charset_info */
965
530
    if (db && !my_strcasecmp(files_charset_info,
966
 
                             extension, reg_ext))
 
531
                             extension, ".dfe"))
967
532
    {
 
533
      uint32_t db_len= strlen(db);
 
534
 
968
535
      /* Drop the table nicely */
969
536
      *extension= 0;                    // Remove extension
970
537
      TableList *table_list=(TableList*)
971
 
                              session->calloc(sizeof(*table_list) + 
972
 
                                          strlen(db) + 1 +
973
 
                                          MYSQL50_TABLE_NAME_PREFIX_LENGTH + 
 
538
                              session->calloc(sizeof(*table_list) +
 
539
                                          db_len + 1 +
974
540
                                          strlen(file->name) + 1);
975
541
 
976
542
      if (!table_list)
977
543
        goto err;
978
544
      table_list->db= (char*) (table_list+1);
979
 
      table_list->table_name= my_stpcpy(table_list->db, db) + 1;
 
545
      table_list->table_name= strcpy(table_list->db, db) + db_len + 1;
980
546
      filename_to_tablename(file->name, table_list->table_name,
981
 
                            MYSQL50_TABLE_NAME_PREFIX_LENGTH +
982
547
                            strlen(file->name) + 1);
983
548
      table_list->alias= table_list->table_name;        // If lower_case_table_names=2
984
 
      table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix);
 
549
      table_list->internal_tmp_table= is_prefix(file->name, TMP_FILE_PREFIX);
985
550
      /* Link into list */
986
551
      (*tot_list_next)= table_list;
987
552
      tot_list_next= &table_list->next_local;
989
554
    }
990
555
    else
991
556
    {
992
 
      strxmov(filePath, org_path, "/", file->name, NULL);
 
557
      sprintf(filePath, "%s/%s", org_path, file->name);
993
558
      if (my_delete_with_symlink(filePath,MYF(MY_WME)))
994
559
      {
995
560
        goto err;
997
562
    }
998
563
  }
999
564
  if (session->killed ||
1000
 
      (tot_list && mysql_rm_table_part2(session, tot_list, 1, 0, 1, 1)))
 
565
      (tot_list && mysql_rm_table_part2(session, tot_list, 1, 0, 1)))
1001
566
    goto err;
1002
567
 
1003
 
  my_dirend(dirp);  
1004
 
  
 
568
  my_dirend(dirp);
 
569
 
1005
570
  if (dropped_tables)
1006
571
    *dropped_tables= tot_list;
1007
 
  
1008
 
  /*
1009
 
    If the directory is a symbolic link, remove the link first, then
1010
 
    remove the directory the symbolic link pointed at
1011
 
  */
1012
 
  if (found_other_files)
1013
 
  {
1014
 
    my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST);
1015
 
    return(-1);
1016
 
  }
1017
 
  else
1018
 
  {
1019
 
    /* Don't give errors if we can't delete 'RAID' directory */
1020
 
    if (rm_dir_w_symlink(org_path, level == 0))
1021
 
      return(-1);
1022
 
  }
1023
 
 
1024
 
  return(deleted);
 
572
 
 
573
  if (rmdir(org_path))
 
574
  {
 
575
    my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, errno);
 
576
    return -1;
 
577
  }
 
578
 
 
579
  return deleted;
1025
580
 
1026
581
err:
1027
582
  my_dirend(dirp);
1028
 
  return(-1);
1029
 
}
1030
 
 
1031
 
 
1032
 
/*
1033
 
  Remove directory with symlink
1034
 
 
1035
 
  SYNOPSIS
1036
 
    rm_dir_w_symlink()
1037
 
    org_path    path of derictory
1038
 
    send_error  send errors
1039
 
  RETURN
1040
 
    0 OK
1041
 
    1 ERROR
1042
 
*/
1043
 
 
1044
 
static bool rm_dir_w_symlink(const char *org_path, bool send_error)
1045
 
{
1046
 
  char tmp_path[FN_REFLEN], *pos;
1047
 
  char *path= tmp_path;
1048
 
  unpack_filename(tmp_path, org_path);
1049
 
#ifdef HAVE_READLINK
1050
 
  int error;
1051
 
  char tmp2_path[FN_REFLEN];
1052
 
 
1053
 
  /* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
1054
 
  pos= strchr(path, '\0');
1055
 
  if (pos > path && pos[-1] == FN_LIBCHAR)
1056
 
    *--pos=0;
1057
 
 
1058
 
  if ((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0)
1059
 
    return(1);
1060
 
  if (!error)
1061
 
  {
1062
 
    if (my_delete(path, MYF(send_error ? MY_WME : 0)))
1063
 
    {
1064
 
      return(send_error);
1065
 
    }
1066
 
    /* Delete directory symbolic link pointed at */
1067
 
    path= tmp2_path;
1068
 
  }
1069
 
#endif
1070
 
  /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
1071
 
  pos= strchr(path, '\0');
1072
 
 
1073
 
  if (pos > path && pos[-1] == FN_LIBCHAR)
1074
 
    *--pos=0;
1075
 
  if (rmdir(path) < 0 && send_error)
1076
 
  {
1077
 
    my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
1078
 
    return(1);
1079
 
  }
1080
 
  return(0);
1081
 
}
1082
 
 
 
583
  return -1;
 
584
}
1083
585
 
1084
586
/**
1085
587
  @brief Internal implementation: switch current database to a valid one.
1092
594
  @param new_db_charset Character set of the new database.
1093
595
*/
1094
596
 
1095
 
static void mysql_change_db_impl(Session *session,
1096
 
                                 LEX_STRING *new_db_name,
1097
 
                                 const CHARSET_INFO * const new_db_charset)
 
597
static void mysql_change_db_impl(Session *session, LEX_STRING *new_db_name)
1098
598
{
1099
599
  /* 1. Change current database in Session. */
1100
600
 
1107
607
 
1108
608
    session->set_db(NULL, 0);
1109
609
  }
1110
 
  else if (new_db_name == &INFORMATION_SCHEMA_NAME)
 
610
  else if (my_strcasecmp(system_charset_info, new_db_name->str,
 
611
                         INFORMATION_SCHEMA_NAME.c_str()) == 0)
1111
612
  {
1112
613
    /*
1113
614
      Here we must use Session::set_db(), because we want to copy
1114
615
      INFORMATION_SCHEMA_NAME constant.
1115
616
    */
1116
617
 
1117
 
    session->set_db(INFORMATION_SCHEMA_NAME.str, INFORMATION_SCHEMA_NAME.length);
 
618
    session->set_db(INFORMATION_SCHEMA_NAME.c_str(),
 
619
                    INFORMATION_SCHEMA_NAME.length());
1118
620
  }
1119
621
  else
1120
622
  {
1129
631
 
1130
632
    session->reset_db(new_db_name->str, new_db_name->length);
1131
633
  }
1132
 
 
1133
 
  /* 3. Update db-charset environment variables. */
1134
 
 
1135
 
  session->db_charset= new_db_charset;
1136
 
  session->variables.collation_database= new_db_charset;
1137
 
}
1138
 
 
1139
 
 
1140
 
 
1141
 
/**
1142
 
  Backup the current database name before switch.
1143
 
 
1144
 
  @param[in]      session             thread handle
1145
 
  @param[in, out] saved_db_name   IN: "str" points to a buffer where to store
1146
 
                                  the old database name, "length" contains the
1147
 
                                  buffer size
1148
 
                                  OUT: if the current (default) database is
1149
 
                                  not NULL, its name is copied to the
1150
 
                                  buffer pointed at by "str"
1151
 
                                  and "length" is updated accordingly.
1152
 
                                  Otherwise "str" is set to NULL and
1153
 
                                  "length" is set to 0.
1154
 
*/
1155
 
 
1156
 
static void backup_current_db_name(Session *session,
1157
 
                                   LEX_STRING *saved_db_name)
1158
 
{
1159
 
  if (!session->db)
1160
 
  {
1161
 
    /* No current (default) database selected. */
1162
 
 
1163
 
    saved_db_name->str= NULL;
1164
 
    saved_db_name->length= 0;
1165
 
  }
1166
 
  else
1167
 
  {
1168
 
    strmake(saved_db_name->str, session->db, saved_db_name->length - 1);
1169
 
    saved_db_name->length= session->db_length;
1170
 
  }
1171
 
}
1172
 
 
 
634
}
1173
635
 
1174
636
/**
1175
637
  Return true if db1_name is equal to db2_name, false otherwise.
1262
724
  LEX_STRING new_db_file_name;
1263
725
  const CHARSET_INFO *db_default_cl;
1264
726
 
1265
 
  if (new_db_name == NULL ||
1266
 
      new_db_name->length == 0)
1267
 
  {
1268
 
    if (force_switch)
1269
 
    {
1270
 
      /*
1271
 
        This can happen only if we're switching the current database back
1272
 
        after loading stored program. The thing is that loading of stored
1273
 
        program can happen when there is no current database.
1274
 
 
1275
 
        TODO: actually, new_db_name and new_db_name->str seem to be always
1276
 
        non-NULL. In case of stored program, new_db_name->str == "" and
1277
 
        new_db_name->length == 0.
1278
 
      */
1279
 
 
1280
 
      mysql_change_db_impl(session, NULL, session->variables.collation_server);
1281
 
 
1282
 
      return(false);
1283
 
    }
1284
 
    else
1285
 
    {
1286
 
      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1287
 
 
1288
 
      return(true);
1289
 
    }
1290
 
  }
 
727
  assert(new_db_name);
 
728
  assert(new_db_name->length);
1291
729
 
1292
730
  if (my_strcasecmp(system_charset_info, new_db_name->str,
1293
 
                    INFORMATION_SCHEMA_NAME.str) == 0)
 
731
                    INFORMATION_SCHEMA_NAME.c_str()) == 0)
1294
732
  {
1295
733
    /* Switch the current database to INFORMATION_SCHEMA. */
1296
 
 
1297
 
    mysql_change_db_impl(session, &INFORMATION_SCHEMA_NAME, system_charset_info);
1298
 
 
1299
 
    return(false);
 
734
    /* const_cast<> is safe here: mysql_change_db_impl does a copy */
 
735
    LEX_STRING is_name= { const_cast<char *>(INFORMATION_SCHEMA_NAME.c_str()),
 
736
                          INFORMATION_SCHEMA_NAME.length() };
 
737
    mysql_change_db_impl(session, &is_name);
 
738
 
 
739
    return false;
1300
740
  }
1301
741
 
1302
742
  /*
1306
746
    TODO: fix check_db_name().
1307
747
  */
1308
748
 
1309
 
  new_db_file_name.str= my_strndup(new_db_name->str, new_db_name->length,
1310
 
                                   MYF(MY_WME));
1311
749
  new_db_file_name.length= new_db_name->length;
1312
 
 
 
750
  new_db_file_name.str= (char *)malloc(new_db_name->length + 1);
1313
751
  if (new_db_file_name.str == NULL)
1314
 
    return(true);                             /* the error is set */
 
752
    return true;                             /* the error is set */
 
753
  memcpy(new_db_file_name.str, new_db_name->str, new_db_name->length);
 
754
  new_db_file_name.str[new_db_name->length]= 0;
 
755
 
1315
756
 
1316
757
  /*
1317
758
    NOTE: if check_db_name() fails, we should throw an error in any case,
1328
769
    free(new_db_file_name.str);
1329
770
 
1330
771
    if (force_switch)
1331
 
      mysql_change_db_impl(session, NULL, session->variables.collation_server);
 
772
      mysql_change_db_impl(session, NULL);
1332
773
 
1333
 
    return(true);
 
774
    return true;
1334
775
  }
1335
776
 
1336
777
  if (check_db_dir_existence(new_db_file_name.str))
1347
788
 
1348
789
      /* Change db to NULL. */
1349
790
 
1350
 
      mysql_change_db_impl(session, NULL, session->variables.collation_server);
 
791
      mysql_change_db_impl(session, NULL);
1351
792
 
1352
793
      /* The operation succeed. */
1353
794
 
1354
 
      return(false);
 
795
      return false;
1355
796
    }
1356
797
    else
1357
798
    {
1362
803
 
1363
804
      /* The operation failed. */
1364
805
 
1365
 
      return(true);
 
806
      return true;
1366
807
    }
1367
808
  }
1368
809
 
1371
812
    attributes and will be freed in Session::~Session().
1372
813
  */
1373
814
 
1374
 
  db_default_cl= get_default_db_collation(session, new_db_file_name.str);
1375
 
 
1376
 
  mysql_change_db_impl(session, &new_db_file_name, db_default_cl);
1377
 
 
1378
 
  return(false);
1379
 
}
1380
 
 
1381
 
 
1382
 
/**
1383
 
  Change the current database and its attributes if needed.
1384
 
 
1385
 
  @param          session             thread handle
1386
 
  @param          new_db_name     database name
1387
 
  @param[in, out] saved_db_name   IN: "str" points to a buffer where to store
1388
 
                                  the old database name, "length" contains the
1389
 
                                  buffer size
1390
 
                                  OUT: if the current (default) database is
1391
 
                                  not NULL, its name is copied to the
1392
 
                                  buffer pointed at by "str"
1393
 
                                  and "length" is updated accordingly.
1394
 
                                  Otherwise "str" is set to NULL and
1395
 
                                  "length" is set to 0.
1396
 
  @param          force_switch    @see mysql_change_db()
1397
 
  @param[out]     cur_db_changed  out-flag to indicate whether the current
1398
 
                                  database has been changed (valid only if
1399
 
                                  the function suceeded)
1400
 
*/
1401
 
 
1402
 
bool mysql_opt_change_db(Session *session,
1403
 
                         const LEX_STRING *new_db_name,
1404
 
                         LEX_STRING *saved_db_name,
1405
 
                         bool force_switch,
1406
 
                         bool *cur_db_changed)
1407
 
{
1408
 
  *cur_db_changed= !cmp_db_names(session->db, new_db_name->str);
1409
 
 
1410
 
  if (!*cur_db_changed)
1411
 
    return false;
1412
 
 
1413
 
  backup_current_db_name(session, saved_db_name);
1414
 
 
1415
 
  return mysql_change_db(session, new_db_name, force_switch);
1416
 
}
1417
 
 
 
815
  db_default_cl= get_default_db_collation(new_db_file_name.str);
 
816
 
 
817
  mysql_change_db_impl(session, &new_db_file_name);
 
818
 
 
819
  return false;
 
820
}
1418
821
 
1419
822
/*
1420
823
  Check if there is directory for the database name.
1434
837
  uint32_t db_dir_path_len;
1435
838
 
1436
839
  db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path),
1437
 
                                        db_name, "", "", 0);
 
840
                                        db_name, "", false);
1438
841
 
1439
842
  if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
1440
843
    db_dir_path[db_dir_path_len - 1]= 0;