diff options
34 files changed, 378 insertions, 30 deletions
diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 113eb07ed66..4b01004f1b4 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -340,4 +340,6 @@ #define ER_SP_CANT_ALTER 1321 #define ER_SP_SUBSELECT_NYI 1322 #define ER_SP_NO_USE 1323 -#define ER_ERROR_MESSAGES 324 +#define ER_SP_VARCOND_AFTER_CURSHNDLR 1324 +#define ER_SP_CURSOR_AFTER_HANDLER 1325 +#define ER_ERROR_MESSAGES 326 diff --git a/include/sql_state.h b/include/sql_state.h index c5a71daceb9..0c35f6bf8c9 100644 --- a/include/sql_state.h +++ b/include/sql_state.h @@ -197,3 +197,5 @@ ER_SP_DUP_CURS, "42000", "", /*ER_SP_CANT_ALTER*/ ER_SP_SUBSELECT_NYI, "0A000", "", ER_SP_NO_USE, "42000", "", +ER_SP_VARCOND_AFTER_CURSHNDLR, "42000", "", +ER_SP_CURSOR_AFTER_HANDLER, "42000", "", diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 1877789e2b0..6bc2af9862e 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -194,8 +194,8 @@ create table t1 (val int, x float)| insert into t1 values (42, 3.1), (19, 1.2)| create procedure p() begin -declare c cursor for select * from t1; declare x int; +declare c cursor for select * from t1; open c; fetch c into x, y; close c; @@ -203,8 +203,8 @@ end| ERROR 42000: Undeclared variable: y create procedure p() begin -declare c cursor for select * from t1; declare x int; +declare c cursor for select * from t1; open c; fetch c into x; close c; @@ -214,10 +214,10 @@ ERROR HY000: Wrong number of FETCH variables drop procedure p| create procedure p() begin -declare c cursor for select * from t1; declare x int; declare y float; declare z int; +declare c cursor for select * from t1; open c; fetch c into x, y, z; close c; @@ -252,9 +252,28 @@ declare c cursor for select field from t1; end| ERROR 42000: Duplicate cursor: c create procedure u() -use sptmp; -#| +use sptmp| ERROR 42000: USE is not allowed in a stored procedure +create procedure p() +begin +declare c cursor for select * from t1; +declare x int; +end| +ERROR 42000: Variable or condition declaration after cursor or handler declaration +create procedure p() +begin +declare x int; +declare continue handler for sqlstate '42S99' set x = 1; +declare foo condition for sqlstate '42S99'; +end| +ERROR 42000: Variable or condition declaration after cursor or handler declaration +create procedure p() +begin +declare x int; +declare continue handler for sqlstate '42S99' set x = 1; +declare c cursor for select * from t1; +end| +ERROR 42000: Cursor declaration after handler declaration create procedure bug1965() begin declare c cursor for select val from t1 order by valname; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 1f3064605bc..bfcf4064cf2 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -660,12 +660,12 @@ drop table t3| drop procedure hndlr4| create procedure cur1() begin -declare done int default 0; -declare continue handler for sqlstate '02000' set done = 1; -declare c cursor for select * from test.t2; declare a char(16); declare b int; declare c double; +declare done int default 0; +declare c cursor for select * from test.t2; +declare continue handler for sqlstate '02000' set done = 1; open c; repeat fetch c into a, b, c; @@ -688,9 +688,9 @@ create table t3 ( s char(16), i int )| create procedure cur2() begin declare done int default 0; -declare continue handler for sqlstate '02000' set done = 1; declare c1 cursor for select id,data from test.t1; declare c2 cursor for select i from test.t2; +declare continue handler for sqlstate '02000' set done = 1; open c1; open c2; repeat @@ -764,8 +764,8 @@ create procedure modes(out c1 int, out c2 int) begin declare done int default 0; declare x int; -declare continue handler for sqlstate '02000' set done = 1; declare c cursor for select data from t1; +declare continue handler for sqlstate '02000' set done = 1; select 1 || 2 into c1; set c2 = 0; open c; @@ -915,8 +915,8 @@ drop procedure bug1874| create procedure bug2260() begin declare v1 int; -declare continue handler for not found set @x2 = 1; declare c1 cursor for select data from t1; +declare continue handler for not found set @x2 = 1; open c1; fetch c1 into v1; set @x2 = 2; @@ -996,10 +996,13 @@ drop table t3| drop procedure bug2614| create function bug2674 () returns int return @@sort_buffer_size| +set @osbs = @@sort_buffer_size| +set @@sort_buffer_size = 262000| select bug2674()| bug2674() -262136 +262000 drop function bug2674| +set @@sort_buffer_size = @osbs| create procedure bug3259_1 () begin end| create procedure BUG3259_2 () begin end| create procedure Bug3259_3 () begin end| diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 43b5c04766a..cbff9b37a11 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -264,8 +264,8 @@ insert into t1 values (42, 3.1), (19, 1.2)| --error 1314 create procedure p() begin - declare c cursor for select * from t1; declare x int; + declare c cursor for select * from t1; open c; fetch c into x, y; @@ -274,8 +274,8 @@ end| create procedure p() begin - declare c cursor for select * from t1; declare x int; + declare c cursor for select * from t1; open c; fetch c into x; @@ -287,10 +287,10 @@ drop procedure p| create procedure p() begin - declare c cursor for select * from t1; declare x int; declare y float; declare z int; + declare c cursor for select * from t1; open c; fetch c into x, y, z; @@ -333,8 +333,30 @@ end| # USE is not allowed --error 1323 create procedure u() - use sptmp; + use sptmp| +# Enforced standard order of declarations +--error 1324 +create procedure p() +begin + declare c cursor for select * from t1; + declare x int; +end| +--error 1324 +create procedure p() +begin + declare x int; + declare continue handler for sqlstate '42S99' set x = 1; + declare foo condition for sqlstate '42S99'; +end| + +--error 1325 +create procedure p() +begin + declare x int; + declare continue handler for sqlstate '42S99' set x = 1; + declare c cursor for select * from t1; +end| # # BUG#1965 diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 69433514728..7e5b734d959 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -776,12 +776,12 @@ drop procedure hndlr4| # create procedure cur1() begin - declare done int default 0; - declare continue handler for sqlstate '02000' set done = 1; - declare c cursor for select * from test.t2; declare a char(16); declare b int; declare c double; + declare done int default 0; + declare c cursor for select * from test.t2; + declare continue handler for sqlstate '02000' set done = 1; open c; repeat @@ -806,9 +806,9 @@ create table t3 ( s char(16), i int )| create procedure cur2() begin declare done int default 0; - declare continue handler for sqlstate '02000' set done = 1; declare c1 cursor for select id,data from test.t1; declare c2 cursor for select i from test.t2; + declare continue handler for sqlstate '02000' set done = 1; open c1; open c2; @@ -879,8 +879,8 @@ create procedure modes(out c1 int, out c2 int) begin declare done int default 0; declare x int; - declare continue handler for sqlstate '02000' set done = 1; declare c cursor for select data from t1; + declare continue handler for sqlstate '02000' set done = 1; select 1 || 2 into c1; set c2 = 0; @@ -1069,8 +1069,8 @@ drop procedure bug1874| create procedure bug2260() begin declare v1 int; - declare continue handler for not found set @x2 = 1; declare c1 cursor for select data from t1; + declare continue handler for not found set @x2 = 1; open c1; fetch c1 into v1; @@ -1156,8 +1156,11 @@ drop procedure bug2614| create function bug2674 () returns int return @@sort_buffer_size| +set @osbs = @@sort_buffer_size| +set @@sort_buffer_size = 262000| select bug2674()| drop function bug2674| +set @@sort_buffer_size = @osbs| # # BUG#3259 diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index eea5912cbdf..6bcdeb9b05a 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -336,3 +336,5 @@ character-set=latin2 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 2c2782d4cf0..2d9543e1076 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -330,3 +330,5 @@ character-set=latin1 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 84bd5781ffb..484892432c0 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -338,3 +338,5 @@ character-set=latin1 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 2c88e1b445f..4d3113d4055 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -327,3 +327,5 @@ character-set=latin1 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index d72d7f94309..ba30d48b895 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -332,3 +332,5 @@ character-set=latin7 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 227b5138e98..1285b7c9d54 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -327,3 +327,5 @@ character-set=latin1 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index d4e42ed5d58..0a6886686b4 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -339,3 +339,5 @@ character-set=latin1 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 44e072bb20e..676beedc8f7 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -327,3 +327,5 @@ character-set=greek "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 72fdf4f8c51..82b96eb8928 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -329,3 +329,5 @@ character-set=latin2 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 6694f220848..aea6afdd304 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -327,3 +327,5 @@ character-set=latin1 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 896146749a9..6838a53ddca 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -329,3 +329,5 @@ character-set=ujis "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 3a92c060c67..04c480108b9 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -327,3 +327,5 @@ character-set=euckr "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index ada0435b52a..0b535727c9f 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -329,3 +329,5 @@ character-set=latin1 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index d0688b2858c..99782982ea7 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -329,3 +329,5 @@ character-set=latin1 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index d0c96146441..16dc1982a70 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -331,3 +331,5 @@ character-set=latin2 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 71be50ba262..1db07659e8f 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -328,3 +328,5 @@ character-set=latin1 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index d800906e663..f58e91e5559 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -331,3 +331,5 @@ character-set=latin2 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 633e29e8c48..e12c4cbeb1f 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -329,3 +329,5 @@ character-set=koi8r "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index efda5bb12cc..9695ae5d207 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -322,3 +322,5 @@ character-set=cp1250 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 8fa84320a8f..2631a9b8e5e 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -335,3 +335,5 @@ character-set=latin2 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 75a6d42bec8..e3312dbdb8d 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -329,3 +329,5 @@ character-set=latin1 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 9b743acb930..8e57aaeda51 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -327,3 +327,5 @@ character-set=latin1 "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 2b3587e2028..0a40fe5b2a8 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -332,3 +332,5 @@ character-set=koi8u "Failed to ALTER %s %s" "Subselect value not supported" "USE is not allowed in a stored procedure" +"Variable or condition declaration after cursor or handler declaration" +"Cursor declaration after handler declaration" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index c8be113e2e1..4c883d4cd3d 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -297,6 +297,24 @@ sp_head::create(THD *thd) DBUG_PRINT("info", ("type: %d name: %s params: %s body: %s", m_type, m_name.str, m_params.str, m_body.str)); +#ifndef DBUG_OFF + String s; + sp_instr *i; + uint ip= 0; + while ((i = get_instr(ip))) + { + char buf[8]; + + sprintf(buf, "%4u: ", ip); + s.append(buf); + i->print(&s); + s.append('\n'); + ip+= 1; + } + s.append('\0'); + DBUG_PRINT("info", ("Code %s\n%s", m_qname.str, s.ptr())); +#endif + if (m_type == TYPE_ENUM_FUNCTION) ret= sp_create_function(thd, this); else @@ -622,9 +640,9 @@ sp_head::reset_lex(THD *thd) (void)m_lex.push_front(oldlex); thd->lex= sublex= new st_lex; - sublex->yylineno= oldlex->yylineno; /* Reset most stuff. The length arguments doesn't matter here. */ lex_start(thd, oldlex->buf, oldlex->end_of_query - oldlex->ptr); + sublex->yylineno= oldlex->yylineno; /* We must reset ptr and end_of_query again */ sublex->ptr= oldlex->ptr; sublex->end_of_query= oldlex->end_of_query; @@ -871,6 +889,15 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) DBUG_RETURN(res); } +void +sp_instr_stmt::print(String *str) +{ + str->reserve(12); + str->append("stmt "); + str->qs_append(m_lex->sql_command); +} + + int sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) { @@ -988,6 +1015,16 @@ sp_instr_set::execute(THD *thd, uint *nextp) DBUG_RETURN(0); } +void +sp_instr_set::print(String *str) +{ + str->reserve(12); + str->append("set "); + str->qs_append(m_offset); + str->append(' '); + m_value->print(str); +} + // // sp_instr_jump // @@ -1001,6 +1038,14 @@ sp_instr_jump::execute(THD *thd, uint *nextp) DBUG_RETURN(0); } +void +sp_instr_jump::print(String *str) +{ + str->reserve(12); + str->append("jump "); + str->qs_append(m_dest); +} + // // sp_instr_jump_if // @@ -1018,6 +1063,16 @@ sp_instr_jump_if::execute(THD *thd, uint *nextp) DBUG_RETURN(0); } +void +sp_instr_jump_if::print(String *str) +{ + str->reserve(12); + str->append("jump_if "); + str->qs_append(m_dest); + str->append(' '); + m_expr->print(str); +} + // // sp_instr_jump_if_not // @@ -1035,6 +1090,16 @@ sp_instr_jump_if_not::execute(THD *thd, uint *nextp) DBUG_RETURN(0); } +void +sp_instr_jump_if_not::print(String *str) +{ + str->reserve(16); + str->append("jump_if_not "); + str->qs_append(m_dest); + str->append(' '); + m_expr->print(str); +} + // // sp_instr_freturn // @@ -1047,6 +1112,16 @@ sp_instr_freturn::execute(THD *thd, uint *nextp) DBUG_RETURN(0); } +void +sp_instr_freturn::print(String *str) +{ + str->reserve(12); + str->append("freturn "); + str->qs_append(m_type); + str->append(' '); + m_value->print(str); +} + // // sp_instr_hpush_jump // @@ -1064,6 +1139,18 @@ sp_instr_hpush_jump::execute(THD *thd, uint *nextp) DBUG_RETURN(0); } +void +sp_instr_hpush_jump::print(String *str) +{ + str->reserve(32); + str->append("hpush_jump "); + str->qs_append(m_type); + str->append(' '); + str->qs_append(m_frame); + str->append(' '); + str->qs_append(m_handler); +} + // // sp_instr_hpop // @@ -1076,6 +1163,14 @@ sp_instr_hpop::execute(THD *thd, uint *nextp) DBUG_RETURN(0); } +void +sp_instr_hpop::print(String *str) +{ + str->reserve(12); + str->append("hpop "); + str->qs_append(m_count); +} + // // sp_instr_hreturn // @@ -1088,6 +1183,14 @@ sp_instr_hreturn::execute(THD *thd, uint *nextp) DBUG_RETURN(0); } +void +sp_instr_hreturn::print(String *str) +{ + str->reserve(12); + str->append("hreturn "); + str->qs_append(m_frame); +} + // // sp_instr_cpush // @@ -1106,6 +1209,12 @@ sp_instr_cpush::~sp_instr_cpush() delete m_lex; } +void +sp_instr_cpush::print(String *str) +{ + str->append("cpush"); +} + // // sp_instr_cpop // @@ -1118,6 +1227,14 @@ sp_instr_cpop::execute(THD *thd, uint *nextp) DBUG_RETURN(0); } +void +sp_instr_cpop::print(String *str) +{ + str->reserve(12); + str->append("cpop "); + str->qs_append(m_count); +} + // // sp_instr_copen // @@ -1145,6 +1262,14 @@ sp_instr_copen::execute(THD *thd, uint *nextp) DBUG_RETURN(res); } +void +sp_instr_copen::print(String *str) +{ + str->reserve(12); + str->append("copen "); + str->qs_append(m_cursor); +} + // // sp_instr_cclose // @@ -1163,6 +1288,14 @@ sp_instr_cclose::execute(THD *thd, uint *nextp) DBUG_RETURN(res); } +void +sp_instr_cclose::print(String *str) +{ + str->reserve(12); + str->append("cclose "); + str->qs_append(m_cursor); +} + // // sp_instr_cfetch // @@ -1181,6 +1314,44 @@ sp_instr_cfetch::execute(THD *thd, uint *nextp) DBUG_RETURN(res); } +void +sp_instr_cfetch::print(String *str) +{ + List_iterator_fast<struct sp_pvar> li(m_varlist); + sp_pvar_t *pv; + + str->reserve(12); + str->append("cfetch "); + str->qs_append(m_cursor); + while ((pv= li++)) + { + str->reserve(8); + str->append(' '); + str->qs_append(pv->offset); + } +} + +// +// sp_instr_error +// +int +sp_instr_error::execute(THD *thd, uint *nextp) +{ + DBUG_ENTER("sp_instr_error::execute"); + + my_error(m_errcode, MYF(0)); + *nextp= m_ip+1; + DBUG_RETURN(-1); +} + +void +sp_instr_error::print(String *str) +{ + str->reserve(12); + str->append("error "); + str->qs_append(m_errcode); +} + /* ------------------------------------------------------------------ */ diff --git a/sql/sp_head.h b/sql/sp_head.h index 791c6697693..19d1cb8254a 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -262,12 +262,9 @@ public: // instruction to execute. (For most instruction this will be the // instruction following this one.) // Returns 0 on success, non-zero if some error occured. - virtual int - execute(THD *thd, uint *nextp) - { // Default is a no-op. - *nextp = m_ip+1; // Next instruction - return 0; - } + virtual int execute(THD *thd, uint *nextp) = 0; + + virtual void print(String *str) = 0; protected: @@ -294,6 +291,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + inline void set_lex(LEX *lex) { @@ -333,6 +332,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + private: uint m_offset; // Frame offset @@ -362,6 +363,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + virtual void set_destination(uint dest) { @@ -395,6 +398,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + private: Item *m_expr; // The condition @@ -422,6 +427,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + private: Item *m_expr; // The condition @@ -445,6 +452,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + protected: Item *m_value; @@ -474,6 +483,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + inline void add_condition(struct sp_cond_type *cond) { m_cond.push_front(cond); @@ -505,6 +516,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + private: uint m_count; @@ -528,6 +541,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + private: uint m_frame; @@ -550,6 +565,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + private: LEX *m_lex; @@ -573,6 +590,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + private: uint m_count; @@ -596,6 +615,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + private: uint m_cursor; // Stack index @@ -619,6 +640,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + private: uint m_cursor; @@ -644,6 +667,8 @@ public: virtual int execute(THD *thd, uint *nextp); + virtual void print(String *str); + void add_to_varlist(struct sp_pvar *var) { m_varlist.push_back(var); @@ -657,6 +682,31 @@ private: }; // class sp_instr_cfetch : public sp_instr +class sp_instr_error : public sp_instr +{ + sp_instr_error(const sp_instr_error &); /* Prevent use of these */ + void operator=(sp_instr_error &); + +public: + + sp_instr_error(uint ip, int errcode) + : sp_instr(ip), m_errcode(errcode) + {} + + virtual ~sp_instr_error() + {} + + virtual int execute(THD *thd, uint *nextp); + + virtual void print(String *str); + +private: + + int m_errcode; + +}; // class sp_instr_error : public sp_instr + + struct st_sp_security_context { bool changed; diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 093b85b46b7..cd25b0c27ec 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -698,6 +698,20 @@ void String::qs_append(const char &c) str_length += sizeof(c); } +void String::qs_append(int i) +{ + char *buff = Ptr + str_length; + sprintf(buff,"%d", i); + str_length += strlen(buff); +} + +void String::qs_append(uint i) +{ + char *buff = Ptr + str_length; + sprintf(buff,"%u", i); + str_length += strlen(buff); +} + int sortcmp(const String *x,const String *y, CHARSET_INFO *cs) { diff --git a/sql/sql_string.h b/sql/sql_string.h index 163156fdfe2..d234bf7b507 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -270,6 +270,8 @@ public: void qs_append(double d); void qs_append(double *d); void qs_append(const char &c); + void qs_append(int i); + void qs_append(uint i); /* Inline (general) functions used by the protocol functions */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d2f7e73b2b8..b9e9b0126df 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1318,6 +1318,20 @@ sp_decls: } | sp_decls sp_decl ';' { + /* We check for declarations out of (standard) order this way + because letting the grammar rules reflect it caused tricky + shift/reduce conflicts with the wrong result. (And we get + better error handling this way.) */ + if (($2.vars || $2.conds) && ($1.curs || $1.hndlrs)) + { /* Variable or condition following cursor or handler */ + send_error(YYTHD, ER_SP_VARCOND_AFTER_CURSHNDLR); + YYABORT; + } + if ($2.curs && $1.hndlrs) + { /* Cursor following handler */ + send_error(YYTHD, ER_SP_CURSOR_AFTER_HANDLER); + YYABORT; + } $$.vars= $1.vars + $2.vars; $$.conds= $1.conds + $2.conds; $$.hndlrs= $1.hndlrs + $2.hndlrs; |