mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
A clean-up for MDEV-10654 add support IN, OUT, INOUT parameter qualifiers for stored functions
Changes: 1. Enabling IN/OUT/INOUT mode for sql_mode=DEFAULT, adding tests for sql_mode=DEFAULT based by mostly translating compat/oracle.sp-inout.test to SQL/PSM with minor changes (e.g. testing trigger OLD.column and NEW.column as IN/OUT parameters). 2. Removing duplicate grammar: sp_pdparam and sp_fdparam implemented exactly the same syntax after - the first patch for MDEV-10654 (for sql_mode=ORACLE) - the change #1 from this patch (for sql_mode=DEFAULT) Removing separate rules and adding a single "sp_param" rule instead, which now covers both PRDEDURE and FUNCTION parameters (and CURSOR parameters as well!). 3. Adding a helper rule sp_param_name_and_mode, which is a combination of the parameter name and the IN/OUT/INOUT mode. It allows to simplify the grammer a bit. 4. The first patch unintentionally allowed IN/OUT/INOUT mode to be specified in CURSOR parameters. This is good for the IN keyword - it is allowed in PL/SQL CURSORs. This is not good the the OUT/INOUT keywords - they should not be allowed. Adding a additional symantic post-check.
This commit is contained in:
@ -737,3 +737,43 @@ rec.en1
|
||||
c
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Start of 10.8 tests
|
||||
#
|
||||
#
|
||||
# MDEV-10654 IN, OUT, INOUT parameters in CREATE FUNCTION
|
||||
#
|
||||
BEGIN NOT ATOMIC
|
||||
DECLARE va INT;
|
||||
DECLARE cur CURSOR (IN a INT) FOR SELECT a FROM dual;
|
||||
OPEN cur(1);
|
||||
FETCH cur INTO va;
|
||||
CLOSE cur;
|
||||
SELECT va;
|
||||
END;
|
||||
$$
|
||||
va
|
||||
1
|
||||
BEGIN NOT ATOMIC
|
||||
DECLARE va INT;
|
||||
DECLARE cur CURSOR (OUT a INT) FOR SELECT a FROM dual;
|
||||
OPEN cur(1);
|
||||
FETCH cur INTO va;
|
||||
CLOSE cur;
|
||||
SELECT va;
|
||||
END;
|
||||
$$
|
||||
ERROR 42000: This version of MariaDB doesn't yet support 'OUT/INOUT cursor parameter'
|
||||
BEGIN NOT ATOMIC
|
||||
DECLARE va INT;
|
||||
DECLARE cur CURSOR (INOUT a INT) FOR SELECT a FROM dual;
|
||||
OPEN cur(1);
|
||||
FETCH cur INTO va;
|
||||
CLOSE cur;
|
||||
SELECT va;
|
||||
END;
|
||||
$$
|
||||
ERROR 42000: This version of MariaDB doesn't yet support 'OUT/INOUT cursor parameter'
|
||||
#
|
||||
# End of 10.8 tests
|
||||
#
|
||||
|
@ -744,3 +744,54 @@ DELIMITER ;$$
|
||||
CALL p1();
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Start of 10.8 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-10654 IN, OUT, INOUT parameters in CREATE FUNCTION
|
||||
--echo #
|
||||
|
||||
DELIMITER $$;
|
||||
BEGIN NOT ATOMIC
|
||||
DECLARE va INT;
|
||||
DECLARE cur CURSOR (IN a INT) FOR SELECT a FROM dual;
|
||||
OPEN cur(1);
|
||||
FETCH cur INTO va;
|
||||
CLOSE cur;
|
||||
SELECT va;
|
||||
END;
|
||||
$$
|
||||
DELIMITER ;$$
|
||||
|
||||
DELIMITER $$;
|
||||
--error ER_NOT_SUPPORTED_YET
|
||||
BEGIN NOT ATOMIC
|
||||
DECLARE va INT;
|
||||
DECLARE cur CURSOR (OUT a INT) FOR SELECT a FROM dual;
|
||||
OPEN cur(1);
|
||||
FETCH cur INTO va;
|
||||
CLOSE cur;
|
||||
SELECT va;
|
||||
END;
|
||||
$$
|
||||
DELIMITER ;$$
|
||||
|
||||
DELIMITER $$;
|
||||
--error ER_NOT_SUPPORTED_YET
|
||||
BEGIN NOT ATOMIC
|
||||
DECLARE va INT;
|
||||
DECLARE cur CURSOR (INOUT a INT) FOR SELECT a FROM dual;
|
||||
OPEN cur(1);
|
||||
FETCH cur INTO va;
|
||||
CLOSE cur;
|
||||
SELECT va;
|
||||
END;
|
||||
$$
|
||||
DELIMITER ;$$
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.8 tests
|
||||
--echo #
|
||||
|
2033
mysql-test/main/sp-inout.result
Normal file
2033
mysql-test/main/sp-inout.result
Normal file
File diff suppressed because it is too large
Load Diff
1964
mysql-test/main/sp-inout.test
Normal file
1964
mysql-test/main/sp-inout.test
Normal file
File diff suppressed because it is too large
Load Diff
@ -977,3 +977,46 @@ $$
|
||||
CALL p1();
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Start of 10.8 tests
|
||||
#
|
||||
#
|
||||
# MDEV-10654 IN, OUT, INOUT parameters in CREATE FUNCTION
|
||||
#
|
||||
DECLARE
|
||||
va INT;
|
||||
CURSOR cur (a IN INT) IS SELECT a FROM dual;
|
||||
BEGIN
|
||||
OPEN cur(1);
|
||||
FETCH cur INTO va;
|
||||
CLOSE cur;
|
||||
SELECT va;
|
||||
END;
|
||||
$$
|
||||
va
|
||||
1
|
||||
DECLARE
|
||||
va INT;
|
||||
CURSOR cur (a OUT INT) IS SELECT a FROM dual;
|
||||
BEGIN
|
||||
OPEN cur(1);
|
||||
FETCH cur INTO va;
|
||||
CLOSE cur;
|
||||
SELECT va;
|
||||
END;
|
||||
$$
|
||||
ERROR 42000: This version of MariaDB doesn't yet support 'OUT/INOUT cursor parameter'
|
||||
DECLARE
|
||||
va INT;
|
||||
CURSOR cur (a INOUT INT) IS SELECT a FROM dual;
|
||||
BEGIN
|
||||
OPEN cur(1);
|
||||
FETCH cur INTO va;
|
||||
CLOSE cur;
|
||||
SELECT va;
|
||||
END;
|
||||
$$
|
||||
ERROR 42000: This version of MariaDB doesn't yet support 'OUT/INOUT cursor parameter'
|
||||
#
|
||||
# End of 10.8 tests
|
||||
#
|
||||
|
@ -987,3 +987,58 @@ DELIMITER ;$$
|
||||
CALL p1();
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Start of 10.8 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-10654 IN, OUT, INOUT parameters in CREATE FUNCTION
|
||||
--echo #
|
||||
|
||||
DELIMITER $$;
|
||||
DECLARE
|
||||
va INT;
|
||||
CURSOR cur (a IN INT) IS SELECT a FROM dual;
|
||||
BEGIN
|
||||
OPEN cur(1);
|
||||
FETCH cur INTO va;
|
||||
CLOSE cur;
|
||||
SELECT va;
|
||||
END;
|
||||
$$
|
||||
DELIMITER ;$$
|
||||
|
||||
DELIMITER $$;
|
||||
--error ER_NOT_SUPPORTED_YET
|
||||
DECLARE
|
||||
va INT;
|
||||
CURSOR cur (a OUT INT) IS SELECT a FROM dual;
|
||||
BEGIN
|
||||
OPEN cur(1);
|
||||
FETCH cur INTO va;
|
||||
CLOSE cur;
|
||||
SELECT va;
|
||||
END;
|
||||
$$
|
||||
DELIMITER ;$$
|
||||
|
||||
DELIMITER $$;
|
||||
--error ER_NOT_SUPPORTED_YET
|
||||
DECLARE
|
||||
va INT;
|
||||
CURSOR cur (a INOUT INT) IS SELECT a FROM dual;
|
||||
BEGIN
|
||||
OPEN cur(1);
|
||||
FETCH cur INTO va;
|
||||
CLOSE cur;
|
||||
SELECT va;
|
||||
END;
|
||||
$$
|
||||
DELIMITER ;$$
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.8 tests
|
||||
--echo #
|
||||
|
@ -7130,6 +7130,27 @@ bool LEX::sp_declare_cursor(THD *thd, const LEX_CSTRING *name,
|
||||
uint offp;
|
||||
sp_instr_cpush *i;
|
||||
|
||||
/* In some cases param_ctx can be NULL. e.g.: FOR rec IN (SELECT...) */
|
||||
if (param_ctx)
|
||||
{
|
||||
for (uint prm= 0; prm < param_ctx->context_var_count(); prm++)
|
||||
{
|
||||
const sp_variable *param= param_ctx->get_context_variable(prm);
|
||||
if (param->mode != sp_variable::MODE_IN)
|
||||
{
|
||||
/*
|
||||
PL/SQL supports the IN keyword in cursor parameters.
|
||||
We also support this for compatibility. Note, OUT/INOUT parameters
|
||||
will unlikely be ever supported. So "YET" may sound confusing here.
|
||||
But it should be better than using a generic error. Adding a dedicated
|
||||
error message for this small issue is not desirable.
|
||||
*/
|
||||
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "OUT/INOUT cursor parameter");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (spcont->find_cursor(name, &offp, true))
|
||||
{
|
||||
my_error(ER_SP_DUP_CURS, MYF(0), name->str);
|
||||
|
136
sql/sql_yacc.yy
136
sql/sql_yacc.yy
@ -1749,8 +1749,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
||||
%type <num> sp_handler_type sp_hcond_list
|
||||
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
|
||||
%type <spname> sp_name
|
||||
%type <spvar> sp_param_name sp_param_name_and_type
|
||||
%type <spvar> sp_param_name_and_type_anchored
|
||||
%type <spvar> sp_param_name sp_param_name_and_mode sp_param
|
||||
%type <spvar> sp_param_anchored
|
||||
%type <for_loop> sp_for_loop_index_and_bounds
|
||||
%type <for_loop_bounds> sp_for_loop_bounds
|
||||
%type <trim> trim_operands
|
||||
@ -3051,8 +3051,8 @@ sp_fdparam_list:
|
||||
;
|
||||
|
||||
sp_fdparams:
|
||||
sp_fdparams ',' sp_param_name_and_type
|
||||
| sp_param_name_and_type
|
||||
sp_fdparams ',' sp_param
|
||||
| sp_param
|
||||
;
|
||||
|
||||
sp_param_name:
|
||||
@ -3070,8 +3070,8 @@ sp_pdparam_list:
|
||||
;
|
||||
|
||||
sp_pdparams:
|
||||
sp_pdparams ',' sp_pdparam
|
||||
| sp_pdparam
|
||||
sp_pdparams ',' sp_param
|
||||
| sp_param
|
||||
;
|
||||
|
||||
sp_parameter_type:
|
||||
@ -18001,11 +18001,6 @@ sp_opt_default:
|
||||
| DEFAULT expr { $$ = $2; }
|
||||
;
|
||||
|
||||
sp_pdparam:
|
||||
sp_parameter_type sp_param_name_and_type { $2->mode=$1; }
|
||||
| sp_param_name_and_type { $1->mode= sp_variable::MODE_IN; }
|
||||
;
|
||||
|
||||
sp_decl_variable_list_anchored:
|
||||
sp_decl_idents_init_vars
|
||||
TYPE_SYM OF_SYM optionally_qualified_column_ident
|
||||
@ -18025,40 +18020,49 @@ sp_decl_variable_list_anchored:
|
||||
}
|
||||
;
|
||||
|
||||
sp_param_name_and_type:
|
||||
sp_param_name field_type
|
||||
sp_param_name_and_mode:
|
||||
sp_parameter_type sp_param_name
|
||||
{
|
||||
$2->mode= $1;
|
||||
$$= $2;
|
||||
}
|
||||
| sp_param_name
|
||||
;
|
||||
|
||||
sp_param:
|
||||
sp_param_name_and_mode field_type
|
||||
{
|
||||
if (unlikely(Lex->sp_param_fill_definition($$= $1, $2)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name ROW_SYM row_type_body
|
||||
| sp_param_name_and_mode ROW_SYM row_type_body
|
||||
{
|
||||
if (unlikely(Lex->sphead->spvar_fill_row(thd, $$= $1, $3)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name_and_type_anchored
|
||||
| sp_param_anchored
|
||||
;
|
||||
|
||||
sp_param_name_and_type_anchored:
|
||||
sp_param_name TYPE_SYM OF_SYM ident '.' ident
|
||||
sp_param_anchored:
|
||||
sp_param_name_and_mode TYPE_SYM OF_SYM ident '.' ident
|
||||
{
|
||||
if (unlikely(Lex->sphead->spvar_fill_type_reference(thd,
|
||||
$$= $1, $4,
|
||||
$6)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name TYPE_SYM OF_SYM ident '.' ident '.' ident
|
||||
| sp_param_name_and_mode TYPE_SYM OF_SYM ident '.' ident '.' ident
|
||||
{
|
||||
if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1,
|
||||
$4, $6, $8)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name ROW_SYM TYPE_SYM OF_SYM ident
|
||||
| sp_param_name_and_mode ROW_SYM TYPE_SYM OF_SYM ident
|
||||
{
|
||||
if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $5)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name ROW_SYM TYPE_SYM OF_SYM ident '.' ident
|
||||
| sp_param_name_and_mode ROW_SYM TYPE_SYM OF_SYM ident '.' ident
|
||||
{
|
||||
if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $5, $7)))
|
||||
MYSQL_YYABORT;
|
||||
@ -18442,46 +18446,6 @@ sp_opt_inout:
|
||||
| IN_SYM OUT_SYM { $$= sp_variable::MODE_INOUT; }
|
||||
;
|
||||
|
||||
sp_pdparam:
|
||||
sp_param_name sp_opt_inout field_type
|
||||
{
|
||||
$1->mode= $2;
|
||||
if (unlikely(Lex->sp_param_fill_definition($1, $3)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name sp_opt_inout sp_decl_ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
|
||||
{
|
||||
$1->mode= $2;
|
||||
if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $1, $3, $5)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name sp_opt_inout sp_decl_ident '.' ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
|
||||
{
|
||||
$1->mode= $2;
|
||||
if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $1, $3, $5, $7)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name sp_opt_inout sp_decl_ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM
|
||||
{
|
||||
$1->mode= $2;
|
||||
if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $1, $3)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name sp_opt_inout sp_decl_ident '.' ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM
|
||||
{
|
||||
$1->mode= $2;
|
||||
if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $1, $3, $5)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name sp_opt_inout ROW_SYM row_type_body
|
||||
{
|
||||
$1->mode= $2;
|
||||
if (unlikely(Lex->sphead->spvar_fill_row(thd, $1, $4)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
sp_proc_stmts1_implicit_block:
|
||||
{
|
||||
Lex->sp_block_init(thd);
|
||||
@ -18913,45 +18877,47 @@ sp_decl_variable_list_anchored:
|
||||
}
|
||||
;
|
||||
|
||||
sp_param_name_and_type:
|
||||
sp_param_name sp_opt_inout field_type
|
||||
sp_param_name_and_mode:
|
||||
sp_param_name sp_opt_inout
|
||||
{
|
||||
$1->mode= $2;
|
||||
if (unlikely(Lex->sp_param_fill_definition($$= $1, $3)))
|
||||
MYSQL_YYABORT;
|
||||
$1->mode= $2;
|
||||
$$= $1;
|
||||
}
|
||||
| sp_param_name sp_opt_inout ROW_SYM row_type_body
|
||||
{
|
||||
$1->mode= $2;
|
||||
if (unlikely(Lex->sphead->spvar_fill_row(thd, $$= $1, $4)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name_and_type_anchored
|
||||
;
|
||||
|
||||
sp_param_name_and_type_anchored:
|
||||
sp_param_name sp_opt_inout sp_decl_ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
|
||||
sp_param:
|
||||
sp_param_name_and_mode field_type
|
||||
{
|
||||
$1->mode= $2;
|
||||
if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $3, $5)))
|
||||
if (unlikely(Lex->sp_param_fill_definition($$= $1, $2)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name sp_opt_inout sp_decl_ident '.' ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
|
||||
| sp_param_name_and_mode ROW_SYM row_type_body
|
||||
{
|
||||
$1->mode= $2;
|
||||
if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $3, $5, $7)))
|
||||
if (unlikely(Lex->sphead->spvar_fill_row(thd, $$= $1, $3)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name sp_opt_inout sp_decl_ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM
|
||||
| sp_param_anchored
|
||||
;
|
||||
|
||||
sp_param_anchored:
|
||||
sp_param_name_and_mode sp_decl_ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
|
||||
{
|
||||
$1->mode= $2;
|
||||
if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $3)))
|
||||
if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name sp_opt_inout sp_decl_ident '.' ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM
|
||||
| sp_param_name_and_mode sp_decl_ident '.' ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
|
||||
{
|
||||
$1->mode= $2;
|
||||
if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $3, $5)))
|
||||
if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4, $6)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name_and_mode sp_decl_ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM
|
||||
{
|
||||
if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $2)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| sp_param_name_and_mode sp_decl_ident '.' ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM
|
||||
{
|
||||
if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $2, $4)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
Reference in New Issue
Block a user