Commit 51537c05 authored by dlenev@mysql.com's avatar dlenev@mysql.com

Fix for bug #12280 "Triggers: crash if flush tables".

We should not allow FLUSH statement to be executed inside both triggers
and stored functions.
parent 069fb89b
...@@ -247,7 +247,7 @@ end| ...@@ -247,7 +247,7 @@ end|
ERROR 42000: Duplicate cursor: c ERROR 42000: Duplicate cursor: c
create procedure u() create procedure u()
use sptmp| use sptmp|
ERROR 42000: USE is not allowed in a stored procedure ERROR 0A000: USE is not allowed in stored procedures
create procedure p() create procedure p()
begin begin
declare c cursor for select * from t1; declare c cursor for select * from t1;
...@@ -616,7 +616,7 @@ begin ...@@ -616,7 +616,7 @@ begin
flush tables; flush tables;
return 5; return 5;
end| end|
ERROR 0A000: FLUSH is not allowed in stored procedures ERROR 0A000: FLUSH is not allowed in stored function or trigger
create procedure bug9529_90123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123() create procedure bug9529_90123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123()
begin begin
end| end|
......
...@@ -2,6 +2,7 @@ drop table if exists t1, t2, t3; ...@@ -2,6 +2,7 @@ drop table if exists t1, t2, t3;
drop view if exists v1; drop view if exists v1;
drop database if exists mysqltest; drop database if exists mysqltest;
drop function if exists f1; drop function if exists f1;
drop procedure if exists p1;
create table t1 (i int); create table t1 (i int);
create trigger trg before insert on t1 for each row set @a:=1; create trigger trg before insert on t1 for each row set @a:=1;
set @a:=0; set @a:=0;
...@@ -635,3 +636,18 @@ show triggers; ...@@ -635,3 +636,18 @@ show triggers;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode
t1_bi INSERT t1 set new.a = '2004-01-00' BEFORE # t1_bi INSERT t1 set new.a = '2004-01-00' BEFORE #
drop table t1; drop table t1;
create table t1 (id int);
create trigger t1_ai after insert on t1 for each row flush tables;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row flush privileges;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
create procedure p1() flush tables;
create trigger t1_ai after insert on t1 for each row call p1();
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
create procedure p1() flush privileges;
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
drop table t1;
...@@ -334,7 +334,7 @@ begin ...@@ -334,7 +334,7 @@ begin
end| end|
# USE is not allowed # USE is not allowed
--error 1336 --error ER_SP_BADSTATEMENT
create procedure u() create procedure u()
use sptmp| use sptmp|
...@@ -885,7 +885,7 @@ create procedure bug10537() ...@@ -885,7 +885,7 @@ create procedure bug10537()
--disable_warnings --disable_warnings
drop function if exists bug8409| drop function if exists bug8409|
--enable_warnings --enable_warnings
--error ER_SP_BADSTATEMENT --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create function bug8409() create function bug8409()
returns int returns int
begin begin
......
...@@ -7,6 +7,7 @@ drop table if exists t1, t2, t3; ...@@ -7,6 +7,7 @@ drop table if exists t1, t2, t3;
drop view if exists v1; drop view if exists v1;
drop database if exists mysqltest; drop database if exists mysqltest;
drop function if exists f1; drop function if exists f1;
drop procedure if exists p1;
--enable_warnings --enable_warnings
create table t1 (i int); create table t1 (i int);
...@@ -642,3 +643,22 @@ show create table t1; ...@@ -642,3 +643,22 @@ show create table t1;
--replace_column 6 # --replace_column 6 #
show triggers; show triggers;
drop table t1; drop table t1;
# Test for bug #12280 "Triggers: crash if flush tables"
# FLUSH TABLES and FLUSH PRIVILEGES should be disallowed inside
# of functions and triggers.
create table t1 (id int);
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create trigger t1_ai after insert on t1 for each row flush tables;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create trigger t1_ai after insert on t1 for each row flush privileges;
create procedure p1() flush tables;
create trigger t1_ai after insert on t1 for each row call p1();
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
insert into t1 values (0);
drop procedure p1;
create procedure p1() flush privileges;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
insert into t1 values (0);
drop procedure p1;
drop table t1;
...@@ -5137,8 +5137,8 @@ ER_SP_CANT_ALTER ...@@ -5137,8 +5137,8 @@ ER_SP_CANT_ALTER
eng "Failed to ALTER %s %s" eng "Failed to ALTER %s %s"
ER_SP_SUBSELECT_NYI 0A000 ER_SP_SUBSELECT_NYI 0A000
eng "Subselect value not supported" eng "Subselect value not supported"
ER_SP_NO_USE 42000 ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG 0A000
eng "USE is not allowed in a stored procedure" eng "%s is not allowed in stored function or trigger"
ER_SP_VARCOND_AFTER_CURSHNDLR 42000 ER_SP_VARCOND_AFTER_CURSHNDLR 42000
eng "Variable or condition declaration after cursor or handler declaration" eng "Variable or condition declaration after cursor or handler declaration"
ER_SP_CURSOR_AFTER_HANDLER 42000 ER_SP_CURSOR_AFTER_HANDLER 42000
......
...@@ -6395,6 +6395,13 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, ...@@ -6395,6 +6395,13 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
bool result=0; bool result=0;
select_errors=0; /* Write if more errors */ select_errors=0; /* Write if more errors */
bool tmp_write_to_binlog= 1; bool tmp_write_to_binlog= 1;
if (thd->in_sub_stmt)
{
my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "FLUSH");
return 1;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (options & REFRESH_GRANT) if (options & REFRESH_GRANT)
{ {
......
...@@ -1960,7 +1960,7 @@ sp_proc_stmt: ...@@ -1960,7 +1960,7 @@ sp_proc_stmt:
} }
if (lex->sql_command == SQLCOM_CHANGE_DB) if (lex->sql_command == SQLCOM_CHANGE_DB)
{ /* "USE db" doesn't work in a procedure */ { /* "USE db" doesn't work in a procedure */
my_message(ER_SP_NO_USE, ER(ER_SP_NO_USE), MYF(0)); my_error(ER_SP_BADSTATEMENT, MYF(0), "USE");
YYABORT; YYABORT;
} }
/* /*
...@@ -6642,9 +6642,14 @@ flush: ...@@ -6642,9 +6642,14 @@ flush:
FLUSH_SYM opt_no_write_to_binlog FLUSH_SYM opt_no_write_to_binlog
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (lex->sphead && lex->sphead->m_type == TYPE_ENUM_FUNCTION) if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
{ {
my_error(ER_SP_BADSTATEMENT, MYF(0), "FLUSH"); /*
Note that both FLUSH TABLES and FLUSH PRIVILEGES will break
execution in prelocked mode. So it is better to disable
FLUSH in stored functions and triggers completely.
*/
my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "FLUSH");
YYABORT; YYABORT;
} }
lex->sql_command= SQLCOM_FLUSH; lex->type=0; lex->sql_command= SQLCOM_FLUSH; lex->type=0;
......
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