summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-11-25 12:19:39 +0400
committerAlexander Barkov <bar@mariadb.com>2019-12-04 15:45:00 +0400
commit3f9d7072e98abd7b9315a4d75e30d55c8a35753e (patch)
tree0fd4664ad1be7b50020de23aeff19664be903527
parentbb459416856661074c9d2560619de1db35b49bfc (diff)
downloadmariadb-git-3f9d7072e98abd7b9315a4d75e30d55c8a35753e.tar.gz
Part1: MDEV-12518 Unify sql_yacc.yy and sql_yacc_ora.yy
Mixing %type and %expect declarations: - sql_mode=ORACLE declarations look like an empty C code section inside sql_yacc.yy, consisting of an inactive #ifdef..#endif block. - sql_mode=DEFAULT declarations look like an empty C code section inside sql_yacc_ora.yy, consisting of an inactive #ifdef..#endif block. Mixing rules: - Adding a special rule _empty to the shared rule section. - Changing all instances of /*Empty*/ in sql_mode=DEFAULT and sql_mode=ORACLE specific sections to _empty. - Changing the rest of C style comments /*xxx*/ in sql_mode=DEFAULT and sql_mode=ORACLE specific blocks to C++ style: //xxx - Mixing sql_yacc.yy and sql_yacc_ora.yy, so sql_mode=ORACLE specific blocks sit in a comment inside sql_yacc.yy, and sql_mode=DEFAULT specific blocks sit in a comment inside sql_yacc_ora.yy.
-rw-r--r--sql/sql_yacc.yy1108
-rw-r--r--sql/sql_yacc_ora.yy479
2 files changed, 1533 insertions, 54 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index fee02f78792..12222483c7b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -320,10 +320,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%parse-param { THD *thd }
%lex-param { THD *thd }
/*
- Currently there are 37 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
+//%{#ifdef SQL_MODE_DEFAULT_SPECIFIC
%expect 37
+//#endif %} // SQL_MODE_DEFAULT_SPECIFIC
+
+
+%{#ifdef SQL_MODE_ORACLE_SPECIFIC
+%expect 40
+#endif %} // SQL_MODE_ORACLE_SPECIFIC
/*
Comments for TOKENS.
@@ -1715,7 +1721,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <vers_history_point> history_point
%type <vers_column_versioning> with_or_without_system
-/* Start of sql_mode=DEFAULT specific declarations */
+//%{#ifdef SQL_MODE_DEFAULT_SPECIFIC
%type <NONE> sp_tail_standalone
%type <NONE> sp_unlabeled_block_not_atomic
%type <NONE> sp_proc_stmt_in_returns_clause
@@ -1727,8 +1733,45 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <spblock> sp_decl_variable_list
%type <spblock> sp_decl_variable_list_anchored
%type <kwd> reserved_keyword_udt_param_type
+//#endif %} // SQL_MODE_DEFAULT_SPECIFIC
-/* End of sql_mode=DEFAULT specific declarations */
+
+%{#ifdef SQL_MODE_ORACLE_SPECIFIC
+%type <NONE> set_assign
+%type <spvar_mode> sp_opt_inout
+%type <NONE> sp_tail_standalone
+%type <NONE> sp_labelable_stmt
+%type <simple_string> remember_end_opt
+%type <lex_str> opt_package_routine_end_name
+%type <lex_str> label_declaration_oracle
+%type <lex_str> labels_declaration_oracle
+%type <kwd> keyword_directly_assignable
+%type <ident_sys> ident_directly_assignable
+%type <ident_cli> ident_cli_directly_assignable
+%type <spname> opt_sp_name
+%type <spblock> sp_decl_body_list
+%type <spblock> opt_sp_decl_body_list
+%type <spblock> sp_decl_variable_list
+%type <spblock> sp_decl_variable_list_anchored
+%type <spblock> sp_decl_non_handler
+%type <spblock> sp_decl_non_handler_list
+%type <spblock> sp_decl_handler
+%type <spblock> sp_decl_handler_list
+%type <spblock> opt_sp_decl_handler_list
+%type <spblock> package_implementation_routine_definition
+%type <spblock> package_implementation_item_declaration
+%type <spblock> package_implementation_declare_section
+%type <spblock> package_implementation_declare_section_list1
+%type <spblock> package_implementation_declare_section_list2
+%type <spblock_handlers> sp_block_statements_and_exceptions
+%type <spblock_handlers> package_implementation_executable_section
+%type <sp_instr_addr> sp_instr_addr
+%type <num> opt_exception_clause exception_handlers
+%type <lex> remember_lex
+%type <lex> package_routine_lex
+%type <lex> package_specification_function
+%type <lex> package_specification_procedure
+#endif %} // SQL_MODE_ORACLE_SPECIFIC
%%
@@ -17587,7 +17630,12 @@ keep_gcc_happy:
}
;
-/* Start of sql_mode=DEFAULT specific rules */
+_empty:
+ /* Empty */
+ ;
+
+/* Start SQL_MODE_DEFAULT_SPECIFIC */
+
statement:
verb_clause
@@ -17616,16 +17664,14 @@ reserved_keyword_udt:
| reserved_keyword_udt_param_type
;
-/* Keywords that start an SP block section. */
+// Keywords that start an SP block section
keyword_sp_block_section:
BEGIN_MARIADB_SYM
| END
;
-/*
- Keywords that we allow for labels in SPs.
- Should not include keywords that start a statement or SP characteristics.
-*/
+// Keywords that we allow for labels in SPs.
+// Should not include keywords that start a statement or SP characteristics.
keyword_label:
keyword_data_type
| keyword_set_special_case
@@ -17650,7 +17696,7 @@ keyword_sp_decl:
;
opt_truncate_table_storage_clause:
- /* Empty */
+ _empty
;
@@ -17702,7 +17748,7 @@ sp_block_label:
;
sp_opt_default:
- /* Empty */ { $$ = NULL; }
+ _empty { $$ = NULL; }
| DEFAULT expr { $$ = $2; }
;
@@ -17856,16 +17902,16 @@ create_routine:
sp_decls:
- /* Empty */
+ _empty
{
$$.init();
}
| sp_decls sp_decl ';'
{
- /* We check for declarations out of (standard) order this way
- because letting the grammar rules reflect it caused tricky
- shift/reduce conflicts with the wrong result. (And we get
- better error handling this way.) */
+ // We check for declarations out of (standard) order this way
+ // because letting the grammar rules reflect it caused tricky
+ // shift/reduce conflicts with the wrong result. (And we get
+ // better error handling this way.)
if (unlikely(Lex->sp_declarations_join(&$$, $1, $2)))
MYSQL_YYABORT;
}
@@ -17904,15 +17950,15 @@ sp_decl_body:
;
-/*
- ps_proc_stmt_in_returns_clause is a statement that is allowed
- in the RETURNS clause of a stored function definition directly,
- without the BEGIN..END block.
- It should not include any syntax structures starting with '(', to avoid
- shift/reduce conflicts with the rule "field_type" and its sub-rules
- that scan an optional length, like CHAR(1) or YEAR(4).
- See MDEV-9166.
-*/
+
+// ps_proc_stmt_in_returns_clause is a statement that is allowed
+// in the RETURNS clause of a stored function definition directly,
+// without the BEGIN..END block.
+// It should not include any syntax structures starting with '(', to avoid
+// shift/reduce conflicts with the rule "field_type" and its sub-rules
+// that scan an optional length, like CHAR(1) or YEAR(4).
+// See MDEV-9166.
+
sp_proc_stmt_in_returns_clause:
sp_proc_stmt_return
| sp_labeled_block
@@ -17971,7 +18017,7 @@ sp_unlabeled_block:
;
sp_unlabeled_block_not_atomic:
- BEGIN_MARIADB_SYM not ATOMIC_SYM /* TODO: BEGIN ATOMIC (not -> opt_not) */
+ BEGIN_MARIADB_SYM not ATOMIC_SYM // TODO: BEGIN ATOMIC (not -> opt_not)
{
if (unlikely(Lex->maybe_start_compound_statement(thd)))
MYSQL_YYABORT;
@@ -17987,7 +18033,1015 @@ sp_unlabeled_block_not_atomic:
;
-/* End of sql_mode=DEFAULT specific rules */
+/* End SQL_MODE_DEFAULT_SPECIFIC */
+
+
+/* Start SQL_MODE_ORACLE_SPECIFIC
+
+statement:
+ verb_clause
+ | set_assign
+ ;
+
+sp_statement:
+ statement
+ | ident_cli_directly_assignable
+ {
+ // Direct procedure call (without the CALL keyword)
+ Lex_ident_sys tmp(thd, &$1);
+ if (unlikely(Lex->call_statement_start(thd, &tmp)))
+ MYSQL_YYABORT;
+ }
+ opt_sp_cparam_list
+ | ident_cli_directly_assignable '.' ident
+ {
+ Lex_ident_sys tmp(thd, &$1);
+ if (unlikely(Lex->call_statement_start(thd, &tmp, &$3)))
+ MYSQL_YYABORT;
+ }
+ opt_sp_cparam_list
+ ;
+
+sp_if_then_statements:
+ sp_proc_stmts1_implicit_block { }
+ ;
+
+sp_case_then_statements:
+ sp_proc_stmts1_implicit_block { }
+ ;
+
+reserved_keyword_udt:
+ reserved_keyword_udt_not_param_type
+ ;
+
+// Keywords that start an SP block section.
+keyword_sp_block_section:
+ BEGIN_ORACLE_SYM
+ | END
+ ;
+
+// Keywords that we allow for labels in SPs.
+// Should not include keywords that start a statement or SP characteristics.
+keyword_label:
+ keyword_data_type
+ | keyword_set_special_case
+ | keyword_sp_var_and_label
+ | keyword_sysvar_type
+ | FUNCTION_SYM
+ | COMPRESSED_SYM
+ | EXCEPTION_ORACLE_SYM
+ ;
+
+keyword_sp_decl:
+ keyword_sp_head
+ | keyword_set_special_case
+ | keyword_sp_var_and_label
+ | keyword_sp_var_not_label
+ | keyword_sysvar_type
+ | keyword_verb_clause
+ | WINDOW_SYM
+ ;
+
+opt_truncate_table_storage_clause:
+ _empty
+ | DROP STORAGE_SYM
+ | REUSE_SYM STORAGE_SYM
+ ;
+
+
+ident_for_loop_index:
+ ident_directly_assignable
+ ;
+
+row_field_name:
+ ident_directly_assignable
+ {
+ if (!($$= Lex->row_field_name(thd, $1)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+while_body:
+ expr_lex LOOP_SYM
+ {
+ if (unlikely($1->sp_while_loop_expression(thd)))
+ MYSQL_YYABORT;
+ }
+ sp_proc_stmts1 END LOOP_SYM
+ {
+ if (unlikely(Lex->sp_while_loop_finalize(thd)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+for_loop_statements:
+ LOOP_SYM sp_proc_stmts1 END LOOP_SYM
+ { }
+ ;
+
+
+sp_control_label:
+ labels_declaration_oracle
+ ;
+
+sp_block_label:
+ labels_declaration_oracle
+ {
+ if (unlikely(Lex->spcont->block_label_declare(&$1)))
+ MYSQL_YYABORT;
+ $$= $1;
+ }
+ ;
+
+
+remember_end_opt:
+ {
+ if (yychar == YYEMPTY)
+ $$= (char*) YYLIP->get_cpp_ptr_rtrim();
+ else
+ $$= (char*) YYLIP->get_cpp_tok_end_rtrim();
+ }
+ ;
+
+sp_opt_default:
+ _empty { $$ = NULL; }
+ | DEFAULT expr { $$ = $2; }
+ | SET_VAR expr { $$ = $2; }
+ ;
+
+sp_opt_inout:
+ _empty { $$= sp_variable::MODE_IN; }
+ | sp_parameter_type
+ | IN_SYM OUT_SYM { $$= sp_variable::MODE_INOUT; }
+ ;
+
+sp_pdparam:
+ sp_param_name sp_opt_inout type_with_opt_collate
+ {
+ $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);
+ }
+ sp_proc_stmts1
+ {
+ if (unlikely(Lex->sp_block_finalize(thd)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+
+remember_lex:
+ {
+ $$= thd->lex;
+ }
+ ;
+
+keyword_directly_assignable:
+ keyword_data_type
+ | keyword_cast_type
+ | keyword_set_special_case
+ | keyword_sp_var_and_label
+ | keyword_sp_var_not_label
+ | keyword_sysvar_type
+ | FUNCTION_SYM
+ | WINDOW_SYM
+ ;
+
+ident_directly_assignable:
+ IDENT_sys
+ | keyword_directly_assignable
+ {
+ if (unlikely($$.copy_keyword(thd, &$1)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+ident_cli_directly_assignable:
+ IDENT_cli
+ | keyword_directly_assignable { $$= $1; }
+ ;
+
+
+set_assign:
+ ident_cli_directly_assignable SET_VAR
+ {
+ LEX *lex=Lex;
+ lex->set_stmt_init();
+ if (sp_create_assignment_lex(thd, $1.pos()))
+ MYSQL_YYABORT;
+ }
+ set_expr_or_default
+ {
+ Lex_ident_sys tmp(thd, &$1);
+ if (unlikely(Lex->set_variable(&tmp, $4)) ||
+ unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY,
+ false)))
+ MYSQL_YYABORT;
+ }
+ | ident_cli_directly_assignable '.' ident SET_VAR
+ {
+ LEX *lex=Lex;
+ lex->set_stmt_init();
+ if (sp_create_assignment_lex(thd, $1.pos()))
+ MYSQL_YYABORT;
+ }
+ set_expr_or_default
+ {
+ LEX *lex= Lex;
+ DBUG_ASSERT(lex->var_list.is_empty());
+ Lex_ident_sys tmp(thd, &$1);
+ if (unlikely(lex->set_variable(&tmp, &$3, $6)) ||
+ unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY,
+ false)))
+ MYSQL_YYABORT;
+ }
+ | COLON_ORACLE_SYM ident '.' ident SET_VAR
+ {
+ LEX *lex= Lex;
+ if (unlikely(!lex->is_trigger_new_or_old_reference(&$2)))
+ {
+ thd->parse_error(ER_SYNTAX_ERROR, $1.pos());
+ MYSQL_YYABORT;
+ }
+ lex->set_stmt_init();
+ if (sp_create_assignment_lex(thd, $1.pos()))
+ MYSQL_YYABORT;
+ }
+ set_expr_or_default
+ {
+ LEX_CSTRING tmp= { $2.str, $2.length };
+ if (unlikely(Lex->set_trigger_field(&tmp, &$4, $7)) ||
+ unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY,
+ false)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+
+labels_declaration_oracle:
+ label_declaration_oracle { $$= $1; }
+ | labels_declaration_oracle label_declaration_oracle { $$= $2; }
+ ;
+
+label_declaration_oracle:
+ SHIFT_LEFT label_ident SHIFT_RIGHT
+ {
+ if (unlikely(Lex->sp_push_goto_label(thd, &$2)))
+ MYSQL_YYABORT;
+ $$= $2;
+ }
+ ;
+
+opt_exception_clause:
+ _empty { $$= 0; }
+ | EXCEPTION_ORACLE_SYM exception_handlers { $$= $2; }
+ ;
+
+exception_handlers:
+ exception_handler { $$= 1; }
+ | exception_handlers exception_handler { $$= $1 + 1; }
+ ;
+
+exception_handler:
+ WHEN_SYM
+ {
+ if (unlikely(Lex->sp_handler_declaration_init(thd, sp_handler::EXIT)))
+ MYSQL_YYABORT;
+ }
+ sp_hcond_list
+ THEN_SYM
+ sp_proc_stmts1_implicit_block
+ {
+ if (unlikely(Lex->sp_handler_declaration_finalize(thd, sp_handler::EXIT)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+sp_no_param:
+ _empty
+ {
+ Lex->sphead->m_param_begin= Lex->sphead->m_param_end=
+ YYLIP->get_cpp_tok_start() + 1;
+ }
+ ;
+
+opt_sp_parenthesized_fdparam_list:
+ sp_no_param
+ | sp_parenthesized_fdparam_list
+ ;
+
+opt_sp_parenthesized_pdparam_list:
+ sp_no_param
+ | sp_parenthesized_pdparam_list
+ ;
+
+
+opt_sp_name:
+ _empty { $$= NULL; }
+ | sp_name { $$= $1; }
+ ;
+
+
+opt_package_routine_end_name:
+ _empty { $$= null_clex_str; }
+ | ident { $$= $1; }
+ ;
+
+sp_tail_is:
+ IS
+ | AS
+ ;
+
+sp_instr_addr:
+ { $$= Lex->sphead->instructions(); }
+ ;
+
+sp_body:
+ {
+ Lex->sp_block_init(thd);
+ }
+ opt_sp_decl_body_list
+ {
+ if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
+ MYSQL_YYABORT;
+ }
+ BEGIN_ORACLE_SYM
+ sp_block_statements_and_exceptions
+ {
+ $2.hndlrs+= $5.hndlrs;
+ if (unlikely(Lex->sp_block_finalize(thd, $2)))
+ MYSQL_YYABORT;
+ }
+ END
+ ;
+
+create_package_chistic:
+ COMMENT_SYM TEXT_STRING_sys
+ { Lex->sp_chistics.comment= $2; }
+ | sp_suid
+ { Lex->sp_chistics.suid= $1; }
+ ;
+
+create_package_chistics:
+ create_package_chistic {}
+ | create_package_chistics create_package_chistic { }
+ ;
+
+opt_create_package_chistics:
+ _empty
+ | create_package_chistics { }
+ ;
+
+opt_create_package_chistics_init:
+ { Lex->sp_chistics.init(); }
+ opt_create_package_chistics
+ ;
+
+
+package_implementation_executable_section:
+ END
+ {
+ if (unlikely(Lex->sp_block_with_exceptions_add_empty(thd)))
+ MYSQL_YYABORT;
+ $$.init(0);
+ }
+ | BEGIN_ORACLE_SYM sp_block_statements_and_exceptions END { $$= $2; }
+ ;
+
+
+// Inside CREATE PACKAGE BODY, package-wide items (e.g. variables)
+// must be declared before routine definitions.
+
+package_implementation_declare_section:
+ package_implementation_declare_section_list1
+ | package_implementation_declare_section_list2
+ | package_implementation_declare_section_list1
+ package_implementation_declare_section_list2
+ { $$.join($1, $2); }
+ ;
+
+package_implementation_declare_section_list1:
+ package_implementation_item_declaration
+ | package_implementation_declare_section_list1
+ package_implementation_item_declaration
+ { $$.join($1, $2); }
+ ;
+
+package_implementation_declare_section_list2:
+ package_implementation_routine_definition
+ | package_implementation_declare_section_list2
+ package_implementation_routine_definition
+ { $$.join($1, $2); }
+ ;
+
+package_routine_lex:
+ {
+ if (unlikely(!($$= new (thd->mem_root)
+ sp_lex_local(thd, thd->lex))))
+ MYSQL_YYABORT;
+ thd->m_parser_state->m_yacc.reset_before_substatement();
+ }
+ ;
+
+
+package_specification_function:
+ remember_lex package_routine_lex ident
+ {
+ DBUG_ASSERT($1->sphead->get_package());
+ $2->sql_command= SQLCOM_CREATE_FUNCTION;
+ sp_name *spname= $1->make_sp_name_package_routine(thd, &$3);
+ if (unlikely(!spname))
+ MYSQL_YYABORT;
+ thd->lex= $2;
+ if (unlikely(!$2->make_sp_head_no_recursive(thd, spname,
+ &sp_handler_package_function,
+ NOT_AGGREGATE)))
+ MYSQL_YYABORT;
+ $1->sphead->get_package()->m_current_routine= $2;
+ (void) is_native_function_with_warn(thd, &$3);
+ }
+ opt_sp_parenthesized_fdparam_list
+ RETURN_ORACLE_SYM sf_return_type
+ sp_c_chistics
+ {
+ sp_head *sp= thd->lex->sphead;
+ sp->restore_thd_mem_root(thd);
+ thd->lex= $1;
+ $$= $2;
+ }
+ ;
+
+package_specification_procedure:
+ remember_lex package_routine_lex ident
+ {
+ DBUG_ASSERT($1->sphead->get_package());
+ $2->sql_command= SQLCOM_CREATE_PROCEDURE;
+ sp_name *spname= $1->make_sp_name_package_routine(thd, &$3);
+ if (unlikely(!spname))
+ MYSQL_YYABORT;
+ thd->lex= $2;
+ if (unlikely(!$2->make_sp_head_no_recursive(thd, spname,
+ &sp_handler_package_procedure,
+ DEFAULT_AGGREGATE)))
+ MYSQL_YYABORT;
+ $1->sphead->get_package()->m_current_routine= $2;
+ }
+ opt_sp_parenthesized_pdparam_list
+ sp_c_chistics
+ {
+ sp_head *sp= thd->lex->sphead;
+ sp->restore_thd_mem_root(thd);
+ thd->lex= $1;
+ $$= $2;
+ }
+ ;
+
+
+package_implementation_routine_definition:
+ FUNCTION_SYM package_specification_function
+ package_implementation_function_body ';'
+ {
+ sp_package *pkg= Lex->get_sp_package();
+ if (unlikely(pkg->add_routine_implementation($2)))
+ MYSQL_YYABORT;
+ pkg->m_current_routine= NULL;
+ $$.init();
+ }
+ | PROCEDURE_SYM package_specification_procedure
+ package_implementation_procedure_body ';'
+ {
+ sp_package *pkg= Lex->get_sp_package();
+ if (unlikely(pkg->add_routine_implementation($2)))
+ MYSQL_YYABORT;
+ pkg->m_current_routine= NULL;
+ $$.init();
+ }
+ | package_specification_element { $$.init(); }
+ ;
+
+
+package_implementation_function_body:
+ sp_tail_is remember_lex
+ {
+ sp_package *pkg= Lex->get_sp_package();
+ sp_head *sp= pkg->m_current_routine->sphead;
+ thd->lex= pkg->m_current_routine;
+ sp->reset_thd_mem_root(thd);
+ sp->set_body_start(thd, YYLIP->get_cpp_tok_start());
+ }
+ sp_body opt_package_routine_end_name
+ {
+ if (unlikely(thd->lex->sp_body_finalize_function(thd) ||
+ thd->lex->sphead->check_package_routine_end_name($5)))
+ MYSQL_YYABORT;
+ thd->lex= $2;
+ }
+ ;
+
+package_implementation_procedure_body:
+ sp_tail_is remember_lex
+ {
+ sp_package *pkg= Lex->get_sp_package();
+ sp_head *sp= pkg->m_current_routine->sphead;
+ thd->lex= pkg->m_current_routine;
+ sp->reset_thd_mem_root(thd);
+ sp->set_body_start(thd, YYLIP->get_cpp_tok_start());
+ }
+ sp_body opt_package_routine_end_name
+ {
+ if (unlikely(thd->lex->sp_body_finalize_procedure(thd) ||
+ thd->lex->sphead->check_package_routine_end_name($5)))
+ MYSQL_YYABORT;
+ thd->lex= $2;
+ }
+ ;
+
+
+package_implementation_item_declaration:
+ sp_decl_variable_list ';'
+ ;
+
+opt_package_specification_element_list:
+ _empty
+ | package_specification_element_list
+ ;
+
+package_specification_element_list:
+ package_specification_element
+ | package_specification_element_list package_specification_element
+ ;
+
+package_specification_element:
+ FUNCTION_SYM package_specification_function ';'
+ {
+ sp_package *pkg= Lex->get_sp_package();
+ if (unlikely(pkg->add_routine_declaration($2)))
+ MYSQL_YYABORT;
+ pkg->m_current_routine= NULL;
+ }
+ | PROCEDURE_SYM package_specification_procedure ';'
+ {
+ sp_package *pkg= Lex->get_sp_package();
+ if (unlikely(pkg->add_routine_declaration($2)))
+ MYSQL_YYABORT;
+ pkg->m_current_routine= NULL;
+ }
+ ;
+
+sp_decl_variable_list_anchored:
+ sp_decl_idents_init_vars
+ optionally_qualified_column_ident PERCENT_ORACLE_SYM TYPE_SYM
+ sp_opt_default
+ {
+ if (unlikely(Lex->sp_variable_declarations_with_ref_finalize(thd, $1, $2, $5)))
+ MYSQL_YYABORT;
+ $$.init_using_vars($1);
+ }
+ | sp_decl_idents_init_vars
+ optionally_qualified_column_ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM
+ sp_opt_default
+ {
+ if (unlikely(Lex->sp_variable_declarations_rowtype_finalize(thd, $1, $2, $5)))
+ MYSQL_YYABORT;
+ $$.init_using_vars($1);
+ }
+ ;
+
+sp_param_name_and_type_anchored:
+ sp_param_name sp_decl_ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
+ {
+ if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4)))
+ MYSQL_YYABORT;
+ }
+ | sp_param_name sp_decl_ident '.' ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
+ {
+ if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4, $6)))
+ MYSQL_YYABORT;
+ }
+ | sp_param_name 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 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;
+ }
+ ;
+
+
+sf_c_chistics_and_body_standalone:
+ sp_c_chistics
+ {
+ LEX *lex= thd->lex;
+ lex->sphead->set_c_chistics(lex->sp_chistics);
+ lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
+ }
+ sp_tail_is
+ sp_body
+ {
+ if (unlikely(Lex->sp_body_finalize_function(thd)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+sp_tail_standalone:
+ sp_name
+ {
+ if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1,
+ &sp_handler_procedure,
+ DEFAULT_AGGREGATE)))
+ MYSQL_YYABORT;
+ }
+ opt_sp_parenthesized_pdparam_list
+ sp_c_chistics
+ {
+ Lex->sphead->set_c_chistics(Lex->sp_chistics);
+ Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
+ }
+ sp_tail_is
+ sp_body
+ opt_sp_name
+ {
+ if (unlikely(Lex->sp_body_finalize_procedure_standalone(thd, $8)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+drop_routine:
+ DROP FUNCTION_SYM opt_if_exists ident '.' ident
+ {
+ if (Lex->stmt_drop_function($3, $4, $6))
+ MYSQL_YYABORT;
+ }
+ | DROP FUNCTION_SYM opt_if_exists ident
+ {
+ if (Lex->stmt_drop_function($3, $4))
+ MYSQL_YYABORT;
+ }
+ | DROP PROCEDURE_SYM opt_if_exists sp_name
+ {
+ if (Lex->stmt_drop_procedure($3, $4))
+ MYSQL_YYABORT;
+ }
+ | DROP PACKAGE_ORACLE_SYM opt_if_exists sp_name
+ {
+ LEX *lex= Lex;
+ lex->set_command(SQLCOM_DROP_PACKAGE, $3);
+ if (unlikely(lex->sphead))
+ my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PACKAGE"));
+ lex->spname= $4;
+ }
+ | DROP PACKAGE_ORACLE_SYM BODY_ORACLE_SYM opt_if_exists sp_name
+ {
+ LEX *lex= Lex;
+ lex->set_command(SQLCOM_DROP_PACKAGE_BODY, $4);
+ if (unlikely(lex->sphead))
+ my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PACKAGE BODY"));
+ lex->spname= $5;
+ }
+ ;
+
+
+create_routine:
+ create_or_replace definer_opt PROCEDURE_SYM opt_if_not_exists
+ {
+ if (Lex->stmt_create_procedure_start($1 | $4))
+ MYSQL_YYABORT;
+ }
+ sp_tail_standalone
+ {
+ Lex->stmt_create_routine_finalize();
+ }
+ | create_or_replace definer opt_aggregate FUNCTION_SYM opt_if_not_exists
+ sp_name
+ {
+ if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6))
+ MYSQL_YYABORT;
+ }
+ opt_sp_parenthesized_fdparam_list
+ RETURN_ORACLE_SYM sf_return_type
+ sf_c_chistics_and_body_standalone
+ opt_sp_name
+ {
+ if (Lex->stmt_create_stored_function_finalize_standalone($12))
+ MYSQL_YYABORT;
+ }
+ | create_or_replace no_definer opt_aggregate FUNCTION_SYM opt_if_not_exists
+ sp_name
+ {
+ if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6))
+ MYSQL_YYABORT;
+ }
+ opt_sp_parenthesized_fdparam_list
+ RETURN_ORACLE_SYM sf_return_type
+ sf_c_chistics_and_body_standalone
+ opt_sp_name
+ {
+ if (Lex->stmt_create_stored_function_finalize_standalone($12))
+ MYSQL_YYABORT;
+ }
+ | create_or_replace no_definer opt_aggregate FUNCTION_SYM opt_if_not_exists
+ ident RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
+ {
+ if (Lex->stmt_create_udf_function($1 | $5, $3, $6,
+ (Item_result) $8, $10))
+ MYSQL_YYABORT;
+ }
+ | create_or_replace definer_opt PACKAGE_ORACLE_SYM
+ opt_if_not_exists sp_name opt_create_package_chistics_init
+ sp_tail_is
+ remember_name
+ {
+ sp_package *pkg;
+ if (unlikely(!(pkg= Lex->
+ create_package_start(thd,
+ SQLCOM_CREATE_PACKAGE,
+ &sp_handler_package_spec,
+ $5, $1 | $4))))
+ MYSQL_YYABORT;
+ pkg->set_c_chistics(Lex->sp_chistics);
+ }
+ opt_package_specification_element_list END
+ remember_end_opt opt_sp_name
+ {
+ if (unlikely(Lex->create_package_finalize(thd, $5, $13, $8, $12)))
+ MYSQL_YYABORT;
+ }
+ | create_or_replace definer_opt PACKAGE_ORACLE_SYM BODY_ORACLE_SYM
+ opt_if_not_exists sp_name opt_create_package_chistics_init
+ sp_tail_is
+ remember_name
+ {
+ sp_package *pkg;
+ if (unlikely(!(pkg= Lex->
+ create_package_start(thd,
+ SQLCOM_CREATE_PACKAGE_BODY,
+ &sp_handler_package_body,
+ $6, $1 | $5))))
+ MYSQL_YYABORT;
+ pkg->set_c_chistics(Lex->sp_chistics);
+ Lex->sp_block_init(thd);
+ }
+ package_implementation_declare_section
+ {
+ if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
+ MYSQL_YYABORT;
+ }
+ package_implementation_executable_section
+ {
+ $11.hndlrs+= $13.hndlrs;
+ if (unlikely(Lex->sp_block_finalize(thd, $11)))
+ MYSQL_YYABORT;
+ }
+ remember_end_opt opt_sp_name
+ {
+ if (unlikely(Lex->create_package_finalize(thd, $6, $16, $9, $15)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+opt_sp_decl_body_list:
+ _empty
+ {
+ $$.init();
+ }
+ | sp_decl_body_list { $$= $1; }
+ ;
+
+sp_decl_body_list:
+ sp_decl_non_handler_list
+ {
+ if (unlikely(Lex->sphead->sp_add_instr_cpush_for_cursors(thd, Lex->spcont)))
+ MYSQL_YYABORT;
+ }
+ opt_sp_decl_handler_list
+ {
+ $$.join($1, $3);
+ }
+ | sp_decl_handler_list
+ ;
+
+sp_decl_non_handler_list:
+ sp_decl_non_handler ';' { $$= $1; }
+ | sp_decl_non_handler_list sp_decl_non_handler ';'
+ {
+ $$.join($1, $2);
+ }
+ ;
+
+sp_decl_handler_list:
+ sp_decl_handler ';' { $$= $1; }
+ | sp_decl_handler_list sp_decl_handler ';'
+ {
+ $$.join($1, $2);
+ }
+ ;
+
+opt_sp_decl_handler_list:
+ _empty { $$.init(); }
+ | sp_decl_handler_list
+ ;
+
+sp_decl_non_handler:
+ sp_decl_variable_list
+ | ident_directly_assignable CONDITION_SYM FOR_SYM sp_cond
+ {
+ if (unlikely(Lex->spcont->declare_condition(thd, &$1, $4)))
+ MYSQL_YYABORT;
+ $$.vars= $$.hndlrs= $$.curs= 0;
+ $$.conds= 1;
+ }
+ | ident_directly_assignable EXCEPTION_ORACLE_SYM
+ {
+ sp_condition_value *spcond= new (thd->mem_root)
+ sp_condition_value_user_defined();
+ if (unlikely(!spcond) ||
+ unlikely(Lex->spcont->declare_condition(thd, &$1, spcond)))
+ MYSQL_YYABORT;
+ $$.vars= $$.hndlrs= $$.curs= 0;
+ $$.conds= 1;
+ }
+ | CURSOR_SYM ident_directly_assignable
+ {
+ Lex->sp_block_init(thd);
+ }
+ opt_parenthesized_cursor_formal_parameters
+ IS sp_cursor_stmt
+ {
+ sp_pcontext *param_ctx= Lex->spcont;
+ if (unlikely(Lex->sp_block_finalize(thd)))
+ MYSQL_YYABORT;
+ if (unlikely(Lex->sp_declare_cursor(thd, &$2, $6, param_ctx, false)))
+ MYSQL_YYABORT;
+ $$.vars= $$.conds= $$.hndlrs= 0;
+ $$.curs= 1;
+ }
+ ;
+
+
+sp_proc_stmt:
+ sp_labeled_block
+ | sp_unlabeled_block
+ | sp_labeled_control
+ | sp_unlabeled_control
+ | sp_labelable_stmt
+ | labels_declaration_oracle sp_labelable_stmt {}
+ ;
+
+sp_labelable_stmt:
+ sp_proc_stmt_statement
+ | sp_proc_stmt_continue_oracle
+ | sp_proc_stmt_exit_oracle
+ | sp_proc_stmt_leave
+ | sp_proc_stmt_iterate
+ | sp_proc_stmt_goto_oracle
+ | sp_proc_stmt_with_cursor
+ | sp_proc_stmt_return
+ | sp_proc_stmt_if
+ | case_stmt_specification
+ | NULL_SYM { }
+ ;
+
+sp_proc_stmt_compound_ok:
+ sp_proc_stmt_if
+ | case_stmt_specification
+ | sp_unlabeled_block
+ | sp_unlabeled_control
+ ;
+
+
+sp_labeled_block:
+ sp_block_label
+ BEGIN_ORACLE_SYM
+ {
+ Lex->sp_block_init(thd, &$1);
+ if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
+ MYSQL_YYABORT;
+ }
+ sp_block_statements_and_exceptions
+ END
+ sp_opt_label
+ {
+ if (unlikely(Lex->sp_block_finalize(thd, Lex_spblock($4), &$6)))
+ MYSQL_YYABORT;
+ }
+ | sp_block_label
+ DECLARE_ORACLE_SYM
+ {
+ Lex->sp_block_init(thd, &$1);
+ }
+ sp_decl_body_list
+ {
+ if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
+ MYSQL_YYABORT;
+ }
+ BEGIN_ORACLE_SYM
+ sp_block_statements_and_exceptions
+ END
+ sp_opt_label
+ {
+ $4.hndlrs+= $7.hndlrs;
+ if (unlikely(Lex->sp_block_finalize(thd, $4, &$9)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+opt_not_atomic:
+ _empty
+ | not ATOMIC_SYM // TODO: BEGIN ATOMIC (not -> opt_not)
+ ;
+
+sp_unlabeled_block:
+ BEGIN_ORACLE_SYM opt_not_atomic
+ {
+ if (unlikely(Lex->maybe_start_compound_statement(thd)))
+ MYSQL_YYABORT;
+ Lex->sp_block_init(thd);
+ if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
+ MYSQL_YYABORT;
+ }
+ sp_block_statements_and_exceptions
+ END
+ {
+ if (unlikely(Lex->sp_block_finalize(thd, Lex_spblock($4))))
+ MYSQL_YYABORT;
+ }
+ | DECLARE_ORACLE_SYM
+ {
+ if (unlikely(Lex->maybe_start_compound_statement(thd)))
+ MYSQL_YYABORT;
+ Lex->sp_block_init(thd);
+ }
+ sp_decl_body_list
+ {
+ if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
+ MYSQL_YYABORT;
+ }
+ BEGIN_ORACLE_SYM
+ sp_block_statements_and_exceptions
+ END
+ {
+ $3.hndlrs+= $6.hndlrs;
+ if (unlikely(Lex->sp_block_finalize(thd, $3)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+sp_block_statements_and_exceptions:
+ sp_instr_addr
+ sp_proc_stmts
+ {
+ if (unlikely(Lex->sp_block_with_exceptions_finalize_executable_section(thd, $1)))
+ MYSQL_YYABORT;
+ }
+ opt_exception_clause
+ {
+ if (unlikely(Lex->sp_block_with_exceptions_finalize_exceptions(thd, $1, $4)))
+ MYSQL_YYABORT;
+ $$.init($4);
+ }
+ ;
+
+End SQL_MODE_ORACLE_SPECIFIC */
/**
@} (end of group Parser)
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index 6c4ed3c2c51..bfeb67c60d1 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -320,10 +320,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%parse-param { THD *thd }
%lex-param { THD *thd }
/*
- Currently there are 40 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
+%{#ifdef SQL_MODE_DEFAULT_SPECIFIC
+%expect 37
+#endif %} // SQL_MODE_DEFAULT_SPECIFIC
+
+
+//%{#ifdef SQL_MODE_ORACLE_SPECIFIC
%expect 40
+//#endif %} // SQL_MODE_ORACLE_SPECIFIC
/*
Comments for TOKENS.
@@ -1715,7 +1721,22 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <vers_history_point> history_point
%type <vers_column_versioning> with_or_without_system
-/* Start of sql_mode=ORACLE specific declarations */
+%{#ifdef SQL_MODE_DEFAULT_SPECIFIC
+%type <NONE> sp_tail_standalone
+%type <NONE> sp_unlabeled_block_not_atomic
+%type <NONE> sp_proc_stmt_in_returns_clause
+%type <lex_str> sp_label
+%type <spblock> sp_decl_handler
+%type <spblock> sp_decls
+%type <spblock> sp_decl
+%type <spblock> sp_decl_body
+%type <spblock> sp_decl_variable_list
+%type <spblock> sp_decl_variable_list_anchored
+%type <kwd> reserved_keyword_udt_param_type
+#endif %} // SQL_MODE_DEFAULT_SPECIFIC
+
+
+//%{#ifdef SQL_MODE_ORACLE_SPECIFIC
%type <NONE> set_assign
%type <spvar_mode> sp_opt_inout
%type <NONE> sp_tail_standalone
@@ -1750,7 +1771,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <lex> package_routine_lex
%type <lex> package_specification_function
%type <lex> package_specification_procedure
-/* End of sql_mode=ORACLE specific declarations */
+//#endif %} // SQL_MODE_ORACLE_SPECIFIC
%%
@@ -17609,7 +17630,413 @@ keep_gcc_happy:
}
;
-/* Start of sql_mode=ORACLE specific rules */
+_empty:
+ /* Empty */
+ ;
+
+/* Start SQL_MODE_DEFAULT_SPECIFIC
+
+
+statement:
+ verb_clause
+ ;
+
+sp_statement:
+ statement
+ ;
+
+sp_if_then_statements:
+ sp_proc_stmts1
+ ;
+
+sp_case_then_statements:
+ sp_proc_stmts1
+ ;
+
+reserved_keyword_udt_param_type:
+ INOUT_SYM
+ | IN_SYM
+ | OUT_SYM
+ ;
+
+reserved_keyword_udt:
+ reserved_keyword_udt_not_param_type
+ | reserved_keyword_udt_param_type
+ ;
+
+// Keywords that start an SP block section
+keyword_sp_block_section:
+ BEGIN_MARIADB_SYM
+ | END
+ ;
+
+// Keywords that we allow for labels in SPs.
+// Should not include keywords that start a statement or SP characteristics.
+keyword_label:
+ keyword_data_type
+ | keyword_set_special_case
+ | keyword_sp_var_and_label
+ | keyword_sysvar_type
+ | FUNCTION_SYM
+ | EXCEPTION_ORACLE_SYM
+ ;
+
+keyword_sp_decl:
+ keyword_data_type
+ | keyword_cast_type
+ | keyword_set_special_case
+ | keyword_sp_block_section
+ | keyword_sp_head
+ | keyword_sp_var_and_label
+ | keyword_sp_var_not_label
+ | keyword_sysvar_type
+ | keyword_verb_clause
+ | FUNCTION_SYM
+ | WINDOW_SYM
+ ;
+
+opt_truncate_table_storage_clause:
+ _empty
+ ;
+
+
+ident_for_loop_index:
+ ident
+ ;
+
+row_field_name:
+ ident
+ {
+ if (!($$= Lex->row_field_name(thd, $1)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+while_body:
+ expr_lex DO_SYM
+ {
+ if (unlikely($1->sp_while_loop_expression(thd)))
+ MYSQL_YYABORT;
+ }
+ sp_proc_stmts1 END WHILE_SYM
+ {
+ if (unlikely(Lex->sp_while_loop_finalize(thd)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+for_loop_statements:
+ DO_SYM sp_proc_stmts1 END FOR_SYM
+ { }
+ ;
+
+sp_label:
+ label_ident ':' { $$= $1; }
+ ;
+
+sp_control_label:
+ sp_label
+ ;
+
+sp_block_label:
+ sp_label
+ {
+ if (unlikely(Lex->spcont->block_label_declare(&$1)))
+ MYSQL_YYABORT;
+ $$= $1;
+ }
+ ;
+
+sp_opt_default:
+ _empty { $$ = NULL; }
+ | 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
+ sp_opt_default
+ {
+ if (unlikely(Lex->sp_variable_declarations_with_ref_finalize(thd, $1, $4, $5)))
+ MYSQL_YYABORT;
+ $$.init_using_vars($1);
+ }
+ | sp_decl_idents_init_vars
+ ROW_SYM TYPE_SYM OF_SYM optionally_qualified_column_ident
+ sp_opt_default
+ {
+ if (unlikely(Lex->sp_variable_declarations_rowtype_finalize(thd, $1, $5, $6)))
+ MYSQL_YYABORT;
+ $$.init_using_vars($1);
+ }
+ ;
+
+sp_param_name_and_type_anchored:
+ sp_param_name 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
+ {
+ 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
+ {
+ 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
+ {
+ if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $5, $7)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+
+sf_c_chistics_and_body_standalone:
+ sp_c_chistics
+ {
+ LEX *lex= thd->lex;
+ lex->sphead->set_c_chistics(lex->sp_chistics);
+ lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
+ }
+ sp_proc_stmt_in_returns_clause
+ {
+ if (unlikely(Lex->sp_body_finalize_function(thd)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+sp_tail_standalone:
+ sp_name
+ {
+ if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1,
+ &sp_handler_procedure,
+ DEFAULT_AGGREGATE)))
+ MYSQL_YYABORT;
+ }
+ sp_parenthesized_pdparam_list
+ sp_c_chistics
+ {
+ Lex->sphead->set_c_chistics(Lex->sp_chistics);
+ Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
+ }
+ sp_proc_stmt
+ {
+ if (unlikely(Lex->sp_body_finalize_procedure(thd)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+drop_routine:
+ DROP FUNCTION_SYM opt_if_exists ident '.' ident
+ {
+ if (Lex->stmt_drop_function($3, $4, $6))
+ MYSQL_YYABORT;
+ }
+ | DROP FUNCTION_SYM opt_if_exists ident
+ {
+ if (Lex->stmt_drop_function($3, $4))
+ MYSQL_YYABORT;
+ }
+ | DROP PROCEDURE_SYM opt_if_exists sp_name
+ {
+ if (Lex->stmt_drop_procedure($3, $4))
+ MYSQL_YYABORT;
+ }
+ ;
+
+
+create_routine:
+ create_or_replace definer_opt PROCEDURE_SYM opt_if_not_exists
+ {
+ if (Lex->stmt_create_procedure_start($1 | $4))
+ MYSQL_YYABORT;
+ }
+ sp_tail_standalone
+ {
+ Lex->stmt_create_routine_finalize();
+ }
+ | create_or_replace definer opt_aggregate FUNCTION_SYM opt_if_not_exists
+ sp_name
+ {
+ if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6))
+ MYSQL_YYABORT;
+ }
+ sp_parenthesized_fdparam_list
+ RETURNS_SYM sf_return_type
+ sf_c_chistics_and_body_standalone
+ {
+ Lex->stmt_create_routine_finalize();
+ }
+ | create_or_replace no_definer opt_aggregate FUNCTION_SYM opt_if_not_exists
+ sp_name
+ {
+ if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6))
+ MYSQL_YYABORT;
+ }
+ sp_parenthesized_fdparam_list
+ RETURNS_SYM sf_return_type
+ sf_c_chistics_and_body_standalone
+ {
+ Lex->stmt_create_routine_finalize();
+ }
+ | create_or_replace no_definer opt_aggregate FUNCTION_SYM opt_if_not_exists
+ ident RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
+ {
+ if (Lex->stmt_create_udf_function($1 | $5, $3, $6,
+ (Item_result) $8, $10))
+ MYSQL_YYABORT;
+ }
+ ;
+
+
+sp_decls:
+ _empty
+ {
+ $$.init();
+ }
+ | sp_decls sp_decl ';'
+ {
+ // We check for declarations out of (standard) order this way
+ // because letting the grammar rules reflect it caused tricky
+ // shift/reduce conflicts with the wrong result. (And we get
+ // better error handling this way.)
+ if (unlikely(Lex->sp_declarations_join(&$$, $1, $2)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+sp_decl:
+ DECLARE_MARIADB_SYM sp_decl_body { $$= $2; }
+ ;
+
+
+sp_decl_body:
+ sp_decl_variable_list
+ | sp_decl_ident CONDITION_SYM FOR_SYM sp_cond
+ {
+ if (unlikely(Lex->spcont->declare_condition(thd, &$1, $4)))
+ MYSQL_YYABORT;
+ $$.vars= $$.hndlrs= $$.curs= 0;
+ $$.conds= 1;
+ }
+ | sp_decl_handler
+ | sp_decl_ident CURSOR_SYM
+ {
+ Lex->sp_block_init(thd);
+ }
+ opt_parenthesized_cursor_formal_parameters
+ FOR_SYM sp_cursor_stmt
+ {
+ sp_pcontext *param_ctx= Lex->spcont;
+ if (unlikely(Lex->sp_block_finalize(thd)))
+ MYSQL_YYABORT;
+ if (unlikely(Lex->sp_declare_cursor(thd, &$1, $6, param_ctx, true)))
+ MYSQL_YYABORT;
+ $$.vars= $$.conds= $$.hndlrs= 0;
+ $$.curs= 1;
+ }
+ ;
+
+
+
+// ps_proc_stmt_in_returns_clause is a statement that is allowed
+// in the RETURNS clause of a stored function definition directly,
+// without the BEGIN..END block.
+// It should not include any syntax structures starting with '(', to avoid
+// shift/reduce conflicts with the rule "field_type" and its sub-rules
+// that scan an optional length, like CHAR(1) or YEAR(4).
+// See MDEV-9166.
+
+sp_proc_stmt_in_returns_clause:
+ sp_proc_stmt_return
+ | sp_labeled_block
+ | sp_unlabeled_block
+ | sp_labeled_control
+ | sp_proc_stmt_compound_ok
+ ;
+
+sp_proc_stmt:
+ sp_proc_stmt_in_returns_clause
+ | sp_proc_stmt_statement
+ | sp_proc_stmt_continue_oracle
+ | sp_proc_stmt_exit_oracle
+ | sp_proc_stmt_leave
+ | sp_proc_stmt_iterate
+ | sp_proc_stmt_goto_oracle
+ | sp_proc_stmt_with_cursor
+ ;
+
+sp_proc_stmt_compound_ok:
+ sp_proc_stmt_if
+ | case_stmt_specification
+ | sp_unlabeled_block_not_atomic
+ | sp_unlabeled_control
+ ;
+
+
+sp_labeled_block:
+ sp_block_label
+ BEGIN_MARIADB_SYM
+ {
+ Lex->sp_block_init(thd, &$1);
+ }
+ sp_decls
+ sp_proc_stmts
+ END
+ sp_opt_label
+ {
+ if (unlikely(Lex->sp_block_finalize(thd, $4, &$7)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+sp_unlabeled_block:
+ BEGIN_MARIADB_SYM
+ {
+ Lex->sp_block_init(thd);
+ }
+ sp_decls
+ sp_proc_stmts
+ END
+ {
+ if (unlikely(Lex->sp_block_finalize(thd, $3)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+sp_unlabeled_block_not_atomic:
+ BEGIN_MARIADB_SYM not ATOMIC_SYM // TODO: BEGIN ATOMIC (not -> opt_not)
+ {
+ if (unlikely(Lex->maybe_start_compound_statement(thd)))
+ MYSQL_YYABORT;
+ Lex->sp_block_init(thd);
+ }
+ sp_decls
+ sp_proc_stmts
+ END
+ {
+ if (unlikely(Lex->sp_block_finalize(thd, $5)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+
+End SQL_MODE_DEFAULT_SPECIFIC */
+
+
+/* Start SQL_MODE_ORACLE_SPECIFIC */
statement:
verb_clause
@@ -17647,16 +18074,14 @@ reserved_keyword_udt:
reserved_keyword_udt_not_param_type
;
-/* Keywords that start an SP block section. */
+// Keywords that start an SP block section.
keyword_sp_block_section:
BEGIN_ORACLE_SYM
| END
;
-/*
- Keywords that we allow for labels in SPs.
- Should not include keywords that start a statement or SP characteristics.
-*/
+// Keywords that we allow for labels in SPs.
+// Should not include keywords that start a statement or SP characteristics.
keyword_label:
keyword_data_type
| keyword_set_special_case
@@ -17678,7 +18103,7 @@ keyword_sp_decl:
;
opt_truncate_table_storage_clause:
- /* Empty */
+ _empty
| DROP STORAGE_SYM
| REUSE_SYM STORAGE_SYM
;
@@ -17739,13 +18164,13 @@ remember_end_opt:
;
sp_opt_default:
- /* Empty */ { $$ = NULL; }
+ _empty { $$ = NULL; }
| DEFAULT expr { $$ = $2; }
| SET_VAR expr { $$ = $2; }
;
sp_opt_inout:
- /*Empty*/ { $$= sp_variable::MODE_IN; }
+ _empty { $$= sp_variable::MODE_IN; }
| sp_parameter_type
| IN_SYM OUT_SYM { $$= sp_variable::MODE_INOUT; }
;
@@ -17905,7 +18330,7 @@ label_declaration_oracle:
;
opt_exception_clause:
- /* Empty */ { $$= 0; }
+ _empty { $$= 0; }
| EXCEPTION_ORACLE_SYM exception_handlers { $$= $2; }
;
@@ -17930,7 +18355,7 @@ exception_handler:
;
sp_no_param:
- /* Empty */
+ _empty
{
Lex->sphead->m_param_begin= Lex->sphead->m_param_end=
YYLIP->get_cpp_tok_start() + 1;
@@ -17949,13 +18374,13 @@ opt_sp_parenthesized_pdparam_list:
opt_sp_name:
- /* Empty */ { $$= NULL; }
+ _empty { $$= NULL; }
| sp_name { $$= $1; }
;
opt_package_routine_end_name:
- /* Empty */ { $$= null_clex_str; }
+ _empty { $$= null_clex_str; }
| ident { $$= $1; }
;
@@ -18000,7 +18425,7 @@ create_package_chistics:
;
opt_create_package_chistics:
- /* Empty */
+ _empty
| create_package_chistics { }
;
@@ -18020,10 +18445,10 @@ package_implementation_executable_section:
| BEGIN_ORACLE_SYM sp_block_statements_and_exceptions END { $$= $2; }
;
-/*
- Inside CREATE PACKAGE BODY, package-wide items (e.g. variables)
- must be declared before routine definitions.
-*/
+
+// Inside CREATE PACKAGE BODY, package-wide items (e.g. variables)
+// must be declared before routine definitions.
+
package_implementation_declare_section:
package_implementation_declare_section_list1
| package_implementation_declare_section_list2
@@ -18174,7 +18599,7 @@ package_implementation_item_declaration:
;
opt_package_specification_element_list:
- /* Empty */
+ _empty
| package_specification_element_list
;
@@ -18415,7 +18840,7 @@ create_routine:
;
opt_sp_decl_body_list:
- /* Empty */
+ _empty
{
$$.init();
}
@@ -18452,7 +18877,7 @@ sp_decl_handler_list:
;
opt_sp_decl_handler_list:
- /* Empty*/ { $$.init(); }
+ _empty { $$.init(); }
| sp_decl_handler_list
;
@@ -18561,8 +18986,8 @@ sp_labeled_block:
;
opt_not_atomic:
- /* Empty */
- | not ATOMIC_SYM /* TODO: BEGIN ATOMIC (not -> opt_not) */
+ _empty
+ | not ATOMIC_SYM // TODO: BEGIN ATOMIC (not -> opt_not)
;
sp_unlabeled_block:
@@ -18616,7 +19041,7 @@ sp_block_statements_and_exceptions:
}
;
-/* End of sql_mode=ORACLE specific rules */
+/* End SQL_MODE_ORACLE_SPECIFIC */
/**
@} (end of group Parser)