Commit 7e10e388 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-10411 Providing compatibility for basic PL/SQL constructs

Part2: Different order of IN, OUT, INOUT keywords in CREATE PROCEDURE params
parent 47a75ed7
SET sql_mode=ORACLE;
# Testing labels
CREATE FUNCTION f1 (a INT) RETURNS CLOB
BEGIN
<<label1>>
......@@ -66,3 +67,16 @@ SELECT f1(4);
f1(4)
2
DROP FUNCTION f1;
# Testing IN/OUT/INOUT
CREATE PROCEDURE p1 (p1 IN VARCHAR2(10), p2 OUT VARCHAR2(10))
BEGIN
SET p1='p1new';
SET p2='p2new';
END;
/
SET @p1='p1', @p2='p2';
CALL p1(@p1, @p2);
SELECT @p1, @p2;
@p1 @p2
p1 p2new
DROP PROCEDURE p1;
SET sql_mode=ORACLE;
--echo # Testing labels
DELIMITER /;
CREATE FUNCTION f1 (a INT) RETURNS CLOB
BEGIN
......@@ -18,7 +20,6 @@ SELECT f1(1);
SELECT f1(2);
DROP FUNCTION f1;
# LOOP WHILE REPEAT
DELIMITER /;
CREATE FUNCTION f1 (a INT) RETURNS INT
......@@ -72,3 +73,18 @@ END;
DELIMITER ;/
SELECT f1(4);
DROP FUNCTION f1;
--echo # Testing IN/OUT/INOUT
DELIMITER /;
CREATE PROCEDURE p1 (p1 IN VARCHAR2(10), p2 OUT VARCHAR2(10))
BEGIN
SET p1='p1new';
SET p2='p2new';
END;
/
DELIMITER ;/
SET @p1='p1', @p2='p2';
CALL p1(@p1, @p2);
SELECT @p1, @p2;
DROP PROCEDURE p1;
......@@ -5065,6 +5065,31 @@ void LEX::check_automatic_up(enum sub_select_type type)
}
}
sp_variable *LEX::sp_param_init(LEX_STRING name)
{
if (spcont->find_variable(name, true))
{
my_error(ER_SP_DUP_PARAM, MYF(0), name.str);
return NULL;
}
sp_variable *spvar= spcont->add_variable(thd, name);
init_last_field(&spvar->field_def, name.str,
thd->variables.collation_database);
return spvar;
}
bool LEX::sp_param_fill_definition(sp_variable *spvar)
{
if (sphead->fill_field_definition(thd, last_field))
return true;
spvar->field_def.field_name= spvar->name.str;
spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
return false;
}
#ifdef MYSQL_SERVER
uint binlog_unsafe_map[256];
......
......@@ -3051,6 +3051,8 @@ struct LEX: public Query_tables_list
}
return false;
}
sp_variable *sp_param_init(LEX_STRING name);
bool sp_param_fill_definition(sp_variable *spvar);
int case_stmt_action_expr(Item* expr);
int case_stmt_action_when(Item *when, bool simple);
......
......@@ -1964,7 +1964,7 @@ END_OF_INPUT
%type <lex> sp_cursor_stmt
%type <spname> sp_name
%type <splabel> sp_block_content
%type <spvar> sp_param_name_and_type
%type <spvar> sp_param_name sp_param_name_and_type
%type <spvar_mode> sp_opt_inout
%type <index_hint> index_hint_type
%type <num> index_hint_clause normal_join inner_join
......@@ -2937,34 +2937,19 @@ sp_fdparams:
| sp_param_name_and_type
;
sp_param_name_and_type:
sp_param_name:
ident
{
LEX *lex= Lex;
sp_pcontext *spc= lex->spcont;
if (spc->find_variable($1, TRUE))
my_yyabort_error((ER_SP_DUP_PARAM, MYF(0), $1.str));
sp_variable *spvar= spc->add_variable(thd, $1);
lex->init_last_field(&spvar->field_def, $1.str,
thd->variables.collation_database);
$<spvar>$= spvar;
if (!($$= Lex->sp_param_init($1)))
MYSQL_YYABORT;
}
type_with_opt_collate
{
LEX *lex= Lex;
sp_variable *spvar= $<spvar>2;
;
if (lex->sphead->fill_field_definition(thd, lex->last_field))
{
sp_param_name_and_type:
sp_param_name type_with_opt_collate
{
if (Lex->sp_param_fill_definition($$= $1))
MYSQL_YYABORT;
}
spvar->field_def.field_name= spvar->name.str;
spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
$$= spvar;
}
;
......
......@@ -1341,7 +1341,7 @@ END_OF_INPUT
%type <lex> sp_cursor_stmt
%type <spname> sp_name
%type <splabel> sp_block_content
%type <spvar> sp_param_name_and_type
%type <spvar> sp_param_name sp_param_name_and_type
%type <spvar_mode> sp_opt_inout
%type <index_hint> index_hint_type
%type <num> index_hint_clause normal_join inner_join
......@@ -2314,34 +2314,19 @@ sp_fdparams:
| sp_param_name_and_type
;
sp_param_name_and_type:
sp_param_name:
ident
{
LEX *lex= Lex;
sp_pcontext *spc= lex->spcont;
if (spc->find_variable($1, TRUE))
my_yyabort_error((ER_SP_DUP_PARAM, MYF(0), $1.str));
sp_variable *spvar= spc->add_variable(thd, $1);
lex->init_last_field(&spvar->field_def, $1.str,
thd->variables.collation_database);
$<spvar>$= spvar;
if (!($$= Lex->sp_param_init($1)))
MYSQL_YYABORT;
}
type_with_opt_collate
{
LEX *lex= Lex;
sp_variable *spvar= $<spvar>2;
;
if (lex->sphead->fill_field_definition(thd, lex->last_field))
{
sp_param_name_and_type:
sp_param_name type_with_opt_collate
{
if (Lex->sp_param_fill_definition($$= $1))
MYSQL_YYABORT;
}
spvar->field_def.field_name= spvar->name.str;
spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
$$= spvar;
}
;
......@@ -2357,7 +2342,12 @@ sp_pdparams:
;
sp_pdparam:
sp_opt_inout sp_param_name_and_type { $2->mode=$1; }
sp_param_name sp_opt_inout type_with_opt_collate
{
$1->mode= $2;
if (Lex->sp_param_fill_definition($1))
MYSQL_YYABORT;
}
;
sp_opt_inout:
......
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