diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-03-06 17:36:30 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-03-07 18:48:15 +0400 |
commit | 5f34513c2a2dd5f8431cf03f6ba083c42f233dca (patch) | |
tree | a4314e0b0762a0401de604a5e23fa20d3a8551b8 /sql/sql_yacc_ora.yy | |
parent | a71d185a9a84c4c5f5d251e43aaaaf6efa0aa8d9 (diff) | |
download | mariadb-git-5f34513c2a2dd5f8431cf03f6ba083c42f233dca.tar.gz |
MDEV-18813 PROCEDURE and anonymous blocks silently ignore FETCH GROUP NEXT ROW
Part#2 (final): rewritting the code to pass the correct enum_sp_aggregate_type
to the sp_head constructor, so sp_head never changes its aggregation type
later on. The grammar has been simplified and defragmented.
This allowed to check aggregate specific instructions right after
a routine body has been scanned, by calling new LEX methods:
sp_body_finalize_{procedure|function|trigger|event}()
Moving some C++ code from *.yy to a few new helper methods in LEX.
Diffstat (limited to 'sql/sql_yacc_ora.yy')
-rw-r--r-- | sql/sql_yacc_ora.yy | 212 |
1 files changed, 85 insertions, 127 deletions
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 0f7bbdcff5e..e709e7e3afa 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -254,6 +254,7 @@ void ORAerror(THD *thd, const char *s) /* enums */ enum enum_sp_suid_behaviour sp_suid; + enum enum_sp_aggregate_type sp_aggregate_type; enum enum_view_suid view_suid; enum Condition_information_item::Name cond_info_item_name; enum enum_diag_condition_item_name diag_condition_item_name; @@ -1565,9 +1566,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); opt_field_or_var_spec fields_or_vars opt_load_data_set_spec view_list_opt view_list view_select trigger_tail event_tail - udf_tail - create_function_tail_standalone - create_aggregate_function_tail_standalone install uninstall partition_entry binlog_base64_event normal_key_options normal_key_opts all_key_opt spatial_key_options fulltext_key_options normal_key_opt @@ -1587,7 +1585,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); opt_delete_gtid_domain asrow_attribute set_assign - sf_tail_standalone sp_tail_standalone opt_constraint_no_id END_OF_INPUT @@ -1613,6 +1610,7 @@ END_OF_INPUT %type <plsql_cursor_attr> plsql_cursor_attr %type <sp_suid> sp_suid +%type <sp_aggregate_type> opt_aggregate %type <num> sp_decl_idents sp_decl_idents_init_vars %type <num> sp_handler_type sp_hcond_list @@ -2381,41 +2379,66 @@ create: { Lex->pop_select(); //main select } - | create_or_replace definer FUNCTION_SYM opt_if_not_exists + | create_or_replace definer opt_aggregate FUNCTION_SYM opt_if_not_exists + sp_name RETURN_ORACLE_SYM { - if (Lex->stmt_create_function_start($1 | $4)) + if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6)) MYSQL_YYABORT; } - sf_tail_standalone + sf_return_type + sf_c_chistics_and_body_standalone + opt_sp_name { - Lex->stmt_create_routine_finalize(); + if (Lex->stmt_create_stored_function_finalize_standalone($11)) + MYSQL_YYABORT; } - | create_or_replace definer AGGREGATE_SYM FUNCTION_SYM opt_if_not_exists + | create_or_replace definer opt_aggregate FUNCTION_SYM opt_if_not_exists + sp_name '(' { - if (Lex->stmt_create_function_start($1 | $5)) + if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6)) MYSQL_YYABORT; } - sf_tail_aggregate_standalone + sp_fdparam_list ')' + RETURN_ORACLE_SYM sf_return_type + sf_c_chistics_and_body_standalone + opt_sp_name { - Lex->stmt_create_routine_finalize(); + if (Lex->stmt_create_stored_function_finalize_standalone($14)) + MYSQL_YYABORT; } - | create_or_replace no_definer FUNCTION_SYM opt_if_not_exists + | create_or_replace no_definer opt_aggregate FUNCTION_SYM opt_if_not_exists + sp_name RETURN_ORACLE_SYM { - if (Lex->stmt_create_function_start($1 | $4)) + if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6)) MYSQL_YYABORT; } - create_function_tail_standalone + sf_return_type + sf_c_chistics_and_body_standalone + opt_sp_name { - Lex->stmt_create_routine_finalize(); + if (Lex->stmt_create_stored_function_finalize_standalone($11)) + MYSQL_YYABORT; } - | create_or_replace no_definer AGGREGATE_SYM FUNCTION_SYM opt_if_not_exists + | create_or_replace no_definer opt_aggregate FUNCTION_SYM opt_if_not_exists + sp_name '(' { - if (Lex->stmt_create_function_start($1 | $5)) + if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6)) MYSQL_YYABORT; } - create_aggregate_function_tail_standalone + sp_fdparam_list ')' + RETURN_ORACLE_SYM sf_return_type + sf_c_chistics_and_body_standalone + opt_sp_name { - Lex->stmt_create_routine_finalize(); + if (Lex->stmt_create_stored_function_finalize_standalone($14)) + 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 USER_SYM opt_if_not_exists clear_privileges grant_list opt_require_clause opt_resource_options opt_account_locking opt_password_expiration @@ -2454,7 +2477,7 @@ create: &sp_handler_package_spec, $5, $1 | $4)))) MYSQL_YYABORT; - pkg->set_chistics(Lex->sp_chistics); + pkg->set_c_chistics(Lex->sp_chistics); } opt_package_specification_element_list END remember_end_opt opt_sp_name @@ -2474,7 +2497,7 @@ create: &sp_handler_package_body, $6, $1 | $5)))) MYSQL_YYABORT; - pkg->set_chistics(Lex->sp_chistics); + pkg->set_c_chistics(Lex->sp_chistics); Lex->sp_block_init(thd); } package_implementation_declare_section @@ -2495,39 +2518,6 @@ create: } ; -sf_tail_not_aggregate_standalone: - sf_tail_standalone - { - if (unlikely(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR)) - { - my_yyabort_error((ER_NOT_AGGREGATE_FUNCTION, MYF(0))); - } - Lex->sphead->set_chistics_agg_type(NOT_AGGREGATE); - } - ; - -sf_tail_aggregate_standalone: - sf_tail_standalone - { - if (unlikely(!(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR))) - { - my_yyabort_error((ER_INVALID_AGGREGATE_FUNCTION, MYF(0))); - } - Lex->sphead->set_chistics_agg_type(GROUP_AGGREGATE); - } - ; - -create_function_tail_standalone: - sf_tail_not_aggregate_standalone { } - | udf_tail { Lex->udf.type= UDFTYPE_FUNCTION; } - ; - - -create_aggregate_function_tail_standalone: - sf_tail_aggregate_standalone { } - | udf_tail { Lex->udf.type= UDFTYPE_AGGREGATE; } - ; - package_implementation_executable_section: END { @@ -2584,13 +2574,14 @@ package_specification_function: MYSQL_YYABORT; thd->lex= $2; if (unlikely(!$2->make_sp_head_no_recursive(thd, spname, - &sp_handler_package_function))) + &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 - sf_return_type + RETURN_ORACLE_SYM sf_return_type sp_c_chistics { sp_head *sp= thd->lex->sphead; @@ -2610,7 +2601,8 @@ package_specification_procedure: MYSQL_YYABORT; thd->lex= $2; if (unlikely(!$2->make_sp_head_no_recursive(thd, spname, - &sp_handler_package_procedure))) + &sp_handler_package_procedure, + DEFAULT_AGGREGATE))) MYSQL_YYABORT; $1->sphead->get_package()->m_current_routine= $2; } @@ -2660,11 +2652,6 @@ package_implementation_function_body: } sp_body opt_package_routine_end_name { - if (unlikely(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR)) - { - my_yyabort_error((ER_NOT_AGGREGATE_FUNCTION, MYF(0))); - } - Lex->sphead->set_chistics_agg_type(NOT_AGGREGATE); if (unlikely(thd->lex->sp_body_finalize_function(thd) || thd->lex->sphead->check_package_routine_end_name($5))) MYSQL_YYABORT; @@ -2684,7 +2671,7 @@ package_implementation_procedure_body: 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))) + thd->lex->sphead->check_package_routine_end_name($5))) MYSQL_YYABORT; thd->lex= $2; } @@ -3043,20 +3030,17 @@ ev_sql_stmt: if (unlikely(!lex->make_sp_head(thd, lex->event_parse_data->identifier, - &sp_handler_procedure))) + &sp_handler_procedure, + DEFAULT_AGGREGATE))) MYSQL_YYABORT; lex->sphead->set_body_start(thd, lip->get_cpp_ptr()); } sp_proc_stmt { - LEX *lex= thd->lex; - /* return back to the original memory root ASAP */ - lex->sphead->set_stmt_end(thd); - lex->sphead->restore_thd_mem_root(thd); - - lex->event_parse_data->body_changed= TRUE; + if (Lex->sp_body_finalize_event(thd)) + MYSQL_YYABORT; } ; @@ -3073,6 +3057,11 @@ clear_privileges: } ; +opt_aggregate: + /* Empty */ { $$= NOT_AGGREGATE; } + | AGGREGATE_SYM { $$= GROUP_AGGREGATE; } + ; + sp_name: ident '.' ident { @@ -3186,7 +3175,18 @@ sp_cparams: /* Stored FUNCTION parameter declaration list */ sp_fdparam_list: /* Empty */ - | sp_fdparams + { + Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start(); + Lex->sphead->m_param_end= Lex->sphead->m_param_begin; + } + | + { + Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start(); + } + sp_fdparams + { + Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start(); + } ; sp_fdparams: @@ -3293,18 +3293,6 @@ sp_opt_inout: | IN_SYM OUT_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: '(' { @@ -3327,7 +3315,7 @@ sp_no_param: opt_sp_parenthesized_fdparam_list: sp_no_param - | sp_parenthesized_fdparam_list + | '(' sp_fdparam_list ')' ; opt_sp_parenthesized_pdparam_list: @@ -17620,8 +17608,8 @@ compound_statement: sp_proc_stmt_compound_ok { Lex->sql_command= SQLCOM_COMPOUND; - Lex->sphead->set_stmt_end(thd); - Lex->sphead->restore_thd_mem_root(thd); + if (Lex->sp_body_finalize_procedure(thd)) + MYSQL_YYABORT; } ; @@ -17908,7 +17896,8 @@ trigger_tail: (*static_cast<st_trg_execution_order*>(&lex->trg_chistics))= ($17); lex->trg_chistics.ordering_clause_end= lip->get_cpp_ptr(); - if (unlikely(!lex->make_sp_head(thd, $4, &sp_handler_trigger))) + if (unlikely(!lex->make_sp_head(thd, $4, &sp_handler_trigger, + DEFAULT_AGGREGATE))) MYSQL_YYABORT; lex->sphead->set_body_start(thd, lip->get_cpp_tok_start()); @@ -17916,15 +17905,9 @@ trigger_tail: sp_proc_stmt /* $19 */ { /* $20 */ LEX *lex= Lex; - sp_head *sp= lex->sphead; - if (unlikely(sp->check_unresolved_goto())) - MYSQL_YYABORT; lex->sql_command= SQLCOM_CREATE_TRIGGER; - sp->set_stmt_end(thd); - sp->restore_thd_mem_root(thd); - - if (unlikely(sp->is_not_allowed_in_function("trigger"))) + if (lex->sp_body_finalize_trigger(thd)) MYSQL_YYABORT; /* @@ -17946,22 +17929,7 @@ trigger_tail: **************************************************************************/ -udf_tail: - ident RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys - { - LEX *lex= thd->lex; - if (unlikely(is_native_function(thd, & $1))) - my_yyabort_error((ER_NATIVE_FCT_NAME_COLLISION, MYF(0), $1.str)); - lex->sql_command= SQLCOM_CREATE_FUNCTION; - lex->udf.name= $1; - lex->udf.returns= (Item_result) $3; - lex->udf.dl= $5.str; - } - ; - - sf_return_type: - RETURN_ORACLE_SYM { LEX *lex= Lex; lex->init_last_field(&lex->sphead->m_return_field_def, @@ -17976,28 +17944,17 @@ sf_return_type: } ; -sf_tail_standalone: - sp_name - { - if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1, - &sp_handler_function))) - MYSQL_YYABORT; - } - opt_sp_parenthesized_fdparam_list - sf_return_type +sf_c_chistics_and_body_standalone: sp_c_chistics { LEX *lex= thd->lex; - Lex_input_stream *lip= YYLIP; - - lex->sphead->set_chistics(lex->sp_chistics); - lex->sphead->set_body_start(thd, lip->get_cpp_tok_start()); + 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_function_standalone(thd, $9))) + if (unlikely(Lex->sp_body_finalize_function(thd))) MYSQL_YYABORT; } ; @@ -18006,13 +17963,14 @@ sp_tail_standalone: sp_name { if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1, - &sp_handler_procedure))) + &sp_handler_procedure, + DEFAULT_AGGREGATE))) MYSQL_YYABORT; } opt_sp_parenthesized_pdparam_list sp_c_chistics { - Lex->sphead->set_chistics(Lex->sp_chistics); + Lex->sphead->set_c_chistics(Lex->sp_chistics); Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start()); } sp_tail_is |