Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into bodhi.local:/opt/local/work/mysql-5.0-runtime-merge
This commit is contained in:
commit
4bfc67fc3c
@ -36,6 +36,7 @@
|
||||
/* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */
|
||||
#include "mysql_priv.h"
|
||||
#include "log_event.h"
|
||||
#include "sql_common.h"
|
||||
|
||||
#define BIN_LOG_HEADER_SIZE 4
|
||||
#define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4)
|
||||
@ -1077,7 +1078,7 @@ could be out of memory");
|
||||
const char *error_msg;
|
||||
Log_event *ev;
|
||||
|
||||
len = net_safe_read(mysql);
|
||||
len= cli_safe_read(mysql);
|
||||
if (len == packet_error)
|
||||
{
|
||||
fprintf(stderr, "Got error reading packet from server: %s\n",
|
||||
|
@ -848,7 +848,6 @@ int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
|
||||
#define stmt_command(mysql, command, arg, length, stmt) \
|
||||
(*(mysql)->methods->advanced_command)(mysql, command, NullS, \
|
||||
0, arg, length, 1, stmt)
|
||||
unsigned long net_safe_read(MYSQL* mysql);
|
||||
|
||||
#ifdef __NETWARE__
|
||||
#pragma pack(pop) /* restore alignment */
|
||||
|
@ -140,7 +140,6 @@ enum enum_server_command
|
||||
|
||||
#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */
|
||||
#define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */
|
||||
#define SERVER_STATUS_MORE_RESULTS 4 /* More results on server */
|
||||
#define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */
|
||||
#define SERVER_QUERY_NO_GOOD_INDEX_USED 16
|
||||
#define SERVER_QUERY_NO_INDEX_USED 32
|
||||
|
@ -36,7 +36,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
||||
const char *header, ulong header_length,
|
||||
const char *arg, ulong arg_length, my_bool skip_check,
|
||||
MYSQL_STMT *stmt);
|
||||
|
||||
unsigned long cli_safe_read(MYSQL *mysql);
|
||||
void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode,
|
||||
const char *sqlstate);
|
||||
void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate);
|
||||
|
@ -645,7 +645,7 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd)
|
||||
NET *net= &mysql->net;
|
||||
ulong pkt_length;
|
||||
|
||||
pkt_length= net_safe_read(mysql);
|
||||
pkt_length= cli_safe_read(mysql);
|
||||
|
||||
if (pkt_length == packet_error)
|
||||
return 1;
|
||||
@ -666,7 +666,7 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd)
|
||||
return 1;
|
||||
}
|
||||
/* Read what server thinks about out new auth message report */
|
||||
if (net_safe_read(mysql) == packet_error)
|
||||
if (cli_safe_read(mysql) == packet_error)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -1887,7 +1887,7 @@ my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
|
||||
DBUG_ENTER("cli_read_prepare_result");
|
||||
|
||||
mysql= mysql->last_used_con;
|
||||
if ((packet_length= net_safe_read(mysql)) == packet_error)
|
||||
if ((packet_length= cli_safe_read(mysql)) == packet_error)
|
||||
DBUG_RETURN(1);
|
||||
mysql->warning_count= 0;
|
||||
|
||||
@ -2505,7 +2505,8 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
|
||||
|
||||
if (stmt->param_count)
|
||||
{
|
||||
NET *net= &stmt->mysql->net;
|
||||
MYSQL *mysql= stmt->mysql;
|
||||
NET *net= &mysql->net;
|
||||
MYSQL_BIND *param, *param_end;
|
||||
char *param_data;
|
||||
ulong length;
|
||||
@ -2517,7 +2518,8 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
|
||||
set_stmt_error(stmt, CR_PARAMS_NOT_BOUND, unknown_sqlstate);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (stmt->mysql->status != MYSQL_STATUS_READY)
|
||||
if (mysql->status != MYSQL_STATUS_READY ||
|
||||
mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
|
||||
{
|
||||
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
|
||||
DBUG_RETURN(1);
|
||||
@ -4532,7 +4534,7 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row)
|
||||
|
||||
int cli_unbuffered_fetch(MYSQL *mysql, char **row)
|
||||
{
|
||||
if (packet_error == net_safe_read(mysql))
|
||||
if (packet_error == cli_safe_read(mysql))
|
||||
return 1;
|
||||
|
||||
*row= ((mysql->net.read_pos[0] == 254) ? NULL :
|
||||
@ -4641,7 +4643,7 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
|
||||
|
||||
mysql= mysql->last_used_con;
|
||||
|
||||
while ((pkt_len= net_safe_read(mysql)) != packet_error)
|
||||
while ((pkt_len= cli_safe_read(mysql)) != packet_error)
|
||||
{
|
||||
cp= net->read_pos;
|
||||
if (cp[0] != 254 || pkt_len >= 8)
|
||||
|
27
mysql-test/include/im_check_env.inc
Normal file
27
mysql-test/include/im_check_env.inc
Normal file
@ -0,0 +1,27 @@
|
||||
# This file is intended to be used in each IM-test. It contains stamements,
|
||||
# that ensure that starting conditions (environment) for the IM-test are as
|
||||
# expected.
|
||||
|
||||
# Wait for mysqld1 (guarded instance) to start.
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD1_PATH_PID 30 started
|
||||
|
||||
# Check the running instances.
|
||||
|
||||
--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
|
||||
|
||||
--connection mysql1_con
|
||||
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
||||
--connection default
|
||||
|
||||
# Let IM detect that mysqld1 is online. This delay should be longer than
|
||||
# monitoring interval.
|
||||
|
||||
--sleep 2
|
||||
|
||||
# Check that IM understands that mysqld1 is online, while mysqld2 is
|
||||
# offline.
|
||||
|
||||
SHOW INSTANCES;
|
@ -2898,12 +2898,16 @@ sub im_stop($) {
|
||||
|
||||
while (1)
|
||||
{
|
||||
# Check that IM-main died.
|
||||
|
||||
if (kill (0, $instance_manager->{'pid'}))
|
||||
{
|
||||
mtr_debug("IM-main is still alive.");
|
||||
last;
|
||||
}
|
||||
|
||||
# Check that IM-angel died.
|
||||
|
||||
if (defined $instance_manager->{'angel_pid'} &&
|
||||
kill (0, $instance_manager->{'angel_pid'}))
|
||||
{
|
||||
@ -2911,21 +2915,39 @@ sub im_stop($) {
|
||||
last;
|
||||
}
|
||||
|
||||
# Check that all guarded mysqld-instances died.
|
||||
|
||||
my $guarded_mysqlds_dead= 1;
|
||||
|
||||
foreach my $pid (@mysqld_pids)
|
||||
{
|
||||
if (kill (0, $pid))
|
||||
{
|
||||
mtr_debug("Guarded mysqld ($pid) is still alive.");
|
||||
$guarded_mysqlds_dead= 0;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
last unless $guarded_mysqlds_dead;
|
||||
|
||||
# Ok, all necessary processes are dead.
|
||||
|
||||
$clean_shutdown= 1;
|
||||
last;
|
||||
}
|
||||
|
||||
# Kill leftovers (the order is important).
|
||||
|
||||
if ($clean_shutdown)
|
||||
{
|
||||
mtr_debug("IM-shutdown was clean -- all processed died.");
|
||||
}
|
||||
else
|
||||
{
|
||||
mtr_debug("IM failed to shutdown gracefully. We have to clean the mess...");
|
||||
}
|
||||
|
||||
unless ($clean_shutdown)
|
||||
{
|
||||
|
||||
@ -2946,17 +2968,24 @@ sub im_stop($) {
|
||||
mtr_kill_processes(\@mysqld_pids);
|
||||
|
||||
# Complain in error log so that a warning will be shown.
|
||||
#
|
||||
# TODO: unless BUG#20761 is fixed, we will print the warning
|
||||
# to stdout, so that it can be seen on console and does not
|
||||
# produce pushbuild error.
|
||||
|
||||
my $errlog= "$opt_vardir/log/mysql-test-run.pl.err";
|
||||
|
||||
open (ERRLOG, ">>$errlog") ||
|
||||
mtr_error("Can not open error log ($errlog)");
|
||||
# my $errlog= "$opt_vardir/log/mysql-test-run.pl.err";
|
||||
#
|
||||
# open (ERRLOG, ">>$errlog") ||
|
||||
# mtr_error("Can not open error log ($errlog)");
|
||||
#
|
||||
# my $ts= localtime();
|
||||
# print ERRLOG
|
||||
# "Warning: [$ts] Instance Manager did not shutdown gracefully.\n";
|
||||
#
|
||||
# close ERRLOG;
|
||||
|
||||
my $ts= localtime();
|
||||
print ERRLOG
|
||||
"Warning: [$ts] Instance Manager did not shutdown gracefully.\n";
|
||||
|
||||
close ERRLOG;
|
||||
print "Warning: [$ts] Instance Manager did not shutdown gracefully.\n";
|
||||
}
|
||||
|
||||
# That's all.
|
||||
|
@ -1,4 +1,7 @@
|
||||
Success: the process has been started.
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
mysqld1 online
|
||||
|
@ -1,8 +1,7 @@
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 1.1.1.
|
||||
--------------------------------------------------------------------
|
||||
Success: the process has been started.
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
mysqld1 online
|
||||
@ -40,10 +39,6 @@ ERROR HY000: Bad instance name. Check that the instance with such a name exists
|
||||
--------------------------------------------------------------------
|
||||
-- 1.1.6.
|
||||
--------------------------------------------------------------------
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
Killing the process...
|
||||
Sleeping...
|
||||
Success: the process was restarted.
|
||||
|
@ -1,8 +1,11 @@
|
||||
server_id = 1
|
||||
server_id = 2
|
||||
Success: the process has been started.
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
SET mysqld1.server_id = 11;
|
||||
server_id =11
|
||||
server_id = 2
|
||||
|
@ -1,8 +1,11 @@
|
||||
server_id = 1
|
||||
server_id = 2
|
||||
Success: the process has been started.
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
UNSET mysqld1.server_id;
|
||||
server_id = 2
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
@ -1,4 +1,7 @@
|
||||
Success: the process has been started.
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
mysqld1 online
|
||||
|
@ -2220,7 +2220,7 @@ RETURN a+b */;;
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
|
||||
/*!50003 DROP FUNCTION IF EXISTS `bug9056_func2` */;;
|
||||
/*!50003 SET SESSION SQL_MODE=""*/;;
|
||||
/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1)
|
||||
/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) CHARSET latin1
|
||||
begin
|
||||
set f1= concat( 'hello', f1 );
|
||||
return f1;
|
||||
|
@ -485,20 +485,6 @@ execute stmt;
|
||||
pnum
|
||||
deallocate prepare stmt;
|
||||
drop table t1, t2;
|
||||
drop table if exists t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
prepare stmt from "delete t1 from t1 where (cast(a1/3 as unsigned) * 3) = a1";
|
||||
drop temporary table t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
execute stmt;
|
||||
drop temporary table t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
execute stmt;
|
||||
drop temporary table t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
execute stmt;
|
||||
drop temporary table t1;
|
||||
deallocate prepare stmt;
|
||||
create table t1 (a varchar(20));
|
||||
insert into t1 values ('foo');
|
||||
prepare stmt FROM 'SELECT char_length (a) FROM t1';
|
||||
@ -650,47 +636,6 @@ id
|
||||
3
|
||||
deallocate prepare stmt;
|
||||
drop table t1, t2;
|
||||
create table t1 (a int);
|
||||
insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
prepare stmt from "select * from t1 limit ?, ?";
|
||||
set @offset=0, @limit=1;
|
||||
execute stmt using @offset, @limit;
|
||||
a
|
||||
1
|
||||
select * from t1 limit 0, 1;
|
||||
a
|
||||
1
|
||||
set @offset=3, @limit=2;
|
||||
execute stmt using @offset, @limit;
|
||||
a
|
||||
4
|
||||
5
|
||||
select * from t1 limit 3, 2;
|
||||
a
|
||||
4
|
||||
5
|
||||
prepare stmt from "select * from t1 limit ?";
|
||||
execute stmt using @limit;
|
||||
a
|
||||
1
|
||||
2
|
||||
prepare stmt from "select * from t1 where a in (select a from t1 limit ?)";
|
||||
ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
|
||||
prepare stmt from "select * from t1 union all select * from t1 limit ?, ?";
|
||||
set @offset=9;
|
||||
set @limit=2;
|
||||
execute stmt using @offset, @limit;
|
||||
a
|
||||
10
|
||||
1
|
||||
prepare stmt from "(select * from t1 limit ?, ?) union all
|
||||
(select * from t1 limit ?, ?) order by a limit ?";
|
||||
execute stmt using @offset, @limit, @offset, @limit, @limit;
|
||||
a
|
||||
10
|
||||
10
|
||||
drop table t1;
|
||||
deallocate prepare stmt;
|
||||
create table t1 (id int);
|
||||
prepare stmt from "insert into t1 (id) select id from t1 union select id from t1";
|
||||
execute stmt;
|
||||
@ -791,15 +736,6 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
|
||||
select ? from t1;
|
||||
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 '? from t1' at line 1
|
||||
drop table t1;
|
||||
CREATE TABLE b12651_T1(a int) ENGINE=MYISAM;
|
||||
CREATE TABLE b12651_T2(b int) ENGINE=MYISAM;
|
||||
CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2;
|
||||
PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)';
|
||||
EXECUTE b12651;
|
||||
1
|
||||
DROP VIEW b12651_V1;
|
||||
DROP TABLE b12651_T1, b12651_T2;
|
||||
DEALLOCATE PREPARE b12651;
|
||||
prepare stmt from "select @@time_zone";
|
||||
execute stmt;
|
||||
@@time_zone
|
||||
@ -1016,6 +952,147 @@ select @@max_prepared_stmt_count, @@prepared_stmt_count;
|
||||
@@max_prepared_stmt_count @@prepared_stmt_count
|
||||
3 0
|
||||
set global max_prepared_stmt_count= @old_max_prepared_stmt_count;
|
||||
drop table if exists t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
prepare stmt from "delete t1 from t1 where (cast(a1/3 as unsigned) * 3) = a1";
|
||||
drop temporary table t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
execute stmt;
|
||||
drop temporary table t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
execute stmt;
|
||||
drop temporary table t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
execute stmt;
|
||||
drop temporary table t1;
|
||||
deallocate prepare stmt;
|
||||
End of 4.1 tests
|
||||
create table t1 (a varchar(20));
|
||||
insert into t1 values ('foo');
|
||||
prepare stmt FROM 'SELECT char_length (a) FROM t1';
|
||||
ERROR 42000: FUNCTION test.char_length does not exist
|
||||
drop table t1;
|
||||
create table t1 (a char(3) not null, b char(3) not null,
|
||||
c char(3) not null, primary key (a, b, c));
|
||||
create table t2 like t1;
|
||||
prepare stmt from
|
||||
"select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b)
|
||||
where t1.a=1";
|
||||
execute stmt;
|
||||
a
|
||||
execute stmt;
|
||||
a
|
||||
execute stmt;
|
||||
a
|
||||
prepare stmt from
|
||||
"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from
|
||||
(t1 left outer join t2 on t2.a=? and t1.b=t2.b)
|
||||
left outer join t2 t3 on t3.a=? where t1.a=?";
|
||||
set @a:=1, @b:=1, @c:=1;
|
||||
execute stmt using @a, @b, @c;
|
||||
a b c a b c
|
||||
execute stmt using @a, @b, @c;
|
||||
a b c a b c
|
||||
execute stmt using @a, @b, @c;
|
||||
a b c a b c
|
||||
deallocate prepare stmt;
|
||||
drop table t1,t2;
|
||||
SET @aux= "SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS A,
|
||||
INFORMATION_SCHEMA.COLUMNS B
|
||||
WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA
|
||||
AND A.TABLE_NAME = B.TABLE_NAME
|
||||
AND A.COLUMN_NAME = B.COLUMN_NAME AND
|
||||
A.TABLE_NAME = 'user'";
|
||||
prepare my_stmt from @aux;
|
||||
execute my_stmt;
|
||||
COUNT(*)
|
||||
37
|
||||
execute my_stmt;
|
||||
COUNT(*)
|
||||
37
|
||||
execute my_stmt;
|
||||
COUNT(*)
|
||||
37
|
||||
deallocate prepare my_stmt;
|
||||
drop procedure if exists p1|
|
||||
drop table if exists t1|
|
||||
create table t1 (id int)|
|
||||
insert into t1 values(1)|
|
||||
create procedure p1(a int, b int)
|
||||
begin
|
||||
declare c int;
|
||||
select max(id)+1 into c from t1;
|
||||
insert into t1 select a+b;
|
||||
insert into t1 select a-b;
|
||||
insert into t1 select a-c;
|
||||
end|
|
||||
set @a= 3, @b= 4|
|
||||
prepare stmt from "call p1(?, ?)"|
|
||||
execute stmt using @a, @b|
|
||||
execute stmt using @a, @b|
|
||||
select * from t1|
|
||||
id
|
||||
1
|
||||
7
|
||||
-1
|
||||
1
|
||||
7
|
||||
-1
|
||||
-5
|
||||
deallocate prepare stmt|
|
||||
drop procedure p1|
|
||||
drop table t1|
|
||||
create table t1 (a int);
|
||||
insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
prepare stmt from "select * from t1 limit ?, ?";
|
||||
set @offset=0, @limit=1;
|
||||
execute stmt using @offset, @limit;
|
||||
a
|
||||
1
|
||||
select * from t1 limit 0, 1;
|
||||
a
|
||||
1
|
||||
set @offset=3, @limit=2;
|
||||
execute stmt using @offset, @limit;
|
||||
a
|
||||
4
|
||||
5
|
||||
select * from t1 limit 3, 2;
|
||||
a
|
||||
4
|
||||
5
|
||||
prepare stmt from "select * from t1 limit ?";
|
||||
execute stmt using @limit;
|
||||
a
|
||||
1
|
||||
2
|
||||
prepare stmt from "select * from t1 where a in (select a from t1 limit ?)";
|
||||
ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
|
||||
prepare stmt from "select * from t1 union all select * from t1 limit ?, ?";
|
||||
set @offset=9;
|
||||
set @limit=2;
|
||||
execute stmt using @offset, @limit;
|
||||
a
|
||||
10
|
||||
1
|
||||
prepare stmt from "(select * from t1 limit ?, ?) union all
|
||||
(select * from t1 limit ?, ?) order by a limit ?";
|
||||
execute stmt using @offset, @limit, @offset, @limit, @limit;
|
||||
a
|
||||
10
|
||||
10
|
||||
drop table t1;
|
||||
deallocate prepare stmt;
|
||||
CREATE TABLE b12651_T1(a int) ENGINE=MYISAM;
|
||||
CREATE TABLE b12651_T2(b int) ENGINE=MYISAM;
|
||||
CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2;
|
||||
PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)';
|
||||
EXECUTE b12651;
|
||||
1
|
||||
DROP VIEW b12651_V1;
|
||||
DROP TABLE b12651_T1, b12651_T2;
|
||||
DEALLOCATE PREPARE b12651;
|
||||
create table t1 (id int);
|
||||
prepare ins_call from "insert into t1 (id) values (1)";
|
||||
execute ins_call;
|
||||
|
@ -420,4 +420,48 @@ SELECT * FROM t1;
|
||||
col
|
||||
test
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
---> Test for BUG#20438
|
||||
|
||||
---> Preparing environment...
|
||||
---> connection: master
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
|
||||
---> Synchronizing slave with master...
|
||||
|
||||
---> connection: master
|
||||
|
||||
---> Creating procedure...
|
||||
/*!50003 CREATE PROCEDURE p1() SET @a = 1 */;
|
||||
/*!50003 CREATE FUNCTION f1() RETURNS INT RETURN 0 */;
|
||||
|
||||
---> Checking on master...
|
||||
SHOW CREATE PROCEDURE p1;
|
||||
Procedure sql_mode Create Procedure
|
||||
p1 CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
|
||||
SET @a = 1
|
||||
SHOW CREATE FUNCTION f1;
|
||||
Function sql_mode Create Function
|
||||
f1 CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
|
||||
RETURN 0
|
||||
|
||||
---> Synchronizing slave with master...
|
||||
---> connection: master
|
||||
|
||||
---> Checking on slave...
|
||||
SHOW CREATE PROCEDURE p1;
|
||||
Procedure sql_mode Create Procedure
|
||||
p1 CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
|
||||
SET @a = 1
|
||||
SHOW CREATE FUNCTION f1;
|
||||
Function sql_mode Create Function
|
||||
f1 CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
|
||||
RETURN 0
|
||||
|
||||
---> connection: master
|
||||
|
||||
---> Cleaning up...
|
||||
DROP PROCEDURE p1;
|
||||
DROP FUNCTION f1;
|
||||
drop table t1;
|
||||
|
@ -896,3 +896,50 @@ Tables_in_test (t_)
|
||||
SHOW TRIGGERS;
|
||||
Trigger Event Table Statement Timing Created sql_mode Definer
|
||||
RESET MASTER;
|
||||
START SLAVE;
|
||||
|
||||
---> Test for BUG#20438
|
||||
|
||||
---> Preparing environment...
|
||||
---> connection: master
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
|
||||
---> Synchronizing slave with master...
|
||||
|
||||
---> connection: master
|
||||
|
||||
---> Creating objects...
|
||||
CREATE TABLE t1(c INT);
|
||||
CREATE TABLE t2(c INT);
|
||||
/*!50003 CREATE TRIGGER t1_bi BEFORE INSERT ON t1
|
||||
FOR EACH ROW
|
||||
INSERT INTO t2 VALUES(NEW.c * 10) */;
|
||||
|
||||
---> Inserting value...
|
||||
INSERT INTO t1 VALUES(1);
|
||||
|
||||
---> Checking on master...
|
||||
SELECT * FROM t1;
|
||||
c
|
||||
1
|
||||
SELECT * FROM t2;
|
||||
c
|
||||
10
|
||||
|
||||
---> Synchronizing slave with master...
|
||||
---> connection: master
|
||||
|
||||
---> Checking on slave...
|
||||
SELECT * FROM t1;
|
||||
c
|
||||
1
|
||||
SELECT * FROM t2;
|
||||
c
|
||||
10
|
||||
|
||||
---> connection: master
|
||||
|
||||
---> Cleaning up...
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
|
@ -54,3 +54,40 @@ slave-bin.000001 # Query 1 # use `test`; delete from v1 where a=2
|
||||
slave-bin.000001 # Query 1 # use `test`; ALTER ALGORITHM=UNDEFINED DEFINER=root@localhost SQL SECURITY DEFINER VIEW v1 AS select a as b from t1
|
||||
slave-bin.000001 # Query 1 # use `test`; drop view v1
|
||||
slave-bin.000001 # Query 1 # use `test`; drop table t1
|
||||
|
||||
---> Test for BUG#20438
|
||||
|
||||
---> Preparing environment...
|
||||
---> connection: master
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP VIEW IF EXISTS v1;
|
||||
|
||||
---> Synchronizing slave with master...
|
||||
|
||||
---> connection: master
|
||||
|
||||
---> Creating objects...
|
||||
CREATE TABLE t1(c INT);
|
||||
/*!50003 CREATE VIEW v1 AS SELECT * FROM t1 */;
|
||||
|
||||
---> Inserting value...
|
||||
INSERT INTO t1 VALUES(1);
|
||||
|
||||
---> Checking on master...
|
||||
SELECT * FROM t1;
|
||||
c
|
||||
1
|
||||
|
||||
---> Synchronizing slave with master...
|
||||
---> connection: master
|
||||
|
||||
---> Checking on slave...
|
||||
SELECT * FROM t1;
|
||||
c
|
||||
1
|
||||
|
||||
---> connection: master
|
||||
|
||||
---> Cleaning up...
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
|
@ -625,3 +625,7 @@ View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_cache 1 AS `1`
|
||||
DROP PROCEDURE p1;
|
||||
DROP VIEW v1;
|
||||
SHOW TABLES FROM no_such_database;
|
||||
ERROR 42000: Unknown database 'no_such_database'
|
||||
SHOW COLUMNS FROM no_such_table;
|
||||
ERROR 42S02: Table 'test.no_such_table' doesn't exist
|
||||
|
@ -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 95 "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 95 "call sudoku_count()"
|
||||
8 stmt 6 "insert into sudoku_schedule (row,col)..."
|
||||
9 set v_scounter@2 0
|
||||
10 set v_i@3 1
|
||||
@ -199,3 +199,10 @@ Pos Instruction
|
||||
44 jump 14
|
||||
45 stmt 9 "drop temporary table sudoku_work, sud..."
|
||||
drop procedure sudoku_solve;
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
CREATE PROCEDURE p1() CREATE INDEX idx ON t1 (c1);
|
||||
SHOW PROCEDURE CODE p1;
|
||||
Pos Instruction
|
||||
0 stmt 2 "CREATE INDEX idx ON t1 (c1)"
|
||||
DROP PROCEDURE p1;
|
||||
End of 5.0 tests.
|
||||
|
@ -1174,3 +1174,16 @@ drop procedure bug15091;
|
||||
drop function if exists bug16896;
|
||||
create aggregate function bug16896() returns int return 1;
|
||||
ERROR 42000: AGGREGATE is not supported for stored functions
|
||||
DROP PROCEDURE IF EXISTS bug14702;
|
||||
CREATE IF NOT EXISTS PROCEDURE bug14702()
|
||||
BEGIN
|
||||
END;
|
||||
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 'IF NOT EXISTS PROCEDURE bug14702()
|
||||
BEGIN
|
||||
END' at line 1
|
||||
CREATE PROCEDURE IF NOT EXISTS bug14702()
|
||||
BEGIN
|
||||
END;
|
||||
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 'IF NOT EXISTS bug14702()
|
||||
BEGIN
|
||||
END' at line 1
|
||||
|
@ -451,3 +451,55 @@ SELECT Host,User,Password FROM mysql.user WHERE User='user19857';
|
||||
Host User Password
|
||||
localhost user19857 *82DC221D557298F6CE9961037DB1C90604792F5C
|
||||
DROP USER user19857@localhost;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP VIEW IF EXISTS v1;
|
||||
DROP FUNCTION IF EXISTS f_suid;
|
||||
DROP PROCEDURE IF EXISTS p_suid;
|
||||
DROP FUNCTION IF EXISTS f_evil;
|
||||
DELETE FROM mysql.user WHERE user LIKE 'mysqltest\_%';
|
||||
DELETE FROM mysql.db WHERE user LIKE 'mysqltest\_%';
|
||||
DELETE FROM mysql.tables_priv WHERE user LIKE 'mysqltest\_%';
|
||||
DELETE FROM mysql.columns_priv WHERE user LIKE 'mysqltest\_%';
|
||||
FLUSH PRIVILEGES;
|
||||
CREATE TABLE t1 (i INT);
|
||||
CREATE FUNCTION f_suid(i INT) RETURNS INT SQL SECURITY DEFINER RETURN 0;
|
||||
CREATE PROCEDURE p_suid(IN i INT) SQL SECURITY DEFINER SET @c:= 0;
|
||||
CREATE USER mysqltest_u1@localhost;
|
||||
GRANT EXECUTE ON test.* TO mysqltest_u1@localhost;
|
||||
CREATE DEFINER=mysqltest_u1@localhost FUNCTION f_evil () RETURNS INT
|
||||
SQL SECURITY INVOKER
|
||||
BEGIN
|
||||
SET @a:= CURRENT_USER();
|
||||
SET @b:= (SELECT COUNT(*) FROM t1);
|
||||
RETURN @b;
|
||||
END|
|
||||
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT f_evil();
|
||||
SELECT COUNT(*) FROM t1;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
|
||||
SELECT f_evil();
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
|
||||
SELECT @a, @b;
|
||||
@a @b
|
||||
mysqltest_u1@localhost NULL
|
||||
SELECT f_suid(f_evil());
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
|
||||
SELECT @a, @b;
|
||||
@a @b
|
||||
mysqltest_u1@localhost NULL
|
||||
CALL p_suid(f_evil());
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
|
||||
SELECT @a, @b;
|
||||
@a @b
|
||||
mysqltest_u1@localhost NULL
|
||||
SELECT * FROM v1;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'v1'
|
||||
SELECT @a, @b;
|
||||
@a @b
|
||||
mysqltest_u1@localhost NULL
|
||||
DROP VIEW v1;
|
||||
DROP FUNCTION f_evil;
|
||||
DROP USER mysqltest_u1@localhost;
|
||||
DROP PROCEDURE p_suid;
|
||||
DROP FUNCTION f_suid;
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests.
|
||||
|
@ -5057,6 +5057,171 @@ concat('data was: /', var1, '/')
|
||||
data was: /1/
|
||||
drop table t3|
|
||||
drop procedure bug15217|
|
||||
DROP PROCEDURE IF EXISTS bug21013 |
|
||||
CREATE PROCEDURE bug21013(IN lim INT)
|
||||
BEGIN
|
||||
DECLARE i INT DEFAULT 0;
|
||||
WHILE (i < lim) DO
|
||||
SET @b = LOCATE(_latin1'b', @a, 1);
|
||||
SET i = i + 1;
|
||||
END WHILE;
|
||||
END |
|
||||
SET @a = _latin2"aaaaaaaaaa" |
|
||||
CALL bug21013(10) |
|
||||
DROP PROCEDURE bug21013 |
|
||||
DROP DATABASE IF EXISTS mysqltest1|
|
||||
DROP DATABASE IF EXISTS mysqltest2|
|
||||
CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8|
|
||||
CREATE DATABASE mysqltest2 DEFAULT CHARACTER SET utf8|
|
||||
use mysqltest1|
|
||||
CREATE FUNCTION bug16211_f1() RETURNS CHAR(10)
|
||||
RETURN ""|
|
||||
CREATE FUNCTION bug16211_f2() RETURNS CHAR(10) CHARSET koi8r
|
||||
RETURN ""|
|
||||
CREATE FUNCTION mysqltest2.bug16211_f3() RETURNS CHAR(10)
|
||||
RETURN ""|
|
||||
CREATE FUNCTION mysqltest2.bug16211_f4() RETURNS CHAR(10) CHARSET koi8r
|
||||
RETURN ""|
|
||||
SHOW CREATE FUNCTION bug16211_f1|
|
||||
Function sql_mode Create Function
|
||||
bug16211_f1 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f1`() RETURNS char(10) CHARSET utf8
|
||||
RETURN ""
|
||||
SHOW CREATE FUNCTION bug16211_f2|
|
||||
Function sql_mode Create Function
|
||||
bug16211_f2 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f2`() RETURNS char(10) CHARSET koi8r
|
||||
RETURN ""
|
||||
SHOW CREATE FUNCTION mysqltest2.bug16211_f3|
|
||||
Function sql_mode Create Function
|
||||
bug16211_f3 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f3`() RETURNS char(10) CHARSET utf8
|
||||
RETURN ""
|
||||
SHOW CREATE FUNCTION mysqltest2.bug16211_f4|
|
||||
Function sql_mode Create Function
|
||||
bug16211_f4 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f4`() RETURNS char(10) CHARSET koi8r
|
||||
RETURN ""
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"|
|
||||
dtd_identifier
|
||||
char(10) CHARSET utf8
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"|
|
||||
dtd_identifier
|
||||
char(10) CHARSET koi8r
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"|
|
||||
dtd_identifier
|
||||
char(10) CHARSET utf8
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"|
|
||||
dtd_identifier
|
||||
char(10) CHARSET koi8r
|
||||
SELECT CHARSET(bug16211_f1())|
|
||||
CHARSET(bug16211_f1())
|
||||
utf8
|
||||
SELECT CHARSET(bug16211_f2())|
|
||||
CHARSET(bug16211_f2())
|
||||
koi8r
|
||||
SELECT CHARSET(mysqltest2.bug16211_f3())|
|
||||
CHARSET(mysqltest2.bug16211_f3())
|
||||
utf8
|
||||
SELECT CHARSET(mysqltest2.bug16211_f4())|
|
||||
CHARSET(mysqltest2.bug16211_f4())
|
||||
koi8r
|
||||
ALTER DATABASE mysqltest1 CHARACTER SET cp1251|
|
||||
ALTER DATABASE mysqltest2 CHARACTER SET cp1251|
|
||||
SHOW CREATE FUNCTION bug16211_f1|
|
||||
Function sql_mode Create Function
|
||||
bug16211_f1 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f1`() RETURNS char(10) CHARSET utf8
|
||||
RETURN ""
|
||||
SHOW CREATE FUNCTION bug16211_f2|
|
||||
Function sql_mode Create Function
|
||||
bug16211_f2 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f2`() RETURNS char(10) CHARSET koi8r
|
||||
RETURN ""
|
||||
SHOW CREATE FUNCTION mysqltest2.bug16211_f3|
|
||||
Function sql_mode Create Function
|
||||
bug16211_f3 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f3`() RETURNS char(10) CHARSET utf8
|
||||
RETURN ""
|
||||
SHOW CREATE FUNCTION mysqltest2.bug16211_f4|
|
||||
Function sql_mode Create Function
|
||||
bug16211_f4 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f4`() RETURNS char(10) CHARSET koi8r
|
||||
RETURN ""
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"|
|
||||
dtd_identifier
|
||||
char(10) CHARSET utf8
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"|
|
||||
dtd_identifier
|
||||
char(10) CHARSET koi8r
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"|
|
||||
dtd_identifier
|
||||
char(10) CHARSET utf8
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"|
|
||||
dtd_identifier
|
||||
char(10) CHARSET koi8r
|
||||
SELECT CHARSET(bug16211_f1())|
|
||||
CHARSET(bug16211_f1())
|
||||
utf8
|
||||
SELECT CHARSET(bug16211_f2())|
|
||||
CHARSET(bug16211_f2())
|
||||
koi8r
|
||||
SELECT CHARSET(mysqltest2.bug16211_f3())|
|
||||
CHARSET(mysqltest2.bug16211_f3())
|
||||
utf8
|
||||
SELECT CHARSET(mysqltest2.bug16211_f4())|
|
||||
CHARSET(mysqltest2.bug16211_f4())
|
||||
koi8r
|
||||
use test|
|
||||
DROP DATABASE mysqltest1|
|
||||
DROP DATABASE mysqltest2|
|
||||
DROP DATABASE IF EXISTS mysqltest1|
|
||||
CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8|
|
||||
use mysqltest1|
|
||||
CREATE PROCEDURE bug16676_p1(
|
||||
IN p1 CHAR(10),
|
||||
INOUT p2 CHAR(10),
|
||||
OUT p3 CHAR(10))
|
||||
BEGIN
|
||||
SELECT CHARSET(p1), COLLATION(p1);
|
||||
SELECT CHARSET(p2), COLLATION(p2);
|
||||
SELECT CHARSET(p3), COLLATION(p3);
|
||||
END|
|
||||
CREATE PROCEDURE bug16676_p2(
|
||||
IN p1 CHAR(10) CHARSET koi8r,
|
||||
INOUT p2 CHAR(10) CHARSET cp1251,
|
||||
OUT p3 CHAR(10) CHARSET greek)
|
||||
BEGIN
|
||||
SELECT CHARSET(p1), COLLATION(p1);
|
||||
SELECT CHARSET(p2), COLLATION(p2);
|
||||
SELECT CHARSET(p3), COLLATION(p3);
|
||||
END|
|
||||
SET @v2 = 'b'|
|
||||
SET @v3 = 'c'|
|
||||
CALL bug16676_p1('a', @v2, @v3)|
|
||||
CHARSET(p1) COLLATION(p1)
|
||||
utf8 utf8_general_ci
|
||||
CHARSET(p2) COLLATION(p2)
|
||||
utf8 utf8_general_ci
|
||||
CHARSET(p3) COLLATION(p3)
|
||||
utf8 utf8_general_ci
|
||||
CALL bug16676_p2('a', @v2, @v3)|
|
||||
CHARSET(p1) COLLATION(p1)
|
||||
koi8r koi8r_general_ci
|
||||
CHARSET(p2) COLLATION(p2)
|
||||
cp1251 cp1251_general_ci
|
||||
CHARSET(p3) COLLATION(p3)
|
||||
greek greek_general_ci
|
||||
use test|
|
||||
DROP DATABASE mysqltest1|
|
||||
drop table if exists t3|
|
||||
drop database if exists mysqltest1|
|
||||
create table t3 (a int)|
|
||||
|
@ -93,6 +93,12 @@ NULL
|
||||
0R
|
||||
FR
|
||||
DROP TABLE bug19904;
|
||||
CREATE DEFINER=CURRENT_USER() FUNCTION should_not_parse
|
||||
RETURNS STRING SONAME "should_not_parse.so";
|
||||
ERROR HY000: Incorrect usage of SONAME and DEFINER
|
||||
CREATE DEFINER=someone@somewhere FUNCTION should_not_parse
|
||||
RETURNS STRING SONAME "should_not_parse.so";
|
||||
ERROR HY000: Incorrect usage of SONAME and DEFINER
|
||||
End of 5.0 tests.
|
||||
DROP FUNCTION metaphon;
|
||||
DROP FUNCTION myfunc_double;
|
||||
|
@ -7,21 +7,7 @@
|
||||
###########################################################################
|
||||
|
||||
--source include/im_check_os.inc
|
||||
|
||||
###########################################################################
|
||||
|
||||
# Wait for mysqld1 (guarded instance) to start.
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD1_PATH_PID 30 started
|
||||
|
||||
# Let IM detect that mysqld1 is online. This delay should be longer than
|
||||
# monitoring interval.
|
||||
|
||||
--sleep 3
|
||||
|
||||
# Check that start conditions are as expected.
|
||||
|
||||
SHOW INSTANCES;
|
||||
--source include/im_check_env.inc
|
||||
|
||||
###########################################################################
|
||||
|
||||
|
@ -7,33 +7,7 @@
|
||||
###########################################################################
|
||||
|
||||
--source include/im_check_os.inc
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 1.1.1. Check that Instance Manager is able:
|
||||
# - to read definitions of two mysqld-instances;
|
||||
# - to start the first instance;
|
||||
# - to understand 'nonguarded' option and keep the second instance down;
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--echo
|
||||
--echo --------------------------------------------------------------------
|
||||
--echo -- 1.1.1.
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
# Wait for mysqld1 (guarded instance) to start.
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD1_PATH_PID 30 started
|
||||
|
||||
# Let IM detect that mysqld1 is online. This delay should be longer than
|
||||
# monitoring interval.
|
||||
|
||||
--sleep 3
|
||||
|
||||
# Check that start conditions are as expected.
|
||||
|
||||
SHOW INSTANCES;
|
||||
--source include/im_check_env.inc
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
@ -54,9 +28,10 @@ START INSTANCE mysqld2;
|
||||
# FIXME: START INSTANCE should be synchronous.
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started
|
||||
|
||||
# FIXME: SHOW INSTANCES is not deterministic unless START INSTANCE is
|
||||
# synchronous. Even waiting for mysqld to start by looking at its pid file is
|
||||
# not enough, because IM may not detect that mysqld has started.
|
||||
# FIXME: Result of SHOW INSTANCES here is not deterministic unless START
|
||||
# INSTANCE is synchronous. Even waiting for mysqld to start by looking at
|
||||
# its pid file is not enough, because it is unknown when IM detects that
|
||||
# mysqld has started.
|
||||
# SHOW INSTANCES;
|
||||
|
||||
--connect (mysql_con,localhost,root,,mysql,$IM_MYSQLD2_PORT,$IM_MYSQLD2_SOCK)
|
||||
@ -86,9 +61,10 @@ STOP INSTANCE mysqld2;
|
||||
# FIXME: STOP INSTANCE should be synchronous.
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 stopped
|
||||
|
||||
# FIXME: SHOW INSTANCES is not deterministic unless START INSTANCE is
|
||||
# synchronous. Even waiting for mysqld to start by looking at its pid file is
|
||||
# not enough, because IM may not detect that mysqld has started.
|
||||
# FIXME: Result of SHOW INSTANCES here is not deterministic unless START
|
||||
# INSTANCE is synchronous. Even waiting for mysqld to start by looking at
|
||||
# its pid file is not enough, because it is unknown when IM detects that
|
||||
# mysqld has started.
|
||||
# SHOW INSTANCES;
|
||||
|
||||
###########################################################################
|
||||
@ -114,8 +90,8 @@ START INSTANCE mysqld1;
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 1.1.5. Check that Instance Manager reports correct errors for 'STOP INSTANCE'
|
||||
# command:
|
||||
# 1.1.5. Check that Instance Manager reports correct errors for
|
||||
# 'STOP INSTANCE' command:
|
||||
# - if the client tries to start unregistered instance;
|
||||
# - if the client tries to start already stopped instance;
|
||||
# - if the client submits invalid arguments;
|
||||
@ -146,12 +122,10 @@ STOP INSTANCE mysqld3;
|
||||
--echo -- 1.1.6.
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_MYSQLD1_PATH_PID restarted 30
|
||||
|
||||
# Give some time to IM to detect that mysqld was restarted. It should be longer
|
||||
# than monitoring interval.
|
||||
# Give some time to IM to detect that mysqld was restarted. It should be
|
||||
# longer than monitoring interval.
|
||||
|
||||
--sleep 3
|
||||
|
||||
@ -172,16 +146,18 @@ START INSTANCE mysqld2;
|
||||
# FIXME: START INSTANCE should be synchronous.
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started
|
||||
|
||||
# FIXME: SHOW INSTANCES is not deterministic unless START INSTANCE is
|
||||
# synchronous. Even waiting for mysqld to start by looking at its pid file is
|
||||
# not enough, because IM may not detect that mysqld has started.
|
||||
# FIXME: Result of SHOW INSTANCES here is not deterministic unless START
|
||||
# INSTANCE is synchronous. Even waiting for mysqld to start by looking at
|
||||
# its pid file is not enough, because it is unknown when IM detects that
|
||||
# mysqld has started.
|
||||
# SHOW INSTANCES;
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_MYSQLD2_PATH_PID killed 10
|
||||
|
||||
# FIXME: SHOW INSTANCES is not deterministic unless START INSTANCE is
|
||||
# synchronous. Even waiting for mysqld to start by looking at its pid file is
|
||||
# not enough, because IM may not detect that mysqld has started.
|
||||
# FIXME: Result of SHOW INSTANCES here is not deterministic unless START
|
||||
# INSTANCE is synchronous. Even waiting for mysqld to start by looking at
|
||||
# its pid file is not enough, because it is unknown when IM detects that
|
||||
# mysqld has started.
|
||||
# SHOW INSTANCES;
|
||||
|
||||
###########################################################################
|
||||
|
@ -39,32 +39,7 @@
|
||||
###########################################################################
|
||||
|
||||
--source include/im_check_os.inc
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 0. Check starting conditions.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# - check the configuration file;
|
||||
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf ;
|
||||
|
||||
# - check the running instances.
|
||||
|
||||
--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
|
||||
|
||||
--connection mysql1_con
|
||||
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
||||
--connection default
|
||||
|
||||
# - check the internal cache.
|
||||
# TODO: we should check only server_id option here.
|
||||
|
||||
# SHOW INSTANCE OPTIONS mysqld1;
|
||||
# SHOW INSTANCE OPTIONS mysqld2;
|
||||
--source include/im_check_env.inc
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
|
@ -46,32 +46,7 @@
|
||||
###########################################################################
|
||||
|
||||
--source include/im_check_os.inc
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 0. Check starting conditions.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# - check the configuration file;
|
||||
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf ;
|
||||
|
||||
# - check the running instances.
|
||||
|
||||
--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
|
||||
|
||||
--connection mysql1_con
|
||||
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
||||
--connection default
|
||||
|
||||
# - check the internal cache.
|
||||
# TODO: we should check only server_id option here.
|
||||
|
||||
# SHOW INSTANCE OPTIONS mysqld1;
|
||||
# SHOW INSTANCE OPTIONS mysqld2;
|
||||
--source include/im_check_env.inc
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
|
@ -7,36 +7,17 @@
|
||||
###########################################################################
|
||||
|
||||
--source include/im_check_os.inc
|
||||
--source include/im_check_env.inc
|
||||
|
||||
###########################################################################
|
||||
|
||||
#
|
||||
# Check starting conditions. This test case assumes that:
|
||||
# - two mysqld-instances are registered;
|
||||
# - the first instance is online;
|
||||
# - the second instance is offline;
|
||||
# Check 'SHOW INSTANCE OPTIONS' command.
|
||||
#
|
||||
|
||||
# Wait for mysqld1 (guarded instance) to start.
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD1_PATH_PID 30 started
|
||||
|
||||
# Let IM detect that mysqld1 is online. This delay should be longer than
|
||||
# monitoring interval.
|
||||
|
||||
--sleep 3
|
||||
|
||||
# Check that start conditions are as expected.
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
#
|
||||
# Check 'SHOW INSTANCE OPTIONS' command:
|
||||
# - check that options of both offline and online instances are accessible;
|
||||
# - since configuration of an mysqld-instance contains directories, we should
|
||||
# completely ignore the second column (values) in order to make the test
|
||||
# case produce the same results on different installations;
|
||||
# TODO: ignore values of only directory-specific options.
|
||||
# Since configuration of an mysqld-instance contains directories, we should
|
||||
# completely ignore the second column (values) in order to make the test
|
||||
# case produce the same results on different installations;
|
||||
# TODO: ignore values of only directory-specific options.
|
||||
#
|
||||
|
||||
--replace_column 2 VALUE
|
||||
|
@ -490,6 +490,7 @@ execute stmt;
|
||||
deallocate prepare stmt;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
#
|
||||
# Bug#19399 "Stored Procedures 'Lost Connection' when dropping/creating
|
||||
# tables"
|
||||
@ -537,86 +538,6 @@ execute stmt;
|
||||
SELECT FOUND_ROWS();
|
||||
deallocate prepare stmt;
|
||||
|
||||
#
|
||||
# Bug#8115: equality propagation and prepared statements
|
||||
#
|
||||
|
||||
create table t1 (a char(3) not null, b char(3) not null,
|
||||
c char(3) not null, primary key (a, b, c));
|
||||
create table t2 like t1;
|
||||
|
||||
# reduced query
|
||||
prepare stmt from
|
||||
"select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b)
|
||||
where t1.a=1";
|
||||
execute stmt;
|
||||
execute stmt;
|
||||
execute stmt;
|
||||
|
||||
# original query
|
||||
prepare stmt from
|
||||
"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from
|
||||
(t1 left outer join t2 on t2.a=? and t1.b=t2.b)
|
||||
left outer join t2 t3 on t3.a=? where t1.a=?";
|
||||
|
||||
set @a:=1, @b:=1, @c:=1;
|
||||
|
||||
execute stmt using @a, @b, @c;
|
||||
execute stmt using @a, @b, @c;
|
||||
execute stmt using @a, @b, @c;
|
||||
|
||||
deallocate prepare stmt;
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
|
||||
#
|
||||
# Bug#9383: INFORMATION_SCHEMA.COLUMNS, JOIN, Crash, prepared statement
|
||||
#
|
||||
|
||||
eval SET @aux= "SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS A,
|
||||
INFORMATION_SCHEMA.COLUMNS B
|
||||
WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA
|
||||
AND A.TABLE_NAME = B.TABLE_NAME
|
||||
AND A.COLUMN_NAME = B.COLUMN_NAME AND
|
||||
A.TABLE_NAME = 'user'";
|
||||
|
||||
let $exec_loop_count= 3;
|
||||
eval prepare my_stmt from @aux;
|
||||
while ($exec_loop_count)
|
||||
{
|
||||
eval execute my_stmt;
|
||||
dec $exec_loop_count;
|
||||
}
|
||||
deallocate prepare my_stmt;
|
||||
|
||||
# Test CALL in prepared mode
|
||||
delimiter |;
|
||||
--disable_warnings
|
||||
drop procedure if exists p1|
|
||||
drop table if exists t1|
|
||||
--enable_warnings
|
||||
create table t1 (id int)|
|
||||
insert into t1 values(1)|
|
||||
create procedure p1(a int, b int)
|
||||
begin
|
||||
declare c int;
|
||||
select max(id)+1 into c from t1;
|
||||
insert into t1 select a+b;
|
||||
insert into t1 select a-b;
|
||||
insert into t1 select a-c;
|
||||
end|
|
||||
set @a= 3, @b= 4|
|
||||
prepare stmt from "call p1(?, ?)"|
|
||||
execute stmt using @a, @b|
|
||||
execute stmt using @a, @b|
|
||||
select * from t1|
|
||||
deallocate prepare stmt|
|
||||
drop procedure p1|
|
||||
drop table t1|
|
||||
delimiter ;|
|
||||
|
||||
#
|
||||
# Bug#9096 "select doesn't return all matched records if prepared statements
|
||||
# is used"
|
||||
@ -691,35 +612,6 @@ select t2.id from t2, t1 where (t1.id=1 and t2.t1_id=t1.id);
|
||||
deallocate prepare stmt;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# Bug#7306 LIMIT ?, ? and also WL#1785 " Prepared statements: implement
|
||||
# support for placeholders in LIMIT clause."
|
||||
# Add basic test coverage for the feature.
|
||||
#
|
||||
create table t1 (a int);
|
||||
insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
prepare stmt from "select * from t1 limit ?, ?";
|
||||
set @offset=0, @limit=1;
|
||||
execute stmt using @offset, @limit;
|
||||
select * from t1 limit 0, 1;
|
||||
set @offset=3, @limit=2;
|
||||
execute stmt using @offset, @limit;
|
||||
select * from t1 limit 3, 2;
|
||||
prepare stmt from "select * from t1 limit ?";
|
||||
execute stmt using @limit;
|
||||
--error 1235
|
||||
prepare stmt from "select * from t1 where a in (select a from t1 limit ?)";
|
||||
prepare stmt from "select * from t1 union all select * from t1 limit ?, ?";
|
||||
set @offset=9;
|
||||
set @limit=2;
|
||||
execute stmt using @offset, @limit;
|
||||
prepare stmt from "(select * from t1 limit ?, ?) union all
|
||||
(select * from t1 limit ?, ?) order by a limit ?";
|
||||
execute stmt using @offset, @limit, @offset, @limit, @limit;
|
||||
|
||||
drop table t1;
|
||||
deallocate prepare stmt;
|
||||
|
||||
#
|
||||
# Bug#11060 "Server crashes on calling stored procedure with INSERT SELECT
|
||||
# UNION SELECT" aka "Server crashes on re-execution of prepared INSERT ...
|
||||
@ -837,22 +729,6 @@ select ??;
|
||||
select ? from t1;
|
||||
--enable_ps_protocol
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#12651
|
||||
# (Crash on a PS including a subquery which is a select from a simple view)
|
||||
#
|
||||
CREATE TABLE b12651_T1(a int) ENGINE=MYISAM;
|
||||
CREATE TABLE b12651_T2(b int) ENGINE=MYISAM;
|
||||
CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2;
|
||||
|
||||
PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)';
|
||||
EXECUTE b12651;
|
||||
|
||||
DROP VIEW b12651_V1;
|
||||
DROP TABLE b12651_T1, b12651_T2;
|
||||
DEALLOCATE PREPARE b12651;
|
||||
|
||||
#
|
||||
# Bug#9359 "Prepared statements take snapshot of system vars at PREPARE
|
||||
# time"
|
||||
@ -1087,7 +963,172 @@ select @@max_prepared_stmt_count, @@prepared_stmt_count;
|
||||
set global max_prepared_stmt_count= @old_max_prepared_stmt_count;
|
||||
--enable_ps_protocol
|
||||
|
||||
# End of 4.1 tests
|
||||
#
|
||||
# Bug#19399 "Stored Procedures 'Lost Connection' when dropping/creating
|
||||
# tables"
|
||||
# Check that multi-delete tables are also cleaned up before re-execution.
|
||||
#
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
--enable_warnings
|
||||
# exact delete syntax is essential
|
||||
prepare stmt from "delete t1 from t1 where (cast(a1/3 as unsigned) * 3) = a1";
|
||||
drop temporary table t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
# the server crashed on the next statement without the fix
|
||||
execute stmt;
|
||||
drop temporary table t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
# the problem was in memory corruption: repeat the test just in case
|
||||
execute stmt;
|
||||
drop temporary table t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
execute stmt;
|
||||
drop temporary table t1;
|
||||
deallocate prepare stmt;
|
||||
|
||||
--echo End of 4.1 tests
|
||||
############################# 5.0 tests start ################################
|
||||
#
|
||||
#
|
||||
# Bug#6102 "Server crash with prepared statement and blank after
|
||||
# function name"
|
||||
# ensure that stored functions are cached when preparing a statement
|
||||
# before we open tables
|
||||
#
|
||||
create table t1 (a varchar(20));
|
||||
insert into t1 values ('foo');
|
||||
--error 1305
|
||||
prepare stmt FROM 'SELECT char_length (a) FROM t1';
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#8115: equality propagation and prepared statements
|
||||
#
|
||||
|
||||
create table t1 (a char(3) not null, b char(3) not null,
|
||||
c char(3) not null, primary key (a, b, c));
|
||||
create table t2 like t1;
|
||||
|
||||
# reduced query
|
||||
prepare stmt from
|
||||
"select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b)
|
||||
where t1.a=1";
|
||||
execute stmt;
|
||||
execute stmt;
|
||||
execute stmt;
|
||||
|
||||
# original query
|
||||
prepare stmt from
|
||||
"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from
|
||||
(t1 left outer join t2 on t2.a=? and t1.b=t2.b)
|
||||
left outer join t2 t3 on t3.a=? where t1.a=?";
|
||||
|
||||
set @a:=1, @b:=1, @c:=1;
|
||||
|
||||
execute stmt using @a, @b, @c;
|
||||
execute stmt using @a, @b, @c;
|
||||
execute stmt using @a, @b, @c;
|
||||
|
||||
deallocate prepare stmt;
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
|
||||
#
|
||||
# Bug#9383: INFORMATION_SCHEMA.COLUMNS, JOIN, Crash, prepared statement
|
||||
#
|
||||
|
||||
eval SET @aux= "SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS A,
|
||||
INFORMATION_SCHEMA.COLUMNS B
|
||||
WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA
|
||||
AND A.TABLE_NAME = B.TABLE_NAME
|
||||
AND A.COLUMN_NAME = B.COLUMN_NAME AND
|
||||
A.TABLE_NAME = 'user'";
|
||||
|
||||
let $exec_loop_count= 3;
|
||||
eval prepare my_stmt from @aux;
|
||||
while ($exec_loop_count)
|
||||
{
|
||||
eval execute my_stmt;
|
||||
dec $exec_loop_count;
|
||||
}
|
||||
deallocate prepare my_stmt;
|
||||
|
||||
# Test CALL in prepared mode
|
||||
delimiter |;
|
||||
--disable_warnings
|
||||
drop procedure if exists p1|
|
||||
drop table if exists t1|
|
||||
--enable_warnings
|
||||
create table t1 (id int)|
|
||||
insert into t1 values(1)|
|
||||
create procedure p1(a int, b int)
|
||||
begin
|
||||
declare c int;
|
||||
select max(id)+1 into c from t1;
|
||||
insert into t1 select a+b;
|
||||
insert into t1 select a-b;
|
||||
insert into t1 select a-c;
|
||||
end|
|
||||
set @a= 3, @b= 4|
|
||||
prepare stmt from "call p1(?, ?)"|
|
||||
execute stmt using @a, @b|
|
||||
execute stmt using @a, @b|
|
||||
select * from t1|
|
||||
deallocate prepare stmt|
|
||||
drop procedure p1|
|
||||
drop table t1|
|
||||
delimiter ;|
|
||||
|
||||
|
||||
#
|
||||
# Bug#7306 LIMIT ?, ? and also WL#1785 " Prepared statements: implement
|
||||
# support for placeholders in LIMIT clause."
|
||||
# Add basic test coverage for the feature.
|
||||
#
|
||||
create table t1 (a int);
|
||||
insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
prepare stmt from "select * from t1 limit ?, ?";
|
||||
set @offset=0, @limit=1;
|
||||
execute stmt using @offset, @limit;
|
||||
select * from t1 limit 0, 1;
|
||||
set @offset=3, @limit=2;
|
||||
execute stmt using @offset, @limit;
|
||||
select * from t1 limit 3, 2;
|
||||
prepare stmt from "select * from t1 limit ?";
|
||||
execute stmt using @limit;
|
||||
--error 1235
|
||||
prepare stmt from "select * from t1 where a in (select a from t1 limit ?)";
|
||||
prepare stmt from "select * from t1 union all select * from t1 limit ?, ?";
|
||||
set @offset=9;
|
||||
set @limit=2;
|
||||
execute stmt using @offset, @limit;
|
||||
prepare stmt from "(select * from t1 limit ?, ?) union all
|
||||
(select * from t1 limit ?, ?) order by a limit ?";
|
||||
execute stmt using @offset, @limit, @offset, @limit, @limit;
|
||||
|
||||
drop table t1;
|
||||
deallocate prepare stmt;
|
||||
|
||||
#
|
||||
# Bug#12651
|
||||
# (Crash on a PS including a subquery which is a select from a simple view)
|
||||
#
|
||||
CREATE TABLE b12651_T1(a int) ENGINE=MYISAM;
|
||||
CREATE TABLE b12651_T2(b int) ENGINE=MYISAM;
|
||||
CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2;
|
||||
|
||||
PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)';
|
||||
EXECUTE b12651;
|
||||
|
||||
DROP VIEW b12651_V1;
|
||||
DROP TABLE b12651_T1, b12651_T2;
|
||||
DEALLOCATE PREPARE b12651;
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Bug #14956: ROW_COUNT() returns incorrect result after EXECUTE of prepared
|
||||
|
@ -435,6 +435,86 @@ connection master;
|
||||
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
|
||||
#
|
||||
# BUG#20438: CREATE statements for views, stored routines and triggers can be
|
||||
# not replicable.
|
||||
#
|
||||
|
||||
--echo
|
||||
--echo ---> Test for BUG#20438
|
||||
|
||||
# Prepare environment.
|
||||
|
||||
--echo
|
||||
--echo ---> Preparing environment...
|
||||
--echo ---> connection: master
|
||||
--connection master
|
||||
|
||||
--disable_warnings
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
--enable_warnings
|
||||
|
||||
--echo
|
||||
--echo ---> Synchronizing slave with master...
|
||||
|
||||
--save_master_pos
|
||||
--connection slave
|
||||
--sync_with_master
|
||||
|
||||
--echo
|
||||
--echo ---> connection: master
|
||||
--connection master
|
||||
|
||||
# Test.
|
||||
|
||||
--echo
|
||||
--echo ---> Creating procedure...
|
||||
|
||||
/*!50003 CREATE PROCEDURE p1() SET @a = 1 */;
|
||||
|
||||
/*!50003 CREATE FUNCTION f1() RETURNS INT RETURN 0 */;
|
||||
|
||||
--echo
|
||||
--echo ---> Checking on master...
|
||||
|
||||
SHOW CREATE PROCEDURE p1;
|
||||
SHOW CREATE FUNCTION f1;
|
||||
|
||||
--echo
|
||||
--echo ---> Synchronizing slave with master...
|
||||
|
||||
--save_master_pos
|
||||
--connection slave
|
||||
--sync_with_master
|
||||
|
||||
--echo ---> connection: master
|
||||
|
||||
--echo
|
||||
--echo ---> Checking on slave...
|
||||
|
||||
SHOW CREATE PROCEDURE p1;
|
||||
SHOW CREATE FUNCTION f1;
|
||||
|
||||
# Cleanup.
|
||||
|
||||
--echo
|
||||
--echo ---> connection: master
|
||||
--connection master
|
||||
|
||||
--echo
|
||||
--echo ---> Cleaning up...
|
||||
|
||||
DROP PROCEDURE p1;
|
||||
DROP FUNCTION f1;
|
||||
|
||||
--save_master_pos
|
||||
--connection slave
|
||||
--sync_with_master
|
||||
--connection master
|
||||
|
||||
|
||||
# cleanup
|
||||
connection master;
|
||||
drop table t1;
|
||||
|
@ -331,6 +331,98 @@ SHOW TRIGGERS;
|
||||
|
||||
RESET MASTER;
|
||||
|
||||
# Restart slave.
|
||||
|
||||
connection slave;
|
||||
START SLAVE;
|
||||
|
||||
|
||||
#
|
||||
# BUG#20438: CREATE statements for views, stored routines and triggers can be
|
||||
# not replicable.
|
||||
#
|
||||
|
||||
--echo
|
||||
--echo ---> Test for BUG#20438
|
||||
|
||||
# Prepare environment.
|
||||
|
||||
--echo
|
||||
--echo ---> Preparing environment...
|
||||
--echo ---> connection: master
|
||||
--connection master
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
--enable_warnings
|
||||
|
||||
--echo
|
||||
--echo ---> Synchronizing slave with master...
|
||||
|
||||
--save_master_pos
|
||||
--connection slave
|
||||
--sync_with_master
|
||||
|
||||
--echo
|
||||
--echo ---> connection: master
|
||||
--connection master
|
||||
|
||||
# Test.
|
||||
|
||||
--echo
|
||||
--echo ---> Creating objects...
|
||||
|
||||
CREATE TABLE t1(c INT);
|
||||
CREATE TABLE t2(c INT);
|
||||
|
||||
/*!50003 CREATE TRIGGER t1_bi BEFORE INSERT ON t1
|
||||
FOR EACH ROW
|
||||
INSERT INTO t2 VALUES(NEW.c * 10) */;
|
||||
|
||||
--echo
|
||||
--echo ---> Inserting value...
|
||||
|
||||
INSERT INTO t1 VALUES(1);
|
||||
|
||||
--echo
|
||||
--echo ---> Checking on master...
|
||||
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
|
||||
--echo
|
||||
--echo ---> Synchronizing slave with master...
|
||||
|
||||
--save_master_pos
|
||||
--connection slave
|
||||
--sync_with_master
|
||||
|
||||
--echo ---> connection: master
|
||||
|
||||
--echo
|
||||
--echo ---> Checking on slave...
|
||||
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
|
||||
# Cleanup.
|
||||
|
||||
--echo
|
||||
--echo ---> connection: master
|
||||
--connection master
|
||||
|
||||
--echo
|
||||
--echo ---> Cleaning up...
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
|
||||
--save_master_pos
|
||||
--connection slave
|
||||
--sync_with_master
|
||||
--connection master
|
||||
|
||||
|
||||
#
|
||||
# End of tests
|
||||
|
@ -45,3 +45,87 @@ drop table t1;
|
||||
sync_slave_with_master;
|
||||
--replace_column 2 # 5 #
|
||||
show binlog events limit 1,100;
|
||||
|
||||
|
||||
|
||||
#
|
||||
# BUG#20438: CREATE statements for views, stored routines and triggers can be
|
||||
# not replicable.
|
||||
#
|
||||
|
||||
--echo
|
||||
--echo ---> Test for BUG#20438
|
||||
|
||||
# Prepare environment.
|
||||
|
||||
--echo
|
||||
--echo ---> Preparing environment...
|
||||
--echo ---> connection: master
|
||||
--connection master
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP VIEW IF EXISTS v1;
|
||||
--enable_warnings
|
||||
|
||||
--echo
|
||||
--echo ---> Synchronizing slave with master...
|
||||
|
||||
--save_master_pos
|
||||
--connection slave
|
||||
--sync_with_master
|
||||
|
||||
--echo
|
||||
--echo ---> connection: master
|
||||
--connection master
|
||||
|
||||
# Test.
|
||||
|
||||
--echo
|
||||
--echo ---> Creating objects...
|
||||
|
||||
CREATE TABLE t1(c INT);
|
||||
|
||||
/*!50003 CREATE VIEW v1 AS SELECT * FROM t1 */;
|
||||
|
||||
--echo
|
||||
--echo ---> Inserting value...
|
||||
|
||||
INSERT INTO t1 VALUES(1);
|
||||
|
||||
--echo
|
||||
--echo ---> Checking on master...
|
||||
|
||||
SELECT * FROM t1;
|
||||
|
||||
--echo
|
||||
--echo ---> Synchronizing slave with master...
|
||||
|
||||
--save_master_pos
|
||||
--connection slave
|
||||
--sync_with_master
|
||||
|
||||
--echo ---> connection: master
|
||||
|
||||
--echo
|
||||
--echo ---> Checking on slave...
|
||||
|
||||
SELECT * FROM t1;
|
||||
|
||||
# Cleanup.
|
||||
|
||||
--echo
|
||||
--echo ---> connection: master
|
||||
--connection master
|
||||
|
||||
--echo
|
||||
--echo ---> Cleaning up...
|
||||
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--save_master_pos
|
||||
--connection slave
|
||||
--sync_with_master
|
||||
--connection master
|
||||
|
||||
|
@ -495,4 +495,15 @@ SHOW CREATE VIEW v1;
|
||||
DROP PROCEDURE p1;
|
||||
DROP VIEW v1;
|
||||
|
||||
|
||||
#
|
||||
# Check that SHOW TABLES and SHOW COLUMNS give a error if there is no
|
||||
# referenced database and table respectively.
|
||||
#
|
||||
--error ER_BAD_DB_ERROR
|
||||
SHOW TABLES FROM no_such_database;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
SHOW COLUMNS FROM no_such_table;
|
||||
|
||||
|
||||
# End of 5.0 tests.
|
||||
|
@ -190,3 +190,25 @@ delimiter ;//
|
||||
show procedure code sudoku_solve;
|
||||
|
||||
drop procedure sudoku_solve;
|
||||
|
||||
|
||||
#
|
||||
# Bug#19207: Final parenthesis omitted for CREATE INDEX in Stored
|
||||
# Procedure
|
||||
#
|
||||
# Wrong criteria was used to distinguish the case when there was no
|
||||
# lookahead performed in the parser. Bug affected only statements
|
||||
# ending in one-character token without any optional tail, like CREATE
|
||||
# INDEX and CALL.
|
||||
#
|
||||
--disable_warnings
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
--enable_warnings
|
||||
|
||||
CREATE PROCEDURE p1() CREATE INDEX idx ON t1 (c1);
|
||||
SHOW PROCEDURE CODE p1;
|
||||
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
@ -1706,6 +1706,28 @@ drop function if exists bug16896;
|
||||
create aggregate function bug16896() returns int return 1;
|
||||
|
||||
|
||||
#
|
||||
# BUG#14702: misleading error message when syntax error in CREATE
|
||||
# PROCEDURE
|
||||
#
|
||||
# Misleading error message was given when IF NOT EXISTS was used in
|
||||
# CREATE PROCEDURE.
|
||||
#
|
||||
--disable_warnings
|
||||
DROP PROCEDURE IF EXISTS bug14702;
|
||||
--enable_warnings
|
||||
|
||||
--error ER_PARSE_ERROR
|
||||
CREATE IF NOT EXISTS PROCEDURE bug14702()
|
||||
BEGIN
|
||||
END;
|
||||
|
||||
--error ER_PARSE_ERROR
|
||||
CREATE PROCEDURE IF NOT EXISTS bug14702()
|
||||
BEGIN
|
||||
END;
|
||||
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
#
|
||||
|
@ -790,4 +790,80 @@ SELECT Host,User,Password FROM mysql.user WHERE User='user19857';
|
||||
|
||||
DROP USER user19857@localhost;
|
||||
|
||||
# End of 5.0 bugs.
|
||||
--disconnect con1root
|
||||
--connection default
|
||||
|
||||
|
||||
#
|
||||
# BUG#18630: Arguments of suid routine calculated in wrong security
|
||||
# context
|
||||
#
|
||||
# Arguments of suid routines were calculated in definer's security
|
||||
# context instead of caller's context thus creating security hole.
|
||||
#
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP VIEW IF EXISTS v1;
|
||||
DROP FUNCTION IF EXISTS f_suid;
|
||||
DROP PROCEDURE IF EXISTS p_suid;
|
||||
DROP FUNCTION IF EXISTS f_evil;
|
||||
--enable_warnings
|
||||
DELETE FROM mysql.user WHERE user LIKE 'mysqltest\_%';
|
||||
DELETE FROM mysql.db WHERE user LIKE 'mysqltest\_%';
|
||||
DELETE FROM mysql.tables_priv WHERE user LIKE 'mysqltest\_%';
|
||||
DELETE FROM mysql.columns_priv WHERE user LIKE 'mysqltest\_%';
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
CREATE TABLE t1 (i INT);
|
||||
CREATE FUNCTION f_suid(i INT) RETURNS INT SQL SECURITY DEFINER RETURN 0;
|
||||
CREATE PROCEDURE p_suid(IN i INT) SQL SECURITY DEFINER SET @c:= 0;
|
||||
|
||||
CREATE USER mysqltest_u1@localhost;
|
||||
# Thanks to this grant statement privileges of anonymous users on
|
||||
# 'test' database are not applicable for mysqltest_u1@localhost.
|
||||
GRANT EXECUTE ON test.* TO mysqltest_u1@localhost;
|
||||
|
||||
delimiter |;
|
||||
CREATE DEFINER=mysqltest_u1@localhost FUNCTION f_evil () RETURNS INT
|
||||
SQL SECURITY INVOKER
|
||||
BEGIN
|
||||
SET @a:= CURRENT_USER();
|
||||
SET @b:= (SELECT COUNT(*) FROM t1);
|
||||
RETURN @b;
|
||||
END|
|
||||
delimiter ;|
|
||||
|
||||
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT f_evil();
|
||||
|
||||
connect (conn1, localhost, mysqltest_u1,,);
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
SELECT COUNT(*) FROM t1;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
SELECT f_evil();
|
||||
SELECT @a, @b;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
SELECT f_suid(f_evil());
|
||||
SELECT @a, @b;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
CALL p_suid(f_evil());
|
||||
SELECT @a, @b;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
SELECT * FROM v1;
|
||||
SELECT @a, @b;
|
||||
|
||||
disconnect conn1;
|
||||
connection default;
|
||||
|
||||
DROP VIEW v1;
|
||||
DROP FUNCTION f_evil;
|
||||
DROP USER mysqltest_u1@localhost;
|
||||
DROP PROCEDURE p_suid;
|
||||
DROP FUNCTION f_suid;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
@ -5962,7 +5962,190 @@ call bug15217()|
|
||||
drop table t3|
|
||||
drop procedure bug15217|
|
||||
|
||||
|
||||
#
|
||||
# BUG#21013: Performance Degrades when importing data that uses
|
||||
# Trigger and Stored Procedure
|
||||
#
|
||||
# This is a performance and memory leak test. Run with large number
|
||||
# passed to bug21013() procedure.
|
||||
#
|
||||
--disable_warnings
|
||||
DROP PROCEDURE IF EXISTS bug21013 |
|
||||
--enable_warnings
|
||||
|
||||
CREATE PROCEDURE bug21013(IN lim INT)
|
||||
BEGIN
|
||||
DECLARE i INT DEFAULT 0;
|
||||
WHILE (i < lim) DO
|
||||
SET @b = LOCATE(_latin1'b', @a, 1);
|
||||
SET i = i + 1;
|
||||
END WHILE;
|
||||
END |
|
||||
|
||||
SET @a = _latin2"aaaaaaaaaa" |
|
||||
CALL bug21013(10) |
|
||||
|
||||
DROP PROCEDURE bug21013 |
|
||||
|
||||
|
||||
#
|
||||
# BUG#16211: Stored function return type for strings is ignored
|
||||
#
|
||||
|
||||
# Prepare: create database with fixed, pre-defined character set.
|
||||
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS mysqltest1|
|
||||
DROP DATABASE IF EXISTS mysqltest2|
|
||||
--enable_warnings
|
||||
|
||||
CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8|
|
||||
CREATE DATABASE mysqltest2 DEFAULT CHARACTER SET utf8|
|
||||
|
||||
# Test case:
|
||||
|
||||
use mysqltest1|
|
||||
|
||||
# - Create two stored functions -- with and without explicit CHARSET-clause
|
||||
# for return value;
|
||||
|
||||
CREATE FUNCTION bug16211_f1() RETURNS CHAR(10)
|
||||
RETURN ""|
|
||||
|
||||
CREATE FUNCTION bug16211_f2() RETURNS CHAR(10) CHARSET koi8r
|
||||
RETURN ""|
|
||||
|
||||
CREATE FUNCTION mysqltest2.bug16211_f3() RETURNS CHAR(10)
|
||||
RETURN ""|
|
||||
|
||||
CREATE FUNCTION mysqltest2.bug16211_f4() RETURNS CHAR(10) CHARSET koi8r
|
||||
RETURN ""|
|
||||
|
||||
# - Check that CHARSET-clause is specified for the second function;
|
||||
|
||||
SHOW CREATE FUNCTION bug16211_f1|
|
||||
SHOW CREATE FUNCTION bug16211_f2|
|
||||
|
||||
SHOW CREATE FUNCTION mysqltest2.bug16211_f3|
|
||||
SHOW CREATE FUNCTION mysqltest2.bug16211_f4|
|
||||
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"|
|
||||
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"|
|
||||
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"|
|
||||
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"|
|
||||
|
||||
SELECT CHARSET(bug16211_f1())|
|
||||
SELECT CHARSET(bug16211_f2())|
|
||||
|
||||
SELECT CHARSET(mysqltest2.bug16211_f3())|
|
||||
SELECT CHARSET(mysqltest2.bug16211_f4())|
|
||||
|
||||
# - Alter database character set.
|
||||
|
||||
ALTER DATABASE mysqltest1 CHARACTER SET cp1251|
|
||||
ALTER DATABASE mysqltest2 CHARACTER SET cp1251|
|
||||
|
||||
# - Check that CHARSET-clause has not changed.
|
||||
|
||||
SHOW CREATE FUNCTION bug16211_f1|
|
||||
SHOW CREATE FUNCTION bug16211_f2|
|
||||
|
||||
SHOW CREATE FUNCTION mysqltest2.bug16211_f3|
|
||||
SHOW CREATE FUNCTION mysqltest2.bug16211_f4|
|
||||
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"|
|
||||
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"|
|
||||
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"|
|
||||
|
||||
SELECT dtd_identifier
|
||||
FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"|
|
||||
|
||||
SELECT CHARSET(bug16211_f1())|
|
||||
SELECT CHARSET(bug16211_f2())|
|
||||
|
||||
SELECT CHARSET(mysqltest2.bug16211_f3())|
|
||||
SELECT CHARSET(mysqltest2.bug16211_f4())|
|
||||
|
||||
# Cleanup.
|
||||
|
||||
use test|
|
||||
|
||||
DROP DATABASE mysqltest1|
|
||||
DROP DATABASE mysqltest2|
|
||||
|
||||
|
||||
#
|
||||
# BUG#16676: Database CHARSET not used for stored procedures
|
||||
#
|
||||
|
||||
# Prepare: create database with fixed, pre-defined character set.
|
||||
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS mysqltest1|
|
||||
--enable_warnings
|
||||
|
||||
CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8|
|
||||
|
||||
# Test case:
|
||||
|
||||
use mysqltest1|
|
||||
|
||||
# - Create two stored procedures -- with and without explicit CHARSET-clause;
|
||||
|
||||
CREATE PROCEDURE bug16676_p1(
|
||||
IN p1 CHAR(10),
|
||||
INOUT p2 CHAR(10),
|
||||
OUT p3 CHAR(10))
|
||||
BEGIN
|
||||
SELECT CHARSET(p1), COLLATION(p1);
|
||||
SELECT CHARSET(p2), COLLATION(p2);
|
||||
SELECT CHARSET(p3), COLLATION(p3);
|
||||
END|
|
||||
|
||||
CREATE PROCEDURE bug16676_p2(
|
||||
IN p1 CHAR(10) CHARSET koi8r,
|
||||
INOUT p2 CHAR(10) CHARSET cp1251,
|
||||
OUT p3 CHAR(10) CHARSET greek)
|
||||
BEGIN
|
||||
SELECT CHARSET(p1), COLLATION(p1);
|
||||
SELECT CHARSET(p2), COLLATION(p2);
|
||||
SELECT CHARSET(p3), COLLATION(p3);
|
||||
END|
|
||||
|
||||
# - Call procedures.
|
||||
|
||||
SET @v2 = 'b'|
|
||||
SET @v3 = 'c'|
|
||||
|
||||
CALL bug16676_p1('a', @v2, @v3)|
|
||||
CALL bug16676_p2('a', @v2, @v3)|
|
||||
|
||||
# Cleanup.
|
||||
|
||||
use test|
|
||||
|
||||
DROP DATABASE mysqltest1|
|
||||
# Bug#21002 "Derived table not selecting from a "real" table fails in JOINs"
|
||||
#
|
||||
# A regression caused by the fix for Bug#18444: for derived tables we should
|
||||
|
@ -109,6 +109,18 @@ SELECT myfunc_double(n) AS f FROM bug19904;
|
||||
SELECT metaphon(v) AS f FROM bug19904;
|
||||
DROP TABLE bug19904;
|
||||
|
||||
#
|
||||
# Bug#21269: DEFINER-clause is allowed for UDF-functions
|
||||
#
|
||||
|
||||
--error ER_WRONG_USAGE
|
||||
CREATE DEFINER=CURRENT_USER() FUNCTION should_not_parse
|
||||
RETURNS STRING SONAME "should_not_parse.so";
|
||||
|
||||
--error ER_WRONG_USAGE
|
||||
CREATE DEFINER=someone@somewhere FUNCTION should_not_parse
|
||||
RETURNS STRING SONAME "should_not_parse.so";
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
||||
#
|
||||
|
@ -584,7 +584,7 @@ err:
|
||||
*****************************************************************************/
|
||||
|
||||
ulong
|
||||
net_safe_read(MYSQL *mysql)
|
||||
cli_safe_read(MYSQL *mysql)
|
||||
{
|
||||
NET *net= &mysql->net;
|
||||
ulong len=0;
|
||||
@ -627,6 +627,16 @@ net_safe_read(MYSQL *mysql)
|
||||
}
|
||||
else
|
||||
set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
|
||||
/*
|
||||
Cover a protocol design error: error packet does not
|
||||
contain the server status. Therefore, the client has no way
|
||||
to find out whether there are more result sets of
|
||||
a multiple-result-set statement pending. Luckily, in 5.0 an
|
||||
error always aborts execution of a statement, wherever it is
|
||||
a multi-statement or a stored procedure, so it should be
|
||||
safe to unconditionally turn off the flag here.
|
||||
*/
|
||||
mysql->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
|
||||
|
||||
DBUG_PRINT("error",("Got error: %d/%s (%s)",
|
||||
net->last_errno, net->sqlstate, net->last_error));
|
||||
@ -653,7 +663,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
||||
NET *net= &mysql->net;
|
||||
my_bool result= 1;
|
||||
init_sigpipe_variables
|
||||
DBUG_ENTER("cli_advanced_command");
|
||||
DBUG_ENTER("cli_advanced_command");
|
||||
|
||||
/* Don't give sigpipe errors if the client doesn't want them */
|
||||
set_sigpipe(mysql);
|
||||
@ -663,7 +673,8 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
||||
if (mysql_reconnect(mysql))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (mysql->status != MYSQL_STATUS_READY)
|
||||
if (mysql->status != MYSQL_STATUS_READY ||
|
||||
mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
|
||||
{
|
||||
DBUG_PRINT("error",("state: %d", mysql->status));
|
||||
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
|
||||
@ -702,7 +713,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
||||
}
|
||||
result=0;
|
||||
if (!skip_check)
|
||||
result= ((mysql->packet_length=net_safe_read(mysql)) == packet_error ?
|
||||
result= ((mysql->packet_length=cli_safe_read(mysql)) == packet_error ?
|
||||
1 : 0);
|
||||
end:
|
||||
reset_sigpipe(mysql);
|
||||
@ -754,7 +765,7 @@ static void cli_flush_use_result(MYSQL *mysql)
|
||||
for (;;)
|
||||
{
|
||||
ulong pkt_len;
|
||||
if ((pkt_len=net_safe_read(mysql)) == packet_error)
|
||||
if ((pkt_len=cli_safe_read(mysql)) == packet_error)
|
||||
break;
|
||||
if (pkt_len <= 8 && mysql->net.read_pos[0] == 254)
|
||||
{
|
||||
@ -1276,7 +1287,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
|
||||
NET *net = &mysql->net;
|
||||
DBUG_ENTER("cli_read_rows");
|
||||
|
||||
if ((pkt_len= net_safe_read(mysql)) == packet_error)
|
||||
if ((pkt_len= cli_safe_read(mysql)) == packet_error)
|
||||
DBUG_RETURN(0);
|
||||
if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
|
||||
MYF(MY_WME | MY_ZEROFILL))))
|
||||
@ -1341,7 +1352,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
|
||||
}
|
||||
}
|
||||
cur->data[field]=to; /* End of last field */
|
||||
if ((pkt_len=net_safe_read(mysql)) == packet_error)
|
||||
if ((pkt_len=cli_safe_read(mysql)) == packet_error)
|
||||
{
|
||||
free_rows(result);
|
||||
DBUG_RETURN(0);
|
||||
@ -1373,7 +1384,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
|
||||
uchar *pos, *prev_pos, *end_pos;
|
||||
NET *net= &mysql->net;
|
||||
|
||||
if ((pkt_len=net_safe_read(mysql)) == packet_error)
|
||||
if ((pkt_len=cli_safe_read(mysql)) == packet_error)
|
||||
return -1;
|
||||
if (pkt_len <= 8 && net->read_pos[0] == 254)
|
||||
{
|
||||
@ -1650,23 +1661,23 @@ static MYSQL_RES *cli_use_result(MYSQL *mysql);
|
||||
|
||||
static MYSQL_METHODS client_methods=
|
||||
{
|
||||
cli_read_query_result,
|
||||
cli_advanced_command,
|
||||
cli_read_rows,
|
||||
cli_use_result,
|
||||
cli_fetch_lengths,
|
||||
cli_flush_use_result
|
||||
cli_read_query_result, /* read_query_result */
|
||||
cli_advanced_command, /* advanced_command */
|
||||
cli_read_rows, /* read_rows */
|
||||
cli_use_result, /* use_result */
|
||||
cli_fetch_lengths, /* fetch_lengths */
|
||||
cli_flush_use_result /* flush_use_result */
|
||||
#ifndef MYSQL_SERVER
|
||||
,cli_list_fields,
|
||||
cli_read_prepare_result,
|
||||
cli_stmt_execute,
|
||||
cli_read_binary_rows,
|
||||
cli_unbuffered_fetch,
|
||||
NULL,
|
||||
cli_read_statistics,
|
||||
cli_read_query_result,
|
||||
cli_read_change_user_result,
|
||||
cli_read_binary_rows
|
||||
,cli_list_fields, /* list_fields */
|
||||
cli_read_prepare_result, /* read_prepare_result */
|
||||
cli_stmt_execute, /* stmt_execute */
|
||||
cli_read_binary_rows, /* read_binary_rows */
|
||||
cli_unbuffered_fetch, /* unbuffered_fetch */
|
||||
NULL, /* free_embedded_thd */
|
||||
cli_read_statistics, /* read_statistics */
|
||||
cli_read_query_result, /* next_result */
|
||||
cli_read_change_user_result, /* read_change_user_result */
|
||||
cli_read_binary_rows /* read_rows_from_cursor */
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -2029,7 +2040,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
|
||||
Part 1: Connection established, read and parse first packet
|
||||
*/
|
||||
|
||||
if ((pkt_length=net_safe_read(mysql)) == packet_error)
|
||||
if ((pkt_length=cli_safe_read(mysql)) == packet_error)
|
||||
goto error;
|
||||
|
||||
/* Check if version of protocol matches current one */
|
||||
@ -2253,7 +2264,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
|
||||
OK-packet, or re-request scrambled password.
|
||||
*/
|
||||
|
||||
if ((pkt_length=net_safe_read(mysql)) == packet_error)
|
||||
if ((pkt_length=cli_safe_read(mysql)) == packet_error)
|
||||
goto error;
|
||||
|
||||
if (pkt_length == 1 && net->read_pos[0] == 254 &&
|
||||
@ -2270,7 +2281,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
|
||||
goto error;
|
||||
}
|
||||
/* Read what server thinks about out new auth message report */
|
||||
if (net_safe_read(mysql) == packet_error)
|
||||
if (cli_safe_read(mysql) == packet_error)
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -2594,7 +2605,7 @@ static my_bool cli_read_query_result(MYSQL *mysql)
|
||||
*/
|
||||
mysql = mysql->last_used_con;
|
||||
|
||||
if ((length = net_safe_read(mysql)) == packet_error)
|
||||
if ((length = cli_safe_read(mysql)) == packet_error)
|
||||
DBUG_RETURN(1);
|
||||
free_old_query(mysql); /* Free old result */
|
||||
#ifdef MYSQL_CLIENT /* Avoid warn of unused labels*/
|
||||
@ -2629,7 +2640,7 @@ get_info:
|
||||
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
|
||||
{
|
||||
int error=handle_local_infile(mysql,(char*) pos);
|
||||
if ((length=net_safe_read(mysql)) == packet_error || error)
|
||||
if ((length= cli_safe_read(mysql)) == packet_error || error)
|
||||
DBUG_RETURN(1);
|
||||
goto get_info; /* Get info packet */
|
||||
}
|
||||
|
@ -1424,7 +1424,8 @@ bool agg_item_charsets(DTCollation &coll, const char *fname,
|
||||
In case we're in statement prepare, create conversion item
|
||||
in its memory: it will be reused on each execute.
|
||||
*/
|
||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||
arena= thd->is_stmt_prepare() ? thd->activate_stmt_arena_if_needed(&backup)
|
||||
: NULL;
|
||||
|
||||
for (i= 0, arg= args; i < nargs; i++, arg+= item_sep)
|
||||
{
|
||||
@ -1459,7 +1460,7 @@ bool agg_item_charsets(DTCollation &coll, const char *fname,
|
||||
been created in prepare. In this case register the change for
|
||||
rollback.
|
||||
*/
|
||||
if (arena && arena->is_conventional())
|
||||
if (arena)
|
||||
*arg= conv;
|
||||
else
|
||||
thd->change_item_tree(arg, conv);
|
||||
|
@ -4830,7 +4830,9 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
|
||||
{
|
||||
bool err_status= TRUE;
|
||||
Sub_statement_state statement_state;
|
||||
Security_context *save_security_ctx= thd->security_ctx, *save_ctx_func;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
Security_context *save_security_ctx= thd->security_ctx;
|
||||
#endif
|
||||
|
||||
DBUG_ENTER("Item_func_sp::execute_impl");
|
||||
|
||||
@ -4841,7 +4843,7 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
|
||||
thd->security_ctx= context->security_ctx;
|
||||
}
|
||||
#endif
|
||||
if (find_and_check_access(thd, EXECUTE_ACL, &save_ctx_func))
|
||||
if (find_and_check_access(thd))
|
||||
goto error;
|
||||
|
||||
/*
|
||||
@ -4853,13 +4855,11 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
|
||||
err_status= m_sp->execute_function(thd, args, arg_count, return_value_fld);
|
||||
thd->restore_sub_statement_state(&statement_state);
|
||||
|
||||
error:
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
sp_restore_security_context(thd, save_ctx_func);
|
||||
error:
|
||||
thd->security_ctx= save_security_ctx;
|
||||
#else
|
||||
error:
|
||||
#endif
|
||||
|
||||
DBUG_RETURN(err_status);
|
||||
}
|
||||
|
||||
@ -4976,70 +4976,38 @@ Item_func_sp::tmp_table_field(TABLE *t_arg)
|
||||
SYNOPSIS
|
||||
find_and_check_access()
|
||||
thd thread handler
|
||||
want_access requested access
|
||||
save backup of security context
|
||||
|
||||
RETURN
|
||||
FALSE Access granted
|
||||
TRUE Requested access can't be granted or function doesn't exists
|
||||
In this case security context is not changed and *save = 0
|
||||
|
||||
NOTES
|
||||
Checks if requested access to function can be granted to user.
|
||||
If function isn't found yet, it searches function first.
|
||||
If function can't be found or user don't have requested access
|
||||
error is raised.
|
||||
If security context sp_ctx is provided and access can be granted then
|
||||
switch back to previous context isn't performed.
|
||||
In case of access error or if context is not provided then
|
||||
find_and_check_access() switches back to previous security context.
|
||||
*/
|
||||
|
||||
bool
|
||||
Item_func_sp::find_and_check_access(THD *thd, ulong want_access,
|
||||
Security_context **save)
|
||||
Item_func_sp::find_and_check_access(THD *thd)
|
||||
{
|
||||
bool res= TRUE;
|
||||
|
||||
*save= 0; // Safety if error
|
||||
if (! m_sp && ! (m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name,
|
||||
&thd->sp_func_cache, TRUE)))
|
||||
{
|
||||
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
|
||||
goto error;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (check_routine_access(thd, want_access,
|
||||
if (check_routine_access(thd, EXECUTE_ACL,
|
||||
m_sp->m_db.str, m_sp->m_name.str, 0, FALSE))
|
||||
goto error;
|
||||
|
||||
sp_change_security_context(thd, m_sp, save);
|
||||
/*
|
||||
If we changed context to run as another user, we need to check the
|
||||
access right for the new context again as someone may have deleted
|
||||
this person the right to use the procedure
|
||||
|
||||
TODO:
|
||||
Cache if the definer has the right to use the object on the first
|
||||
usage and only reset the cache if someone does a GRANT statement
|
||||
that 'may' affect this.
|
||||
*/
|
||||
if (*save &&
|
||||
check_routine_access(thd, want_access,
|
||||
m_sp->m_db.str, m_sp->m_name.str, 0, FALSE))
|
||||
{
|
||||
sp_restore_security_context(thd, *save);
|
||||
*save= 0; // Safety
|
||||
goto error;
|
||||
}
|
||||
return TRUE;
|
||||
#endif
|
||||
res= FALSE; // no error
|
||||
|
||||
error:
|
||||
return res;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Item_func_sp::fix_fields(THD *thd, Item **ref)
|
||||
{
|
||||
@ -5050,19 +5018,23 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
|
||||
{
|
||||
/*
|
||||
Here we check privileges of the stored routine only during view
|
||||
creation, in order to validate the view. A runtime check is perfomed
|
||||
in Item_func_sp::execute(), and this method is not called during
|
||||
context analysis. We do not need to restore the security context
|
||||
changed in find_and_check_access because all view structures created
|
||||
in CREATE VIEW are not used for execution. Notice, that during view
|
||||
creation we do not infer into stored routine bodies and do not check
|
||||
privileges of its statements, which would probably be a good idea
|
||||
especially if the view has SQL SECURITY DEFINER and the used stored
|
||||
procedure has SQL SECURITY DEFINER
|
||||
creation, in order to validate the view. A runtime check is
|
||||
perfomed in Item_func_sp::execute(), and this method is not
|
||||
called during context analysis. Notice, that during view
|
||||
creation we do not infer into stored routine bodies and do not
|
||||
check privileges of its statements, which would probably be a
|
||||
good idea especially if the view has SQL SECURITY DEFINER and
|
||||
the used stored procedure has SQL SECURITY DEFINER.
|
||||
*/
|
||||
Security_context *save_ctx;
|
||||
if (!(res= find_and_check_access(thd, EXECUTE_ACL, &save_ctx)))
|
||||
sp_restore_security_context(thd, save_ctx);
|
||||
res= find_and_check_access(thd);
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
Security_context *save_secutiry_ctx;
|
||||
if (!res && !(res= set_routine_security_ctx(thd, m_sp, false,
|
||||
&save_secutiry_ctx)))
|
||||
{
|
||||
sp_restore_security_context(thd, save_secutiry_ctx);
|
||||
}
|
||||
#endif /* ! NO_EMBEDDED_ACCESS_CHECKS */
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -1468,8 +1468,7 @@ public:
|
||||
{ context= (Name_resolution_context *)cntx; return FALSE; }
|
||||
|
||||
void fix_length_and_dec();
|
||||
bool find_and_check_access(THD * thd, ulong want_access,
|
||||
Security_context **backup);
|
||||
bool find_and_check_access(THD * thd);
|
||||
virtual enum Functype functype() const { return FUNC_SP; }
|
||||
|
||||
bool fix_fields(THD *thd, Item **ref);
|
||||
|
@ -865,8 +865,6 @@ bool mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create);
|
||||
void mysqld_list_processes(THD *thd,const char *user,bool verbose);
|
||||
int mysqld_show_status(THD *thd);
|
||||
int mysqld_show_variables(THD *thd,const char *wild);
|
||||
int mysql_find_files(THD *thd,List<char> *files, const char *db,
|
||||
const char *path, const char *wild, bool dir);
|
||||
bool mysqld_show_storage_engines(THD *thd);
|
||||
bool mysqld_show_privileges(THD *thd);
|
||||
bool mysqld_show_column_types(THD *thd);
|
||||
@ -1138,7 +1136,10 @@ uint check_word(TYPELIB *lib, const char *val, const char *end,
|
||||
bool is_keyword(const char *name, uint len);
|
||||
|
||||
#define MY_DB_OPT_FILE "db.opt"
|
||||
bool check_db_dir_existence(const char *db_name);
|
||||
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
|
||||
bool load_db_opt_by_name(THD *thd, const char *db_name,
|
||||
HA_CREATE_INFO *db_create_info);
|
||||
bool my_dbopt_init(void);
|
||||
void my_dbopt_cleanup(void);
|
||||
void my_dbopt_free(void);
|
||||
|
@ -322,7 +322,7 @@ static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */
|
||||
254 Marker (1 byte)
|
||||
warning_count Stored in 2 bytes; New in 4.1 protocol
|
||||
status_flag Stored in 2 bytes;
|
||||
For flags like SERVER_STATUS_MORE_RESULTS
|
||||
For flags like SERVER_MORE_RESULTS_EXISTS
|
||||
|
||||
Note that the warning count will not be sent if 'no_flush' is set as
|
||||
we don't want to report the warning count until all data is sent to the
|
||||
|
@ -3051,7 +3051,7 @@ static ulong read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings)
|
||||
return packet_error;
|
||||
#endif
|
||||
|
||||
len = net_safe_read(mysql);
|
||||
len = cli_safe_read(mysql);
|
||||
if (len == packet_error || (long) len < 1)
|
||||
{
|
||||
if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
|
||||
|
17
sql/sp.cc
17
sql/sp.cc
@ -495,6 +495,13 @@ sp_returns_type(THD *thd, String &result, sp_head *sp)
|
||||
table.s = &table.share_not_to_be_used;
|
||||
field= sp->create_result_field(0, 0, &table);
|
||||
field->sql_type(result);
|
||||
|
||||
if (field->has_charset())
|
||||
{
|
||||
result.append(STRING_WITH_LEN(" CHARSET "));
|
||||
result.append(field->charset()->csname);
|
||||
}
|
||||
|
||||
delete field;
|
||||
}
|
||||
|
||||
@ -626,7 +633,10 @@ db_create_routine(THD *thd, int type, sp_head *sp)
|
||||
log_query.append(STRING_WITH_LEN("CREATE "));
|
||||
append_definer(thd, &log_query, &thd->lex->definer->user,
|
||||
&thd->lex->definer->host);
|
||||
log_query.append(thd->lex->stmt_definition_begin);
|
||||
log_query.append(thd->lex->stmt_definition_begin,
|
||||
(char *)sp->m_body_begin -
|
||||
thd->lex->stmt_definition_begin +
|
||||
sp->m_body.length);
|
||||
|
||||
/* Such a statement can always go directly to binlog, no trans cache */
|
||||
Query_log_event qinfo(thd, log_query.c_ptr(), log_query.length(), 0,
|
||||
@ -974,6 +984,11 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp,
|
||||
sp_head *new_sp;
|
||||
const char *returns= "";
|
||||
char definer[USER_HOST_BUFF_SIZE];
|
||||
|
||||
/*
|
||||
String buffer for RETURNS data type must have system charset;
|
||||
64 -- size of "returns" column of mysql.proc.
|
||||
*/
|
||||
String retstr(64);
|
||||
|
||||
DBUG_PRINT("info", ("found: 0x%lx", (ulong)sp));
|
||||
|
248
sql/sp_head.cc
248
sql/sp_head.cc
@ -470,7 +470,7 @@ sp_head::init(LEX *lex)
|
||||
lex->trg_table_fields.empty();
|
||||
my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8);
|
||||
m_param_begin= m_param_end= m_body_begin= 0;
|
||||
m_qname.str= m_db.str= m_name.str= m_params.str=
|
||||
m_qname.str= m_db.str= m_name.str= m_params.str=
|
||||
m_body.str= m_defstr.str= 0;
|
||||
m_qname.length= m_db.length= m_name.length= m_params.length=
|
||||
m_body.length= m_defstr.length= 0;
|
||||
@ -478,29 +478,42 @@ sp_head::init(LEX *lex)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sp_head::init_strings(THD *thd, LEX *lex, sp_name *name)
|
||||
sp_head::init_sp_name(THD *thd, sp_name *spname)
|
||||
{
|
||||
DBUG_ENTER("sp_head::init_sp_name");
|
||||
|
||||
/* Must be initialized in the parser. */
|
||||
|
||||
DBUG_ASSERT(spname && spname->m_db.str && spname->m_db.length);
|
||||
|
||||
/* We have to copy strings to get them into the right memroot. */
|
||||
|
||||
m_db.length= spname->m_db.length;
|
||||
m_db.str= strmake_root(thd->mem_root, spname->m_db.str, spname->m_db.length);
|
||||
|
||||
m_name.length= spname->m_name.length;
|
||||
m_name.str= strmake_root(thd->mem_root, spname->m_name.str,
|
||||
spname->m_name.length);
|
||||
|
||||
if (spname->m_qname.length == 0)
|
||||
spname->init_qname(thd);
|
||||
|
||||
m_qname.length= spname->m_qname.length;
|
||||
m_qname.str= strmake_root(thd->mem_root, spname->m_qname.str,
|
||||
m_qname.length);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sp_head::init_strings(THD *thd, LEX *lex)
|
||||
{
|
||||
DBUG_ENTER("sp_head::init_strings");
|
||||
uchar *endp; /* Used to trim the end */
|
||||
/* During parsing, we must use thd->mem_root */
|
||||
MEM_ROOT *root= thd->mem_root;
|
||||
|
||||
DBUG_ASSERT(name);
|
||||
/* Must be initialized in the parser */
|
||||
DBUG_ASSERT(name->m_db.str && name->m_db.length);
|
||||
|
||||
/* We have to copy strings to get them into the right memroot */
|
||||
m_db.length= name->m_db.length;
|
||||
m_db.str= strmake_root(root, name->m_db.str, name->m_db.length);
|
||||
m_name.length= name->m_name.length;
|
||||
m_name.str= strmake_root(root, name->m_name.str, name->m_name.length);
|
||||
|
||||
if (name->m_qname.length == 0)
|
||||
name->init_qname(thd);
|
||||
m_qname.length= name->m_qname.length;
|
||||
m_qname.str= strmake_root(root, name->m_qname.str, m_qname.length);
|
||||
|
||||
if (m_param_begin && m_param_end)
|
||||
{
|
||||
m_params.length= m_param_end - m_param_begin;
|
||||
@ -514,10 +527,7 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name)
|
||||
Trim "garbage" at the end. This is sometimes needed with the
|
||||
"/ * ! VERSION... * /" wrapper in dump files.
|
||||
*/
|
||||
while (m_body_begin < endp &&
|
||||
(endp[-1] <= ' ' || endp[-1] == '*' ||
|
||||
endp[-1] == '/' || endp[-1] == ';'))
|
||||
endp-= 1;
|
||||
endp= skip_rear_comments(m_body_begin, endp);
|
||||
|
||||
m_body.length= endp - m_body_begin;
|
||||
m_body.str= strmake_root(root, (char *)m_body_begin, m_body.length);
|
||||
@ -1097,6 +1107,7 @@ sp_head::execute(THD *thd)
|
||||
|
||||
thd->restore_active_arena(&execute_arena, &backup_arena);
|
||||
|
||||
thd->spcont->pop_all_cursors(); // To avoid memory leaks after an error
|
||||
|
||||
/* Restore all saved */
|
||||
old_packet.swap(thd->packet);
|
||||
@ -1158,6 +1169,161 @@ sp_head::execute(THD *thd)
|
||||
m_first_instance->m_first_free_instance->m_recursion_level ==
|
||||
m_recursion_level + 1));
|
||||
m_first_instance->m_first_free_instance= this;
|
||||
|
||||
DBUG_RETURN(err_status);
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/*
|
||||
set_routine_security_ctx() changes routine security context, and
|
||||
checks if there is an EXECUTE privilege in new context. If there is
|
||||
no EXECUTE privilege, it changes the context back and returns a
|
||||
error.
|
||||
|
||||
SYNOPSIS
|
||||
set_routine_security_ctx()
|
||||
thd thread handle
|
||||
sp stored routine to change the context for
|
||||
is_proc TRUE is procedure, FALSE if function
|
||||
save_ctx pointer to an old security context
|
||||
|
||||
RETURN
|
||||
TRUE if there was a error, and the context wasn't changed.
|
||||
FALSE if the context was changed.
|
||||
*/
|
||||
|
||||
bool
|
||||
set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc,
|
||||
Security_context **save_ctx)
|
||||
{
|
||||
*save_ctx= 0;
|
||||
if (sp_change_security_context(thd, sp, save_ctx))
|
||||
return TRUE;
|
||||
|
||||
/*
|
||||
If we changed context to run as another user, we need to check the
|
||||
access right for the new context again as someone may have revoked
|
||||
the right to use the procedure from this user.
|
||||
|
||||
TODO:
|
||||
Cache if the definer has the right to use the object on the
|
||||
first usage and only reset the cache if someone does a GRANT
|
||||
statement that 'may' affect this.
|
||||
*/
|
||||
if (*save_ctx &&
|
||||
check_routine_access(thd, EXECUTE_ACL,
|
||||
sp->m_db.str, sp->m_name.str, is_proc, FALSE))
|
||||
{
|
||||
sp_restore_security_context(thd, *save_ctx);
|
||||
*save_ctx= 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif // ! NO_EMBEDDED_ACCESS_CHECKS
|
||||
|
||||
|
||||
/*
|
||||
Execute a trigger:
|
||||
- changes security context for triggers
|
||||
- switch to new memroot
|
||||
- call sp_head::execute
|
||||
- restore old memroot
|
||||
- restores security context
|
||||
|
||||
SYNOPSIS
|
||||
sp_head::execute_trigger()
|
||||
thd Thread handle
|
||||
db database name
|
||||
table table name
|
||||
grant_info GRANT_INFO structure to be filled with
|
||||
information about definer's privileges
|
||||
on subject table
|
||||
|
||||
RETURN
|
||||
FALSE on success
|
||||
TRUE on error
|
||||
*/
|
||||
|
||||
bool
|
||||
sp_head::execute_trigger(THD *thd, const char *db, const char *table,
|
||||
GRANT_INFO *grant_info)
|
||||
{
|
||||
sp_rcontext *octx = thd->spcont;
|
||||
sp_rcontext *nctx = NULL;
|
||||
bool err_status= FALSE;
|
||||
MEM_ROOT call_mem_root;
|
||||
Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP);
|
||||
Query_arena backup_arena;
|
||||
|
||||
DBUG_ENTER("sp_head::execute_trigger");
|
||||
DBUG_PRINT("info", ("trigger %s", m_name.str));
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
Security_context *save_ctx;
|
||||
if (sp_change_security_context(thd, this, &save_ctx))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
/*
|
||||
NOTE: TRIGGER_ACL should be used here.
|
||||
*/
|
||||
if (check_global_access(thd, SUPER_ACL))
|
||||
{
|
||||
sp_restore_security_context(thd, save_ctx);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
Fetch information about table-level privileges to GRANT_INFO
|
||||
structure for subject table. Check of privileges that will use it
|
||||
and information about column-level privileges will happen in
|
||||
Item_trigger_field::fix_fields().
|
||||
*/
|
||||
fill_effective_table_privileges(thd, grant_info, db, table);
|
||||
#endif // NO_EMBEDDED_ACCESS_CHECKS
|
||||
|
||||
/*
|
||||
Prepare arena and memroot for objects which lifetime is whole
|
||||
duration of trigger call (sp_rcontext, it's tables and items,
|
||||
sp_cursor and Item_cache holders for case expressions). We can't
|
||||
use caller's arena/memroot for those objects because in this case
|
||||
some fixed amount of memory will be consumed for each trigger
|
||||
invocation and so statements which involve lot of them will hog
|
||||
memory.
|
||||
|
||||
TODO: we should create sp_rcontext once per command and reuse it
|
||||
on subsequent executions of a trigger.
|
||||
*/
|
||||
init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
|
||||
thd->set_n_backup_active_arena(&call_arena, &backup_arena);
|
||||
|
||||
if (!(nctx= new sp_rcontext(m_pcont, 0, octx)) ||
|
||||
nctx->init(thd))
|
||||
{
|
||||
err_status= TRUE;
|
||||
goto err_with_cleanup;
|
||||
}
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
nctx->sp= this;
|
||||
#endif
|
||||
|
||||
thd->spcont= nctx;
|
||||
|
||||
err_status= execute(thd);
|
||||
|
||||
err_with_cleanup:
|
||||
thd->restore_active_arena(&call_arena, &backup_arena);
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
sp_restore_security_context(thd, save_ctx);
|
||||
#endif // NO_EMBEDDED_ACCESS_CHECKS
|
||||
delete nctx;
|
||||
call_arena.free_items();
|
||||
free_root(&call_mem_root, MYF(0));
|
||||
thd->spcont= octx;
|
||||
|
||||
DBUG_RETURN(err_status);
|
||||
}
|
||||
|
||||
@ -1165,8 +1331,12 @@ sp_head::execute(THD *thd)
|
||||
/*
|
||||
Execute a function:
|
||||
- evaluate parameters
|
||||
- changes security context for SUID routines
|
||||
- switch to new memroot
|
||||
- call sp_head::execute
|
||||
- restore old memroot
|
||||
- evaluate the return value
|
||||
- restores security context
|
||||
|
||||
SYNOPSIS
|
||||
sp_head::execute_function()
|
||||
@ -1293,6 +1463,15 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
|
||||
}
|
||||
thd->spcont= nctx;
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
Security_context *save_security_ctx;
|
||||
if (set_routine_security_ctx(thd, this, FALSE, &save_security_ctx))
|
||||
{
|
||||
err_status= TRUE;
|
||||
goto err_with_cleanup;
|
||||
}
|
||||
#endif
|
||||
|
||||
binlog_save_options= thd->options;
|
||||
if (need_binlog_call)
|
||||
{
|
||||
@ -1333,7 +1512,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
|
||||
reset_dynamic(&thd->user_var_events);
|
||||
}
|
||||
|
||||
if (m_type == TYPE_ENUM_FUNCTION && !err_status)
|
||||
if (!err_status)
|
||||
{
|
||||
/* We need result only in function but not in trigger */
|
||||
|
||||
@ -1344,8 +1523,9 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nctx->pop_all_cursors(); // To avoid memory leaks after an error
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
sp_restore_security_context(thd, save_security_ctx);
|
||||
#endif
|
||||
|
||||
err_with_cleanup:
|
||||
delete nctx;
|
||||
@ -1368,8 +1548,10 @@ err_with_cleanup:
|
||||
|
||||
The function does the following steps:
|
||||
- Set all parameters
|
||||
- changes security context for SUID routines
|
||||
- call sp_head::execute
|
||||
- copy back values of INOUT and OUT parameters
|
||||
- restores security context
|
||||
|
||||
RETURN
|
||||
FALSE on success
|
||||
@ -1490,6 +1672,12 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
||||
|
||||
thd->spcont= nctx;
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
Security_context *save_security_ctx= 0;
|
||||
if (!err_status)
|
||||
err_status= set_routine_security_ctx(thd, this, TRUE, &save_security_ctx);
|
||||
#endif
|
||||
|
||||
if (!err_status)
|
||||
err_status= execute(thd);
|
||||
|
||||
@ -1534,10 +1722,14 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (save_security_ctx)
|
||||
sp_restore_security_context(thd, save_security_ctx);
|
||||
#endif
|
||||
|
||||
if (!save_spcont)
|
||||
delete octx;
|
||||
|
||||
nctx->pop_all_cursors(); // To avoid memory leaks after an error
|
||||
delete nctx;
|
||||
thd->spcont= save_spcont;
|
||||
|
||||
@ -1674,14 +1866,18 @@ sp_head::fill_field_definition(THD *thd, LEX *lex,
|
||||
enum enum_field_types field_type,
|
||||
create_field *field_def)
|
||||
{
|
||||
HA_CREATE_INFO sp_db_info;
|
||||
LEX_STRING cmt = { 0, 0 };
|
||||
uint unused1= 0;
|
||||
int unused2= 0;
|
||||
|
||||
load_db_opt_by_name(thd, m_db.str, &sp_db_info);
|
||||
|
||||
if (field_def->init(thd, (char*) "", field_type, lex->length, lex->dec,
|
||||
lex->type, (Item*) 0, (Item*) 0, &cmt, 0,
|
||||
&lex->interval_list,
|
||||
(lex->charset ? lex->charset : default_charset_info),
|
||||
(lex->charset ? lex->charset :
|
||||
sp_db_info.default_table_charset),
|
||||
lex->uint_geom_type))
|
||||
return TRUE;
|
||||
|
||||
|
@ -193,9 +193,13 @@ public:
|
||||
void
|
||||
init(LEX *lex);
|
||||
|
||||
/* Copy sp name from parser. */
|
||||
void
|
||||
init_sp_name(THD *thd, sp_name *spname);
|
||||
|
||||
// Initialize strings after parsing header
|
||||
void
|
||||
init_strings(THD *thd, LEX *lex, sp_name *name);
|
||||
init_strings(THD *thd, LEX *lex);
|
||||
|
||||
int
|
||||
create(THD *thd);
|
||||
@ -206,6 +210,10 @@ public:
|
||||
void
|
||||
destroy();
|
||||
|
||||
bool
|
||||
execute_trigger(THD *thd, const char *db, const char *table,
|
||||
GRANT_INFO *grant_onfo);
|
||||
|
||||
bool
|
||||
execute_function(THD *thd, Item **args, uint argcount, Field *return_fld);
|
||||
|
||||
@ -1149,6 +1157,10 @@ sp_change_security_context(THD *thd, sp_head *sp,
|
||||
Security_context **backup);
|
||||
void
|
||||
sp_restore_security_context(THD *thd, Security_context *backup);
|
||||
|
||||
bool
|
||||
set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc,
|
||||
Security_context **save_ctx);
|
||||
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
|
||||
|
||||
TABLE_LIST *
|
||||
|
@ -295,7 +295,6 @@ static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
|
||||
create Where to store the read options
|
||||
|
||||
DESCRIPTION
|
||||
For now, only default-character-set is read.
|
||||
|
||||
RETURN VALUES
|
||||
0 File found
|
||||
@ -383,6 +382,50 @@ err1:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Retrieve database options by name. Load database options file or fetch from
|
||||
cache.
|
||||
|
||||
SYNOPSIS
|
||||
load_db_opt_by_name()
|
||||
db_name Database name
|
||||
db_create_info Where to store the database options
|
||||
|
||||
DESCRIPTION
|
||||
load_db_opt_by_name() is a shortcut for load_db_opt().
|
||||
|
||||
NOTE
|
||||
Although load_db_opt_by_name() (and load_db_opt()) returns status of
|
||||
the operation, it is useless usually and should be ignored. The problem
|
||||
is that there are 1) system databases ("mysql") and 2) virtual
|
||||
databases ("information_schema"), which do not contain options file.
|
||||
So, load_db_opt[_by_name]() returns FALSE for these databases, but this
|
||||
is not an error.
|
||||
|
||||
load_db_opt[_by_name]() clears db_create_info structure in any case, so
|
||||
even on failure it contains valid data. So, common use case is just
|
||||
call load_db_opt[_by_name]() without checking return value and use
|
||||
db_create_info right after that.
|
||||
|
||||
RETURN VALUES (read NOTE!)
|
||||
FALSE Success
|
||||
TRUE Failed to retrieve options
|
||||
*/
|
||||
|
||||
bool load_db_opt_by_name(THD *thd, const char *db_name,
|
||||
HA_CREATE_INFO *db_create_info)
|
||||
{
|
||||
char db_opt_path[FN_REFLEN];
|
||||
|
||||
strxnmov(db_opt_path, sizeof (db_opt_path) - 1, mysql_data_home, "/",
|
||||
db_name, "/", MY_DB_OPT_FILE, NullS);
|
||||
|
||||
unpack_filename(db_opt_path, db_opt_path);
|
||||
|
||||
return load_db_opt(thd, db_opt_path, db_create_info);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Create a database
|
||||
|
||||
@ -1126,8 +1169,6 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
|
||||
{
|
||||
int path_length, db_length;
|
||||
char *db_name;
|
||||
char path[FN_REFLEN];
|
||||
HA_CREATE_INFO create;
|
||||
bool system_db= 0;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
ulong db_access;
|
||||
@ -1196,16 +1237,14 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
(void) sprintf(path,"%s/%s", mysql_data_home, db_name);
|
||||
path_length= unpack_dirname(path, path); // Convert if not UNIX
|
||||
if (path_length && path[path_length-1] == FN_LIBCHAR)
|
||||
path[path_length-1]= '\0'; // remove ending '\'
|
||||
if (my_access(path,F_OK))
|
||||
|
||||
if (check_db_dir_existence(db_name))
|
||||
{
|
||||
my_error(ER_BAD_DB_ERROR, MYF(0), db_name);
|
||||
my_free(db_name, MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
end:
|
||||
x_free(thd->db);
|
||||
DBUG_ASSERT(db_name == NULL || db_name[0] != '\0');
|
||||
@ -1221,8 +1260,10 @@ end:
|
||||
}
|
||||
else
|
||||
{
|
||||
strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE);
|
||||
load_db_opt(thd, path, &create);
|
||||
HA_CREATE_INFO create;
|
||||
|
||||
load_db_opt_by_name(thd, db_name, &create);
|
||||
|
||||
thd->db_charset= create.default_table_charset ?
|
||||
create.default_table_charset :
|
||||
thd->variables.collation_server;
|
||||
@ -1230,3 +1271,36 @@ end:
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Check if there is directory for the database name.
|
||||
|
||||
SYNOPSIS
|
||||
check_db_dir_existence()
|
||||
db_name database name
|
||||
|
||||
RETURN VALUES
|
||||
FALSE There is directory for the specified database name.
|
||||
TRUE The directory does not exist.
|
||||
*/
|
||||
|
||||
bool check_db_dir_existence(const char *db_name)
|
||||
{
|
||||
char db_dir_path[FN_REFLEN];
|
||||
uint db_dir_path_len;
|
||||
|
||||
strxnmov(db_dir_path, sizeof (db_dir_path) - 1, mysql_data_home, "/",
|
||||
db_name, NullS);
|
||||
|
||||
db_dir_path_len= unpack_dirname(db_dir_path, db_dir_path);
|
||||
|
||||
/* Remove trailing '/' or '\' if exists. */
|
||||
|
||||
if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
|
||||
db_dir_path[db_dir_path_len - 1]= 0;
|
||||
|
||||
/* Check access. */
|
||||
|
||||
return my_access(db_dir_path, F_OK);
|
||||
}
|
||||
|
@ -126,6 +126,7 @@ void lex_start(THD *thd, uchar *buf,uint length)
|
||||
lex->param_list.empty();
|
||||
lex->view_list.empty();
|
||||
lex->prepared_stmt_params.empty();
|
||||
lex->auxiliary_table_list.empty();
|
||||
lex->unit.next= lex->unit.master=
|
||||
lex->unit.link_next= lex->unit.return_to= 0;
|
||||
lex->unit.prev= lex->unit.link_prev= 0;
|
||||
@ -1053,6 +1054,30 @@ int MYSQLlex(void *arg, void *yythd)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Skip comment in the end of statement.
|
||||
|
||||
SYNOPSIS
|
||||
skip_rear_comments()
|
||||
begin pointer to the beginning of statement
|
||||
end pointer to the end of statement
|
||||
|
||||
DESCRIPTION
|
||||
The function is intended to trim comments at the end of the statement.
|
||||
|
||||
RETURN
|
||||
Pointer to the last non-comment symbol of the statement.
|
||||
*/
|
||||
|
||||
uchar *skip_rear_comments(uchar *begin, uchar *end)
|
||||
{
|
||||
while (begin < end && (end[-1] <= ' ' || end[-1] == '*' ||
|
||||
end[-1] == '/' || end[-1] == ';'))
|
||||
end-= 1;
|
||||
return end;
|
||||
}
|
||||
|
||||
/*
|
||||
st_select_lex structures initialisations
|
||||
*/
|
||||
|
@ -1115,4 +1115,4 @@ extern void lex_free(void);
|
||||
extern void lex_start(THD *thd, uchar *buf,uint length);
|
||||
extern void lex_end(LEX *lex);
|
||||
extern int MYSQLlex(void *arg, void *yythd);
|
||||
|
||||
extern uchar *skip_rear_comments(uchar *begin, uchar *end);
|
||||
|
@ -4413,9 +4413,6 @@ end_with_restore_list:
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
Security_context *save_ctx;
|
||||
#endif
|
||||
ha_rows select_limit;
|
||||
/* bits that should be cleared in thd->server_status */
|
||||
uint bits_to_be_cleared= 0;
|
||||
@ -4457,21 +4454,11 @@ end_with_restore_list:
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (check_routine_access(thd, EXECUTE_ACL,
|
||||
sp->m_db.str, sp->m_name.str, TRUE, 0) ||
|
||||
sp_change_security_context(thd, sp, &save_ctx))
|
||||
sp->m_db.str, sp->m_name.str, TRUE, FALSE))
|
||||
{
|
||||
thd->net.no_send_ok= nsok;
|
||||
goto error;
|
||||
}
|
||||
if (save_ctx &&
|
||||
check_routine_access(thd, EXECUTE_ACL,
|
||||
sp->m_db.str, sp->m_name.str, TRUE, 0))
|
||||
{
|
||||
thd->net.no_send_ok= nsok;
|
||||
sp_restore_security_context(thd, save_ctx);
|
||||
goto error;
|
||||
}
|
||||
|
||||
#endif
|
||||
select_limit= thd->variables.select_limit;
|
||||
thd->variables.select_limit= HA_POS_ERROR;
|
||||
@ -4495,9 +4482,6 @@ end_with_restore_list:
|
||||
thd->total_warn_count= 0;
|
||||
|
||||
thd->variables.select_limit= select_limit;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
sp_restore_security_context(thd, save_ctx);
|
||||
#endif
|
||||
|
||||
thd->net.no_send_ok= nsok;
|
||||
thd->server_status&= ~bits_to_be_cleared;
|
||||
|
@ -2128,29 +2128,21 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
|
||||
they have their own table list).
|
||||
*/
|
||||
for (TABLE_LIST *tables= lex->query_tables;
|
||||
tables;
|
||||
tables= tables->next_global)
|
||||
tables;
|
||||
tables= tables->next_global)
|
||||
{
|
||||
tables->reinit_before_use(thd);
|
||||
}
|
||||
/*
|
||||
Cleanup of the special case of DELETE t1, t2 FROM t1, t2, t3 ...
|
||||
(multi-delete). We do a full clean up, although at the moment all we
|
||||
need to clean in the tables of MULTI-DELETE list is 'table' member.
|
||||
*/
|
||||
for (TABLE_LIST *tables= (TABLE_LIST*) lex->auxiliary_table_list.first;
|
||||
tables;
|
||||
tables= tables->next_global)
|
||||
{
|
||||
/*
|
||||
Reset old pointers to TABLEs: they are not valid since the tables
|
||||
were closed in the end of previous prepare or execute call.
|
||||
*/
|
||||
tables->reinit_before_use(thd);
|
||||
|
||||
/* Reset is_schema_table_processed value(needed for I_S tables */
|
||||
tables->is_schema_table_processed= FALSE;
|
||||
|
||||
TABLE_LIST *embedded; /* The table at the current level of nesting. */
|
||||
TABLE_LIST *embedding= tables; /* The parent nested table reference. */
|
||||
do
|
||||
{
|
||||
embedded= embedding;
|
||||
if (embedded->prep_on_expr)
|
||||
embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
|
||||
embedding= embedded->embedding;
|
||||
}
|
||||
while (embedding &&
|
||||
embedding->nested_join->join_list.head() == embedded);
|
||||
}
|
||||
lex->current_select= &lex->select_lex;
|
||||
|
||||
@ -2165,7 +2157,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
|
||||
}
|
||||
lex->allow_sum_func= 0;
|
||||
lex->in_sum_func= NULL;
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
121
sql/sql_show.cc
121
sql/sql_show.cc
@ -250,9 +250,35 @@ bool mysqld_show_column_types(THD *thd)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
|
||||
const char *wild, bool dir)
|
||||
/*
|
||||
find_files() - find files in a given directory.
|
||||
|
||||
SYNOPSIS
|
||||
find_files()
|
||||
thd thread handler
|
||||
files put found files in this list
|
||||
db database name to set in TABLE_LIST structure
|
||||
path path to database
|
||||
wild filter for found files
|
||||
dir read databases in path if TRUE, read .frm files in
|
||||
database otherwise
|
||||
|
||||
RETURN
|
||||
FIND_FILES_OK success
|
||||
FIND_FILES_OOM out of memory error
|
||||
FIND_FILES_DIR no such directory, or directory can't be read
|
||||
*/
|
||||
|
||||
enum find_files_result {
|
||||
FIND_FILES_OK,
|
||||
FIND_FILES_OOM,
|
||||
FIND_FILES_DIR
|
||||
};
|
||||
|
||||
static
|
||||
find_files_result
|
||||
find_files(THD *thd, List<char> *files, const char *db,
|
||||
const char *path, const char *wild, bool dir)
|
||||
{
|
||||
uint i;
|
||||
char *ext;
|
||||
@ -262,7 +288,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
|
||||
uint col_access=thd->col_access;
|
||||
#endif
|
||||
TABLE_LIST table_list;
|
||||
DBUG_ENTER("mysql_find_files");
|
||||
DBUG_ENTER("find_files");
|
||||
|
||||
if (wild && !wild[0])
|
||||
wild=0;
|
||||
@ -275,7 +301,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
|
||||
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db);
|
||||
else
|
||||
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno);
|
||||
DBUG_RETURN(-1);
|
||||
DBUG_RETURN(FIND_FILES_DIR);
|
||||
}
|
||||
|
||||
for (i=0 ; i < (uint) dirp->number_off_files ; i++)
|
||||
@ -337,7 +363,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
|
||||
if (files->push_back(thd->strdup(file->name)))
|
||||
{
|
||||
my_dirend(dirp);
|
||||
DBUG_RETURN(-1);
|
||||
DBUG_RETURN(FIND_FILES_OOM);
|
||||
}
|
||||
}
|
||||
DBUG_PRINT("info",("found: %d files", files->elements));
|
||||
@ -345,7 +371,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
|
||||
|
||||
VOID(ha_find_files(thd,db,path,wild,dir,files));
|
||||
|
||||
DBUG_RETURN(0);
|
||||
DBUG_RETURN(FIND_FILES_OK);
|
||||
}
|
||||
|
||||
|
||||
@ -439,13 +465,11 @@ bool mysqld_show_create_db(THD *thd, char *dbname,
|
||||
{
|
||||
Security_context *sctx= thd->security_ctx;
|
||||
int length;
|
||||
char path[FN_REFLEN];
|
||||
char buff[2048];
|
||||
String buffer(buff, sizeof(buff), system_charset_info);
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
uint db_access;
|
||||
#endif
|
||||
bool found_libchar;
|
||||
HA_CREATE_INFO create;
|
||||
uint create_options = create_info ? create_info->options : 0;
|
||||
Protocol *protocol=thd->protocol;
|
||||
@ -480,23 +504,13 @@ bool mysqld_show_create_db(THD *thd, char *dbname,
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) sprintf(path,"%s/%s",mysql_data_home, dbname);
|
||||
length=unpack_dirname(path,path); // Convert if not unix
|
||||
found_libchar= 0;
|
||||
if (length && path[length-1] == FN_LIBCHAR)
|
||||
{
|
||||
found_libchar= 1;
|
||||
path[length-1]=0; // remove ending '\'
|
||||
}
|
||||
if (access(path,F_OK))
|
||||
if (check_db_dir_existence(dbname))
|
||||
{
|
||||
my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (found_libchar)
|
||||
path[length-1]= FN_LIBCHAR;
|
||||
strmov(path+length, MY_DB_OPT_FILE);
|
||||
load_db_opt(thd, path, &create);
|
||||
|
||||
load_db_opt_by_name(thd, dbname, &create);
|
||||
}
|
||||
List<Item> field_list;
|
||||
field_list.push_back(new Item_empty_string("Database",NAME_LEN));
|
||||
@ -2000,8 +2014,8 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
|
||||
wild string otherwise it's db name;
|
||||
|
||||
RETURN
|
||||
1 error
|
||||
0 success
|
||||
zero success
|
||||
non-zero error
|
||||
*/
|
||||
|
||||
int make_db_list(THD *thd, List<char> *files,
|
||||
@ -2027,8 +2041,8 @@ int make_db_list(THD *thd, List<char> *files,
|
||||
if (files->push_back(thd->strdup(information_schema_name.str)))
|
||||
return 1;
|
||||
}
|
||||
return mysql_find_files(thd, files, NullS, mysql_data_home,
|
||||
idx_field_vals->db_value, 1);
|
||||
return (find_files(thd, files, NullS, mysql_data_home,
|
||||
idx_field_vals->db_value, 1) != FIND_FILES_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2055,7 +2069,8 @@ int make_db_list(THD *thd, List<char> *files,
|
||||
if (files->push_back(thd->strdup(information_schema_name.str)))
|
||||
return 1;
|
||||
*with_i_schema= 1;
|
||||
return mysql_find_files(thd, files, NullS, mysql_data_home, NullS, 1);
|
||||
return (find_files(thd, files, NullS,
|
||||
mysql_data_home, NullS, 1) != FIND_FILES_OK);
|
||||
}
|
||||
|
||||
|
||||
@ -2204,9 +2219,28 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||
strxmov(path, mysql_data_home, "/", base_name, NullS);
|
||||
end= path + (len= unpack_dirname(path,path));
|
||||
len= FN_LEN - len;
|
||||
if (mysql_find_files(thd, &files, base_name,
|
||||
path, idx_field_vals.table_value, 0))
|
||||
goto err;
|
||||
find_files_result res= find_files(thd, &files, base_name,
|
||||
path, idx_field_vals.table_value, 0);
|
||||
if (res != FIND_FILES_OK)
|
||||
{
|
||||
/*
|
||||
Downgrade errors about problems with database directory to
|
||||
warnings if this is not a 'SHOW' command. Another thread
|
||||
may have dropped database, and we may still have a name
|
||||
for that directory.
|
||||
*/
|
||||
if (res == FIND_FILES_DIR && lex->orig_sql_command == SQLCOM_END)
|
||||
{
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
thd->net.last_errno, thd->net.last_error);
|
||||
thd->clear_error();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (lower_case_table_names)
|
||||
orig_base_name= thd->strdup(base_name);
|
||||
}
|
||||
@ -2319,8 +2353,11 @@ bool store_schema_shemata(THD* thd, TABLE *table, const char *db_name,
|
||||
|
||||
int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||
{
|
||||
char path[FN_REFLEN];
|
||||
bool found_libchar;
|
||||
/*
|
||||
TODO: fill_schema_shemata() is called when new client is connected.
|
||||
Returning error status in this case leads to client hangup.
|
||||
*/
|
||||
|
||||
INDEX_FIELD_VALUES idx_field_vals;
|
||||
List<char> files;
|
||||
char *file_name;
|
||||
@ -2352,20 +2389,9 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||
(grant_option && !check_grant_db(thd, file_name)))
|
||||
#endif
|
||||
{
|
||||
strxmov(path, mysql_data_home, "/", file_name, NullS);
|
||||
length=unpack_dirname(path,path); // Convert if not unix
|
||||
found_libchar= 0;
|
||||
if (length && path[length-1] == FN_LIBCHAR)
|
||||
{
|
||||
found_libchar= 1;
|
||||
path[length-1]=0; // remove ending '\'
|
||||
}
|
||||
load_db_opt_by_name(thd, file_name, &create);
|
||||
|
||||
if (found_libchar)
|
||||
path[length-1]= FN_LIBCHAR;
|
||||
strmov(path+length, MY_DB_OPT_FILE);
|
||||
load_db_opt(thd, path, &create);
|
||||
if (store_schema_shemata(thd, table, file_name,
|
||||
if (store_schema_shemata(thd, table, file_name,
|
||||
create.default_table_charset))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
@ -3969,7 +3995,12 @@ bool get_schema_tables_result(JOIN *join)
|
||||
|
||||
if (table_list->schema_table->fill_table(thd, table_list,
|
||||
tab->select_cond))
|
||||
{
|
||||
result= 1;
|
||||
join->error= 1;
|
||||
table_list->is_schema_table_processed= TRUE;
|
||||
break;
|
||||
}
|
||||
table_list->is_schema_table_processed= TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -1631,10 +1631,9 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
|
||||
if (!create_info->default_table_charset)
|
||||
{
|
||||
HA_CREATE_INFO db_info;
|
||||
char path[FN_REFLEN];
|
||||
/* Abuse build_table_path() to build the path to the db.opt file */
|
||||
build_table_path(path, sizeof(path), db, MY_DB_OPT_FILE, "");
|
||||
load_db_opt(thd, path, &db_info);
|
||||
|
||||
load_db_opt_by_name(thd, db, &db_info);
|
||||
|
||||
create_info->default_table_charset= db_info.default_table_charset;
|
||||
}
|
||||
|
||||
|
@ -295,7 +295,10 @@ end:
|
||||
append_definer(thd, &log_query, &definer_user, &definer_host);
|
||||
}
|
||||
|
||||
log_query.append(thd->lex->stmt_definition_begin);
|
||||
log_query.append(thd->lex->stmt_definition_begin,
|
||||
(char *)thd->lex->sphead->m_body_begin -
|
||||
thd->lex->stmt_definition_begin +
|
||||
thd->lex->sphead->m_body.length);
|
||||
}
|
||||
|
||||
/* Such a statement can always go directly to binlog, no trans cache. */
|
||||
@ -1503,40 +1506,11 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
|
||||
old_field= table->field;
|
||||
}
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
Security_context *save_ctx;
|
||||
|
||||
if (sp_change_security_context(thd, sp_trigger, &save_ctx))
|
||||
return TRUE;
|
||||
|
||||
/*
|
||||
NOTE: TRIGGER_ACL should be used below.
|
||||
*/
|
||||
|
||||
if (check_global_access(thd, SUPER_ACL))
|
||||
{
|
||||
sp_restore_security_context(thd, save_ctx);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
Fetch information about table-level privileges to GRANT_INFO structure for
|
||||
subject table. Check of privileges that will use it and information about
|
||||
column-level privileges will happen in Item_trigger_field::fix_fields().
|
||||
*/
|
||||
|
||||
fill_effective_table_privileges(thd,
|
||||
&subject_table_grants[event][time_type],
|
||||
table->s->db, table->s->table_name);
|
||||
#endif // NO_EMBEDDED_ACCESS_CHECKS
|
||||
|
||||
thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER);
|
||||
err_status= sp_trigger->execute_function(thd, 0, 0, 0);
|
||||
err_status= sp_trigger->execute_trigger
|
||||
(thd, table->s->db, table->s->table_name,
|
||||
&subject_table_grants[event][time_type]);
|
||||
thd->restore_sub_statement_state(&statement_state);
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
sp_restore_security_context(thd, save_ctx);
|
||||
#endif // NO_EMBEDDED_ACCESS_CHECKS
|
||||
}
|
||||
|
||||
return err_status;
|
||||
|
@ -671,8 +671,10 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
||||
view->query.str= (char*)str.ptr();
|
||||
view->query.length= str.length()-1; // we do not need last \0
|
||||
view->source.str= thd->query + thd->lex->create_view_select_start;
|
||||
view->source.length= (thd->query_length -
|
||||
thd->lex->create_view_select_start);
|
||||
view->source.length= (char *)skip_rear_comments((uchar *)view->source.str,
|
||||
(uchar *)thd->query +
|
||||
thd->query_length) -
|
||||
view->source.str;
|
||||
view->file_version= 1;
|
||||
view->calc_md5(md5);
|
||||
view->md5.str= md5;
|
||||
|
@ -1256,6 +1256,17 @@ create_function_tail:
|
||||
RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING_sys
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
if (lex->definer != NULL)
|
||||
{
|
||||
/*
|
||||
DEFINER is a concept meaningful when interpreting SQL code.
|
||||
UDF functions are compiled.
|
||||
Using DEFINER with UDF has therefore no semantic,
|
||||
and is considered a parsing error.
|
||||
*/
|
||||
my_error(ER_WRONG_USAGE, MYF(0), "SONAME", "DEFINER");
|
||||
YYABORT;
|
||||
}
|
||||
lex->sql_command = SQLCOM_CREATE_FUNCTION;
|
||||
lex->udf.name = lex->spname->m_name;
|
||||
lex->udf.returns=(Item_result) $2;
|
||||
@ -1285,6 +1296,7 @@ create_function_tail:
|
||||
sp= new sp_head();
|
||||
sp->reset_thd_mem_root(YYTHD);
|
||||
sp->init(lex);
|
||||
sp->init_sp_name(YYTHD, lex->spname);
|
||||
|
||||
sp->m_type= TYPE_ENUM_FUNCTION;
|
||||
lex->sphead= sp;
|
||||
@ -1339,7 +1351,7 @@ create_function_tail:
|
||||
YYABORT;
|
||||
|
||||
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
|
||||
sp->init_strings(YYTHD, lex, lex->spname);
|
||||
sp->init_strings(YYTHD, lex);
|
||||
if (!(sp->m_flags & sp_head::HAS_RETURN))
|
||||
{
|
||||
my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
|
||||
@ -1911,9 +1923,12 @@ sp_proc_stmt:
|
||||
sp_instr_stmt *i=new sp_instr_stmt(sp->instructions(),
|
||||
lex->spcont, lex);
|
||||
|
||||
/* Extract the query statement from the tokenizer:
|
||||
The end is either lex->tok_end or tok->ptr. */
|
||||
if (lex->ptr - lex->tok_end > 1)
|
||||
/*
|
||||
Extract the query statement from the tokenizer. The
|
||||
end is either lex->ptr, if there was no lookahead,
|
||||
lex->tok_end otherwise.
|
||||
*/
|
||||
if (yychar == YYEMPTY)
|
||||
i->m_query.length= lex->ptr - sp->m_tmp_query;
|
||||
else
|
||||
i->m_query.length= lex->tok_end - sp->m_tmp_query;
|
||||
@ -7822,7 +7837,12 @@ option_type_value:
|
||||
lex)))
|
||||
YYABORT;
|
||||
|
||||
if (lex->ptr - lex->tok_end > 1)
|
||||
/*
|
||||
Extract the query statement from the tokenizer. The
|
||||
end is either lex->ptr, if there was no lookahead,
|
||||
lex->tok_end otherwise.
|
||||
*/
|
||||
if (yychar == YYEMPTY)
|
||||
qbuff.length= lex->ptr - sp->m_tmp_query;
|
||||
else
|
||||
qbuff.length= lex->tok_end - sp->m_tmp_query;
|
||||
@ -9092,6 +9112,7 @@ trigger_tail:
|
||||
YYABORT;
|
||||
sp->reset_thd_mem_root(YYTHD);
|
||||
sp->init(lex);
|
||||
sp->init_sp_name(YYTHD, $3);
|
||||
|
||||
lex->stmt_definition_begin= $2;
|
||||
lex->ident.str= $7;
|
||||
@ -9120,7 +9141,7 @@ trigger_tail:
|
||||
sp_head *sp= lex->sphead;
|
||||
|
||||
lex->sql_command= SQLCOM_CREATE_TRIGGER;
|
||||
sp->init_strings(YYTHD, lex, $3);
|
||||
sp->init_strings(YYTHD, lex);
|
||||
/* Restore flag if it was cleared above */
|
||||
if (sp->m_old_cmq)
|
||||
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
|
||||
@ -9168,13 +9189,14 @@ sp_tail:
|
||||
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "PROCEDURE");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
|
||||
lex->stmt_definition_begin= $2;
|
||||
|
||||
|
||||
/* Order is important here: new - reset - init */
|
||||
sp= new sp_head();
|
||||
sp->reset_thd_mem_root(YYTHD);
|
||||
sp->init(lex);
|
||||
sp->init_sp_name(YYTHD, $3);
|
||||
|
||||
sp->m_type= TYPE_ENUM_PROCEDURE;
|
||||
lex->sphead= sp;
|
||||
@ -9212,7 +9234,7 @@ sp_tail:
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
|
||||
sp->init_strings(YYTHD, lex, $3);
|
||||
sp->init_strings(YYTHD, lex);
|
||||
lex->sql_command= SQLCOM_CREATE_PROCEDURE;
|
||||
/* Restore flag if it was cleared above */
|
||||
if (sp->m_old_cmq)
|
||||
|
16
sql/table.cc
16
sql/table.cc
@ -2992,13 +2992,27 @@ Field_iterator_table_ref::get_natural_column_ref()
|
||||
st_table_list::reinit_before_use()
|
||||
*/
|
||||
|
||||
void st_table_list::reinit_before_use(THD * /* thd */)
|
||||
void st_table_list::reinit_before_use(THD *thd)
|
||||
{
|
||||
/*
|
||||
Reset old pointers to TABLEs: they are not valid since the tables
|
||||
were closed in the end of previous prepare or execute call.
|
||||
*/
|
||||
table= 0;
|
||||
/* Reset is_schema_table_processed value(needed for I_S tables */
|
||||
is_schema_table_processed= FALSE;
|
||||
|
||||
TABLE_LIST *embedded; /* The table at the current level of nesting. */
|
||||
TABLE_LIST *embedding= this; /* The parent nested table reference. */
|
||||
do
|
||||
{
|
||||
embedded= embedding;
|
||||
if (embedded->prep_on_expr)
|
||||
embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
|
||||
embedding= embedded->embedding;
|
||||
}
|
||||
while (embedding &&
|
||||
embedding->nested_join->join_list.head() == embedded);
|
||||
}
|
||||
|
||||
|
||||
|
@ -677,6 +677,10 @@ typedef struct st_table_list
|
||||
private:
|
||||
bool prep_check_option(THD *thd, uint8 check_opt_type);
|
||||
bool prep_where(THD *thd, Item **conds, bool no_where_clause);
|
||||
/*
|
||||
Cleanup for re-execution in a prepared statement or a stored
|
||||
procedure.
|
||||
*/
|
||||
} TABLE_LIST;
|
||||
|
||||
class Item;
|
||||
|
@ -50,7 +50,6 @@ static unsigned int opt_port;
|
||||
static my_bool tty_password= 0, opt_silent= 0;
|
||||
|
||||
static MYSQL *mysql= 0;
|
||||
static char query[MAX_TEST_QUERY_LENGTH];
|
||||
static char current_db[]= "client_test_db";
|
||||
static unsigned int test_count= 0;
|
||||
static unsigned int opt_count= 0;
|
||||
@ -270,6 +269,7 @@ mysql_simple_prepare(MYSQL *mysql, const char *query)
|
||||
static void client_connect(ulong flag)
|
||||
{
|
||||
int rc;
|
||||
static char query[MAX_TEST_QUERY_LENGTH];
|
||||
myheader_r("client_connect");
|
||||
|
||||
if (!opt_silent)
|
||||
@ -327,6 +327,8 @@ static void client_connect(ulong flag)
|
||||
|
||||
static void client_disconnect()
|
||||
{
|
||||
static char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader_r("client_disconnect");
|
||||
|
||||
if (mysql)
|
||||
@ -658,6 +660,7 @@ int my_stmt_result(const char *buff)
|
||||
static void verify_col_data(const char *table, const char *col,
|
||||
const char *exp_data)
|
||||
{
|
||||
static char query[MAX_TEST_QUERY_LENGTH];
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
int rc, field= 1;
|
||||
@ -1363,6 +1366,7 @@ static void test_prepare_insert_update()
|
||||
|
||||
for (cur_query= testcase; *cur_query; cur_query++)
|
||||
{
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
printf("\nRunning query: %s", *cur_query);
|
||||
strmov(query, *cur_query);
|
||||
stmt= mysql_simple_prepare(mysql, query);
|
||||
@ -1397,6 +1401,7 @@ static void test_prepare_simple()
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_prepare_simple");
|
||||
|
||||
@ -1467,6 +1472,7 @@ static void test_prepare_field_result()
|
||||
MYSQL_STMT *stmt;
|
||||
MYSQL_RES *result;
|
||||
int rc;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_prepare_field_result");
|
||||
|
||||
@ -1518,6 +1524,7 @@ static void test_prepare_syntax()
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_prepare_syntax");
|
||||
|
||||
@ -1559,6 +1566,7 @@ static void test_prepare()
|
||||
my_bool is_null[7];
|
||||
char llbuf[22];
|
||||
MYSQL_BIND bind[7];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_prepare");
|
||||
|
||||
@ -1732,6 +1740,7 @@ static void test_double_compare()
|
||||
MYSQL_RES *result;
|
||||
MYSQL_BIND bind[3];
|
||||
ulong length[3];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_double_compare");
|
||||
|
||||
@ -1814,6 +1823,7 @@ static void test_null()
|
||||
uint nData;
|
||||
MYSQL_BIND bind[2];
|
||||
my_bool is_null[2];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_null");
|
||||
|
||||
@ -1960,6 +1970,7 @@ static void test_ps_null_param()
|
||||
/* Execute several queries, all returning NULL in result. */
|
||||
for(cur_query= queries; *cur_query; cur_query++)
|
||||
{
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
strmov(query, *cur_query);
|
||||
stmt= mysql_simple_prepare(mysql, query);
|
||||
check_stmt(stmt);
|
||||
@ -1991,6 +2002,7 @@ static void test_fetch_null()
|
||||
MYSQL_BIND bind[11];
|
||||
ulong length[11];
|
||||
my_bool is_null[11];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_fetch_null");
|
||||
|
||||
@ -2219,6 +2231,7 @@ static void test_select()
|
||||
int nData= 1;
|
||||
MYSQL_BIND bind[2];
|
||||
ulong length[2];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_select");
|
||||
|
||||
@ -2290,6 +2303,7 @@ static void test_ps_conj_select()
|
||||
int32 int_data;
|
||||
char str_data[32];
|
||||
unsigned long str_length;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
myheader("test_ps_conj_select");
|
||||
|
||||
rc= mysql_query(mysql, "drop table if exists t1");
|
||||
@ -2347,6 +2361,7 @@ static void test_bug1115()
|
||||
MYSQL_BIND bind[1];
|
||||
ulong length[1];
|
||||
char szData[11];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_bug1115");
|
||||
|
||||
@ -2458,6 +2473,7 @@ static void test_bug1180()
|
||||
MYSQL_BIND bind[1];
|
||||
ulong length[1];
|
||||
char szData[11];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_select_bug");
|
||||
|
||||
@ -2548,6 +2564,7 @@ static void test_bug1644()
|
||||
int num;
|
||||
my_bool isnull;
|
||||
int rc, i;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_bug1644");
|
||||
|
||||
@ -2647,6 +2664,7 @@ static void test_select_show()
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_select_show");
|
||||
|
||||
@ -2715,6 +2733,7 @@ static void test_simple_update()
|
||||
MYSQL_RES *result;
|
||||
MYSQL_BIND bind[2];
|
||||
ulong length[2];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_simple_update");
|
||||
|
||||
@ -2792,6 +2811,7 @@ static void test_long_data()
|
||||
char *data= NullS;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_BIND bind[3];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_long_data");
|
||||
|
||||
@ -2878,6 +2898,7 @@ static void test_long_data_str()
|
||||
MYSQL_RES *result;
|
||||
MYSQL_BIND bind[2];
|
||||
my_bool is_null[2];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_long_data_str");
|
||||
|
||||
@ -2970,6 +2991,7 @@ static void test_long_data_str1()
|
||||
MYSQL_RES *result;
|
||||
MYSQL_BIND bind[2];
|
||||
MYSQL_FIELD *field;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_long_data_str1");
|
||||
|
||||
@ -3125,6 +3147,7 @@ static void test_long_data_bin()
|
||||
long length;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_BIND bind[2];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
|
||||
myheader("test_long_data_bin");
|
||||
@ -3204,6 +3227,7 @@ static void test_simple_delete()
|
||||
MYSQL_RES *result;
|
||||
MYSQL_BIND bind[2];
|
||||
ulong length[2];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_simple_delete");
|
||||
|
||||
@ -3286,6 +3310,7 @@ static void test_update()
|
||||
MYSQL_RES *result;
|
||||
MYSQL_BIND bind[2];
|
||||
ulong length[2];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_update");
|
||||
|
||||
@ -3382,6 +3407,7 @@ static void test_prepare_noparam()
|
||||
MYSQL_STMT *stmt;
|
||||
int rc;
|
||||
MYSQL_RES *result;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_prepare_noparam");
|
||||
|
||||
@ -4238,6 +4264,7 @@ static void test_prepare_ext()
|
||||
short sData= 10;
|
||||
longlong bData= 20;
|
||||
MYSQL_BIND bind[6];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
myheader("test_prepare_ext");
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_ext");
|
||||
@ -4625,6 +4652,7 @@ static void test_stmt_close()
|
||||
MYSQL_RES *result;
|
||||
unsigned int count;
|
||||
int rc;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_stmt_close");
|
||||
|
||||
@ -5271,6 +5299,7 @@ static void test_manual_sample()
|
||||
ulonglong affected_rows;
|
||||
MYSQL_BIND bind[3];
|
||||
my_bool is_null;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_manual_sample");
|
||||
|
||||
@ -5625,6 +5654,7 @@ static void test_prepare_multi_statements()
|
||||
{
|
||||
MYSQL *mysql_local;
|
||||
MYSQL_STMT *stmt;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
myheader("test_prepare_multi_statements");
|
||||
|
||||
if (!(mysql_local= mysql_init(NULL)))
|
||||
@ -5842,6 +5872,7 @@ static void test_store_result2()
|
||||
int nData;
|
||||
ulong length;
|
||||
MYSQL_BIND bind[1];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_store_result2");
|
||||
|
||||
@ -7121,6 +7152,7 @@ static void test_set_option()
|
||||
static void test_prepare_grant()
|
||||
{
|
||||
int rc;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_prepare_grant");
|
||||
|
||||
@ -8593,6 +8625,7 @@ static void test_sqlmode()
|
||||
MYSQL_BIND bind[2];
|
||||
char c1[5], c2[5];
|
||||
int rc;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_sqlmode");
|
||||
|
||||
@ -8736,6 +8769,7 @@ static void test_ts()
|
||||
ulong length;
|
||||
int rc, field_count;
|
||||
char name;
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
myheader("test_ts");
|
||||
|
||||
@ -15027,6 +15061,65 @@ static void test_bug20152()
|
||||
}
|
||||
}
|
||||
|
||||
/* Bug#15752 "Lost connection to MySQL server when calling a SP from C API" */
|
||||
|
||||
static void test_bug15752()
|
||||
{
|
||||
MYSQL mysql_local;
|
||||
int rc, i;
|
||||
const int ITERATION_COUNT= 100;
|
||||
char *query= "CALL p1()";
|
||||
|
||||
myheader("test_bug15752");
|
||||
|
||||
rc= mysql_query(mysql, "drop procedure if exists p1");
|
||||
myquery(rc);
|
||||
rc= mysql_query(mysql, "create procedure p1() select 1");
|
||||
myquery(rc);
|
||||
|
||||
mysql_init(&mysql_local);
|
||||
if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
|
||||
opt_password, current_db, opt_port,
|
||||
opt_unix_socket,
|
||||
CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS))
|
||||
{
|
||||
printf("Unable connect to MySQL server: %s\n", mysql_error(&mysql_local));
|
||||
DIE_UNLESS(0);
|
||||
}
|
||||
rc= mysql_real_query(&mysql_local, query, strlen(query));
|
||||
myquery(rc);
|
||||
mysql_free_result(mysql_store_result(&mysql_local));
|
||||
|
||||
rc= mysql_real_query(&mysql_local, query, strlen(query));
|
||||
DIE_UNLESS(rc && mysql_errno(&mysql_local) == CR_COMMANDS_OUT_OF_SYNC);
|
||||
|
||||
if (! opt_silent)
|
||||
printf("Got error (as expected): %s\n", mysql_error(&mysql_local));
|
||||
|
||||
/* Check some other commands too */
|
||||
|
||||
DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
|
||||
mysql_free_result(mysql_store_result(&mysql_local));
|
||||
DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
|
||||
|
||||
/* The second problem is not reproducible: add the test case */
|
||||
for (i = 0; i < ITERATION_COUNT; i++)
|
||||
{
|
||||
if (mysql_real_query(&mysql_local, query, strlen(query)))
|
||||
{
|
||||
printf("\ni=%d %s failed: %s\n", i, query, mysql_error(&mysql_local));
|
||||
break;
|
||||
}
|
||||
mysql_free_result(mysql_store_result(&mysql_local));
|
||||
DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
|
||||
mysql_free_result(mysql_store_result(&mysql_local));
|
||||
DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
|
||||
|
||||
}
|
||||
mysql_close(&mysql_local);
|
||||
rc= mysql_query(mysql, "drop procedure p1");
|
||||
myquery(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
Bug#21206: memory corruption when too many cursors are opened at once
|
||||
@ -15342,7 +15435,8 @@ static struct my_tests_st my_tests[]= {
|
||||
{ "test_bug20152", test_bug20152 },
|
||||
{ "test_bug14169", test_bug14169 },
|
||||
{ "test_bug17667", test_bug17667 },
|
||||
{ "test_bug19671", test_bug19671},
|
||||
{ "test_bug19671", test_bug19671 },
|
||||
{ "test_bug15752", test_bug15752 },
|
||||
{ "test_bug21206", test_bug21206},
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user