summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-11-15 17:37:59 +0400
committerAlexander Barkov <bar@mariadb.com>2019-11-16 08:32:15 +0400
commit6d373e8b817861d3fd3cb181c02d45d2874d5a27 (patch)
tree9127b343c982af3924981f2a43cc0dd9584204fb
parentc233d406cb50d987a5200b51c64d99c33dd77013 (diff)
downloadmariadb-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.cc2
-rw-r--r--sql/sql_lex.cc101
-rw-r--r--sql/sql_lex.h42
-rw-r--r--sql/sql_yacc.yy148
-rw-r--r--sql/sql_yacc_ora.yy148
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
{