Commit 6d373e8b authored by Alexander Barkov's avatar Alexander Barkov

MDEV-21064 Add a new class sp_expr_lex and a new grammar rule expr_lex

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).
parent c233d406
......@@ -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;
......
......@@ -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;
}
......@@ -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 @@ struct LEX: public Query_tables_list
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 @@ struct LEX: public Query_tables_list
@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 @@ struct LEX: public Query_tables_list
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 @@ struct LEX: public Query_tables_list
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 @@ struct LEX: public Query_tables_list
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 @@ class sp_lex_set_var: public sp_lex_local
};
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
......
......@@ -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
{
......
......@@ -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
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment