diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-11-15 17:37:59 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-11-16 08:32:15 +0400 |
commit | 6d373e8b817861d3fd3cb181c02d45d2874d5a27 (patch) | |
tree | 9127b343c982af3924981f2a43cc0dd9584204fb | |
parent | c233d406cb50d987a5200b51c64d99c33dd77013 (diff) | |
download | mariadb-git-bb-anel-json-v2-alter_force-10.3.tar.gz |
MDEV-21064 Add a new class sp_expr_lex and a new grammar rule expr_lexbb-anel-json-v2-alter_force-10.3
Adding:
- new class sp_expr_lex
- new grammar rule expr_lex, which includes both reset_lex()
and its corresponding restore_lex()
Also:
- Moving a few methods from LEX to sp_expr_lex.
- Moving the code from *.yy to new method sp_expr_lex methods
sp_repeat_loop_finalize() and sp_if_expr().
This change makes it easier to edit the related grammar
(and makes it easier to unify sql_yacc.yy and sql_yacc_ora.yy later).
-rw-r--r-- | sql/sp_head.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 101 | ||||
-rw-r--r-- | sql/sql_lex.h | 42 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 148 | ||||
-rw-r--r-- | sql/sql_yacc_ora.yy | 148 |
5 files changed, 223 insertions, 218 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 945b3ac8854..33590646ef7 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -3078,7 +3078,7 @@ bool sp_head::add_instr_freturn(THD *thd, sp_pcontext *spcont, { sp_instr_freturn *i= new (thd->mem_root) sp_instr_freturn(instructions(), spcont, item, - m_return_field_def.type_handler(), thd->lex); + m_return_field_def.type_handler(), lex); if (i == NULL || add_instr(i)) return true; m_flags|= sp_head::HAS_RETURN; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 0a3385edb3b..d522b8e3a5e 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -61,7 +61,7 @@ const LEX_CSTRING param_clex_str= {"?", 1}; @return 0 on success */ -int LEX::case_stmt_action_expr(Item* expr) +int sp_expr_lex::case_stmt_action_expr() { int case_expr_id= spcont->register_case_expr(); sp_instr_set_case_expr *i; @@ -70,8 +70,8 @@ int LEX::case_stmt_action_expr(Item* expr) return 1; i= new (thd->mem_root) - sp_instr_set_case_expr(sphead->instructions(), spcont, case_expr_id, expr, - this); + sp_instr_set_case_expr(sphead->instructions(), spcont, case_expr_id, + get_item(), this); sphead->add_cont_backpatch(i); return sphead->add_instr(i); @@ -85,7 +85,7 @@ int LEX::case_stmt_action_expr(Item* expr) @param simple true for simple cases, false for searched cases */ -int LEX::case_stmt_action_when(Item *when, bool simple) +int sp_expr_lex::case_stmt_action_when(bool simple) { uint ip= sphead->instructions(); sp_instr_jump_if_not *i; @@ -104,11 +104,11 @@ int LEX::case_stmt_action_when(Item *when, bool simple) } #endif - expr= new (thd->mem_root) Item_func_eq(thd, var, when); + expr= new (thd->mem_root) Item_func_eq(thd, var, get_item()); i= new (thd->mem_root) sp_instr_jump_if_not(ip, spcont, expr, this); } else - i= new (thd->mem_root) sp_instr_jump_if_not(ip, spcont, when, this); + i= new (thd->mem_root) sp_instr_jump_if_not(ip, spcont, get_item(), this); /* BACKPATCH: Registering forward jump from @@ -7334,7 +7334,7 @@ bool LEX::sp_exit_block(THD *thd, sp_label *lab, Item *when) sp_instr_jump_if_not *i= new (thd->mem_root) sp_instr_jump_if_not(sphead->instructions(), spcont, - when, thd->lex); + when, this); if (unlikely(i == NULL) || unlikely(sphead->add_instr(i)) || unlikely(sp_exit_block(thd, lab))) @@ -7397,17 +7397,40 @@ bool LEX::sp_continue_loop(THD *thd, sp_label *lab) } -bool LEX::sp_continue_loop(THD *thd, sp_label *lab, Item *when) +bool LEX::sp_continue_statement(THD *thd) { - if (!when) - return sp_continue_loop(thd, lab); + sp_label *lab= spcont->find_label_current_loop_start(); + if (unlikely(!lab)) + { + my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "CONTINUE", ""); + return true; + } + DBUG_ASSERT(lab->type == sp_label::ITERATION); + return sp_continue_loop(thd, lab); +} + +bool LEX::sp_continue_statement(THD *thd, const LEX_CSTRING *label_name) +{ + sp_label *lab= spcont->find_label(label_name); + if (!lab || lab->type != sp_label::ITERATION) + { + my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "CONTINUE", label_name->str); + return true; + } + return sp_continue_loop(thd, lab); +} + + +bool LEX::sp_continue_loop(THD *thd, sp_label *lab, Item *when) +{ + DBUG_ASSERT(when); DBUG_ASSERT(sphead == thd->lex->sphead); DBUG_ASSERT(spcont == thd->lex->spcont); sp_instr_jump_if_not *i= new (thd->mem_root) sp_instr_jump_if_not(sphead->instructions(), spcont, - when, thd->lex); + when, this); if (unlikely(i == NULL) || unlikely(sphead->add_instr(i)) || unlikely(sp_continue_loop(thd, lab))) @@ -7417,7 +7440,7 @@ bool LEX::sp_continue_loop(THD *thd, sp_label *lab, Item *when) } -bool LEX::sp_continue_statement(THD *thd, Item *when) +bool sp_expr_lex::sp_continue_when_statement(THD *thd) { sp_label *lab= spcont->find_label_current_loop_start(); if (unlikely(!lab)) @@ -7426,12 +7449,12 @@ bool LEX::sp_continue_statement(THD *thd, Item *when) return true; } DBUG_ASSERT(lab->type == sp_label::ITERATION); - return sp_continue_loop(thd, lab, when); + return sp_continue_loop(thd, lab, get_item()); } -bool LEX::sp_continue_statement(THD *thd, const LEX_CSTRING *label_name, - Item *when) +bool sp_expr_lex::sp_continue_when_statement(THD *thd, + const LEX_CSTRING *label_name) { sp_label *lab= spcont->find_label(label_name); if (!lab || lab->type != sp_label::ITERATION) @@ -7439,7 +7462,7 @@ bool LEX::sp_continue_statement(THD *thd, const LEX_CSTRING *label_name, my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "CONTINUE", label_name->str); return true; } - return sp_continue_loop(thd, lab, when); + return sp_continue_loop(thd, lab, get_item()); } @@ -7504,10 +7527,10 @@ void LEX::sp_pop_loop_empty_label(THD *thd) } -bool LEX::sp_while_loop_expression(THD *thd, Item *expr) +bool LEX::sp_while_loop_expression(THD *thd, Item *item) { sp_instr_jump_if_not *i= new (thd->mem_root) - sp_instr_jump_if_not(sphead->instructions(), spcont, expr, this); + sp_instr_jump_if_not(sphead->instructions(), spcont, item, this); return (unlikely(i == NULL) || /* Jumping forward */ unlikely(sphead->push_backpatch(thd, i, spcont->last_label())) || @@ -11065,3 +11088,45 @@ bool LEX::set_cast_type_udt(Lex_cast_type_st *type, return false; } + +bool sp_expr_lex::sp_repeat_loop_finalize(THD *thd) +{ + uint ip= sphead->instructions(); + sp_label *lab= spcont->last_label(); /* Jumping back */ + sp_instr_jump_if_not *i= new (thd->mem_root) + sp_instr_jump_if_not(ip, spcont, get_item(), lab->ip, this); + if (unlikely(i == NULL) || + unlikely(sphead->add_instr(i))) + return true; + /* We can shortcut the cont_backpatch here */ + i->m_cont_dest= ip+1; + return false; +} + + +bool sp_expr_lex::sp_if_expr(THD *thd) +{ + uint ip= sphead->instructions(); + sp_instr_jump_if_not *i= new (thd->mem_root) + sp_instr_jump_if_not(ip, spcont, get_item(), this); + return + (unlikely(i == NULL) || + unlikely(sphead->push_backpatch(thd, i, + spcont->push_label(thd, &empty_clex_str, + 0))) || + unlikely(sphead->add_cont_backpatch(i)) || + unlikely(sphead->add_instr(i))); +} + + +bool LEX::sp_if_after_statements(THD *thd) +{ + uint ip= sphead->instructions(); + sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(ip, spcont); + if (unlikely(i == NULL) || + unlikely(sphead->add_instr(i))) + return true; + sphead->backpatch(spcont->pop_label()); + sphead->push_backpatch(thd, i, spcont->push_label(thd, &empty_clex_str, 0)); + return false; +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 7fc905528d6..44e4e579fdc 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -267,6 +267,7 @@ class sp_name; class sp_instr; class sp_pcontext; class sp_variable; +class sp_expr_lex; class sp_assignment_lex; class st_alter_tablespace; class partition_info; @@ -3224,7 +3225,6 @@ private: bool sp_exit_block(THD *thd, sp_label *lab, Item *when); bool sp_continue_loop(THD *thd, sp_label *lab); - bool sp_continue_loop(THD *thd, sp_label *lab, Item *when); bool sp_for_loop_condition(THD *thd, const Lex_for_loop_st &loop); bool sp_for_loop_increment(THD *thd, const Lex_for_loop_st &loop); @@ -3235,6 +3235,10 @@ private: @retval true ERROR (fields are not allowed). Error is raised. */ bool check_expr_allows_fields_or_error(THD *thd, const char *name) const; + +protected: + bool sp_continue_loop(THD *thd, sp_label *lab, Item *when); + public: void parse_error(uint err_number= ER_SYNTAX_ERROR); inline bool is_arena_for_set_stmt() {return arena_for_set_stmt != 0;} @@ -3754,8 +3758,6 @@ public: const Lex_field_type_st &def); bool sf_return_fill_definition(const Lex_field_type_st &def); - int case_stmt_action_expr(Item* expr); - int case_stmt_action_when(Item *when, bool simple); int case_stmt_action_then(); bool setup_select_in_parentheses(); bool set_trigger_new_row(const LEX_CSTRING *name, Item *val); @@ -4120,8 +4122,8 @@ public: bool sp_leave_statement(THD *thd, const LEX_CSTRING *label_name); bool sp_goto_statement(THD *thd, const LEX_CSTRING *label_name); - bool sp_continue_statement(THD *thd, Item *when); - bool sp_continue_statement(THD *thd, const LEX_CSTRING *label_name, Item *when); + bool sp_continue_statement(THD *thd); + bool sp_continue_statement(THD *thd, const LEX_CSTRING *label_name); bool sp_iterate_statement(THD *thd, const LEX_CSTRING *label_name); bool maybe_start_compound_statement(THD *thd); @@ -4131,6 +4133,7 @@ public: void sp_pop_loop_empty_label(THD *thd); bool sp_while_loop_expression(THD *thd, Item *expr); bool sp_while_loop_finalize(THD *thd); + bool sp_if_after_statements(THD *thd); bool sp_push_goto_label(THD *thd, const LEX_CSTRING *label_name); Item_param *add_placeholder(THD *thd, const LEX_CSTRING *name, @@ -4827,6 +4830,35 @@ public: }; +class sp_expr_lex: public sp_lex_local +{ + Item *m_item; // The expression +public: + sp_expr_lex(THD *thd, LEX *oldlex) + :sp_lex_local(thd, oldlex), + m_item(NULL) + { } + void set_item(Item *item) + { + m_item= item; + } + Item *get_item() const + { + return m_item; + } + bool sp_continue_when_statement(THD *thd); + bool sp_continue_when_statement(THD *thd, const LEX_CSTRING *label_name); + int case_stmt_action_expr(); + int case_stmt_action_when(bool simple); + bool sp_while_loop_expression(THD *thd) + { + return LEX::sp_while_loop_expression(thd, get_item()); + } + bool sp_repeat_loop_finalize(THD *thd); + bool sp_if_expr(THD *thd); +}; + + /** An assignment specific LEX, which additionally has an Item (an expression) and an associated with the Item free_list, which is usually freed diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ad28eac306f..9c0068b5436 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -236,6 +236,7 @@ void turn_parser_debug_on() Item_basic_constant *item_basic_constant; Key_part_spec *key_part; LEX *lex; + sp_expr_lex *expr_lex; sp_assignment_lex *assignment_lex; class sp_lex_cursor *sp_cursor_stmt; LEX_CSTRING *lex_str_ptr; @@ -1420,7 +1421,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); signal_allowed_expr simple_target_specification condition_number - reset_lex_expr opt_versioning_interval_start %type <item_param> param_marker @@ -1441,6 +1441,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); sp_cursor_stmt_lex sp_cursor_stmt +%type <expr_lex> + expr_lex + %type <assignment_lex> assignment_source_lex assignment_source_expr @@ -3702,15 +3705,11 @@ RETURN_ALLMODES_SYM: ; sp_proc_stmt_return: - RETURN_ALLMODES_SYM - { Lex->sphead->reset_lex(thd); } - expr + RETURN_ALLMODES_SYM expr_lex { - LEX *lex= Lex; - sp_head *sp= lex->sphead; - if (unlikely(sp->m_handler->add_instr_freturn(thd, sp, lex->spcont, - $3, lex)) || - unlikely(sp->restore_lex(thd))) + sp_head *sp= $2->sphead; + if (unlikely(sp->m_handler->add_instr_freturn(thd, sp, $2->spcont, + $2->get_item(), $2))) MYSQL_YYABORT; } | RETURN_ORACLE_SYM @@ -3723,10 +3722,6 @@ sp_proc_stmt_return: } ; -reset_lex_expr: - { Lex->sphead->reset_lex(thd); } expr { $$= $2; } - ; - sp_proc_stmt_exit_oracle: EXIT_ORACLE_SYM { @@ -3738,16 +3733,14 @@ sp_proc_stmt_exit_oracle: if (unlikely(Lex->sp_exit_statement(thd, &$2, NULL))) MYSQL_YYABORT; } - | EXIT_ORACLE_SYM WHEN_SYM reset_lex_expr + | EXIT_ORACLE_SYM WHEN_SYM expr_lex { - if (unlikely(Lex->sp_exit_statement(thd, $3)) || - unlikely(Lex->sphead->restore_lex(thd))) + if (unlikely($3->sp_exit_statement(thd, $3->get_item()))) MYSQL_YYABORT; } - | EXIT_ORACLE_SYM label_ident WHEN_SYM reset_lex_expr + | EXIT_ORACLE_SYM label_ident WHEN_SYM expr_lex { - if (unlikely(Lex->sp_exit_statement(thd, &$2, $4)) || - unlikely(Lex->sphead->restore_lex(thd))) + if (unlikely($4->sp_exit_statement(thd, &$2, $4->get_item()))) MYSQL_YYABORT; } ; @@ -3755,24 +3748,22 @@ sp_proc_stmt_exit_oracle: sp_proc_stmt_continue_oracle: CONTINUE_ORACLE_SYM { - if (unlikely(Lex->sp_continue_statement(thd, NULL))) + if (unlikely(Lex->sp_continue_statement(thd))) MYSQL_YYABORT; } | CONTINUE_ORACLE_SYM label_ident { - if (unlikely(Lex->sp_continue_statement(thd, &$2, NULL))) + if (unlikely(Lex->sp_continue_statement(thd, &$2))) MYSQL_YYABORT; } - | CONTINUE_ORACLE_SYM WHEN_SYM reset_lex_expr + | CONTINUE_ORACLE_SYM WHEN_SYM expr_lex { - if (unlikely(Lex->sp_continue_statement(thd, $3)) || - unlikely(Lex->sphead->restore_lex(thd))) + if (unlikely($3->sp_continue_when_statement(thd))) MYSQL_YYABORT; } - | CONTINUE_ORACLE_SYM label_ident WHEN_SYM reset_lex_expr + | CONTINUE_ORACLE_SYM label_ident WHEN_SYM expr_lex { - if (unlikely(Lex->sp_continue_statement(thd, &$2, $4)) || - unlikely(Lex->sphead->restore_lex(thd))) + if (unlikely($4->sp_continue_when_statement(thd, &$2))) MYSQL_YYABORT; } ; @@ -3802,6 +3793,26 @@ sp_proc_stmt_goto_oracle: } ; + +expr_lex: + { + DBUG_ASSERT(Lex->sphead); + if (unlikely(!($<expr_lex>$= new (thd->mem_root) + sp_expr_lex(thd, thd->lex)))) + MYSQL_YYABORT; + Lex->sphead->reset_lex(thd, $<expr_lex>$); + } + expr + { + $$= $<expr_lex>1; + $$->sp_lex_in_use= true; + $$->set_item($2); + if ($$->sphead->restore_lex(thd)) + MYSQL_YYABORT; + } + ; + + assignment_source_lex: { DBUG_ASSERT(Lex->sphead); @@ -3951,34 +3962,15 @@ sp_fetch_list: ; sp_if: - { Lex->sphead->reset_lex(thd); } - expr THEN_SYM + expr_lex THEN_SYM { - LEX *lex= Lex; - sp_head *sp= lex->sphead; - sp_pcontext *ctx= lex->spcont; - uint ip= sp->instructions(); - sp_instr_jump_if_not *i= new (thd->mem_root) - sp_instr_jump_if_not(ip, ctx, $2, lex); - if (unlikely(i == NULL) || - unlikely(sp->push_backpatch(thd, i, ctx->push_label(thd, &empty_clex_str, 0))) || - unlikely(sp->add_cont_backpatch(i)) || - unlikely(sp->add_instr(i))) - MYSQL_YYABORT; - if (unlikely(sp->restore_lex(thd))) + if (unlikely($1->sp_if_expr(thd))) MYSQL_YYABORT; } sp_proc_stmts1 { - sp_head *sp= Lex->sphead; - sp_pcontext *ctx= Lex->spcont; - uint ip= sp->instructions(); - sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(ip, ctx); - if (unlikely(i == NULL) || - unlikely(sp->add_instr(i))) + if (unlikely($1->sp_if_after_statements(thd))) MYSQL_YYABORT; - sp->backpatch(ctx->pop_label()); - sp->push_backpatch(thd, i, ctx->push_label(thd, &empty_clex_str, 0)); } sp_elseifs { @@ -4065,13 +4057,9 @@ case_stmt_specification: ; case_stmt_body: - { Lex->sphead->reset_lex(thd); /* For expr $2 */ } - expr + expr_lex { - if (unlikely(Lex->case_stmt_action_expr($2))) - MYSQL_YYABORT; - - if (Lex->sphead->restore_lex(thd)) + if (unlikely($1->case_stmt_action_expr())) MYSQL_YYABORT; } simple_when_clause_list @@ -4091,19 +4079,10 @@ searched_when_clause_list: ; simple_when_clause: - WHEN_SYM - { - Lex->sphead->reset_lex(thd); /* For expr $3 */ - } - expr + WHEN_SYM expr_lex { /* Simple case: <caseval> = <whenval> */ - - LEX *lex= Lex; - if (unlikely(lex->case_stmt_action_when($3, true))) - MYSQL_YYABORT; - /* For expr $3 */ - if (unlikely(lex->sphead->restore_lex(thd))) + if (unlikely($2->case_stmt_action_when(true))) MYSQL_YYABORT; } THEN_SYM @@ -4115,17 +4094,9 @@ simple_when_clause: ; searched_when_clause: - WHEN_SYM + WHEN_SYM expr_lex { - Lex->sphead->reset_lex(thd); /* For expr $3 */ - } - expr - { - LEX *lex= Lex; - if (unlikely(lex->case_stmt_action_when($3, false))) - MYSQL_YYABORT; - /* For expr $3 */ - if (unlikely(lex->sphead->restore_lex(thd))) + if (unlikely($2->case_stmt_action_when(false))) MYSQL_YYABORT; } THEN_SYM @@ -4265,12 +4236,9 @@ loop_body: ; while_body: - expr DO_SYM + expr_lex DO_SYM { - LEX *lex= Lex; - if (unlikely(lex->sp_while_loop_expression(thd, $1))) - MYSQL_YYABORT; - if (lex->sphead->restore_lex(thd)) + if (unlikely($1->sp_while_loop_expression(thd))) MYSQL_YYABORT; } sp_proc_stmts1 END WHILE_SYM @@ -4281,22 +4249,10 @@ while_body: ; repeat_body: - sp_proc_stmts1 UNTIL_SYM - { Lex->sphead->reset_lex(thd); } - expr END REPEAT_SYM + sp_proc_stmts1 UNTIL_SYM expr_lex END REPEAT_SYM { - LEX *lex= Lex; - uint ip= lex->sphead->instructions(); - sp_label *lab= lex->spcont->last_label(); /* Jumping back */ - sp_instr_jump_if_not *i= new (thd->mem_root) - sp_instr_jump_if_not(ip, lex->spcont, $4, lab->ip, lex); - if (unlikely(i == NULL) || - unlikely(lex->sphead->add_instr(i))) - MYSQL_YYABORT; - if (lex->sphead->restore_lex(thd)) + if ($3->sp_repeat_loop_finalize(thd)) MYSQL_YYABORT; - /* We can shortcut the cont_backpatch here */ - i->m_cont_dest= ip+1; } ; @@ -4320,7 +4276,6 @@ sp_labeled_control: { if (unlikely(Lex->sp_push_loop_label(thd, &$1))) MYSQL_YYABORT; - Lex->sphead->reset_lex(thd); } while_body pop_sp_loop_label { } @@ -4371,7 +4326,6 @@ sp_unlabeled_control: { if (unlikely(Lex->sp_push_loop_empty_label(thd))) MYSQL_YYABORT; - Lex->sphead->reset_lex(thd); } while_body { diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index c98c0f3bc00..83691438581 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -213,6 +213,7 @@ void ORAerror(THD *thd, const char *s) Item_basic_constant *item_basic_constant; Key_part_spec *key_part; LEX *lex; + sp_expr_lex *expr_lex; sp_assignment_lex *assignment_lex; class sp_lex_cursor *sp_cursor_stmt; LEX_CSTRING *lex_str_ptr; @@ -1397,7 +1398,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); signal_allowed_expr simple_target_specification condition_number - reset_lex_expr opt_versioning_interval_start %type <item_param> param_marker @@ -1418,6 +1418,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); sp_cursor_stmt_lex sp_cursor_stmt +%type <expr_lex> + expr_lex + %type <assignment_lex> assignment_source_lex assignment_source_expr @@ -4080,15 +4083,11 @@ RETURN_ALLMODES_SYM: ; sp_proc_stmt_return: - RETURN_ALLMODES_SYM - { Lex->sphead->reset_lex(thd); } - expr + RETURN_ALLMODES_SYM expr_lex { - LEX *lex= Lex; - sp_head *sp= lex->sphead; - if (unlikely(sp->m_handler->add_instr_freturn(thd, sp, lex->spcont, - $3, lex)) || - unlikely(sp->restore_lex(thd))) + sp_head *sp= $2->sphead; + if (unlikely(sp->m_handler->add_instr_freturn(thd, sp, $2->spcont, + $2->get_item(), $2))) MYSQL_YYABORT; } | RETURN_ORACLE_SYM @@ -4101,10 +4100,6 @@ sp_proc_stmt_return: } ; -reset_lex_expr: - { Lex->sphead->reset_lex(thd); } expr { $$= $2; } - ; - sp_proc_stmt_exit_oracle: EXIT_ORACLE_SYM { @@ -4116,16 +4111,14 @@ sp_proc_stmt_exit_oracle: if (unlikely(Lex->sp_exit_statement(thd, &$2, NULL))) MYSQL_YYABORT; } - | EXIT_ORACLE_SYM WHEN_SYM reset_lex_expr + | EXIT_ORACLE_SYM WHEN_SYM expr_lex { - if (unlikely(Lex->sp_exit_statement(thd, $3)) || - unlikely(Lex->sphead->restore_lex(thd))) + if (unlikely($3->sp_exit_statement(thd, $3->get_item()))) MYSQL_YYABORT; } - | EXIT_ORACLE_SYM label_ident WHEN_SYM reset_lex_expr + | EXIT_ORACLE_SYM label_ident WHEN_SYM expr_lex { - if (unlikely(Lex->sp_exit_statement(thd, &$2, $4)) || - unlikely(Lex->sphead->restore_lex(thd))) + if (unlikely($4->sp_exit_statement(thd, &$2, $4->get_item()))) MYSQL_YYABORT; } ; @@ -4133,24 +4126,22 @@ sp_proc_stmt_exit_oracle: sp_proc_stmt_continue_oracle: CONTINUE_ORACLE_SYM { - if (unlikely(Lex->sp_continue_statement(thd, NULL))) + if (unlikely(Lex->sp_continue_statement(thd))) MYSQL_YYABORT; } | CONTINUE_ORACLE_SYM label_ident { - if (unlikely(Lex->sp_continue_statement(thd, &$2, NULL))) + if (unlikely(Lex->sp_continue_statement(thd, &$2))) MYSQL_YYABORT; } - | CONTINUE_ORACLE_SYM WHEN_SYM reset_lex_expr + | CONTINUE_ORACLE_SYM WHEN_SYM expr_lex { - if (unlikely(Lex->sp_continue_statement(thd, $3)) || - unlikely(Lex->sphead->restore_lex(thd))) + if (unlikely($3->sp_continue_when_statement(thd))) MYSQL_YYABORT; } - | CONTINUE_ORACLE_SYM label_ident WHEN_SYM reset_lex_expr + | CONTINUE_ORACLE_SYM label_ident WHEN_SYM expr_lex { - if (unlikely(Lex->sp_continue_statement(thd, &$2, $4)) || - unlikely(Lex->sphead->restore_lex(thd))) + if (unlikely($4->sp_continue_when_statement(thd, &$2))) MYSQL_YYABORT; } ; @@ -4187,6 +4178,26 @@ remember_lex: } ; + +expr_lex: + { + DBUG_ASSERT(Lex->sphead); + if (unlikely(!($<expr_lex>$= new (thd->mem_root) + sp_expr_lex(thd, thd->lex)))) + MYSQL_YYABORT; + Lex->sphead->reset_lex(thd, $<expr_lex>$); + } + expr + { + $$= $<expr_lex>1; + $$->sp_lex_in_use= true; + $$->set_item($2); + if ($$->sphead->restore_lex(thd)) + MYSQL_YYABORT; + } + ; + + assignment_source_lex: { DBUG_ASSERT(Lex->sphead); @@ -4336,34 +4347,15 @@ sp_fetch_list: ; sp_if: - { Lex->sphead->reset_lex(thd); } - expr THEN_SYM + expr_lex THEN_SYM { - LEX *lex= Lex; - sp_head *sp= lex->sphead; - sp_pcontext *ctx= lex->spcont; - uint ip= sp->instructions(); - sp_instr_jump_if_not *i= new (thd->mem_root) - sp_instr_jump_if_not(ip, ctx, $2, lex); - if (unlikely(i == NULL) || - unlikely(sp->push_backpatch(thd, i, ctx->push_label(thd, &empty_clex_str, 0))) || - unlikely(sp->add_cont_backpatch(i)) || - unlikely(sp->add_instr(i))) - MYSQL_YYABORT; - if (unlikely(sp->restore_lex(thd))) + if (unlikely($1->sp_if_expr(thd))) MYSQL_YYABORT; } sp_proc_stmts1_implicit_block { - sp_head *sp= Lex->sphead; - sp_pcontext *ctx= Lex->spcont; - uint ip= sp->instructions(); - sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(ip, ctx); - if (unlikely(i == NULL) || - unlikely(sp->add_instr(i))) + if (unlikely($1->sp_if_after_statements(thd))) MYSQL_YYABORT; - sp->backpatch(ctx->pop_label()); - sp->push_backpatch(thd, i, ctx->push_label(thd, &empty_clex_str, 0)); } sp_elseifs { @@ -4450,13 +4442,9 @@ case_stmt_specification: ; case_stmt_body: - { Lex->sphead->reset_lex(thd); /* For expr $2 */ } - expr + expr_lex { - if (unlikely(Lex->case_stmt_action_expr($2))) - MYSQL_YYABORT; - - if (Lex->sphead->restore_lex(thd)) + if (unlikely($1->case_stmt_action_expr())) MYSQL_YYABORT; } simple_when_clause_list @@ -4476,19 +4464,10 @@ searched_when_clause_list: ; simple_when_clause: - WHEN_SYM - { - Lex->sphead->reset_lex(thd); /* For expr $3 */ - } - expr + WHEN_SYM expr_lex { /* Simple case: <caseval> = <whenval> */ - - LEX *lex= Lex; - if (unlikely(lex->case_stmt_action_when($3, true))) - MYSQL_YYABORT; - /* For expr $3 */ - if (unlikely(lex->sphead->restore_lex(thd))) + if (unlikely($2->case_stmt_action_when(true))) MYSQL_YYABORT; } THEN_SYM @@ -4500,17 +4479,9 @@ simple_when_clause: ; searched_when_clause: - WHEN_SYM + WHEN_SYM expr_lex { - Lex->sphead->reset_lex(thd); /* For expr $3 */ - } - expr - { - LEX *lex= Lex; - if (unlikely(lex->case_stmt_action_when($3, false))) - MYSQL_YYABORT; - /* For expr $3 */ - if (unlikely(lex->sphead->restore_lex(thd))) + if (unlikely($2->case_stmt_action_when(false))) MYSQL_YYABORT; } THEN_SYM @@ -4740,12 +4711,9 @@ loop_body: ; while_body: - expr LOOP_SYM + expr_lex LOOP_SYM { - LEX *lex= Lex; - if (unlikely(lex->sp_while_loop_expression(thd, $1))) - MYSQL_YYABORT; - if (lex->sphead->restore_lex(thd)) + if (unlikely($1->sp_while_loop_expression(thd))) MYSQL_YYABORT; } sp_proc_stmts1 END LOOP_SYM @@ -4756,22 +4724,10 @@ while_body: ; repeat_body: - sp_proc_stmts1 UNTIL_SYM - { Lex->sphead->reset_lex(thd); } - expr END REPEAT_SYM + sp_proc_stmts1 UNTIL_SYM expr_lex END REPEAT_SYM { - LEX *lex= Lex; - uint ip= lex->sphead->instructions(); - sp_label *lab= lex->spcont->last_label(); /* Jumping back */ - sp_instr_jump_if_not *i= new (thd->mem_root) - sp_instr_jump_if_not(ip, lex->spcont, $4, lab->ip, lex); - if (unlikely(i == NULL) || - unlikely(lex->sphead->add_instr(i))) - MYSQL_YYABORT; - if (lex->sphead->restore_lex(thd)) + if ($3->sp_repeat_loop_finalize(thd)) MYSQL_YYABORT; - /* We can shortcut the cont_backpatch here */ - i->m_cont_dest= ip+1; } ; @@ -4795,7 +4751,6 @@ sp_labeled_control: { if (unlikely(Lex->sp_push_loop_label(thd, &$1))) MYSQL_YYABORT; - Lex->sphead->reset_lex(thd); } while_body pop_sp_loop_label { } @@ -4846,7 +4801,6 @@ sp_unlabeled_control: { if (unlikely(Lex->sp_push_loop_empty_label(thd))) MYSQL_YYABORT; - Lex->sphead->reset_lex(thd); } while_body { |