From bd76d44564b6e23356ff7de59101cf02aee1e338 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 12 Aug 2016 14:41:13 +0400 Subject: [PATCH] MDEV-10411 Providing compatibility for basic PL/SQL constructs Part 12: No parentheses if no arguments Now "CREATE PROCEDURE p1 AS" is supported with no parentheses after the name. Note, "CREATE FUNCTION f1 AS" is not supported yet, due to grammar conflict with UDFs. Functions will be done in a separate patch. --- mysql-test/suite/compat/oracle/r/sp.result | 24 ++++++ mysql-test/suite/compat/oracle/t/sp.test | 17 +++++ sql/sql_yacc.yy | 73 +++++++++--------- sql/sql_yacc_ora.yy | 88 ++++++++++++---------- 4 files changed, 127 insertions(+), 75 deletions(-) diff --git a/mysql-test/suite/compat/oracle/r/sp.result b/mysql-test/suite/compat/oracle/r/sp.result index f5569360e44..19aa220cfdf 100644 --- a/mysql-test/suite/compat/oracle/r/sp.result +++ b/mysql-test/suite/compat/oracle/r/sp.result @@ -1,4 +1,28 @@ SET sql_mode=ORACLE; +# Testing routines with no parameters +CREATE PROCEDURE p1 +AS +BEGIN +SET @a=10; +END; +/ +SHOW CREATE PROCEDURE p1; +Procedure p1 +sql_mode PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER +Create Procedure CREATE DEFINER="root"@"localhost" PROCEDURE "p1"() +AS +BEGIN +SET @a=10; +END +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci +SET @a=0; +CALL p1(); +SELECT @a; +@a +10 +DROP PROCEDURE p1; # Testing ":=" to set the default value of a variable CREATE FUNCTION f1 () RETURNS NUMBER(10) AS a NUMBER(10) := 10; diff --git a/mysql-test/suite/compat/oracle/t/sp.test b/mysql-test/suite/compat/oracle/t/sp.test index 466f89b939b..4d35d056409 100644 --- a/mysql-test/suite/compat/oracle/t/sp.test +++ b/mysql-test/suite/compat/oracle/t/sp.test @@ -1,5 +1,22 @@ SET sql_mode=ORACLE; +--echo # Testing routines with no parameters +DELIMITER /; +CREATE PROCEDURE p1 +AS +BEGIN + SET @a=10; +END; +/ +DELIMITER ;/ +--vertical_results +SHOW CREATE PROCEDURE p1; +--horizontal_results +SET @a=0; +CALL p1(); +SELECT @a; +DROP PROCEDURE p1; + --echo # Testing ":=" to set the default value of a variable DELIMITER /; CREATE FUNCTION f1 () RETURNS NUMBER(10) AS diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e90e188bcb0..1b2b1854c7e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2944,6 +2944,30 @@ sp_opt_inout: | INOUT_SYM { $$= sp_variable::MODE_INOUT; } ; +sp_parenthesized_fdparam_list: + '(' + { + Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start() + 1; + } + sp_fdparam_list + ')' + { + Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start(); + } + ; + +sp_parenthesized_pdparam_list: + '(' + { + Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start() + 1; + } + sp_pdparam_list + ')' + { + Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start(); + } + ; + sp_proc_stmts: /* Empty */ {} | sp_proc_stmts sp_proc_stmt ';' @@ -16409,45 +16433,32 @@ sf_tail: FUNCTION_SYM /* $1 */ opt_if_not_exists /* $2 */ sp_name /* $3 */ - { - if (!Lex->make_sp_head_no_recursive(thd, $2, $3, TYPE_ENUM_FUNCTION)) + { /* $4 */ + if (!Lex->make_sp_head_no_recursive(thd, $2, $3, + TYPE_ENUM_FUNCTION)) MYSQL_YYABORT; Lex->spname= $3; } - '(' /* $5 */ - { /* $6 */ - LEX *lex= Lex; - Lex_input_stream *lip= YYLIP; - const char* tmp_param_begin; - - tmp_param_begin= lip->get_cpp_tok_start(); - tmp_param_begin++; - lex->sphead->m_param_begin= tmp_param_begin; - } - sp_fdparam_list /* $7 */ - ')' /* $8 */ - { /* $9 */ - Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start(); - } - RETURNS_SYM /* $10 */ - { /* $11 */ + sp_parenthesized_fdparam_list /* $5 */ + RETURNS_SYM /* $6 */ + { /* $7 */ LEX *lex= Lex; lex->init_last_field(&lex->sphead->m_return_field_def, NULL, thd->variables.collation_database); } - type_with_opt_collate /* $12 */ - { /* $13 */ + type_with_opt_collate /* $8 */ + { /* $9 */ if (Lex->sphead->fill_field_definition(thd, Lex->last_field)) MYSQL_YYABORT; } - sp_c_chistics /* $14 */ - { /* $15 */ + sp_c_chistics /* $10 */ + { /* $11 */ LEX *lex= thd->lex; Lex_input_stream *lip= YYLIP; lex->sphead->set_body_start(thd, lip->get_cpp_tok_start()); } - sp_proc_stmt_in_returns_clause /* $16 */ + sp_proc_stmt_in_returns_clause /* $12 */ { LEX *lex= thd->lex; sp_head *sp= lex->sphead; @@ -16473,19 +16484,7 @@ sp_tail: MYSQL_YYABORT; Lex->spname= $3; } - '(' - { - const char* tmp_param_begin; - - tmp_param_begin= YYLIP->get_cpp_tok_start(); - tmp_param_begin++; - Lex->sphead->m_param_begin= tmp_param_begin; - } - sp_pdparam_list - ')' - { - Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start(); - } + sp_parenthesized_pdparam_list sp_c_chistics { Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start()); diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 7b75342aa92..49e4d7d1afd 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -2331,6 +2331,43 @@ sp_opt_inout: | INOUT_SYM { $$= sp_variable::MODE_INOUT; } ; +sp_parenthesized_fdparam_list: + '(' + { + Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start() + 1; + } + sp_fdparam_list + ')' + { + Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start(); + } + ; + +sp_parenthesized_pdparam_list: + '(' + { + Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start() + 1; + } + sp_pdparam_list + ')' + { + Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start(); + } + ; + +sp_no_param: + /* Empty */ + { + Lex->sphead->m_param_begin= Lex->sphead->m_param_end= + YYLIP->get_cpp_tok_start() + 1; + } + ; + +opt_sp_parenthesized_pdparam_list: + sp_no_param + | sp_parenthesized_pdparam_list + ; + sp_proc_stmts: /* Empty */ {} | sp_proc_stmts sp_proc_stmt ';' @@ -15991,46 +16028,33 @@ sf_tail: FUNCTION_SYM /* $1 */ opt_if_not_exists /* $2 */ sp_name /* $3 */ - { - if (!Lex->make_sp_head_no_recursive(thd, $2, $3, TYPE_ENUM_FUNCTION)) + { /* $4 */ + if (!Lex->make_sp_head_no_recursive(thd, $2, $3, + TYPE_ENUM_FUNCTION)) MYSQL_YYABORT; Lex->spname= $3; } - '(' /* $5 */ - { /* $6 */ - LEX *lex= Lex; - Lex_input_stream *lip= YYLIP; - const char* tmp_param_begin; - - tmp_param_begin= lip->get_cpp_tok_start(); - tmp_param_begin++; - lex->sphead->m_param_begin= tmp_param_begin; - } - sp_fdparam_list /* $7 */ - ')' /* $8 */ - { /* $9 */ - Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start(); - } - RETURNS_SYM /* $10 */ - { /* $11 */ + sp_parenthesized_fdparam_list /* $5 */ + RETURNS_SYM /* $6 */ + { /* $7 */ LEX *lex= Lex; lex->init_last_field(&lex->sphead->m_return_field_def, NULL, thd->variables.collation_database); } - type_with_opt_collate /* $12 */ - { /* $13 */ + type_with_opt_collate /* $8 */ + { /* $9 */ if (Lex->sphead->fill_field_definition(thd, Lex->last_field)) MYSQL_YYABORT; } - sp_c_chistics /* $14 */ - { /* $15 */ + sp_c_chistics /* $10 */ + { /* $11 */ LEX *lex= thd->lex; Lex_input_stream *lip= YYLIP; lex->sphead->set_body_start(thd, lip->get_cpp_tok_start()); } - sp_tail_is /* $16 */ - sp_body /* $17 */ + sp_tail_is /* $12 */ + sp_body /* $13 */ { LEX *lex= thd->lex; sp_head *sp= lex->sphead; @@ -16056,19 +16080,7 @@ sp_tail: MYSQL_YYABORT; Lex->spname= $3; } - '(' - { - const char* tmp_param_begin; - - tmp_param_begin= YYLIP->get_cpp_tok_start(); - tmp_param_begin++; - Lex->sphead->m_param_begin= tmp_param_begin; - } - sp_pdparam_list - ')' - { - Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start(); - } + opt_sp_parenthesized_pdparam_list sp_c_chistics { Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());