WL#4030 (Deprecate RENAME DATABASE: replace with ALTER DATABASE <name>
UPGRADE) Bug 17565 (RENAME DATABASE destroys events) Bug#28360 (RENAME DATABASE destroys routines) Removed the RENAME DATABASE db1 TO db2 statement. Implemented the ALTER DATABASE db UPGRADE DATA DIRECTORY NAME statement, which has the same function. client/mysqlcheck.c: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME mysql-test/r/create.result: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME mysql-test/r/query_cache.result: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME mysql-test/r/renamedb.result: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME mysql-test/r/sp-code.result: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME mysql-test/r/sp-error.result: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME mysql-test/r/upgrade.result: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME mysql-test/t/create.test: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME mysql-test/t/query_cache.test: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME mysql-test/t/renamedb.test: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME mysql-test/t/sp-error.test: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME mysql-test/t/upgrade.test: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME sql/mysql_priv.h: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME sql/sql_lex.h: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME sql/sql_parse.cc: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME sql/sql_prepare.cc: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME sql/sql_yacc.yy: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME sql/sql_db.cc: ALTER DATABASE db UPGRADE DATA DIRECTORY NAME
This commit is contained in:
parent
5a437ae911
commit
8076d23f41
@ -539,13 +539,13 @@ static int process_all_tables_in_db(char *database)
|
||||
|
||||
|
||||
|
||||
static int fix_object_name(const char *obj, const char *name)
|
||||
static int fix_table_storage_name(const char *name)
|
||||
{
|
||||
char qbuf[100 + NAME_LEN*4];
|
||||
int rc= 0;
|
||||
if (strncmp(name, "#mysql50#", 9))
|
||||
return 1;
|
||||
sprintf(qbuf, "RENAME %s `%s` TO `%s`", obj, name, name + 9);
|
||||
sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9);
|
||||
if (mysql_query(sock, qbuf))
|
||||
{
|
||||
fprintf(stderr, "Failed to %s\n", qbuf);
|
||||
@ -557,6 +557,23 @@ static int fix_object_name(const char *obj, const char *name)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int fix_database_storage_name(const char *name)
|
||||
{
|
||||
char qbuf[100 + NAME_LEN*4];
|
||||
int rc= 0;
|
||||
if (strncmp(name, "#mysql50#", 9))
|
||||
return 1;
|
||||
sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name);
|
||||
if (mysql_query(sock, qbuf))
|
||||
{
|
||||
fprintf(stderr, "Failed to %s\n", qbuf);
|
||||
fprintf(stderr, "Error: %s\n", mysql_error(sock));
|
||||
rc= 1;
|
||||
}
|
||||
if (verbose)
|
||||
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int process_one_db(char *database)
|
||||
{
|
||||
@ -565,7 +582,7 @@ static int process_one_db(char *database)
|
||||
int rc= 0;
|
||||
if (opt_fix_db_names && !strncmp(database,"#mysql50#", 9))
|
||||
{
|
||||
rc= fix_object_name("DATABASE", database);
|
||||
rc= fix_database_storage_name(database);
|
||||
database+= 9;
|
||||
}
|
||||
if (rc || !opt_fix_table_names)
|
||||
@ -620,7 +637,7 @@ static int handle_request_for_tables(char *tables, uint length)
|
||||
op= (opt_write_binlog) ? "OPTIMIZE" : "OPTIMIZE NO_WRITE_TO_BINLOG";
|
||||
break;
|
||||
case DO_UPGRADE:
|
||||
return fix_object_name("TABLE", tables);
|
||||
return fix_table_storage_name(tables);
|
||||
}
|
||||
|
||||
if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME))))
|
||||
|
@ -1588,14 +1588,6 @@ CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
DROP DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
RENAME DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa TO a;
|
||||
ERROR 42000: Unknown database 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
create database mysqltest;
|
||||
RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
drop database mysqltest;
|
||||
USE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
SHOW CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
|
@ -1684,52 +1684,3 @@ set GLOBAL query_cache_limit=default;
|
||||
set GLOBAL query_cache_min_res_unit=default;
|
||||
set GLOBAL query_cache_size=default;
|
||||
End of 5.0 tests
|
||||
drop database if exists db1;
|
||||
drop database if exists db2;
|
||||
set GLOBAL query_cache_size=15*1024*1024;
|
||||
create database db1;
|
||||
use db1;
|
||||
create table t1(c1 int)engine=myisam;
|
||||
insert into t1(c1) values (1);
|
||||
select * from db1.t1 f;
|
||||
c1
|
||||
1
|
||||
show status like 'Qcache_queries_in_cache';
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
rename schema db1 to db2;
|
||||
show status like 'Qcache_queries_in_cache';
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
drop database db2;
|
||||
set global query_cache_size=default;
|
||||
drop database if exists db1;
|
||||
drop database if exists db3;
|
||||
set GLOBAL query_cache_size=15*1024*1024;
|
||||
create database db1;
|
||||
create database db3;
|
||||
use db1;
|
||||
create table t1(c1 int) engine=myisam;
|
||||
use db3;
|
||||
create table t1(c1 int) engine=myisam;
|
||||
use db1;
|
||||
insert into t1(c1) values (1);
|
||||
use mysql;
|
||||
select * from db1.t1;
|
||||
c1
|
||||
1
|
||||
select c1+1 from db1.t1;
|
||||
c1+1
|
||||
2
|
||||
select * from db3.t1;
|
||||
c1
|
||||
show status like 'Qcache_queries_in_cache';
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 3
|
||||
rename schema db1 to db2;
|
||||
show status like 'Qcache_queries_in_cache';
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
drop database db2;
|
||||
drop database db3;
|
||||
End of 5.1 tests
|
||||
|
@ -1,33 +1,12 @@
|
||||
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;
|
||||
create database testdb1;
|
||||
rename database testdb1 to testdb1;
|
||||
ERROR HY000: Can't create database 'testdb1'; database exists
|
||||
drop database testdb1;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'database testdb1 to testdb2' at line 1
|
||||
ALTER DATABASE wrong UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name
|
||||
ALTER DATABASE `#mysql41#not-supported` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name
|
||||
ALTER DATABASE `#mysql51#not-yet` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name
|
||||
ALTER DATABASE `#mysql50#` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name
|
||||
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR 42000: Unknown database '#mysql50#upgrade-me'
|
||||
|
@ -155,11 +155,11 @@ Pos Instruction
|
||||
0 stmt 9 "drop temporary table if exists sudoku..."
|
||||
1 stmt 1 "create temporary table sudoku_work ( ..."
|
||||
2 stmt 1 "create temporary table sudoku_schedul..."
|
||||
3 stmt 95 "call sudoku_init()"
|
||||
3 stmt 94 "call sudoku_init()"
|
||||
4 jump_if_not 7(8) p_naive@0
|
||||
5 stmt 4 "update sudoku_work set cnt = 0 where ..."
|
||||
6 jump 8
|
||||
7 stmt 95 "call sudoku_count()"
|
||||
7 stmt 94 "call sudoku_count()"
|
||||
8 stmt 6 "insert into sudoku_schedule (row,col)..."
|
||||
9 set v_scounter@2 0
|
||||
10 set v_i@3 1
|
||||
|
@ -1478,3 +1478,16 @@ end
|
||||
until true end repeat retry;
|
||||
end//
|
||||
ERROR 42000: LEAVE with no matching label: retry
|
||||
drop procedure if exists proc_28360;
|
||||
drop function if exists func_28360;
|
||||
CREATE PROCEDURE proc_28360()
|
||||
BEGIN
|
||||
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
|
||||
END//
|
||||
ERROR HY000: Can't drop or alter a DATABASE from within another stored routine
|
||||
CREATE FUNCTION func_28360() RETURNS int
|
||||
BEGIN
|
||||
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
|
||||
RETURN 0;
|
||||
END//
|
||||
ERROR HY000: Can't drop or alter a DATABASE from within another stored routine
|
||||
|
@ -59,3 +59,28 @@ drop table `txu@0023p@0023p1`;
|
||||
drop table `txu#p#p1`;
|
||||
truncate t1;
|
||||
drop table t1;
|
||||
drop database if exists `tabc`;
|
||||
drop database if exists `a-b-c`;
|
||||
create database `tabc` default character set latin2;
|
||||
create table tabc.t1 (a int);
|
||||
FLUSH TABLES;
|
||||
show databases like '%a-b-c%';
|
||||
Database (%a-b-c%)
|
||||
#mysql50#a-b-c
|
||||
ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;
|
||||
show databases like '%a-b-c%';
|
||||
Database (%a-b-c%)
|
||||
a-b-c
|
||||
show create database `a-b-c`;
|
||||
Database Create Database
|
||||
a-b-c CREATE DATABASE `a-b-c` /*!40100 DEFAULT CHARACTER SET latin2 */
|
||||
show tables in `a-b-c`;
|
||||
Tables_in_a-b-c
|
||||
t1
|
||||
show create table `a-b-c`.`t1`;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin2
|
||||
drop database `a-b-c`;
|
||||
drop database `tabc`;
|
||||
|
@ -1197,14 +1197,17 @@ drop table t1,t2;
|
||||
CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
--error 1102
|
||||
DROP DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
--error 1049
|
||||
RENAME DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa TO a;
|
||||
--error 1102
|
||||
RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
create database mysqltest;
|
||||
--error 1102
|
||||
RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
drop database mysqltest;
|
||||
|
||||
# TODO: enable these tests when RENAME DATABASE is implemented.
|
||||
# --error 1049
|
||||
# RENAME DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa TO a;
|
||||
# --error 1102
|
||||
# RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
# create database mysqltest;
|
||||
# --error 1102
|
||||
# RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
# drop database mysqltest;
|
||||
|
||||
--error 1102
|
||||
USE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
--error 1102
|
||||
|
@ -1293,44 +1293,42 @@ set GLOBAL query_cache_size=default;
|
||||
|
||||
#
|
||||
# Bug #28211 RENAME DATABASE and query cache don't play nicely together
|
||||
#
|
||||
--disable_warnings
|
||||
drop database if exists db1;
|
||||
drop database if exists db2;
|
||||
--enable_warnings
|
||||
set GLOBAL query_cache_size=15*1024*1024;
|
||||
create database db1;
|
||||
use db1;
|
||||
create table t1(c1 int)engine=myisam;
|
||||
insert into t1(c1) values (1);
|
||||
select * from db1.t1 f;
|
||||
show status like 'Qcache_queries_in_cache';
|
||||
rename schema db1 to db2;
|
||||
show status like 'Qcache_queries_in_cache';
|
||||
drop database db2;
|
||||
set global query_cache_size=default;
|
||||
|
||||
--disable_warnings
|
||||
drop database if exists db1;
|
||||
drop database if exists db3;
|
||||
--enable_warnings
|
||||
set GLOBAL query_cache_size=15*1024*1024;
|
||||
create database db1;
|
||||
create database db3;
|
||||
use db1;
|
||||
create table t1(c1 int) engine=myisam;
|
||||
use db3;
|
||||
create table t1(c1 int) engine=myisam;
|
||||
use db1;
|
||||
insert into t1(c1) values (1);
|
||||
use mysql;
|
||||
select * from db1.t1;
|
||||
select c1+1 from db1.t1;
|
||||
select * from db3.t1;
|
||||
show status like 'Qcache_queries_in_cache';
|
||||
rename schema db1 to db2;
|
||||
show status like 'Qcache_queries_in_cache';
|
||||
drop database db2;
|
||||
drop database db3;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
# TODO: enable these tests when RENAME DATABASE is implemented.
|
||||
# --disable_warnings
|
||||
# drop database if exists db1;
|
||||
# drop database if exists db2;
|
||||
# --enable_warnings
|
||||
# set GLOBAL query_cache_size=15*1024*1024;
|
||||
# create database db1;
|
||||
# use db1;
|
||||
# create table t1(c1 int)engine=myisam;
|
||||
# insert into t1(c1) values (1);
|
||||
# select * from db1.t1 f;
|
||||
# show status like 'Qcache_queries_in_cache';
|
||||
# rename schema db1 to db2;
|
||||
# show status like 'Qcache_queries_in_cache';
|
||||
# drop database db2;
|
||||
# set global query_cache_size=default;
|
||||
#
|
||||
# --disable_warnings
|
||||
# drop database if exists db1;
|
||||
# drop database if exists db3;
|
||||
# --enable_warnings
|
||||
# set GLOBAL query_cache_size=15*1024*1024;
|
||||
# create database db1;
|
||||
# create database db3;
|
||||
# use db1;
|
||||
# create table t1(c1 int) engine=myisam;
|
||||
# use db3;
|
||||
# create table t1(c1 int) engine=myisam;
|
||||
# use db1;
|
||||
# insert into t1(c1) values (1);
|
||||
# use mysql;
|
||||
# select * from db1.t1;
|
||||
# select c1+1 from db1.t1;
|
||||
# select * from db3.t1;
|
||||
# show status like 'Qcache_queries_in_cache';
|
||||
# rename schema db1 to db2;
|
||||
# show status like 'Qcache_queries_in_cache';
|
||||
# drop database db2;
|
||||
# drop database db3;
|
||||
|
@ -1,26 +1,53 @@
|
||||
--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;
|
||||
|
||||
# TODO: enable these tests when RENAME DATABASE is implemented.
|
||||
#
|
||||
# --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;
|
||||
#
|
||||
#
|
||||
# Bug#19392 Rename Database: Crash if case change
|
||||
#
|
||||
create database testdb1;
|
||||
--error 1007
|
||||
rename database testdb1 to testdb1;
|
||||
drop database testdb1;
|
||||
# create database testdb1;
|
||||
# --error 1007
|
||||
# rename database testdb1 to testdb1;
|
||||
# drop database testdb1;
|
||||
|
||||
#
|
||||
# WL#4030 (Deprecate RENAME DATABASE: replace with ALTER DATABASE <name> UPGRADE)
|
||||
#
|
||||
|
||||
--error ER_PARSE_ERROR
|
||||
rename database testdb1 to testdb2;
|
||||
|
||||
--error ER_WRONG_USAGE
|
||||
ALTER DATABASE wrong UPGRADE DATA DIRECTORY NAME;
|
||||
|
||||
--error ER_WRONG_USAGE
|
||||
ALTER DATABASE `#mysql41#not-supported` UPGRADE DATA DIRECTORY NAME;
|
||||
|
||||
--error ER_WRONG_USAGE
|
||||
ALTER DATABASE `#mysql51#not-yet` UPGRADE DATA DIRECTORY NAME;
|
||||
|
||||
--error ER_WRONG_USAGE
|
||||
ALTER DATABASE `#mysql50#` UPGRADE DATA DIRECTORY NAME;
|
||||
|
||||
--error ER_BAD_DB_ERROR
|
||||
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
|
||||
|
||||
|
||||
|
@ -2150,6 +2150,34 @@ end//
|
||||
|
||||
delimiter ;//
|
||||
|
||||
|
||||
#
|
||||
# Bug#28360 (RENAME DATABASE destroys routines)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop procedure if exists proc_28360;
|
||||
drop function if exists func_28360;
|
||||
--enable_warnings
|
||||
|
||||
delimiter //;
|
||||
|
||||
--error ER_SP_NO_DROP_SP
|
||||
CREATE PROCEDURE proc_28360()
|
||||
BEGIN
|
||||
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
|
||||
END//
|
||||
|
||||
--error ER_SP_NO_DROP_SP
|
||||
CREATE FUNCTION func_28360() RETURNS int
|
||||
BEGIN
|
||||
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
|
||||
RETURN 0;
|
||||
END//
|
||||
|
||||
delimiter ;//
|
||||
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
#
|
||||
|
@ -56,3 +56,34 @@ system cp $MYSQL_TEST_DIR/std_data/old_table-323.frm $MYSQLTEST_VARDIR/master-da
|
||||
truncate t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#28360 (RENAME DATABASE destroys routines)
|
||||
#
|
||||
|
||||
|
||||
--disable_warnings
|
||||
drop database if exists `tabc`;
|
||||
drop database if exists `a-b-c`;
|
||||
--enable_warnings
|
||||
|
||||
create database `tabc` default character set latin2;
|
||||
create table tabc.t1 (a int);
|
||||
FLUSH TABLES;
|
||||
|
||||
# Manually make a 5.0 database from the template
|
||||
--exec mkdir $MYSQLTEST_VARDIR/master-data/a-b-c
|
||||
--copy_file $MYSQLTEST_VARDIR/master-data/tabc/db.opt $MYSQLTEST_VARDIR/master-data/a-b-c/db.opt
|
||||
--copy_file $MYSQLTEST_VARDIR/master-data/tabc/t1.frm $MYSQLTEST_VARDIR/master-data/a-b-c/t1.frm
|
||||
--copy_file $MYSQLTEST_VARDIR/master-data/tabc/t1.MYD $MYSQLTEST_VARDIR/master-data/a-b-c/t1.MYD
|
||||
--copy_file $MYSQLTEST_VARDIR/master-data/tabc/t1.MYI $MYSQLTEST_VARDIR/master-data/a-b-c/t1.MYI
|
||||
|
||||
show databases like '%a-b-c%';
|
||||
ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;
|
||||
# The physical directory name is now a@002db@002dc, the logical name still a-b-c
|
||||
show databases like '%a-b-c%';
|
||||
show create database `a-b-c`;
|
||||
show tables in `a-b-c`;
|
||||
show create table `a-b-c`.`t1`;
|
||||
drop database `a-b-c`;
|
||||
drop database `tabc`;
|
||||
|
||||
|
@ -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,
|
||||
|
118
sql/sql_db.cc
118
sql/sql_db.cc
@ -1727,41 +1727,21 @@ lock_databases(THD *thd, const char *db1, uint length1,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Rename database.
|
||||
/**
|
||||
Upgrade a 5.0 database.
|
||||
This function is invoked whenever an ALTER DATABASE UPGRADE query is executed:
|
||||
ALTER DATABASE 'olddb' UPGRADE DATA DIRECTORY NAME.
|
||||
|
||||
SYNOPSIS
|
||||
mysql_rename_db()
|
||||
thd Thread handler
|
||||
olddb Old database name
|
||||
newdb New database 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.
|
||||
|
||||
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
|
||||
@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,46 +1906,12 @@ 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)
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user