Merge bk-internal.mysql.com:/home/bk/mysql-5.1
into bodhi.(none):/opt/local/work/mysql-5.1-runtime mysql-test/include/mix1.inc: Auto merged mysql-test/r/create.result: Auto merged mysql-test/r/innodb_mysql.result: Auto merged mysql-test/r/sp.result: Auto merged mysql-test/t/sp.test: Auto merged sql/sql_lex.h: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_yacc.yy: Auto merged libmysql/libmysql.c: Manual merge.
This commit is contained in:
commit
ded7fe7fd1
@ -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))))
|
||||
|
@ -1507,7 +1507,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
|
||||
die("Failed to create temporary file for ds");
|
||||
|
||||
/* Write ds to temporary file and set file pos to beginning*/
|
||||
if (my_write(fd, ds->str, ds->length,
|
||||
if (my_write(fd, (uchar *) ds->str, ds->length,
|
||||
MYF(MY_FNABP | MY_WME)) ||
|
||||
my_seek(fd, 0, SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
|
||||
{
|
||||
@ -1986,7 +1986,7 @@ void var_set_query_get_value(struct st_command *command, VAR *var)
|
||||
const struct command_arg query_get_value_args[] = {
|
||||
"query", ARG_STRING, TRUE, &ds_query, "Query to run",
|
||||
"column name", ARG_STRING, TRUE, &ds_col, "Name of column",
|
||||
"row number", ARG_STRING, TRUE, &ds_row, "Number for row",
|
||||
"row number", ARG_STRING, TRUE, &ds_row, "Number for row"
|
||||
};
|
||||
|
||||
DBUG_ENTER("var_set_query_get_value");
|
||||
|
@ -63,3 +63,7 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd);
|
||||
int init_embedded_server(int argc, char **argv, char **groups);
|
||||
void end_embedded_server();
|
||||
#endif /*EMBEDDED_LIBRARY*/
|
||||
|
||||
C_MODE_START
|
||||
extern int mysql_init_character_set(MYSQL *mysql);
|
||||
C_MODE_END
|
||||
|
@ -685,14 +685,25 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
||||
const char *passwd, const char *db)
|
||||
{
|
||||
char buff[512],*end=buff;
|
||||
int rc;
|
||||
CHARSET_INFO *saved_cs= mysql->charset;
|
||||
|
||||
DBUG_ENTER("mysql_change_user");
|
||||
|
||||
/* Get the connection-default character set. */
|
||||
|
||||
if (mysql_init_character_set(mysql))
|
||||
{
|
||||
mysql->charset= saved_cs;
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
/* Use an empty string instead of NULL. */
|
||||
|
||||
if (!user)
|
||||
user="";
|
||||
if (!passwd)
|
||||
@ -721,6 +732,14 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
||||
/* Add database if needed */
|
||||
end= strmov(end, db ? db : "") + 1;
|
||||
|
||||
/* Add character set number. */
|
||||
|
||||
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
|
||||
{
|
||||
int2store(end, (ushort) mysql->charset->number);
|
||||
end+= 2;
|
||||
}
|
||||
|
||||
/* Write authentication package */
|
||||
simple_command(mysql,COM_CHANGE_USER, (uchar*) buff, (ulong) (end-buff), 1);
|
||||
|
||||
@ -743,6 +762,11 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
||||
mysql->passwd=my_strdup(passwd,MYF(MY_WME));
|
||||
mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mysql->charset= saved_cs;
|
||||
}
|
||||
|
||||
DBUG_RETURN(rc);
|
||||
}
|
||||
|
||||
@ -2502,7 +2526,7 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length)
|
||||
5 /* execution flags */];
|
||||
my_bool res;
|
||||
DBUG_ENTER("execute");
|
||||
DBUG_DUMP("packet", packet, length);
|
||||
DBUG_DUMP("packet", (uchar *) packet, length);
|
||||
|
||||
mysql->last_used_con= mysql;
|
||||
int4store(buff, stmt->stmt_id); /* Send stmt id to server */
|
||||
@ -4679,7 +4703,7 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
|
||||
NET *net;
|
||||
|
||||
DBUG_ENTER("cli_read_binary_rows");
|
||||
|
||||
|
||||
if (!mysql)
|
||||
{
|
||||
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate);
|
||||
|
@ -1146,4 +1146,38 @@ select @b:=f2 from t1;
|
||||
select if(@a=@b,"ok","wrong");
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#30747 Create table with identical constraint names behaves incorrectly
|
||||
#
|
||||
|
||||
if ($test_foreign_keys)
|
||||
{
|
||||
CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) engine=innodb;
|
||||
--error ER_WRONG_FK_DEF
|
||||
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
|
||||
CONSTRAINT c2 FOREIGN KEY f2 (c) REFERENCES t1 (a,b) ON UPDATE NO ACTION) engine=innodb;
|
||||
--error ER_WRONG_FK_DEF
|
||||
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
|
||||
CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a,b) ON UPDATE NO ACTION) engine=innodb;
|
||||
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
|
||||
CONSTRAINT c1 FOREIGN KEY c2 (c) REFERENCES t1 (a) ON DELETE NO ACTION,
|
||||
CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION) engine=innodb;
|
||||
ALTER TABLE t2 DROP FOREIGN KEY c2;
|
||||
DROP TABLE t2;
|
||||
--error ER_WRONG_FK_DEF
|
||||
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
|
||||
FOREIGN KEY (c) REFERENCES t1 (a,k) ON UPDATE NO ACTION) engine=innodb;
|
||||
--error ER_WRONG_FK_DEF
|
||||
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
|
||||
FOREIGN KEY f1 (c) REFERENCES t1 (a,k) ON UPDATE NO ACTION) engine=innodb;
|
||||
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
|
||||
CONSTRAINT c1 FOREIGN KEY f1 (c) REFERENCES t1 (a) ON DELETE NO ACTION,
|
||||
CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION,
|
||||
FOREIGN KEY f3 (c) REFERENCES t1 (a) ON UPDATE NO ACTION,
|
||||
FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION) engine=innodb;
|
||||
SHOW CREATE TABLE t2;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
}
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -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;
|
||||
@ -1699,4 +1691,18 @@ ERROR 42000: Identifier name 'очень_очень_очень_очень_оче
|
||||
drop view имя_вью_кодировке_утф8_длиной_больше_чем_42;
|
||||
drop table имя_таблицы_в_кодировке_утф8_длиной_больше_чем_48;
|
||||
set names default;
|
||||
drop table if exists t1,t2,t3;
|
||||
drop function if exists f1;
|
||||
create function f1() returns int
|
||||
begin
|
||||
declare res int;
|
||||
create temporary table t3 select 1 i;
|
||||
set res:= (select count(*) from t1);
|
||||
drop temporary table t3;
|
||||
return res;
|
||||
end|
|
||||
create table t1 as select 1;
|
||||
create table t2 as select f1() from t1;
|
||||
drop table t1,t2;
|
||||
drop function f1;
|
||||
End of 5.1 tests
|
||||
|
@ -255,3 +255,32 @@ CREATE TABLE t2(c1 INT) ENGINE=MERGE UNION=(t1);
|
||||
INSERT DELAYED INTO t2 VALUES(1);
|
||||
ERROR HY000: Table storage engine for 't2' doesn't have this option
|
||||
DROP TABLE t1, t2;
|
||||
DROP TABLE IF EXISTS t1,t2;
|
||||
SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
|
||||
CREATE TABLE `t1` (
|
||||
`id` int(11) PRIMARY KEY auto_increment,
|
||||
`f1` varchar(10) NOT NULL UNIQUE
|
||||
);
|
||||
INSERT DELAYED INTO t1 VALUES(0,"test1");
|
||||
SELECT * FROM t1;
|
||||
id f1
|
||||
0 test1
|
||||
SET SQL_MODE='PIPES_AS_CONCAT';
|
||||
INSERT DELAYED INTO t1 VALUES(0,'a' || 'b');
|
||||
SELECT * FROM t1;
|
||||
id f1
|
||||
0 test1
|
||||
1 ab
|
||||
SET SQL_MODE='ERROR_FOR_DIVISION_BY_ZERO,STRICT_ALL_TABLES';
|
||||
INSERT DELAYED INTO t1 VALUES(mod(1,0),"test3");
|
||||
ERROR 22012: Division by 0
|
||||
CREATE TABLE t2 (
|
||||
`id` int(11) PRIMARY KEY auto_increment,
|
||||
`f1` date
|
||||
);
|
||||
SET SQL_MODE='NO_ZERO_DATE,STRICT_ALL_TABLES,NO_ZERO_IN_DATE';
|
||||
INSERT DELAYED INTO t2 VALUES (0,'0000-00-00');
|
||||
ERROR 22007: Incorrect date value: '0000-00-00' for column 'f1' at row 1
|
||||
INSERT DELAYED INTO t2 VALUES (0,'2007-00-00');
|
||||
ERROR 22007: Incorrect date value: '2007-00-00' for column 'f1' at row 1
|
||||
DROP TABLE t1,t2;
|
||||
|
@ -1419,4 +1419,40 @@ select if(@a=@b,"ok","wrong");
|
||||
if(@a=@b,"ok","wrong")
|
||||
ok
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) engine=innodb;
|
||||
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
|
||||
CONSTRAINT c2 FOREIGN KEY f2 (c) REFERENCES t1 (a,b) ON UPDATE NO ACTION) engine=innodb;
|
||||
ERROR 42000: Incorrect foreign key definition for 'f2': Key reference and table reference don't match
|
||||
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
|
||||
CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a,b) ON UPDATE NO ACTION) engine=innodb;
|
||||
ERROR 42000: Incorrect foreign key definition for 'c2': Key reference and table reference don't match
|
||||
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
|
||||
CONSTRAINT c1 FOREIGN KEY c2 (c) REFERENCES t1 (a) ON DELETE NO ACTION,
|
||||
CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION) engine=innodb;
|
||||
ALTER TABLE t2 DROP FOREIGN KEY c2;
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
|
||||
FOREIGN KEY (c) REFERENCES t1 (a,k) ON UPDATE NO ACTION) engine=innodb;
|
||||
ERROR 42000: Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match
|
||||
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
|
||||
FOREIGN KEY f1 (c) REFERENCES t1 (a,k) ON UPDATE NO ACTION) engine=innodb;
|
||||
ERROR 42000: Incorrect foreign key definition for 'f1': Key reference and table reference don't match
|
||||
CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d),
|
||||
CONSTRAINT c1 FOREIGN KEY f1 (c) REFERENCES t1 (a) ON DELETE NO ACTION,
|
||||
CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION,
|
||||
FOREIGN KEY f3 (c) REFERENCES t1 (a) ON UPDATE NO ACTION,
|
||||
FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION) engine=innodb;
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c` int(11) NOT NULL,
|
||||
`d` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c`,`d`),
|
||||
CONSTRAINT `c1` FOREIGN KEY (`c`) REFERENCES `t1` (`a`) ON DELETE NO ACTION,
|
||||
CONSTRAINT `c2` FOREIGN KEY (`c`) REFERENCES `t1` (`a`) ON UPDATE NO ACTION,
|
||||
CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`c`) REFERENCES `t1` (`a`) ON UPDATE NO ACTION,
|
||||
CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`c`) REFERENCES `t1` (`a`) ON UPDATE NO ACTION
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests
|
||||
|
@ -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
|
||||
|
@ -4914,7 +4914,7 @@ create table t3 as select * from v1|
|
||||
show create table t3|
|
||||
Table Create Table
|
||||
t3 CREATE TABLE `t3` (
|
||||
`j` bigint(11) DEFAULT NULL
|
||||
`j` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
select * from t3|
|
||||
j
|
||||
@ -6621,3 +6621,51 @@ DROP TABLE t1;
|
||||
DROP PROCEDURE p1;
|
||||
DROP PROCEDURE p2;
|
||||
End of 5.0 tests
|
||||
|
||||
#
|
||||
# Bug#20550.
|
||||
#
|
||||
|
||||
#
|
||||
# - Prepare.
|
||||
#
|
||||
|
||||
DROP VIEW IF EXISTS v1;
|
||||
DROP VIEW IF EXISTS v2;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
DROP FUNCTION IF EXISTS f2;
|
||||
|
||||
#
|
||||
# - Create required objects.
|
||||
#
|
||||
|
||||
CREATE FUNCTION f1() RETURNS VARCHAR(65525) RETURN 'Hello';
|
||||
|
||||
CREATE FUNCTION f2() RETURNS TINYINT RETURN 1;
|
||||
|
||||
CREATE VIEW v1 AS SELECT f1();
|
||||
|
||||
CREATE VIEW v2 AS SELECT f2();
|
||||
|
||||
#
|
||||
# - Check.
|
||||
#
|
||||
|
||||
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'v1';
|
||||
DATA_TYPE
|
||||
varchar
|
||||
|
||||
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'v2';
|
||||
DATA_TYPE
|
||||
tinyint
|
||||
|
||||
#
|
||||
# - Cleanup.
|
||||
#
|
||||
|
||||
DROP FUNCTION f1;
|
||||
DROP FUNCTION f2;
|
||||
DROP VIEW v1;
|
||||
DROP VIEW v2;
|
||||
|
||||
End of 5.1 tests
|
||||
|
@ -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
|
||||
@ -1300,4 +1303,29 @@ return 0;
|
||||
drop view имя_вью_кодировке_утф8_длиной_больше_чем_42;
|
||||
drop table имя_таблицы_в_кодировке_утф8_длиной_больше_чем_48;
|
||||
set names default;
|
||||
|
||||
#
|
||||
# Bug#21136 CREATE TABLE SELECT within CREATE TABLE SELECT causes server crash
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1,t2,t3;
|
||||
drop function if exists f1;
|
||||
--enable_warnings
|
||||
|
||||
--delimiter |
|
||||
create function f1() returns int
|
||||
begin
|
||||
declare res int;
|
||||
create temporary table t3 select 1 i;
|
||||
set res:= (select count(*) from t1);
|
||||
drop temporary table t3;
|
||||
return res;
|
||||
end|
|
||||
--delimiter ;
|
||||
create table t1 as select 1;
|
||||
create table t2 as select f1() from t1;
|
||||
drop table t1,t2;
|
||||
drop function f1;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -251,4 +251,35 @@ CREATE TABLE t2(c1 INT) ENGINE=MERGE UNION=(t1);
|
||||
--error 1031
|
||||
INSERT DELAYED INTO t2 VALUES(1);
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# Bug#27358 INSERT DELAYED does not honour SQL_MODE of the client
|
||||
#
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1,t2;
|
||||
--enable_warnings
|
||||
SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
|
||||
CREATE TABLE `t1` (
|
||||
`id` int(11) PRIMARY KEY auto_increment,
|
||||
`f1` varchar(10) NOT NULL UNIQUE
|
||||
);
|
||||
INSERT DELAYED INTO t1 VALUES(0,"test1");
|
||||
sleep 1;
|
||||
SELECT * FROM t1;
|
||||
SET SQL_MODE='PIPES_AS_CONCAT';
|
||||
INSERT DELAYED INTO t1 VALUES(0,'a' || 'b');
|
||||
sleep 1;
|
||||
SELECT * FROM t1;
|
||||
SET SQL_MODE='ERROR_FOR_DIVISION_BY_ZERO,STRICT_ALL_TABLES';
|
||||
--error 1365
|
||||
INSERT DELAYED INTO t1 VALUES(mod(1,0),"test3");
|
||||
CREATE TABLE t2 (
|
||||
`id` int(11) PRIMARY KEY auto_increment,
|
||||
`f1` date
|
||||
);
|
||||
SET SQL_MODE='NO_ZERO_DATE,STRICT_ALL_TABLES,NO_ZERO_IN_DATE';
|
||||
--error ER_TRUNCATED_WRONG_VALUE
|
||||
INSERT DELAYED INTO t2 VALUES (0,'0000-00-00');
|
||||
--error ER_TRUNCATED_WRONG_VALUE
|
||||
INSERT DELAYED INTO t2 VALUES (0,'2007-00-00');
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
|
@ -8,8 +8,8 @@
|
||||
# server or run mysql-test-run --debug mysql_client_test and check
|
||||
# var/log/mysql_client_test.trace
|
||||
|
||||
--exec echo "$MYSQL_CLIENT_TEST" > $MYSQLTEST_VARDIR/log/mysql_client_test.log 2>&1
|
||||
--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test.log 2>&1
|
||||
--exec echo "$MYSQL_CLIENT_TEST" > $MYSQLTEST_VARDIR/log/mysql_client_test.out.log 2>&1
|
||||
--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test.out.log 2>&1
|
||||
|
||||
# End of 4.1 tests
|
||||
echo ok;
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -7582,3 +7582,87 @@ DROP PROCEDURE p1;
|
||||
DROP PROCEDURE p2;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
||||
###########################################################################
|
||||
|
||||
#
|
||||
# Bug#20550: Stored function: wrong RETURN type metadata when used in a VIEW.
|
||||
#
|
||||
|
||||
###########################################################################
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # Bug#20550.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Prepare.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
--disable_warnings
|
||||
DROP VIEW IF EXISTS v1;
|
||||
DROP VIEW IF EXISTS v2;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
DROP FUNCTION IF EXISTS f2;
|
||||
--enable_warnings
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Create required objects.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
CREATE FUNCTION f1() RETURNS VARCHAR(65525) RETURN 'Hello';
|
||||
|
||||
--echo
|
||||
|
||||
CREATE FUNCTION f2() RETURNS TINYINT RETURN 1;
|
||||
|
||||
--echo
|
||||
|
||||
CREATE VIEW v1 AS SELECT f1();
|
||||
|
||||
--echo
|
||||
|
||||
CREATE VIEW v2 AS SELECT f2();
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Check.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'v1';
|
||||
|
||||
--echo
|
||||
|
||||
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'v2';
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Cleanup.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
DROP FUNCTION f1;
|
||||
DROP FUNCTION f2;
|
||||
DROP VIEW v1;
|
||||
DROP VIEW v2;
|
||||
|
||||
--echo
|
||||
|
||||
###########################################################################
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -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`;
|
||||
|
||||
|
@ -1535,6 +1535,11 @@ public:
|
||||
bool fix_fields(THD *thd, Item **ref);
|
||||
void fix_length_and_dec(void);
|
||||
bool is_expensive() { return 1; }
|
||||
|
||||
inline Field *get_sp_result_field()
|
||||
{
|
||||
return sp_result_field;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -2699,7 +2699,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
|
||||
|
||||
query= thd->query;
|
||||
query_length= thd->query_length;
|
||||
if (!(res= alloc_query(thd, m_query.str, m_query.length+1)) &&
|
||||
if (!(res= alloc_query(thd, m_query.str, m_query.length)) &&
|
||||
!(res=subst_spvars(thd, this, &m_query)))
|
||||
{
|
||||
/*
|
||||
|
@ -2133,6 +2133,10 @@ class select_create: public select_insert {
|
||||
TABLE_LIST *select_tables;
|
||||
Alter_info *alter_info;
|
||||
Field **field;
|
||||
/* lock data for tmp table */
|
||||
MYSQL_LOCK *m_lock;
|
||||
/* m_lock or thd->extra_lock */
|
||||
MYSQL_LOCK **m_plock;
|
||||
public:
|
||||
select_create (TABLE_LIST *table_arg,
|
||||
HA_CREATE_INFO *create_info_par,
|
||||
@ -2143,7 +2147,8 @@ public:
|
||||
create_table(table_arg),
|
||||
create_info(create_info_par),
|
||||
select_tables(select_tables_arg),
|
||||
alter_info(alter_info_arg)
|
||||
alter_info(alter_info_arg),
|
||||
m_plock(NULL)
|
||||
{}
|
||||
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
|
||||
|
||||
|
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);
|
||||
|
@ -1639,6 +1639,8 @@ public:
|
||||
char *record;
|
||||
enum_duplicates dup;
|
||||
time_t start_time;
|
||||
ulong sql_mode;
|
||||
bool auto_increment_field_not_null;
|
||||
bool query_start_used, ignore, log_query;
|
||||
bool stmt_depends_on_first_successful_insert_id_in_prev_stmt;
|
||||
ulonglong first_successful_insert_id_in_prev_stmt;
|
||||
@ -2141,6 +2143,9 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic,
|
||||
/* Copy session variables. */
|
||||
row->auto_increment_increment= thd->variables.auto_increment_increment;
|
||||
row->auto_increment_offset= thd->variables.auto_increment_offset;
|
||||
row->sql_mode= thd->variables.sql_mode;
|
||||
row->auto_increment_field_not_null= table->auto_increment_field_not_null;
|
||||
|
||||
/* Copy the next forced auto increment value, if any. */
|
||||
if ((forced_auto_inc= thd->auto_inc_intervals_forced.get_next()))
|
||||
{
|
||||
@ -2555,10 +2560,13 @@ bool Delayed_insert::handle_inserts(void)
|
||||
thd.stmt_depends_on_first_successful_insert_id_in_prev_stmt=
|
||||
row->stmt_depends_on_first_successful_insert_id_in_prev_stmt;
|
||||
table->timestamp_field_type= row->timestamp_field_type;
|
||||
table->auto_increment_field_not_null= row->auto_increment_field_not_null;
|
||||
|
||||
/* Copy the session variables. */
|
||||
thd.variables.auto_increment_increment= row->auto_increment_increment;
|
||||
thd.variables.auto_increment_offset= row->auto_increment_offset;
|
||||
thd.variables.sql_mode= row->sql_mode;
|
||||
|
||||
/* Copy a forced insert_id, if any. */
|
||||
if (row->forced_insert_id)
|
||||
{
|
||||
@ -3419,6 +3427,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
||||
int
|
||||
select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
{
|
||||
MYSQL_LOCK *extra_lock= NULL;
|
||||
DBUG_ENTER("select_create::prepare");
|
||||
|
||||
TABLEOP_HOOKS *hook_ptr= NULL;
|
||||
@ -3488,9 +3497,21 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
|
||||
if (!(table= create_table_from_items(thd, create_info, create_table,
|
||||
alter_info, &values,
|
||||
&thd->extra_lock, hook_ptr)))
|
||||
&extra_lock, hook_ptr)))
|
||||
DBUG_RETURN(-1); // abort() deletes table
|
||||
|
||||
if (extra_lock)
|
||||
{
|
||||
DBUG_ASSERT(m_plock == NULL);
|
||||
|
||||
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
|
||||
m_plock= &m_lock;
|
||||
else
|
||||
m_plock= &thd->extra_lock;
|
||||
|
||||
*m_plock= extra_lock;
|
||||
}
|
||||
|
||||
if (table->s->fields < values.elements)
|
||||
{
|
||||
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
|
||||
@ -3629,10 +3650,11 @@ bool select_create::send_eof()
|
||||
|
||||
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
|
||||
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
|
||||
if (thd->extra_lock)
|
||||
if (m_plock)
|
||||
{
|
||||
mysql_unlock_tables(thd, thd->extra_lock);
|
||||
thd->extra_lock=0;
|
||||
mysql_unlock_tables(thd, *m_plock);
|
||||
*m_plock= NULL;
|
||||
m_plock= NULL;
|
||||
}
|
||||
}
|
||||
return tmp;
|
||||
@ -3667,10 +3689,11 @@ void select_create::abort()
|
||||
if (thd->current_stmt_binlog_row_based)
|
||||
ha_rollback_stmt(thd);
|
||||
|
||||
if (thd->extra_lock)
|
||||
if (m_plock)
|
||||
{
|
||||
mysql_unlock_tables(thd, thd->extra_lock);
|
||||
thd->extra_lock=0;
|
||||
mysql_unlock_tables(thd, *m_plock);
|
||||
*m_plock= NULL;
|
||||
m_plock= NULL;
|
||||
}
|
||||
|
||||
if (table)
|
||||
|
@ -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;
|
||||
|
159
sql/sql_parse.cc
159
sql/sql_parse.cc
@ -321,8 +321,6 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
|
||||
values of init_command_var can't be changed
|
||||
*/
|
||||
rw_rdlock(var_mutex);
|
||||
thd->query= init_command_var->value;
|
||||
thd->query_length= init_command_var->value_length;
|
||||
save_client_capabilities= thd->client_capabilities;
|
||||
thd->client_capabilities|= CLIENT_MULTI_QUERIES;
|
||||
/*
|
||||
@ -332,7 +330,9 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
|
||||
save_vio= thd->net.vio;
|
||||
thd->net.vio= 0;
|
||||
thd->net.no_send_error= 0;
|
||||
dispatch_command(COM_QUERY, thd, thd->query, thd->query_length+1);
|
||||
dispatch_command(COM_QUERY, thd,
|
||||
init_command_var->value,
|
||||
init_command_var->value_length);
|
||||
rw_unlock(var_mutex);
|
||||
thd->client_capabilities= save_client_capabilities;
|
||||
thd->net.vio= save_vio;
|
||||
@ -691,30 +691,39 @@ bool do_command(THD *thd)
|
||||
net->error= 0;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
else
|
||||
|
||||
packet= (char*) net->read_pos;
|
||||
/*
|
||||
'packet_length' contains length of data, as it was stored in packet
|
||||
header. In case of malformed header, my_net_read returns zero.
|
||||
If packet_length is not zero, my_net_read ensures that the returned
|
||||
number of bytes was actually read from network.
|
||||
There is also an extra safety measure in my_net_read:
|
||||
it sets packet[packet_length]= 0, but only for non-zero packets.
|
||||
*/
|
||||
if (packet_length == 0) /* safety */
|
||||
{
|
||||
packet=(char*) net->read_pos;
|
||||
command = (enum enum_server_command) (uchar) packet[0];
|
||||
if (command >= COM_END)
|
||||
command= COM_END; // Wrong command
|
||||
DBUG_PRINT("info",("Command on %s = %d (%s)",
|
||||
vio_description(net->vio), command,
|
||||
command_name[command].str));
|
||||
/* Initialize with COM_SLEEP packet */
|
||||
packet[0]= (uchar) COM_SLEEP;
|
||||
packet_length= 1;
|
||||
}
|
||||
/* Do not rely on my_net_read, extra safety against programming errors. */
|
||||
packet[packet_length]= '\0'; /* safety */
|
||||
|
||||
command= (enum enum_server_command) (uchar) packet[0];
|
||||
|
||||
if (command >= COM_END)
|
||||
command= COM_END; // Wrong command
|
||||
|
||||
DBUG_PRINT("info",("Command on %s = %d (%s)",
|
||||
vio_description(net->vio), command,
|
||||
command_name[command].str));
|
||||
|
||||
/* Restore read timeout value */
|
||||
my_net_set_read_timeout(net, thd->variables.net_read_timeout);
|
||||
|
||||
/*
|
||||
packet_length contains length of data, as it was stored in packet
|
||||
header. In case of malformed header, packet_length can be zero.
|
||||
If packet_length is not zero, my_net_read ensures that this number
|
||||
of bytes was actually read from network. Additionally my_net_read
|
||||
sets packet[packet_length]= 0 (thus if packet_length == 0,
|
||||
command == packet[0] == COM_SLEEP).
|
||||
In dispatch_command packet[packet_length] points beyond the end of packet.
|
||||
*/
|
||||
DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
|
||||
DBUG_ASSERT(packet_length);
|
||||
DBUG_RETURN(dispatch_command(command, thd, packet+1, (uint) (packet_length-1)));
|
||||
}
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
@ -727,9 +736,7 @@ bool do_command(THD *thd)
|
||||
thd connection handle
|
||||
command type of command to perform
|
||||
packet data for the command, packet is always null-terminated
|
||||
packet_length length of packet + 1 (to show that data is
|
||||
null-terminated) except for COM_SLEEP, where it
|
||||
can be zero.
|
||||
packet_length length of packet. Can be zero, e.g. in case of COM_SLEEP.
|
||||
RETURN VALUE
|
||||
0 ok
|
||||
1 request of thread shutdown, i. e. if command is
|
||||
@ -773,7 +780,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
LEX_STRING tmp;
|
||||
status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]);
|
||||
thd->convert_string(&tmp, system_charset_info,
|
||||
packet, packet_length-1, thd->charset());
|
||||
packet, packet_length, thd->charset());
|
||||
if (!mysql_change_db(thd, &tmp, FALSE))
|
||||
{
|
||||
general_log_print(thd, command, "%s",thd->db);
|
||||
@ -793,14 +800,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
{
|
||||
char *tbl_name;
|
||||
LEX_STRING db;
|
||||
/* Safe because there is always a trailing \0 at the end of the packet */
|
||||
uint db_len= *(uchar*) packet;
|
||||
if (db_len >= packet_length || db_len > NAME_LEN)
|
||||
if (db_len + 1 > packet_length || db_len > NAME_LEN)
|
||||
{
|
||||
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
|
||||
break;
|
||||
}
|
||||
/* Safe because there is always a trailing \0 at the end of the packet */
|
||||
uint tbl_len= *(uchar*) (packet + db_len + 1);
|
||||
if (db_len+tbl_len+2 > packet_length || tbl_len > NAME_LEN)
|
||||
if (db_len + tbl_len + 2 > packet_length || tbl_len > NAME_LEN)
|
||||
{
|
||||
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
|
||||
break;
|
||||
@ -823,7 +832,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
case COM_CHANGE_USER:
|
||||
{
|
||||
status_var_increment(thd->status_var.com_other);
|
||||
char *user= (char*) packet, *packet_end= packet+ packet_length;
|
||||
char *user= (char*) packet, *packet_end= packet + packet_length;
|
||||
/* Safe because there is always a trailing \0 at the end of the packet */
|
||||
char *passwd= strend(user)+1;
|
||||
|
||||
thd->change_user();
|
||||
@ -840,6 +850,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
|
||||
char *db= passwd;
|
||||
char *save_db;
|
||||
/*
|
||||
If there is no password supplied, the packet must contain '\0',
|
||||
in any type of handshake (4.1 or pre-4.1).
|
||||
*/
|
||||
if (passwd >= packet_end)
|
||||
{
|
||||
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
|
||||
break;
|
||||
}
|
||||
uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
|
||||
(uchar)(*passwd++) : strlen(passwd));
|
||||
uint dummy_errors, save_db_length, db_length;
|
||||
@ -848,22 +867,32 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
USER_CONN *save_user_connect;
|
||||
|
||||
db+= passwd_len + 1;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
/* Small check for incoming packet */
|
||||
if ((uint) ((uchar*) db - net->read_pos) > packet_length)
|
||||
/*
|
||||
Database name is always NUL-terminated, so in case of empty database
|
||||
the packet must contain at least the trailing '\0'.
|
||||
*/
|
||||
if (db >= packet_end)
|
||||
{
|
||||
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
db_length= strlen(db);
|
||||
|
||||
char *ptr= db + db_length + 1;
|
||||
uint cs_number= 0;
|
||||
|
||||
if (ptr < packet_end)
|
||||
{
|
||||
if (ptr + 2 > packet_end)
|
||||
{
|
||||
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
|
||||
break;
|
||||
}
|
||||
|
||||
cs_number= uint2korr(ptr);
|
||||
}
|
||||
|
||||
/* Convert database name to utf8 */
|
||||
/*
|
||||
Handle problem with old bug in client protocol where db had an extra
|
||||
\0
|
||||
*/
|
||||
db_length= (packet_end - db);
|
||||
if (db_length > 0 && db[db_length-1] == 0)
|
||||
db_length--;
|
||||
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
|
||||
system_charset_info, db, db_length,
|
||||
thd->charset(), &dummy_errors)]= 0;
|
||||
@ -907,6 +936,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
|
||||
x_free((uchar*) save_db);
|
||||
x_free((uchar*) save_security_ctx.user);
|
||||
|
||||
if (cs_number)
|
||||
{
|
||||
thd_init_client_charset(thd, cs_number);
|
||||
thd->update_charset();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -999,7 +1034,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
break;
|
||||
#else
|
||||
{
|
||||
char *fields, *packet_end= packet + packet_length - 1, *arg_end;
|
||||
char *fields, *packet_end= packet + packet_length, *arg_end;
|
||||
/* Locked closure of all tables */
|
||||
TABLE_LIST table_list;
|
||||
LEX_STRING conv_name;
|
||||
@ -1073,7 +1108,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
HA_CREATE_INFO create_info;
|
||||
|
||||
status_var_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB]);
|
||||
if (thd->make_lex_string(&db, packet, packet_length - 1, FALSE) ||
|
||||
if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
|
||||
thd->make_lex_string(&alias, db.str, db.length, FALSE) ||
|
||||
check_db_name(&db))
|
||||
{
|
||||
@ -1094,7 +1129,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
status_var_increment(thd->status_var.com_stat[SQLCOM_DROP_DB]);
|
||||
LEX_STRING db;
|
||||
|
||||
if (thd->make_lex_string(&db, packet, packet_length - 1, FALSE) ||
|
||||
if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
|
||||
check_db_name(&db))
|
||||
{
|
||||
my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
|
||||
@ -1163,7 +1198,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
break; /* purecov: inspected */
|
||||
/*
|
||||
If the client is < 4.1.3, it is going to send us no argument; then
|
||||
packet_length is 1, packet[0] is the end 0 of the packet. Note that
|
||||
packet_length is 0, packet[0] is the end 0 of the packet. Note that
|
||||
SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
|
||||
packet[0].
|
||||
*/
|
||||
@ -1521,9 +1556,8 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
||||
|
||||
bool alloc_query(THD *thd, const char *packet, uint packet_length)
|
||||
{
|
||||
packet_length--; // Remove end null
|
||||
/* Remove garbage at start and end of query */
|
||||
while (my_isspace(thd->charset(),packet[0]) && packet_length > 0)
|
||||
while (packet_length > 0 && my_isspace(thd->charset(), packet[0]))
|
||||
{
|
||||
packet++;
|
||||
packet_length--;
|
||||
@ -3173,12 +3207,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;
|
||||
@ -3186,24 +3217,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;
|
||||
@ -3215,7 +3244,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;
|
||||
@ -7242,7 +7272,12 @@ bool parse_sql(THD *thd,
|
||||
|
||||
/* Parse the query. */
|
||||
|
||||
bool err_status= MYSQLparse(thd) != 0 || thd->is_fatal_error;
|
||||
bool mysql_parse_status= MYSQLparse(thd) != 0;
|
||||
|
||||
/* Check that if MYSQLparse() failed, thd->net.report_error is set. */
|
||||
|
||||
DBUG_ASSERT(!mysql_parse_status ||
|
||||
mysql_parse_status && thd->net.report_error);
|
||||
|
||||
/* Reset Lex_input_stream. */
|
||||
|
||||
@ -7255,7 +7290,7 @@ bool parse_sql(THD *thd,
|
||||
|
||||
/* That's it. */
|
||||
|
||||
return err_status;
|
||||
return mysql_parse_status || thd->is_fatal_error;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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:
|
||||
@ -2107,7 +2107,7 @@ void mysql_sql_stmt_prepare(THD *thd)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
if (stmt->prepare(query, query_len+1))
|
||||
if (stmt->prepare(query, query_len))
|
||||
{
|
||||
/* Statement map deletes the statement on erase */
|
||||
thd->stmt_map.erase(stmt);
|
||||
@ -2270,7 +2270,7 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
|
||||
/* Query text for binary, general or slow log, if any of them is open */
|
||||
String expanded_query;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
uchar *packet_end= packet + packet_length - 1;
|
||||
uchar *packet_end= packet + packet_length;
|
||||
#endif
|
||||
Prepared_statement *stmt;
|
||||
bool error;
|
||||
@ -2585,14 +2585,14 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
|
||||
Prepared_statement *stmt;
|
||||
Item_param *param;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
char *packet_end= packet + packet_length - 1;
|
||||
char *packet_end= packet + packet_length;
|
||||
#endif
|
||||
DBUG_ENTER("mysql_stmt_get_longdata");
|
||||
|
||||
status_var_increment(thd->status_var.com_stmt_send_long_data);
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
/* Minimal size of long data packet is 6 bytes */
|
||||
if (packet_length <= MYSQL_LONG_DATA_HEADER)
|
||||
if (packet_length < MYSQL_LONG_DATA_HEADER)
|
||||
{
|
||||
my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_send_long_data");
|
||||
DBUG_VOID_RETURN;
|
||||
@ -2866,6 +2866,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
||||
error= parse_sql(thd, &lip, NULL) ||
|
||||
thd->net.report_error ||
|
||||
init_param_array(this);
|
||||
|
||||
lex->set_trg_event_type_for_tables();
|
||||
|
||||
/* Remember the current database. */
|
||||
@ -3059,7 +3060,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
||||
|
||||
if (expanded_query->length() &&
|
||||
alloc_query(thd, (char*) expanded_query->ptr(),
|
||||
expanded_query->length()+1))
|
||||
expanded_query->length()))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, 0, expanded_query->length());
|
||||
goto error;
|
||||
|
@ -9343,6 +9343,36 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
||||
}
|
||||
/* Fall through */
|
||||
case Item::FUNC_ITEM:
|
||||
if (((Item_func *) item)->functype() == Item_func::FUNC_SP)
|
||||
{
|
||||
Item_func_sp *item_func_sp= (Item_func_sp *) item;
|
||||
Field *sp_result_field= item_func_sp->get_sp_result_field();
|
||||
|
||||
if (make_copy_field)
|
||||
{
|
||||
DBUG_ASSERT(item_func_sp->result_field);
|
||||
*from_field= item_func_sp->result_field;
|
||||
}
|
||||
else
|
||||
{
|
||||
*((*copy_func)++)= item;
|
||||
}
|
||||
|
||||
Field *result_field=
|
||||
create_tmp_field_from_field(thd,
|
||||
sp_result_field,
|
||||
item_func_sp->name,
|
||||
table,
|
||||
NULL,
|
||||
convert_blob_length);
|
||||
|
||||
if (modify_item)
|
||||
item->set_result_field(result_field);
|
||||
|
||||
return result_field;
|
||||
}
|
||||
|
||||
/* Fall through */
|
||||
case Item::COND_ITEM:
|
||||
case Item::FIELD_AVG_ITEM:
|
||||
case Item::FIELD_STD_ITEM:
|
||||
|
@ -1261,7 +1261,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
|
||||
@ -3362,7 +3362,6 @@ change_ts_option:
|
||||
;
|
||||
|
||||
tablespace_option_list:
|
||||
/* empty */ {}
|
||||
tablespace_options
|
||||
;
|
||||
|
||||
@ -3384,7 +3383,6 @@ tablespace_option:
|
||||
;
|
||||
|
||||
alter_tablespace_option_list:
|
||||
/* empty */ {}
|
||||
alter_tablespace_options
|
||||
;
|
||||
|
||||
@ -3403,7 +3401,6 @@ alter_tablespace_option:
|
||||
;
|
||||
|
||||
logfile_group_option_list:
|
||||
/* empty */ {}
|
||||
logfile_group_options
|
||||
;
|
||||
|
||||
@ -3424,7 +3421,6 @@ logfile_group_option:
|
||||
;
|
||||
|
||||
alter_logfile_group_option_list:
|
||||
/* empty */ {}
|
||||
alter_logfile_group_options
|
||||
;
|
||||
|
||||
@ -3669,7 +3665,7 @@ size_number:
|
||||
create2:
|
||||
'(' create2a {}
|
||||
| opt_create_table_options
|
||||
opt_partitioning {}
|
||||
opt_partitioning
|
||||
create3 {}
|
||||
| LIKE table_ident
|
||||
{
|
||||
@ -3693,19 +3689,22 @@ create2:
|
||||
|
||||
create2a:
|
||||
field_list ')' opt_create_table_options
|
||||
opt_partitioning {}
|
||||
opt_partitioning
|
||||
create3 {}
|
||||
| opt_partitioning {}
|
||||
| opt_partitioning
|
||||
create_select ')'
|
||||
{ Select->set_braces(1);} union_opt {}
|
||||
{ Select->set_braces(1);}
|
||||
union_opt {}
|
||||
;
|
||||
|
||||
create3:
|
||||
/* empty */ {}
|
||||
| opt_duplicate opt_as create_select
|
||||
{ Select->set_braces(0);} union_clause {}
|
||||
{ Select->set_braces(0);}
|
||||
union_clause {}
|
||||
| opt_duplicate opt_as '(' create_select ')'
|
||||
{ Select->set_braces(1);} union_opt {}
|
||||
{ Select->set_braces(1);}
|
||||
union_opt {}
|
||||
;
|
||||
|
||||
/*
|
||||
@ -3787,7 +3786,7 @@ partition_entry:
|
||||
;
|
||||
|
||||
partition:
|
||||
BY part_type_def opt_no_parts {} opt_sub_part {} part_defs
|
||||
BY part_type_def opt_no_parts opt_sub_part part_defs
|
||||
;
|
||||
|
||||
part_type_def:
|
||||
@ -3988,10 +3987,11 @@ part_definition:
|
||||
part_info->use_default_partitions= FALSE;
|
||||
part_info->use_default_no_partitions= FALSE;
|
||||
}
|
||||
part_name {}
|
||||
opt_part_values {}
|
||||
opt_part_options {}
|
||||
opt_sub_partition {}
|
||||
part_name
|
||||
opt_part_values
|
||||
opt_part_options
|
||||
opt_sub_partition
|
||||
{}
|
||||
;
|
||||
|
||||
part_name:
|
||||
@ -4657,8 +4657,9 @@ key_def:
|
||||
| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
const char *key_name= $4 ? $4 : $1;
|
||||
Key *key= new Foreign_key(key_name, lex->col_list,
|
||||
const char *key_name= $1 ? $1 : $4;
|
||||
const char *fkey_name = $4 ? $4 : key_name;
|
||||
Key *key= new Foreign_key(fkey_name, lex->col_list,
|
||||
$8,
|
||||
lex->ref_list,
|
||||
lex->fk_delete_opt,
|
||||
@ -5401,6 +5402,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;
|
||||
@ -6185,13 +6197,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;
|
||||
@ -6229,18 +6234,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
|
||||
{
|
||||
|
@ -119,6 +119,8 @@ static void client_disconnect(void);
|
||||
|
||||
#define DIE_UNLESS(expr) \
|
||||
((void) ((expr) ? 0 : (die(__FILE__, __LINE__, #expr), 0)))
|
||||
#define DIE_IF(expr) \
|
||||
((void) ((expr) ? (die(__FILE__, __LINE__, #expr), 0) : 0))
|
||||
#define DIE(expr) \
|
||||
die(__FILE__, __LINE__, #expr)
|
||||
|
||||
@ -177,8 +179,8 @@ if (stmt == 0) \
|
||||
DIE_UNLESS(stmt == 0);\
|
||||
}
|
||||
|
||||
#define mytest(x) if (!x) {myerror(NULL);DIE_UNLESS(FALSE);}
|
||||
#define mytest_r(x) if (x) {myerror(NULL);DIE_UNLESS(FALSE);}
|
||||
#define mytest(x) if (!(x)) {myerror(NULL);DIE_UNLESS(FALSE);}
|
||||
#define mytest_r(x) if ((x)) {myerror(NULL);DIE_UNLESS(FALSE);}
|
||||
|
||||
|
||||
/* A workaround for Sun Forte 5.6 on Solaris x86 */
|
||||
@ -13534,7 +13536,7 @@ static void test_bug9478()
|
||||
|
||||
{
|
||||
char buff[8];
|
||||
/* Fill in the fethc packet */
|
||||
/* Fill in the fetch packet */
|
||||
int4store(buff, stmt->stmt_id);
|
||||
buff[4]= 1; /* prefetch rows */
|
||||
rc= ((*mysql->methods->advanced_command)(mysql, COM_STMT_FETCH,
|
||||
@ -16214,6 +16216,204 @@ static void test_bug28934()
|
||||
myquery(mysql_query(mysql, "drop table t1"));
|
||||
}
|
||||
|
||||
/*
|
||||
Test mysql_change_user() C API and COM_CHANGE_USER
|
||||
*/
|
||||
|
||||
static void test_change_user()
|
||||
{
|
||||
char buff[256];
|
||||
const char *user_pw= "mysqltest_pw";
|
||||
const char *user_no_pw= "mysqltest_no_pw";
|
||||
const char *pw= "password";
|
||||
const char *db= "mysqltest_user_test_database";
|
||||
int rc;
|
||||
|
||||
DBUG_ENTER("test_change_user");
|
||||
myheader("test_change_user");
|
||||
|
||||
/* Prepare environment */
|
||||
sprintf(buff, "drop database if exists %s", db);
|
||||
rc= mysql_query(mysql, buff);
|
||||
myquery(rc);
|
||||
|
||||
sprintf(buff, "create database %s", db);
|
||||
rc= mysql_query(mysql, buff);
|
||||
myquery(rc);
|
||||
|
||||
sprintf(buff,
|
||||
"grant select on %s.* to %s@'%%' identified by '%s'",
|
||||
db,
|
||||
user_pw,
|
||||
pw);
|
||||
rc= mysql_query(mysql, buff);
|
||||
myquery(rc);
|
||||
|
||||
sprintf(buff,
|
||||
"grant select on %s.* to %s@'%%'",
|
||||
db,
|
||||
user_no_pw);
|
||||
rc= mysql_query(mysql, buff);
|
||||
myquery(rc);
|
||||
|
||||
|
||||
/* Try some combinations */
|
||||
rc= mysql_change_user(mysql, NULL, NULL, NULL);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
|
||||
rc= mysql_change_user(mysql, "", NULL, NULL);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, "", "", NULL);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, "", "", "");
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, NULL, "", "");
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
|
||||
rc= mysql_change_user(mysql, NULL, NULL, "");
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, "", NULL, "");
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, NULL, "");
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, "", "");
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, "", NULL);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, NULL, NULL);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, "", db);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, NULL, db);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, pw, db);
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, pw, NULL);
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, pw, "");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, pw, db);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, pw, "");
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, pw, NULL);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, "", NULL);
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, "", "");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, "", db);
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, NULL, db);
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_change_user(mysql, "", pw, db);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, "", pw, "");
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, "", pw, NULL);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, NULL, pw, NULL);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, NULL, NULL, db);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, NULL, "", db);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
rc= mysql_change_user(mysql, "", "", db);
|
||||
DIE_UNLESS(rc);
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(mysql));
|
||||
|
||||
/* Cleanup the environment */
|
||||
|
||||
mysql_change_user(mysql, opt_user, opt_password, current_db);
|
||||
|
||||
sprintf(buff, "drop database %s", db);
|
||||
rc= mysql_query(mysql, buff);
|
||||
myquery(rc);
|
||||
|
||||
sprintf(buff, "drop user %s@'%%'", user_pw);
|
||||
rc= mysql_query(mysql, buff);
|
||||
myquery(rc);
|
||||
|
||||
sprintf(buff, "drop user %s@'%%'", user_no_pw);
|
||||
rc= mysql_query(mysql, buff);
|
||||
myquery(rc);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
Bug#27592 (stack overrun when storing datetime value using prepared statements)
|
||||
@ -16451,6 +16651,175 @@ static void test_bug29306()
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
/*
|
||||
Bug#30472: libmysql doesn't reset charset, insert_id after succ.
|
||||
mysql_change_user() call row insertions.
|
||||
*/
|
||||
|
||||
static void bug30472_retrieve_charset_info(MYSQL *con,
|
||||
char *character_set_name,
|
||||
char *character_set_client,
|
||||
char *character_set_results,
|
||||
char *collation_connection)
|
||||
{
|
||||
MYSQL_RES *rs;
|
||||
MYSQL_ROW row;
|
||||
|
||||
/* Get the cached client character set name. */
|
||||
|
||||
strcpy(character_set_name, mysql_character_set_name(con));
|
||||
|
||||
/* Retrieve server character set information. */
|
||||
|
||||
DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_client'"));
|
||||
DIE_UNLESS(rs= mysql_store_result(con));
|
||||
DIE_UNLESS(row= mysql_fetch_row(rs));
|
||||
strcpy(character_set_client, row[1]);
|
||||
mysql_free_result(rs);
|
||||
|
||||
DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'"));
|
||||
DIE_UNLESS(rs= mysql_store_result(con));
|
||||
DIE_UNLESS(row= mysql_fetch_row(rs));
|
||||
strcpy(character_set_results, row[1]);
|
||||
mysql_free_result(rs);
|
||||
|
||||
DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'collation_connection'"));
|
||||
DIE_UNLESS(rs= mysql_store_result(con));
|
||||
DIE_UNLESS(row= mysql_fetch_row(rs));
|
||||
strcpy(collation_connection, row[1]);
|
||||
mysql_free_result(rs);
|
||||
}
|
||||
|
||||
static void test_bug30472()
|
||||
{
|
||||
MYSQL con;
|
||||
|
||||
char character_set_name_1[MY_CS_NAME_SIZE];
|
||||
char character_set_client_1[MY_CS_NAME_SIZE];
|
||||
char character_set_results_1[MY_CS_NAME_SIZE];
|
||||
char collation_connnection_1[MY_CS_NAME_SIZE];
|
||||
|
||||
char character_set_name_2[MY_CS_NAME_SIZE];
|
||||
char character_set_client_2[MY_CS_NAME_SIZE];
|
||||
char character_set_results_2[MY_CS_NAME_SIZE];
|
||||
char collation_connnection_2[MY_CS_NAME_SIZE];
|
||||
|
||||
char character_set_name_3[MY_CS_NAME_SIZE];
|
||||
char character_set_client_3[MY_CS_NAME_SIZE];
|
||||
char character_set_results_3[MY_CS_NAME_SIZE];
|
||||
char collation_connnection_3[MY_CS_NAME_SIZE];
|
||||
|
||||
char character_set_name_4[MY_CS_NAME_SIZE];
|
||||
char character_set_client_4[MY_CS_NAME_SIZE];
|
||||
char character_set_results_4[MY_CS_NAME_SIZE];
|
||||
char collation_connnection_4[MY_CS_NAME_SIZE];
|
||||
|
||||
/* Create a new connection. */
|
||||
|
||||
DIE_UNLESS(mysql_init(&con));
|
||||
|
||||
DIE_UNLESS(mysql_real_connect(&con,
|
||||
opt_host,
|
||||
opt_user,
|
||||
opt_password,
|
||||
opt_db ? opt_db : "test",
|
||||
opt_port,
|
||||
opt_unix_socket,
|
||||
CLIENT_FOUND_ROWS));
|
||||
|
||||
/* Retrieve character set information. */
|
||||
|
||||
bug30472_retrieve_charset_info(&con,
|
||||
character_set_name_1,
|
||||
character_set_client_1,
|
||||
character_set_results_1,
|
||||
collation_connnection_1);
|
||||
|
||||
/* Switch client character set. */
|
||||
|
||||
DIE_IF(mysql_set_character_set(&con, "utf8"));
|
||||
|
||||
/* Retrieve character set information. */
|
||||
|
||||
bug30472_retrieve_charset_info(&con,
|
||||
character_set_name_2,
|
||||
character_set_client_2,
|
||||
character_set_results_2,
|
||||
collation_connnection_2);
|
||||
|
||||
/*
|
||||
Check that
|
||||
1) character set has been switched and
|
||||
2) new character set is different from the original one.
|
||||
*/
|
||||
|
||||
DIE_UNLESS(strcmp(character_set_name_2, "utf8") == 0);
|
||||
DIE_UNLESS(strcmp(character_set_client_2, "utf8") == 0);
|
||||
DIE_UNLESS(strcmp(character_set_results_2, "utf8") == 0);
|
||||
DIE_UNLESS(strcmp(collation_connnection_2, "utf8_general_ci") == 0);
|
||||
|
||||
DIE_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0);
|
||||
DIE_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0);
|
||||
DIE_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0);
|
||||
DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_2) != 0);
|
||||
|
||||
/* Call mysql_change_user() with the same username, password, database. */
|
||||
|
||||
DIE_IF(mysql_change_user(&con,
|
||||
opt_user,
|
||||
opt_password,
|
||||
opt_db ? opt_db : "test"));
|
||||
|
||||
/* Retrieve character set information. */
|
||||
|
||||
bug30472_retrieve_charset_info(&con,
|
||||
character_set_name_3,
|
||||
character_set_client_3,
|
||||
character_set_results_3,
|
||||
collation_connnection_3);
|
||||
|
||||
/* Check that character set information has been reset. */
|
||||
|
||||
DIE_UNLESS(strcmp(character_set_name_1, character_set_name_3) == 0);
|
||||
DIE_UNLESS(strcmp(character_set_client_1, character_set_client_3) == 0);
|
||||
DIE_UNLESS(strcmp(character_set_results_1, character_set_results_3) == 0);
|
||||
DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_3) == 0);
|
||||
|
||||
/* Change connection-default character set in the client. */
|
||||
|
||||
con.options.charset_name= my_strdup("utf8", MYF(MY_FAE));
|
||||
|
||||
/*
|
||||
Call mysql_change_user() in order to check that new connection will
|
||||
have UTF8 character set on the client and on the server.
|
||||
*/
|
||||
|
||||
DIE_IF(mysql_change_user(&con,
|
||||
opt_user,
|
||||
opt_password,
|
||||
opt_db ? opt_db : "test"));
|
||||
|
||||
/* Retrieve character set information. */
|
||||
|
||||
bug30472_retrieve_charset_info(&con,
|
||||
character_set_name_4,
|
||||
character_set_client_4,
|
||||
character_set_results_4,
|
||||
collation_connnection_4);
|
||||
|
||||
/* Check that we have UTF8 on the server and on the client. */
|
||||
|
||||
DIE_UNLESS(strcmp(character_set_name_4, "utf8") == 0);
|
||||
DIE_UNLESS(strcmp(character_set_client_4, "utf8") == 0);
|
||||
DIE_UNLESS(strcmp(character_set_results_4, "utf8") == 0);
|
||||
DIE_UNLESS(strcmp(collation_connnection_4, "utf8_general_ci") == 0);
|
||||
|
||||
/* That's it. Cleanup. */
|
||||
|
||||
mysql_close(&con);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Read and parse arguments and MySQL options from my.cnf
|
||||
*/
|
||||
@ -16744,6 +17113,8 @@ static struct my_tests_st my_tests[]= {
|
||||
{ "test_bug29687", test_bug29687 },
|
||||
{ "test_bug29692", test_bug29692 },
|
||||
{ "test_bug29306", test_bug29306 },
|
||||
{ "test_change_user", test_change_user },
|
||||
{ "test_bug30472", test_bug30472 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user