summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mysqld_error.h4
-rw-r--r--include/sql_state.h2
-rw-r--r--mysql-test/r/sp-error.result29
-rw-r--r--mysql-test/r/sp.result17
-rw-r--r--mysql-test/t/sp-error.test30
-rw-r--r--mysql-test/t/sp.test15
-rw-r--r--sql/share/czech/errmsg.txt2
-rw-r--r--sql/share/danish/errmsg.txt2
-rw-r--r--sql/share/dutch/errmsg.txt2
-rw-r--r--sql/share/english/errmsg.txt2
-rw-r--r--sql/share/estonian/errmsg.txt2
-rw-r--r--sql/share/french/errmsg.txt2
-rw-r--r--sql/share/german/errmsg.txt2
-rw-r--r--sql/share/greek/errmsg.txt2
-rw-r--r--sql/share/hungarian/errmsg.txt2
-rw-r--r--sql/share/italian/errmsg.txt2
-rw-r--r--sql/share/japanese/errmsg.txt2
-rw-r--r--sql/share/korean/errmsg.txt2
-rw-r--r--sql/share/norwegian-ny/errmsg.txt2
-rw-r--r--sql/share/norwegian/errmsg.txt2
-rw-r--r--sql/share/polish/errmsg.txt2
-rw-r--r--sql/share/portuguese/errmsg.txt2
-rw-r--r--sql/share/romanian/errmsg.txt2
-rw-r--r--sql/share/russian/errmsg.txt2
-rw-r--r--sql/share/serbian/errmsg.txt2
-rw-r--r--sql/share/slovak/errmsg.txt2
-rw-r--r--sql/share/spanish/errmsg.txt2
-rw-r--r--sql/share/swedish/errmsg.txt2
-rw-r--r--sql/share/ukrainian/errmsg.txt2
-rw-r--r--sql/sp_head.cc173
-rw-r--r--sql/sp_head.h62
-rw-r--r--sql/sql_string.cc14
-rw-r--r--sql/sql_string.h2
-rw-r--r--sql/sql_yacc.yy14
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;