12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
17
/* create and drop of databases */
22
#include <sys/types.h>
28
#include <drizzled/error.h>
29
#include <drizzled/gettext.h>
30
#include <drizzled/my_hash.h>
31
#include <drizzled/internal/m_string.h>
32
#include <drizzled/session.h>
33
#include <drizzled/schema.h>
34
#include <drizzled/sql_base.h>
35
#include <drizzled/lock.h>
36
#include <drizzled/errmsg_print.h>
37
#include <drizzled/transaction_services.h>
38
#include <drizzled/message/schema.pb.h>
39
#include <drizzled/sql_table.h>
40
#include <drizzled/plugin/storage_engine.h>
41
#include <drizzled/plugin/authorization.h>
42
#include <drizzled/global_charset_info.h>
43
#include <drizzled/pthread_globals.h>
44
#include <drizzled/charset.h>
45
#include <drizzled/internal/my_sys.h>
47
#include <boost/thread/mutex.hpp>
23
#include <drizzled/serialize/serialize.h>
25
#include <drizzled/server_includes.h>
26
#include <mysys/mysys_err.h>
27
#include <mysys/my_dir.h>
29
#include <drizzled/drizzled_error_messages.h>
30
#include <libdrizzle/gettext.h>
49
33
#define MAX_DROP_TABLE_Q_LEN 1024
59
static void change_db_impl(Session &session);
60
static void change_db_impl(Session &session, identifier::Schema &schema_identifier);
35
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NULL};
36
static TYPELIB deletable_extentions=
37
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
39
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
40
const char *db, const char *path, uint32_t level,
41
TableList **dropped_tables);
43
static bool rm_dir_w_symlink(const char *org_path, bool send_error);
44
static void mysql_change_db_impl(THD *thd,
45
LEX_STRING *new_db_name,
46
const CHARSET_INFO * const new_db_charset);
49
/* Database lock hash */
51
pthread_mutex_t LOCK_lock_db;
52
int creating_database= 0; // how many database locks are made
55
/* Structure for database lock */
56
typedef struct my_dblock_st
58
char *name; /* Database name */
59
uint32_t name_length; /* Database length name */
67
extern "C" unsigned char* lock_db_get_key(my_dblock_t *, size_t *, bool not_used);
69
unsigned char* lock_db_get_key(my_dblock_t *ptr, size_t *length,
70
bool not_used __attribute__((unused)))
72
*length= ptr->name_length;
73
return (unsigned char*) ptr->name;
78
Free lock_db hash element.
81
extern "C" void lock_db_free_element(void *ptr);
83
void lock_db_free_element(void *ptr)
90
Delete a database lock entry from hash.
93
void lock_db_delete(const char *name, uint32_t length)
96
safe_mutex_assert_owner(&LOCK_lock_db);
97
if ((opt= (my_dblock_t *)hash_search(&lock_db_cache,
98
(const unsigned char*) name, length)))
99
hash_delete(&lock_db_cache, (unsigned char*) opt);
103
/* Database options hash */
104
static HASH dboptions;
105
static bool dboptions_init= 0;
106
static rw_lock_t LOCK_dboptions;
108
/* Structure for database options */
109
typedef struct my_dbopt_st
111
char *name; /* Database name */
112
uint32_t name_length; /* Database length name */
113
const CHARSET_INFO *charset; /* Database default character set */
118
Function we use in the creation of our hash to get key.
121
extern "C" unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
124
unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
125
bool not_used __attribute__((unused)))
127
*length= opt->name_length;
128
return (unsigned char*) opt->name;
133
Helper function to write a query to binlog used by mysql_rm_db()
136
static inline void write_to_binlog(THD *thd, char *query, uint32_t q_len,
137
char *db, uint32_t db_len)
139
Query_log_event qinfo(thd, query, q_len, 0, 0);
142
qinfo.db_len= db_len;
143
mysql_bin_log.write(&qinfo);
148
Function to free dboptions hash element
151
extern "C" void free_dbopt(void *dbopt);
153
void free_dbopt(void *dbopt)
155
free((unsigned char*) dbopt);
160
Initialize database option hash and locked database hash.
166
Must be called before any other database function is called.
173
bool my_database_names_init(void)
176
(void) my_rwlock_init(&LOCK_dboptions, NULL);
180
error= hash_init(&dboptions, lower_case_table_names ?
181
&my_charset_bin : system_charset_info,
182
32, 0, 0, (hash_get_key) dboptions_get_key,
184
hash_init(&lock_db_cache, lower_case_table_names ?
185
&my_charset_bin : system_charset_info,
186
32, 0, 0, (hash_get_key) lock_db_get_key,
187
lock_db_free_element,0);
196
Free database option hash and locked databases hash.
199
void my_database_names_free(void)
204
hash_free(&dboptions);
205
(void) rwlock_destroy(&LOCK_dboptions);
206
hash_free(&lock_db_cache);
212
Cleanup cached options
215
void my_dbopt_cleanup(void)
217
rw_wrlock(&LOCK_dboptions);
218
hash_free(&dboptions);
219
hash_init(&dboptions, lower_case_table_names ?
220
&my_charset_bin : system_charset_info,
221
32, 0, 0, (hash_get_key) dboptions_get_key,
223
rw_unlock(&LOCK_dboptions);
228
Find database options in the hash.
231
Search a database options in the hash, usings its path.
232
Fills "create" on success.
239
static bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
245
length= (uint) strlen(dbname);
247
rw_rdlock(&LOCK_dboptions);
248
if ((opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
250
create->default_table_charset= opt->charset;
253
rw_unlock(&LOCK_dboptions);
259
Writes database options into the hash.
262
Inserts database options into the hash, or updates
263
options if they are already in the hash.
270
static bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
276
length= (uint) strlen(dbname);
278
rw_wrlock(&LOCK_dboptions);
279
if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
281
/* Options are not in the hash, insert them */
283
if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
284
&opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
292
my_stpcpy(opt->name, dbname);
293
opt->name_length= length;
295
if ((error= my_hash_insert(&dboptions, (unsigned char*) opt)))
302
/* Update / write options in hash */
303
opt->charset= create->default_table_charset;
306
rw_unlock(&LOCK_dboptions);
312
Deletes database options from the hash.
315
void del_dbopt(const char *path)
318
rw_wrlock(&LOCK_dboptions);
319
if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const unsigned char*) path,
321
hash_delete(&dboptions, (unsigned char*) opt);
322
rw_unlock(&LOCK_dboptions);
327
Create database options file:
330
Currently database default charset is only stored there.
334
1 Could not create file or write to it. Error sent through my_error()
337
static bool write_db_opt(THD *thd, const char *path, const char *name, HA_CREATE_INFO *create)
344
if (!create->default_table_charset)
345
create->default_table_charset= thd->variables.collation_server;
347
if (put_dbopt(path, create))
351
db.set_characterset(create->default_table_charset->csname);
352
db.set_collation(create->default_table_charset->name);
354
fstream output(path, ios::out | ios::trunc | ios::binary);
355
if (!db.SerializeToOstream(&output))
363
Load database options file
366
path Path for option file
367
create Where to store the read options
373
1 No database file or could not open it
377
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
383
memset(create, 0, sizeof(*create));
384
create->default_table_charset= thd->variables.collation_server;
386
/* Check if options for this database are already in the hash */
387
if (!get_dbopt(path, create))
390
fstream input(path, ios::in | ios::binary);
393
else if (!db.ParseFromIstream(&input))
396
buffer= db.characterset();
397
if (!(create->default_table_charset= get_charset_by_csname(buffer.c_str(), MY_CS_PRIMARY, MYF(0))))
399
sql_print_error(_("Error while loading database options: '%s':"),path);
400
sql_print_error(ER(ER_UNKNOWN_COLLATION), buffer.c_str());
401
create->default_table_charset= default_charset_info;
404
buffer= db.collation();
405
if (!(create->default_table_charset= get_charset_by_name(buffer.c_str(), MYF(0))))
407
sql_print_error(_("Error while loading database options: '%s':"),path);
408
sql_print_error(ER(ER_UNKNOWN_COLLATION), buffer.c_str());
409
create->default_table_charset= default_charset_info;
413
Put the loaded value into the hash.
414
Note that another thread could've added the same
415
entry to the hash after we called get_dbopt(),
416
but it's not an error, as put_dbopt() takes this
417
possibility into account.
419
error= put_dbopt(path, create);
427
Retrieve database options by name. Load database options file or fetch from
431
load_db_opt_by_name()
432
db_name Database name
433
db_create_info Where to store the database options
436
load_db_opt_by_name() is a shortcut for load_db_opt().
439
Although load_db_opt_by_name() (and load_db_opt()) returns status of
440
the operation, it is useless usually and should be ignored. The problem
441
is that there are 1) system databases ("mysql") and 2) virtual
442
databases ("information_schema"), which do not contain options file.
443
So, load_db_opt[_by_name]() returns false for these databases, but this
446
load_db_opt[_by_name]() clears db_create_info structure in any case, so
447
even on failure it contains valid data. So, common use case is just
448
call load_db_opt[_by_name]() without checking return value and use
449
db_create_info right after that.
451
RETURN VALUES (read NOTE!)
453
true Failed to retrieve options
456
bool load_db_opt_by_name(THD *thd, const char *db_name,
457
HA_CREATE_INFO *db_create_info)
459
char db_opt_path[FN_REFLEN];
462
Pass an empty file name, and the database options file name as extension
463
to avoid table name to file name encoding.
465
(void) build_table_filename(db_opt_path, sizeof(db_opt_path),
466
db_name, "", MY_DB_OPT_FILE, 0);
468
return load_db_opt(thd, db_opt_path, db_create_info);
473
Return default database collation.
475
@param thd Thread context.
476
@param db_name Database name.
478
@return CHARSET_INFO object. The operation always return valid character
479
set, even if the database does not exist.
482
const CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
484
HA_CREATE_INFO db_info;
486
if (thd->db != NULL && strcmp(db_name, thd->db) == 0)
487
return thd->db_charset;
489
load_db_opt_by_name(thd, db_name, &db_info);
492
NOTE: even if load_db_opt_by_name() fails,
493
db_info.default_table_charset contains valid character set
494
(collation_server). We should not fail if load_db_opt_by_name() fails,
495
because it is valid case. If a database has been created just by
496
"mkdir", it does not contain db.opt file, but it is valid database.
499
return db_info.default_table_charset;
67
session Thread handler
68
509
db Name of database to create
69
510
Function assumes that this is already validated.
70
511
create_info Database create options (like character set)
512
silent Used by replication when internally creating a database.
513
In this case the entry should not be logged.
73
516
1. Report back to client that command succeeded (my_ok)
74
517
2. Report errors to client
75
518
3. Log event to binary log
519
(The 'silent' flags turns off 1 and 3.)
83
bool create(Session &session, const message::Schema &schema_message, const bool is_if_not_exists)
527
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent)
85
TransactionServices &transaction_services= TransactionServices::singleton();
529
char path[FN_REFLEN+16];
530
char tmp_query[FN_REFLEN+16];
533
struct stat stat_info;
534
uint32_t create_options= create_info ? create_info->options : 0;
537
/* do not create 'information_schema' db */
538
if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.str))
540
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
89
545
Do not create database if another thread is holding read lock.
90
Wait for global read lock before acquiring session->catalog()->schemaLock().
546
Wait for global read lock before acquiring LOCK_mysql_create_db.
91
547
After wait_if_global_read_lock() we have protection against another
92
global read lock. If we would acquire session->catalog()->schemaLock() first,
548
global read lock. If we would acquire LOCK_mysql_create_db first,
93
549
another thread could step in and get the global read lock before we
94
550
reach wait_if_global_read_lock(). If this thread tries the same as we
95
(admin a db), it would then go and wait on session->catalog()->schemaLock()...
551
(admin a db), it would then go and wait on LOCK_mysql_create_db...
96
552
Furthermore wait_if_global_read_lock() checks if the current thread
97
553
has the global read lock and refuses the operation with
98
554
ER_CANT_UPDATE_WITH_READLOCK if applicable.
100
if (session.wait_if_global_read_lock(false, true))
105
assert(schema_message.has_name());
106
assert(schema_message.has_collation());
108
// @todo push this lock down into the engine
110
boost::mutex::scoped_lock scopedLock(session.catalog().schemaLock());
112
// Check to see if it exists already.
113
identifier::Schema schema_identifier(schema_message.name());
114
if (plugin::StorageEngine::doesSchemaExist(schema_identifier))
116
if (not is_if_not_exists)
118
my_error(ER_DB_CREATE_EXISTS, schema_identifier);
123
push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
124
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
125
schema_message.name().c_str());
129
else if (not plugin::StorageEngine::createSchema(schema_message)) // Try to create it
131
my_error(ER_CANT_CREATE_DB, MYF(0), schema_message.name().c_str(), errno);
136
transaction_services.createSchema(session, schema_message);
140
session.startWaitingGlobalReadLock();
556
if (wait_if_global_read_lock(thd, 0, 1))
562
pthread_mutex_lock(&LOCK_mysql_create_db);
564
/* Check directory */
565
path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
566
path[path_len-1]= 0; // Remove last '/' from path
568
if (!stat(path,&stat_info))
570
if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
572
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
576
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
577
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
587
my_error(EE_STAT, MYF(0), path, errno);
590
if (my_mkdir(path,0777,MYF(0)) < 0)
592
my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
598
path[path_len-1]= FN_LIBCHAR;
599
strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
600
if (write_db_opt(thd, path, db, create_info))
603
Could not create options file.
604
Restore things to beginning.
607
if (rmdir(path) >= 0)
613
We come here when we managed to create the database, but not the option
614
file. In this case it's best to just continue as if nothing has
615
happened. (This is a very unlikely senario)
622
uint32_t query_length;
624
if (!thd->query) // Only in replication
627
query_length= (uint) (strxmov(tmp_query,"create database `",
628
db, "`", NULL) - tmp_query);
633
query_length= thd->query_length;
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);
668
pthread_mutex_unlock(&LOCK_mysql_create_db);
669
start_waiting_global_read_lock(thd);
146
675
/* db-name is already validated when we come here */
148
bool alter(Session &session,
149
const message::Schema &schema_message,
150
const message::Schema &original_schema)
677
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
152
TransactionServices &transaction_services= TransactionServices::singleton();
679
char path[FN_REFLEN+16];
155
684
Do not alter database if another thread is holding read lock.
156
Wait for global read lock before acquiring session->catalog()->schemaLock().
685
Wait for global read lock before acquiring LOCK_mysql_create_db.
157
686
After wait_if_global_read_lock() we have protection against another
158
global read lock. If we would acquire session->catalog()->schemaLock() first,
687
global read lock. If we would acquire LOCK_mysql_create_db first,
159
688
another thread could step in and get the global read lock before we
160
689
reach wait_if_global_read_lock(). If this thread tries the same as we
161
(admin a db), it would then go and wait on session->catalog()->schemaLock()...
690
(admin a db), it would then go and wait on LOCK_mysql_create_db...
162
691
Furthermore wait_if_global_read_lock() checks if the current thread
163
692
has the global read lock and refuses the operation with
164
693
ER_CANT_UPDATE_WITH_READLOCK if applicable.
166
if ((session.wait_if_global_read_lock(false, true)))
171
boost::mutex::scoped_lock scopedLock(session.catalog().schemaLock());
173
identifier::Schema schema_idenifier(schema_message.name());
174
if (not plugin::StorageEngine::doesSchemaExist(schema_idenifier))
176
my_error(ER_SCHEMA_DOES_NOT_EXIST, schema_idenifier);
180
/* Change options if current database is being altered. */
181
success= plugin::StorageEngine::alterSchema(schema_message);
185
transaction_services.alterSchema(session, original_schema, schema_message);
190
my_error(ER_ALTER_SCHEMA, schema_idenifier);
193
session.startWaitingGlobalReadLock();
695
if ((error=wait_if_global_read_lock(thd,0,1)))
698
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)))
709
/* 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
if (mysql_bin_log.is_open())
721
Query_log_event qinfo(thd, thd->query, thd->query_length, 0,
722
/* suppress_use */ true);
725
Write should use the database being created as the "current
726
database" and not the threads current database, which is the
730
qinfo.db_len = strlen(db);
733
/* These DDL methods and logging protected with LOCK_mysql_create_db */
734
mysql_bin_log.write(&qinfo);
739
pthread_mutex_unlock(&LOCK_mysql_create_db);
740
start_waiting_global_read_lock(thd);
216
bool drop(Session &session, identifier::Schema &schema_identifier, const bool if_exists)
763
bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
767
char path[FN_REFLEN+16];
770
TableList* dropped_tables= 0;
772
if (db && (strcmp(db, "information_schema") == 0))
774
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
221
779
Do not drop database if another thread is holding read lock.
222
Wait for global read lock before acquiring session->catalog()->schemaLock().
780
Wait for global read lock before acquiring LOCK_mysql_create_db.
223
781
After wait_if_global_read_lock() we have protection against another
224
global read lock. If we would acquire session->catalog()->schemaLock() first,
782
global read lock. If we would acquire LOCK_mysql_create_db first,
225
783
another thread could step in and get the global read lock before we
226
784
reach wait_if_global_read_lock(). If this thread tries the same as we
227
(admin a db), it would then go and wait on session->catalog()->schemaLock()...
785
(admin a db), it would then go and wait on LOCK_mysql_create_db...
228
786
Furthermore wait_if_global_read_lock() checks if the current thread
229
787
has the global read lock and refuses the operation with
230
788
ER_CANT_UPDATE_WITH_READLOCK if applicable.
232
if (session.wait_if_global_read_lock(false, true))
239
boost::mutex::scoped_lock scopedLock(session.catalog().schemaLock());
240
message::schema::shared_ptr message= plugin::StorageEngine::getSchemaDefinition(schema_identifier);
242
/* See if the schema exists */
248
schema_identifier.getSQLPath(path);
250
push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
251
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
257
my_error(ER_DB_DROP_EXISTS, schema_identifier);
263
error= plugin::StorageEngine::dropSchema(session, schema_identifier, *message);
790
if (wait_if_global_read_lock(thd, 0, 1))
796
pthread_mutex_lock(&LOCK_mysql_create_db);
799
This statement will be replicated as a statement, even when using
800
row-based replication. The flag will be reset at the end of the
803
thd->clear_current_stmt_binlog_row_based();
805
length= build_table_filename(path, sizeof(path), db, "", "", 0);
806
my_stpcpy(path+length, MY_DB_OPT_FILE); // Append db option file name
807
del_dbopt(path); // Remove dboption hash entry
808
path[length]= '\0'; // Remove file name
810
/* See if the directory exists */
811
if (!(dirp= my_dir(path,MYF(MY_DONT_SORT))))
816
my_error(ER_DB_DROP_EXISTS, MYF(0), db);
820
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
821
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db);
825
pthread_mutex_lock(&LOCK_open);
826
remove_db_from_cache(db);
827
pthread_mutex_unlock(&LOCK_open);
831
if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0,
832
&dropped_tables)) >= 0)
834
ha_drop_database(path);
838
if (!silent && deleted>=0)
841
uint32_t query_length;
844
/* The client used the old obsolete mysql_drop_db() call */
846
query_length= (uint) (strxmov(path, "drop database `", db, "`",
852
query_length= thd->query_length;
854
if (mysql_bin_log.is_open())
856
Query_log_event qinfo(thd, query, query_length, 0,
857
/* suppress_use */ true);
859
Write should use the database being created as the "current
860
database" and not the threads current database, which is the
864
qinfo.db_len = strlen(db);
867
/* These DDL methods and logging protected with LOCK_mysql_create_db */
868
mysql_bin_log.write(&qinfo);
871
thd->server_status|= SERVER_STATUS_DB_DROPPED;
872
my_ok(thd, (uint32_t) deleted);
873
thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
875
else if (mysql_bin_log.is_open())
877
char *query, *query_pos, *query_end, *query_data_start;
881
if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN)))
882
goto exit; /* not much else we can do */
883
query_pos= query_data_start= my_stpcpy(query,"drop table ");
884
query_end= query + MAX_DROP_TABLE_Q_LEN;
887
for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
889
uint32_t tbl_name_len;
891
/* 3 for the quotes and the comma*/
892
tbl_name_len= strlen(tbl->table_name) + 3;
893
if (query_pos + tbl_name_len + 1 >= query_end)
895
/* These DDL methods and logging protected with LOCK_mysql_create_db */
896
write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
897
query_pos= query_data_start;
901
query_pos= my_stpcpy(query_pos,tbl->table_name);
906
if (query_pos != query_data_start)
908
/* These DDL methods and logging protected with LOCK_mysql_create_db */
909
write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
269
915
If this database was the client's selected database, we silently
270
916
change the client's selected database to nothing (to have an empty
271
SELECT DATABASE() in the future). For this we free() session->db and set
917
SELECT DATABASE() in the future). For this we free() thd->db and set
274
if (not error and schema_identifier.compare(*session.schema()))
275
change_db_impl(session);
277
session.startWaitingGlobalReadLock();
920
if (thd->db && !strcmp(thd->db, db))
921
mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
922
pthread_mutex_unlock(&LOCK_mysql_create_db);
923
start_waiting_global_read_lock(thd);
929
Removes files with known extensions plus.
930
thd MUST be set when calling this function!
933
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
934
const char *org_path, uint32_t level,
935
TableList **dropped_tables)
938
uint32_t found_other_files=0;
939
char filePath[FN_REFLEN];
940
TableList *tot_list=0, **tot_list_next;
942
tot_list_next= &tot_list;
944
for (uint32_t idx=0 ;
945
idx < (uint) dirp->number_off_files && !thd->killed ;
948
FILEINFO *file=dirp->dir_entry+idx;
951
/* skiping . and .. */
952
if (file->name[0] == '.' && (!file->name[1] ||
953
(file->name[1] == '.' && !file->name[2])))
956
if (!(extension= strrchr(file->name, '.')))
957
extension= strchr(file->name, '\0');
958
if (find_type(extension, &deletable_extentions,1+2) <= 0)
960
if (find_type(extension, ha_known_exts(),1+2) <= 0)
964
/* just for safety we use files_charset_info */
965
if (db && !my_strcasecmp(files_charset_info,
968
/* Drop the table nicely */
969
*extension= 0; // Remove extension
970
TableList *table_list=(TableList*)
971
thd->calloc(sizeof(*table_list) +
973
MYSQL50_TABLE_NAME_PREFIX_LENGTH +
974
strlen(file->name) + 1);
978
table_list->db= (char*) (table_list+1);
979
table_list->table_name= my_stpcpy(table_list->db, db) + 1;
980
filename_to_tablename(file->name, table_list->table_name,
981
MYSQL50_TABLE_NAME_PREFIX_LENGTH +
982
strlen(file->name) + 1);
983
table_list->alias= table_list->table_name; // If lower_case_table_names=2
984
table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix);
986
(*tot_list_next)= table_list;
987
tot_list_next= &table_list->next_local;
992
strxmov(filePath, org_path, "/", file->name, NULL);
993
if (my_delete_with_symlink(filePath,MYF(MY_WME)))
1000
(tot_list && mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1)))
1006
*dropped_tables= tot_list;
1009
If the directory is a symbolic link, remove the link first, then
1010
remove the directory the symbolic link pointed at
1012
if (found_other_files)
1014
my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST);
1019
/* Don't give errors if we can't delete 'RAID' directory */
1020
if (rm_dir_w_symlink(org_path, level == 0))
1033
Remove directory with symlink
1037
org_path path of derictory
1038
send_error send errors
1044
static bool rm_dir_w_symlink(const char *org_path, bool send_error)
1046
char tmp_path[FN_REFLEN], *pos;
1047
char *path= tmp_path;
1048
unpack_filename(tmp_path, org_path);
1049
#ifdef HAVE_READLINK
1051
char tmp2_path[FN_REFLEN];
1053
/* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
1054
pos= strchr(path, '\0');
1055
if (pos > path && pos[-1] == FN_LIBCHAR)
1058
if ((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0)
1062
if (my_delete(path, MYF(send_error ? MY_WME : 0)))
1066
/* Delete directory symbolic link pointed at */
1070
/* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
1071
pos= strchr(path, '\0');
1073
if (pos > path && pos[-1] == FN_LIBCHAR)
1075
if (rmdir(path) < 0 && send_error)
1077
my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
1085
@brief Internal implementation: switch current database to a valid one.
1087
@param thd Thread context.
1088
@param new_db_name Name of the database to switch to. The function will
1089
take ownership of the name (the caller must not free
1090
the allocated memory). If the name is NULL, we're
1091
going to switch to NULL db.
1092
@param new_db_charset Character set of the new database.
1095
static void mysql_change_db_impl(THD *thd,
1096
LEX_STRING *new_db_name,
1097
const CHARSET_INFO * const new_db_charset)
1099
/* 1. Change current database in THD. */
1101
if (new_db_name == NULL)
1104
THD::set_db() does all the job -- it frees previous database name and
1108
thd->set_db(NULL, 0);
1110
else if (new_db_name == &INFORMATION_SCHEMA_NAME)
1113
Here we must use THD::set_db(), because we want to copy
1114
INFORMATION_SCHEMA_NAME constant.
1117
thd->set_db(INFORMATION_SCHEMA_NAME.str, INFORMATION_SCHEMA_NAME.length);
1122
Here we already have a copy of database name to be used in THD. So,
1123
we just call THD::reset_db(). Since THD::reset_db() does not releases
1124
the previous database name, we should do it explicitly.
1130
thd->reset_db(new_db_name->str, new_db_name->length);
1133
/* 3. Update db-charset environment variables. */
1135
thd->db_charset= new_db_charset;
1136
thd->variables.collation_database= new_db_charset;
1142
Backup the current database name before switch.
1144
@param[in] thd thread handle
1145
@param[in, out] saved_db_name IN: "str" points to a buffer where to store
1146
the old database name, "length" contains the
1148
OUT: if the current (default) database is
1149
not NULL, its name is copied to the
1150
buffer pointed at by "str"
1151
and "length" is updated accordingly.
1152
Otherwise "str" is set to NULL and
1153
"length" is set to 0.
1156
static void backup_current_db_name(THD *thd,
1157
LEX_STRING *saved_db_name)
1161
/* No current (default) database selected. */
1163
saved_db_name->str= NULL;
1164
saved_db_name->length= 0;
1168
strmake(saved_db_name->str, thd->db, saved_db_name->length - 1);
1169
saved_db_name->length= thd->db_length;
1175
Return true if db1_name is equal to db2_name, false otherwise.
1177
The function allows to compare database names according to the MySQL
1178
rules. The database names db1 and db2 are equal if:
1179
- db1 is NULL and db2 is NULL;
1181
- db1 is not-NULL, db2 is not-NULL, db1 is equal (ignoring case) to
1182
db2 in system character set (UTF8).
1186
cmp_db_names(const char *db1_name,
1187
const char *db2_name)
1190
/* db1 is NULL and db2 is NULL */
1191
(!db1_name && !db2_name) ||
1193
/* db1 is not-NULL, db2 is not-NULL, db1 == db2. */
1194
(db1_name && db2_name && my_strcasecmp(system_charset_info, db1_name, db2_name) == 0);
283
1199
@brief Change the current database and its attributes unconditionally.
285
@param session thread handle
1201
@param thd thread handle
286
1202
@param new_db_name database name
287
1203
@param force_switch if force_switch is false, then the operation will fail if
341
1257
@retval true Error
344
bool change(Session &session, identifier::Schema &schema_identifier)
1260
bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
347
if (not plugin::Authorization::isAuthorized(*session.user(), schema_identifier))
349
/* Error message is set in isAuthorized */
353
if (not check(session, schema_identifier))
355
my_error(ER_WRONG_DB_NAME, schema_identifier);
360
if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
362
my_error(ER_BAD_DB_ERROR, schema_identifier);
364
/* The operation failed. */
369
change_db_impl(session, schema_identifier);
1262
LEX_STRING new_db_file_name;
1263
const CHARSET_INFO *db_default_cl;
1265
if (new_db_name == NULL ||
1266
new_db_name->length == 0)
1271
This can happen only if we're switching the current database back
1272
after loading stored program. The thing is that loading of stored
1273
program can happen when there is no current database.
1275
TODO: actually, new_db_name and new_db_name->str seem to be always
1276
non-NULL. In case of stored program, new_db_name->str == "" and
1277
new_db_name->length == 0.
1280
mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
1286
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1292
if (my_strcasecmp(system_charset_info, new_db_name->str,
1293
INFORMATION_SCHEMA_NAME.str) == 0)
1295
/* Switch the current database to INFORMATION_SCHEMA. */
1297
mysql_change_db_impl(thd, &INFORMATION_SCHEMA_NAME, system_charset_info);
1303
Now we need to make a copy because check_db_name requires a
1304
non-constant argument. Actually, it takes database file name.
1306
TODO: fix check_db_name().
1309
new_db_file_name.str= my_strndup(new_db_name->str, new_db_name->length,
1311
new_db_file_name.length= new_db_name->length;
1313
if (new_db_file_name.str == NULL)
1314
return(true); /* the error is set */
1317
NOTE: if check_db_name() fails, we should throw an error in any case,
1318
even if we are called from sp_head::execute().
1320
It's next to impossible however to get this error when we are called
1321
from sp_head::execute(). But let's switch the current database to NULL
1322
in this case to be sure.
1325
if (check_db_name(&new_db_file_name))
1327
my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
1328
free(new_db_file_name.str);
1331
mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
1336
if (check_db_dir_existence(new_db_file_name.str))
1340
/* Throw a warning and free new_db_file_name. */
1342
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1343
ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
1344
new_db_file_name.str);
1346
free(new_db_file_name.str);
1348
/* Change db to NULL. */
1350
mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
1352
/* The operation succeed. */
1358
/* Report an error and free new_db_file_name. */
1360
my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
1361
free(new_db_file_name.str);
1363
/* The operation failed. */
1370
NOTE: in mysql_change_db_impl() new_db_file_name is assigned to THD
1371
attributes and will be freed in THD::~THD().
1374
db_default_cl= get_default_db_collation(thd, new_db_file_name.str);
1376
mysql_change_db_impl(thd, &new_db_file_name, db_default_cl);
375
@brief Internal implementation: switch current database to a valid one.
1383
Change the current database and its attributes if needed.
377
@param session Thread context.
378
@param new_db_name Name of the database to switch to. The function will
379
take ownership of the name (the caller must not free
380
the allocated memory). If the name is NULL, we're
381
going to switch to NULL db.
382
@param new_db_charset Character set of the new database.
1385
@param thd thread handle
1386
@param new_db_name database name
1387
@param[in, out] saved_db_name IN: "str" points to a buffer where to store
1388
the old database name, "length" contains the
1390
OUT: if the current (default) database is
1391
not NULL, its name is copied to the
1392
buffer pointed at by "str"
1393
and "length" is updated accordingly.
1394
Otherwise "str" is set to NULL and
1395
"length" is set to 0.
1396
@param force_switch @see mysql_change_db()
1397
@param[out] cur_db_changed out-flag to indicate whether the current
1398
database has been changed (valid only if
1399
the function suceeded)
385
static void change_db_impl(Session &session, identifier::Schema &schema_identifier)
387
/* 1. Change current database in Session. */
390
if (new_db_name == NULL)
393
Session::set_db() does all the job -- it frees previous database name and
397
session->set_db(NULL, 0);
403
Here we already have a copy of database name to be used in Session. So,
404
we just call Session::reset_db(). Since Session::reset_db() does not releases
405
the previous database name, we should do it explicitly.
408
session.set_db(schema_identifier.getSchemaName());
412
static void change_db_impl(Session &session)
414
session.set_db(string());
1402
bool mysql_opt_change_db(THD *thd,
1403
const LEX_STRING *new_db_name,
1404
LEX_STRING *saved_db_name,
1406
bool *cur_db_changed)
1408
*cur_db_changed= !cmp_db_names(thd->db, new_db_name->str);
1410
if (!*cur_db_changed)
1413
backup_current_db_name(thd, saved_db_name);
1415
return mysql_change_db(thd, new_db_name, force_switch);
418
Check if database name is valid
422
org_name Name of database and length
1420
Check if there is directory for the database name.
1423
check_db_dir_existence()
1424
db_name database name
1427
false There is directory for the specified database name.
1428
true The directory does not exist.
429
bool check(Session &session, identifier::Schema &schema_identifier)
1431
bool check_db_dir_existence(const char *db_name)
431
if (not plugin::Authorization::isAuthorized(*session.user(), schema_identifier))
436
return schema_identifier.isValid();
1433
char db_dir_path[FN_REFLEN];
1434
uint32_t db_dir_path_len;
1436
db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path),
1437
db_name, "", "", 0);
1439
if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
1440
db_dir_path[db_dir_path_len - 1]= 0;
1444
return my_access(db_dir_path, F_OK);
439
} /* namespace schema */
441
} /* namespace drizzled */