26
24
#include <mysys/mysys_err.h>
27
25
#include <mysys/my_dir.h>
29
#include <drizzled/error.h>
30
#include <drizzled/gettext.h>
27
#include <drizzled/drizzled_error_messages.h>
28
#include <libdrizzle/gettext.h>
33
31
#define MAX_DROP_TABLE_Q_LEN 1024
36
34
static TYPELIB deletable_extentions=
37
35
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
39
static long mysql_rm_known_files(Session *session, MY_DIR *dirp,
37
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
40
38
const char *db, const char *path, uint32_t level,
41
39
TableList **dropped_tables);
43
41
static bool rm_dir_w_symlink(const char *org_path, bool send_error);
44
static void mysql_change_db_impl(Session *session,
42
static void mysql_change_db_impl(THD *thd,
45
43
LEX_STRING *new_db_name,
46
44
const CHARSET_INFO * const new_db_charset);
133
131
Helper function to write a query to binlog used by mysql_rm_db()
136
static inline void write_to_binlog(Session *session, char *query, uint32_t q_len,
134
static inline void write_to_binlog(THD *thd, char *query, uint32_t q_len,
137
135
char *db, uint32_t db_len)
139
Query_log_event qinfo(session, query, q_len, 0, 0);
137
Query_log_event qinfo(thd, query, q_len, 0, 0);
140
138
qinfo.error_code= 0;
142
140
qinfo.db_len= db_len;
334
332
1 Could not create file or write to it. Error sent through my_error()
337
static bool write_db_opt(Session *session, const char *path, const char *name, HA_CREATE_INFO *create)
335
static bool write_db_opt(THD *thd, const char *path, const char *name, HA_CREATE_INFO *create)
339
337
bool error= true;
340
338
drizzle::Schema db;
344
342
if (!create->default_table_charset)
345
create->default_table_charset= session->variables.collation_server;
343
create->default_table_charset= thd->variables.collation_server;
347
345
if (put_dbopt(path, create))
377
bool load_db_opt(Session *session, const char *path, HA_CREATE_INFO *create)
375
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
380
378
drizzle::Schema db;
383
381
memset(create, 0, sizeof(*create));
384
create->default_table_charset= session->variables.collation_server;
382
create->default_table_charset= thd->variables.collation_server;
386
384
/* Check if options for this database are already in the hash */
387
385
if (!get_dbopt(path, create))
453
451
true Failed to retrieve options
456
bool load_db_opt_by_name(Session *session, const char *db_name,
454
bool load_db_opt_by_name(THD *thd, const char *db_name,
457
455
HA_CREATE_INFO *db_create_info)
459
457
char db_opt_path[FN_REFLEN];
465
463
(void) build_table_filename(db_opt_path, sizeof(db_opt_path),
466
464
db_name, "", MY_DB_OPT_FILE, 0);
468
return load_db_opt(session, db_opt_path, db_create_info);
466
return load_db_opt(thd, db_opt_path, db_create_info);
473
471
Return default database collation.
475
@param session Thread context.
473
@param thd Thread context.
476
474
@param db_name Database name.
478
476
@return CHARSET_INFO object. The operation always return valid character
479
477
set, even if the database does not exist.
482
const CHARSET_INFO *get_default_db_collation(Session *session, const char *db_name)
480
const CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
484
482
HA_CREATE_INFO db_info;
486
if (session->db != NULL && strcmp(db_name, session->db) == 0)
487
return session->db_charset;
484
if (thd->db != NULL && strcmp(db_name, thd->db) == 0)
485
return thd->db_charset;
489
load_db_opt_by_name(session, db_name, &db_info);
487
load_db_opt_by_name(thd, db_name, &db_info);
492
490
NOTE: even if load_db_opt_by_name() fails,
527
int mysql_create_db(Session *session, char *db, HA_CREATE_INFO *create_info, bool silent)
525
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent)
529
527
char path[FN_REFLEN+16];
530
528
char tmp_query[FN_REFLEN+16];
553
551
has the global read lock and refuses the operation with
554
552
ER_CANT_UPDATE_WITH_READLOCK if applicable.
556
if (wait_if_global_read_lock(session, 0, 1))
554
if (wait_if_global_read_lock(thd, 0, 1))
576
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
574
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
577
575
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
598
596
path[path_len-1]= FN_LIBCHAR;
599
597
strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
600
if (write_db_opt(session, path, db, create_info))
598
if (write_db_opt(thd, path, db, create_info))
603
601
Could not create options file.
632
query= session->query;
633
query_length= session->query_length;
631
query_length= thd->query_length;
636
634
if (mysql_bin_log.is_open())
638
Query_log_event qinfo(session, query, query_length, 0,
636
Query_log_event qinfo(thd, query, query_length, 0,
639
637
/* suppress_use */ true);
661
659
/* These DDL methods and logging protected with LOCK_mysql_create_db */
662
660
mysql_bin_log.write(&qinfo);
664
my_ok(session, result);
668
666
pthread_mutex_unlock(&LOCK_mysql_create_db);
669
start_waiting_global_read_lock(session);
667
start_waiting_global_read_lock(thd);
675
673
/* db-name is already validated when we come here */
677
bool mysql_alter_db(Session *session, const char *db, HA_CREATE_INFO *create_info)
675
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
679
677
char path[FN_REFLEN+16];
692
690
has the global read lock and refuses the operation with
693
691
ER_CANT_UPDATE_WITH_READLOCK if applicable.
695
if ((error=wait_if_global_read_lock(session,0,1)))
693
if ((error=wait_if_global_read_lock(thd,0,1)))
698
696
pthread_mutex_lock(&LOCK_mysql_create_db);
703
701
"table name to file name" encoding.
705
703
build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0);
706
if ((error=write_db_opt(session, path, db, create_info)))
704
if ((error=write_db_opt(thd, path, db, create_info)))
709
707
/* Change options if current database is being altered. */
711
if (session->db && !strcmp(session->db,db))
709
if (thd->db && !strcmp(thd->db,db))
713
session->db_charset= create_info->default_table_charset ?
711
thd->db_charset= create_info->default_table_charset ?
714
712
create_info->default_table_charset :
715
session->variables.collation_server;
716
session->variables.collation_database= session->db_charset;
713
thd->variables.collation_server;
714
thd->variables.collation_database= thd->db_charset;
719
717
if (mysql_bin_log.is_open())
721
Query_log_event qinfo(session, session->query, session->query_length, 0,
719
Query_log_event qinfo(thd, thd->query, thd->query_length, 0,
722
720
/* suppress_use */ true);
730
728
qinfo.db_len = strlen(db);
732
session->clear_error();
733
731
/* These DDL methods and logging protected with LOCK_mysql_create_db */
734
732
mysql_bin_log.write(&qinfo);
736
my_ok(session, result);
739
737
pthread_mutex_unlock(&LOCK_mysql_create_db);
740
start_waiting_global_read_lock(session);
738
start_waiting_global_read_lock(thd);
763
bool mysql_rm_db(Session *session,char *db,bool if_exists, bool silent)
761
bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
766
764
int error= false;
787
785
has the global read lock and refuses the operation with
788
786
ER_CANT_UPDATE_WITH_READLOCK if applicable.
790
if (wait_if_global_read_lock(session, 0, 1))
788
if (wait_if_global_read_lock(thd, 0, 1))
800
798
row-based replication. The flag will be reset at the end of the
803
session->clear_current_stmt_binlog_row_based();
801
thd->clear_current_stmt_binlog_row_based();
805
803
length= build_table_filename(path, sizeof(path), db, "", "", 0);
806
804
my_stpcpy(path+length, MY_DB_OPT_FILE); // Append db option file name
820
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
818
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
821
819
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db);
831
if ((deleted= mysql_rm_known_files(session, dirp, db, path, 0,
829
if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0,
832
830
&dropped_tables)) >= 0)
834
832
ha_drop_database(path);
851
query =session->query;
852
query_length= session->query_length;
850
query_length= thd->query_length;
854
852
if (mysql_bin_log.is_open())
856
Query_log_event qinfo(session, query, query_length, 0,
854
Query_log_event qinfo(thd, query, query_length, 0,
857
855
/* suppress_use */ true);
859
857
Write should use the database being created as the "current
864
862
qinfo.db_len = strlen(db);
866
session->clear_error();
867
865
/* These DDL methods and logging protected with LOCK_mysql_create_db */
868
866
mysql_bin_log.write(&qinfo);
870
session->clear_error();
871
session->server_status|= SERVER_STATUS_DB_DROPPED;
872
my_ok(session, (uint32_t) deleted);
873
session->server_status&= ~SERVER_STATUS_DB_DROPPED;
869
thd->server_status|= SERVER_STATUS_DB_DROPPED;
870
my_ok(thd, (uint32_t) deleted);
871
thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
875
873
else if (mysql_bin_log.is_open())
881
if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
879
if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN)))
882
880
goto exit; /* not much else we can do */
883
881
query_pos= query_data_start= my_stpcpy(query,"drop table ");
884
882
query_end= query + MAX_DROP_TABLE_Q_LEN;
893
891
if (query_pos + tbl_name_len + 1 >= query_end)
895
893
/* These DDL methods and logging protected with LOCK_mysql_create_db */
896
write_to_binlog(session, query, query_pos -1 - query, db, db_len);
894
write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
897
895
query_pos= query_data_start;
906
904
if (query_pos != query_data_start)
908
906
/* These DDL methods and logging protected with LOCK_mysql_create_db */
909
write_to_binlog(session, query, query_pos -1 - query, db, db_len);
907
write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
915
913
If this database was the client's selected database, we silently
916
914
change the client's selected database to nothing (to have an empty
917
SELECT DATABASE() in the future). For this we free() session->db and set
915
SELECT DATABASE() in the future). For this we free() thd->db and set
920
if (session->db && !strcmp(session->db, db))
921
mysql_change_db_impl(session, NULL, session->variables.collation_server);
918
if (thd->db && !strcmp(thd->db, db))
919
mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
922
920
pthread_mutex_unlock(&LOCK_mysql_create_db);
923
start_waiting_global_read_lock(session);
921
start_waiting_global_read_lock(thd);
929
927
Removes files with known extensions plus.
930
session MUST be set when calling this function!
928
thd MUST be set when calling this function!
933
static long mysql_rm_known_files(Session *session, MY_DIR *dirp, const char *db,
931
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
934
932
const char *org_path, uint32_t level,
935
933
TableList **dropped_tables)
968
966
/* Drop the table nicely */
969
967
*extension= 0; // Remove extension
970
968
TableList *table_list=(TableList*)
971
session->calloc(sizeof(*table_list) +
969
thd->calloc(sizeof(*table_list) +
973
971
MYSQL50_TABLE_NAME_PREFIX_LENGTH +
974
972
strlen(file->name) + 1);
999
if (session->killed ||
1000
(tot_list && mysql_rm_table_part2(session, tot_list, 1, 0, 1, 1)))
998
(tot_list && mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1)))
1003
1001
my_dirend(dirp);
1085
1083
@brief Internal implementation: switch current database to a valid one.
1087
@param session Thread context.
1085
@param thd Thread context.
1088
1086
@param new_db_name Name of the database to switch to. The function will
1089
1087
take ownership of the name (the caller must not free
1090
1088
the allocated memory). If the name is NULL, we're
1092
1090
@param new_db_charset Character set of the new database.
1095
static void mysql_change_db_impl(Session *session,
1093
static void mysql_change_db_impl(THD *thd,
1096
1094
LEX_STRING *new_db_name,
1097
1095
const CHARSET_INFO * const new_db_charset)
1099
/* 1. Change current database in Session. */
1097
/* 1. Change current database in THD. */
1101
1099
if (new_db_name == NULL)
1104
Session::set_db() does all the job -- it frees previous database name and
1102
THD::set_db() does all the job -- it frees previous database name and
1105
1103
sets the new one.
1108
session->set_db(NULL, 0);
1106
thd->set_db(NULL, 0);
1110
1108
else if (new_db_name == &INFORMATION_SCHEMA_NAME)
1113
Here we must use Session::set_db(), because we want to copy
1111
Here we must use THD::set_db(), because we want to copy
1114
1112
INFORMATION_SCHEMA_NAME constant.
1117
session->set_db(INFORMATION_SCHEMA_NAME.str, INFORMATION_SCHEMA_NAME.length);
1115
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 Session. So,
1123
we just call Session::reset_db(). Since Session::reset_db() does not releases
1120
Here we already have a copy of database name to be used in THD. So,
1121
we just call THD::reset_db(). Since THD::reset_db() does not releases
1124
1122
the previous database name, we should do it explicitly.
1130
session->reset_db(new_db_name->str, new_db_name->length);
1128
thd->reset_db(new_db_name->str, new_db_name->length);
1133
1131
/* 3. Update db-charset environment variables. */
1135
session->db_charset= new_db_charset;
1136
session->variables.collation_database= new_db_charset;
1133
thd->db_charset= new_db_charset;
1134
thd->variables.collation_database= new_db_charset;
1142
1140
Backup the current database name before switch.
1144
@param[in] session thread handle
1142
@param[in] thd thread handle
1145
1143
@param[in, out] saved_db_name IN: "str" points to a buffer where to store
1146
1144
the old database name, "length" contains the
1153
1151
"length" is set to 0.
1156
static void backup_current_db_name(Session *session,
1154
static void backup_current_db_name(THD *thd,
1157
1155
LEX_STRING *saved_db_name)
1161
1159
/* No current (default) database selected. */
1168
strmake(saved_db_name->str, session->db, saved_db_name->length - 1);
1169
saved_db_name->length= session->db_length;
1166
strmake(saved_db_name->str, thd->db, saved_db_name->length - 1);
1167
saved_db_name->length= thd->db_length;
1199
1197
@brief Change the current database and its attributes unconditionally.
1201
@param session thread handle
1199
@param thd thread handle
1202
1200
@param new_db_name database name
1203
1201
@param force_switch if force_switch is false, then the operation will fail if
1224
1222
@@collation_server, but the operation will fail;
1226
1224
- user privileges will not be checked
1227
(Session::db_access however is updated);
1225
(THD::db_access however is updated);
1229
1227
TODO: is this really the intention?
1230
1228
(see sp-security.test).
1237
1235
@details The function checks that the database name corresponds to a
1238
1236
valid and existent database, checks access rights and changes the current
1239
1237
database with database attributes (@@collation_database session variable,
1240
Session::db_access).
1242
1240
This function is not the only way to switch the database that is
1243
1241
currently employed. When the replication slave thread switches the
1244
database before executing a query, it calls session->set_db directly.
1242
database before executing a query, it calls thd->set_db directly.
1245
1243
However, if the query, in turn, uses a stored routine, the stored routine
1246
1244
will use this function, even if it's run on the slave.
1257
1255
@retval true Error
1260
bool mysql_change_db(Session *session, const LEX_STRING *new_db_name, bool force_switch)
1258
bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
1262
1260
LEX_STRING new_db_file_name;
1263
1261
const CHARSET_INFO *db_default_cl;
1277
1275
new_db_name->length == 0.
1280
mysql_change_db_impl(session, NULL, session->variables.collation_server);
1278
mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
1295
1293
/* Switch the current database to INFORMATION_SCHEMA. */
1297
mysql_change_db_impl(session, &INFORMATION_SCHEMA_NAME, system_charset_info);
1295
mysql_change_db_impl(thd, &INFORMATION_SCHEMA_NAME, system_charset_info);
1328
1326
free(new_db_file_name.str);
1330
1328
if (force_switch)
1331
mysql_change_db_impl(session, NULL, session->variables.collation_server);
1329
mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
1340
1338
/* Throw a warning and free new_db_file_name. */
1342
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1340
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1343
1341
ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
1344
1342
new_db_file_name.str);
1348
1346
/* Change db to NULL. */
1350
mysql_change_db_impl(session, NULL, session->variables.collation_server);
1348
mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
1352
1350
/* The operation succeed. */
1370
NOTE: in mysql_change_db_impl() new_db_file_name is assigned to Session
1371
attributes and will be freed in Session::~Session().
1368
NOTE: in mysql_change_db_impl() new_db_file_name is assigned to THD
1369
attributes and will be freed in THD::~THD().
1374
db_default_cl= get_default_db_collation(session, new_db_file_name.str);
1372
db_default_cl= get_default_db_collation(thd, new_db_file_name.str);
1376
mysql_change_db_impl(session, &new_db_file_name, db_default_cl);
1374
mysql_change_db_impl(thd, &new_db_file_name, db_default_cl);
1383
1381
Change the current database and its attributes if needed.
1385
@param session thread handle
1383
@param thd thread handle
1386
1384
@param new_db_name database name
1387
1385
@param[in, out] saved_db_name IN: "str" points to a buffer where to store
1388
1386
the old database name, "length" contains the
1399
1397
the function suceeded)
1402
bool mysql_opt_change_db(Session *session,
1400
bool mysql_opt_change_db(THD *thd,
1403
1401
const LEX_STRING *new_db_name,
1404
1402
LEX_STRING *saved_db_name,
1405
1403
bool force_switch,
1406
1404
bool *cur_db_changed)
1408
*cur_db_changed= !cmp_db_names(session->db, new_db_name->str);
1406
*cur_db_changed= !cmp_db_names(thd->db, new_db_name->str);
1410
1408
if (!*cur_db_changed)
1413
backup_current_db_name(session, saved_db_name);
1411
backup_current_db_name(thd, saved_db_name);
1415
return mysql_change_db(session, new_db_name, force_switch);
1413
return mysql_change_db(thd, new_db_name, force_switch);