17
17
/* create and drop of databases */
22
#include <sys/types.h>
20
#include <drizzled/serialize/serialize.h>
28
#include <drizzled/message/schema.pb.h>
29
#include "drizzled/error.h"
30
#include <drizzled/gettext.h>
31
#include <drizzled/my_hash.h>
32
#include "drizzled/internal/m_string.h"
33
#include <drizzled/session.h>
34
#include <drizzled/db.h>
35
#include <drizzled/sql_base.h>
36
#include <drizzled/lock.h>
37
#include <drizzled/errmsg_print.h>
38
#include <drizzled/replication_services.h>
39
#include <drizzled/message/schema.pb.h>
40
#include "drizzled/sql_table.h"
41
#include "drizzled/plugin/info_schema_table.h"
42
#include "drizzled/global_charset_info.h"
43
#include "drizzled/pthread_globals.h"
44
#include "drizzled/charset.h"
46
#include "drizzled/internal/my_sys.h"
48
#define MY_DB_OPT_FILE "db.opt"
49
#define MAX_DROP_TABLE_Q_LEN 1024
21
51
using namespace std;
22
#include <drizzled/server_includes.h>
23
#include <mysys/mysys_err.h>
24
#include <mysys/my_dir.h>
26
#include <drizzled/drizzled_error_messages.h>
29
#define MAX_DROP_TABLE_Q_LEN 1024
31
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
32
static TYPELIB deletable_extentions=
33
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
35
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
36
const char *db, const char *path, uint level,
37
TABLE_LIST **dropped_tables);
39
static bool rm_dir_w_symlink(const char *org_path, bool send_error);
40
static void mysql_change_db_impl(THD *thd,
41
LEX_STRING *new_db_name,
42
const CHARSET_INFO * const new_db_charset);
45
/* Database lock hash */
47
pthread_mutex_t LOCK_lock_db;
48
int creating_database= 0; // how many database locks are made
51
/* Structure for database lock */
52
typedef struct my_dblock_st
54
char *name; /* Database name */
55
uint name_length; /* Database length name */
63
extern "C" uchar* lock_db_get_key(my_dblock_t *, size_t *, bool not_used);
65
uchar* lock_db_get_key(my_dblock_t *ptr, size_t *length,
66
bool not_used __attribute__((unused)))
68
*length= ptr->name_length;
69
return (uchar*) ptr->name;
74
Free lock_db hash element.
77
extern "C" void lock_db_free_element(void *ptr);
79
void lock_db_free_element(void *ptr)
86
Delete a database lock entry from hash.
89
void lock_db_delete(const char *name, uint length)
92
safe_mutex_assert_owner(&LOCK_lock_db);
93
if ((opt= (my_dblock_t *)hash_search(&lock_db_cache,
94
(const uchar*) name, length)))
95
hash_delete(&lock_db_cache, (uchar*) opt);
99
/* Database options hash */
100
static HASH dboptions;
101
static bool dboptions_init= 0;
102
static rw_lock_t LOCK_dboptions;
104
/* Structure for database options */
105
typedef struct my_dbopt_st
107
char *name; /* Database name */
108
uint name_length; /* Database length name */
109
const CHARSET_INFO *charset; /* Database default character set */
114
Function we use in the creation of our hash to get key.
117
extern "C" uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
120
uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
121
bool not_used __attribute__((unused)))
123
*length= opt->name_length;
124
return (uchar*) opt->name;
129
Helper function to write a query to binlog used by mysql_rm_db()
132
static inline void write_to_binlog(THD *thd, char *query, uint q_len,
133
char *db, uint db_len)
135
Query_log_event qinfo(thd, query, q_len, 0, 0);
138
qinfo.db_len= db_len;
139
mysql_bin_log.write(&qinfo);
144
Function to free dboptions hash element
147
extern "C" void free_dbopt(void *dbopt);
149
void free_dbopt(void *dbopt)
151
my_free((uchar*) dbopt, MYF(0));
156
Initialize database option hash and locked database hash.
162
Must be called before any other database function is called.
169
bool my_database_names_init(void)
172
(void) my_rwlock_init(&LOCK_dboptions, NULL);
176
error= hash_init(&dboptions, lower_case_table_names ?
177
&my_charset_bin : system_charset_info,
178
32, 0, 0, (hash_get_key) dboptions_get_key,
180
hash_init(&lock_db_cache, lower_case_table_names ?
181
&my_charset_bin : system_charset_info,
182
32, 0, 0, (hash_get_key) lock_db_get_key,
183
lock_db_free_element,0);
192
Free database option hash and locked databases hash.
195
void my_database_names_free(void)
200
hash_free(&dboptions);
201
(void) rwlock_destroy(&LOCK_dboptions);
202
hash_free(&lock_db_cache);
208
Cleanup cached options
211
void my_dbopt_cleanup(void)
213
rw_wrlock(&LOCK_dboptions);
214
hash_free(&dboptions);
215
hash_init(&dboptions, lower_case_table_names ?
216
&my_charset_bin : system_charset_info,
217
32, 0, 0, (hash_get_key) dboptions_get_key,
219
rw_unlock(&LOCK_dboptions);
224
Find database options in the hash.
227
Search a database options in the hash, usings its path.
228
Fills "create" on success.
235
static bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
241
length= (uint) strlen(dbname);
243
rw_rdlock(&LOCK_dboptions);
244
if ((opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
246
create->default_table_charset= opt->charset;
249
rw_unlock(&LOCK_dboptions);
255
Writes database options into the hash.
258
Inserts database options into the hash, or updates
259
options if they are already in the hash.
266
static bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
272
length= (uint) strlen(dbname);
274
rw_wrlock(&LOCK_dboptions);
275
if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
277
/* Options are not in the hash, insert them */
279
if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
280
&opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
288
stpcpy(opt->name, dbname);
289
opt->name_length= length;
291
if ((error= my_hash_insert(&dboptions, (uchar*) opt)))
293
my_free(opt, MYF(0));
298
/* Update / write options in hash */
299
opt->charset= create->default_table_charset;
302
rw_unlock(&LOCK_dboptions);
308
Deletes database options from the hash.
311
void del_dbopt(const char *path)
314
rw_wrlock(&LOCK_dboptions);
315
if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const uchar*) path,
317
hash_delete(&dboptions, (uchar*) opt);
318
rw_unlock(&LOCK_dboptions);
323
Create database options file:
326
Currently database default charset is only stored there.
330
1 Could not create file or write to it. Error sent through my_error()
333
static bool write_db_opt(THD *thd, const char *path, const char *name, HA_CREATE_INFO *create)
340
if (!create->default_table_charset)
341
create->default_table_charset= thd->variables.collation_server;
343
if (put_dbopt(path, create))
347
db.set_characterset(create->default_table_charset->csname);
348
db.set_collation(create->default_table_charset->name);
350
fstream output(path, ios::out | ios::trunc | ios::binary);
351
if (!db.SerializeToOstream(&output))
359
Load database options file
362
path Path for option file
363
create Where to store the read options
369
1 No database file or could not open it
373
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
379
memset(create, 0, sizeof(*create));
380
create->default_table_charset= thd->variables.collation_server;
382
/* Check if options for this database are already in the hash */
383
if (!get_dbopt(path, create))
386
fstream input(path, ios::in | ios::binary);
389
else if (!db.ParseFromIstream(&input))
392
buffer= db.characterset();
393
if (!(create->default_table_charset= get_charset_by_csname(buffer.c_str(), MY_CS_PRIMARY, MYF(0))))
395
sql_print_error("Error while loading database options: '%s':",path);
396
sql_print_error(ER(ER_UNKNOWN_COLLATION), buffer.c_str());
397
create->default_table_charset= default_charset_info;
400
buffer= db.collation();
401
if (!(create->default_table_charset= get_charset_by_name(buffer.c_str(), MYF(0))))
403
sql_print_error("Error while loading database options: '%s':",path);
404
sql_print_error(ER(ER_UNKNOWN_COLLATION), buffer.c_str());
405
create->default_table_charset= default_charset_info;
409
Put the loaded value into the hash.
410
Note that another thread could've added the same
411
entry to the hash after we called get_dbopt(),
412
but it's not an error, as put_dbopt() takes this
413
possibility into account.
415
error= put_dbopt(path, create);
423
Retrieve database options by name. Load database options file or fetch from
427
load_db_opt_by_name()
428
db_name Database name
429
db_create_info Where to store the database options
432
load_db_opt_by_name() is a shortcut for load_db_opt().
435
Although load_db_opt_by_name() (and load_db_opt()) returns status of
436
the operation, it is useless usually and should be ignored. The problem
437
is that there are 1) system databases ("mysql") and 2) virtual
438
databases ("information_schema"), which do not contain options file.
439
So, load_db_opt[_by_name]() returns false for these databases, but this
442
load_db_opt[_by_name]() clears db_create_info structure in any case, so
443
even on failure it contains valid data. So, common use case is just
444
call load_db_opt[_by_name]() without checking return value and use
445
db_create_info right after that.
447
RETURN VALUES (read NOTE!)
449
true Failed to retrieve options
452
bool load_db_opt_by_name(THD *thd, const char *db_name,
453
HA_CREATE_INFO *db_create_info)
455
char db_opt_path[FN_REFLEN];
458
Pass an empty file name, and the database options file name as extension
459
to avoid table name to file name encoding.
461
(void) build_table_filename(db_opt_path, sizeof(db_opt_path),
462
db_name, "", MY_DB_OPT_FILE, 0);
464
return load_db_opt(thd, db_opt_path, db_create_info);
56
const string del_exts[]= {".dfe", ".blk", ".arz", ".BAK", ".TMD", ".opt"};
57
static set<string> deletable_extentions(del_exts, &del_exts[sizeof(del_exts)/sizeof(del_exts[0])]);
60
static long mysql_rm_known_files(Session *session, CachedDirectory &dirp,
61
const string &db, const char *path,
62
TableList **dropped_tables);
63
static void mysql_change_db_impl(Session *session, LEX_STRING *new_db_name);
469
66
Return default database collation.
471
@param thd Thread context.
68
@param session Thread context.
472
69
@param db_name Database name.
474
71
@return CHARSET_INFO object. The operation always return valid character
475
72
set, even if the database does not exist.
478
const CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
480
HA_CREATE_INFO db_info;
482
if (thd->db != NULL && strcmp(db_name, thd->db) == 0)
483
return thd->db_charset;
485
load_db_opt_by_name(thd, db_name, &db_info);
75
const CHARSET_INFO *get_default_db_collation(const char *db_name)
79
get_database_metadata(db_name, &db);
81
/* If for some reason the db.opt file lacks a collation,
82
we just return the default */
84
if (db.has_collation())
86
const string buffer= db.collation();
87
const CHARSET_INFO* cs= get_charset_by_name(buffer.c_str());
91
errmsg_printf(ERRMSG_LVL_ERROR,
92
_("Error while loading database options: '%s':"),db_name);
93
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
95
return default_charset_info;
101
return default_charset_info;
104
/* path is path to database, not schema file */
105
static int write_schema_file(const char *path, const message::Schema &db)
107
char schema_file_tmp[FN_REFLEN];
108
string schema_file(path);
110
snprintf(schema_file_tmp, FN_REFLEN, "%s%c%s.tmpXXXXXX", path, FN_LIBCHAR, MY_DB_OPT_FILE);
112
schema_file.append(1, FN_LIBCHAR);
113
schema_file.append(MY_DB_OPT_FILE);
115
int fd= mkstemp(schema_file_tmp);
121
if (!db.SerializeToFileDescriptor(fd))
124
unlink(schema_file_tmp);
128
if (rename(schema_file_tmp, schema_file.c_str()) == -1)
138
int get_database_metadata(const char *dbname, message::Schema *db)
140
char db_opt_path[FN_REFLEN];
488
NOTE: even if load_db_opt_by_name() fails,
489
db_info.default_table_charset contains valid character set
490
(collation_server). We should not fail if load_db_opt_by_name() fails,
491
because it is valid case. If a database has been created just by
492
"mkdir", it does not contain db.opt file, but it is valid database.
144
Pass an empty file name, and the database options file name as extension
145
to avoid table name to file name encoding.
495
return db_info.default_table_charset;
147
length= build_table_filename(db_opt_path, sizeof(db_opt_path),
149
strcpy(db_opt_path + length, MY_DB_OPT_FILE);
151
int fd= open(db_opt_path, O_RDONLY);
156
if (!db->ParseFromFileDescriptor(fd))
500
167
Create a database
503
170
mysql_create_db()
171
session Thread handler
505
172
db Name of database to create
506
173
Function assumes that this is already validated.
507
174
create_info Database create options (like character set)
508
silent Used by replication when internally creating a database.
509
In this case the entry should not be logged.
512
177
1. Report back to client that command succeeded (my_ok)
513
178
2. Report errors to client
514
179
3. Log event to binary log
515
(The 'silent' flags turns off 1 and 3.)
523
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent)
187
bool mysql_create_db(Session *session, const char *db, message::Schema *schema_message, bool is_if_not_exists)
525
char path[FN_REFLEN+16];
526
char tmp_query[FN_REFLEN+16];
189
ReplicationServices &replication_services= ReplicationServices::singleton();
529
struct stat stat_info;
530
uint create_options= create_info ? create_info->options : 0;
533
194
/* do not create 'information_schema' db */
534
if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.str))
195
if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.c_str()))
536
197
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
201
schema_message->set_name(db);
541
204
Do not create database if another thread is holding read lock.
542
Wait for global read lock before acquiring LOCK_mysql_create_db.
205
Wait for global read lock before acquiring LOCK_create_db.
543
206
After wait_if_global_read_lock() we have protection against another
544
global read lock. If we would acquire LOCK_mysql_create_db first,
207
global read lock. If we would acquire LOCK_create_db first,
545
208
another thread could step in and get the global read lock before we
546
209
reach wait_if_global_read_lock(). If this thread tries the same as we
547
(admin a db), it would then go and wait on LOCK_mysql_create_db...
210
(admin a db), it would then go and wait on LOCK_create_db...
548
211
Furthermore wait_if_global_read_lock() checks if the current thread
549
212
has the global read lock and refuses the operation with
550
213
ER_CANT_UPDATE_WITH_READLOCK if applicable.
552
if (wait_if_global_read_lock(thd, 0, 1))
215
if (wait_if_global_read_lock(session, 0, 1))
558
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
560
/* Check directory */
561
path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
562
path[path_len-1]= 0; // Remove last '/' from path
564
if (!stat(path,&stat_info))
221
pthread_mutex_lock(&LOCK_create_db);
223
/* check directory */
224
char path[FN_REFLEN+16];
226
path_len= build_table_filename(path, sizeof(path), db, "", false);
227
path[path_len-1]= 0; // remove last '/' from path
229
if (mkdir(path, 0777) == -1)
566
if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
568
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
233
if (! is_if_not_exists)
235
my_error(ER_DB_CREATE_EXISTS, MYF(0), path);
239
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
240
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
572
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
573
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
247
my_error(ER_CANT_CREATE_DB, MYF(0), path, errno);
583
my_error(EE_STAT, MYF(0), path, errno);
586
if (my_mkdir(path,0777,MYF(0)) < 0)
588
my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
594
path[path_len-1]= FN_LIBCHAR;
595
strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
596
if (write_db_opt(thd, path, db, create_info))
252
error_erno= write_schema_file(path, *schema_message);
253
if (error_erno && error_erno != EEXIST)
599
Could not create options file.
600
Restore things to beginning.
603
255
if (rmdir(path) >= 0)
609
We come here when we managed to create the database, but not the option
610
file. In this case it's best to just continue as if nothing has
611
happened. (This is a very unlikely senario)
620
if (!thd->query) // Only in replication
623
query_length= (uint) (strxmov(tmp_query,"create database `",
624
db, "`", NullS) - tmp_query);
629
query_length= thd->query_length;
632
ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
636
if (mysql_bin_log.is_open())
638
Query_log_event qinfo(thd, query, query_length, 0,
639
/* suppress_use */ true);
642
Write should use the database being created as the "current
643
database" and not the threads current database, which is the
644
default. If we do not change the "current database" to the
645
database being created, the CREATE statement will not be
646
replicated when using --binlog-do-db to select databases to be
649
An example (--binlog-do-db=sisyfos):
651
CREATE DATABASE bob; # Not replicated
652
USE bob; # 'bob' is the current database
653
CREATE DATABASE sisyfos; # Not replicated since 'bob' is
655
USE sisyfos; # Will give error on slave since
656
# database does not exist.
659
qinfo.db_len = strlen(db);
661
/* These DDL methods and logging protected with LOCK_mysql_create_db */
662
mysql_bin_log.write(&qinfo);
264
replication_services.rawStatement(session, session->query, session->query_length);
265
session->my_ok(result);
668
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
669
start_waiting_global_read_lock(thd);
268
pthread_mutex_unlock(&LOCK_create_db);
269
start_waiting_global_read_lock(session);
675
275
/* db-name is already validated when we come here */
677
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
277
bool mysql_alter_db(Session *session, const char *db, message::Schema *schema_message)
679
char path[FN_REFLEN+16];
279
ReplicationServices &replication_services= ReplicationServices::singleton();
282
char path[FN_REFLEN+16];
684
286
Do not alter database if another thread is holding read lock.
685
Wait for global read lock before acquiring LOCK_mysql_create_db.
287
Wait for global read lock before acquiring LOCK_create_db.
686
288
After wait_if_global_read_lock() we have protection against another
687
global read lock. If we would acquire LOCK_mysql_create_db first,
289
global read lock. If we would acquire LOCK_create_db first,
688
290
another thread could step in and get the global read lock before we
689
291
reach wait_if_global_read_lock(). If this thread tries the same as we
690
(admin a db), it would then go and wait on LOCK_mysql_create_db...
292
(admin a db), it would then go and wait on LOCK_create_db...
691
293
Furthermore wait_if_global_read_lock() checks if the current thread
692
294
has the global read lock and refuses the operation with
693
295
ER_CANT_UPDATE_WITH_READLOCK if applicable.
695
if ((error=wait_if_global_read_lock(thd,0,1)))
698
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
701
Recreate db options file: /dbpath/.db.opt
702
We pass MY_DB_OPT_FILE as "extension" to avoid
703
"table name to file name" encoding.
705
build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0);
706
if ((error=write_db_opt(thd, path, db, create_info)))
297
if ((error=wait_if_global_read_lock(session,0,1)))
300
assert(schema_message);
302
schema_message->set_name(db);
304
pthread_mutex_lock(&LOCK_create_db);
709
306
/* Change options if current database is being altered. */
711
if (thd->db && !strcmp(thd->db,db))
713
thd->db_charset= create_info->default_table_charset ?
714
create_info->default_table_charset :
715
thd->variables.collation_server;
716
thd->variables.collation_database= thd->db_charset;
719
ha_binlog_log_query(thd, 0, LOGCOM_ALTER_DB,
720
thd->query, thd->query_length,
723
if (mysql_bin_log.is_open())
725
Query_log_event qinfo(thd, thd->query, thd->query_length, 0,
726
/* suppress_use */ true);
729
Write should use the database being created as the "current
730
database" and not the threads current database, which is the
734
qinfo.db_len = strlen(db);
737
/* These DDL methods and logging protected with LOCK_mysql_create_db */
738
mysql_bin_log.write(&qinfo);
307
path_len= build_table_filename(path, sizeof(path), db, "", false);
308
path[path_len-1]= 0; // Remove last '/' from path
310
error= write_schema_file(path, *schema_message);
311
if (error && error != EEXIST)
313
/* TODO: find some witty way of getting back an error message */
314
pthread_mutex_unlock(&LOCK_create_db);
318
replication_services.rawStatement(session, session->getQueryString(), session->getQueryLength());
319
session->my_ok(result);
321
pthread_mutex_unlock(&LOCK_create_db);
322
start_waiting_global_read_lock(session);
743
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
744
start_waiting_global_read_lock(thd);
324
return error ? true : false;
767
bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
345
bool mysql_rm_db(Session *session, char *db, bool if_exists)
770
348
int error= false;
771
349
char path[FN_REFLEN+16];
774
TABLE_LIST* dropped_tables= 0;
351
TableList *dropped_tables= NULL;
776
353
if (db && (strcmp(db, "information_schema") == 0))
778
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
355
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
783
361
Do not drop database if another thread is holding read lock.
784
Wait for global read lock before acquiring LOCK_mysql_create_db.
362
Wait for global read lock before acquiring LOCK_create_db.
785
363
After wait_if_global_read_lock() we have protection against another
786
global read lock. If we would acquire LOCK_mysql_create_db first,
364
global read lock. If we would acquire LOCK_create_db first,
787
365
another thread could step in and get the global read lock before we
788
366
reach wait_if_global_read_lock(). If this thread tries the same as we
789
(admin a db), it would then go and wait on LOCK_mysql_create_db...
367
(admin a db), it would then go and wait on LOCK_create_db...
790
368
Furthermore wait_if_global_read_lock() checks if the current thread
791
369
has the global read lock and refuses the operation with
792
370
ER_CANT_UPDATE_WITH_READLOCK if applicable.
794
if (wait_if_global_read_lock(thd, 0, 1))
372
if (wait_if_global_read_lock(session, 0, 1))
800
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
803
This statement will be replicated as a statement, even when using
804
row-based replication. The flag will be reset at the end of the
807
thd->clear_current_stmt_binlog_row_based();
809
length= build_table_filename(path, sizeof(path), db, "", "", 0);
810
stpcpy(path+length, MY_DB_OPT_FILE); // Append db option file name
811
del_dbopt(path); // Remove dboption hash entry
377
pthread_mutex_lock(&LOCK_create_db);
379
length= build_table_filename(path, sizeof(path),
381
strcpy(path+length, MY_DB_OPT_FILE); // Append db option file name
812
383
path[length]= '\0'; // Remove file name
814
385
/* See if the directory exists */
815
if (!(dirp= my_dir(path,MYF(MY_DONT_SORT))))
386
CachedDirectory dirp(path);
820
my_error(ER_DB_DROP_EXISTS, MYF(0), db);
392
my_error(ER_DB_DROP_EXISTS, MYF(0), path);
824
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
825
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db);
396
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
397
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
829
pthread_mutex_lock(&LOCK_open);
402
pthread_mutex_lock(&LOCK_open); /* After deleting database, remove all cache entries related to schema */
830
403
remove_db_from_cache(db);
831
404
pthread_mutex_unlock(&LOCK_open);
835
if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0,
836
&dropped_tables)) >= 0)
408
deleted= mysql_rm_known_files(session, dirp, db,
409
path, &dropped_tables);
838
ha_drop_database(path);
412
plugin::StorageEngine::dropDatabase(path);
842
if (!silent && deleted>=0)
844
418
const char *query;
845
419
uint32_t query_length;
848
/* The client used the old obsolete mysql_drop_db() call */
850
query_length= (uint) (strxmov(path, "drop database `", db, "`",
856
query_length= thd->query_length;
858
if (mysql_bin_log.is_open())
860
Query_log_event qinfo(thd, query, query_length, 0,
861
/* suppress_use */ true);
863
Write should use the database being created as the "current
864
database" and not the threads current database, which is the
868
qinfo.db_len = strlen(db);
871
/* These DDL methods and logging protected with LOCK_mysql_create_db */
872
mysql_bin_log.write(&qinfo);
875
thd->server_status|= SERVER_STATUS_DB_DROPPED;
876
my_ok(thd, (uint32_t) deleted);
877
thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
421
assert(session->query);
423
query= session->query;
424
query_length= session->query_length;
426
ReplicationServices &replication_services= ReplicationServices::singleton();
427
replication_services.rawStatement(session, session->getQueryString(), session->getQueryLength());
428
session->clear_error();
429
session->server_status|= SERVER_STATUS_DB_DROPPED;
430
session->my_ok((uint32_t) deleted);
431
session->server_status&= ~SERVER_STATUS_DB_DROPPED;
879
else if (mysql_bin_log.is_open())
881
435
char *query, *query_pos, *query_end, *query_data_start;
885
if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN)))
439
if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
886
440
goto exit; /* not much else we can do */
887
query_pos= query_data_start= stpcpy(query,"drop table ");
441
query_pos= query_data_start= strcpy(query,"drop table ")+11;
888
442
query_end= query + MAX_DROP_TABLE_Q_LEN;
889
443
db_len= strlen(db);
445
ReplicationServices &replication_services= ReplicationServices::singleton();
891
446
for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
448
uint32_t tbl_name_len;
895
450
/* 3 for the quotes and the comma*/
896
451
tbl_name_len= strlen(tbl->table_name) + 3;
897
452
if (query_pos + tbl_name_len + 1 >= query_end)
899
/* These DDL methods and logging protected with LOCK_mysql_create_db */
900
write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
454
/* These DDL methods and logging protected with LOCK_create_db */
455
replication_services.rawStatement(session, query, (size_t) (query_pos -1 - query));
901
456
query_pos= query_data_start;
904
459
*query_pos++ = '`';
905
query_pos= stpcpy(query_pos,tbl->table_name);
460
query_pos= strcpy(query_pos,tbl->table_name) + (tbl_name_len-3);
906
461
*query_pos++ = '`';
907
462
*query_pos++ = ',';
910
465
if (query_pos != query_data_start)
912
/* These DDL methods and logging protected with LOCK_mysql_create_db */
913
write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
467
/* These DDL methods and logging protected with LOCK_create_db */
468
replication_services.rawStatement(session, query, (size_t) (query_pos -1 - query));
919
474
If this database was the client's selected database, we silently
920
475
change the client's selected database to nothing (to have an empty
921
SELECT DATABASE() in the future). For this we free() thd->db and set
476
SELECT DATABASE() in the future). For this we free() session->db and set
924
if (thd->db && !strcmp(thd->db, db))
925
mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
926
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
927
start_waiting_global_read_lock(thd);
479
if (! session->db.empty() && session->db.compare(db) == 0)
480
mysql_change_db_impl(session, NULL);
481
pthread_mutex_unlock(&LOCK_create_db);
482
start_waiting_global_read_lock(session);
487
static int rm_table_part2(Session *session, TableList *tables)
492
bool foreign_key_error= false;
494
pthread_mutex_lock(&LOCK_open); /* Part 2 of rm a table */
497
If we have the table in the definition cache, we don't have to check the
498
.frm cursor to find if the table is a normal table (not view) and what
502
for (table= tables; table; table= table->next_local)
505
table->db_type= NULL;
506
if ((share= TableShare::getShare(table->db, table->table_name)))
507
table->db_type= share->db_type();
510
if (lock_table_names_exclusively(session, tables))
512
pthread_mutex_unlock(&LOCK_open);
516
/* Don't give warnings for not found errors, as we already generate notes */
517
session->no_warnings_for_error= 1;
519
for (table= tables; table; table= table->next_local)
522
plugin::StorageEngine *table_type;
524
error= session->drop_temporary_table(table);
528
// removed temporary table
532
goto err_with_placeholders;
534
// temporary table not found
538
table_type= table->db_type;
542
abort_locked_tables(session, db, table->table_name);
543
remove_table_from_cache(session, db, table->table_name,
544
RTFC_WAIT_OTHER_THREAD_FLAG |
545
RTFC_CHECK_KILLED_FLAG);
547
If the table was used in lock tables, remember it so that
548
unlock_table_names can free it
550
if ((locked_table= drop_locked_tables(session, db, table->table_name)))
551
table->table= locked_table;
556
goto err_with_placeholders;
560
TableIdentifier identifier(db, table->table_name, table->internal_tmp_table ? INTERNAL_TMP_TABLE : NO_TMP_TABLE);
562
if ((table_type == NULL
563
&& (plugin::StorageEngine::getTableDefinition(*session,
564
identifier) != EEXIST)))
566
// Table was not found on disk and table can't be created from engine
567
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
568
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
573
error= plugin::StorageEngine::dropTable(*session,
577
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
580
session->clear_error();
583
if (error == HA_ERR_ROW_IS_REFERENCED)
585
/* the table is referenced by a foreign key constraint */
586
foreign_key_error= true;
590
if (error == 0 || (foreign_key_error == false))
591
write_bin_log_drop_table(session, true, db, table->table_name);
595
if (wrong_tables.length())
596
wrong_tables.append(',');
597
wrong_tables.append(String(table->table_name,system_charset_info));
601
It's safe to unlock LOCK_open: we have an exclusive lock
604
pthread_mutex_unlock(&LOCK_open);
606
if (wrong_tables.length())
608
if (!foreign_key_error)
609
my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
610
wrong_tables.c_ptr());
613
my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
618
pthread_mutex_lock(&LOCK_open); /* final bit in rm table lock */
619
err_with_placeholders:
620
unlock_table_names(tables, NULL);
621
pthread_mutex_unlock(&LOCK_open);
622
session->no_warnings_for_error= 0;
933
628
Removes files with known extensions plus.
934
thd MUST be set when calling this function!
629
session MUST be set when calling this function!
937
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
938
const char *org_path, uint level,
939
TABLE_LIST **dropped_tables)
632
static long mysql_rm_known_files(Session *session, CachedDirectory &dirp,
634
const char *org_path,
635
TableList **dropped_tables)
942
uint32_t found_other_files=0;
943
640
char filePath[FN_REFLEN];
944
TABLE_LIST *tot_list=0, **tot_list_next;
641
TableList *tot_list= NULL, **tot_list_next;
946
643
tot_list_next= &tot_list;
949
idx < (uint) dirp->number_off_files && !thd->killed ;
645
for (CachedDirectory::Entries::const_iterator iter= dirp.getEntries().begin();
646
iter != dirp.getEntries().end() && !session->killed;
952
FILEINFO *file=dirp->dir_entry+idx;
649
string filename((*iter)->filename);
955
651
/* skiping . and .. */
956
if (file->name[0] == '.' && (!file->name[1] ||
957
(file->name[1] == '.' && !file->name[2])))
652
if (filename[0] == '.' && (!filename[1] ||
653
(filename[1] == '.' && !filename[2])))
960
if (!(extension= strrchr(file->name, '.')))
961
extension= strend(file->name);
962
if (find_type(extension, &deletable_extentions,1+2) <= 0)
964
if (find_type(extension, ha_known_exts(),1+2) <= 0)
656
string extension("");
657
size_t ext_pos= filename.rfind('.');
658
if (ext_pos != string::npos)
660
extension= filename.substr(ext_pos);
662
if (deletable_extentions.find(extension) == deletable_extentions.end())
667
strange checking for magic extensions that are then deleted if
668
not reg_ext (i.e. .frm).
670
and (previously) we'd err out on drop database if files not matching
671
engine ha_known_exts() or deletable_extensions were present.
673
presumably this was to avoid deleting other user data... except if that
674
data happened to be in files ending in .BAK, .opt or .TMD. *fun*
968
678
/* just for safety we use files_charset_info */
969
if (db && !my_strcasecmp(files_charset_info,
679
if (!my_strcasecmp(files_charset_info, extension.c_str(), ".dfe"))
681
size_t db_len= db.size();
972
683
/* Drop the table nicely */
973
*extension= 0; // Remove extension
974
TABLE_LIST *table_list=(TABLE_LIST*)
975
thd->calloc(sizeof(*table_list) +
977
MYSQL50_TABLE_NAME_PREFIX_LENGTH +
978
strlen(file->name) + 1);
684
filename.erase(ext_pos);
685
TableList *table_list=(TableList*)
686
session->calloc(sizeof(*table_list) +
688
filename.size() + 1);
982
692
table_list->db= (char*) (table_list+1);
983
table_list->table_name= stpcpy(table_list->db, db) + 1;
984
VOID(filename_to_tablename(file->name, table_list->table_name,
985
MYSQL50_TABLE_NAME_PREFIX_LENGTH +
986
strlen(file->name) + 1));
987
table_list->alias= table_list->table_name; // If lower_case_table_names=2
988
table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix);
693
table_list->table_name= strcpy(table_list->db, db.c_str()) + db_len + 1;
694
filename_to_tablename(filename.c_str(), table_list->table_name,
695
filename.size() + 1);
696
table_list->alias= table_list->table_name; // If lower_case_table_names=2
697
table_list->internal_tmp_table= (strncmp(filename.c_str(),
699
strlen(TMP_FILE_PREFIX)) == 0);
989
700
/* Link into list */
990
701
(*tot_list_next)= table_list;
991
702
tot_list_next= &table_list->next_local;
996
strxmov(filePath, org_path, "/", file->name, NullS);
997
if (my_delete_with_symlink(filePath,MYF(MY_WME)))
707
sprintf(filePath, "%s/%s", org_path, filename.c_str());
708
if (internal::my_delete_with_symlink(filePath,MYF(MY_WME)))
1004
(tot_list && mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1)))
719
if (rm_table_part2(session, tot_list))
1009
723
if (dropped_tables)
1010
724
*dropped_tables= tot_list;
1013
If the directory is a symbolic link, remove the link first, then
1014
remove the directory the symbolic link pointed at
1016
if (found_other_files)
1018
my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST);
1023
/* Don't give errors if we can't delete 'RAID' directory */
1024
if (rm_dir_w_symlink(org_path, level == 0))
1037
Remove directory with symlink
1041
org_path path of derictory
1042
send_error send errors
1048
static bool rm_dir_w_symlink(const char *org_path, bool send_error)
1050
char tmp_path[FN_REFLEN], *pos;
1051
char *path= tmp_path;
1052
unpack_filename(tmp_path, org_path);
1053
#ifdef HAVE_READLINK
1055
char tmp2_path[FN_REFLEN];
1057
/* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
1059
if (pos > path && pos[-1] == FN_LIBCHAR)
1062
if ((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0)
1066
if (my_delete(path, MYF(send_error ? MY_WME : 0)))
1070
/* Delete directory symbolic link pointed at */
1074
/* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
1077
if (pos > path && pos[-1] == FN_LIBCHAR)
1079
if (rmdir(path) < 0 && send_error)
1081
my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
1089
@brief Internal implementation: switch current database to a valid one.
1091
@param thd Thread context.
1092
@param new_db_name Name of the database to switch to. The function will
1093
take ownership of the name (the caller must not free
1094
the allocated memory). If the name is NULL, we're
1095
going to switch to NULL db.
1096
@param new_db_charset Character set of the new database.
1099
static void mysql_change_db_impl(THD *thd,
1100
LEX_STRING *new_db_name,
1101
const CHARSET_INFO * const new_db_charset)
1103
/* 1. Change current database in THD. */
1105
if (new_db_name == NULL)
1108
THD::set_db() does all the job -- it frees previous database name and
1112
thd->set_db(NULL, 0);
1114
else if (new_db_name == &INFORMATION_SCHEMA_NAME)
1117
Here we must use THD::set_db(), because we want to copy
1118
INFORMATION_SCHEMA_NAME constant.
1121
thd->set_db(INFORMATION_SCHEMA_NAME.str, INFORMATION_SCHEMA_NAME.length);
1126
Here we already have a copy of database name to be used in THD. So,
1127
we just call THD::reset_db(). Since THD::reset_db() does not releases
1128
the previous database name, we should do it explicitly.
1133
thd->reset_db(new_db_name->str, new_db_name->length);
1136
/* 3. Update db-charset environment variables. */
1138
thd->db_charset= new_db_charset;
1139
thd->variables.collation_database= new_db_charset;
1145
Backup the current database name before switch.
1147
@param[in] thd thread handle
1148
@param[in, out] saved_db_name IN: "str" points to a buffer where to store
1149
the old database name, "length" contains the
1151
OUT: if the current (default) database is
1152
not NULL, its name is copied to the
1153
buffer pointed at by "str"
1154
and "length" is updated accordingly.
1155
Otherwise "str" is set to NULL and
1156
"length" is set to 0.
1159
static void backup_current_db_name(THD *thd,
1160
LEX_STRING *saved_db_name)
1164
/* No current (default) database selected. */
1166
saved_db_name->str= NULL;
1167
saved_db_name->length= 0;
1171
strmake(saved_db_name->str, thd->db, saved_db_name->length - 1);
1172
saved_db_name->length= thd->db_length;
1178
Return true if db1_name is equal to db2_name, false otherwise.
1180
The function allows to compare database names according to the MySQL
1181
rules. The database names db1 and db2 are equal if:
1182
- db1 is NULL and db2 is NULL;
1184
- db1 is not-NULL, db2 is not-NULL, db1 is equal (ignoring case) to
1185
db2 in system character set (UTF8).
1189
cmp_db_names(const char *db1_name,
1190
const char *db2_name)
1193
/* db1 is NULL and db2 is NULL */
1194
(!db1_name && !db2_name) ||
1196
/* db1 is not-NULL, db2 is not-NULL, db1 == db2. */
1197
(db1_name && db2_name && my_strcasecmp(system_charset_info, db1_name, db2_name) == 0);
728
my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, errno);
1202
736
@brief Change the current database and its attributes unconditionally.
1204
@param thd thread handle
738
@param session thread handle
1205
739
@param new_db_name database name
1206
740
@param force_switch if force_switch is false, then the operation will fail if