Commit 9dfe7bf8 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-10598 Variable declarations can go after cursor declarations

Based on a contributed patch from Jerome Brauge.
parent 84c55a56
......@@ -1277,3 +1277,74 @@ Pos Instruction
28 jump 4
29 cpop 1
DROP PROCEDURE p1;
#
# MDEV-10598 sql_mode=ORACLE: Variable declarations can go after cursor declarations
#
#
# Cursor declaration and cursor%ROWTYPE declaration in the same block
#
CREATE TABLE t1 (a INT, b VARCHAR(10));
INSERT INTO t1 VALUES (1,'a');
CREATE PROCEDURE p1()
AS
CURSOR cur1 IS SELECT a FROM t1;
rec1 cur1%ROWTYPE;
BEGIN
rec1.a:= 10;
END;
$$
SHOW PROCEDURE CODE p1;
Pos Instruction
0 cursor_copy_struct cur1 rec1@0
1 set rec1@0 NULL
2 cpush cur1@0
3 set rec1.a@0["a"] 10
4 cpop 1
CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1;
#
# Recursive cursor and cursor%ROWTYPE declarations in the same block
#
CREATE PROCEDURE p1
AS
a INT:=10;
CURSOR cur1 IS SELECT a;
rec1 cur1%ROWTYPE;
CURSOR cur2 IS SELECT rec1.a + 1 "a";
rec2 cur2%ROWTYPE;
BEGIN
OPEN cur1;
FETCH cur1 INTO rec1;
CLOSE cur1;
SELECT rec1.a;
open cur2;
FETCH cur2 INTO rec2;
CLOSE cur2;
SELECT rec2.a;
END;
$$
SHOW PROCEDURE CODE p1;
Pos Instruction
0 set a@0 10
1 cursor_copy_struct cur1 rec1@1
2 set rec1@1 NULL
3 cursor_copy_struct cur2 rec2@2
4 set rec2@2 NULL
5 cpush cur1@0
6 cpush cur2@1
7 copen cur1@0
8 cfetch cur1@0 rec1@1
9 cclose cur1@0
10 stmt 0 "SELECT rec1.a"
11 copen cur2@1
12 cfetch cur2@1 rec2@2
13 cclose cur2@1
14 stmt 0 "SELECT rec2.a"
15 cpop 2
CALL p1();
rec1.a
10
rec2.a
11
DROP PROCEDURE p1;
SET sql_mode=ORACLE;
#
# MDEV-10598 sql_mode=ORACLE: Variable declarations can go after cursor declarations
#
#
# Variable after cursor declaration
#
CREATE TABLE t1 (a INT);
insert into t1 values (1);
insert into t1 values (2);
CREATE PROCEDURE p1
AS
CURSOR c IS SELECT a FROM t1;
var1 varchar(10);
BEGIN
OPEN c;
fetch c into var1;
SELECT c%ROWCOUNT,var1;
close c;
END;
$$
CALL p1;
c%ROWCOUNT var1
1 1
DROP PROCEDURE p1;
drop table t1;
#
# Variable after condition declaration
#
CREATE TABLE t1 (col1 INT);
insert into t1 values (1);
create unique index t1_col1 on t1 (col1);
CREATE PROCEDURE p1
AS
dup_key CONDITION FOR SQLSTATE '23000';
var1 varchar(40);
CONTINUE HANDLER FOR dup_key
BEGIN
var1:='duplicate key in index';
END;
BEGIN
var1:='';
insert into t1 values (1);
select var1;
END;
$$
CALL p1;
var1
duplicate key in index
DROP PROCEDURE p1;
drop table t1;
#
# Condition after cursor declaration
#
CREATE TABLE t1 (col1 INT);
insert into t1 values (1);
create unique index t1_col1 on t1 (col1);
CREATE PROCEDURE p1
AS
var1 varchar(40);
var2 integer;
CURSOR c IS SELECT col1 FROM t1;
dup_key CONDITION FOR SQLSTATE '23000';
CONTINUE HANDLER FOR dup_key
BEGIN
var1:='duplicate key in index';
END;
BEGIN
var1:='';
insert into t1 values (1);
SELECT var1;
END;
$$
CALL p1;
var1
duplicate key in index
DROP PROCEDURE p1;
drop table t1;
#
# Cursor after handler declaration
#
CREATE TABLE t1 (col1 INT);
insert into t1 values (1);
create unique index t1_col1 on t1 (col1);
CREATE PROCEDURE p1
AS
var1 varchar(40);
var2 integer;
dup_key CONDITION FOR SQLSTATE '23000';
CONTINUE HANDLER FOR dup_key
BEGIN
var1:='duplicate key in index';
END;
CURSOR c IS SELECT col1 FROM t1;
BEGIN
var1:='';
insert into t1 values (1);
SELECT var1;
END;
$$
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'CURSOR c IS SELECT col1 FROM t1;
BEGIN
var1:='';
insert into t1 values (1);
SELE' at line 10
drop table t1;
#
# Condition after handler declaration
#
CREATE TABLE t1 (col1 INT);
insert into t1 values (1);
create unique index t1_col1 on t1 (col1);
CREATE PROCEDURE p1
AS
var1 varchar(40);
var2 integer;
dup_key CONDITION FOR SQLSTATE '23000';
CURSOR c IS SELECT col1 FROM t1;
CONTINUE HANDLER FOR dup_key
BEGIN
var1:='duplicate key in index';
END;
divide_by_zero CONDITION FOR SQLSTATE '22012';
BEGIN
var1:='';
insert into t1 values (1);
SELECT var1;
END;
$$
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'divide_by_zero CONDITION FOR SQLSTATE '22012';
BEGIN
var1:='';
insert into t1 va' at line 11
drop table t1;
#
# Variable after handler declaration
#
CREATE TABLE t1 (col1 INT);
insert into t1 values (1);
create unique index t1_col1 on t1 (col1);
CREATE PROCEDURE p1
AS
var1 varchar(40);
var2 integer;
dup_key CONDITION FOR SQLSTATE '23000';
CURSOR c IS SELECT col1 FROM t1;
CONTINUE HANDLER FOR dup_key
BEGIN
var1:='duplicate key in index';
END;
divide_by_zero CONDITION FOR SQLSTATE '22012';
BEGIN
var1:='';
insert into t1 values (1);
SELECT var1;
END;
$$
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'divide_by_zero CONDITION FOR SQLSTATE '22012';
BEGIN
var1:='';
insert into t1 va' at line 11
drop table t1;
#
# Variable after cursor (inner block)
#
CREATE TABLE t1 (col1 INT);
insert into t1 values (1);
insert into t1 values (2);
create unique index t1_col1 on t1 (col1);
CREATE PROCEDURE p1
AS
CURSOR c IS SELECT col1 FROM t1;
var1 varchar(40);
BEGIN
OPEN c;
begin
declare
CURSOR c IS SELECT col1 FROM t1 where col1=2;
var2 integer;
dup_key CONDITION FOR SQLSTATE '23000';
CONTINUE HANDLER FOR dup_key
BEGIN
var1:='duplicate key in index';
END;
begin
OPEN c;
fetch c into var1;
SELECT 'inner cursor',var1;
insert into t1 values (2);
close c;
end;
end;
SELECT var1;
fetch c into var1;
SELECT c%ROWCOUNT,var1;
begin
insert into t1 values (2);
exception when 1062 then
begin
SELECT 'dup key caugth';
end;
end;
close c;
END;
$$
CALL p1;
inner cursor var1
inner cursor 2
var1
duplicate key in index
c%ROWCOUNT var1
1 1
dup key caugth
dup key caugth
DROP PROCEDURE p1;
drop table t1;
#
# Cursor declaration and row type declaration in same block
#
CREATE TABLE t1 (a INT, b VARCHAR(10));
insert into t1 values(1,'a');
CREATE PROCEDURE p1()
AS
CURSOR cur1 IS SELECT a FROM t1;
rec1 cur1%ROWTYPE;
BEGIN
rec1.a:= 10;
END;
$$
call p1;
DROP PROCEDURE p1;
drop table t1;
#
# Recursive cursor and cursor%ROWTYPE declarations in the same block
#
CREATE PROCEDURE p1
AS
a INT:=10;
b VARCHAR(10):='b0';
c DOUBLE:=0.1;
CURSOR cur1 IS SELECT a, b, c;
rec1 cur1%ROWTYPE;
CURSOR cur2 IS SELECT rec1.a + 1 "a", rec1.b||'0' AS b, rec1.c AS c;
rec2 cur2%ROWTYPE;
BEGIN
OPEN cur1;
FETCH cur1 INTO rec1;
CLOSE cur1;
SELECT rec1.a;
OPEN cur2;
FETCH cur2 INTO rec2;
CLOSE cur2;
SELECT rec2.a;
CREATE TABLE t2 AS SELECT rec2.a AS a, rec2.b AS b, rec2.c AS c;
SHOW CREATE TABLE t2;
DROP TABLE t2;
END;
$$
CALL p1();
rec1.a
10
rec2.a
11
Table Create Table
t2 CREATE TABLE "t2" (
"a" bigint(21) DEFAULT NULL,
"b" varchar(11) DEFAULT NULL,
"c" double DEFAULT NULL
)
DROP PROCEDURE p1;
......@@ -917,3 +917,57 @@ $$
DELIMITER ;$$
SHOW PROCEDURE CODE p1;
DROP PROCEDURE p1;
--echo #
--echo # MDEV-10598 sql_mode=ORACLE: Variable declarations can go after cursor declarations
--echo #
--echo #
--echo # Cursor declaration and cursor%ROWTYPE declaration in the same block
--echo #
CREATE TABLE t1 (a INT, b VARCHAR(10));
INSERT INTO t1 VALUES (1,'a');
DELIMITER $$;
CREATE PROCEDURE p1()
AS
CURSOR cur1 IS SELECT a FROM t1;
rec1 cur1%ROWTYPE;
BEGIN
rec1.a:= 10;
END;
$$
DELIMITER ;$$
SHOW PROCEDURE CODE p1;
CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1;
--echo #
--echo # Recursive cursor and cursor%ROWTYPE declarations in the same block
--echo #
DELIMITER $$;
CREATE PROCEDURE p1
AS
a INT:=10;
CURSOR cur1 IS SELECT a;
rec1 cur1%ROWTYPE;
CURSOR cur2 IS SELECT rec1.a + 1 "a";
rec2 cur2%ROWTYPE;
BEGIN
OPEN cur1;
FETCH cur1 INTO rec1;
CLOSE cur1;
SELECT rec1.a;
open cur2;
FETCH cur2 INTO rec2;
CLOSE cur2;
SELECT rec2.a;
END;
$$
DELIMITER ;$$
SHOW PROCEDURE CODE p1;
CALL p1();
DROP PROCEDURE p1;
SET sql_mode=ORACLE;
--echo #
--echo # MDEV-10598 sql_mode=ORACLE: Variable declarations can go after cursor declarations
--echo #
--echo #
--echo # Variable after cursor declaration
--echo #
CREATE TABLE t1 (a INT);
insert into t1 values (1);
insert into t1 values (2);
DELIMITER $$;
CREATE PROCEDURE p1
AS
CURSOR c IS SELECT a FROM t1;
var1 varchar(10);
BEGIN
OPEN c;
fetch c into var1;
SELECT c%ROWCOUNT,var1;
close c;
END;
$$
DELIMITER ;$$
CALL p1;
DROP PROCEDURE p1;
drop table t1;
--echo #
--echo # Variable after condition declaration
--echo #
CREATE TABLE t1 (col1 INT);
insert into t1 values (1);
create unique index t1_col1 on t1 (col1);
DELIMITER $$;
CREATE PROCEDURE p1
AS
dup_key CONDITION FOR SQLSTATE '23000';
var1 varchar(40);
CONTINUE HANDLER FOR dup_key
BEGIN
var1:='duplicate key in index';
END;
BEGIN
var1:='';
insert into t1 values (1);
select var1;
END;
$$
DELIMITER ;$$
CALL p1;
DROP PROCEDURE p1;
drop table t1;
--echo #
--echo # Condition after cursor declaration
--echo #
CREATE TABLE t1 (col1 INT);
insert into t1 values (1);
create unique index t1_col1 on t1 (col1);
DELIMITER $$;
CREATE PROCEDURE p1
AS
var1 varchar(40);
var2 integer;
CURSOR c IS SELECT col1 FROM t1;
dup_key CONDITION FOR SQLSTATE '23000';
CONTINUE HANDLER FOR dup_key
BEGIN
var1:='duplicate key in index';
END;
BEGIN
var1:='';
insert into t1 values (1);
SELECT var1;
END;
$$
DELIMITER ;$$
CALL p1;
DROP PROCEDURE p1;
drop table t1;
--echo #
--echo # Cursor after handler declaration
--echo #
CREATE TABLE t1 (col1 INT);
insert into t1 values (1);
create unique index t1_col1 on t1 (col1);
DELIMITER $$;
--error ER_PARSE_ERROR
CREATE PROCEDURE p1
AS
var1 varchar(40);
var2 integer;
dup_key CONDITION FOR SQLSTATE '23000';
CONTINUE HANDLER FOR dup_key
BEGIN
var1:='duplicate key in index';
END;
CURSOR c IS SELECT col1 FROM t1;
BEGIN
var1:='';
insert into t1 values (1);
SELECT var1;
END;
$$
DELIMITER ;$$
drop table t1;
--echo #
--echo # Condition after handler declaration
--echo #
CREATE TABLE t1 (col1 INT);
insert into t1 values (1);
create unique index t1_col1 on t1 (col1);
DELIMITER $$;
--error ER_PARSE_ERROR
CREATE PROCEDURE p1
AS
var1 varchar(40);
var2 integer;
dup_key CONDITION FOR SQLSTATE '23000';
CURSOR c IS SELECT col1 FROM t1;
CONTINUE HANDLER FOR dup_key
BEGIN
var1:='duplicate key in index';
END;
divide_by_zero CONDITION FOR SQLSTATE '22012';
BEGIN
var1:='';
insert into t1 values (1);
SELECT var1;
END;
$$
DELIMITER ;$$
drop table t1;
--echo #
--echo # Variable after handler declaration
--echo #
CREATE TABLE t1 (col1 INT);
insert into t1 values (1);
create unique index t1_col1 on t1 (col1);
DELIMITER $$;
--error ER_PARSE_ERROR
CREATE PROCEDURE p1
AS
var1 varchar(40);
var2 integer;
dup_key CONDITION FOR SQLSTATE '23000';
CURSOR c IS SELECT col1 FROM t1;
CONTINUE HANDLER FOR dup_key
BEGIN
var1:='duplicate key in index';
END;
divide_by_zero CONDITION FOR SQLSTATE '22012';
BEGIN
var1:='';
insert into t1 values (1);
SELECT var1;
END;
$$
DELIMITER ;$$
drop table t1;
--echo #
--echo # Variable after cursor (inner block)
--echo #
CREATE TABLE t1 (col1 INT);
insert into t1 values (1);
insert into t1 values (2);
create unique index t1_col1 on t1 (col1);
DELIMITER $$;
CREATE PROCEDURE p1
AS
CURSOR c IS SELECT col1 FROM t1;
var1 varchar(40);
BEGIN
OPEN c;
begin
declare
CURSOR c IS SELECT col1 FROM t1 where col1=2;
var2 integer;
dup_key CONDITION FOR SQLSTATE '23000';
CONTINUE HANDLER FOR dup_key
BEGIN
var1:='duplicate key in index';
END;
begin
OPEN c;
fetch c into var1;
SELECT 'inner cursor',var1;
insert into t1 values (2);
close c;
end;
end;
SELECT var1;
fetch c into var1;
SELECT c%ROWCOUNT,var1;
begin
insert into t1 values (2);
exception when 1062 then
begin
SELECT 'dup key caugth';
end;
end;
close c;
END;
$$
DELIMITER ;$$
CALL p1;
DROP PROCEDURE p1;
drop table t1;
--echo #
--echo # Cursor declaration and row type declaration in same block
--echo #
CREATE TABLE t1 (a INT, b VARCHAR(10));
insert into t1 values(1,'a');
delimiter $$;
CREATE PROCEDURE p1()
AS
CURSOR cur1 IS SELECT a FROM t1;
rec1 cur1%ROWTYPE;
BEGIN
rec1.a:= 10;
END;
$$
delimiter ;$$
call p1;
DROP PROCEDURE p1;
drop table t1;
--echo #
--echo # Recursive cursor and cursor%ROWTYPE declarations in the same block
--echo #
delimiter $$;
CREATE PROCEDURE p1
AS
a INT:=10;
b VARCHAR(10):='b0';
c DOUBLE:=0.1;
CURSOR cur1 IS SELECT a, b, c;
rec1 cur1%ROWTYPE;
CURSOR cur2 IS SELECT rec1.a + 1 "a", rec1.b||'0' AS b, rec1.c AS c;
rec2 cur2%ROWTYPE;
BEGIN
OPEN cur1;
FETCH cur1 INTO rec1;
CLOSE cur1;
SELECT rec1.a;
OPEN cur2;
FETCH cur2 INTO rec2;
CLOSE cur2;
SELECT rec2.a;
CREATE TABLE t2 AS SELECT rec2.a AS a, rec2.b AS b, rec2.c AS c;
SHOW CREATE TABLE t2;
DROP TABLE t2;
END;
$$
DELIMITER ;$$
CALL p1();
DROP PROCEDURE p1;
......@@ -2423,6 +2423,23 @@ sp_head::do_cont_backpatch()
}
}
bool
sp_head::sp_add_instr_cpush_for_cursors(THD *thd, sp_pcontext *pcontext)
{
for (uint i= 0; i < pcontext->frame_cursor_count(); i++)
{
const sp_pcursor *c= pcontext->get_cursor_by_local_frame_offset(i);
sp_instr_cpush *instr= new (thd->mem_root)
sp_instr_cpush(instructions(), pcontext, c->lex(),
pcontext->cursor_offset() + i);
if (instr == NULL || add_instr(instr))
return true;
}
return false;
}
void
sp_head::set_info(longlong created, longlong modified,
st_sp_chistics *chistics, sql_mode_t sql_mode)
......
......@@ -573,6 +573,9 @@ class sp_head :private Query_arena,
void
do_cont_backpatch();
/// Add cpush instructions for all cursors declared in the current frame
bool sp_add_instr_cpush_for_cursors(THD *thd, sp_pcontext *pcontext);
char *name(uint *lenp = 0) const
{
if (lenp)
......
......@@ -659,6 +659,15 @@ class sp_pcontext : public Sql_alloc
/// Find cursor by offset (for SHOW {PROCEDURE|FUNCTION} CODE only).
const sp_pcursor *find_cursor(uint offset) const;
const sp_pcursor *get_cursor_by_local_frame_offset(uint offset) const
{ return &m_cursors.at(offset); }
uint cursor_offset() const
{ return m_cursor_offset; }
uint frame_cursor_count() const
{ return m_cursors.elements(); }
uint max_cursor_index() const
{ return m_max_cursor_index + m_cursors.elements(); }
......
......@@ -5628,7 +5628,7 @@ bool LEX::sp_for_loop_cursor_finalize(THD *thd, const Lex_for_loop_st &loop)
bool LEX::sp_declare_cursor(THD *thd, const LEX_STRING name,
sp_lex_cursor *cursor_stmt,
sp_pcontext *param_ctx)
sp_pcontext *param_ctx, bool add_cpush_instr)
{
uint offp;
sp_instr_cpush *i;
......@@ -5639,12 +5639,18 @@ bool LEX::sp_declare_cursor(THD *thd, const LEX_STRING name,
return true;
}
cursor_stmt->set_cursor_name(name);
i= new (thd->mem_root)
sp_instr_cpush(sphead->instructions(), spcont, cursor_stmt,
spcont->current_cursor_count());
return i == NULL ||
sphead->add_instr(i) ||
spcont->add_cursor(name, param_ctx, cursor_stmt);
if (spcont->add_cursor(name, param_ctx, cursor_stmt))
return true;
if (add_cpush_instr)
{
i= new (thd->mem_root)
sp_instr_cpush(sphead->instructions(), spcont, cursor_stmt,
spcont->current_cursor_count() - 1);
return i == NULL || sphead->add_instr(i);
}
return false;
}
......
......@@ -3165,7 +3165,8 @@ struct LEX: public Query_tables_list
bool sp_declare_cursor(THD *thd, const LEX_STRING name,
class sp_lex_cursor *cursor_stmt,
sp_pcontext *param_ctx);
sp_pcontext *param_ctx, bool add_cpush_instr);
bool sp_open_cursor(THD *thd, const LEX_STRING name,
List<sp_assignment_lex> *parameters);
Item_splocal *create_item_for_sp_var(LEX_STRING name, sp_variable *spvar,
......
......@@ -3022,7 +3022,7 @@ sp_decl_body:
}
| ident CURSOR_SYM FOR_SYM sp_cursor_stmt
{
if (Lex->sp_declare_cursor(thd, $1, $4, NULL))
if (Lex->sp_declare_cursor(thd, $1, $4, NULL, true))
MYSQL_YYABORT;
$$.vars= $$.conds= $$.hndlrs= 0;
$$.curs= 1;
......
......@@ -1335,7 +1335,9 @@ END_OF_INPUT
%type <num> sp_decl_idents sp_handler_type sp_hcond_list
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
%type <spblock> sp_decl_body sp_decl_body_list opt_sp_decl_body_list
%type <spblock> sp_decl_body_list opt_sp_decl_body_list
%type <spblock> sp_decl_non_handler sp_decl_non_handler_list
%type <spblock> sp_decl_handler sp_decl_handler_list opt_sp_decl_handler_list
%type <spblock_handlers> sp_block_statements_and_exceptions
%type <sp_instr_addr> sp_instr_addr
%type <sp_cursor_name_and_offset> sp_cursor_name_and_offset
......@@ -2444,12 +2446,37 @@ opt_sp_decl_body_list:
;
sp_decl_body_list:
sp_decl_body ';' { $$= $1; }
| sp_decl_body_list sp_decl_body ';'
sp_decl_non_handler_list
{
if (Lex->sp_declarations_join(&$$, $1, $2))
if (Lex->sphead->sp_add_instr_cpush_for_cursors(thd, Lex->spcont))
MYSQL_YYABORT;
}
opt_sp_decl_handler_list
{
$$.join($1, $3);
}
| sp_decl_handler_list
;
sp_decl_non_handler_list:
sp_decl_non_handler ';' { $$= $1; }
| sp_decl_non_handler_list sp_decl_non_handler ';'
{
$$.join($1, $2);
}
;
sp_decl_handler_list:
sp_decl_handler ';' { $$= $1; }
| sp_decl_handler_list sp_decl_handler ';'
{
$$.join($1, $2);
}
;
opt_sp_decl_handler_list:
/* Empty*/ { $$.init(); }
| sp_decl_handler_list
;
qualified_column_ident:
......@@ -2527,7 +2554,7 @@ type_or_rowtype:
| ROWTYPE_SYM { $$= 1; }
;
sp_decl_body:
sp_decl_non_handler:
sp_decl_idents
{
Lex->sp_variable_declarations_init(thd, $1);
......@@ -2581,18 +2608,6 @@ sp_decl_body:
$$.vars= $$.hndlrs= $$.curs= 0;
$$.conds= 1;
}
| sp_handler_type HANDLER_SYM FOR_SYM
{
if (Lex->sp_handler_declaration_init(thd, $1))
MYSQL_YYABORT;
}
sp_hcond_list sp_proc_stmt
{
if (Lex->sp_handler_declaration_finalize(thd, $1))
MYSQL_YYABORT;
$$.vars= $$.conds= $$.curs= 0;
$$.hndlrs= 1;
}
| CURSOR_SYM ident_directly_assignable
{
Lex->sp_block_init(thd);
......@@ -2603,13 +2618,28 @@ sp_decl_body:
sp_pcontext *param_ctx= Lex->spcont;
if (Lex->sp_block_finalize(thd))
MYSQL_YYABORT;
if (Lex->sp_declare_cursor(thd, $2, $6, param_ctx))
if (Lex->sp_declare_cursor(thd, $2, $6, param_ctx, false))
MYSQL_YYABORT;
$$.vars= $$.conds= $$.hndlrs= 0;
$$.curs= 1;
}
;
sp_decl_handler:
sp_handler_type HANDLER_SYM FOR_SYM
{
if (Lex->sp_handler_declaration_init(thd, $1))
MYSQL_YYABORT;
}
sp_hcond_list sp_proc_stmt
{
if (Lex->sp_handler_declaration_finalize(thd, $1))
MYSQL_YYABORT;
$$.vars= $$.conds= $$.curs= 0;
$$.hndlrs= 1;
}
;
opt_parenthesized_cursor_formal_parameters:
/* Empty */
| '(' sp_fdparams ')'
......@@ -3849,7 +3879,7 @@ sp_for_loop_bounds:
{
DBUG_ASSERT(Lex->sphead);
LEX_STRING name= {C_STRING_WITH_LEN("[implicit_cursor]") };
if (Lex->sp_declare_cursor(thd, name, $4, NULL))
if (Lex->sp_declare_cursor(thd, name, $4, NULL, true))
MYSQL_YYABORT;
$$.m_direction= 1;
if (!($$.m_index= new (thd->mem_root) sp_assignment_lex(thd, thd->lex)))
......
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