diff --git a/mysql-test/suite/compat/oracle/r/sp.result b/mysql-test/suite/compat/oracle/r/sp.result index 99845551f1bf8..7490feb05b8f7 100644 --- a/mysql-test/suite/compat/oracle/r/sp.result +++ b/mysql-test/suite/compat/oracle/r/sp.result @@ -1,4 +1,5 @@ SET sql_mode=ORACLE; +# Testing labels CREATE FUNCTION f1 (a INT) RETURNS CLOB BEGIN <> @@ -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; diff --git a/mysql-test/suite/compat/oracle/t/sp.test b/mysql-test/suite/compat/oracle/t/sp.test index ad55f4006a38a..dd14ab918acaf 100644 --- a/mysql-test/suite/compat/oracle/t/sp.test +++ b/mysql-test/suite/compat/oracle/t/sp.test @@ -1,5 +1,7 @@ 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; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index c7f964bb9164e..d28504431e214 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -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]; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 0918c223d3c84..0b433867974dd 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -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); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b5dc995521e89..9eb5669a60f72 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1964,7 +1964,7 @@ END_OF_INPUT %type sp_cursor_stmt %type sp_name %type sp_block_content -%type sp_param_name_and_type +%type sp_param_name sp_param_name_and_type %type sp_opt_inout %type index_hint_type %type 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; + if (!($$= Lex->sp_param_init($1))) + MYSQL_YYABORT; } - type_with_opt_collate - { - LEX *lex= Lex; - sp_variable *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; } ; diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 0d1b61fdc1a72..081a26f2c05dc 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -1341,7 +1341,7 @@ END_OF_INPUT %type sp_cursor_stmt %type sp_name %type sp_block_content -%type sp_param_name_and_type +%type sp_param_name sp_param_name_and_type %type sp_opt_inout %type index_hint_type %type 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; + if (!($$= Lex->sp_param_init($1))) + MYSQL_YYABORT; } - type_with_opt_collate - { - LEX *lex= Lex; - sp_variable *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: