~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/db.cc

  • Committer: Monty Taylor
  • Date: 2009-01-09 07:02:24 UTC
  • mto: (779.1.2 devel)
  • mto: This revision was merged to the branch mainline in revision 784.
  • Revision ID: mordred@inaugust.com-20090109070224-prwl5p52mfql3zfw
Split out readline.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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"
28
29
#include <drizzled/error.h>
29
30
#include <drizzled/gettext.h>
30
31
#include <mysys/hash.h>
33
34
#include <drizzled/sql_base.h>
34
35
#include <drizzled/lock.h>
35
36
#include <drizzled/errmsg_print.h>
36
 
#include <drizzled/replicator.h>
37
37
 
38
 
#define MY_DB_OPT_FILE "db.opt"
39
38
#define MAX_DROP_TABLE_Q_LEN      1024
40
39
 
41
 
const char *del_exts[]= {".dfe", ".BAK", ".TMD",".opt", NULL};
 
40
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NULL};
42
41
static TYPELIB deletable_extentions=
43
42
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
44
43
 
56
55
/* Database lock hash */
57
56
HASH lock_db_cache;
58
57
pthread_mutex_t LOCK_lock_db;
59
 
bool dbcache_init= false;
60
58
int creating_database= 0;  // how many database locks are made
61
59
 
62
60
 
75
73
extern "C" unsigned char* lock_db_get_key(my_dblock_t *, size_t *, bool not_used);
76
74
 
77
75
unsigned char* lock_db_get_key(my_dblock_t *ptr, size_t *length,
78
 
                       bool )
 
76
                       bool not_used __attribute__((unused)))
79
77
{
80
78
  *length= ptr->name_length;
81
79
  return (unsigned char*) ptr->name;
107
105
    hash_delete(&lock_db_cache, (unsigned char*) opt);
108
106
}
109
107
 
 
108
 
 
109
/* Database options hash */
 
110
static HASH dboptions;
 
111
static bool dboptions_init= 0;
 
112
static pthread_rwlock_t LOCK_dboptions;
 
113
 
 
114
/* Structure for database options */
 
115
typedef struct my_dbopt_st
 
116
{
 
117
  char *name;                   /* Database name                  */
 
118
  uint32_t name_length;         /* Database length name           */
 
119
  const CHARSET_INFO *charset;  /* Database default character set */
 
120
} my_dbopt_t;
 
121
 
 
122
 
 
123
/*
 
124
  Function we use in the creation of our hash to get key.
 
125
*/
 
126
 
 
127
extern "C" unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
 
128
                                    bool not_used);
 
129
 
 
130
unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
 
131
                         bool not_used __attribute__((unused)))
 
132
{
 
133
  *length= opt->name_length;
 
134
  return (unsigned char*) opt->name;
 
135
}
 
136
 
 
137
 
110
138
/*
111
139
  Helper function to write a query to binlog used by mysql_rm_db()
112
140
*/
113
141
 
114
 
static inline void write_to_binlog(Session *session, char *query, uint32_t query_length, char *, uint32_t)
115
 
{
116
 
  (void)replicator_statement(session, query, query_length);
117
 
}
 
142
static inline void write_to_binlog(Session *session, char *query, uint32_t q_len,
 
143
                                   char *db, uint32_t db_len)
 
144
{
 
145
  Query_log_event qinfo(session, query, q_len, 0, 0);
 
146
  qinfo.error_code= 0;
 
147
  qinfo.db= db;
 
148
  qinfo.db_len= db_len;
 
149
  drizzle_bin_log.write(&qinfo);
 
150
}
 
151
 
 
152
 
 
153
/*
 
154
  Function to free dboptions hash element
 
155
*/
 
156
 
 
157
extern "C" void free_dbopt(void *dbopt);
 
158
 
 
159
void free_dbopt(void *dbopt)
 
160
{
 
161
  free((unsigned char*) dbopt);
 
162
}
 
163
 
118
164
 
119
165
/*
120
166
  Initialize database option hash and locked database hash.
133
179
bool my_database_names_init(void)
134
180
{
135
181
  bool error= false;
136
 
  if (!dbcache_init)
 
182
  (void) pthread_rwlock_init(&LOCK_dboptions, NULL);
 
183
  if (!dboptions_init)
137
184
  {
138
 
    dbcache_init= true;
139
 
    error= hash_init(&lock_db_cache, lower_case_table_names ?
 
185
    dboptions_init= 1;
 
186
    error= hash_init(&dboptions, lower_case_table_names ?
 
187
                     &my_charset_bin : system_charset_info,
 
188
                     32, 0, 0, (hash_get_key) dboptions_get_key,
 
189
                     free_dbopt,0) ||
 
190
           hash_init(&lock_db_cache, lower_case_table_names ?
140
191
                     &my_charset_bin : system_charset_info,
141
192
                     32, 0, 0, (hash_get_key) lock_db_get_key,
142
193
                     lock_db_free_element,0);
145
196
  return error;
146
197
}
147
198
 
148
 
/**
149
 
  Return default database collation.
150
 
 
151
 
  @param session     Thread context.
152
 
  @param db_name Database name.
153
 
 
154
 
  @return CHARSET_INFO object. The operation always return valid character
155
 
    set, even if the database does not exist.
156
 
*/
157
 
 
158
 
const CHARSET_INFO *get_default_db_collation(Session *session, const char *db_name)
159
 
{
160
 
  HA_CREATE_INFO db_info;
161
 
 
162
 
  if (session->db != NULL && strcmp(db_name, session->db) == 0)
163
 
    return session->db_charset;
164
 
 
165
 
  /*
166
 
    db_info.default_table_charset contains valid character set
167
 
    (collation_server).
168
 
  */
169
 
 
170
 
  load_db_opt_by_name(session, db_name, &db_info);
171
 
 
172
 
  return db_info.default_table_charset;
173
 
}
174
 
 
175
 
/* path is path to database, not schema file */
176
 
static int write_schema_file(Session *session,
177
 
                             const char *path, const char *name,
178
 
                             HA_CREATE_INFO *create)
179
 
{
 
199
 
 
200
 
 
201
/*
 
202
  Free database option hash and locked databases hash.
 
203
*/
 
204
 
 
205
void my_database_names_free(void)
 
206
{
 
207
  if (dboptions_init)
 
208
  {
 
209
    dboptions_init= 0;
 
210
    hash_free(&dboptions);
 
211
    (void) pthread_rwlock_destroy(&LOCK_dboptions);
 
212
    hash_free(&lock_db_cache);
 
213
  }
 
214
}
 
215
 
 
216
 
 
217
/*
 
218
  Cleanup cached options
 
219
*/
 
220
 
 
221
void my_dbopt_cleanup(void)
 
222
{
 
223
  pthread_rwlock_wrlock(&LOCK_dboptions);
 
224
  hash_free(&dboptions);
 
225
  hash_init(&dboptions, lower_case_table_names ?
 
226
            &my_charset_bin : system_charset_info,
 
227
            32, 0, 0, (hash_get_key) dboptions_get_key,
 
228
            free_dbopt,0);
 
229
  pthread_rwlock_unlock(&LOCK_dboptions);
 
230
}
 
231
 
 
232
 
 
233
/*
 
234
  Find database options in the hash.
 
235
 
 
236
  DESCRIPTION
 
237
    Search a database options in the hash, usings its path.
 
238
    Fills "create" on success.
 
239
 
 
240
  RETURN VALUES
 
241
    0 on success.
 
242
    1 on error.
 
243
*/
 
244
 
 
245
static bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
 
246
{
 
247
  my_dbopt_t *opt;
 
248
  uint32_t length;
 
249
  bool error= true;
 
250
 
 
251
  length= (uint) strlen(dbname);
 
252
 
 
253
  pthread_rwlock_rdlock(&LOCK_dboptions);
 
254
  if ((opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
 
255
  {
 
256
    create->default_table_charset= opt->charset;
 
257
    error= true;
 
258
  }
 
259
  pthread_rwlock_unlock(&LOCK_dboptions);
 
260
  return error;
 
261
}
 
262
 
 
263
 
 
264
/*
 
265
  Writes database options into the hash.
 
266
 
 
267
  DESCRIPTION
 
268
    Inserts database options into the hash, or updates
 
269
    options if they are already in the hash.
 
270
 
 
271
  RETURN VALUES
 
272
    0 on success.
 
273
    1 on error.
 
274
*/
 
275
 
 
276
static bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
 
277
{
 
278
  my_dbopt_t *opt;
 
279
  uint32_t length;
 
280
  bool error= false;
 
281
 
 
282
  length= (uint) strlen(dbname);
 
283
 
 
284
  pthread_rwlock_wrlock(&LOCK_dboptions);
 
285
  if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
 
286
  {
 
287
    /* Options are not in the hash, insert them */
 
288
    char *tmp_name;
 
289
    if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
 
290
                         &opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
 
291
                         NULL))
 
292
    {
 
293
      error= true;
 
294
      goto end;
 
295
    }
 
296
 
 
297
    opt->name= tmp_name;
 
298
    strcpy(opt->name, dbname);
 
299
    opt->name_length= length;
 
300
 
 
301
    if ((error= my_hash_insert(&dboptions, (unsigned char*) opt)))
 
302
    {
 
303
      free(opt);
 
304
      goto end;
 
305
    }
 
306
  }
 
307
 
 
308
  /* Update / write options in hash */
 
309
  opt->charset= create->default_table_charset;
 
310
 
 
311
end:
 
312
  pthread_rwlock_unlock(&LOCK_dboptions);
 
313
  return(error);
 
314
}
 
315
 
 
316
 
 
317
/*
 
318
  Deletes database options from the hash.
 
319
*/
 
320
 
 
321
void del_dbopt(const char *path)
 
322
{
 
323
  my_dbopt_t *opt;
 
324
  pthread_rwlock_wrlock(&LOCK_dboptions);
 
325
  if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const unsigned char*) path,
 
326
                                      strlen(path))))
 
327
    hash_delete(&dboptions, (unsigned char*) opt);
 
328
  pthread_rwlock_unlock(&LOCK_dboptions);
 
329
}
 
330
 
 
331
 
 
332
/*
 
333
  Create database options file:
 
334
 
 
335
  DESCRIPTION
 
336
    Currently database default charset is only stored there.
 
337
 
 
338
  RETURN VALUES
 
339
  0     ok
 
340
  1     Could not create file or write to it.  Error sent through my_error()
 
341
*/
 
342
 
 
343
static bool write_db_opt(Session *session, const char *path, const char *name, HA_CREATE_INFO *create)
 
344
{
 
345
  bool error= true;
180
346
  drizzle::Schema db;
181
 
  char schema_file_tmp[FN_REFLEN];
182
 
  string schema_file(path);
183
347
 
184
 
  assert(path);
185
348
  assert(name);
186
 
  assert(create);
187
 
 
188
 
  snprintf(schema_file_tmp, FN_REFLEN, "%s%c%s.tmpXXXXXX", path, FN_LIBCHAR, MY_DB_OPT_FILE);
189
 
 
190
 
  schema_file.append(1, FN_LIBCHAR);
191
 
  schema_file.append(MY_DB_OPT_FILE);
192
 
 
193
 
  int fd= mkstemp(schema_file_tmp);
194
 
 
195
 
  if (fd==-1)
196
 
    return errno;
197
349
 
198
350
  if (!create->default_table_charset)
199
351
    create->default_table_charset= session->variables.collation_server;
200
352
 
 
353
  if (put_dbopt(path, create))
 
354
    return 1;
 
355
 
201
356
  db.set_name(name);
 
357
  db.set_characterset(create->default_table_charset->csname);
202
358
  db.set_collation(create->default_table_charset->name);
203
359
 
204
 
  if (!db.SerializeToFileDescriptor(fd))
205
 
  {
206
 
    close(fd);
207
 
    unlink(schema_file_tmp);
208
 
    return -1;
209
 
  }
210
 
 
211
 
  if (rename(schema_file_tmp, schema_file.c_str()) == -1)
212
 
  {
213
 
    close(fd);
214
 
    return errno;
215
 
  }
216
 
 
217
 
  close(fd);
218
 
  return 0;
 
360
  fstream output(path, ios::out | ios::trunc | ios::binary);
 
361
  if (!db.SerializeToOstream(&output))
 
362
    error= false;
 
363
 
 
364
  return error;
219
365
}
220
366
 
221
 
int load_db_opt(Session *session, const char *path, HA_CREATE_INFO *create)
 
367
 
 
368
/*
 
369
  Load database options file
 
370
 
 
371
  load_db_opt()
 
372
  path          Path for option file
 
373
  create        Where to store the read options
 
374
 
 
375
  DESCRIPTION
 
376
 
 
377
  RETURN VALUES
 
378
  0     File found
 
379
  1     No database file or could not open it
 
380
 
 
381
*/
 
382
 
 
383
bool load_db_opt(Session *session, const char *path, HA_CREATE_INFO *create)
222
384
{
 
385
  bool error=1;
223
386
  drizzle::Schema db;
224
387
  string buffer;
225
388
 
226
389
  memset(create, 0, sizeof(*create));
227
390
  create->default_table_charset= session->variables.collation_server;
228
391
 
229
 
  int fd= open(path, O_RDONLY);
230
 
 
231
 
  if (fd == -1)
232
 
    return errno;
233
 
 
234
 
  if (!db.ParseFromFileDescriptor(fd))
 
392
  /* Check if options for this database are already in the hash */
 
393
  if (!get_dbopt(path, create))
 
394
    return(0);
 
395
 
 
396
  fstream input(path, ios::in | ios::binary);
 
397
  if (!input)
 
398
    goto err1;
 
399
  else if (!db.ParseFromIstream(&input))
 
400
    goto err1;
 
401
 
 
402
  buffer= db.characterset();
 
403
  if (!(create->default_table_charset= get_charset_by_csname(buffer.c_str(), MY_CS_PRIMARY, MYF(0))))
235
404
  {
236
 
    close(fd);
237
 
    return -1;
 
405
    errmsg_printf(ERRMSG_LVL_ERROR, _("Error while loading database options: '%s':"),path);
 
406
    errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
 
407
    create->default_table_charset= default_charset_info;
238
408
  }
239
 
  close(fd);
240
409
 
241
410
  buffer= db.collation();
242
 
  if (!(create->default_table_charset= get_charset_by_name(buffer.c_str())))
 
411
  if (!(create->default_table_charset= get_charset_by_name(buffer.c_str(), MYF(0))))
243
412
  {
244
 
    errmsg_printf(ERRMSG_LVL_ERROR,
245
 
                  _("Error while loading database options: '%s':"),path);
 
413
    errmsg_printf(ERRMSG_LVL_ERROR, _("Error while loading database options: '%s':"),path);
246
414
    errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
247
415
    create->default_table_charset= default_charset_info;
248
 
    return -1;
249
416
  }
250
417
 
251
 
  return 0;
 
418
  /*
 
419
    Put the loaded value into the hash.
 
420
    Note that another thread could've added the same
 
421
    entry to the hash after we called get_dbopt(),
 
422
    but it's not an error, as put_dbopt() takes this
 
423
    possibility into account.
 
424
  */
 
425
  error= put_dbopt(path, create);
 
426
 
 
427
err1:
 
428
  return(error);
252
429
}
253
430
 
254
 
int load_db_opt_by_name(Session *session, const char *db_name,
255
 
                        HA_CREATE_INFO *db_create_info)
 
431
 
 
432
/*
 
433
  Retrieve database options by name. Load database options file or fetch from
 
434
  cache.
 
435
 
 
436
  SYNOPSIS
 
437
    load_db_opt_by_name()
 
438
    db_name         Database name
 
439
    db_create_info  Where to store the database options
 
440
 
 
441
  DESCRIPTION
 
442
    load_db_opt_by_name() is a shortcut for load_db_opt().
 
443
 
 
444
  NOTE
 
445
    Although load_db_opt_by_name() (and load_db_opt()) returns status of
 
446
    the operation, it is useless usually and should be ignored. The problem
 
447
    is that there are 1) system databases ("mysql") and 2) virtual
 
448
    databases ("information_schema"), which do not contain options file.
 
449
    So, load_db_opt[_by_name]() returns false for these databases, but this
 
450
    is not an error.
 
451
 
 
452
    load_db_opt[_by_name]() clears db_create_info structure in any case, so
 
453
    even on failure it contains valid data. So, common use case is just
 
454
    call load_db_opt[_by_name]() without checking return value and use
 
455
    db_create_info right after that.
 
456
 
 
457
  RETURN VALUES (read NOTE!)
 
458
    false   Success
 
459
    true    Failed to retrieve options
 
460
*/
 
461
 
 
462
bool load_db_opt_by_name(Session *session, const char *db_name,
 
463
                         HA_CREATE_INFO *db_create_info)
256
464
{
257
465
  char db_opt_path[FN_REFLEN];
258
466
 
267
475
}
268
476
 
269
477
 
 
478
/**
 
479
  Return default database collation.
 
480
 
 
481
  @param session     Thread context.
 
482
  @param db_name Database name.
 
483
 
 
484
  @return CHARSET_INFO object. The operation always return valid character
 
485
    set, even if the database does not exist.
 
486
*/
 
487
 
 
488
const CHARSET_INFO *get_default_db_collation(Session *session, const char *db_name)
 
489
{
 
490
  HA_CREATE_INFO db_info;
 
491
 
 
492
  if (session->db != NULL && strcmp(db_name, session->db) == 0)
 
493
    return session->db_charset;
 
494
 
 
495
  load_db_opt_by_name(session, db_name, &db_info);
 
496
 
 
497
  /*
 
498
    NOTE: even if load_db_opt_by_name() fails,
 
499
    db_info.default_table_charset contains valid character set
 
500
    (collation_server). We should not fail if load_db_opt_by_name() fails,
 
501
    because it is valid case. If a database has been created just by
 
502
    "mkdir", it does not contain db.opt file, but it is valid database.
 
503
  */
 
504
 
 
505
  return db_info.default_table_charset;
 
506
}
 
507
 
 
508
 
270
509
/*
271
510
  Create a database
272
511
 
297
536
  char   tmp_query[FN_REFLEN+16];
298
537
  long result= 1;
299
538
  int error= 0;
 
539
  struct stat stat_info;
300
540
  uint32_t create_options= create_info ? create_info->options : 0;
301
541
  uint32_t path_len;
302
542
 
309
549
 
310
550
  /*
311
551
    Do not create database if another thread is holding read lock.
312
 
    Wait for global read lock before acquiring LOCK_drizzleclient_create_db.
 
552
    Wait for global read lock before acquiring LOCK_drizzle_create_db.
313
553
    After wait_if_global_read_lock() we have protection against another
314
 
    global read lock. If we would acquire LOCK_drizzleclient_create_db first,
 
554
    global read lock. If we would acquire LOCK_drizzle_create_db first,
315
555
    another thread could step in and get the global read lock before we
316
556
    reach wait_if_global_read_lock(). If this thread tries the same as we
317
 
    (admin a db), it would then go and wait on LOCK_drizzleclient_create_db...
 
557
    (admin a db), it would then go and wait on LOCK_drizzle_create_db...
318
558
    Furthermore wait_if_global_read_lock() checks if the current thread
319
559
    has the global read lock and refuses the operation with
320
560
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
325
565
    goto exit2;
326
566
  }
327
567
 
328
 
  pthread_mutex_lock(&LOCK_drizzleclient_create_db);
 
568
  pthread_mutex_lock(&LOCK_drizzle_create_db);
329
569
 
330
570
  /* Check directory */
331
571
  path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
332
572
  path[path_len-1]= 0;                    // Remove last '/' from path
333
573
 
334
 
  if (mkdir(path,0777) == -1)
 
574
  if (!stat(path,&stat_info))
335
575
  {
336
 
    if (errno == EEXIST)
 
576
    if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
337
577
    {
338
 
      if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
339
 
      {
340
 
        my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
341
 
        error= -1;
342
 
        goto exit;
343
 
      }
344
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
345
 
                          ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
346
 
      if (!silent)
347
 
        session->my_ok();
348
 
      error= 0;
 
578
      my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
 
579
      error= -1;
349
580
      goto exit;
350
581
    }
351
 
 
352
 
    my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
353
 
    error= -1;
 
582
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
583
                        ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
 
584
    if (!silent)
 
585
      my_ok(session);
 
586
    error= 0;
354
587
    goto exit;
355
588
  }
 
589
  else
 
590
  {
 
591
    if (errno != ENOENT)
 
592
    {
 
593
      my_error(EE_STAT, MYF(0), path, errno);
 
594
      goto exit;
 
595
    }
 
596
    if (mkdir(path,0777) < 0)
 
597
    {
 
598
      my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
 
599
      error= -1;
 
600
      goto exit;
 
601
    }
 
602
  }
356
603
 
357
 
  error= write_schema_file(session, path, db, create_info);
358
 
  if (error && error != EEXIST)
 
604
  path[path_len-1]= FN_LIBCHAR;
 
605
  strncpy(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
 
606
  if (write_db_opt(session, path, db, create_info))
359
607
  {
 
608
    /*
 
609
      Could not create options file.
 
610
      Restore things to beginning.
 
611
    */
 
612
    path[path_len]= 0;
360
613
    if (rmdir(path) >= 0)
361
614
    {
362
615
      error= -1;
363
616
      goto exit;
364
617
    }
 
618
    /*
 
619
      We come here when we managed to create the database, but not the option
 
620
      file.  In this case it's best to just continue as if nothing has
 
621
      happened.  (This is a very unlikely senario)
 
622
    */
365
623
  }
366
624
 
367
625
  if (!silent)
380
638
      query_length= session->query_length;
381
639
    }
382
640
 
383
 
    (void)replicator_statement(session, query, query_length);
384
 
    session->my_ok(result);
 
641
    if (drizzle_bin_log.is_open())
 
642
    {
 
643
      Query_log_event qinfo(session, query, query_length, 0,
 
644
                            /* suppress_use */ true);
 
645
 
 
646
      /*
 
647
        Write should use the database being created as the "current
 
648
        database" and not the threads current database, which is the
 
649
        default. If we do not change the "current database" to the
 
650
        database being created, the CREATE statement will not be
 
651
        replicated when using --binlog-do-db to select databases to be
 
652
        replicated.
 
653
 
 
654
        An example (--binlog-do-db=sisyfos):
 
655
 
 
656
          CREATE DATABASE bob;        # Not replicated
 
657
          USE bob;                    # 'bob' is the current database
 
658
          CREATE DATABASE sisyfos;    # Not replicated since 'bob' is
 
659
                                      # current database.
 
660
          USE sisyfos;                # Will give error on slave since
 
661
                                      # database does not exist.
 
662
      */
 
663
      qinfo.db     = db;
 
664
      qinfo.db_len = strlen(db);
 
665
 
 
666
      /* These DDL methods and logging protected with LOCK_drizzle_create_db */
 
667
      drizzle_bin_log.write(&qinfo);
 
668
    }
 
669
    my_ok(session, result);
385
670
  }
386
671
 
387
672
exit:
388
 
  pthread_mutex_unlock(&LOCK_drizzleclient_create_db);
 
673
  pthread_mutex_unlock(&LOCK_drizzle_create_db);
389
674
  start_waiting_global_read_lock(session);
390
675
exit2:
391
676
  return(error);
396
681
 
397
682
bool mysql_alter_db(Session *session, const char *db, HA_CREATE_INFO *create_info)
398
683
{
 
684
  char path[FN_REFLEN+16];
399
685
  long result=1;
400
 
  int error= 0;
401
 
  char   path[FN_REFLEN+16];
402
 
  uint32_t path_len;
 
686
  int error= false;
403
687
 
404
688
  /*
405
689
    Do not alter database if another thread is holding read lock.
406
 
    Wait for global read lock before acquiring LOCK_drizzleclient_create_db.
 
690
    Wait for global read lock before acquiring LOCK_drizzle_create_db.
407
691
    After wait_if_global_read_lock() we have protection against another
408
 
    global read lock. If we would acquire LOCK_drizzleclient_create_db first,
 
692
    global read lock. If we would acquire LOCK_drizzle_create_db first,
409
693
    another thread could step in and get the global read lock before we
410
694
    reach wait_if_global_read_lock(). If this thread tries the same as we
411
 
    (admin a db), it would then go and wait on LOCK_drizzleclient_create_db...
 
695
    (admin a db), it would then go and wait on LOCK_drizzle_create_db...
412
696
    Furthermore wait_if_global_read_lock() checks if the current thread
413
697
    has the global read lock and refuses the operation with
414
698
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
415
699
  */
416
700
  if ((error=wait_if_global_read_lock(session,0,1)))
 
701
    goto exit2;
 
702
 
 
703
  pthread_mutex_lock(&LOCK_drizzle_create_db);
 
704
 
 
705
  /*
 
706
     Recreate db options file: /dbpath/.db.opt
 
707
     We pass MY_DB_OPT_FILE as "extension" to avoid
 
708
     "table name to file name" encoding.
 
709
  */
 
710
  build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0);
 
711
  if ((error=write_db_opt(session, path, db, create_info)))
417
712
    goto exit;
418
713
 
419
 
  pthread_mutex_lock(&LOCK_drizzleclient_create_db);
420
 
 
421
714
  /* Change options if current database is being altered. */
422
 
  path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
423
 
  path[path_len-1]= 0;                    // Remove last '/' from path
424
 
 
425
 
  error= write_schema_file(session, path, db, create_info);
426
 
  if (error && error != EEXIST)
427
 
  {
428
 
    /* TODO: find some witty way of getting back an error message */
429
 
    pthread_mutex_unlock(&LOCK_drizzleclient_create_db);
430
 
    goto exit;
431
 
  }
432
715
 
433
716
  if (session->db && !strcmp(session->db,db))
434
717
  {
438
721
    session->variables.collation_database= session->db_charset;
439
722
  }
440
723
 
441
 
  (void)replicator_statement(session, session->query, session->query_length);
442
 
  session->my_ok(result);
443
 
 
444
 
  pthread_mutex_unlock(&LOCK_drizzleclient_create_db);
 
724
  if (drizzle_bin_log.is_open())
 
725
  {
 
726
    Query_log_event qinfo(session, session->query, session->query_length, 0,
 
727
                          /* suppress_use */ true);
 
728
 
 
729
    /*
 
730
      Write should use the database being created as the "current
 
731
      database" and not the threads current database, which is the
 
732
      default.
 
733
    */
 
734
    qinfo.db     = db;
 
735
    qinfo.db_len = strlen(db);
 
736
 
 
737
    session->clear_error();
 
738
    /* These DDL methods and logging protected with LOCK_drizzle_create_db */
 
739
    drizzle_bin_log.write(&qinfo);
 
740
  }
 
741
  my_ok(session, result);
 
742
 
 
743
exit:
 
744
  pthread_mutex_unlock(&LOCK_drizzle_create_db);
445
745
  start_waiting_global_read_lock(session);
446
 
exit:
 
746
exit2:
447
747
  return(error);
448
748
}
449
749
 
482
782
 
483
783
  /*
484
784
    Do not drop database if another thread is holding read lock.
485
 
    Wait for global read lock before acquiring LOCK_drizzleclient_create_db.
 
785
    Wait for global read lock before acquiring LOCK_drizzle_create_db.
486
786
    After wait_if_global_read_lock() we have protection against another
487
 
    global read lock. If we would acquire LOCK_drizzleclient_create_db first,
 
787
    global read lock. If we would acquire LOCK_drizzle_create_db first,
488
788
    another thread could step in and get the global read lock before we
489
789
    reach wait_if_global_read_lock(). If this thread tries the same as we
490
 
    (admin a db), it would then go and wait on LOCK_drizzleclient_create_db...
 
790
    (admin a db), it would then go and wait on LOCK_drizzle_create_db...
491
791
    Furthermore wait_if_global_read_lock() checks if the current thread
492
792
    has the global read lock and refuses the operation with
493
793
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
498
798
    goto exit2;
499
799
  }
500
800
 
501
 
  pthread_mutex_lock(&LOCK_drizzleclient_create_db);
 
801
  pthread_mutex_lock(&LOCK_drizzle_create_db);
502
802
 
503
803
  length= build_table_filename(path, sizeof(path), db, "", "", 0);
504
 
  strcpy(path+length, MY_DB_OPT_FILE);         // Append db option file name
505
 
  unlink(path);
 
804
  strcpy(path+length, MY_DB_OPT_FILE);          // Append db option file name
 
805
  del_dbopt(path);                              // Remove dboption hash entry
506
806
  path[length]= '\0';                           // Remove file name
507
807
 
508
808
  /* See if the directory exists */
548
848
      query= session->query;
549
849
      query_length= session->query_length;
550
850
    }
551
 
    (void)replicator_statement(session, session->query, session->query_length);
 
851
    if (drizzle_bin_log.is_open())
 
852
    {
 
853
      Query_log_event qinfo(session, query, query_length, 0,
 
854
                            /* suppress_use */ true);
 
855
      /*
 
856
        Write should use the database being created as the "current
 
857
        database" and not the threads current database, which is the
 
858
        default.
 
859
      */
 
860
      qinfo.db     = db;
 
861
      qinfo.db_len = strlen(db);
 
862
 
 
863
      session->clear_error();
 
864
      /* These DDL methods and logging protected with LOCK_drizzle_create_db */
 
865
      drizzle_bin_log.write(&qinfo);
 
866
    }
552
867
    session->clear_error();
553
868
    session->server_status|= SERVER_STATUS_DB_DROPPED;
554
 
    session->my_ok((uint32_t) deleted);
 
869
    my_ok(session, (uint32_t) deleted);
555
870
    session->server_status&= ~SERVER_STATUS_DB_DROPPED;
556
871
  }
557
 
  else
 
872
  else if (drizzle_bin_log.is_open())
558
873
  {
559
874
    char *query, *query_pos, *query_end, *query_data_start;
560
875
    TableList *tbl;
574
889
      tbl_name_len= strlen(tbl->table_name) + 3;
575
890
      if (query_pos + tbl_name_len + 1 >= query_end)
576
891
      {
577
 
        /* These DDL methods and logging protected with LOCK_drizzleclient_create_db */
 
892
        /* These DDL methods and logging protected with LOCK_drizzle_create_db */
578
893
        write_to_binlog(session, query, query_pos -1 - query, db, db_len);
579
894
        query_pos= query_data_start;
580
895
      }
587
902
 
588
903
    if (query_pos != query_data_start)
589
904
    {
590
 
      /* These DDL methods and logging protected with LOCK_drizzleclient_create_db */
 
905
      /* These DDL methods and logging protected with LOCK_drizzle_create_db */
591
906
      write_to_binlog(session, query, query_pos -1 - query, db, db_len);
592
907
    }
593
908
  }
601
916
  */
602
917
  if (session->db && !strcmp(session->db, db))
603
918
    mysql_change_db_impl(session, NULL, session->variables.collation_server);
604
 
  pthread_mutex_unlock(&LOCK_drizzleclient_create_db);
 
919
  pthread_mutex_unlock(&LOCK_drizzle_create_db);
605
920
  start_waiting_global_read_lock(session);
606
921
exit2:
607
922
  return(error);
624
939
  tot_list_next= &tot_list;
625
940
 
626
941
  for (uint32_t idx=0 ;
627
 
       idx < (uint32_t) dirp->number_off_files && !session->killed ;
 
942
       idx < (uint) dirp->number_off_files && !session->killed ;
628
943
       idx++)
629
944
  {
630
945
    FILEINFO *file=dirp->dir_entry+idx;
656
971
    }
657
972
    /* just for safety we use files_charset_info */
658
973
    if (db && !my_strcasecmp(files_charset_info,
659
 
                             extension, ".dfe"))
 
974
                             extension, reg_ext))
660
975
    {
661
976
      uint32_t db_len= strlen(db);
662
977
 
665
980
      TableList *table_list=(TableList*)
666
981
                              session->calloc(sizeof(*table_list) +
667
982
                                          db_len + 1 +
 
983
                                          MYSQL50_TABLE_NAME_PREFIX_LENGTH +
668
984
                                          strlen(file->name) + 1);
669
985
 
670
986
      if (!table_list)
672
988
      table_list->db= (char*) (table_list+1);
673
989
      table_list->table_name= strcpy(table_list->db, db) + db_len + 1;
674
990
      filename_to_tablename(file->name, table_list->table_name,
 
991
                            MYSQL50_TABLE_NAME_PREFIX_LENGTH +
675
992
                            strlen(file->name) + 1);
676
993
      table_list->alias= table_list->table_name;        // If lower_case_table_names=2
677
994
      table_list->internal_tmp_table= is_prefix(file->name, TMP_FILE_PREFIX);