diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2020-08-11 16:37:48 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2020-08-31 14:40:34 +0200 |
commit | 0f080dd60a9a4fbfcd9c8a2d0361c9d7f0c080aa (patch) | |
tree | b3d3281f2182f1cc40a215d9c8cbe31d188dd9c0 /sql/sql_yacc.yy | |
parent | 571764c04fc9b736366959b2c0e00d9bd0eb5a4e (diff) | |
download | mariadb-git-0f080dd60a9a4fbfcd9c8a2d0361c9d7f0c080aa.tar.gz |
MDEV-23094: Multiple calls to a Stored Procedure from another Stored Procedure crashes serverbb-10.4-MDEV-23094
Added system-SELECT to IF/WHILE/REPET/FOR for correct subqueries connecting.
Added control of system/usual selects for correct error detection.
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r-- | sql/sql_yacc.yy | 85 |
1 files changed, 72 insertions, 13 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 14b7a5589e1..83323e3f7e3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2809,8 +2809,6 @@ create: { Lex->create_info.default_table_charset= NULL; Lex->create_info.used_fields= 0; - if (Lex->main_select_push()) - MYSQL_YYABORT; } opt_create_database_options { @@ -2819,7 +2817,6 @@ create: $1 | $3))) MYSQL_YYABORT; lex->name= $4; - Lex->pop_select(); //main select } | create_or_replace definer_opt opt_view_suid VIEW_SYM opt_if_not_exists table_ident @@ -3653,10 +3650,13 @@ sp_cursor_stmt: { DBUG_ASSERT(thd->free_list == NULL); Lex->sphead->reset_lex(thd, $1); + if (Lex->main_select_push(true)) + MYSQL_YYABORT; } select { DBUG_ASSERT(Lex == $1); + Lex->pop_select(); //main select if (unlikely($1->stmt_finalize(thd)) || unlikely($1->sphead->restore_lex(thd))) MYSQL_YYABORT; @@ -4154,6 +4154,11 @@ sp_proc_stmt_statement: Lex_input_stream *lip= YYLIP; lex->sphead->reset_lex(thd); + /* + We should not push main select here, it will be done or not + done by the statement, we just provide only a new LEX for the + statement here as if it is start of parsing a new statement. + */ lex->sphead->m_tmp_query= lip->get_tok_start(); } statement @@ -4172,11 +4177,16 @@ RETURN_ALLMODES_SYM: sp_proc_stmt_return: RETURN_ALLMODES_SYM - { Lex->sphead->reset_lex(thd); } + { + Lex->sphead->reset_lex(thd); + if (Lex->main_select_push(true)) + MYSQL_YYABORT; + } expr { LEX *lex= Lex; sp_head *sp= lex->sphead; + Lex->pop_select(); //main select if (unlikely(sp->m_handler->add_instr_freturn(thd, sp, lex->spcont, $3, lex)) || unlikely(sp->restore_lex(thd))) @@ -4193,7 +4203,16 @@ sp_proc_stmt_return: ; reset_lex_expr: - { Lex->sphead->reset_lex(thd); } expr { $$= $2; } + { + Lex->sphead->reset_lex(thd); + if (Lex->main_select_push(true)) + MYSQL_YYABORT; + } + expr + { + Lex->pop_select(); //main select + $$= $2; + } ; sp_proc_stmt_exit_oracle: @@ -4285,6 +4304,8 @@ assignment_source_expr: { DBUG_ASSERT(thd->free_list == NULL); Lex->sphead->reset_lex(thd, $1); + if (Lex->main_select_push(true)) + MYSQL_YYABORT; } expr { @@ -4293,6 +4314,7 @@ assignment_source_expr: $$->sp_lex_in_use= true; $$->set_item_and_free_list($3, thd->free_list); thd->free_list= NULL; + Lex->pop_select(); //min select if ($$->sphead->restore_lex(thd)) MYSQL_YYABORT; } @@ -4302,6 +4324,8 @@ for_loop_bound_expr: assignment_source_lex { Lex->sphead->reset_lex(thd, $1); + if (Lex->main_select_push(true)) + MYSQL_YYABORT; Lex->current_select->parsing_place= FOR_LOOP_BOUND; } expr @@ -4310,6 +4334,7 @@ for_loop_bound_expr: $$= $1; $$->sp_lex_in_use= true; $$->set_item_and_free_list($3, NULL); + Lex->pop_select(); //main select if (unlikely($$->sphead->restore_lex(thd))) MYSQL_YYABORT; Lex->current_select->parsing_place= NO_MATTER; @@ -4424,7 +4449,11 @@ sp_fetch_list: ; sp_if: - { Lex->sphead->reset_lex(thd); } + { + Lex->sphead->reset_lex(thd); + if (Lex->main_select_push(true)) + MYSQL_YYABORT; + } expr THEN_SYM { LEX *lex= Lex; @@ -4438,6 +4467,7 @@ sp_if: unlikely(sp->add_cont_backpatch(i)) || unlikely(sp->add_instr(i))) MYSQL_YYABORT; + Lex->pop_select(); //main select if (unlikely(sp->restore_lex(thd))) MYSQL_YYABORT; } @@ -4538,12 +4568,17 @@ case_stmt_specification: ; case_stmt_body: - { Lex->sphead->reset_lex(thd); /* For expr $2 */ } + { + Lex->sphead->reset_lex(thd); /* For expr $2 */ + if (Lex->main_select_push(true)) + MYSQL_YYABORT; + } expr { if (unlikely(Lex->case_stmt_action_expr($2))) MYSQL_YYABORT; + Lex->pop_select(); //main select if (Lex->sphead->restore_lex(thd)) MYSQL_YYABORT; } @@ -4567,6 +4602,8 @@ simple_when_clause: WHEN_SYM { Lex->sphead->reset_lex(thd); /* For expr $3 */ + if (Lex->main_select_push(true)) + MYSQL_YYABORT; } expr { @@ -4575,6 +4612,7 @@ simple_when_clause: LEX *lex= Lex; if (unlikely(lex->case_stmt_action_when($3, true))) MYSQL_YYABORT; + Lex->pop_select(); //main select /* For expr $3 */ if (unlikely(lex->sphead->restore_lex(thd))) MYSQL_YYABORT; @@ -4591,12 +4629,15 @@ searched_when_clause: WHEN_SYM { Lex->sphead->reset_lex(thd); /* For expr $3 */ + if (Lex->main_select_push(true)) + MYSQL_YYABORT; } expr { LEX *lex= Lex; if (unlikely(lex->case_stmt_action_when($3, false))) MYSQL_YYABORT; + Lex->pop_select(); //main select /* For expr $3 */ if (unlikely(lex->sphead->restore_lex(thd))) MYSQL_YYABORT; @@ -4695,9 +4736,15 @@ opt_sp_for_loop_direction: ; sp_for_loop_index_and_bounds: - ident sp_for_loop_bounds + ident { - if (unlikely(Lex->sp_for_loop_declarations(thd, &$$, &$1, $2))) + if (Lex->main_select_push(true)) + MYSQL_YYABORT; + } + sp_for_loop_bounds + { + Lex->pop_select(); //main select + if (unlikely(Lex->sp_for_loop_declarations(thd, &$$, &$1, $3))) MYSQL_YYABORT; } ; @@ -4743,8 +4790,11 @@ while_body: LEX *lex= Lex; if (unlikely(lex->sp_while_loop_expression(thd, $1))) MYSQL_YYABORT; + Lex->pop_select(); //main select if (lex->sphead->restore_lex(thd)) MYSQL_YYABORT; + if (lex->main_select_push(true)) + MYSQL_YYABORT; } sp_proc_stmts1 END WHILE_SYM { @@ -4755,7 +4805,11 @@ while_body: repeat_body: sp_proc_stmts1 UNTIL_SYM - { Lex->sphead->reset_lex(thd); } + { + Lex->sphead->reset_lex(thd); + if (Lex->main_select_push(true)) + MYSQL_YYABORT; + } expr END REPEAT_SYM { LEX *lex= Lex; @@ -4766,6 +4820,7 @@ repeat_body: if (unlikely(i == NULL) || unlikely(lex->sphead->add_instr(i))) MYSQL_YYABORT; + Lex->pop_select(); //main select if (lex->sphead->restore_lex(thd)) MYSQL_YYABORT; /* We can shortcut the cont_backpatch here */ @@ -4794,6 +4849,8 @@ sp_labeled_control: if (unlikely(Lex->sp_push_loop_label(thd, &$1))) MYSQL_YYABORT; Lex->sphead->reset_lex(thd); + if (Lex->main_select_push(true)) + MYSQL_YYABORT; } while_body pop_sp_loop_label { } @@ -4845,6 +4902,8 @@ sp_unlabeled_control: if (unlikely(Lex->sp_push_loop_empty_label(thd))) MYSQL_YYABORT; Lex->sphead->reset_lex(thd); + if (Lex->main_select_push(true)) + MYSQL_YYABORT; } while_body { @@ -7816,7 +7875,7 @@ alter: { Lex->create_info.default_table_charset= NULL; Lex->create_info.used_fields= 0; - if (Lex->main_select_push()) + if (Lex->main_select_push(true)) MYSQL_YYABORT; } create_database_options @@ -13265,7 +13324,7 @@ do: { LEX *lex=Lex; lex->sql_command = SQLCOM_DO; - if (lex->main_select_push()) + if (lex->main_select_push(true)) MYSQL_YYABORT; mysql_init_select(lex); } @@ -16453,7 +16512,7 @@ set: SET { LEX *lex=Lex; - if (lex->main_select_push()) + if (lex->main_select_push(true)) MYSQL_YYABORT; lex->set_stmt_init(); lex->var_list.empty(); |