Skip to content

Commit

Permalink
MDEV-10411 Providing compatibility for basic PL/SQL constructs
Browse files Browse the repository at this point in the history
Part2: Different order of IN, OUT, INOUT keywords in CREATE PROCEDURE params
  • Loading branch information
Alexander Barkov committed Apr 5, 2017
1 parent 47a75ed commit 7e10e38
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 50 deletions.
14 changes: 14 additions & 0 deletions 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
<<label1>>
Expand Down Expand Up @@ -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;
18 changes: 17 additions & 1 deletion 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
Expand All @@ -18,7 +20,6 @@ SELECT f1(1);
SELECT f1(2);
DROP FUNCTION f1;

# LOOP WHILE REPEAT

DELIMITER /;
CREATE FUNCTION f1 (a INT) RETURNS INT
Expand Down Expand Up @@ -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;
25 changes: 25 additions & 0 deletions sql/sql_lex.cc
Expand Up @@ -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];

Expand Down
2 changes: 2 additions & 0 deletions sql/sql_lex.h
Expand Up @@ -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);
Expand Down
33 changes: 9 additions & 24 deletions sql/sql_yacc.yy
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
;

Expand Down
40 changes: 15 additions & 25 deletions sql/sql_yacc_ora.yy
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
;

Expand All @@ -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:
Expand Down

0 comments on commit 7e10e38

Please sign in to comment.