Commit 2482c597 authored by malff/marcsql@weblab.(none)'s avatar malff/marcsql@weblab.(none)

Merge weblab.(none):/home/marcsql/TREE/mysql-5.1-base

into  weblab.(none):/home/marcsql/TREE/mysql-5.1-rt50-merge
parents 52ae4496 7ed3555c
...@@ -105,7 +105,7 @@ if [ "x$warning_mode" != "xpedantic" ]; then ...@@ -105,7 +105,7 @@ if [ "x$warning_mode" != "xpedantic" ]; then
# Added unless --with-debug=full # Added unless --with-debug=full
debug_extra_cflags="-O1 -Wuninitialized" debug_extra_cflags="-O1 -Wuninitialized"
else else
warnings="-W -Wall -ansi -pedantic -Wno-long-long -D_POSIX_SOURCE" warnings="-W -Wall -ansi -pedantic -Wno-long-long -Wno-unused -D_POSIX_SOURCE"
c_warnings="$warnings" c_warnings="$warnings"
cxx_warnings="$warnings -std=c++98" cxx_warnings="$warnings -std=c++98"
# NOTE: warning mode should not influence optimize/debug mode. # NOTE: warning mode should not influence optimize/debug mode.
...@@ -207,3 +207,28 @@ then ...@@ -207,3 +207,28 @@ then
echo "$CC" | grep "ccache" > /dev/null || CC="ccache $CC" echo "$CC" | grep "ccache" > /dev/null || CC="ccache $CC"
echo "$CXX" | grep "ccache" > /dev/null || CXX="ccache $CXX" echo "$CXX" | grep "ccache" > /dev/null || CXX="ccache $CXX"
fi fi
# gcov
# The -fprofile-arcs and -ftest-coverage options cause GCC to instrument the
# code with profiling information used by gcov.
# The -DDISABLE_TAO_ASM is needed to avoid build failures in Yassl.
# The -DHAVE_gcov enables code to write out coverage info even when crashing.
gcov_compile_flags="-fprofile-arcs -ftest-coverage"
gcov_compile_flags="$gcov_compile_flags -DDISABLE_TAO_ASM"
gcov_compile_flags="$gcov_compile_flags -DMYSQL_SERVER_SUFFIX=-gcov -DHAVE_gcov"
# GCC4 needs -fprofile-arcs -ftest-coverage on the linker command line (as well
# as on the compiler command line), and this requires setting LDFLAGS for BDB.
gcov_link_flags="-fprofile-arcs -ftest-coverage"
gcov_configs="--disable-shared"
# gprof
gprof_compile_flags="-O2 -pg -g"
gprof_link_flags="--disable-shared $static_link"
#! /bin/sh
path=`dirname $0`
. "$path/SETUP.sh"
# Need to disable ccache, or we loose the gcov-needed compiler output files.
CCACHE_DISABLE=1
export CCACHE_DISABLE
export LDFLAGS="$gcov_link_flags"
extra_flags="$amd64_cflags $debug_cflags $max_cflags $gcov_compile_flags"
c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$amd64_configs $debug_configs $gcov_configs $max_configs"
. "$path/FINISH.sh"
#! /bin/sh
path=`dirname $0`
. "$path/SETUP.sh"
extra_flags="$amd64_cflags $gprof_compile_flags"
extra_configs="$amd64_configs $debug_configs $gprof_link_flags"
. "$path/FINISH.sh"
...@@ -20,18 +20,11 @@ export CCACHE_GCOV_VERSION_ENABLED ...@@ -20,18 +20,11 @@ export CCACHE_GCOV_VERSION_ENABLED
path=`dirname $0` path=`dirname $0`
. "$path/SETUP.sh" . "$path/SETUP.sh"
# GCC4 needs -fprofile-arcs -ftest-coverage on the linker command line (as well export LDFLAGS="$gcov_link_flags"
# as on the compiler command line), and this requires setting LDFLAGS for BDB.
export LDFLAGS="-fprofile-arcs -ftest-coverage"
# The -fprofile-arcs and -ftest-coverage options cause GCC to instrument the extra_flags="$pentium_cflags $debug_cflags $max_cflags $gcov_compile_flags"
# code with profiling information used by gcov.
# The -DDISABLE_TAO_ASM is needed to avoid build failures in Yassl.
# The -DHAVE_gcov enables code to write out coverage info even when crashing.
extra_flags="$pentium_cflags -fprofile-arcs -ftest-coverage -DDISABLE_TAO_ASM -DHAVE_MUTEX_THREAD_ONLY $debug_extra_flags $debug_cflags $max_cflags -DMYSQL_SERVER_SUFFIX=-gcov -DHAVE_gcov"
extra_configs="$pentium_configs $debug_configs --disable-shared $static_link"
extra_configs="$extra_configs $max_configs"
c_warnings="$c_warnings $debug_extra_warnings" c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium_configs $debug_configs $gcov_configs $max_configs"
. "$path/FINISH.sh" . "$path/FINISH.sh"
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
path=`dirname $0` path=`dirname $0`
. "$path/SETUP.sh" . "$path/SETUP.sh"
extra_flags="$pentium_cflags -O2 -pg -g" extra_flags="$pentium_cflags $gprof_compile_flags"
extra_configs="$pentium_configs $debug_configs --disable-shared $static_link" extra_configs="$pentium_configs $debug_configs $gprof_link_flags"
. "$path/FINISH.sh" . "$path/FINISH.sh"
#! /bin/sh
path=`dirname $0`
. "$path/SETUP.sh"
# Need to disable ccache, or we loose the gcov-needed compiler output files.
CCACHE_DISABLE=1
export CCACHE_DISABLE
export LDFLAGS="$gcov_link_flags"
extra_flags="$pentium64_cflags $debug_cflags $max_cflags $gcov_compile_flags"
c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium64_configs $debug_configs $gcov_configs $max_configs"
. "$path/FINISH.sh"
#! /bin/sh
path=`dirname $0`
. "$path/SETUP.sh"
extra_flags="$pentium64_cflags $gprof_compile_flags"
extra_configs="$pentium64_configs $debug_configs $gprof_link_flags"
. "$path/FINISH.sh"
...@@ -1263,6 +1263,7 @@ static bool add_line(String &buffer,char *line,char *in_string, ...@@ -1263,6 +1263,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
char buff[80], *pos, *out; char buff[80], *pos, *out;
COMMANDS *com; COMMANDS *com;
bool need_space= 0; bool need_space= 0;
bool ss_comment= 0;
DBUG_ENTER("add_line"); DBUG_ENTER("add_line");
if (!line[0] && buffer.is_empty()) if (!line[0] && buffer.is_empty())
...@@ -1316,6 +1317,19 @@ static bool add_line(String &buffer,char *line,char *in_string, ...@@ -1316,6 +1317,19 @@ static bool add_line(String &buffer,char *line,char *in_string,
if ((*com->func)(&buffer,pos-1) > 0) if ((*com->func)(&buffer,pos-1) > 0)
DBUG_RETURN(1); // Quit DBUG_RETURN(1); // Quit
if (com->takes_params) if (com->takes_params)
{
if (ss_comment)
{
/*
If a client-side macro appears inside a server-side comment,
discard all characters in the comment after the macro (that is,
until the end of the comment rather than the next delimiter)
*/
for (pos++; *pos && (*pos != '*' || *(pos + 1) != '/'); pos++)
;
pos--;
}
else
{ {
for (pos++ ; for (pos++ ;
*pos && (*pos != *delimiter || *pos && (*pos != *delimiter ||
...@@ -1326,6 +1340,7 @@ static bool add_line(String &buffer,char *line,char *in_string, ...@@ -1326,6 +1340,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
else else
pos+= delimiter_length - 1; // Point at last delim char pos+= delimiter_length - 1; // Point at last delim char
} }
}
out=line; out=line;
} }
else else
...@@ -1386,7 +1401,7 @@ static bool add_line(String &buffer,char *line,char *in_string, ...@@ -1386,7 +1401,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
out=line; out=line;
} }
} }
else if (*ml_comment && inchar == '*' && *(pos + 1) == '/') else if (*ml_comment && !ss_comment && inchar == '*' && *(pos + 1) == '/')
{ {
pos++; pos++;
*ml_comment= 0; *ml_comment= 0;
...@@ -1394,6 +1409,11 @@ static bool add_line(String &buffer,char *line,char *in_string, ...@@ -1394,6 +1409,11 @@ static bool add_line(String &buffer,char *line,char *in_string,
} }
else else
{ // Add found char to buffer { // Add found char to buffer
if (!*in_string && inchar == '/' && *(pos + 1) == '*' &&
*(pos + 2) == '!')
ss_comment= 1;
else if (!*in_string && ss_comment && inchar == '*' && *(pos + 1) == '/')
ss_comment= 0;
if (inchar == *in_string) if (inchar == *in_string)
*in_string= 0; *in_string= 0;
else if (!*ml_comment && !*in_string && else if (!*ml_comment && !*in_string &&
......
...@@ -144,4 +144,29 @@ disconnect con1; ...@@ -144,4 +144,29 @@ disconnect con1;
disconnect con2; disconnect con2;
drop table t1, t2; drop table t1, t2;
# End of 4.1 tests --echo End of 4.1 tests
#
# Bug#25164 create table `a` as select * from `A` hangs
#
set storage_engine=innodb;
--disable_warnings
drop table if exists a;
drop table if exists A;
--enable_warnings
create table A (c int);
insert into A (c) values (0);
--error 0,ER_LOCK_DEADLOCK,ER_UPDATE_TABLE_USED
create table a as select * from A;
drop table A;
--disable_warnings
drop table if exists a;
--enable_warnings
set storage_engine=default;
--echo End of 5.0 tests.
...@@ -479,3 +479,22 @@ handler t1 open; ...@@ -479,3 +479,22 @@ handler t1 open;
--echo --> client 1 --echo --> client 1
connection default; connection default;
drop table t1; drop table t1;
#
# Bug#30632 HANDLER read failure causes hang
#
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
handler t1 open as t1_alias;
--error 1176
handler t1_alias read a next;
--error 1054
handler t1_alias READ a next where inexistent > 0;
--error 1176
handler t1_alias read a next;
--error 1054
handler t1_alias READ a next where inexistent > 0;
handler t1_alias close;
drop table t1;
...@@ -36,3 +36,18 @@ select 1/*!999992*/; ...@@ -36,3 +36,18 @@ select 1/*!999992*/;
select 1 + /*!00000 2 */ + 3 /*!99999 noise*/ + 4; select 1 + /*!00000 2 */ + 3 /*!99999 noise*/ + 4;
1 + 2 + 3 + 4 1 + 2 + 3 + 4
10 10
drop table if exists table_28779;
create table table_28779 (a int);
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';";
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 '/*' AND b = 'bar'' at line 1
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';*";
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 '/*' AND b = 'bar';*' at line 1
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;";
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 '' at line 1
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;*";
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 ';*' at line 1
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';";
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 '/*!98765' AND b = 'bar'' at line 1
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';*";
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 '/*!98765' AND b = 'bar';*' at line 1
drop table table_28779;
...@@ -112,3 +112,14 @@ id x ...@@ -112,3 +112,14 @@ id x
commit; commit;
# Switch to connection default + disconnect con1 and con2 # Switch to connection default + disconnect con1 and con2
drop table t1, t2; drop table t1, t2;
End of 4.1 tests
set storage_engine=innodb;
drop table if exists a;
drop table if exists A;
create table A (c int);
insert into A (c) values (0);
create table a as select * from A;
drop table A;
drop table if exists a;
set storage_engine=default;
End of 5.0 tests.
...@@ -499,6 +499,9 @@ set global event_scheduler=off; ...@@ -499,6 +499,9 @@ set global event_scheduler=off;
select /*4*/ user, host, db, command, state, info from information_schema.processlist where (command!='Daemon' || user='event_scheduler') and (info is null or info not like '%processlist%') order by info; select /*4*/ user, host, db, command, state, info from information_schema.processlist where (command!='Daemon' || user='event_scheduler') and (info is null or info not like '%processlist%') order by info;
user host db command state info user host db command state info
root localhost events_test Connect User lock select get_lock("test_lock2_1", 20) root localhost events_test Connect User lock select get_lock("test_lock2_1", 20)
select release_lock("test_lock2_1");
release_lock("test_lock2_1")
1
drop event закачка21; drop event закачка21;
create table t_16 (s1 int); create table t_16 (s1 int);
create trigger t_16_bi before insert on t_16 for each row create event e_16 on schedule every 1 second do set @a=5; create trigger t_16_bi before insert on t_16 for each row create event e_16 on schedule every 1 second do set @a=5;
......
...@@ -522,3 +522,16 @@ handler t1 open; ...@@ -522,3 +522,16 @@ handler t1 open;
ERROR HY000: Table storage engine for 't1' doesn't have this option ERROR HY000: Table storage engine for 't1' doesn't have this option
--> client 1 --> client 1
drop table t1; drop table t1;
drop table if exists t1;
create table t1 (a int);
handler t1 open as t1_alias;
handler t1_alias read a next;
ERROR 42000: Key 'a' doesn't exist in table 't1_alias'
handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias read a next;
ERROR 42000: Key 'a' doesn't exist in table 't1_alias'
handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias close;
drop table t1;
...@@ -522,3 +522,16 @@ handler t1 open; ...@@ -522,3 +522,16 @@ handler t1 open;
ERROR HY000: Table storage engine for 't1' doesn't have this option ERROR HY000: Table storage engine for 't1' doesn't have this option
--> client 1 --> client 1
drop table t1; drop table t1;
drop table if exists t1;
create table t1 (a int);
handler t1 open as t1_alias;
handler t1_alias read a next;
ERROR 42000: Key 'a' doesn't exist in table 't1_alias'
handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias read a next;
ERROR 42000: Key 'a' doesn't exist in table 't1_alias'
handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias close;
drop table t1;
...@@ -176,5 +176,7 @@ ERROR at line 1: DELIMITER cannot contain a backslash character ...@@ -176,5 +176,7 @@ ERROR at line 1: DELIMITER cannot contain a backslash character
ERROR at line 1: DELIMITER cannot contain a backslash character ERROR at line 1: DELIMITER cannot contain a backslash character
1 1
1 1
1
1
End of 5.0 tests End of 5.0 tests
WARNING: --server-arg option not supported in this configuration. WARNING: --server-arg option not supported in this configuration.
This diff is collapsed.
...@@ -969,6 +969,18 @@ CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create user 'mysqltest ...@@ -969,6 +969,18 @@ CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create user 'mysqltest
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN create user 'mysqltest_1'; return 1; END | CREATE FUNCTION bug_13627_f() returns int BEGIN create user 'mysqltest_1'; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN grant select on t1 to 'mysqltest_1'; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug21975() returns int BEGIN grant select on t1 to 'mysqltest_1'; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN revoke select on t1 from 'mysqltest_1'; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug21975() returns int BEGIN revoke select on t1 from 'mysqltest_1'; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN revoke all privileges on *.* from 'mysqltest_1'; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug21975() returns int BEGIN revoke all privileges on *.* from 'mysqltest_1'; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop user 'mysqltest_1'; END | CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop user 'mysqltest_1'; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN drop user 'mysqltest_1'; return 1; END | CREATE FUNCTION bug_13627_f() returns int BEGIN drop user 'mysqltest_1'; return 1; END |
......
...@@ -6546,4 +6546,79 @@ DROP VIEW v1; ...@@ -6546,4 +6546,79 @@ DROP VIEW v1;
DROP FUNCTION f1; DROP FUNCTION f1;
DROP FUNCTION f2; DROP FUNCTION f2;
DROP TABLE t1; DROP TABLE t1;
drop table if exists t1;
drop procedure if exists p1;
create table t1 (value varchar(15));
create procedure p1() update t1 set value='updated' where value='old';
call p1();
insert into t1 (value) values ("old");
select get_lock('b26162',120);
get_lock('b26162',120)
1
select 'rl_acquirer', value from t1 where get_lock('b26162',120);;
set session low_priority_updates=on;
call p1();;
select 'rl_contender', value from t1;
rl_contender value
rl_contender old
select release_lock('b26162');
release_lock('b26162')
1
rl_acquirer value
rl_acquirer old
drop procedure p1;
drop table t1;
set session low_priority_updates=default;
# Bug#13675.
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p2;
DROP TABLE IF EXISTS t1;
CREATE PROCEDURE p1(v DATETIME) CREATE TABLE t1 SELECT v;
CREATE PROCEDURE p2(v INT) CREATE TABLE t1 SELECT v;
CALL p1(NOW());
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`v` datetime DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CALL p1('text');
Warnings:
Warning 1264 Out of range value for column 'v' at row 1
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`v` datetime DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CALL p2(10);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`v` bigint(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CALL p2('text');
Warnings:
Warning 1366 Incorrect integer value: 'text' for column 'v' at row 1
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`v` bigint(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
DROP PROCEDURE p1;
DROP PROCEDURE p2;
End of 5.0 tests End of 5.0 tests
drop database if exists d1;
create database d1;
use d1;
create table t (s1 int) engine=innodb;
set @@autocommit=0;
start transaction;
insert into t values (1);
grant select on t to x@y;
rollback;
show grants for x@y;
Grants for x@y
GRANT USAGE ON *.* TO 'x'@'y'
GRANT SELECT ON `d1`.`t` TO 'x'@'y'
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 4 Format_desc 1 106 Server ver: VERSION, Binlog ver: 4
master-bin.000001 106 Query 1 193 drop database if exists d1
master-bin.000001 193 Query 1 272 create database d1
master-bin.000001 272 Query 1 370 use `d1`; create table t (s1 int) engine=innodb
master-bin.000001 370 Query 1 436 use `d1`; BEGIN
master-bin.000001 436 Query 1 521 use `d1`; insert into t values (1)
master-bin.000001 521 Xid 1 548 COMMIT /* xid=12 */
master-bin.000001 548 Query 1 633 use `d1`; grant select on t to x@y
start transaction;
insert into t values (2);
revoke select on t from x@y;
commit;
select * from t;
s1
1
2
show grants for x@y;
Grants for x@y
GRANT USAGE ON *.* TO 'x'@'y'
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 4 Format_desc 1 106 Server ver: VERSION, Binlog ver: 4
master-bin.000001 106 Query 1 193 drop database if exists d1
master-bin.000001 193 Query 1 272 create database d1
master-bin.000001 272 Query 1 370 use `d1`; create table t (s1 int) engine=innodb
master-bin.000001 370 Query 1 436 use `d1`; BEGIN
master-bin.000001 436 Query 1 521 use `d1`; insert into t values (1)
master-bin.000001 521 Xid 1 548 COMMIT /* xid=12 */
master-bin.000001 548 Query 1 633 use `d1`; grant select on t to x@y
master-bin.000001 633 Query 1 699 use `d1`; BEGIN
master-bin.000001 699 Query 1 784 use `d1`; insert into t values (2)
master-bin.000001 784 Xid 1 811 COMMIT /* xid=18 */
master-bin.000001 811 Query 1 899 use `d1`; revoke select on t from x@y
drop user x@y;
drop database d1;
-- source include/have_innodb.inc
-- source include/not_embedded.inc
-- source include/have_binlog_format_mixed_or_statement.inc
let $VERSION=`select version()`;
# Bug #21975: grant/revoke statements in transaction
# used to disappear from binlog upon rallback.
# Now GRANT/REVOKE do implicitly commit
# transaction
--disable_warnings
drop database if exists d1;
--enable_warnings
create database d1;
use d1;
create table t (s1 int) engine=innodb;
set @@autocommit=0;
start transaction;
insert into t values (1);
grant select on t to x@y;
#
# There is no active transaction here
#
rollback;
show grants for x@y;
--replace_result $VERSION VERSION
show binlog events;
start transaction;
insert into t values (2);
revoke select on t from x@y;
#
# There is no active transaction here
#
commit;
select * from t;
show grants for x@y;
--replace_result $VERSION VERSION
show binlog events;
drop user x@y;
drop database d1;
...@@ -34,3 +34,34 @@ select 1/*!999992*/; ...@@ -34,3 +34,34 @@ select 1/*!999992*/;
select 1 + /*!00000 2 */ + 3 /*!99999 noise*/ + 4; select 1 + /*!00000 2 */ + 3 /*!99999 noise*/ + 4;
#
# Bug#28779 (mysql_query() allows execution of statements with unbalanced
# comments)
#
--disable_warnings
drop table if exists table_28779;
--enable_warnings
create table table_28779 (a int);
--error 1064
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';";
--error 1064
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';*";
--error 1064
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;";
--error 1064
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;*";
--error 1064
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';";
--error 1064
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';*";
drop table table_28779;
...@@ -466,13 +466,17 @@ drop event закачка; ...@@ -466,13 +466,17 @@ drop event закачка;
set global event_scheduler=1; set global event_scheduler=1;
select get_lock("test_lock2_1", 20); select get_lock("test_lock2_1", 20);
create event закачка21 on schedule every 10 hour do select get_lock("test_lock2_1", 20); create event закачка21 on schedule every 10 hour do select get_lock("test_lock2_1", 20);
--sleep 1 let $wait_condition= select count(*) = 3 from information_schema.processlist;
--source include/wait_condition.inc
--echo "Should have only 3 processes: the scheduler, our conn and the locked event" --echo "Should have only 3 processes: the scheduler, our conn and the locked event"
select /*3*/ user, host, db, command, state, info from information_schema.processlist where (command!='Daemon' || user='event_scheduler') and (info is null or info not like '%processlist%') order by info; select /*3*/ user, host, db, command, state, info from information_schema.processlist where (command!='Daemon' || user='event_scheduler') and (info is null or info not like '%processlist%') order by info;
set global event_scheduler=off; set global event_scheduler=off;
--sleep 0.8 let $wait_condition= select count(*) =1 from information_schema.processlist
where (command!='Daemon' || user='event_scheduler') and (info is null or info not like '%processlist%') order by info;
--source include/wait_condition.inc
--echo "Should have only our process now:" --echo "Should have only our process now:"
select /*4*/ user, host, db, command, state, info from information_schema.processlist where (command!='Daemon' || user='event_scheduler') and (info is null or info not like '%processlist%') order by info; select /*4*/ user, host, db, command, state, info from information_schema.processlist where (command!='Daemon' || user='event_scheduler') and (info is null or info not like '%processlist%') order by info;
select release_lock("test_lock2_1");
drop event закачка21; drop event закачка21;
let $wait_condition= let $wait_condition=
select count(*) = 0 from information_schema.processlist select count(*) = 0 from information_schema.processlist
......
...@@ -274,6 +274,11 @@ EOF ...@@ -274,6 +274,11 @@ EOF
--exec $MYSQL --pager="540bytelengthstringxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -e "select 1" > /dev/null 2>&1 --exec $MYSQL --pager="540bytelengthstringxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -e "select 1" > /dev/null 2>&1
--exec $MYSQL --character-sets-dir="540bytelengthstringxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -e "select 1" 2>&1 --exec $MYSQL --character-sets-dir="540bytelengthstringxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -e "select 1" 2>&1
#
# bug #30164: Using client side macro inside server side comments generates broken queries
#
--exec $MYSQL test -e "/*! \C latin1 */ select 1;"
--echo End of 5.0 tests --echo End of 5.0 tests
# #
......
This diff is collapsed.
...@@ -1386,6 +1386,21 @@ CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create user 'mysqltest ...@@ -1386,6 +1386,21 @@ CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create user 'mysqltest
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG -- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN create user 'mysqltest_1'; return 1; END | CREATE FUNCTION bug_13627_f() returns int BEGIN create user 'mysqltest_1'; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN grant select on t1 to 'mysqltest_1'; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug21975() returns int BEGIN grant select on t1 to 'mysqltest_1'; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN revoke select on t1 from 'mysqltest_1'; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug21975() returns int BEGIN revoke select on t1 from 'mysqltest_1'; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN revoke all privileges on *.* from 'mysqltest_1'; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug21975() returns int BEGIN revoke all privileges on *.* from 'mysqltest_1'; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG -- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop user 'mysqltest_1'; END | CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop user 'mysqltest_1'; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG -- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
......
...@@ -7494,4 +7494,123 @@ DROP FUNCTION f1; ...@@ -7494,4 +7494,123 @@ DROP FUNCTION f1;
DROP FUNCTION f2; DROP FUNCTION f2;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#29936 Stored Procedure DML ignores low_priority_updates setting
#
--disable_warnings
drop table if exists t1;
drop procedure if exists p1;
--enable_warnings
create table t1 (value varchar(15));
create procedure p1() update t1 set value='updated' where value='old';
# load the procedure into sp cache and execute once
call p1();
insert into t1 (value) values ("old");
connect (rl_holder, localhost, root,,);
connect (rl_acquirer, localhost, root,,);
connect (rl_contender, localhost, root,,);
connect (rl_wait, localhost, root,,);
connection rl_holder;
select get_lock('b26162',120);
connection rl_acquirer;
--send select 'rl_acquirer', value from t1 where get_lock('b26162',120);
# we must wait till this select opens and locks the tables
connection rl_wait;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "User lock" and
info = "select 'rl_acquirer', value from t1 where get_lock('b26162',120)";
--source include/wait_condition.inc
connection default;
set session low_priority_updates=on;
--send call p1();
connection rl_wait;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Locked" and
info = "update t1 set value='updated' where value='old'";
--source include/wait_condition.inc
connection rl_contender;
select 'rl_contender', value from t1;
connection rl_holder;
select release_lock('b26162');
connection rl_acquirer;
--reap
connection default;
--reap
disconnect rl_holder;
disconnect rl_acquirer;
disconnect rl_wait;
drop procedure p1;
drop table t1;
set session low_priority_updates=default;
#
# Bug#13675: DATETIME/DATE type in store proc param seems to be converted as
# varbinary
#
--echo
--echo # Bug#13675.
--echo
--disable_warnings
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p2;
DROP TABLE IF EXISTS t1;
--enable_warnings
--echo
CREATE PROCEDURE p1(v DATETIME) CREATE TABLE t1 SELECT v;
CREATE PROCEDURE p2(v INT) CREATE TABLE t1 SELECT v;
--echo
CALL p1(NOW());
SHOW CREATE TABLE t1;
--echo
DROP TABLE t1;
--echo
CALL p1('text');
SHOW CREATE TABLE t1;
--echo
DROP TABLE t1;
--echo
CALL p2(10);
SHOW CREATE TABLE t1;
--echo
DROP TABLE t1;
--echo
CALL p2('text');
SHOW CREATE TABLE t1;
--echo
DROP TABLE t1;
--echo
DROP PROCEDURE p1;
DROP PROCEDURE p2;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -1424,6 +1424,7 @@ public: ...@@ -1424,6 +1424,7 @@ public:
Item_cond(List<Item> &nlist) Item_cond(List<Item> &nlist)
:Item_bool_func(), list(nlist), abort_on_null(0) {} :Item_bool_func(), list(nlist), abort_on_null(0) {}
bool add(Item *item) { return list.push_back(item); } bool add(Item *item) { return list.push_back(item); }
bool add_at_head(Item *item) { return list.push_front(item); }
void add_at_head(List<Item> *nlist) { list.prepand(nlist); } void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
bool fix_fields(THD *, Item **ref); bool fix_fields(THD *, Item **ref);
...@@ -1616,6 +1617,15 @@ public: ...@@ -1616,6 +1617,15 @@ public:
Item *neg_transformer(THD *thd); Item *neg_transformer(THD *thd);
}; };
inline bool is_cond_and(Item *item)
{
if (item->type() != Item::COND_ITEM)
return FALSE;
Item_cond *cond_item= (Item_cond*) item;
return (cond_item->functype() == Item_func::COND_AND_FUNC);
}
class Item_cond_or :public Item_cond class Item_cond_or :public Item_cond
{ {
public: public:
...@@ -1637,6 +1647,14 @@ public: ...@@ -1637,6 +1647,14 @@ public:
Item *neg_transformer(THD *thd); Item *neg_transformer(THD *thd);
}; };
inline bool is_cond_or(Item *item)
{
if (item->type() != Item::COND_ITEM)
return FALSE;
Item_cond *cond_item= (Item_cond*) item;
return (cond_item->functype() == Item_func::COND_OR_FUNC);
}
/* /*
XOR is Item_cond, not an Item_int_func because we could like to XOR is Item_cond, not an Item_int_func because we could like to
......
...@@ -276,6 +276,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, ...@@ -276,6 +276,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
thd->lock_id)]; thd->lock_id)];
if (rc > 1) /* a timeout or a deadlock */ if (rc > 1) /* a timeout or a deadlock */
{ {
if (sql_lock->table_count)
VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
my_error(rc, MYF(0)); my_error(rc, MYF(0));
my_free((uchar*) sql_lock,MYF(0)); my_free((uchar*) sql_lock,MYF(0));
sql_lock= 0; sql_lock= 0;
......
...@@ -575,7 +575,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, ...@@ -575,7 +575,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
we'll update it later in switch_query_ctx(). we'll update it later in switch_query_ctx().
*/ */
if ((ret= sp_use_new_db(thd, name->m_db, &old_db, 1, &dbchanged))) if ((ret= sp_use_new_db(thd, name->m_db, &old_db, TRUE, &dbchanged)))
goto end; goto end;
thd->spcont= NULL; thd->spcont= NULL;
...@@ -2028,34 +2028,41 @@ create_string(THD *thd, String *buf, ...@@ -2028,34 +2028,41 @@ create_string(THD *thd, String *buf,
/* /**
Change the current database if needed. Change the current database if needed.
SYNOPSIS @param[in] thd thread handle
sp_use_new_db() @param[in] new_db new database name
thd thread handle @param[in, out] old_db IN: str points to a buffer where to store
new_db new database name (a string and its length) the old database, length contains the
old_db [IN] str points to a buffer where to store the old size of the buffer
database, length contains the size of the buffer OUT: if old db was not NULL, its name is
[OUT] if old db was not NULL, its name is copied copied to the buffer pointed at by str
to the buffer pointed at by str and length is updated and length is updated accordingly.
accordingly. Otherwise str[0] is set to '\0' and length Otherwise str[0] is set to '\0' and
is set to 0. The out parameter should be used only if length is set to 0. The out parameter
the database name has been changed (see dbchangedp). should be used only if the database name
dbchangedp [OUT] is set to TRUE if the current database is changed, has been changed (see dbchangedp).
FALSE otherwise. A database is not changed if the old @param[in] force_switch Flag to mysql_change_db(). For more information,
name is the same as the new one, both names are empty, see mysql_change_db() comment.
or an error has occurred. @param[out] dbchangedp is set to TRUE if the current database is
changed, FALSE otherwise. The current
RETURN VALUE database is not changed if the old name
0 success is equal to the new one, both names are
1 access denied or out of memory (the error message is empty, or an error has occurred.
set in THD)
@return Operation status.
@retval 0 on success
@retval 1 access denied or out of memory
(the error message is set in THD)
*/ */
int int
sp_use_new_db(THD *thd, LEX_STRING new_db, LEX_STRING *old_db, sp_use_new_db(THD *thd,
bool no_access_check, bool *dbchangedp) LEX_STRING new_db,
LEX_STRING *old_db,
bool force_switch,
bool *dbchangedp)
{ {
int ret; int ret;
DBUG_ENTER("sp_use_new_db"); DBUG_ENTER("sp_use_new_db");
...@@ -2086,7 +2093,7 @@ sp_use_new_db(THD *thd, LEX_STRING new_db, LEX_STRING *old_db, ...@@ -2086,7 +2093,7 @@ sp_use_new_db(THD *thd, LEX_STRING new_db, LEX_STRING *old_db,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
ret= mysql_change_db(thd, &new_db, no_access_check); ret= mysql_change_db(thd, &new_db, force_switch);
*dbchangedp= ret == 0; *dbchangedp= ret == 0;
DBUG_RETURN(ret); DBUG_RETURN(ret);
......
...@@ -249,11 +249,14 @@ sp_get_flags_for_command(LEX *lex) ...@@ -249,11 +249,14 @@ sp_get_flags_for_command(LEX *lex)
case SQLCOM_CREATE_TRIGGER: case SQLCOM_CREATE_TRIGGER:
case SQLCOM_CREATE_USER: case SQLCOM_CREATE_USER:
case SQLCOM_ALTER_TABLE: case SQLCOM_ALTER_TABLE:
case SQLCOM_GRANT:
case SQLCOM_REVOKE:
case SQLCOM_BEGIN: case SQLCOM_BEGIN:
case SQLCOM_RENAME_TABLE: case SQLCOM_RENAME_TABLE:
case SQLCOM_RENAME_USER: case SQLCOM_RENAME_USER:
case SQLCOM_DROP_INDEX: case SQLCOM_DROP_INDEX:
case SQLCOM_DROP_DB: case SQLCOM_DROP_DB:
case SQLCOM_REVOKE_ALL:
case SQLCOM_DROP_USER: case SQLCOM_DROP_USER:
case SQLCOM_DROP_VIEW: case SQLCOM_DROP_VIEW:
case SQLCOM_DROP_TRIGGER: case SQLCOM_DROP_TRIGGER:
......
...@@ -1802,11 +1802,27 @@ public: ...@@ -1802,11 +1802,27 @@ public:
} }
} }
/* /**
Initialize the current database from a NULL-terminated string with length Set the current database; use deep copy of C-string.
If we run out of memory, we free the current database and return TRUE.
This way the user will notice the error as there will be no current @param new_db a pointer to the new database name.
database selected (in addition to the error message set by malloc). @param new_db_len length of the new database name.
Initialize the current database from a NULL-terminated string with
length. If we run out of memory, we free the current database and
return TRUE. This way the user will notice the error as there will be
no current database selected (in addition to the error message set by
malloc).
@note This operation just sets {thd->db, thd->db_length}. Switching the
current database usually involves other actions, like switching other
database attributes including security context. In the future, this
operation will be made private and more convenient interface will be
provided.
@return Operation status
@retval FALSE Success
@retval TRUE Out-of-memory error
*/ */
bool set_db(const char *new_db, size_t new_db_len) bool set_db(const char *new_db, size_t new_db_len)
{ {
...@@ -1821,6 +1837,19 @@ public: ...@@ -1821,6 +1837,19 @@ public:
db_length= db ? new_db_len : 0; db_length= db ? new_db_len : 0;
return new_db && !db; return new_db && !db;
} }
/**
Set the current database; use shallow copy of C-string.
@param new_db a pointer to the new database name.
@param new_db_len length of the new database name.
@note This operation just sets {thd->db, thd->db_length}. Switching the
current database usually involves other actions, like switching other
database attributes including security context. In the future, this
operation will be made private and more convenient interface will be
provided.
*/
void reset_db(char *new_db, size_t new_db_len) void reset_db(char *new_db, size_t new_db_len)
{ {
db= new_db; db= new_db;
......
...@@ -39,6 +39,10 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, ...@@ -39,6 +39,10 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
static long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path); static long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path);
static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error); static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error);
static void mysql_change_db_impl(THD *thd,
LEX_STRING *new_db_name,
ulong new_db_access,
CHARSET_INFO *new_db_charset);
/* Database lock hash */ /* Database lock hash */
...@@ -997,7 +1001,7 @@ exit: ...@@ -997,7 +1001,7 @@ exit:
it to 0. it to 0.
*/ */
if (thd->db && !strcmp(thd->db, db)) if (thd->db && !strcmp(thd->db, db))
thd->set_db(NULL, 0); mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
start_waiting_global_read_lock(thd); start_waiting_global_read_lock(thd);
exit2: exit2:
...@@ -1356,21 +1360,48 @@ static void mysql_change_db_impl(THD *thd, ...@@ -1356,21 +1360,48 @@ static void mysql_change_db_impl(THD *thd,
/** /**
@brief Change the current database. @brief Change the current database and its attributes.
@param thd thread handle @param thd thread handle
@param new_db_name database name @param new_db_name database name
@param force_switch if this flag is set (TRUE), mysql_change_db() will @param force_switch if force_switch is FALSE, then the operation will fail if
switch to NULL db if the specified database is not
available anymore. Corresponding warning will be - new_db_name is NULL or empty;
thrown in this case. This flag is used to change
database in stored-routine-execution code. - OR new database name is invalid
(check_db_name() failed);
@details Check that the database name corresponds to a valid and existent
database, check access rights (unless called with no_access_check), and - OR user has no privilege on the new database;
set the current database. This function is called to change the current
database upon user request (COM_CHANGE_DB command) or temporarily, to - OR new database does not exist;
execute a stored routine.
if force_switch is TRUE, then
- if new_db_name is NULL or empty, the current
database will be NULL, @@collation_database will
be set to @@collation_server, the operation will
succeed.
- if new database name is invalid
(check_db_name() failed), the current database
will be NULL, @@collation_database will be set to
@@collation_server, but the operation will fail;
- user privileges will not be checked
(THD::db_access however is updated);
TODO: is this really the intention?
(see sp-security.test).
- if new database does not exist,the current database
will be NULL, @@collation_database will be set to
@@collation_server, a warning will be thrown, the
operation will succeed.
@details The function checks that the database name corresponds to a
valid and existent database, checks access rights and changes the current
database with database attributes (@@collation_database session variable,
THD::db_access).
This function is not the only way to switch the database that is This function is not the only way to switch the database that is
currently employed. When the replication slave thread switches the currently employed. When the replication slave thread switches the
...@@ -1407,8 +1438,13 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch) ...@@ -1407,8 +1438,13 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
if (force_switch) if (force_switch)
{ {
/* /*
This can only happen when we restore the old db in THD after This can happen only if we're switching the current database back
execution of a routine is complete. Change db to NULL. after loading stored program. The thing is that loading of stored
program can happen when there is no current database.
TODO: actually, new_db_name and new_db_name->str seem to be always
non-NULL. In case of stored program, new_db_name->str == "" and
new_db_name->length == 0.
*/ */
mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server); mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
...@@ -1426,7 +1462,7 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch) ...@@ -1426,7 +1462,7 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
if (my_strcasecmp(system_charset_info, new_db_name->str, if (my_strcasecmp(system_charset_info, new_db_name->str,
INFORMATION_SCHEMA_NAME.str) == 0) INFORMATION_SCHEMA_NAME.str) == 0)
{ {
/* Switch database to INFORMATION_SCHEMA. */ /* Switch the current database to INFORMATION_SCHEMA. */
mysql_change_db_impl(thd, &INFORMATION_SCHEMA_NAME, SELECT_ACL, mysql_change_db_impl(thd, &INFORMATION_SCHEMA_NAME, SELECT_ACL,
system_charset_info); system_charset_info);
...@@ -1453,8 +1489,8 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch) ...@@ -1453,8 +1489,8 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
even if we are called from sp_head::execute(). even if we are called from sp_head::execute().
It's next to impossible however to get this error when we are called It's next to impossible however to get this error when we are called
from sp_head::execute(). But let's switch database to NULL in this case from sp_head::execute(). But let's switch the current database to NULL
to be sure. in this case to be sure.
*/ */
if (check_db_name(&new_db_file_name)) if (check_db_name(&new_db_file_name))
...@@ -1463,10 +1499,8 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch) ...@@ -1463,10 +1499,8 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
my_free(new_db_file_name.str, MYF(0)); my_free(new_db_file_name.str, MYF(0));
if (force_switch) if (force_switch)
{
/* Change db to NULL. */
mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server); mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
}
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
...@@ -1501,6 +1535,8 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch) ...@@ -1501,6 +1535,8 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
{ {
if (force_switch) if (force_switch)
{ {
/* Throw a warning and free new_db_file_name. */
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR), ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
new_db_file_name.str); new_db_file_name.str);
...@@ -1511,12 +1547,19 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch) ...@@ -1511,12 +1547,19 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server); mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
/* The operation succeed. */
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
else else
{ {
/* Report an error and free new_db_file_name. */
my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str); my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
my_free(new_db_file_name.str, MYF(0)); my_free(new_db_file_name.str, MYF(0));
/* The operation failed. */
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
} }
...@@ -1829,7 +1872,7 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db) ...@@ -1829,7 +1872,7 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
/* Step9: Let's do "use newdb" if we renamed the current database */ /* Step9: Let's do "use newdb" if we renamed the current database */
if (change_to_newdb) if (change_to_newdb)
error|= mysql_change_db(thd, new_db, 0); error|= mysql_change_db(thd, new_db, FALSE);
exit: exit:
pthread_mutex_lock(&LOCK_lock_db); pthread_mutex_lock(&LOCK_lock_db);
......
...@@ -444,7 +444,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, ...@@ -444,7 +444,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
cond->cleanup(); // File was reopened cond->cleanup(); // File was reopened
if ((!cond->fixed && if ((!cond->fixed &&
cond->fix_fields(thd, &cond)) || cond->check_cols(1)) cond->fix_fields(thd, &cond)) || cond->check_cols(1))
goto err0; goto err;
} }
if (keyname) if (keyname)
...@@ -452,13 +452,13 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, ...@@ -452,13 +452,13 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
if ((keyno=find_type(keyname, &table->s->keynames, 1+2)-1)<0) if ((keyno=find_type(keyname, &table->s->keynames, 1+2)-1)<0)
{ {
my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias); my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias);
goto err0; goto err;
} }
} }
if (insert_fields(thd, &thd->lex->select_lex.context, if (insert_fields(thd, &thd->lex->select_lex.context,
tables->db, tables->alias, &it, 0)) tables->db, tables->alias, &it, 0))
goto err0; goto err;
protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
......
...@@ -323,7 +323,6 @@ void lex_start(THD *thd) ...@@ -323,7 +323,6 @@ void lex_start(THD *thd)
lex->length=0; lex->length=0;
lex->part_info= 0; lex->part_info= 0;
lex->select_lex.in_sum_expr=0; lex->select_lex.in_sum_expr=0;
lex->select_lex.expr_list.empty();
lex->select_lex.ftfunc_list_alloc.empty(); lex->select_lex.ftfunc_list_alloc.empty();
lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc; lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc;
lex->select_lex.group_list.empty(); lex->select_lex.group_list.empty();
...@@ -720,6 +719,7 @@ static inline uint int_token(const char *str,uint length) ...@@ -720,6 +719,7 @@ static inline uint int_token(const char *str,uint length)
int MYSQLlex(void *arg, void *yythd) int MYSQLlex(void *arg, void *yythd)
{ {
reg1 uchar c; reg1 uchar c;
bool comment_closed;
int tokval, result_state; int tokval, result_state;
uint length; uint length;
enum my_lex_states state; enum my_lex_states state;
...@@ -1212,7 +1212,10 @@ int MYSQLlex(void *arg, void *yythd) ...@@ -1212,7 +1212,10 @@ int MYSQLlex(void *arg, void *yythd)
/* /*
The special comment format is very strict: The special comment format is very strict:
'/' '*' '!', followed by exactly '/' '*' '!', followed by exactly
2 digits (major), then 3 digits (minor). 1 digit (major), 2 digits (minor), then 2 digits (dot).
32302 -> 3.23.02
50032 -> 5.0.32
50114 -> 5.1.14
*/ */
char version_str[6]; char version_str[6];
version_str[0]= lip->yyPeekn(0); version_str[0]= lip->yyPeekn(0);
...@@ -1231,7 +1234,7 @@ int MYSQLlex(void *arg, void *yythd) ...@@ -1231,7 +1234,7 @@ int MYSQLlex(void *arg, void *yythd)
ulong version; ulong version;
version=strtol(version_str, NULL, 10); version=strtol(version_str, NULL, 10);
/* Accept 'M' 'M' 'm' 'm' 'm' */ /* Accept 'M' 'm' 'm' 'd' 'd' */
lip->yySkipn(5); lip->yySkipn(5);
if (version <= MYSQL_VERSION_ID) if (version <= MYSQL_VERSION_ID)
...@@ -1255,16 +1258,36 @@ int MYSQLlex(void *arg, void *yythd) ...@@ -1255,16 +1258,36 @@ int MYSQLlex(void *arg, void *yythd)
lip->yySkip(); // Accept / lip->yySkip(); // Accept /
lip->yySkip(); // Accept * lip->yySkip(); // Accept *
} }
/*
while (! lip->eof() && Discard:
((c=lip->yyGet()) != '*' || lip->yyPeek() != '/')) - regular '/' '*' comments,
- special comments '/' '*' '!' for a future version,
by scanning until we find a closing '*' '/' marker.
Note: There is no such thing as nesting comments,
the first '*' '/' sequence seen will mark the end.
*/
comment_closed= FALSE;
while (! lip->eof())
{ {
if (c == '\n') c= lip->yyGet();
if (c == '*')
{
if (lip->yyPeek() == '/')
{
lip->yySkip();
comment_closed= TRUE;
state = MY_LEX_START;
break;
}
}
else if (c == '\n')
lip->yylineno++; lip->yylineno++;
} }
if (! lip->eof()) /* Unbalanced comments with a missing '*' '/' are a syntax error */
lip->yySkip(); // remove last '/' if (! comment_closed)
return (ABORT_SYM);
state = MY_LEX_START; // Try again state = MY_LEX_START; // Try again
lip->in_comment= NO_COMMENT;
lip->set_echo(TRUE); lip->set_echo(TRUE);
break; break;
case MY_LEX_END_LONG_COMMENT: case MY_LEX_END_LONG_COMMENT:
...@@ -1316,6 +1339,9 @@ int MYSQLlex(void *arg, void *yythd) ...@@ -1316,6 +1339,9 @@ int MYSQLlex(void *arg, void *yythd)
lip->set_echo(FALSE); lip->set_echo(FALSE);
lip->yySkip(); lip->yySkip();
lip->set_echo(TRUE); lip->set_echo(TRUE);
/* Unbalanced comments with a missing '*' '/' are a syntax error */
if (lip->in_comment != NO_COMMENT)
return (ABORT_SYM);
lip->next_state=MY_LEX_END; // Mark for next loop lip->next_state=MY_LEX_END; // Mark for next loop
return(END_OF_INPUT); return(END_OF_INPUT);
} }
...@@ -1556,7 +1582,6 @@ void st_select_lex::init_select() ...@@ -1556,7 +1582,6 @@ void st_select_lex::init_select()
options= 0; options= 0;
sql_cache= SQL_CACHE_UNSPECIFIED; sql_cache= SQL_CACHE_UNSPECIFIED;
braces= 0; braces= 0;
expr_list.empty();
interval_list.empty(); interval_list.empty();
ftfunc_list_alloc.empty(); ftfunc_list_alloc.empty();
inner_sum_func_list= 0; inner_sum_func_list= 0;
......
...@@ -596,7 +596,6 @@ public: ...@@ -596,7 +596,6 @@ public:
const char *type; /* type of select for EXPLAIN */ const char *type; /* type of select for EXPLAIN */
SQL_LIST order_list; /* ORDER clause */ SQL_LIST order_list; /* ORDER clause */
List<List_item> expr_list;
SQL_LIST *gorder_list; SQL_LIST *gorder_list;
Item *select_limit, *offset_limit; /* LIMIT clause parameters */ Item *select_limit, *offset_limit; /* LIMIT clause parameters */
// Arrays of pointers to top elements of all_fields list // Arrays of pointers to top elements of all_fields list
......
...@@ -3381,6 +3381,8 @@ end_with_restore_list: ...@@ -3381,6 +3381,8 @@ end_with_restore_list:
} }
case SQLCOM_REVOKE_ALL: case SQLCOM_REVOKE_ALL:
{ {
if (end_active_trans(thd))
goto error;
if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) && if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
check_global_access(thd,CREATE_USER_ACL)) check_global_access(thd,CREATE_USER_ACL))
break; break;
...@@ -3392,6 +3394,9 @@ end_with_restore_list: ...@@ -3392,6 +3394,9 @@ end_with_restore_list:
case SQLCOM_REVOKE: case SQLCOM_REVOKE:
case SQLCOM_GRANT: case SQLCOM_GRANT:
{ {
if (end_active_trans(thd))
goto error;
if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL, if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
first_table ? first_table->db : select_lex->db, first_table ? first_table->db : select_lex->db,
first_table ? &first_table->grant.privilege : 0, first_table ? &first_table->grant.privilege : 0,
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment