mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-10411 Providing compatibility for basic PL/SQL constructs
Part 7: variable declarations
This commit is contained in:
@ -252,3 +252,101 @@ CREATE TABLE begin (begin INT);
|
|||||||
DROP TABLE begin;
|
DROP TABLE begin;
|
||||||
CREATE TABLE end (end INT);
|
CREATE TABLE end (end INT);
|
||||||
DROP TABLE end;
|
DROP TABLE end;
|
||||||
|
# Testing top-level declarations
|
||||||
|
CREATE PROCEDURE p1 (p1 OUT VARCHAR2(10))
|
||||||
|
AS
|
||||||
|
p2 VARCHAR(10);
|
||||||
|
BEGIN
|
||||||
|
p2:='p1new';
|
||||||
|
p1:=p2;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
SET @p1='p1';
|
||||||
|
CALL p1(@p1);
|
||||||
|
SELECT @p1;
|
||||||
|
@p1
|
||||||
|
p1new
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
CREATE FUNCTION f1 (p1 VARCHAR2(10)) RETURNS VARCHAR(20)
|
||||||
|
AS
|
||||||
|
p2 VARCHAR(10);
|
||||||
|
BEGIN
|
||||||
|
p2:='new';
|
||||||
|
RETURN CONCAT(p1, p2);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
SET @p1='p1';
|
||||||
|
SELECT f1(@p1);
|
||||||
|
f1(@p1)
|
||||||
|
p1new
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
# Testing non-top declarations
|
||||||
|
CREATE PROCEDURE p1 (p1 OUT VARCHAR2(10))
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
DECLARE
|
||||||
|
p2 VARCHAR(10);
|
||||||
|
BEGIN
|
||||||
|
p2:='p1new';
|
||||||
|
p1:=p2;
|
||||||
|
END;
|
||||||
|
DECLARE
|
||||||
|
t1 VARCHAR(10);
|
||||||
|
t2 VARCHAR(10);
|
||||||
|
BEGIN
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
SET @p1='p1';
|
||||||
|
CALL p1(@p1);
|
||||||
|
SELECT @p1;
|
||||||
|
@p1
|
||||||
|
p1new
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
CREATE FUNCTION f1 (p1 VARCHAR2(10)) RETURNS VARCHAR(20)
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
DECLARE
|
||||||
|
p2 VARCHAR(10);
|
||||||
|
BEGIN
|
||||||
|
p2:='new';
|
||||||
|
RETURN CONCAT(p1, p2);
|
||||||
|
END;
|
||||||
|
DECLARE
|
||||||
|
t1 VARCHAR(10);
|
||||||
|
t2 VARCHAR(10);
|
||||||
|
BEGIN
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
SET @p1='p1';
|
||||||
|
SELECT f1(@p1);
|
||||||
|
f1(@p1)
|
||||||
|
p1new
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
# Testing BEGIN NOT ATOMIC with no declarations
|
||||||
|
BEGIN NOT ATOMIC
|
||||||
|
SELECT 1 AS a;
|
||||||
|
END
|
||||||
|
/
|
||||||
|
a
|
||||||
|
1
|
||||||
|
# Testing BEGIN NOT ATOMIC with declarations
|
||||||
|
# DECLARE starts a new block and thus must be followed by BEGIN .. END
|
||||||
|
BEGIN NOT ATOMIC
|
||||||
|
DECLARE
|
||||||
|
i INT DEFAULT 5;
|
||||||
|
x INT DEFAULT 10;
|
||||||
|
BEGIN
|
||||||
|
<<label>>
|
||||||
|
WHILE i > 3 DO
|
||||||
|
i:= i - 1;
|
||||||
|
SELECT i;
|
||||||
|
END WHILE label;
|
||||||
|
END;
|
||||||
|
END
|
||||||
|
/
|
||||||
|
i
|
||||||
|
4
|
||||||
|
i
|
||||||
|
3
|
||||||
|
@ -272,3 +272,108 @@ CREATE TABLE begin (begin INT);
|
|||||||
DROP TABLE begin;
|
DROP TABLE begin;
|
||||||
CREATE TABLE end (end INT);
|
CREATE TABLE end (end INT);
|
||||||
DROP TABLE end;
|
DROP TABLE end;
|
||||||
|
|
||||||
|
|
||||||
|
--echo # Testing top-level declarations
|
||||||
|
DELIMITER /;
|
||||||
|
CREATE PROCEDURE p1 (p1 OUT VARCHAR2(10))
|
||||||
|
AS
|
||||||
|
p2 VARCHAR(10);
|
||||||
|
BEGIN
|
||||||
|
p2:='p1new';
|
||||||
|
p1:=p2;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
DELIMITER ;/
|
||||||
|
SET @p1='p1';
|
||||||
|
CALL p1(@p1);
|
||||||
|
SELECT @p1;
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
|
||||||
|
DELIMITER /;
|
||||||
|
CREATE FUNCTION f1 (p1 VARCHAR2(10)) RETURNS VARCHAR(20)
|
||||||
|
AS
|
||||||
|
p2 VARCHAR(10);
|
||||||
|
BEGIN
|
||||||
|
p2:='new';
|
||||||
|
RETURN CONCAT(p1, p2);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
DELIMITER ;/
|
||||||
|
SET @p1='p1';
|
||||||
|
SELECT f1(@p1);
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
|
||||||
|
--echo # Testing non-top declarations
|
||||||
|
|
||||||
|
DELIMITER /;
|
||||||
|
CREATE PROCEDURE p1 (p1 OUT VARCHAR2(10))
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
DECLARE
|
||||||
|
p2 VARCHAR(10);
|
||||||
|
BEGIN
|
||||||
|
p2:='p1new';
|
||||||
|
p1:=p2;
|
||||||
|
END;
|
||||||
|
DECLARE
|
||||||
|
t1 VARCHAR(10);
|
||||||
|
t2 VARCHAR(10);
|
||||||
|
BEGIN
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
DELIMITER ;/
|
||||||
|
SET @p1='p1';
|
||||||
|
CALL p1(@p1);
|
||||||
|
SELECT @p1;
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
|
||||||
|
DELIMITER /;
|
||||||
|
CREATE FUNCTION f1 (p1 VARCHAR2(10)) RETURNS VARCHAR(20)
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
DECLARE
|
||||||
|
p2 VARCHAR(10);
|
||||||
|
BEGIN
|
||||||
|
p2:='new';
|
||||||
|
RETURN CONCAT(p1, p2);
|
||||||
|
END;
|
||||||
|
DECLARE
|
||||||
|
t1 VARCHAR(10);
|
||||||
|
t2 VARCHAR(10);
|
||||||
|
BEGIN
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
DELIMITER ;/
|
||||||
|
SET @p1='p1';
|
||||||
|
SELECT f1(@p1);
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo # Testing BEGIN NOT ATOMIC with no declarations
|
||||||
|
DELIMITER /;
|
||||||
|
BEGIN NOT ATOMIC
|
||||||
|
SELECT 1 AS a;
|
||||||
|
END
|
||||||
|
/
|
||||||
|
DELIMITER ;/
|
||||||
|
|
||||||
|
--echo # Testing BEGIN NOT ATOMIC with declarations
|
||||||
|
--echo # DECLARE starts a new block and thus must be followed by BEGIN .. END
|
||||||
|
DELIMITER /;
|
||||||
|
BEGIN NOT ATOMIC
|
||||||
|
DECLARE
|
||||||
|
i INT DEFAULT 5;
|
||||||
|
x INT DEFAULT 10;
|
||||||
|
BEGIN
|
||||||
|
<<label>>
|
||||||
|
WHILE i > 3 DO
|
||||||
|
i:= i - 1;
|
||||||
|
SELECT i;
|
||||||
|
END WHILE label;
|
||||||
|
END;
|
||||||
|
END
|
||||||
|
/
|
||||||
|
DELIMITER ;/
|
||||||
|
@ -3097,8 +3097,16 @@ public:
|
|||||||
class sp_label *tmp;
|
class sp_label *tmp;
|
||||||
return sp_block_finalize(thd, spblock, &tmp);
|
return sp_block_finalize(thd, spblock, &tmp);
|
||||||
}
|
}
|
||||||
|
bool sp_block_finalize(THD *thd)
|
||||||
|
{
|
||||||
|
return sp_block_finalize(thd, Lex_spblock());
|
||||||
|
}
|
||||||
bool sp_block_finalize(THD *thd, const Lex_spblock_st spblock,
|
bool sp_block_finalize(THD *thd, const Lex_spblock_st spblock,
|
||||||
const LEX_STRING end_label);
|
const LEX_STRING end_label);
|
||||||
|
bool sp_block_finalize(THD *thd, const LEX_STRING end_label)
|
||||||
|
{
|
||||||
|
return sp_block_finalize(thd, Lex_spblock(), end_label);
|
||||||
|
}
|
||||||
bool sp_declarations_join(Lex_spblock_st *res,
|
bool sp_declarations_join(Lex_spblock_st *res,
|
||||||
const Lex_spblock_st b1,
|
const Lex_spblock_st b1,
|
||||||
const Lex_spblock_st b2) const
|
const Lex_spblock_st b2) const
|
||||||
|
@ -1329,7 +1329,7 @@ END_OF_INPUT
|
|||||||
|
|
||||||
%type <num> sp_decl_idents sp_handler_type sp_hcond_list
|
%type <num> sp_decl_idents sp_handler_type sp_hcond_list
|
||||||
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
|
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
|
||||||
%type <spblock> sp_decls sp_decl sp_decl_body
|
%type <spblock> sp_decl_body sp_decl_body_list opt_sp_decl_body_list
|
||||||
%type <lex> sp_cursor_stmt
|
%type <lex> sp_cursor_stmt
|
||||||
%type <spname> sp_name
|
%type <spname> sp_name
|
||||||
%type <spvar> sp_param_name sp_param_name_and_type
|
%type <spvar> sp_param_name sp_param_name_and_type
|
||||||
@ -2359,26 +2359,23 @@ sp_proc_stmts1:
|
|||||||
| sp_proc_stmts1 sp_proc_stmt ';'
|
| sp_proc_stmts1 sp_proc_stmt ';'
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_decls:
|
opt_sp_decl_body_list:
|
||||||
/* Empty */
|
/* Empty */
|
||||||
{
|
{
|
||||||
$$.init();
|
$$.init();
|
||||||
}
|
}
|
||||||
| sp_decls sp_decl ';'
|
| sp_decl_body_list { $$= $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
sp_decl_body_list:
|
||||||
|
sp_decl_body ';' { $$= $1; }
|
||||||
|
| sp_decl_body_list sp_decl_body ';'
|
||||||
{
|
{
|
||||||
/* 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 (Lex->sp_declarations_join(&$$, $1, $2))
|
if (Lex->sp_declarations_join(&$$, $1, $2))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_decl:
|
|
||||||
DECLARE_SYM sp_decl_body { $$= $2; }
|
|
||||||
;
|
|
||||||
|
|
||||||
sp_decl_body:
|
sp_decl_body:
|
||||||
sp_decl_idents
|
sp_decl_idents
|
||||||
{
|
{
|
||||||
@ -2392,7 +2389,7 @@ sp_decl_body:
|
|||||||
$$.vars= $1;
|
$$.vars= $1;
|
||||||
$$.conds= $$.hndlrs= $$.curs= 0;
|
$$.conds= $$.hndlrs= $$.curs= 0;
|
||||||
}
|
}
|
||||||
| ident CONDITION_SYM FOR_SYM sp_cond
|
| ident_directly_assignable CONDITION_SYM FOR_SYM sp_cond
|
||||||
{
|
{
|
||||||
if (Lex->spcont->declare_condition(thd, $1, $4))
|
if (Lex->spcont->declare_condition(thd, $1, $4))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
@ -2411,7 +2408,7 @@ sp_decl_body:
|
|||||||
$$.vars= $$.conds= $$.curs= 0;
|
$$.vars= $$.conds= $$.curs= 0;
|
||||||
$$.hndlrs= 1;
|
$$.hndlrs= 1;
|
||||||
}
|
}
|
||||||
| ident CURSOR_SYM FOR_SYM sp_cursor_stmt
|
| ident_directly_assignable CURSOR_SYM FOR_SYM sp_cursor_stmt
|
||||||
{
|
{
|
||||||
if (Lex->sp_declare_cursor(thd, $1, $4))
|
if (Lex->sp_declare_cursor(thd, $1, $4))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
@ -2823,7 +2820,7 @@ condition_information_item_name:
|
|||||||
;
|
;
|
||||||
|
|
||||||
sp_decl_idents:
|
sp_decl_idents:
|
||||||
ident
|
ident_directly_assignable
|
||||||
{
|
{
|
||||||
/* NOTE: field definition is filled in sp_decl section. */
|
/* NOTE: field definition is filled in sp_decl section. */
|
||||||
|
|
||||||
@ -3381,12 +3378,25 @@ sp_labeled_block:
|
|||||||
{
|
{
|
||||||
Lex->sp_block_init(thd, $1);
|
Lex->sp_block_init(thd, $1);
|
||||||
}
|
}
|
||||||
sp_decls
|
|
||||||
sp_proc_stmts
|
sp_proc_stmts
|
||||||
END
|
END
|
||||||
sp_opt_label
|
sp_opt_label
|
||||||
{
|
{
|
||||||
if (Lex->sp_block_finalize(thd, $4, $7))
|
if (Lex->sp_block_finalize(thd, $6))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| sp_block_label
|
||||||
|
DECLARE_SYM
|
||||||
|
{
|
||||||
|
Lex->sp_block_init(thd, $1);
|
||||||
|
}
|
||||||
|
sp_decl_body_list
|
||||||
|
BEGIN_SYM
|
||||||
|
sp_proc_stmts
|
||||||
|
END
|
||||||
|
sp_opt_label
|
||||||
|
{
|
||||||
|
if (Lex->sp_block_finalize(thd, $4, $8))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -3396,7 +3406,18 @@ sp_unlabeled_block:
|
|||||||
{
|
{
|
||||||
Lex->sp_block_init(thd);
|
Lex->sp_block_init(thd);
|
||||||
}
|
}
|
||||||
sp_decls
|
sp_proc_stmts
|
||||||
|
END
|
||||||
|
{
|
||||||
|
if (Lex->sp_block_finalize(thd))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| DECLARE_SYM
|
||||||
|
{
|
||||||
|
Lex->sp_block_init(thd);
|
||||||
|
}
|
||||||
|
sp_decl_body_list
|
||||||
|
BEGIN_SYM
|
||||||
sp_proc_stmts
|
sp_proc_stmts
|
||||||
END
|
END
|
||||||
{
|
{
|
||||||
@ -3405,6 +3426,20 @@ sp_unlabeled_block:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
sp_body:
|
||||||
|
{
|
||||||
|
Lex->sp_block_init(thd);
|
||||||
|
}
|
||||||
|
opt_sp_decl_body_list
|
||||||
|
BEGIN_SYM
|
||||||
|
sp_proc_stmts
|
||||||
|
END
|
||||||
|
{
|
||||||
|
if (Lex->sp_block_finalize(thd, $2))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
sp_unlabeled_block_not_atomic:
|
sp_unlabeled_block_not_atomic:
|
||||||
BEGIN_SYM not ATOMIC_SYM /* TODO: BEGIN ATOMIC (not -> opt_not) */
|
BEGIN_SYM not ATOMIC_SYM /* TODO: BEGIN ATOMIC (not -> opt_not) */
|
||||||
{
|
{
|
||||||
@ -3412,11 +3447,10 @@ sp_unlabeled_block_not_atomic:
|
|||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
Lex->sp_block_init(thd);
|
Lex->sp_block_init(thd);
|
||||||
}
|
}
|
||||||
sp_decls
|
|
||||||
sp_proc_stmts
|
sp_proc_stmts
|
||||||
END
|
END
|
||||||
{
|
{
|
||||||
if (Lex->sp_block_finalize(thd, $5))
|
if (Lex->sp_block_finalize(thd))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -15982,7 +16016,7 @@ sf_tail:
|
|||||||
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
|
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
|
||||||
}
|
}
|
||||||
sp_tail_is /* $15 */
|
sp_tail_is /* $15 */
|
||||||
sp_proc_stmt_in_returns_clause /* $16 */
|
sp_body /* $16 */
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
sp_head *sp= lex->sphead;
|
sp_head *sp= lex->sphead;
|
||||||
@ -16031,7 +16065,7 @@ sp_tail:
|
|||||||
Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
|
Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
|
||||||
}
|
}
|
||||||
sp_tail_is
|
sp_tail_is
|
||||||
sp_proc_stmt
|
sp_body
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_head *sp= lex->sphead;
|
sp_head *sp= lex->sphead;
|
||||||
|
@ -649,4 +649,10 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Lex_spblock: public Lex_spblock_st
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Lex_spblock() { init(); }
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* STRUCTS_INCLUDED */
|
#endif /* STRUCTS_INCLUDED */
|
||||||
|
Reference in New Issue
Block a user