summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/sql_db.cc122
-rw-r--r--sql/sql_lex.h3
-rw-r--r--sql/sql_parse.cc26
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_yacc.yy32
6 files changed, 68 insertions, 119 deletions
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 47a42354423..6a7e3e00f6f 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -923,7 +923,7 @@ void end_connection(THD *thd);
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_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);
+bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db);
void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags);
void mysql_client_binlog_statement(THD *thd);
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index cd7ad048802..abbf2131957 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1727,41 +1727,21 @@ lock_databases(THD *thd, const char *db1, uint length1,
}
-/*
- Rename database.
-
- SYNOPSIS
- mysql_rename_db()
- thd Thread handler
- olddb Old database name
- newdb New database name
-
- DESCRIPTION
- This function is invoked whenever a RENAME DATABASE query is executed:
-
- RENAME DATABASE 'olddb' TO 'newdb'.
-
- NOTES
-
- If we have managed to rename (move) tables to the new database
- but something failed on a later step, then we store the
- RENAME DATABASE event in the log. mysql_rename_db() is atomic in
- the sense that it will rename all or none of the tables.
-
- TODO:
- - Better trigger, stored procedure, event, grant handling,
- see the comments below.
- NOTE: It's probably a good idea to call wait_if_global_read_lock()
- once in mysql_rename_db(), instead of locking inside all
- the required functions for renaming triggerts, SP, events, grants, etc.
-
- RETURN VALUES
- 0 ok
- 1 error
+/**
+ Upgrade a 5.0 database.
+ This function is invoked whenever an ALTER DATABASE UPGRADE query is executed:
+ ALTER DATABASE 'olddb' UPGRADE DATA DIRECTORY NAME.
+
+ If we have managed to rename (move) tables to the new database
+ but something failed on a later step, then we store the
+ RENAME DATABASE event in the log. mysql_rename_db() is atomic in
+ the sense that it will rename all or none of the tables.
+
+ @param thd Current thread
+ @param old_db 5.0 database name, in #mysql50#name format
+ @return 0 on success, 1 on error
*/
-
-
-bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
+bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db)
{
int error= 0, change_to_newdb= 0;
char path[FN_REFLEN+16];
@@ -1770,11 +1750,27 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
MY_DIR *dirp;
TABLE_LIST *table_list;
SELECT_LEX *sl= thd->lex->current_select;
- DBUG_ENTER("mysql_rename_db");
+ LEX_STRING new_db;
+ DBUG_ENTER("mysql_upgrade_db");
+
+ if ((old_db->length <= MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
+ (strncmp(old_db->str,
+ MYSQL50_TABLE_NAME_PREFIX,
+ MYSQL50_TABLE_NAME_PREFIX_LENGTH) != 0))
+ {
+ my_error(ER_WRONG_USAGE, MYF(0),
+ "ALTER DATABASE UPGRADE DATA DIRECTORY NAME",
+ "name");
+ DBUG_RETURN(1);
+ }
+
+ /* `#mysql50#<name>` converted to encoded `<name>` */
+ new_db.str= old_db->str + MYSQL50_TABLE_NAME_PREFIX_LENGTH;
+ new_db.length= old_db->length - MYSQL50_TABLE_NAME_PREFIX_LENGTH;
if (lock_databases(thd, old_db->str, old_db->length,
- new_db->str, new_db->length))
- return 1;
+ new_db.str, new_db.length))
+ DBUG_RETURN(1);
/*
Let's remember if we should do "USE newdb" afterwards.
@@ -1798,7 +1794,7 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
}
/* Step1: Create the new database */
- if ((error= mysql_create_db(thd, new_db->str, &create_info, 1)))
+ if ((error= mysql_create_db(thd, new_db.str, &create_info, 1)))
goto exit;
/* Step2: Move tables to the new database */
@@ -1819,12 +1815,12 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
/* A frm file found, add the table info rename list */
*extension= '\0';
-
+
table_str.length= filename_to_tablename(file->name,
tname, sizeof(tname)-1);
table_str.str= (char*) sql_memdup(tname, table_str.length + 1);
Table_ident *old_ident= new Table_ident(thd, *old_db, table_str, 0);
- Table_ident *new_ident= new Table_ident(thd, *new_db, table_str, 0);
+ Table_ident *new_ident= new Table_ident(thd, new_db, table_str, 0);
if (!old_ident || !new_ident ||
!sl->add_table_to_list(thd, old_ident, NULL,
TL_OPTION_UPDATING, TL_IGNORE) ||
@@ -1854,9 +1850,9 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
It garantees we never loose any tables.
*/
build_table_filename(path, sizeof(path)-1,
- new_db->str,"",MY_DB_OPT_FILE, 0);
+ new_db.str,"",MY_DB_OPT_FILE, 0);
my_delete(path, MYF(MY_WME));
- length= build_table_filename(path, sizeof(path)-1, new_db->str, "", "", 0);
+ length= build_table_filename(path, sizeof(path)-1, new_db.str, "", "", 0);
if (length && path[length-1] == FN_LIBCHAR)
path[length-1]=0; // remove ending '\'
rmdir(path);
@@ -1910,47 +1906,13 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
build_table_filename(oldname, sizeof(oldname)-1,
old_db->str, "", file->name, 0);
build_table_filename(newname, sizeof(newname)-1,
- new_db->str, "", file->name, 0);
+ new_db.str, "", file->name, 0);
my_rename(oldname, newname, MYF(MY_WME));
}
- my_dirend(dirp);
+ my_dirend(dirp);
}
/*
- Step4: TODO: moving stored procedures in the 'proc' system table
- We need a new function: sp_move_db_routines(thd, olddb, newdb)
- Which will basically have the same effect with:
- UPDATE proc SET db='newdb' WHERE db='olddb'
- Note, for 5.0 to 5.1 upgrade purposes we don't really need it.
-
- The biggest problem here is that we can't have a lock on LOCK_open() while
- calling open_table() for 'proc'.
-
- Two solutions:
- - Start by opening the 'event' and 'proc' (and other) tables for write
- even before creating the 'to' database. (This will have the nice
- effect of blocking another 'rename database' while the lock is active).
- - Use the solution "Disable create of new tables during lock table"
-
- For an example of how to read through all rows, see:
- sql_help.cc::search_topics()
- */
-
- /*
- Step5: TODO: moving events in the 'event' system table
- We need a new function evex_move_db_events(thd, olddb, newdb)
- Which will have the same effect with:
- UPDATE event SET db='newdb' WHERE db='olddb'
- Note, for 5.0 to 5.1 upgrade purposes we don't really need it.
- */
-
- /*
- Step6: TODO: moving grants in the 'db', 'tables_priv', 'columns_priv'.
- Update each grant table, doing the same with:
- UPDATE system_table SET db='newdb' WHERE db='olddb'
- */
-
- /*
Step7: drop the old database.
remove_db_from_cache(olddb) and query_cache_invalidate(olddb)
are done inside mysql_rm_db(), no needs to execute them again.
@@ -1968,13 +1930,13 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
/* Step9: Let's do "use newdb" if we renamed the current database */
if (change_to_newdb)
- error|= mysql_change_db(thd, new_db, FALSE);
+ error|= mysql_change_db(thd, & new_db, FALSE);
exit:
pthread_mutex_lock(&LOCK_lock_db);
/* Remove the databases from db lock cache */
lock_db_delete(old_db->str, old_db->length);
- lock_db_delete(new_db->str, new_db->length);
+ lock_db_delete(new_db.str, new_db.length);
creating_database--;
/* Signal waiting CREATE TABLE's to continue */
pthread_cond_signal(&COND_refresh);
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index da0134a7f72..ae689be263e 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -78,7 +78,6 @@ enum enum_sql_command {
SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES,
SQLCOM_GRANT,
SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB,
- SQLCOM_RENAME_DB,
SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
@@ -117,6 +116,7 @@ enum enum_sql_command {
SQLCOM_CREATE_EVENT, SQLCOM_ALTER_EVENT, SQLCOM_DROP_EVENT,
SQLCOM_SHOW_CREATE_EVENT, SQLCOM_SHOW_EVENTS,
SQLCOM_SHOW_CREATE_TRIGGER,
+ SQLCOM_ALTER_DB_UPGRADE,
/* This should be the last !!! */
@@ -1550,7 +1550,6 @@ typedef struct st_lex : public Query_tables_list
required a local context, the parser pops the top-most context.
*/
List<Name_resolution_context> context_stack;
- List<LEX_STRING> db_list;
SQL_LIST proc_list, auxiliary_table_list, save_list;
Create_field *last_field;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index bbd6cb16d11..6002d7545ba 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3175,12 +3175,9 @@ end_with_restore_list:
res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
break;
}
- case SQLCOM_RENAME_DB:
+ case SQLCOM_ALTER_DB_UPGRADE:
{
- LEX_STRING *olddb, *newdb;
- List_iterator <LEX_STRING> db_list(lex->db_list);
- olddb= db_list++;
- newdb= db_list++;
+ LEX_STRING *db= & lex->name;
if (end_active_trans(thd))
{
res= 1;
@@ -3188,24 +3185,22 @@ end_with_restore_list:
}
#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)))
+ (!rpl_filter->db_ok(db->str) ||
+ !rpl_filter->db_ok_with_wild_table(db->str)))
{
res= 1;
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
#endif
- if (check_db_name(newdb))
+ if (check_db_name(db))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), newdb->str);
+ my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
break;
}
- 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)))
+ if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0, is_schema_db(db->str)) ||
+ check_access(thd, DROP_ACL, db->str, 0, 1, 0, is_schema_db(db->str)) ||
+ check_access(thd, CREATE_ACL, db->str, 0, 1, 0, is_schema_db(db->str)))
{
res= 1;
break;
@@ -3217,7 +3212,8 @@ end_with_restore_list:
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
- res= mysql_rename_db(thd, olddb, newdb);
+
+ res= mysql_upgrade_db(thd, db);
if (!res)
send_ok(thd);
break;
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 9337a2aa329..c576a9dba1d 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1799,7 +1799,7 @@ static bool check_prepared_statement(Prepared_statement *stmt,
case SQLCOM_UNINSTALL_PLUGIN:
case SQLCOM_CREATE_DB:
case SQLCOM_DROP_DB:
- case SQLCOM_RENAME_DB:
+ case SQLCOM_ALTER_DB_UPGRADE:
case SQLCOM_CHECKSUM:
case SQLCOM_CREATE_USER:
case SQLCOM_RENAME_USER:
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index efd8c20e6d7..864d838c183 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1260,7 +1260,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
clear_privileges flush_options flush_option
equal optional_braces
opt_mi_check_type opt_to mi_check_types normal_join
- db_to_db table_to_table_list table_to_table opt_table_list opt_as
+ table_to_table_list table_to_table opt_table_list opt_as
handler_rkey_function handler_read_or_scan
single_multi table_wild_list table_wild_one opt_wild
union_clause union_list
@@ -5400,6 +5400,17 @@ alter:
lex->copy_db_to(&lex->name.str, &lex->name.length))
MYSQL_YYABORT;
}
+ | ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM
+ {
+ LEX *lex= Lex;
+ if (lex->sphead)
+ {
+ my_error(ER_SP_NO_DROP_SP, MYF(0), "DATABASE");
+ MYSQL_YYABORT;
+ }
+ lex->sql_command= SQLCOM_ALTER_DB_UPGRADE;
+ lex->name= $3;
+ }
| ALTER PROCEDURE sp_name
{
LEX *lex= Lex;
@@ -6184,13 +6195,6 @@ rename:
}
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
{
Lex->sql_command = SQLCOM_RENAME_USER;
@@ -6228,18 +6232,6 @@ table_to_table:
}
;
-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))))
- MYSQL_YYABORT;
- }
- ;
-
keycache:
CACHE_SYM INDEX_SYM keycache_list IN_SYM key_cache_name
{