17
17
/* create and drop of databases */
22
#include <drizzled/message/schema.pb.h>
23
#include "drizzled/my_error.h"
24
#include "drizzled/internal/my_dir.h"
25
#include <drizzled/error.h>
26
#include <drizzled/gettext.h>
27
#include <drizzled/my_hash.h>
28
#include "drizzled/internal/m_string.h"
29
#include <drizzled/session.h>
30
#include <drizzled/db.h>
31
#include <drizzled/sql_base.h>
32
#include <drizzled/lock.h>
33
#include <drizzled/errmsg_print.h>
34
#include <drizzled/replication_services.h>
35
#include <drizzled/message/schema.pb.h>
36
#include "drizzled/sql_table.h"
37
#include "drizzled/plugin/info_schema_table.h"
38
#include "drizzled/global_charset_info.h"
39
#include "drizzled/pthread_globals.h"
40
#include "drizzled/charset.h"
42
#include "drizzled/internal/my_sys.h"
45
using namespace drizzled;
47
#define MY_DB_OPT_FILE "db.opt"
19
#include "mysql_priv.h"
20
#include <mysys_err.h>
48
25
#define MAX_DROP_TABLE_Q_LEN 1024
50
const char *del_exts[]= {".dfe", ".blk", ".arz", ".BAK", ".TMD",".opt", NULL};
27
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
51
28
static TYPELIB deletable_extentions=
52
29
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
54
static long mysql_rm_known_files(Session *session, MY_DIR *dirp,
55
const char *db, const char *path,
56
TableList **dropped_tables);
31
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
32
const char *db, const char *path, uint level,
33
TABLE_LIST **dropped_tables);
35
static long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path);
36
static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error);
37
static void mysql_change_db_impl(THD *thd,
38
LEX_STRING *new_db_name,
39
CHARSET_INFO *new_db_charset);
42
/* Database lock hash */
44
pthread_mutex_t LOCK_lock_db;
45
int creating_database= 0; // how many database locks are made
48
/* Structure for database lock */
49
typedef struct my_dblock_st
51
char *name; /* Database name */
52
uint name_length; /* Database length name */
60
extern "C" uchar* lock_db_get_key(my_dblock_t *, size_t *, my_bool not_used);
62
uchar* lock_db_get_key(my_dblock_t *ptr, size_t *length,
63
my_bool not_used __attribute__((unused)))
65
*length= ptr->name_length;
66
return (uchar*) ptr->name;
71
Free lock_db hash element.
74
extern "C" void lock_db_free_element(void *ptr);
76
void lock_db_free_element(void *ptr)
83
Put a database lock entry into the hash.
86
Insert a database lock entry into hash.
87
LOCK_db_lock must be previously locked.
94
static my_bool lock_db_insert(const char *dbname, uint length)
98
DBUG_ENTER("lock_db_insert");
100
safe_mutex_assert_owner(&LOCK_lock_db);
102
if (!(opt= (my_dblock_t*) hash_search(&lock_db_cache,
103
(uchar*) dbname, length)))
105
/* Db is not in the hash, insert it */
107
if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
108
&opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
116
strmov(opt->name, dbname);
117
opt->name_length= length;
119
if ((error= my_hash_insert(&lock_db_cache, (uchar*) opt)))
120
my_free(opt, MYF(0));
129
Delete a database lock entry from hash.
132
void lock_db_delete(const char *name, uint length)
135
safe_mutex_assert_owner(&LOCK_lock_db);
136
if ((opt= (my_dblock_t *)hash_search(&lock_db_cache,
137
(const uchar*) name, length)))
138
hash_delete(&lock_db_cache, (uchar*) opt);
142
/* Database options hash */
143
static HASH dboptions;
144
static my_bool dboptions_init= 0;
145
static rw_lock_t LOCK_dboptions;
147
/* Structure for database options */
148
typedef struct my_dbopt_st
150
char *name; /* Database name */
151
uint name_length; /* Database length name */
152
CHARSET_INFO *charset; /* Database default character set */
157
Function we use in the creation of our hash to get key.
160
extern "C" uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
163
uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
164
my_bool not_used __attribute__((unused)))
166
*length= opt->name_length;
167
return (uchar*) opt->name;
172
Helper function to write a query to binlog used by mysql_rm_db()
175
static inline void write_to_binlog(THD *thd, char *query, uint q_len,
176
char *db, uint db_len)
178
Query_log_event qinfo(thd, query, q_len, 0, 0);
181
qinfo.db_len= db_len;
182
mysql_bin_log.write(&qinfo);
187
Function to free dboptions hash element
190
extern "C" void free_dbopt(void *dbopt);
192
void free_dbopt(void *dbopt)
194
my_free((uchar*) dbopt, MYF(0));
199
Initialize database option hash and locked database hash.
205
Must be called before any other database function is called.
212
bool my_database_names_init(void)
215
(void) my_rwlock_init(&LOCK_dboptions, NULL);
219
error= hash_init(&dboptions, lower_case_table_names ?
220
&my_charset_bin : system_charset_info,
221
32, 0, 0, (hash_get_key) dboptions_get_key,
223
hash_init(&lock_db_cache, lower_case_table_names ?
224
&my_charset_bin : system_charset_info,
225
32, 0, 0, (hash_get_key) lock_db_get_key,
226
lock_db_free_element,0);
235
Free database option hash and locked databases hash.
238
void my_database_names_free(void)
243
hash_free(&dboptions);
244
(void) rwlock_destroy(&LOCK_dboptions);
245
hash_free(&lock_db_cache);
251
Cleanup cached options
254
void my_dbopt_cleanup(void)
256
rw_wrlock(&LOCK_dboptions);
257
hash_free(&dboptions);
258
hash_init(&dboptions, lower_case_table_names ?
259
&my_charset_bin : system_charset_info,
260
32, 0, 0, (hash_get_key) dboptions_get_key,
262
rw_unlock(&LOCK_dboptions);
267
Find database options in the hash.
270
Search a database options in the hash, usings its path.
271
Fills "create" on success.
278
static my_bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
284
length= (uint) strlen(dbname);
286
rw_rdlock(&LOCK_dboptions);
287
if ((opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
289
create->default_table_charset= opt->charset;
292
rw_unlock(&LOCK_dboptions);
298
Writes database options into the hash.
301
Inserts database options into the hash, or updates
302
options if they are already in the hash.
309
static my_bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
314
DBUG_ENTER("put_dbopt");
316
length= (uint) strlen(dbname);
318
rw_wrlock(&LOCK_dboptions);
319
if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
321
/* Options are not in the hash, insert them */
323
if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
324
&opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
332
strmov(opt->name, dbname);
333
opt->name_length= length;
335
if ((error= my_hash_insert(&dboptions, (uchar*) opt)))
337
my_free(opt, MYF(0));
342
/* Update / write options in hash */
343
opt->charset= create->default_table_charset;
346
rw_unlock(&LOCK_dboptions);
352
Deletes database options from the hash.
355
void del_dbopt(const char *path)
358
rw_wrlock(&LOCK_dboptions);
359
if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const uchar*) path,
361
hash_delete(&dboptions, (uchar*) opt);
362
rw_unlock(&LOCK_dboptions);
367
Create database options file:
370
Currently database default charset is only stored there.
374
1 Could not create file or write to it. Error sent through my_error()
377
static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
380
char buf[256]; // Should be enough for one option
383
if (!create->default_table_charset)
384
create->default_table_charset= thd->variables.collation_server;
386
if (put_dbopt(path, create))
389
if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
392
length= (ulong) (strxnmov(buf, sizeof(buf)-1, "default-character-set=",
393
create->default_table_charset->csname,
394
"\ndefault-collation=",
395
create->default_table_charset->name,
398
/* Error is written by my_write */
399
if (!my_write(file,(uchar*) buf, length, MYF(MY_NABP+MY_WME)))
401
my_close(file,MYF(0));
408
Load database options file
411
path Path for option file
412
create Where to store the read options
418
1 No database file or could not open it
422
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
426
DBUG_ENTER("load_db_opt");
430
bzero((char*) create,sizeof(*create));
431
create->default_table_charset= thd->variables.collation_server;
433
/* Check if options for this database are already in the hash */
434
if (!get_dbopt(path, create))
437
/* Otherwise, load options from the .opt file */
438
if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
442
if (init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0)))
445
while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0)
447
char *pos= buf+nbytes-1;
448
/* Remove end space and control characters */
449
while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1]))
452
if ((pos= strchr(buf, '=')))
454
if (!strncmp(buf,"default-character-set", (pos-buf)))
457
Try character set name, and if it fails
458
try collation name, probably it's an old
459
4.1.0 db.opt file, which didn't have
460
separate default-character-set and
461
default-collation commands.
463
if (!(create->default_table_charset=
464
get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(0))) &&
465
!(create->default_table_charset=
466
get_charset_by_name(pos+1, MYF(0))))
468
sql_print_error("Error while loading database options: '%s':",path);
469
sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1);
470
create->default_table_charset= default_charset_info;
473
else if (!strncmp(buf,"default-collation", (pos-buf)))
475
if (!(create->default_table_charset= get_charset_by_name(pos+1,
478
sql_print_error("Error while loading database options: '%s':",path);
479
sql_print_error(ER(ER_UNKNOWN_COLLATION),pos+1);
480
create->default_table_charset= default_charset_info;
486
Put the loaded value into the hash.
487
Note that another thread could've added the same
488
entry to the hash after we called get_dbopt(),
489
but it's not an error, as put_dbopt() takes this
490
possibility into account.
492
error= put_dbopt(path, create);
494
end_io_cache(&cache);
496
my_close(file,MYF(0));
503
Retrieve database options by name. Load database options file or fetch from
507
load_db_opt_by_name()
508
db_name Database name
509
db_create_info Where to store the database options
512
load_db_opt_by_name() is a shortcut for load_db_opt().
515
Although load_db_opt_by_name() (and load_db_opt()) returns status of
516
the operation, it is useless usually and should be ignored. The problem
517
is that there are 1) system databases ("mysql") and 2) virtual
518
databases ("information_schema"), which do not contain options file.
519
So, load_db_opt[_by_name]() returns FALSE for these databases, but this
522
load_db_opt[_by_name]() clears db_create_info structure in any case, so
523
even on failure it contains valid data. So, common use case is just
524
call load_db_opt[_by_name]() without checking return value and use
525
db_create_info right after that.
527
RETURN VALUES (read NOTE!)
529
TRUE Failed to retrieve options
532
bool load_db_opt_by_name(THD *thd, const char *db_name,
533
HA_CREATE_INFO *db_create_info)
535
char db_opt_path[FN_REFLEN];
538
Pass an empty file name, and the database options file name as extension
539
to avoid table name to file name encoding.
541
(void) build_table_filename(db_opt_path, sizeof(db_opt_path),
542
db_name, "", MY_DB_OPT_FILE, 0);
544
return load_db_opt(thd, db_opt_path, db_create_info);
59
549
Return default database collation.
61
@param session Thread context.
551
@param thd Thread context.
62
552
@param db_name Database name.
64
554
@return CHARSET_INFO object. The operation always return valid character
65
555
set, even if the database does not exist.
68
const CHARSET_INFO *get_default_db_collation(const char *db_name)
72
get_database_metadata(db_name, &db);
74
/* If for some reason the db.opt file lacks a collation,
75
we just return the default */
77
if (db.has_collation())
79
const string buffer= db.collation();
80
const CHARSET_INFO* cs= get_charset_by_name(buffer.c_str());
84
errmsg_printf(ERRMSG_LVL_ERROR,
85
_("Error while loading database options: '%s':"),db_name);
86
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
88
return default_charset_info;
94
return default_charset_info;
97
/* path is path to database, not schema file */
98
static int write_schema_file(const DatabasePathName &path, const message::Schema &db)
100
char schema_file_tmp[FN_REFLEN];
101
string schema_file(path.to_string());
103
snprintf(schema_file_tmp, FN_REFLEN, "%s%c%s.tmpXXXXXX", path.to_string().c_str(), FN_LIBCHAR, MY_DB_OPT_FILE);
105
schema_file.append(1, FN_LIBCHAR);
106
schema_file.append(MY_DB_OPT_FILE);
108
int fd= mkstemp(schema_file_tmp);
114
if (!db.SerializeToFileDescriptor(fd))
117
unlink(schema_file_tmp);
121
if (rename(schema_file_tmp, schema_file.c_str()) == -1)
131
int get_database_metadata(const char *dbname, message::Schema *db)
133
char db_opt_path[FN_REFLEN];
558
CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
560
HA_CREATE_INFO db_info;
562
if (thd->db != NULL && strcmp(db_name, thd->db) == 0)
563
return thd->db_charset;
565
load_db_opt_by_name(thd, db_name, &db_info);
137
Pass an empty file name, and the database options file name as extension
138
to avoid table name to file name encoding.
568
NOTE: even if load_db_opt_by_name() fails,
569
db_info.default_table_charset contains valid character set
570
(collation_server). We should not fail if load_db_opt_by_name() fails,
571
because it is valid case. If a database has been created just by
572
"mkdir", it does not contain db.opt file, but it is valid database.
140
length= build_table_filename(db_opt_path, sizeof(db_opt_path),
142
strcpy(db_opt_path + length, MY_DB_OPT_FILE);
144
int fd= open(db_opt_path, O_RDONLY);
149
if (!db->ParseFromFileDescriptor(fd))
575
return db_info.default_table_charset;
160
580
Create a database
163
583
mysql_create_db()
164
session Thread handler
165
585
db Name of database to create
166
586
Function assumes that this is already validated.
167
587
create_info Database create options (like character set)
588
silent Used by replication when internally creating a database.
589
In this case the entry should not be logged.
170
592
1. Report back to client that command succeeded (my_ok)
171
593
2. Report errors to client
172
594
3. Log event to binary log
595
(The 'silent' flags turns off 1 and 3.)
180
bool mysql_create_db(Session *session, const NormalisedDatabaseName &database_name, message::Schema *schema_message, bool is_if_not_exists)
603
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
182
ReplicationServices &replication_services= ReplicationServices::singleton();
606
char path[FN_REFLEN+16];
607
char tmp_query[FN_REFLEN+16];
186
DatabasePathName database_path(database_name);
610
struct stat stat_info;
611
uint create_options= create_info ? create_info->options : 0;
613
DBUG_ENTER("mysql_create_db");
188
615
/* do not create 'information_schema' db */
189
if (!my_strcasecmp(system_charset_info, database_name.to_string().c_str(), INFORMATION_SCHEMA_NAME.c_str()))
616
if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.str))
191
my_error(ER_DB_CREATE_EXISTS, MYF(0), database_name.to_string().c_str());
618
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
195
assert(database_name.isValid());
196
schema_message->set_name(database_name.to_string());
199
623
Do not create database if another thread is holding read lock.
200
Wait for global read lock before acquiring LOCK_create_db.
624
Wait for global read lock before acquiring LOCK_mysql_create_db.
201
625
After wait_if_global_read_lock() we have protection against another
202
global read lock. If we would acquire LOCK_create_db first,
626
global read lock. If we would acquire LOCK_mysql_create_db first,
203
627
another thread could step in and get the global read lock before we
204
628
reach wait_if_global_read_lock(). If this thread tries the same as we
205
(admin a db), it would then go and wait on LOCK_create_db...
629
(admin a db), it would then go and wait on LOCK_mysql_create_db...
206
630
Furthermore wait_if_global_read_lock() checks if the current thread
207
631
has the global read lock and refuses the operation with
208
632
ER_CANT_UPDATE_WITH_READLOCK if applicable.
210
if (wait_if_global_read_lock(session, 0, 1))
634
if (wait_if_global_read_lock(thd, 0, 1))
216
pthread_mutex_lock(&LOCK_create_db);
218
if (mkdir(database_path.to_string().c_str(),0777) == -1)
640
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
642
/* Check directory */
643
path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
644
path[path_len-1]= 0; // Remove last '/' from path
646
if (!stat(path,&stat_info))
648
if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
222
if (! is_if_not_exists)
224
my_error(ER_DB_CREATE_EXISTS, MYF(0), database_name.to_string().c_str());
228
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
229
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
230
database_name.to_string().c_str());
650
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
236
my_error(ER_CANT_CREATE_DB, MYF(0), database_name.to_string().c_str(), errno);
654
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
655
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
241
error_erno= write_schema_file(database_path, *schema_message);
242
if (error_erno && error_erno != EEXIST)
244
if (rmdir(database_path.to_string().c_str()) >= 0)
253
replication_services.rawStatement(session, session->query, session->query_length);
254
session->my_ok(result);
665
my_error(EE_STAT, MYF(0), path, errno);
668
if (my_mkdir(path,0777,MYF(0)) < 0)
670
my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
676
path[path_len-1]= FN_LIBCHAR;
677
strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
678
if (write_db_opt(thd, path, create_info))
681
Could not create options file.
682
Restore things to beginning.
685
if (rmdir(path) >= 0)
691
We come here when we managed to create the database, but not the option
692
file. In this case it's best to just continue as if nothing has
693
happened. (This is a very unlikely senario)
702
if (!thd->query) // Only in replication
705
query_length= (uint) (strxmov(tmp_query,"create database `",
706
db, "`", NullS) - tmp_query);
711
query_length= thd->query_length;
714
ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
718
if (mysql_bin_log.is_open())
720
Query_log_event qinfo(thd, query, query_length, 0,
721
/* suppress_use */ TRUE);
724
Write should use the database being created as the "current
725
database" and not the threads current database, which is the
726
default. If we do not change the "current database" to the
727
database being created, the CREATE statement will not be
728
replicated when using --binlog-do-db to select databases to be
731
An example (--binlog-do-db=sisyfos):
733
CREATE DATABASE bob; # Not replicated
734
USE bob; # 'bob' is the current database
735
CREATE DATABASE sisyfos; # Not replicated since 'bob' is
737
USE sisyfos; # Will give error on slave since
738
# database does not exist.
741
qinfo.db_len = strlen(db);
743
/* These DDL methods and logging protected with LOCK_mysql_create_db */
744
mysql_bin_log.write(&qinfo);
257
pthread_mutex_unlock(&LOCK_create_db);
258
start_waiting_global_read_lock(session);
750
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
751
start_waiting_global_read_lock(thd);
264
757
/* db-name is already validated when we come here */
266
bool mysql_alter_db(Session *session, const NormalisedDatabaseName &database_name, message::Schema *schema_message)
759
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
268
ReplicationServices &replication_services= ReplicationServices::singleton();
761
char path[FN_REFLEN+16];
271
DatabasePathName database_path(database_name);
764
DBUG_ENTER("mysql_alter_db");
274
767
Do not alter database if another thread is holding read lock.
275
Wait for global read lock before acquiring LOCK_create_db.
768
Wait for global read lock before acquiring LOCK_mysql_create_db.
276
769
After wait_if_global_read_lock() we have protection against another
277
global read lock. If we would acquire LOCK_create_db first,
770
global read lock. If we would acquire LOCK_mysql_create_db first,
278
771
another thread could step in and get the global read lock before we
279
772
reach wait_if_global_read_lock(). If this thread tries the same as we
280
(admin a db), it would then go and wait on LOCK_create_db...
773
(admin a db), it would then go and wait on LOCK_mysql_create_db...
281
774
Furthermore wait_if_global_read_lock() checks if the current thread
282
775
has the global read lock and refuses the operation with
283
776
ER_CANT_UPDATE_WITH_READLOCK if applicable.
285
if ((error=wait_if_global_read_lock(session,0,1)))
288
assert(schema_message);
289
assert(database_name.isValid());
291
schema_message->set_name(database_name.to_string());
293
pthread_mutex_lock(&LOCK_create_db);
295
error= write_schema_file(database_path, *schema_message);
296
if (error && error != EEXIST)
298
/* TODO: find some witty way of getting back an error message */
299
pthread_mutex_unlock(&LOCK_create_db);
303
replication_services.rawStatement(session, session->getQueryString(), session->getQueryLength());
304
session->my_ok(result);
306
pthread_mutex_unlock(&LOCK_create_db);
307
start_waiting_global_read_lock(session);
778
if ((error=wait_if_global_read_lock(thd,0,1)))
781
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
784
Recreate db options file: /dbpath/.db.opt
785
We pass MY_DB_OPT_FILE as "extension" to avoid
786
"table name to file name" encoding.
788
build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0);
789
if ((error=write_db_opt(thd, path, create_info)))
792
/* Change options if current database is being altered. */
794
if (thd->db && !strcmp(thd->db,db))
796
thd->db_charset= create_info->default_table_charset ?
797
create_info->default_table_charset :
798
thd->variables.collation_server;
799
thd->variables.collation_database= thd->db_charset;
802
ha_binlog_log_query(thd, 0, LOGCOM_ALTER_DB,
803
thd->query, thd->query_length,
806
if (mysql_bin_log.is_open())
808
Query_log_event qinfo(thd, thd->query, thd->query_length, 0,
809
/* suppress_use */ TRUE);
812
Write should use the database being created as the "current
813
database" and not the threads current database, which is the
817
qinfo.db_len = strlen(db);
820
/* These DDL methods and logging protected with LOCK_mysql_create_db */
821
mysql_bin_log.write(&qinfo);
309
return error ? true : false;
826
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
827
start_waiting_global_read_lock(thd);
457
1003
If this database was the client's selected database, we silently
458
1004
change the client's selected database to nothing (to have an empty
459
SELECT DATABASE() in the future). For this we free() session->db and set
1005
SELECT DATABASE() in the future). For this we free() thd->db and set
462
if (! session->db.empty() && session->db.compare(database_name.to_string()) == 0)
464
pthread_mutex_unlock(&LOCK_create_db);
465
start_waiting_global_read_lock(session);
1008
if (thd->db && !strcmp(thd->db, db))
1009
mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
1010
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
1011
start_waiting_global_read_lock(thd);
471
static int rm_table_part2(Session *session, TableList *tables)
476
bool foreign_key_error= false;
478
pthread_mutex_lock(&LOCK_open); /* Part 2 of rm a table */
481
If we have the table in the definition cache, we don't have to check the
482
.frm cursor to find if the table is a normal table (not view) and what
486
for (table= tables; table; table= table->next_local)
489
table->db_type= NULL;
490
if ((share= TableShare::getShare(table->db, table->table_name)))
491
table->db_type= share->db_type();
494
if (lock_table_names_exclusively(session, tables))
496
pthread_mutex_unlock(&LOCK_open);
500
/* Don't give warnings for not found errors, as we already generate notes */
501
session->no_warnings_for_error= 1;
503
for (table= tables; table; table= table->next_local)
506
plugin::StorageEngine *table_type;
508
error= session->drop_temporary_table(table);
512
// removed temporary table
516
goto err_with_placeholders;
518
// temporary table not found
522
table_type= table->db_type;
526
abort_locked_tables(session, db, table->table_name);
527
remove_table_from_cache(session, db, table->table_name,
528
RTFC_WAIT_OTHER_THREAD_FLAG |
529
RTFC_CHECK_KILLED_FLAG);
531
If the table was used in lock tables, remember it so that
532
unlock_table_names can free it
534
if ((locked_table= drop_locked_tables(session, db, table->table_name)))
535
table->table= locked_table;
540
goto err_with_placeholders;
544
TableIdentifier identifier(db, table->table_name, table->internal_tmp_table ? INTERNAL_TMP_TABLE : NO_TMP_TABLE);
546
if ((table_type == NULL
547
&& (plugin::StorageEngine::getTableDefinition(*session,
548
identifier) != EEXIST)))
550
// Table was not found on disk and table can't be created from engine
551
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
552
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
557
error= plugin::StorageEngine::dropTable(*session,
561
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
564
session->clear_error();
567
if (error == HA_ERR_ROW_IS_REFERENCED)
569
/* the table is referenced by a foreign key constraint */
570
foreign_key_error= true;
574
if (error == 0 || (foreign_key_error == false))
575
write_bin_log_drop_table(session, true, db, table->table_name);
579
if (wrong_tables.length())
580
wrong_tables.append(',');
581
wrong_tables.append(String(table->table_name,system_charset_info));
585
It's safe to unlock LOCK_open: we have an exclusive lock
588
pthread_mutex_unlock(&LOCK_open);
590
if (wrong_tables.length())
592
if (!foreign_key_error)
593
my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
594
wrong_tables.c_ptr());
597
my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
602
pthread_mutex_lock(&LOCK_open); /* final bit in rm table lock */
603
err_with_placeholders:
604
unlock_table_names(tables, NULL);
605
pthread_mutex_unlock(&LOCK_open);
606
session->no_warnings_for_error= 0;
612
Removes files with known extensions plus.
613
session MUST be set when calling this function!
1017
Removes files with known extensions plus all found subdirectories that
1018
are 2 hex digits (raid directories).
1019
thd MUST be set when calling this function!
616
static long mysql_rm_known_files(Session *session, MY_DIR *dirp, const char *db,
617
const char *org_path,
618
TableList **dropped_tables)
1022
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
1023
const char *org_path, uint level,
1024
TABLE_LIST **dropped_tables)
1027
ulong found_other_files=0;
621
1028
char filePath[FN_REFLEN];
622
TableList *tot_list= NULL, **tot_list_next;
1029
TABLE_LIST *tot_list=0, **tot_list_next;
1030
List<String> raid_dirs;
1031
DBUG_ENTER("mysql_rm_known_files");
1032
DBUG_PRINT("enter",("path: %s", org_path));
624
1034
tot_list_next= &tot_list;
626
for (uint32_t idx= 0;
627
idx < (uint32_t) dirp->number_off_files && !session->killed ;
1037
idx < (uint) dirp->number_off_files && !thd->killed ;
630
1040
FILEINFO *file=dirp->dir_entry+idx;
631
1041
char *extension;
1042
DBUG_PRINT("info",("Examining: %s", file->name));
633
1044
/* skiping . and .. */
634
1045
if (file->name[0] == '.' && (!file->name[1] ||
635
1046
(file->name[1] == '.' && !file->name[2])))
1049
/* Check if file is a raid directory */
1050
if ((my_isdigit(system_charset_info, file->name[0]) ||
1051
(file->name[0] >= 'a' && file->name[0] <= 'f')) &&
1052
(my_isdigit(system_charset_info, file->name[1]) ||
1053
(file->name[1] >= 'a' && file->name[1] <= 'f')) &&
1054
!file->name[2] && !level)
1056
char newpath[FN_REFLEN], *copy_of_path;
1061
strxmov(newpath,org_path,"/",file->name,NullS);
1062
length= unpack_filename(newpath,newpath);
1063
if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT))))
1065
DBUG_PRINT("my",("New subdir found: %s", newpath));
1066
if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1,0)) < 0)
1068
if (!(copy_of_path= (char*) thd->memdup(newpath, length+1)) ||
1069
!(dir= new (thd->mem_root) String(copy_of_path, length,
1070
&my_charset_bin)) ||
1071
raid_dirs.push_back(dir))
1075
found_other_files++;
1078
else if (file->name[0] == 'a' && file->name[1] == 'r' &&
1079
file->name[2] == 'c' && file->name[3] == '\0')
1082
char newpath[FN_REFLEN];
1084
strxmov(newpath, org_path, "/", "arc", NullS);
1085
(void) unpack_filename(newpath, newpath);
1086
if ((new_dirp = my_dir(newpath, MYF(MY_DONT_SORT))))
1088
DBUG_PRINT("my",("Archive subdir found: %s", newpath));
1089
if ((mysql_rm_arc_files(thd, new_dirp, newpath)) < 0)
1093
found_other_files++;
638
1096
if (!(extension= strrchr(file->name, '.')))
639
extension= strchr(file->name, '\0');
1097
extension= strend(file->name);
640
1098
if (find_type(extension, &deletable_extentions,1+2) <= 0)
645
strange checking for magic extensions that are then deleted if
646
not reg_ext (i.e. .frm).
648
and (previously) we'd err out on drop database if files not matching
649
engine ha_known_exts() or deletable_extensions were present.
651
presumably this was to avoid deleting other user data... except if that
652
data happened to be in files ending in .BAK, .opt or .TMD. *fun*
1100
if (find_type(extension, ha_known_exts(),1+2) <= 0)
1101
found_other_files++;
656
1104
/* just for safety we use files_charset_info */
657
1105
if (db && !my_strcasecmp(files_charset_info,
1106
extension, reg_ext))
660
uint32_t db_len= strlen(db);
662
1108
/* Drop the table nicely */
663
1109
*extension= 0; // Remove extension
664
TableList *table_list=(TableList*)
665
session->calloc(sizeof(*table_list) +
1110
TABLE_LIST *table_list=(TABLE_LIST*)
1111
thd->calloc(sizeof(*table_list) +
1113
MYSQL50_TABLE_NAME_PREFIX_LENGTH +
667
1114
strlen(file->name) + 1);
669
1116
if (!table_list)
671
1118
table_list->db= (char*) (table_list+1);
672
table_list->table_name= strcpy(table_list->db, db) + db_len + 1;
673
filename_to_tablename(file->name, table_list->table_name,
674
strlen(file->name) + 1);
675
table_list->alias= table_list->table_name; // If lower_case_table_names=2
676
table_list->internal_tmp_table= (strncmp(file->name,
678
strlen(TMP_FILE_PREFIX)) == 0);
1119
table_list->table_name= strmov(table_list->db, db) + 1;
1120
VOID(filename_to_tablename(file->name, table_list->table_name,
1121
MYSQL50_TABLE_NAME_PREFIX_LENGTH +
1122
strlen(file->name) + 1));
1123
table_list->alias= table_list->table_name; // If lower_case_table_names=2
1124
table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix);
679
1125
/* Link into list */
680
1126
(*tot_list_next)= table_list;
681
1127
tot_list_next= &table_list->next_local;
686
sprintf(filePath, "%s/%s", org_path, file->name);
1132
strxmov(filePath, org_path, "/", file->name, NullS);
687
1133
if (my_delete_with_symlink(filePath,MYF(MY_WME)))
1140
(tot_list && mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1)))
1143
/* Remove RAID directories */
698
if (rm_table_part2(session, tot_list))
1145
List_iterator<String> it(raid_dirs);
1148
if (rmdir(dir->c_ptr()) < 0)
1149
found_other_files++;
704
1153
if (dropped_tables)
705
1154
*dropped_tables= tot_list;
709
my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, errno);
1157
If the directory is a symbolic link, remove the link first, then
1158
remove the directory the symbolic link pointed at
1160
if (found_other_files)
1162
my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST);
1167
/* Don't give errors if we can't delete 'RAID' directory */
1168
if (rm_dir_w_symlink(org_path, level == 0))
1172
DBUG_RETURN(deleted);
1181
Remove directory with symlink
1185
org_path path of derictory
1186
send_error send errors
1192
static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error)
1194
char tmp_path[FN_REFLEN], *pos;
1195
char *path= tmp_path;
1196
DBUG_ENTER("rm_dir_w_symlink");
1197
unpack_filename(tmp_path, org_path);
1198
#ifdef HAVE_READLINK
1200
char tmp2_path[FN_REFLEN];
1202
/* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
1204
if (pos > path && pos[-1] == FN_LIBCHAR)
1207
if ((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0)
1211
if (my_delete(path, MYF(send_error ? MY_WME : 0)))
1213
DBUG_RETURN(send_error);
1215
/* Delete directory symbolic link pointed at */
1219
/* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
1222
if (pos > path && pos[-1] == FN_LIBCHAR)
1224
if (rmdir(path) < 0 && send_error)
1226
my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
1234
Remove .frm archives from directory
1238
dirp list of files in archive directory
1240
org_path path of archive directory
1243
> 0 number of removed files
1246
static long mysql_rm_arc_files(THD *thd, MY_DIR *dirp,
1247
const char *org_path)
1250
ulong found_other_files= 0;
1251
char filePath[FN_REFLEN];
1252
DBUG_ENTER("mysql_rm_arc_files");
1253
DBUG_PRINT("enter", ("path: %s", org_path));
1256
idx < (uint) dirp->number_off_files && !thd->killed ;
1259
FILEINFO *file=dirp->dir_entry+idx;
1260
char *extension, *revision;
1261
DBUG_PRINT("info",("Examining: %s", file->name));
1263
/* skiping . and .. */
1264
if (file->name[0] == '.' && (!file->name[1] ||
1265
(file->name[1] == '.' && !file->name[2])))
1268
extension= fn_ext(file->name);
1269
if (extension[0] != '.' ||
1270
extension[1] != 'f' || extension[2] != 'r' ||
1271
extension[3] != 'm' || extension[4] != '-')
1273
found_other_files++;
1276
revision= extension+5;
1277
while (*revision && my_isdigit(system_charset_info, *revision))
1281
found_other_files++;
1284
strxmov(filePath, org_path, "/", file->name, NullS);
1285
if (my_delete_with_symlink(filePath,MYF(MY_WME)))
1296
If the directory is a symbolic link, remove the link first, then
1297
remove the directory the symbolic link pointed at
1299
if (!found_other_files &&
1300
rm_dir_w_symlink(org_path, 0))
1302
DBUG_RETURN(deleted);
1311
@brief Internal implementation: switch current database to a valid one.
1313
@param thd Thread context.
1314
@param new_db_name Name of the database to switch to. The function will
1315
take ownership of the name (the caller must not free
1316
the allocated memory). If the name is NULL, we're
1317
going to switch to NULL db.
1318
@param new_db_charset Character set of the new database.
1321
static void mysql_change_db_impl(THD *thd,
1322
LEX_STRING *new_db_name,
1323
CHARSET_INFO *new_db_charset)
1325
/* 1. Change current database in THD. */
1327
if (new_db_name == NULL)
1330
THD::set_db() does all the job -- it frees previous database name and
1334
thd->set_db(NULL, 0);
1336
else if (new_db_name == &INFORMATION_SCHEMA_NAME)
1339
Here we must use THD::set_db(), because we want to copy
1340
INFORMATION_SCHEMA_NAME constant.
1343
thd->set_db(INFORMATION_SCHEMA_NAME.str, INFORMATION_SCHEMA_NAME.length);
1348
Here we already have a copy of database name to be used in THD. So,
1349
we just call THD::reset_db(). Since THD::reset_db() does not releases
1350
the previous database name, we should do it explicitly.
1355
thd->reset_db(new_db_name->str, new_db_name->length);
1358
/* 3. Update db-charset environment variables. */
1360
thd->db_charset= new_db_charset;
1361
thd->variables.collation_database= new_db_charset;
1367
Backup the current database name before switch.
1369
@param[in] thd thread handle
1370
@param[in, out] saved_db_name IN: "str" points to a buffer where to store
1371
the old database name, "length" contains the
1373
OUT: if the current (default) database is
1374
not NULL, its name is copied to the
1375
buffer pointed at by "str"
1376
and "length" is updated accordingly.
1377
Otherwise "str" is set to NULL and
1378
"length" is set to 0.
1381
static void backup_current_db_name(THD *thd,
1382
LEX_STRING *saved_db_name)
1386
/* No current (default) database selected. */
1388
saved_db_name->str= NULL;
1389
saved_db_name->length= 0;
1393
strmake(saved_db_name->str, thd->db, saved_db_name->length - 1);
1394
saved_db_name->length= thd->db_length;
1400
Return TRUE if db1_name is equal to db2_name, FALSE otherwise.
1402
The function allows to compare database names according to the MySQL
1403
rules. The database names db1 and db2 are equal if:
1404
- db1 is NULL and db2 is NULL;
1406
- db1 is not-NULL, db2 is not-NULL, db1 is equal (ignoring case) to
1407
db2 in system character set (UTF8).
1411
cmp_db_names(const char *db1_name,
1412
const char *db2_name)
1415
/* db1 is NULL and db2 is NULL */
1416
(!db1_name && !db2_name) ||
1418
/* db1 is not-NULL, db2 is not-NULL, db1 == db2. */
1419
(db1_name && db2_name && my_strcasecmp(system_charset_info, db1_name, db2_name) == 0);
721
1424
@brief Change the current database and its attributes unconditionally.
723
@param session thread handle
1426
@param thd thread handle
724
1427
@param new_db_name database name
725
@param force_switch if force_switch is false, then the operation will fail if
1428
@param force_switch if force_switch is FALSE, then the operation will fail if
727
1430
- new_db_name is NULL or empty;
801
1549
from sp_head::execute(). But let's switch the current database to NULL
802
1550
in this case to be sure.
804
if (! normalised_database_name.isValid())
1553
if (check_db_name(&new_db_file_name))
806
my_error(ER_WRONG_DB_NAME, MYF(0),
807
normalised_database_name.to_string().c_str());
1555
my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
1556
my_free(new_db_file_name.str, MYF(0));
809
1558
if (force_switch)
1559
mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
815
DatabasePathName database_path(normalised_database_name);
817
if (! database_path.exists())
1564
DBUG_PRINT("info",("Use database: %s", new_db_file_name.str));
1567
if (check_db_dir_existence(new_db_file_name.str))
819
1569
if (force_switch)
821
1571
/* Throw a warning and free new_db_file_name. */
823
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1573
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
824
1574
ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
825
normalised_database_name.to_string().c_str());
1575
new_db_file_name.str);
1577
my_free(new_db_file_name.str, MYF(0));
827
1579
/* Change db to NULL. */
1581
mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
831
1583
/* The operation succeed. */
837
1589
/* Report an error and free new_db_file_name. */
839
my_error(ER_BAD_DB_ERROR, MYF(0),
840
normalised_database_name.to_string().c_str());
1591
my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
1592
my_free(new_db_file_name.str, MYF(0));
842
1594
/* The operation failed. */
848
db_default_cl= get_default_db_collation(normalised_database_name.to_string().c_str());
850
session->set_db(normalised_database_name);
855
NormalisedDatabaseName::NormalisedDatabaseName(const NonNormalisedDatabaseName &dbname)
857
const std::string &non_norm_string= dbname.to_string();
858
database_name= (char*)malloc(non_norm_string.size()+1);
860
assert(database_name); /* FIXME: should throw exception */
862
strncpy(database_name, non_norm_string.c_str(), non_norm_string.size()+1);
864
my_casedn_str(files_charset_info, database_name);
867
NormalisedDatabaseName::~NormalisedDatabaseName()
872
bool NormalisedDatabaseName::isValid() const
874
LEX_STRING db_lexstring;
876
db_lexstring.str= database_name;
877
db_lexstring.length= strlen(database_name);
879
if (db_lexstring.length == 0
880
|| db_lexstring.length > NAME_LEN
881
|| database_name[db_lexstring.length - 1] == ' ')
884
return (! check_identifier_name(&db_lexstring));
887
DatabasePathName::DatabasePathName(const NormalisedDatabaseName &database_name)
1601
NOTE: in mysql_change_db_impl() new_db_file_name is assigned to THD
1602
attributes and will be freed in THD::~THD().
1605
db_default_cl= get_default_db_collation(thd, new_db_file_name.str);
1607
mysql_change_db_impl(thd, &new_db_file_name, db_default_cl);
1614
Change the current database and its attributes if needed.
1616
@param thd thread handle
1617
@param new_db_name database name
1618
@param[in, out] saved_db_name IN: "str" points to a buffer where to store
1619
the old database name, "length" contains the
1621
OUT: if the current (default) database is
1622
not NULL, its name is copied to the
1623
buffer pointed at by "str"
1624
and "length" is updated accordingly.
1625
Otherwise "str" is set to NULL and
1626
"length" is set to 0.
1627
@param force_switch @see mysql_change_db()
1628
@param[out] cur_db_changed out-flag to indicate whether the current
1629
database has been changed (valid only if
1630
the function suceeded)
1633
bool mysql_opt_change_db(THD *thd,
1634
const LEX_STRING *new_db_name,
1635
LEX_STRING *saved_db_name,
1637
bool *cur_db_changed)
1639
*cur_db_changed= !cmp_db_names(thd->db, new_db_name->str);
1641
if (!*cur_db_changed)
1644
backup_current_db_name(thd, saved_db_name);
1646
return mysql_change_db(thd, new_db_name, force_switch);
1651
lock_databases(THD *thd, const char *db1, uint length1,
1652
const char *db2, uint length2)
1654
pthread_mutex_lock(&LOCK_lock_db);
1655
while (!thd->killed &&
1656
(hash_search(&lock_db_cache,(uchar*) db1, length1) ||
1657
hash_search(&lock_db_cache,(uchar*) db2, length2)))
1659
wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
1660
pthread_mutex_lock(&LOCK_lock_db);
1665
pthread_mutex_unlock(&LOCK_lock_db);
1669
lock_db_insert(db1, length1);
1670
lock_db_insert(db2, length2);
1671
creating_database++;
1674
Wait if a concurent thread is creating a table at the same time.
1675
The assumption here is that it will not take too long until
1676
there is a point in time when a table is not created.
1679
while (!thd->killed && creating_table)
1681
wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
1682
pthread_mutex_lock(&LOCK_lock_db);
1687
lock_db_delete(db1, length1);
1688
lock_db_delete(db2, length2);
1689
creating_database--;
1690
pthread_mutex_unlock(&LOCK_lock_db);
1691
pthread_cond_signal(&COND_refresh);
1696
We can unlock now as the hash will protect against anyone creating a table
1697
in the databases we are using
1699
pthread_mutex_unlock(&LOCK_lock_db);
1705
Upgrade a 5.0 database.
1706
This function is invoked whenever an ALTER DATABASE UPGRADE query is executed:
1707
ALTER DATABASE 'olddb' UPGRADE DATA DIRECTORY NAME.
1709
If we have managed to rename (move) tables to the new database
1710
but something failed on a later step, then we store the
1711
RENAME DATABASE event in the log. mysql_rename_db() is atomic in
1712
the sense that it will rename all or none of the tables.
1714
@param thd Current thread
1715
@param old_db 5.0 database name, in #mysql50#name format
1716
@return 0 on success, 1 on error
1718
bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db)
1720
int error= 0, change_to_newdb= 0;
1721
char path[FN_REFLEN+16];
1723
HA_CREATE_INFO create_info;
1725
TABLE_LIST *table_list;
1726
SELECT_LEX *sl= thd->lex->current_select;
1728
DBUG_ENTER("mysql_upgrade_db");
1730
if ((old_db->length <= MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
1731
(strncmp(old_db->str,
1732
MYSQL50_TABLE_NAME_PREFIX,
1733
MYSQL50_TABLE_NAME_PREFIX_LENGTH) != 0))
1735
my_error(ER_WRONG_USAGE, MYF(0),
1736
"ALTER DATABASE UPGRADE DATA DIRECTORY NAME",
1741
/* `#mysql50#<name>` converted to encoded `<name>` */
1742
new_db.str= old_db->str + MYSQL50_TABLE_NAME_PREFIX_LENGTH;
1743
new_db.length= old_db->length - MYSQL50_TABLE_NAME_PREFIX_LENGTH;
1745
if (lock_databases(thd, old_db->str, old_db->length,
1746
new_db.str, new_db.length))
1750
Let's remember if we should do "USE newdb" afterwards.
1751
thd->db will be cleared in mysql_rename_db()
1753
if (thd->db && !strcmp(thd->db, old_db->str))
1756
build_table_filename(path, sizeof(path)-1,
1757
old_db->str, "", MY_DB_OPT_FILE, 0);
1758
if ((load_db_opt(thd, path, &create_info)))
1759
create_info.default_table_charset= thd->variables.collation_server;
1761
length= build_table_filename(path, sizeof(path)-1, old_db->str, "", "", 0);
1762
if (length && path[length-1] == FN_LIBCHAR)
1763
path[length-1]=0; // remove ending '\'
1764
if ((error= my_access(path,F_OK)))
1766
my_error(ER_BAD_DB_ERROR, MYF(0), old_db->str);
1770
/* Step1: Create the new database */
1771
if ((error= mysql_create_db(thd, new_db.str, &create_info, 1)))
1774
/* Step2: Move tables to the new database */
1775
if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
1777
uint nfiles= (uint) dirp->number_off_files;
1778
for (uint idx=0 ; idx < nfiles && !thd->killed ; idx++)
1780
FILEINFO *file= dirp->dir_entry + idx;
1781
char *extension, tname[FN_REFLEN];
1782
LEX_STRING table_str;
1783
DBUG_PRINT("info",("Examining: %s", file->name));
1785
/* skiping non-FRM files */
1786
if (my_strcasecmp(files_charset_info,
1787
(extension= fn_rext(file->name)), reg_ext))
1790
/* A frm file found, add the table info rename list */
1793
table_str.length= filename_to_tablename(file->name,
1794
tname, sizeof(tname)-1);
1795
table_str.str= (char*) sql_memdup(tname, table_str.length + 1);
1796
Table_ident *old_ident= new Table_ident(thd, *old_db, table_str, 0);
1797
Table_ident *new_ident= new Table_ident(thd, new_db, table_str, 0);
1798
if (!old_ident || !new_ident ||
1799
!sl->add_table_to_list(thd, old_ident, NULL,
1800
TL_OPTION_UPDATING, TL_IGNORE) ||
1801
!sl->add_table_to_list(thd, new_ident, NULL,
1802
TL_OPTION_UPDATING, TL_IGNORE))
1812
if ((table_list= thd->lex->query_tables) &&
1813
(error= mysql_rename_tables(thd, table_list, 1)))
1816
Failed to move all tables from the old database to the new one.
1817
In the best case mysql_rename_tables() moved all tables back to the old
1818
database. In the worst case mysql_rename_tables() moved some tables
1819
to the new database, then failed, then started to move the tables back,
1820
and then failed again. In this situation we have some tables in the
1821
old database and some tables in the new database.
1822
Let's delete the option file, and then the new database directory.
1823
If some tables were left in the new directory, rmdir() will fail.
1824
It garantees we never loose any tables.
1826
build_table_filename(path, sizeof(path)-1,
1827
new_db.str,"",MY_DB_OPT_FILE, 0);
1828
my_delete(path, MYF(MY_WME));
1829
length= build_table_filename(path, sizeof(path)-1, new_db.str, "", "", 0);
1830
if (length && path[length-1] == FN_LIBCHAR)
1831
path[length-1]=0; // remove ending '\'
1837
if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
1839
uint nfiles= (uint) dirp->number_off_files;
1840
for (uint idx=0 ; idx < nfiles ; idx++)
1842
FILEINFO *file= dirp->dir_entry + idx;
1843
char oldname[FN_REFLEN], newname[FN_REFLEN];
1844
DBUG_PRINT("info",("Examining: %s", file->name));
1846
/* skiping . and .. and MY_DB_OPT_FILE */
1847
if ((file->name[0] == '.' &&
1848
(!file->name[1] || (file->name[1] == '.' && !file->name[2]))) ||
1849
!my_strcasecmp(files_charset_info, file->name, MY_DB_OPT_FILE))
1852
/* pass empty file name, and file->name as extension to avoid encoding */
1853
build_table_filename(oldname, sizeof(oldname)-1,
1854
old_db->str, "", file->name, 0);
1855
build_table_filename(newname, sizeof(newname)-1,
1856
new_db.str, "", file->name, 0);
1857
my_rename(oldname, newname, MYF(MY_WME));
1863
Step7: drop the old database.
1864
remove_db_from_cache(olddb) and query_cache_invalidate(olddb)
1865
are done inside mysql_rm_db(), no needs to execute them again.
1866
mysql_rm_db() also "unuses" if we drop the current database.
1868
error= mysql_rm_db(thd, old_db->str, 0, 1);
1870
/* Step8: logging */
1871
if (mysql_bin_log.is_open())
1873
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, TRUE);
1875
mysql_bin_log.write(&qinfo);
1878
/* Step9: Let's do "use newdb" if we renamed the current database */
1879
if (change_to_newdb)
1880
error|= mysql_change_db(thd, & new_db, FALSE);
1883
pthread_mutex_lock(&LOCK_lock_db);
1884
/* Remove the databases from db lock cache */
1885
lock_db_delete(old_db->str, old_db->length);
1886
lock_db_delete(new_db.str, new_db.length);
1887
creating_database--;
1888
/* Signal waiting CREATE TABLE's to continue */
1889
pthread_cond_signal(&COND_refresh);
1890
pthread_mutex_unlock(&LOCK_lock_db);
1898
Check if there is directory for the database name.
1901
check_db_dir_existence()
1902
db_name database name
1905
FALSE There is directory for the specified database name.
1906
TRUE The directory does not exist.
1909
bool check_db_dir_existence(const char *db_name)
889
1911
char db_dir_path[FN_REFLEN];
890
uint32_t db_dir_path_len;
1912
uint db_dir_path_len;
892
1914
db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path),
893
database_name.to_string().c_str(),
1915
db_name, "", "", 0);
896
1917
if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
897
1918
db_dir_path[db_dir_path_len - 1]= 0;
899
database_path.assign(db_dir_path);
902
bool DatabasePathName::exists() const
904
/* TODO: handle EIO and other fun errors */
905
return access(database_path.c_str(), F_OK) == 0;
1922
return my_access(db_dir_path, F_OK);