~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2003 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
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 */
15
16
17
/* create and drop of databases */
612.2.4 by Monty Taylor
Moved some defines to config.h. Stopped including config.h directly anywhere.
18
#include <drizzled/global.h>
481.1.9 by Monty Taylor
Added autoconf tests for location of cstdint and cinttypes. Use those in C++ programs now, so that we don't have to define _STDC_LIMIT_MACROS, etc by hand. Stop, in fact, defining those by hand.
19
#include CSTDINT_H
20
#include CINTTYPES_H
318 by Brian Aker
Modified sql_db to now use Google Proto buffers instead of MySQL type.
21
#include <string>
22
#include <fstream>
316 by Brian Aker
First pass of new sql_db.cc work
23
#include <drizzled/serialize/serialize.h>
318 by Brian Aker
Modified sql_db to now use Google Proto buffers instead of MySQL type.
24
using namespace std;
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
25
#include <drizzled/server_includes.h>
212.5.13 by Monty Taylor
Moved my_sys/my_pthread/my_nosys and mysys_err to mysys.
26
#include <mysys/mysys_err.h>
212.5.38 by Monty Taylor
Moved my_dir (and removed references to a lot of places)
27
#include <mysys/my_dir.h>
1 by brian
clean slate
28
#include "log.h"
549 by Monty Taylor
Took gettext.h out of header files.
29
#include <drizzled/error.h>
538 by Monty Taylor
Moved gettext.h into drizzled in anticipation of the new client lib.
30
#include <drizzled/gettext.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
31
#include <mysys/hash.h>
32
#include <drizzled/session.h>
33
#include <drizzled/db.h>
34
#include <drizzled/sql_base.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
35
#include <drizzled/lock.h>
722.4.1 by Mark Atwood
integrate errmsg plugin into sql_print_* functions
36
#include <drizzled/errmsg_print.h>
316 by Brian Aker
First pass of new sql_db.cc work
37
1 by brian
clean slate
38
#define MAX_DROP_TABLE_Q_LEN      1024
39
461 by Monty Taylor
Removed NullS. bu-bye.
40
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NULL};
1 by brian
clean slate
41
static TYPELIB deletable_extentions=
42
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
43
520.1.22 by Brian Aker
Second pass of thd cleanup
44
static long mysql_rm_known_files(Session *session, MY_DIR *dirp,
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
45
                                 const char *db, const char *path,
46
                                 uint32_t level,
327.2.4 by Brian Aker
Refactoring table.h
47
                                 TableList **dropped_tables);
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
48
253 by Brian Aker
Removed final my_bool from sql_db.
49
static bool rm_dir_w_symlink(const char *org_path, bool send_error);
520.1.22 by Brian Aker
Second pass of thd cleanup
50
static void mysql_change_db_impl(Session *session,
1 by brian
clean slate
51
                                 LEX_STRING *new_db_name,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
52
                                 const CHARSET_INFO * const new_db_charset);
1 by brian
clean slate
53
54
55
/* Database lock hash */
56
HASH lock_db_cache;
57
pthread_mutex_t LOCK_lock_db;
58
int creating_database= 0;  // how many database locks are made
59
60
61
/* Structure for database lock */
62
typedef struct my_dblock_st
63
{
64
  char *name;        /* Database name        */
482 by Brian Aker
Remove uint.
65
  uint32_t name_length;  /* Database length name */
1 by brian
clean slate
66
} my_dblock_t;
67
68
69
/*
70
  lock_db key.
71
*/
72
481 by Brian Aker
Remove all of uchar.
73
extern "C" unsigned char* lock_db_get_key(my_dblock_t *, size_t *, bool not_used);
1 by brian
clean slate
74
481 by Brian Aker
Remove all of uchar.
75
unsigned char* lock_db_get_key(my_dblock_t *ptr, size_t *length,
253 by Brian Aker
Removed final my_bool from sql_db.
76
                       bool not_used __attribute__((unused)))
1 by brian
clean slate
77
{
78
  *length= ptr->name_length;
481 by Brian Aker
Remove all of uchar.
79
  return (unsigned char*) ptr->name;
1 by brian
clean slate
80
}
81
82
83
/*
84
  Free lock_db hash element.
85
*/
86
87
extern "C" void lock_db_free_element(void *ptr);
88
89
void lock_db_free_element(void *ptr)
90
{
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
91
  free(ptr);
1 by brian
clean slate
92
}
93
94
95
/*
96
  Delete a database lock entry from hash.
97
*/
98
482 by Brian Aker
Remove uint.
99
void lock_db_delete(const char *name, uint32_t length)
1 by brian
clean slate
100
{
101
  my_dblock_t *opt;
102
  safe_mutex_assert_owner(&LOCK_lock_db);
103
  if ((opt= (my_dblock_t *)hash_search(&lock_db_cache,
481 by Brian Aker
Remove all of uchar.
104
                                       (const unsigned char*) name, length)))
105
    hash_delete(&lock_db_cache, (unsigned char*) opt);
1 by brian
clean slate
106
}
107
108
109
/* Database options hash */
110
static HASH dboptions;
253 by Brian Aker
Removed final my_bool from sql_db.
111
static bool dboptions_init= 0;
658 by Brian Aker
Part removal of my_pthread.h
112
static pthread_rwlock_t LOCK_dboptions;
1 by brian
clean slate
113
114
/* Structure for database options */
115
typedef struct my_dbopt_st
116
{
117
  char *name;			/* Database name                  */
482 by Brian Aker
Remove uint.
118
  uint32_t name_length;		/* Database length name           */
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
119
  const CHARSET_INFO *charset;	/* Database default character set */
1 by brian
clean slate
120
} my_dbopt_t;
121
122
123
/*
124
  Function we use in the creation of our hash to get key.
125
*/
126
481 by Brian Aker
Remove all of uchar.
127
extern "C" unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
253 by Brian Aker
Removed final my_bool from sql_db.
128
                                    bool not_used);
1 by brian
clean slate
129
481 by Brian Aker
Remove all of uchar.
130
unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
253 by Brian Aker
Removed final my_bool from sql_db.
131
                         bool not_used __attribute__((unused)))
1 by brian
clean slate
132
{
133
  *length= opt->name_length;
481 by Brian Aker
Remove all of uchar.
134
  return (unsigned char*) opt->name;
1 by brian
clean slate
135
}
136
137
138
/*
139
  Helper function to write a query to binlog used by mysql_rm_db()
140
*/
141
520.1.22 by Brian Aker
Second pass of thd cleanup
142
static inline void write_to_binlog(Session *session, char *query, uint32_t q_len,
482 by Brian Aker
Remove uint.
143
                                   char *db, uint32_t db_len)
1 by brian
clean slate
144
{
520.1.22 by Brian Aker
Second pass of thd cleanup
145
  Query_log_event qinfo(session, query, q_len, 0, 0);
1 by brian
clean slate
146
  qinfo.error_code= 0;
147
  qinfo.db= db;
148
  qinfo.db_len= db_len;
586.1.1 by Yoshinori Sano
Rename mysql to drizzle, specifically mysql_bin_log to drizzle_bin_log.
149
  drizzle_bin_log.write(&qinfo);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
150
}
1 by brian
clean slate
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
{
481 by Brian Aker
Remove all of uchar.
161
  free((unsigned char*) dbopt);
1 by brian
clean slate
162
}
163
164
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
165
/*
1 by brian
clean slate
166
  Initialize database option hash and locked database hash.
167
168
  SYNOPSIS
169
    my_database_names()
170
171
  NOTES
172
    Must be called before any other database function is called.
173
174
  RETURN
175
    0	ok
176
    1	Fatal error
177
*/
178
179
bool my_database_names_init(void)
180
{
253 by Brian Aker
Removed final my_bool from sql_db.
181
  bool error= false;
658 by Brian Aker
Part removal of my_pthread.h
182
  (void) pthread_rwlock_init(&LOCK_dboptions, NULL);
1 by brian
clean slate
183
  if (!dboptions_init)
184
  {
185
    dboptions_init= 1;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
186
    error= hash_init(&dboptions, lower_case_table_names ?
1 by brian
clean slate
187
                     &my_charset_bin : system_charset_info,
188
                     32, 0, 0, (hash_get_key) dboptions_get_key,
189
                     free_dbopt,0) ||
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
190
           hash_init(&lock_db_cache, lower_case_table_names ?
1 by brian
clean slate
191
                     &my_charset_bin : system_charset_info,
192
                     32, 0, 0, (hash_get_key) lock_db_get_key,
193
                     lock_db_free_element,0);
194
195
  }
196
  return error;
197
}
198
199
200
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
201
/*
1 by brian
clean slate
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);
658 by Brian Aker
Part removal of my_pthread.h
211
    (void) pthread_rwlock_destroy(&LOCK_dboptions);
1 by brian
clean slate
212
    hash_free(&lock_db_cache);
213
  }
214
}
215
216
217
/*
218
  Cleanup cached options
219
*/
220
221
void my_dbopt_cleanup(void)
222
{
658 by Brian Aker
Part removal of my_pthread.h
223
  pthread_rwlock_wrlock(&LOCK_dboptions);
1 by brian
clean slate
224
  hash_free(&dboptions);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
225
  hash_init(&dboptions, lower_case_table_names ?
1 by brian
clean slate
226
            &my_charset_bin : system_charset_info,
227
            32, 0, 0, (hash_get_key) dboptions_get_key,
228
            free_dbopt,0);
658 by Brian Aker
Part removal of my_pthread.h
229
  pthread_rwlock_unlock(&LOCK_dboptions);
1 by brian
clean slate
230
}
231
232
233
/*
234
  Find database options in the hash.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
235
1 by brian
clean slate
236
  DESCRIPTION
237
    Search a database options in the hash, usings its path.
238
    Fills "create" on success.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
239
1 by brian
clean slate
240
  RETURN VALUES
241
    0 on success.
242
    1 on error.
243
*/
244
253 by Brian Aker
Removed final my_bool from sql_db.
245
static bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
1 by brian
clean slate
246
{
247
  my_dbopt_t *opt;
482 by Brian Aker
Remove uint.
248
  uint32_t length;
253 by Brian Aker
Removed final my_bool from sql_db.
249
  bool error= true;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
250
1 by brian
clean slate
251
  length= (uint) strlen(dbname);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
252
658 by Brian Aker
Part removal of my_pthread.h
253
  pthread_rwlock_rdlock(&LOCK_dboptions);
481 by Brian Aker
Remove all of uchar.
254
  if ((opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
1 by brian
clean slate
255
  {
256
    create->default_table_charset= opt->charset;
253 by Brian Aker
Removed final my_bool from sql_db.
257
    error= true;
1 by brian
clean slate
258
  }
658 by Brian Aker
Part removal of my_pthread.h
259
  pthread_rwlock_unlock(&LOCK_dboptions);
1 by brian
clean slate
260
  return error;
261
}
262
263
264
/*
265
  Writes database options into the hash.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
266
1 by brian
clean slate
267
  DESCRIPTION
268
    Inserts database options into the hash, or updates
269
    options if they are already in the hash.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
270
1 by brian
clean slate
271
  RETURN VALUES
272
    0 on success.
273
    1 on error.
274
*/
275
253 by Brian Aker
Removed final my_bool from sql_db.
276
static bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
1 by brian
clean slate
277
{
278
  my_dbopt_t *opt;
482 by Brian Aker
Remove uint.
279
  uint32_t length;
253 by Brian Aker
Removed final my_bool from sql_db.
280
  bool error= false;
1 by brian
clean slate
281
282
  length= (uint) strlen(dbname);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
283
658 by Brian Aker
Part removal of my_pthread.h
284
  pthread_rwlock_wrlock(&LOCK_dboptions);
481 by Brian Aker
Remove all of uchar.
285
  if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
286
  {
1 by brian
clean slate
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,
461 by Monty Taylor
Removed NullS. bu-bye.
291
                         NULL))
1 by brian
clean slate
292
    {
253 by Brian Aker
Removed final my_bool from sql_db.
293
      error= true;
1 by brian
clean slate
294
      goto end;
295
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
296
1 by brian
clean slate
297
    opt->name= tmp_name;
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
298
    strcpy(opt->name, dbname);
1 by brian
clean slate
299
    opt->name_length= length;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
300
481 by Brian Aker
Remove all of uchar.
301
    if ((error= my_hash_insert(&dboptions, (unsigned char*) opt)))
1 by brian
clean slate
302
    {
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
303
      free(opt);
1 by brian
clean slate
304
      goto end;
305
    }
306
  }
307
308
  /* Update / write options in hash */
309
  opt->charset= create->default_table_charset;
310
311
end:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
312
  pthread_rwlock_unlock(&LOCK_dboptions);
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
313
  return(error);
1 by brian
clean slate
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;
658 by Brian Aker
Part removal of my_pthread.h
324
  pthread_rwlock_wrlock(&LOCK_dboptions);
481 by Brian Aker
Remove all of uchar.
325
  if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const unsigned char*) path,
1 by brian
clean slate
326
                                      strlen(path))))
481 by Brian Aker
Remove all of uchar.
327
    hash_delete(&dboptions, (unsigned char*) opt);
658 by Brian Aker
Part removal of my_pthread.h
328
  pthread_rwlock_unlock(&LOCK_dboptions);
1 by brian
clean slate
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
520.1.22 by Brian Aker
Second pass of thd cleanup
343
static bool write_db_opt(Session *session, const char *path, const char *name, HA_CREATE_INFO *create)
1 by brian
clean slate
344
{
253 by Brian Aker
Removed final my_bool from sql_db.
345
  bool error= true;
323 by Brian Aker
Updated proto file for table (not FRM work).
346
  drizzle::Schema db;
318 by Brian Aker
Modified sql_db to now use Google Proto buffers instead of MySQL type.
347
348
  assert(name);
1 by brian
clean slate
349
350
  if (!create->default_table_charset)
520.1.22 by Brian Aker
Second pass of thd cleanup
351
    create->default_table_charset= session->variables.collation_server;
1 by brian
clean slate
352
353
  if (put_dbopt(path, create))
354
    return 1;
355
318 by Brian Aker
Modified sql_db to now use Google Proto buffers instead of MySQL type.
356
  db.set_name(name);
357
  db.set_characterset(create->default_table_charset->csname);
358
  db.set_collation(create->default_table_charset->name);
359
360
  fstream output(path, ios::out | ios::trunc | ios::binary);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
361
  if (!db.SerializeToOstream(&output))
318 by Brian Aker
Modified sql_db to now use Google Proto buffers instead of MySQL type.
362
    error= false;
363
1 by brian
clean slate
364
  return error;
365
}
366
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
520.1.22 by Brian Aker
Second pass of thd cleanup
383
bool load_db_opt(Session *session, const char *path, HA_CREATE_INFO *create)
1 by brian
clean slate
384
{
385
  bool error=1;
323 by Brian Aker
Updated proto file for table (not FRM work).
386
  drizzle::Schema db;
318 by Brian Aker
Modified sql_db to now use Google Proto buffers instead of MySQL type.
387
  string buffer;
1 by brian
clean slate
388
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
389
  memset(create, 0, sizeof(*create));
520.1.22 by Brian Aker
Second pass of thd cleanup
390
  create->default_table_charset= session->variables.collation_server;
1 by brian
clean slate
391
392
  /* Check if options for this database are already in the hash */
393
  if (!get_dbopt(path, create))
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
394
    return(0);
1 by brian
clean slate
395
318 by Brian Aker
Modified sql_db to now use Google Proto buffers instead of MySQL type.
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))))
404
  {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
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());
318 by Brian Aker
Modified sql_db to now use Google Proto buffers instead of MySQL type.
407
    create->default_table_charset= default_charset_info;
408
  }
409
410
  buffer= db.collation();
411
  if (!(create->default_table_charset= get_charset_by_name(buffer.c_str(), MYF(0))))
412
  {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
413
    errmsg_printf(ERRMSG_LVL_ERROR, _("Error while loading database options: '%s':"),path);
414
    errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
318 by Brian Aker
Modified sql_db to now use Google Proto buffers instead of MySQL type.
415
    create->default_table_charset= default_charset_info;
416
  }
417
1 by brian
clean slate
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:
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
428
  return(error);
1 by brian
clean slate
429
}
430
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.
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
449
    So, load_db_opt[_by_name]() returns false for these databases, but this
1 by brian
clean slate
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!)
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
458
    false   Success
459
    true    Failed to retrieve options
1 by brian
clean slate
460
*/
461
520.1.22 by Brian Aker
Second pass of thd cleanup
462
bool load_db_opt_by_name(Session *session, const char *db_name,
1 by brian
clean slate
463
                         HA_CREATE_INFO *db_create_info)
464
{
465
  char db_opt_path[FN_REFLEN];
466
467
  /*
468
    Pass an empty file name, and the database options file name as extension
469
    to avoid table name to file name encoding.
470
  */
471
  (void) build_table_filename(db_opt_path, sizeof(db_opt_path),
472
                              db_name, "", MY_DB_OPT_FILE, 0);
473
520.1.22 by Brian Aker
Second pass of thd cleanup
474
  return load_db_opt(session, db_opt_path, db_create_info);
1 by brian
clean slate
475
}
476
477
478
/**
479
  Return default database collation.
480
520.1.22 by Brian Aker
Second pass of thd cleanup
481
  @param session     Thread context.
1 by brian
clean slate
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
520.1.22 by Brian Aker
Second pass of thd cleanup
488
const CHARSET_INFO *get_default_db_collation(Session *session, const char *db_name)
1 by brian
clean slate
489
{
490
  HA_CREATE_INFO db_info;
491
520.1.22 by Brian Aker
Second pass of thd cleanup
492
  if (session->db != NULL && strcmp(db_name, session->db) == 0)
493
    return session->db_charset;
1 by brian
clean slate
494
520.1.22 by Brian Aker
Second pass of thd cleanup
495
  load_db_opt_by_name(session, db_name, &db_info);
1 by brian
clean slate
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
509
/*
510
  Create a database
511
512
  SYNOPSIS
513
  mysql_create_db()
520.1.22 by Brian Aker
Second pass of thd cleanup
514
  session		Thread handler
1 by brian
clean slate
515
  db		Name of database to create
516
		Function assumes that this is already validated.
517
  create_info	Database create options (like character set)
518
  silent	Used by replication when internally creating a database.
519
		In this case the entry should not be logged.
520
521
  SIDE-EFFECTS
522
   1. Report back to client that command succeeded (my_ok)
523
   2. Report errors to client
524
   3. Log event to binary log
525
   (The 'silent' flags turns off 1 and 3.)
526
527
  RETURN VALUES
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
528
  false ok
529
  true  Error
1 by brian
clean slate
530
531
*/
532
520.1.22 by Brian Aker
Second pass of thd cleanup
533
int mysql_create_db(Session *session, char *db, HA_CREATE_INFO *create_info, bool silent)
1 by brian
clean slate
534
{
535
  char	 path[FN_REFLEN+16];
536
  char	 tmp_query[FN_REFLEN+16];
537
  long result= 1;
538
  int error= 0;
15 by brian
Fix for stat, NETWARE removal
539
  struct stat stat_info;
482 by Brian Aker
Remove uint.
540
  uint32_t create_options= create_info ? create_info->options : 0;
541
  uint32_t path_len;
1 by brian
clean slate
542
543
  /* do not create 'information_schema' db */
575.4.7 by Monty Taylor
More header cleanup.
544
  if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.c_str()))
1 by brian
clean slate
545
  {
546
    my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
547
    return(-1);
1 by brian
clean slate
548
  }
549
550
  /*
551
    Do not create database if another thread is holding read lock.
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
552
    Wait for global read lock before acquiring LOCK_drizzle_create_db.
1 by brian
clean slate
553
    After wait_if_global_read_lock() we have protection against another
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
554
    global read lock. If we would acquire LOCK_drizzle_create_db first,
1 by brian
clean slate
555
    another thread could step in and get the global read lock before we
556
    reach wait_if_global_read_lock(). If this thread tries the same as we
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
557
    (admin a db), it would then go and wait on LOCK_drizzle_create_db...
1 by brian
clean slate
558
    Furthermore wait_if_global_read_lock() checks if the current thread
559
    has the global read lock and refuses the operation with
560
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
561
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
562
  if (wait_if_global_read_lock(session, 0, 1))
1 by brian
clean slate
563
  {
564
    error= -1;
565
    goto exit2;
566
  }
567
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
568
  pthread_mutex_lock(&LOCK_drizzle_create_db);
1 by brian
clean slate
569
570
  /* Check directory */
571
  path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
572
  path[path_len-1]= 0;                    // Remove last '/' from path
573
15 by brian
Fix for stat, NETWARE removal
574
  if (!stat(path,&stat_info))
1 by brian
clean slate
575
  {
576
    if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
577
    {
578
      my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
579
      error= -1;
580
      goto exit;
581
    }
520.1.22 by Brian Aker
Second pass of thd cleanup
582
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1 by brian
clean slate
583
			ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
584
    if (!silent)
520.1.22 by Brian Aker
Second pass of thd cleanup
585
      my_ok(session);
1 by brian
clean slate
586
    error= 0;
587
    goto exit;
588
  }
589
  else
590
  {
15 by brian
Fix for stat, NETWARE removal
591
    if (errno != ENOENT)
1 by brian
clean slate
592
    {
15 by brian
Fix for stat, NETWARE removal
593
      my_error(EE_STAT, MYF(0), path, errno);
1 by brian
clean slate
594
      goto exit;
595
    }
685.3.1 by Toru Maesaka
Removed my_mkdir() and my_sleep()
596
    if (mkdir(path,0777) < 0)
1 by brian
clean slate
597
    {
598
      my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
599
      error= -1;
600
      goto exit;
601
    }
602
  }
603
604
  path[path_len-1]= FN_LIBCHAR;
629.5.2 by Toru Maesaka
Second pass of replacing MySQL's strmake() with libc calls
605
  strncpy(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
520.1.22 by Brian Aker
Second pass of thd cleanup
606
  if (write_db_opt(session, path, db, create_info))
1 by brian
clean slate
607
  {
608
    /*
609
      Could not create options file.
610
      Restore things to beginning.
611
    */
612
    path[path_len]= 0;
613
    if (rmdir(path) >= 0)
614
    {
615
      error= -1;
616
      goto exit;
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
    */
623
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
624
1 by brian
clean slate
625
  if (!silent)
626
  {
627
    char *query;
482 by Brian Aker
Remove uint.
628
    uint32_t query_length;
1 by brian
clean slate
629
520.1.22 by Brian Aker
Second pass of thd cleanup
630
    if (!session->query)				// Only in replication
1 by brian
clean slate
631
    {
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
632
      query= tmp_query;
633
      query_length= sprintf(tmp_query, "create database `%s`", db);
1 by brian
clean slate
634
    }
635
    else
636
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
637
      query= 	    session->query;
638
      query_length= session->query_length;
1 by brian
clean slate
639
    }
640
586.1.1 by Yoshinori Sano
Rename mysql to drizzle, specifically mysql_bin_log to drizzle_bin_log.
641
    if (drizzle_bin_log.is_open())
1 by brian
clean slate
642
    {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
643
      Query_log_event qinfo(session, query, query_length, 0,
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
644
			    /* suppress_use */ true);
1 by brian
clean slate
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
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
652
        replicated.
1 by brian
clean slate
653
654
	An example (--binlog-do-db=sisyfos):
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
655
1 by brian
clean slate
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
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
666
      /* These DDL methods and logging protected with LOCK_drizzle_create_db */
586.1.1 by Yoshinori Sano
Rename mysql to drizzle, specifically mysql_bin_log to drizzle_bin_log.
667
      drizzle_bin_log.write(&qinfo);
1 by brian
clean slate
668
    }
520.1.22 by Brian Aker
Second pass of thd cleanup
669
    my_ok(session, result);
1 by brian
clean slate
670
  }
671
672
exit:
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
673
  pthread_mutex_unlock(&LOCK_drizzle_create_db);
520.1.22 by Brian Aker
Second pass of thd cleanup
674
  start_waiting_global_read_lock(session);
1 by brian
clean slate
675
exit2:
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
676
  return(error);
1 by brian
clean slate
677
}
678
679
680
/* db-name is already validated when we come here */
681
520.1.22 by Brian Aker
Second pass of thd cleanup
682
bool mysql_alter_db(Session *session, const char *db, HA_CREATE_INFO *create_info)
1 by brian
clean slate
683
{
684
  char path[FN_REFLEN+16];
685
  long result=1;
253 by Brian Aker
Removed final my_bool from sql_db.
686
  int error= false;
1 by brian
clean slate
687
688
  /*
689
    Do not alter database if another thread is holding read lock.
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
690
    Wait for global read lock before acquiring LOCK_drizzle_create_db.
1 by brian
clean slate
691
    After wait_if_global_read_lock() we have protection against another
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
692
    global read lock. If we would acquire LOCK_drizzle_create_db first,
1 by brian
clean slate
693
    another thread could step in and get the global read lock before we
694
    reach wait_if_global_read_lock(). If this thread tries the same as we
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
695
    (admin a db), it would then go and wait on LOCK_drizzle_create_db...
1 by brian
clean slate
696
    Furthermore wait_if_global_read_lock() checks if the current thread
697
    has the global read lock and refuses the operation with
698
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
699
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
700
  if ((error=wait_if_global_read_lock(session,0,1)))
1 by brian
clean slate
701
    goto exit2;
702
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
703
  pthread_mutex_lock(&LOCK_drizzle_create_db);
1 by brian
clean slate
704
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
705
  /*
1 by brian
clean slate
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);
520.1.22 by Brian Aker
Second pass of thd cleanup
711
  if ((error=write_db_opt(session, path, db, create_info)))
1 by brian
clean slate
712
    goto exit;
713
714
  /* Change options if current database is being altered. */
715
520.1.22 by Brian Aker
Second pass of thd cleanup
716
  if (session->db && !strcmp(session->db,db))
1 by brian
clean slate
717
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
718
    session->db_charset= create_info->default_table_charset ?
1 by brian
clean slate
719
		     create_info->default_table_charset :
520.1.22 by Brian Aker
Second pass of thd cleanup
720
		     session->variables.collation_server;
721
    session->variables.collation_database= session->db_charset;
1 by brian
clean slate
722
  }
723
586.1.1 by Yoshinori Sano
Rename mysql to drizzle, specifically mysql_bin_log to drizzle_bin_log.
724
  if (drizzle_bin_log.is_open())
1 by brian
clean slate
725
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
726
    Query_log_event qinfo(session, session->query, session->query_length, 0,
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
727
			  /* suppress_use */ true);
1 by brian
clean slate
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
520.1.22 by Brian Aker
Second pass of thd cleanup
737
    session->clear_error();
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
738
    /* These DDL methods and logging protected with LOCK_drizzle_create_db */
586.1.1 by Yoshinori Sano
Rename mysql to drizzle, specifically mysql_bin_log to drizzle_bin_log.
739
    drizzle_bin_log.write(&qinfo);
1 by brian
clean slate
740
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
741
  my_ok(session, result);
1 by brian
clean slate
742
743
exit:
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
744
  pthread_mutex_unlock(&LOCK_drizzle_create_db);
520.1.22 by Brian Aker
Second pass of thd cleanup
745
  start_waiting_global_read_lock(session);
1 by brian
clean slate
746
exit2:
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
747
  return(error);
1 by brian
clean slate
748
}
749
750
751
/*
752
  Drop all tables in a database and the database itself
753
754
  SYNOPSIS
755
    mysql_rm_db()
520.1.22 by Brian Aker
Second pass of thd cleanup
756
    session			Thread handle
1 by brian
clean slate
757
    db			Database name in the case given by user
758
		        It's already validated and set to lower case
759
                        (if needed) when we come here
760
    if_exists		Don't give error if database doesn't exists
761
    silent		Don't generate errors
762
763
  RETURN
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
764
    false ok (Database dropped)
1 by brian
clean slate
765
    ERROR Error
766
*/
767
520.1.22 by Brian Aker
Second pass of thd cleanup
768
bool mysql_rm_db(Session *session,char *db,bool if_exists, bool silent)
1 by brian
clean slate
769
{
770
  long deleted=0;
253 by Brian Aker
Removed final my_bool from sql_db.
771
  int error= false;
1 by brian
clean slate
772
  char	path[FN_REFLEN+16];
773
  MY_DIR *dirp;
482 by Brian Aker
Remove uint.
774
  uint32_t length;
327.2.4 by Brian Aker
Refactoring table.h
775
  TableList* dropped_tables= 0;
1 by brian
clean slate
776
777
  if (db && (strcmp(db, "information_schema") == 0))
778
  {
575.4.7 by Monty Taylor
More header cleanup.
779
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
780
    return(true);
1 by brian
clean slate
781
  }
782
783
  /*
784
    Do not drop database if another thread is holding read lock.
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
785
    Wait for global read lock before acquiring LOCK_drizzle_create_db.
1 by brian
clean slate
786
    After wait_if_global_read_lock() we have protection against another
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
787
    global read lock. If we would acquire LOCK_drizzle_create_db first,
1 by brian
clean slate
788
    another thread could step in and get the global read lock before we
789
    reach wait_if_global_read_lock(). If this thread tries the same as we
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
790
    (admin a db), it would then go and wait on LOCK_drizzle_create_db...
1 by brian
clean slate
791
    Furthermore wait_if_global_read_lock() checks if the current thread
792
    has the global read lock and refuses the operation with
793
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
794
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
795
  if (wait_if_global_read_lock(session, 0, 1))
1 by brian
clean slate
796
  {
797
    error= -1;
798
    goto exit2;
799
  }
800
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
801
  pthread_mutex_lock(&LOCK_drizzle_create_db);
1 by brian
clean slate
802
803
  length= build_table_filename(path, sizeof(path), db, "", "", 0);
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
804
  strcpy(path+length, MY_DB_OPT_FILE);		// Append db option file name
1 by brian
clean slate
805
  del_dbopt(path);				// Remove dboption hash entry
806
  path[length]= '\0';				// Remove file name
807
808
  /* See if the directory exists */
809
  if (!(dirp= my_dir(path,MYF(MY_DONT_SORT))))
810
  {
811
    if (!if_exists)
812
    {
813
      error= -1;
814
      my_error(ER_DB_DROP_EXISTS, MYF(0), db);
815
      goto exit;
816
    }
817
    else
520.1.22 by Brian Aker
Second pass of thd cleanup
818
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1 by brian
clean slate
819
			  ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db);
820
  }
821
  else
822
  {
823
    pthread_mutex_lock(&LOCK_open);
824
    remove_db_from_cache(db);
825
    pthread_mutex_unlock(&LOCK_open);
826
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
827
1 by brian
clean slate
828
    error= -1;
520.1.22 by Brian Aker
Second pass of thd cleanup
829
    if ((deleted= mysql_rm_known_files(session, dirp, db, path, 0,
1 by brian
clean slate
830
                                       &dropped_tables)) >= 0)
831
    {
832
      ha_drop_database(path);
833
      error = 0;
834
    }
835
  }
836
  if (!silent && deleted>=0)
837
  {
838
    const char *query;
308 by Brian Aker
ulong conversion
839
    uint32_t query_length;
520.1.22 by Brian Aker
Second pass of thd cleanup
840
    if (!session->query)
1 by brian
clean slate
841
    {
842
      /* The client used the old obsolete mysql_drop_db() call */
843
      query= path;
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
844
      query_length= sprintf(path, "drop database `%s`", db);
1 by brian
clean slate
845
    }
846
    else
847
    {
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
848
      query= session->query;
520.1.22 by Brian Aker
Second pass of thd cleanup
849
      query_length= session->query_length;
1 by brian
clean slate
850
    }
586.1.1 by Yoshinori Sano
Rename mysql to drizzle, specifically mysql_bin_log to drizzle_bin_log.
851
    if (drizzle_bin_log.is_open())
1 by brian
clean slate
852
    {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
853
      Query_log_event qinfo(session, query, query_length, 0,
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
854
			    /* suppress_use */ true);
1 by brian
clean slate
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
520.1.22 by Brian Aker
Second pass of thd cleanup
863
      session->clear_error();
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
864
      /* These DDL methods and logging protected with LOCK_drizzle_create_db */
586.1.1 by Yoshinori Sano
Rename mysql to drizzle, specifically mysql_bin_log to drizzle_bin_log.
865
      drizzle_bin_log.write(&qinfo);
1 by brian
clean slate
866
    }
520.1.22 by Brian Aker
Second pass of thd cleanup
867
    session->clear_error();
868
    session->server_status|= SERVER_STATUS_DB_DROPPED;
869
    my_ok(session, (uint32_t) deleted);
870
    session->server_status&= ~SERVER_STATUS_DB_DROPPED;
1 by brian
clean slate
871
  }
586.1.1 by Yoshinori Sano
Rename mysql to drizzle, specifically mysql_bin_log to drizzle_bin_log.
872
  else if (drizzle_bin_log.is_open())
1 by brian
clean slate
873
  {
874
    char *query, *query_pos, *query_end, *query_data_start;
327.2.4 by Brian Aker
Refactoring table.h
875
    TableList *tbl;
482 by Brian Aker
Remove uint.
876
    uint32_t db_len;
1 by brian
clean slate
877
520.1.22 by Brian Aker
Second pass of thd cleanup
878
    if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
1 by brian
clean slate
879
      goto exit; /* not much else we can do */
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
880
    query_pos= query_data_start= strcpy(query,"drop table ")+11;
1 by brian
clean slate
881
    query_end= query + MAX_DROP_TABLE_Q_LEN;
882
    db_len= strlen(db);
883
884
    for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
885
    {
482 by Brian Aker
Remove uint.
886
      uint32_t tbl_name_len;
1 by brian
clean slate
887
888
      /* 3 for the quotes and the comma*/
889
      tbl_name_len= strlen(tbl->table_name) + 3;
890
      if (query_pos + tbl_name_len + 1 >= query_end)
891
      {
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
892
        /* These DDL methods and logging protected with LOCK_drizzle_create_db */
520.1.22 by Brian Aker
Second pass of thd cleanup
893
        write_to_binlog(session, query, query_pos -1 - query, db, db_len);
1 by brian
clean slate
894
        query_pos= query_data_start;
895
      }
896
897
      *query_pos++ = '`';
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
898
      query_pos= strcpy(query_pos,tbl->table_name) + (tbl_name_len-3);
1 by brian
clean slate
899
      *query_pos++ = '`';
900
      *query_pos++ = ',';
901
    }
902
903
    if (query_pos != query_data_start)
904
    {
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
905
      /* These DDL methods and logging protected with LOCK_drizzle_create_db */
520.1.22 by Brian Aker
Second pass of thd cleanup
906
      write_to_binlog(session, query, query_pos -1 - query, db, db_len);
1 by brian
clean slate
907
    }
908
  }
909
910
exit:
911
  /*
912
    If this database was the client's selected database, we silently
913
    change the client's selected database to nothing (to have an empty
520.1.22 by Brian Aker
Second pass of thd cleanup
914
    SELECT DATABASE() in the future). For this we free() session->db and set
1 by brian
clean slate
915
    it to 0.
916
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
917
  if (session->db && !strcmp(session->db, db))
918
    mysql_change_db_impl(session, NULL, session->variables.collation_server);
575.4.4 by Yoshinori Sano
Rename mysql to drizzle.
919
  pthread_mutex_unlock(&LOCK_drizzle_create_db);
520.1.22 by Brian Aker
Second pass of thd cleanup
920
  start_waiting_global_read_lock(session);
1 by brian
clean slate
921
exit2:
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
922
  return(error);
1 by brian
clean slate
923
}
924
925
/*
255 by Brian Aker
Removed RAID table delete point.
926
  Removes files with known extensions plus.
520.1.22 by Brian Aker
Second pass of thd cleanup
927
  session MUST be set when calling this function!
1 by brian
clean slate
928
*/
929
520.1.22 by Brian Aker
Second pass of thd cleanup
930
static long mysql_rm_known_files(Session *session, MY_DIR *dirp, const char *db,
482 by Brian Aker
Remove uint.
931
				 const char *org_path, uint32_t level,
327.2.4 by Brian Aker
Refactoring table.h
932
                                 TableList **dropped_tables)
1 by brian
clean slate
933
{
934
  long deleted=0;
308 by Brian Aker
ulong conversion
935
  uint32_t found_other_files=0;
1 by brian
clean slate
936
  char filePath[FN_REFLEN];
327.2.4 by Brian Aker
Refactoring table.h
937
  TableList *tot_list=0, **tot_list_next;
1 by brian
clean slate
938
939
  tot_list_next= &tot_list;
940
482 by Brian Aker
Remove uint.
941
  for (uint32_t idx=0 ;
520.1.22 by Brian Aker
Second pass of thd cleanup
942
       idx < (uint) dirp->number_off_files && !session->killed ;
1 by brian
clean slate
943
       idx++)
944
  {
945
    FILEINFO *file=dirp->dir_entry+idx;
946
    char *extension;
947
948
    /* skiping . and .. */
949
    if (file->name[0] == '.' && (!file->name[1] ||
950
       (file->name[1] == '.' &&  !file->name[2])))
951
      continue;
952
953
    if (!(extension= strrchr(file->name, '.')))
376 by Brian Aker
strend remove
954
      extension= strchr(file->name, '\0');
1 by brian
clean slate
955
    if (find_type(extension, &deletable_extentions,1+2) <= 0)
956
    {
584.2.7 by Stewart Smith
rename and delete tabledefinition protobuf file
957
      /*
958
        ass ass ass.
959
960
        strange checking for magic extensions that are then deleted if
961
        not reg_ext (i.e. .frm).
962
963
        and (previously) we'd err out on drop database if files not matching
964
        engine ha_known_exts() or deletable_extensions were present.
965
966
        presumably this was to avoid deleting other user data... except if that
967
        data happened to be in files ending in .BAK, .opt or .TMD. *fun*
968
       */
969
      find_type(extension, ha_known_exts(),1+2);
1 by brian
clean slate
970
      continue;
971
    }
972
    /* just for safety we use files_charset_info */
973
    if (db && !my_strcasecmp(files_charset_info,
974
                             extension, reg_ext))
975
    {
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
976
      uint32_t db_len= strlen(db);
977
1 by brian
clean slate
978
      /* Drop the table nicely */
979
      *extension= 0;			// Remove extension
327.2.4 by Brian Aker
Refactoring table.h
980
      TableList *table_list=(TableList*)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
981
                              session->calloc(sizeof(*table_list) +
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
982
                                          db_len + 1 +
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
983
                                          MYSQL50_TABLE_NAME_PREFIX_LENGTH +
1 by brian
clean slate
984
                                          strlen(file->name) + 1);
985
986
      if (!table_list)
987
        goto err;
988
      table_list->db= (char*) (table_list+1);
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
989
      table_list->table_name= strcpy(table_list->db, db) + db_len + 1;
398.1.10 by Monty Taylor
Actually removed VOID() this time.
990
      filename_to_tablename(file->name, table_list->table_name,
991
                            MYSQL50_TABLE_NAME_PREFIX_LENGTH +
992
                            strlen(file->name) + 1);
1 by brian
clean slate
993
      table_list->alias= table_list->table_name;	// If lower_case_table_names=2
584.2.1 by Stewart Smith
convert tmp_file_prefix to TMP_FILE_PREFIX to indicate it's a macro
994
      table_list->internal_tmp_table= is_prefix(file->name, TMP_FILE_PREFIX);
1 by brian
clean slate
995
      /* Link into list */
996
      (*tot_list_next)= table_list;
997
      tot_list_next= &table_list->next_local;
998
      deleted++;
999
    }
1000
    else
1001
    {
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
1002
      sprintf(filePath, "%s/%s", org_path, file->name);
1 by brian
clean slate
1003
      if (my_delete_with_symlink(filePath,MYF(MY_WME)))
1004
      {
1005
	goto err;
1006
      }
1007
    }
1008
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
1009
  if (session->killed ||
590.1.7 by Stewart Smith
remove mysql_frm_type
1010
      (tot_list && mysql_rm_table_part2(session, tot_list, 1, 0, 1)))
1 by brian
clean slate
1011
    goto err;
1012
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1013
  my_dirend(dirp);
1014
1 by brian
clean slate
1015
  if (dropped_tables)
1016
    *dropped_tables= tot_list;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1017
1 by brian
clean slate
1018
  /*
1019
    If the directory is a symbolic link, remove the link first, then
1020
    remove the directory the symbolic link pointed at
1021
  */
1022
  if (found_other_files)
1023
  {
1024
    my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST);
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1025
    return(-1);
1 by brian
clean slate
1026
  }
1027
  else
1028
  {
1029
    /* Don't give errors if we can't delete 'RAID' directory */
1030
    if (rm_dir_w_symlink(org_path, level == 0))
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1031
      return(-1);
1 by brian
clean slate
1032
  }
1033
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1034
  return(deleted);
1 by brian
clean slate
1035
1036
err:
1037
  my_dirend(dirp);
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1038
  return(-1);
1 by brian
clean slate
1039
}
1040
1041
1042
/*
1043
  Remove directory with symlink
1044
1045
  SYNOPSIS
1046
    rm_dir_w_symlink()
1047
    org_path    path of derictory
1048
    send_error  send errors
1049
  RETURN
1050
    0 OK
1051
    1 ERROR
1052
*/
1053
253 by Brian Aker
Removed final my_bool from sql_db.
1054
static bool rm_dir_w_symlink(const char *org_path, bool send_error)
1 by brian
clean slate
1055
{
1056
  char tmp_path[FN_REFLEN], *pos;
1057
  char *path= tmp_path;
1058
  unpack_filename(tmp_path, org_path);
1059
#ifdef HAVE_READLINK
1060
  int error;
1061
  char tmp2_path[FN_REFLEN];
1062
1063
  /* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
376 by Brian Aker
strend remove
1064
  pos= strchr(path, '\0');
1 by brian
clean slate
1065
  if (pos > path && pos[-1] == FN_LIBCHAR)
1066
    *--pos=0;
1067
1068
  if ((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0)
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1069
    return(1);
1 by brian
clean slate
1070
  if (!error)
1071
  {
1072
    if (my_delete(path, MYF(send_error ? MY_WME : 0)))
1073
    {
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1074
      return(send_error);
1 by brian
clean slate
1075
    }
1076
    /* Delete directory symbolic link pointed at */
1077
    path= tmp2_path;
1078
  }
1079
#endif
1080
  /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
376 by Brian Aker
strend remove
1081
  pos= strchr(path, '\0');
1 by brian
clean slate
1082
1083
  if (pos > path && pos[-1] == FN_LIBCHAR)
1084
    *--pos=0;
1085
  if (rmdir(path) < 0 && send_error)
1086
  {
1087
    my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1088
    return(1);
1 by brian
clean slate
1089
  }
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1090
  return(0);
1 by brian
clean slate
1091
}
1092
1093
1094
/**
1095
  @brief Internal implementation: switch current database to a valid one.
1096
520.1.22 by Brian Aker
Second pass of thd cleanup
1097
  @param session            Thread context.
1 by brian
clean slate
1098
  @param new_db_name    Name of the database to switch to. The function will
1099
                        take ownership of the name (the caller must not free
1100
                        the allocated memory). If the name is NULL, we're
1101
                        going to switch to NULL db.
1102
  @param new_db_charset Character set of the new database.
1103
*/
1104
520.1.22 by Brian Aker
Second pass of thd cleanup
1105
static void mysql_change_db_impl(Session *session,
1 by brian
clean slate
1106
                                 LEX_STRING *new_db_name,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
1107
                                 const CHARSET_INFO * const new_db_charset)
1 by brian
clean slate
1108
{
520.1.21 by Brian Aker
THD -> Session rename
1109
  /* 1. Change current database in Session. */
1 by brian
clean slate
1110
1111
  if (new_db_name == NULL)
1112
  {
1113
    /*
520.1.21 by Brian Aker
THD -> Session rename
1114
      Session::set_db() does all the job -- it frees previous database name and
1 by brian
clean slate
1115
      sets the new one.
1116
    */
1117
520.1.22 by Brian Aker
Second pass of thd cleanup
1118
    session->set_db(NULL, 0);
1 by brian
clean slate
1119
  }
575.4.7 by Monty Taylor
More header cleanup.
1120
  else if (my_strcasecmp(system_charset_info, new_db_name->str,
1121
                         INFORMATION_SCHEMA_NAME.c_str()) == 0)
1 by brian
clean slate
1122
  {
1123
    /*
520.1.21 by Brian Aker
THD -> Session rename
1124
      Here we must use Session::set_db(), because we want to copy
1 by brian
clean slate
1125
      INFORMATION_SCHEMA_NAME constant.
1126
    */
1127
575.4.7 by Monty Taylor
More header cleanup.
1128
    session->set_db(INFORMATION_SCHEMA_NAME.c_str(),
1129
                    INFORMATION_SCHEMA_NAME.length());
1 by brian
clean slate
1130
  }
1131
  else
1132
  {
1133
    /*
520.1.21 by Brian Aker
THD -> Session rename
1134
      Here we already have a copy of database name to be used in Session. So,
1135
      we just call Session::reset_db(). Since Session::reset_db() does not releases
1 by brian
clean slate
1136
      the previous database name, we should do it explicitly.
1137
    */
1138
520.1.22 by Brian Aker
Second pass of thd cleanup
1139
    if (session->db)
1140
      free(session->db);
1 by brian
clean slate
1141
520.1.22 by Brian Aker
Second pass of thd cleanup
1142
    session->reset_db(new_db_name->str, new_db_name->length);
1 by brian
clean slate
1143
  }
1144
1145
  /* 3. Update db-charset environment variables. */
1146
520.1.22 by Brian Aker
Second pass of thd cleanup
1147
  session->db_charset= new_db_charset;
1148
  session->variables.collation_database= new_db_charset;
1 by brian
clean slate
1149
}
1150
1151
1152
1153
/**
1154
  Backup the current database name before switch.
1155
520.1.22 by Brian Aker
Second pass of thd cleanup
1156
  @param[in]      session             thread handle
1 by brian
clean slate
1157
  @param[in, out] saved_db_name   IN: "str" points to a buffer where to store
1158
                                  the old database name, "length" contains the
1159
                                  buffer size
1160
                                  OUT: if the current (default) database is
1161
                                  not NULL, its name is copied to the
1162
                                  buffer pointed at by "str"
1163
                                  and "length" is updated accordingly.
1164
                                  Otherwise "str" is set to NULL and
1165
                                  "length" is set to 0.
1166
*/
1167
520.1.22 by Brian Aker
Second pass of thd cleanup
1168
static void backup_current_db_name(Session *session,
1 by brian
clean slate
1169
                                   LEX_STRING *saved_db_name)
1170
{
520.1.22 by Brian Aker
Second pass of thd cleanup
1171
  if (!session->db)
1 by brian
clean slate
1172
  {
1173
    /* No current (default) database selected. */
1174
1175
    saved_db_name->str= NULL;
1176
    saved_db_name->length= 0;
1177
  }
1178
  else
1179
  {
629.5.2 by Toru Maesaka
Second pass of replacing MySQL's strmake() with libc calls
1180
    strncpy(saved_db_name->str, session->db, saved_db_name->length - 1);
520.1.22 by Brian Aker
Second pass of thd cleanup
1181
    saved_db_name->length= session->db_length;
1 by brian
clean slate
1182
  }
1183
}
1184
1185
1186
/**
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1187
  Return true if db1_name is equal to db2_name, false otherwise.
1 by brian
clean slate
1188
1189
  The function allows to compare database names according to the MySQL
1190
  rules. The database names db1 and db2 are equal if:
1191
     - db1 is NULL and db2 is NULL;
1192
     or
1193
     - db1 is not-NULL, db2 is not-NULL, db1 is equal (ignoring case) to
1194
       db2 in system character set (UTF8).
1195
*/
1196
1197
static inline bool
1198
cmp_db_names(const char *db1_name,
1199
             const char *db2_name)
1200
{
1201
  return
1202
         /* db1 is NULL and db2 is NULL */
1203
         (!db1_name && !db2_name) ||
1204
1205
         /* db1 is not-NULL, db2 is not-NULL, db1 == db2. */
1206
         (db1_name && db2_name && my_strcasecmp(system_charset_info, db1_name, db2_name) == 0);
1207
}
1208
1209
1210
/**
1211
  @brief Change the current database and its attributes unconditionally.
1212
520.1.22 by Brian Aker
Second pass of thd cleanup
1213
  @param session          thread handle
1 by brian
clean slate
1214
  @param new_db_name  database name
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1215
  @param force_switch if force_switch is false, then the operation will fail if
1 by brian
clean slate
1216
1217
                        - new_db_name is NULL or empty;
1218
1219
                        - OR new database name is invalid
1220
                          (check_db_name() failed);
1221
1222
                        - OR user has no privilege on the new database;
1223
1224
                        - OR new database does not exist;
1225
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1226
                      if force_switch is true, then
1 by brian
clean slate
1227
1228
                        - if new_db_name is NULL or empty, the current
1229
                          database will be NULL, @@collation_database will
1230
                          be set to @@collation_server, the operation will
1231
                          succeed.
1232
1233
                        - if new database name is invalid
1234
                          (check_db_name() failed), the current database
1235
                          will be NULL, @@collation_database will be set to
1236
                          @@collation_server, but the operation will fail;
1237
1238
                        - user privileges will not be checked
520.1.21 by Brian Aker
THD -> Session rename
1239
                          (Session::db_access however is updated);
1 by brian
clean slate
1240
1241
                          TODO: is this really the intention?
1242
                                (see sp-security.test).
1243
1244
                        - if new database does not exist,the current database
1245
                          will be NULL, @@collation_database will be set to
1246
                          @@collation_server, a warning will be thrown, the
1247
                          operation will succeed.
1248
1249
  @details The function checks that the database name corresponds to a
1250
  valid and existent database, checks access rights and changes the current
1251
  database with database attributes (@@collation_database session variable,
520.1.21 by Brian Aker
THD -> Session rename
1252
  Session::db_access).
1 by brian
clean slate
1253
1254
  This function is not the only way to switch the database that is
1255
  currently employed. When the replication slave thread switches the
520.1.22 by Brian Aker
Second pass of thd cleanup
1256
  database before executing a query, it calls session->set_db directly.
1 by brian
clean slate
1257
  However, if the query, in turn, uses a stored routine, the stored routine
1258
  will use this function, even if it's run on the slave.
1259
1260
  This function allocates the name of the database on the system heap: this
1261
  is necessary to be able to uniformly change the database from any module
1262
  of the server. Up to 5.0 different modules were using different memory to
1263
  store the name of the database, and this led to memory corruption:
1264
  a stack pointer set by Stored Procedures was used by replication after
1265
  the stack address was long gone.
1266
1267
  @return Operation status
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1268
    @retval false Success
1269
    @retval true  Error
1 by brian
clean slate
1270
*/
1271
520.1.22 by Brian Aker
Second pass of thd cleanup
1272
bool mysql_change_db(Session *session, const LEX_STRING *new_db_name, bool force_switch)
1 by brian
clean slate
1273
{
1274
  LEX_STRING new_db_file_name;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
1275
  const CHARSET_INFO *db_default_cl;
1 by brian
clean slate
1276
1277
  if (new_db_name == NULL ||
1278
      new_db_name->length == 0)
1279
  {
1280
    if (force_switch)
1281
    {
1282
      /*
1283
        This can happen only if we're switching the current database back
1284
        after loading stored program. The thing is that loading of stored
1285
        program can happen when there is no current database.
1286
1287
        TODO: actually, new_db_name and new_db_name->str seem to be always
1288
        non-NULL. In case of stored program, new_db_name->str == "" and
1289
        new_db_name->length == 0.
1290
      */
1291
520.1.22 by Brian Aker
Second pass of thd cleanup
1292
      mysql_change_db_impl(session, NULL, session->variables.collation_server);
1 by brian
clean slate
1293
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1294
      return(false);
1 by brian
clean slate
1295
    }
1296
    else
1297
    {
1298
      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1299
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1300
      return(true);
1 by brian
clean slate
1301
    }
1302
  }
1303
1304
  if (my_strcasecmp(system_charset_info, new_db_name->str,
575.4.7 by Monty Taylor
More header cleanup.
1305
                    INFORMATION_SCHEMA_NAME.c_str()) == 0)
1 by brian
clean slate
1306
  {
1307
    /* Switch the current database to INFORMATION_SCHEMA. */
575.4.7 by Monty Taylor
More header cleanup.
1308
    /* const_cast<> is safe here: mysql_change_db_impl does a copy */
1309
    LEX_STRING is_name= { const_cast<char *>(INFORMATION_SCHEMA_NAME.c_str()),
1310
                          INFORMATION_SCHEMA_NAME.length() };
1311
    mysql_change_db_impl(session, &is_name, system_charset_info);
1 by brian
clean slate
1312
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1313
    return(false);
1 by brian
clean slate
1314
  }
1315
1316
  /*
1317
    Now we need to make a copy because check_db_name requires a
1318
    non-constant argument. Actually, it takes database file name.
1319
1320
    TODO: fix check_db_name().
1321
  */
1322
656.1.34 by Monty Taylor
Got closer...
1323
  new_db_file_name.length= new_db_name->length;
1324
  new_db_file_name.str= (char *)malloc(new_db_name->length + 1);
656.1.44 by Monty Taylor
Added some return checking.
1325
  if (new_db_file_name.str == NULL)
1326
    return(true);                             /* the error is set */
656.1.34 by Monty Taylor
Got closer...
1327
  memcpy(new_db_file_name.str, new_db_name->str, new_db_name->length);
1328
  new_db_file_name.str[new_db_name->length]= 0;
1329
1 by brian
clean slate
1330
1331
  /*
1332
    NOTE: if check_db_name() fails, we should throw an error in any case,
1333
    even if we are called from sp_head::execute().
1334
1335
    It's next to impossible however to get this error when we are called
1336
    from sp_head::execute(). But let's switch the current database to NULL
1337
    in this case to be sure.
1338
  */
1339
1340
  if (check_db_name(&new_db_file_name))
1341
  {
1342
    my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
1343
    free(new_db_file_name.str);
1 by brian
clean slate
1344
1345
    if (force_switch)
520.1.22 by Brian Aker
Second pass of thd cleanup
1346
      mysql_change_db_impl(session, NULL, session->variables.collation_server);
1 by brian
clean slate
1347
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1348
    return(true);
1 by brian
clean slate
1349
  }
1350
1351
  if (check_db_dir_existence(new_db_file_name.str))
1352
  {
1353
    if (force_switch)
1354
    {
1355
      /* Throw a warning and free new_db_file_name. */
1356
520.1.22 by Brian Aker
Second pass of thd cleanup
1357
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1 by brian
clean slate
1358
                          ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
1359
                          new_db_file_name.str);
1360
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
1361
      free(new_db_file_name.str);
1 by brian
clean slate
1362
1363
      /* Change db to NULL. */
1364
520.1.22 by Brian Aker
Second pass of thd cleanup
1365
      mysql_change_db_impl(session, NULL, session->variables.collation_server);
1 by brian
clean slate
1366
1367
      /* The operation succeed. */
1368
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1369
      return(false);
1 by brian
clean slate
1370
    }
1371
    else
1372
    {
1373
      /* Report an error and free new_db_file_name. */
1374
1375
      my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
1376
      free(new_db_file_name.str);
1 by brian
clean slate
1377
1378
      /* The operation failed. */
1379
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1380
      return(true);
1 by brian
clean slate
1381
    }
1382
  }
1383
1384
  /*
520.1.21 by Brian Aker
THD -> Session rename
1385
    NOTE: in mysql_change_db_impl() new_db_file_name is assigned to Session
1386
    attributes and will be freed in Session::~Session().
1 by brian
clean slate
1387
  */
1388
520.1.22 by Brian Aker
Second pass of thd cleanup
1389
  db_default_cl= get_default_db_collation(session, new_db_file_name.str);
1 by brian
clean slate
1390
520.1.22 by Brian Aker
Second pass of thd cleanup
1391
  mysql_change_db_impl(session, &new_db_file_name, db_default_cl);
1 by brian
clean slate
1392
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1393
  return(false);
1 by brian
clean slate
1394
}
1395
1396
1397
/**
1398
  Change the current database and its attributes if needed.
1399
520.1.22 by Brian Aker
Second pass of thd cleanup
1400
  @param          session             thread handle
1 by brian
clean slate
1401
  @param          new_db_name     database name
1402
  @param[in, out] saved_db_name   IN: "str" points to a buffer where to store
1403
                                  the old database name, "length" contains the
1404
                                  buffer size
1405
                                  OUT: if the current (default) database is
1406
                                  not NULL, its name is copied to the
1407
                                  buffer pointed at by "str"
1408
                                  and "length" is updated accordingly.
1409
                                  Otherwise "str" is set to NULL and
1410
                                  "length" is set to 0.
1411
  @param          force_switch    @see mysql_change_db()
1412
  @param[out]     cur_db_changed  out-flag to indicate whether the current
1413
                                  database has been changed (valid only if
1414
                                  the function suceeded)
1415
*/
1416
520.1.22 by Brian Aker
Second pass of thd cleanup
1417
bool mysql_opt_change_db(Session *session,
1 by brian
clean slate
1418
                         const LEX_STRING *new_db_name,
1419
                         LEX_STRING *saved_db_name,
1420
                         bool force_switch,
1421
                         bool *cur_db_changed)
1422
{
520.1.22 by Brian Aker
Second pass of thd cleanup
1423
  *cur_db_changed= !cmp_db_names(session->db, new_db_name->str);
1 by brian
clean slate
1424
1425
  if (!*cur_db_changed)
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1426
    return false;
1 by brian
clean slate
1427
520.1.22 by Brian Aker
Second pass of thd cleanup
1428
  backup_current_db_name(session, saved_db_name);
1 by brian
clean slate
1429
520.1.22 by Brian Aker
Second pass of thd cleanup
1430
  return mysql_change_db(session, new_db_name, force_switch);
1 by brian
clean slate
1431
}
1432
1433
1434
/*
1435
  Check if there is directory for the database name.
1436
1437
  SYNOPSIS
1438
    check_db_dir_existence()
1439
    db_name   database name
1440
1441
  RETURN VALUES
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1442
    false   There is directory for the specified database name.
1443
    true    The directory does not exist.
1 by brian
clean slate
1444
*/
1445
1446
bool check_db_dir_existence(const char *db_name)
1447
{
1448
  char db_dir_path[FN_REFLEN];
482 by Brian Aker
Remove uint.
1449
  uint32_t db_dir_path_len;
1 by brian
clean slate
1450
1451
  db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path),
1452
                                        db_name, "", "", 0);
1453
1454
  if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
1455
    db_dir_path[db_dir_path_len - 1]= 0;
1456
1457
  /* Check access. */
1458
1459
  return my_access(db_dir_path, F_OK);
1460
}