49
49
const char *db, const char *path,
50
50
TableList **dropped_tables);
52
static void mysql_change_db_impl(Session *session, LEX_STRING *new_db_name);
56
53
Return default database collation.
94
91
/* path is path to database, not schema file */
95
static int write_schema_file(Session *session,
96
const char *path, const char *name,
97
HA_CREATE_INFO *create)
92
static int write_schema_file(const DatabasePathName &path, const message::Schema &db)
100
94
char schema_file_tmp[FN_REFLEN];
101
string schema_file(path);
107
snprintf(schema_file_tmp, FN_REFLEN, "%s%c%s.tmpXXXXXX", path, FN_LIBCHAR, MY_DB_OPT_FILE);
95
string schema_file(path.to_string());
97
snprintf(schema_file_tmp, FN_REFLEN, "%s%c%s.tmpXXXXXX", path.to_string().c_str(), FN_LIBCHAR, MY_DB_OPT_FILE);
109
99
schema_file.append(1, FN_LIBCHAR);
110
100
schema_file.append(MY_DB_OPT_FILE);
189
bool mysql_create_db(Session *session, const char *db, HA_CREATE_INFO *create_info, bool is_if_not_exists)
174
bool mysql_create_db(Session *session, const NormalisedDatabaseName &database_name, message::Schema *schema_message, bool is_if_not_exists)
191
176
ReplicationServices &replication_services= ReplicationServices::singleton();
192
char path[FN_REFLEN+16];
195
179
bool error= false;
180
DatabasePathName database_path(database_name);
198
182
/* do not create 'information_schema' db */
199
if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.c_str()))
183
if (!my_strcasecmp(system_charset_info, database_name.to_string().c_str(), INFORMATION_SCHEMA_NAME.c_str()))
201
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
185
my_error(ER_DB_CREATE_EXISTS, MYF(0), database_name.to_string().c_str());
189
assert(database_name.isValid());
190
schema_message->set_name(database_name.to_string());
206
193
Do not create database if another thread is holding read lock.
207
194
Wait for global read lock before acquiring LOCK_create_db.
223
210
pthread_mutex_lock(&LOCK_create_db);
225
/* Check directory */
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)
212
if (mkdir(database_path.to_string().c_str(),0777) == -1)
231
214
if (errno == EEXIST)
233
216
if (! is_if_not_exists)
235
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
218
my_error(ER_DB_CREATE_EXISTS, MYF(0), database_name.to_string().c_str());
239
222
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
240
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
223
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
224
database_name.to_string().c_str());
241
225
session->my_ok();
246
my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
230
my_error(ER_CANT_CREATE_DB, MYF(0), database_name.to_string().c_str(), my_errno);
251
error_erno= write_schema_file(session, path, db, create_info);
235
error_erno= write_schema_file(database_path, *schema_message);
252
236
if (error_erno && error_erno != EEXIST)
254
if (rmdir(path) >= 0)
238
if (rmdir(database_path.to_string().c_str()) >= 0)
274
258
/* db-name is already validated when we come here */
276
bool mysql_alter_db(Session *session, const char *db, HA_CREATE_INFO *create_info)
260
bool mysql_alter_db(Session *session, const NormalisedDatabaseName &database_name, message::Schema *schema_message)
278
262
ReplicationServices &replication_services= ReplicationServices::singleton();
281
char path[FN_REFLEN+16];
265
DatabasePathName database_path(database_name);
285
268
Do not alter database if another thread is holding read lock.
296
279
if ((error=wait_if_global_read_lock(session,0,1)))
282
assert(schema_message);
283
assert(database_name.isValid());
285
schema_message->set_name(database_name.to_string());
299
287
pthread_mutex_lock(&LOCK_create_db);
301
/* Change options if current database is being altered. */
302
path_len= build_table_filename(path, sizeof(path), db, "", false);
303
path[path_len-1]= 0; // Remove last '/' from path
305
error= write_schema_file(session, path, db, create_info);
289
error= write_schema_file(database_path, *schema_message);
306
290
if (error && error != EEXIST)
308
292
/* TODO: find some witty way of getting back an error message */
347
331
TableList *dropped_tables= NULL;
349
if (db && (strcmp(db, "information_schema") == 0))
333
if (database_name.to_string().compare(INFORMATION_SCHEMA_NAME) == 0)
351
335
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
373
357
pthread_mutex_lock(&LOCK_create_db);
375
length= build_table_filename(path, sizeof(path), db, "", false);
359
length= build_table_filename(path, sizeof(path),
360
database_name.to_string().c_str(), "", false);
376
361
strcpy(path+length, MY_DB_OPT_FILE); // Append db option file name
378
363
path[length]= '\0'; // Remove file name
386
my_error(ER_DB_DROP_EXISTS, MYF(0), db);
371
my_error(ER_DB_DROP_EXISTS, MYF(0), database_name.to_string().c_str());
390
375
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
391
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db);
376
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
377
database_name.to_string().c_str());
395
381
pthread_mutex_lock(&LOCK_open); /* After deleting database, remove all cache entries related to schema */
396
remove_db_from_cache(db);
382
remove_db_from_cache(database_name.to_string().c_str());
397
383
pthread_mutex_unlock(&LOCK_open);
401
if ((deleted= mysql_rm_known_files(session, dirp, db, path, &dropped_tables)) >= 0)
387
if ((deleted= mysql_rm_known_files(session, dirp, database_name.to_string().c_str(), path, &dropped_tables)) >= 0)
403
389
plugin::StorageEngine::dropDatabase(path);
409
395
const char *query;
410
396
uint32_t query_length;
413
/* The client used the old obsolete mysql_drop_db() call */
415
query_length= sprintf(path, "drop database `%s`", db);
419
query= session->query;
420
query_length= session->query_length;
398
assert(session->query);
400
query= session->query;
401
query_length= session->query_length;
422
403
ReplicationServices &replication_services= ReplicationServices::singleton();
423
404
replication_services.rawStatement(session, session->getQueryString(), session->getQueryLength());
424
405
session->clear_error();
436
417
goto exit; /* not much else we can do */
437
418
query_pos= query_data_start= strcpy(query,"drop table ")+11;
438
419
query_end= query + MAX_DROP_TABLE_Q_LEN;
420
db_len= database_name.to_string().length();
441
422
ReplicationServices &replication_services= ReplicationServices::singleton();
442
423
for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
472
453
SELECT DATABASE() in the future). For this we free() session->db and set
475
if (! session->db.empty() && ! strcmp(session->db.c_str(), db))
476
mysql_change_db_impl(session, NULL);
456
if (! session->db.empty() && session->db.compare(database_name.to_string()) == 0)
477
458
pthread_mutex_unlock(&LOCK_create_db);
478
459
start_waiting_global_read_lock(session);
732
@brief Internal implementation: switch current database to a valid one.
734
@param session Thread context.
735
@param new_db_name Name of the database to switch to. The function will
736
take ownership of the name (the caller must not free
737
the allocated memory). If the name is NULL, we're
738
going to switch to NULL db.
739
@param new_db_charset Character set of the new database.
742
static void mysql_change_db_impl(Session *session, LEX_STRING *new_db_name)
744
/* 1. Change current database in Session. */
746
if (new_db_name == NULL)
749
Session::set_db() does all the job -- it frees previous database name and
753
session->set_db(NULL, 0);
758
Here we already have a copy of database name to be used in Session. So,
759
we just call Session::reset_db(). Since Session::reset_db() does not releases
760
the previous database name, we should do it explicitly.
763
session->set_db(new_db_name->str, new_db_name->length);
768
Return true if db1_name is equal to db2_name, false otherwise.
770
The function allows to compare database names according to the MySQL
771
rules. The database names db1 and db2 are equal if:
772
- db1 is NULL and db2 is NULL;
774
- db1 is not-NULL, db2 is not-NULL, db1 is equal (ignoring case) to
775
db2 in system character set (UTF8).
779
cmp_db_names(const char *db1_name,
780
const char *db2_name)
783
/* db1 is NULL and db2 is NULL */
784
(!db1_name && !db2_name) ||
786
/* db1 is not-NULL, db2 is not-NULL, db1 == db2. */
787
(db1_name && db2_name && my_strcasecmp(system_charset_info, db1_name, db2_name) == 0);
792
713
@brief Change the current database and its attributes unconditionally.
794
715
@param session thread handle
850
771
@retval true Error
853
bool mysql_change_db(Session *session, const LEX_STRING *new_db_name, bool force_switch)
774
bool mysql_change_db(Session *session, const NormalisedDatabaseName &normalised_database_name, bool force_switch)
855
LEX_STRING new_db_file_name;
856
776
const CHARSET_INFO *db_default_cl;
859
assert(new_db_name->length);
861
if (my_strcasecmp(system_charset_info, new_db_name->str,
778
if (my_strcasecmp(system_charset_info, normalised_database_name.to_string().c_str(),
862
779
INFORMATION_SCHEMA_NAME.c_str()) == 0)
864
/* Switch the current database to INFORMATION_SCHEMA. */
865
/* const_cast<> is safe here: mysql_change_db_impl does a copy */
866
LEX_STRING is_name= { const_cast<char *>(INFORMATION_SCHEMA_NAME.c_str()),
867
INFORMATION_SCHEMA_NAME.length() };
868
mysql_change_db_impl(session, &is_name);
781
NonNormalisedDatabaseName non_normalised_i_s(INFORMATION_SCHEMA_NAME);
782
NormalisedDatabaseName is_name(non_normalised_i_s);
784
session->set_db(is_name);
874
Now we need to make a copy because check_db_name requires a
875
non-constant argument. Actually, it takes database file name.
877
TODO: fix check_db_name().
880
new_db_file_name.length= new_db_name->length;
881
new_db_file_name.str= (char *)malloc(new_db_name->length + 1);
882
if (new_db_file_name.str == NULL)
883
return true; /* the error is set */
884
memcpy(new_db_file_name.str, new_db_name->str, new_db_name->length);
885
new_db_file_name.str[new_db_name->length]= 0;
889
789
NOTE: if check_db_name() fails, we should throw an error in any case,
890
790
even if we are called from sp_head::execute().
893
793
from sp_head::execute(). But let's switch the current database to NULL
894
794
in this case to be sure.
897
if (check_db_name(&new_db_file_name))
796
if (! normalised_database_name.isValid())
899
my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
900
free(new_db_file_name.str);
798
my_error(ER_WRONG_DB_NAME, MYF(0),
799
normalised_database_name.to_string().c_str());
902
801
if (force_switch)
903
mysql_change_db_impl(session, NULL);
908
if (check_db_dir_existence(new_db_file_name.str))
807
DatabasePathName database_path(normalised_database_name);
809
if (! database_path.exists())
910
811
if (force_switch)
914
815
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
915
816
ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
916
new_db_file_name.str);
918
free(new_db_file_name.str);
817
normalised_database_name.to_string().c_str());
920
819
/* Change db to NULL. */
922
mysql_change_db_impl(session, NULL);
924
823
/* The operation succeed. */
930
829
/* Report an error and free new_db_file_name. */
932
my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
933
free(new_db_file_name.str);
831
my_error(ER_BAD_DB_ERROR, MYF(0),
832
normalised_database_name.to_string().c_str());
935
834
/* The operation failed. */
941
db_default_cl= get_default_db_collation(new_db_file_name.str);
840
db_default_cl= get_default_db_collation(normalised_database_name.to_string().c_str());
943
mysql_change_db_impl(session, &new_db_file_name);
944
free(new_db_file_name.str);
842
session->set_db(normalised_database_name);
950
Check if there is directory for the database name.
953
check_db_dir_existence()
954
db_name database name
957
false There is directory for the specified database name.
958
true The directory does not exist.
961
bool check_db_dir_existence(const char *db_name)
847
NormalisedDatabaseName::NormalisedDatabaseName(const NonNormalisedDatabaseName &dbname)
849
const std::string &non_norm_string= dbname.to_string();
850
database_name= (char*)malloc(non_norm_string.size()+1);
852
assert(database_name); /* FIXME: should throw exception */
854
strncpy(database_name, non_norm_string.c_str(), non_norm_string.size()+1);
856
my_casedn_str(files_charset_info, database_name);
859
NormalisedDatabaseName::~NormalisedDatabaseName()
864
bool NormalisedDatabaseName::isValid() const
866
LEX_STRING db_lexstring;
868
db_lexstring.str= database_name;
869
db_lexstring.length= strlen(database_name);
871
if (db_lexstring.length == 0
872
|| db_lexstring.length > NAME_LEN
873
|| database_name[db_lexstring.length - 1] == ' ')
876
return (! check_identifier_name(&db_lexstring));
879
DatabasePathName::DatabasePathName(const NormalisedDatabaseName &database_name)
963
881
char db_dir_path[FN_REFLEN];
964
882
uint32_t db_dir_path_len;
966
884
db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path),
885
database_name.to_string().c_str(),
969
888
if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
970
889
db_dir_path[db_dir_path_len - 1]= 0;
891
database_path.assign(db_dir_path);
974
return my_access(db_dir_path, F_OK);
894
bool DatabasePathName::exists() const
896
/* TODO: handle EIO and other fun errors */
897
return access(database_path.c_str(), F_OK) == 0;