Commit bc5dc9e0 authored by unknown's avatar unknown

renamedb.test, renamedb.result:

  new file
Many files:
  WL#757 RENAME DATABASE


sql/mysql_priv.h:
  WL#757 RENAME DATABASE
sql/mysqld.cc:
  WL#757 RENAME DATABASE
sql/sql_db.cc:
  WL#757 RENAME DATABASE
sql/sql_lex.h:
  WL#757 RENAME DATABASE
sql/sql_parse.cc:
  WL#757 RENAME DATABASE
sql/sql_rename.cc:
  WL#757 RENAME DATABASE
sql/sql_table.cc:
  WL#757 RENAME DATABASE
sql/sql_yacc.yy:
  WL#757 RENAME DATABASE
parent 3a2b70f8
drop database if exists testdb1;
create database testdb1 default character set latin2;
use testdb1;
create table t1 (a int);
insert into t1 values (1),(2),(3);
show create database testdb1;
Database Create Database
testdb1 CREATE DATABASE `testdb1` /*!40100 DEFAULT CHARACTER SET latin2 */
show tables;
Tables_in_testdb1
t1
rename database testdb1 to testdb2;
show create database testdb1;
ERROR 42000: Unknown database 'testdb1'
show create database testdb2;
Database Create Database
testdb2 CREATE DATABASE `testdb2` /*!40100 DEFAULT CHARACTER SET latin2 */
select database();
database()
testdb2
show tables;
Tables_in_testdb2
t1
select a from t1 order by a;
a
1
2
3
drop database testdb2;
--disable_warnings
drop database if exists testdb1;
--enable_warnings
create database testdb1 default character set latin2;
use testdb1;
create table t1 (a int);
insert into t1 values (1),(2),(3);
show create database testdb1;
show tables;
rename database testdb1 to testdb2;
--error 1049
show create database testdb1;
show create database testdb2;
select database();
show tables;
select a from t1 order by a;
drop database testdb2;
...@@ -611,6 +611,7 @@ void write_bin_log(THD *thd, bool clear_error, ...@@ -611,6 +611,7 @@ void write_bin_log(THD *thd, bool clear_error,
bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent); bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create); bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create);
bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent); bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent);
bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db);
void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags); void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags);
void mysql_client_binlog_statement(THD *thd); void mysql_client_binlog_statement(THD *thd);
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
...@@ -623,7 +624,7 @@ int mysql_rm_table_part2_with_lock(THD *thd, TABLE_LIST *tables, ...@@ -623,7 +624,7 @@ int mysql_rm_table_part2_with_lock(THD *thd, TABLE_LIST *tables,
bool quick_rm_table(handlerton *base,const char *db, bool quick_rm_table(handlerton *base,const char *db,
const char *table_name); const char *table_name);
void close_cached_table(THD *thd, TABLE *table); void close_cached_table(THD *thd, TABLE *table);
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list); bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent);
bool mysql_change_db(THD *thd,const char *name,bool no_access_check); bool mysql_change_db(THD *thd,const char *name,bool no_access_check);
void mysql_parse(THD *thd,char *inBuf,uint length); void mysql_parse(THD *thd,char *inBuf,uint length);
bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length); bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
...@@ -1228,10 +1229,12 @@ uint check_word(TYPELIB *lib, const char *val, const char *end, ...@@ -1228,10 +1229,12 @@ uint check_word(TYPELIB *lib, const char *val, const char *end,
bool is_keyword(const char *name, uint len); bool is_keyword(const char *name, uint len);
#define MY_DB_OPT_FILE "db.opt" #define MY_DB_OPT_FILE "db.opt"
bool my_database_names_init(void);
void my_database_names_free(void);
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create); bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
bool my_dbopt_init(void);
void my_dbopt_cleanup(void); void my_dbopt_cleanup(void);
void my_dbopt_free(void); extern int creating_database; // How many database locks are made
extern int creating_table; // How many mysql_create_table() are running
/* /*
External variables External variables
...@@ -1334,7 +1337,7 @@ extern FILE *bootstrap_file; ...@@ -1334,7 +1337,7 @@ extern FILE *bootstrap_file;
extern int bootstrap_error; extern int bootstrap_error;
extern FILE *stderror_file; extern FILE *stderror_file;
extern pthread_key(MEM_ROOT**,THR_MALLOC); extern pthread_key(MEM_ROOT**,THR_MALLOC);
extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_lock_db,
LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status, LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator, LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator,
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
...@@ -1365,7 +1368,7 @@ extern const char *opt_date_time_formats[]; ...@@ -1365,7 +1368,7 @@ extern const char *opt_date_time_formats[];
extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[]; extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
extern String null_string; extern String null_string;
extern HASH open_cache; extern HASH open_cache, lock_db_cache;
extern TABLE *unused_tables; extern TABLE *unused_tables;
extern const char* any_db; extern const char* any_db;
extern struct my_option my_long_options[]; extern struct my_option my_long_options[];
......
...@@ -1158,7 +1158,7 @@ void clean_up(bool print_message) ...@@ -1158,7 +1158,7 @@ void clean_up(bool print_message)
bitmap_free(&slave_error_mask); bitmap_free(&slave_error_mask);
#endif #endif
my_tz_free(); my_tz_free();
my_dbopt_free(); my_database_names_free();
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
acl_free(1); acl_free(1);
grant_free(); grant_free();
...@@ -1274,6 +1274,7 @@ static void wait_for_signal_thread_to_end() ...@@ -1274,6 +1274,7 @@ static void wait_for_signal_thread_to_end()
static void clean_up_mutexes() static void clean_up_mutexes()
{ {
(void) pthread_mutex_destroy(&LOCK_mysql_create_db); (void) pthread_mutex_destroy(&LOCK_mysql_create_db);
(void) pthread_mutex_destroy(&LOCK_lock_db);
(void) pthread_mutex_destroy(&LOCK_Acl); (void) pthread_mutex_destroy(&LOCK_Acl);
(void) rwlock_destroy(&LOCK_grant); (void) rwlock_destroy(&LOCK_grant);
(void) pthread_mutex_destroy(&LOCK_open); (void) pthread_mutex_destroy(&LOCK_open);
...@@ -2829,7 +2830,7 @@ static int init_common_variables(const char *conf_file_name, int argc, ...@@ -2829,7 +2830,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1)) if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
return 1; return 1;
if (my_dbopt_init()) if (my_database_names_init())
return 1; return 1;
/* /*
...@@ -2883,6 +2884,7 @@ You should consider changing lower_case_table_names to 1 or 2", ...@@ -2883,6 +2884,7 @@ You should consider changing lower_case_table_names to 1 or 2",
static int init_thread_environment() static int init_thread_environment()
{ {
(void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW); (void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_lock_db,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW); (void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_open, NULL); (void) pthread_mutex_init(&LOCK_open, NULL);
(void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
......
This diff is collapsed.
...@@ -67,6 +67,7 @@ enum enum_sql_command { ...@@ -67,6 +67,7 @@ enum enum_sql_command {
SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES, SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES,
SQLCOM_GRANT, SQLCOM_GRANT,
SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB, SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB,
SQLCOM_RENAME_DB,
SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT, SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION, SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
...@@ -817,6 +818,7 @@ typedef struct st_lex ...@@ -817,6 +818,7 @@ typedef struct st_lex
required a local context, the parser pops the top-most context. required a local context, the parser pops the top-most context.
*/ */
List<Name_resolution_context> context_stack; List<Name_resolution_context> context_stack;
List<LEX_STRING> db_list;
SQL_LIST proc_list, auxilliary_table_list, save_list; SQL_LIST proc_list, auxilliary_table_list, save_list;
create_field *last_field; create_field *last_field;
......
...@@ -3065,7 +3065,7 @@ mysql_execute_command(THD *thd) ...@@ -3065,7 +3065,7 @@ mysql_execute_command(THD *thd)
} }
} }
query_cache_invalidate3(thd, first_table, 0); query_cache_invalidate3(thd, first_table, 0);
if (end_active_trans(thd) || mysql_rename_tables(thd, first_table)) if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
goto error; goto error;
break; break;
} }
...@@ -3643,6 +3643,48 @@ mysql_execute_command(THD *thd) ...@@ -3643,6 +3643,48 @@ mysql_execute_command(THD *thd)
res= mysql_rm_db(thd, lex->name, lex->drop_if_exists, 0); res= mysql_rm_db(thd, lex->name, lex->drop_if_exists, 0);
break; break;
} }
case SQLCOM_RENAME_DB:
{
LEX_STRING *olddb, *newdb;
List_iterator <LEX_STRING> db_list(lex->db_list);
olddb= db_list++;
newdb= db_list++;
if (end_active_trans(thd))
{
res= 1;
break;
}
#ifdef HAVE_REPLICATION
if (thd->slave_thread &&
(!rpl_filter->db_ok(olddb->str) ||
!rpl_filter->db_ok(newdb->str) ||
!rpl_filter->db_ok_with_wild_table(olddb->str) ||
!rpl_filter->db_ok_with_wild_table(newdb->str)))
{
res= 1;
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
#endif
if (check_access(thd,ALTER_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) ||
check_access(thd,DROP_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) ||
check_access(thd,CREATE_ACL,newdb->str,0,1,0,is_schema_db(newdb->str)))
{
res= 1;
break;
}
if (thd->locked_tables || thd->active_transaction())
{
res= 1;
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
res= mysql_rename_db(thd, olddb, newdb);
if (!res)
send_ok(thd);
break;
}
case SQLCOM_ALTER_DB: case SQLCOM_ALTER_DB:
{ {
char *db= lex->name ? lex->name : thd->db; char *db= lex->name ? lex->name : thd->db;
......
...@@ -31,7 +31,7 @@ static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list); ...@@ -31,7 +31,7 @@ static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list);
second entry is the new name. second entry is the new name.
*/ */
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
{ {
bool error= 1; bool error= 1;
TABLE_LIST *ren_table= 0; TABLE_LIST *ren_table= 0;
...@@ -79,7 +79,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) ...@@ -79,7 +79,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
} }
/* Lets hope this doesn't fail as the result will be messy */ /* Lets hope this doesn't fail as the result will be messy */
if (!error) if (!silent && !error)
{ {
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <io.h> #include <io.h>
#endif #endif
int creating_table= 0; // How many mysql_create_table are running
const char *primary_key_name="PRIMARY"; const char *primary_key_name="PRIMARY";
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end); static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
...@@ -1973,7 +1975,7 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field) ...@@ -1973,7 +1975,7 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field)
Create a table Create a table
SYNOPSIS SYNOPSIS
mysql_create_table() mysql_create_table_internal()
thd Thread object thd Thread object
db Database db Database
table_name Table name table_name Table name
...@@ -1996,7 +1998,8 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field) ...@@ -1996,7 +1998,8 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field)
TRUE error TRUE error
*/ */
bool mysql_create_table(THD *thd,const char *db, const char *table_name, bool mysql_create_table_internal(THD *thd,
const char *db, const char *table_name,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
List<create_field> &fields, List<create_field> &fields,
List<Key> &keys,bool internal_tmp_table, List<Key> &keys,bool internal_tmp_table,
...@@ -2009,7 +2012,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -2009,7 +2012,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
KEY *key_info_buffer; KEY *key_info_buffer;
handler *file; handler *file;
bool error= TRUE; bool error= TRUE;
DBUG_ENTER("mysql_create_table"); DBUG_ENTER("mysql_create_table_internal");
/* Check for duplicate fields and check type of table to create */ /* Check for duplicate fields and check type of table to create */
if (!fields.elements) if (!fields.elements)
...@@ -2289,6 +2292,49 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -2289,6 +2292,49 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
goto unlock_and_end; goto unlock_and_end;
} }
/*
Database locking aware wrapper for mysql_create_table_internal(),
*/
bool mysql_create_table(THD *thd, const char *db, const char *table_name,
HA_CREATE_INFO *create_info,
List<create_field> &fields,
List<Key> &keys,bool internal_tmp_table,
uint select_field_count)
{
bool result;
DBUG_ENTER("mysql_create_table");
/* Wait for any database locks */
pthread_mutex_lock(&LOCK_lock_db);
while (!thd->killed &&
hash_search(&lock_db_cache,(byte*) db, strlen(db)))
{
wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
pthread_mutex_lock(&LOCK_lock_db);
}
if (thd->killed)
{
pthread_mutex_unlock(&LOCK_lock_db);
DBUG_RETURN(TRUE);
}
creating_table++;
pthread_mutex_unlock(&LOCK_lock_db);
result= mysql_create_table_internal(thd, db, table_name, create_info,
fields, keys, internal_tmp_table,
select_field_count);
pthread_mutex_lock(&LOCK_lock_db);
if (!--creating_table && creating_database)
pthread_cond_signal(&COND_refresh);
pthread_mutex_unlock(&LOCK_lock_db);
DBUG_RETURN(result);
}
/* /*
** Give the key name after the first field with an optional '_#' after ** Give the key name after the first field with an optional '_#' after
**/ **/
......
...@@ -868,7 +868,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -868,7 +868,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
clear_privileges flush_options flush_option clear_privileges flush_options flush_option
equal optional_braces opt_key_definition key_usage_list2 equal optional_braces opt_key_definition key_usage_list2
opt_mi_check_type opt_to mi_check_types normal_join opt_mi_check_type opt_to mi_check_types normal_join
table_to_table_list table_to_table opt_table_list opt_as db_to_db table_to_table_list table_to_table opt_table_list opt_as
handler_rkey_function handler_read_or_scan handler_rkey_function handler_read_or_scan
single_multi table_wild_list table_wild_one opt_wild single_multi table_wild_list table_wild_one opt_wild
union_clause union_list union_clause union_list
...@@ -5483,6 +5483,13 @@ rename: ...@@ -5483,6 +5483,13 @@ rename:
} }
table_to_table_list table_to_table_list
{} {}
| RENAME DATABASE
{
Lex->db_list.empty();
Lex->sql_command= SQLCOM_RENAME_DB;
}
db_to_db
{}
| RENAME USER clear_privileges rename_list | RENAME USER clear_privileges rename_list
{ {
Lex->sql_command = SQLCOM_RENAME_USER; Lex->sql_command = SQLCOM_RENAME_USER;
...@@ -5518,6 +5525,17 @@ table_to_table: ...@@ -5518,6 +5525,17 @@ table_to_table:
YYABORT; YYABORT;
}; };
db_to_db:
ident TO_SYM ident
{
LEX *lex=Lex;
if (Lex->db_list.push_back((LEX_STRING*)
sql_memdup(&$1, sizeof(LEX_STRING))) ||
Lex->db_list.push_back((LEX_STRING*)
sql_memdup(&$3, sizeof(LEX_STRING))))
YYABORT;
};
keycache: keycache:
CACHE_SYM INDEX_SYM keycache_list IN_SYM key_cache_name CACHE_SYM INDEX_SYM keycache_list IN_SYM key_cache_name
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment