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; SET sql_mode=ORACLE;
# Testing labels
CREATE FUNCTION f1 (a INT) RETURNS CLOB CREATE FUNCTION f1 (a INT) RETURNS CLOB
BEGIN BEGIN
<<label1>> <<label1>>
...@@ -66,3 +67,16 @@ SELECT f1(4); ...@@ -66,3 +67,16 @@ SELECT f1(4);
f1(4) f1(4)
2 2
DROP FUNCTION f1; 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; SET sql_mode=ORACLE;
--echo # Testing labels
DELIMITER /; DELIMITER /;
CREATE FUNCTION f1 (a INT) RETURNS CLOB CREATE FUNCTION f1 (a INT) RETURNS CLOB
BEGIN BEGIN
...@@ -18,7 +20,6 @@ SELECT f1(1); ...@@ -18,7 +20,6 @@ SELECT f1(1);
SELECT f1(2); SELECT f1(2);
DROP FUNCTION f1; DROP FUNCTION f1;
# LOOP WHILE REPEAT
DELIMITER /; DELIMITER /;
CREATE FUNCTION f1 (a INT) RETURNS INT CREATE FUNCTION f1 (a INT) RETURNS INT
...@@ -72,3 +73,18 @@ END; ...@@ -72,3 +73,18 @@ END;
DELIMITER ;/ DELIMITER ;/
SELECT f1(4); SELECT f1(4);
DROP FUNCTION f1; 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) ...@@ -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 #ifdef MYSQL_SERVER
uint binlog_unsafe_map[256]; uint binlog_unsafe_map[256];
......
...@@ -3051,6 +3051,8 @@ struct LEX: public Query_tables_list ...@@ -3051,6 +3051,8 @@ struct LEX: public Query_tables_list
} }
return false; 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_expr(Item* expr);
int case_stmt_action_when(Item *when, bool simple); int case_stmt_action_when(Item *when, bool simple);
......
...@@ -1964,7 +1964,7 @@ END_OF_INPUT ...@@ -1964,7 +1964,7 @@ END_OF_INPUT
%type <lex> sp_cursor_stmt %type <lex> sp_cursor_stmt
%type <spname> sp_name %type <spname> sp_name
%type <splabel> sp_block_content %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 <spvar_mode> sp_opt_inout
%type <index_hint> index_hint_type %type <index_hint> index_hint_type
%type <num> index_hint_clause normal_join inner_join %type <num> index_hint_clause normal_join inner_join
...@@ -2937,34 +2937,19 @@ sp_fdparams: ...@@ -2937,34 +2937,19 @@ sp_fdparams:
| sp_param_name_and_type | sp_param_name_and_type
; ;
sp_param_name_and_type: sp_param_name:
ident ident
{ {
LEX *lex= Lex; if (!($$= Lex->sp_param_init($1)))
sp_pcontext *spc= lex->spcont; MYSQL_YYABORT;
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;
} }
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; 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 ...@@ -1341,7 +1341,7 @@ END_OF_INPUT
%type <lex> sp_cursor_stmt %type <lex> sp_cursor_stmt
%type <spname> sp_name %type <spname> sp_name
%type <splabel> sp_block_content %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 <spvar_mode> sp_opt_inout
%type <index_hint> index_hint_type %type <index_hint> index_hint_type
%type <num> index_hint_clause normal_join inner_join %type <num> index_hint_clause normal_join inner_join
...@@ -2314,34 +2314,19 @@ sp_fdparams: ...@@ -2314,34 +2314,19 @@ sp_fdparams:
| sp_param_name_and_type | sp_param_name_and_type
; ;
sp_param_name_and_type: sp_param_name:
ident ident
{ {
LEX *lex= Lex; if (!($$= Lex->sp_param_init($1)))
sp_pcontext *spc= lex->spcont; MYSQL_YYABORT;
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;
} }
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; 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: ...@@ -2357,7 +2342,12 @@ sp_pdparams:
; ;
sp_pdparam: 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: 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