mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
sql_lex.yy / sql_yacc_ora.yy refactoring for MDEV-10411.
1. Adding const qualifiers into a few method parameters. 2. Adding methods: - sp_label::block_label_declare() - LEX::sp_block_init() - LEX::sp_block_finalize() to share more code between the files sql_yacc.yy and sql_yacc_ora.yy, as well as between the rules sp_labeled_block, sp_unlabeled_block, sp_unlabeled_block_not_atomic. 3. sql_yacc.yy, sql_yacc_ora.yy changes: - Removing sp_block_content - Reorganizing the grammar so the rules sp_labeled_block, sp_unlabeled_block, sp_unlabeled_block_not_atomic now contain both BEGIN_SYM and END keywords. Previously, BEGIN_SYM and END resided in different rules. This change makes the grammar easier to read, as well as simplifies adding Oracle-style DECLARE section (coming soon): DECLARE .. BEGIN .. END; Good side effects: - SP block related grammar does not use Lex->name any more. - The "splabel" member was removed from %union
This commit is contained in:
parent
36b80caed1
commit
365e0b3178
7 changed files with 161 additions and 122 deletions
|
@ -211,7 +211,7 @@ sp_label *sp_pcontext::push_label(THD *thd, LEX_STRING name, uint ip)
|
|||
}
|
||||
|
||||
|
||||
sp_label *sp_pcontext::find_label(LEX_STRING name)
|
||||
sp_label *sp_pcontext::find_label(const LEX_STRING name)
|
||||
{
|
||||
List_iterator_fast<sp_label> li(m_labels);
|
||||
sp_label *lab;
|
||||
|
|
|
@ -108,7 +108,8 @@ public:
|
|||
class sp_pcontext *ctx;
|
||||
|
||||
public:
|
||||
sp_label(LEX_STRING _name, uint _ip, enum_type _type, sp_pcontext *_ctx)
|
||||
sp_label(const LEX_STRING _name,
|
||||
uint _ip, enum_type _type, sp_pcontext *_ctx)
|
||||
:Sql_alloc(),
|
||||
name(_name),
|
||||
ip(_ip),
|
||||
|
@ -401,9 +402,9 @@ public:
|
|||
// Labels.
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
sp_label *push_label(THD *thd, LEX_STRING name, uint ip);
|
||||
sp_label *push_label(THD *thd, const LEX_STRING name, uint ip);
|
||||
|
||||
sp_label *find_label(LEX_STRING name);
|
||||
sp_label *find_label(const LEX_STRING name);
|
||||
|
||||
sp_label *last_label()
|
||||
{
|
||||
|
@ -418,6 +419,17 @@ public:
|
|||
sp_label *pop_label()
|
||||
{ return m_labels.pop(); }
|
||||
|
||||
bool block_label_declare(LEX_STRING label)
|
||||
{
|
||||
sp_label *lab= find_label(label);
|
||||
if (lab)
|
||||
{
|
||||
my_error(ER_SP_LABEL_REDEFINE, MYF(0), label.str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Conditions.
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -5309,6 +5309,62 @@ bool LEX::sp_handler_declaration_finalize(THD *thd, int type)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
void LEX::sp_block_init(THD *thd, const LEX_STRING label)
|
||||
{
|
||||
sp_label *lab= spcont->push_label(thd, label, sphead->instructions());
|
||||
lab->type= sp_label::BEGIN;
|
||||
spcont= spcont->push_context(thd, sp_pcontext::REGULAR_SCOPE);
|
||||
}
|
||||
|
||||
|
||||
bool LEX::sp_block_finalize(THD *thd, const Lex_spblock_st spblock,
|
||||
class sp_label **splabel)
|
||||
{
|
||||
sp_head *sp= sphead;
|
||||
sp_pcontext *ctx= spcont;
|
||||
sp_instr *i;
|
||||
|
||||
sp->backpatch(ctx->last_label()); /* We always have a label */
|
||||
if (spblock.hndlrs)
|
||||
{
|
||||
i= new (thd->mem_root)
|
||||
sp_instr_hpop(sp->instructions(), ctx, spblock.hndlrs);
|
||||
if (i == NULL ||
|
||||
sp->add_instr(i))
|
||||
return true;
|
||||
}
|
||||
if (spblock.curs)
|
||||
{
|
||||
i= new (thd->mem_root)
|
||||
sp_instr_cpop(sp->instructions(), ctx, spblock.curs);
|
||||
if (i == NULL ||
|
||||
sp->add_instr(i))
|
||||
return true;
|
||||
}
|
||||
spcont= ctx->pop_context();
|
||||
*splabel= spcont->pop_label();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool LEX::sp_block_finalize(THD *thd, const Lex_spblock_st spblock,
|
||||
const LEX_STRING end_label)
|
||||
{
|
||||
sp_label *splabel;
|
||||
if (sp_block_finalize(thd, spblock, &splabel))
|
||||
return true;
|
||||
if (end_label.str &&
|
||||
my_strcasecmp(system_charset_info,
|
||||
end_label.str, splabel->name.str) != 0)
|
||||
{
|
||||
my_error(ER_SP_LABEL_MISMATCH, MYF(0), end_label.str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MYSQL_SERVER
|
||||
uint binlog_unsafe_map[256];
|
||||
|
||||
|
|
|
@ -2626,6 +2626,8 @@ private:
|
|||
Query_arena_memroot *arena_for_set_stmt;
|
||||
MEM_ROOT *mem_root_for_set_stmt;
|
||||
void parse_error();
|
||||
bool sp_block_finalize(THD *thd, const Lex_spblock_st spblock,
|
||||
class sp_label **splabel);
|
||||
public:
|
||||
inline bool is_arena_for_set_stmt() {return arena_for_set_stmt != 0;}
|
||||
bool set_arena_for_set_stmt(Query_arena *backup);
|
||||
|
@ -3084,6 +3086,20 @@ public:
|
|||
const char *start_in_q,
|
||||
const char *end_in_q);
|
||||
|
||||
void sp_block_init(THD *thd, const LEX_STRING label);
|
||||
void sp_block_init(THD *thd)
|
||||
{
|
||||
// Unlabeled blocks get an empty label
|
||||
sp_block_init(thd, empty_lex_str);
|
||||
}
|
||||
public:
|
||||
bool sp_block_finalize(THD *thd, const Lex_spblock_st spblock)
|
||||
{
|
||||
class sp_label *tmp;
|
||||
return sp_block_finalize(thd, spblock, &tmp);
|
||||
}
|
||||
bool sp_block_finalize(THD *thd, const Lex_spblock_st spblock,
|
||||
const LEX_STRING end_label);
|
||||
// Check if "KEY IF NOT EXISTS name" used outside of ALTER context
|
||||
bool check_add_key(DDL_options_st ddl)
|
||||
{
|
||||
|
|
|
@ -859,7 +859,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
|
|||
LEX_SYMBOL symbol;
|
||||
Lex_string_with_metadata_st lex_string_with_metadata;
|
||||
struct sys_var_with_base variable;
|
||||
struct { int vars, conds, hndlrs, curs; } spblock;
|
||||
Lex_spblock_st spblock;
|
||||
Lex_length_and_dec_st Lex_length_and_dec;
|
||||
Lex_cast_type_st Lex_cast_type;
|
||||
Lex_field_type_st Lex_field_type;
|
||||
|
@ -894,7 +894,6 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
|
|||
class my_var *myvar;
|
||||
class sp_condition_value *spcondvalue;
|
||||
class sp_head *sphead;
|
||||
class sp_label *splabel;
|
||||
class sp_name *spname;
|
||||
class sp_variable *spvar;
|
||||
class With_clause *with_clause;
|
||||
|
@ -1672,6 +1671,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
opt_component key_cache_name
|
||||
sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
|
||||
opt_constraint constraint opt_ident
|
||||
sp_block_label
|
||||
|
||||
%type <lex_string_with_metadata>
|
||||
TEXT_STRING
|
||||
|
@ -1952,7 +1952,6 @@ END_OF_INPUT
|
|||
%type <spblock> sp_decls sp_decl sp_decl_body
|
||||
%type <lex> sp_cursor_stmt
|
||||
%type <spname> sp_name
|
||||
%type <splabel> sp_block_content
|
||||
%type <spvar> sp_param_name sp_param_name_and_type
|
||||
%type <spvar_mode> sp_opt_inout
|
||||
%type <index_hint> index_hint_type
|
||||
|
@ -3987,34 +3986,43 @@ sp_opt_label:
|
|||
| label_ident { $$= $1; }
|
||||
;
|
||||
|
||||
sp_labeled_block:
|
||||
label_ident ':' BEGIN_SYM
|
||||
sp_block_label:
|
||||
label_ident ':'
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_label *lab= ctx->find_label($1);
|
||||
|
||||
if (lab)
|
||||
my_yyabort_error((ER_SP_LABEL_REDEFINE, MYF(0), $1.str));
|
||||
lex->name= $1;
|
||||
if (Lex->spcont->block_label_declare($1))
|
||||
MYSQL_YYABORT;
|
||||
$$= $1;
|
||||
}
|
||||
sp_block_content sp_opt_label
|
||||
;
|
||||
|
||||
sp_labeled_block:
|
||||
sp_block_label
|
||||
BEGIN_SYM
|
||||
{
|
||||
if ($6.str)
|
||||
{
|
||||
if (my_strcasecmp(system_charset_info, $6.str, $5->name.str) != 0)
|
||||
my_yyabort_error((ER_SP_LABEL_MISMATCH, MYF(0), $6.str));
|
||||
}
|
||||
Lex->sp_block_init(thd, $1);
|
||||
}
|
||||
sp_decls
|
||||
sp_proc_stmts
|
||||
END
|
||||
sp_opt_label
|
||||
{
|
||||
if (Lex->sp_block_finalize(thd, $4, $7))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
sp_unlabeled_block:
|
||||
BEGIN_SYM
|
||||
{
|
||||
Lex->name= empty_lex_str; // Unlabeled blocks get an empty label
|
||||
Lex->sp_block_init(thd);
|
||||
}
|
||||
sp_decls
|
||||
sp_proc_stmts
|
||||
END
|
||||
{
|
||||
if (Lex->sp_block_finalize(thd, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
sp_block_content
|
||||
{ }
|
||||
;
|
||||
|
||||
sp_unlabeled_block_not_atomic:
|
||||
|
@ -4022,49 +4030,14 @@ sp_unlabeled_block_not_atomic:
|
|||
{
|
||||
if (maybe_start_compound_statement(thd))
|
||||
MYSQL_YYABORT;
|
||||
Lex->name= empty_lex_str; // Unlabeled blocks get an empty label
|
||||
}
|
||||
sp_block_content
|
||||
{ }
|
||||
;
|
||||
|
||||
sp_block_content:
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_label *lab= lex->spcont->push_label(thd, lex->name,
|
||||
lex->sphead->instructions());
|
||||
lab->type= sp_label::BEGIN;
|
||||
lex->spcont= lex->spcont->push_context(thd,
|
||||
sp_pcontext::REGULAR_SCOPE);
|
||||
Lex->sp_block_init(thd);
|
||||
}
|
||||
sp_decls
|
||||
sp_proc_stmts
|
||||
END
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_instr *i;
|
||||
|
||||
sp->backpatch(ctx->last_label()); /* We always have a label */
|
||||
if ($2.hndlrs)
|
||||
{
|
||||
i= new (thd->mem_root)
|
||||
sp_instr_hpop(sp->instructions(), ctx, $2.hndlrs);
|
||||
if (i == NULL ||
|
||||
sp->add_instr(i))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
if ($2.curs)
|
||||
{
|
||||
i= new (thd->mem_root)
|
||||
sp_instr_cpop(sp->instructions(), ctx, $2.curs);
|
||||
if (i == NULL ||
|
||||
sp->add_instr(i))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
lex->spcont= ctx->pop_context();
|
||||
$$ = lex->spcont->pop_label();
|
||||
if (Lex->sp_block_finalize(thd, $5))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -234,7 +234,7 @@ static bool push_sp_empty_label(THD *thd)
|
|||
LEX_SYMBOL symbol;
|
||||
Lex_string_with_metadata_st lex_string_with_metadata;
|
||||
struct sys_var_with_base variable;
|
||||
struct { int vars, conds, hndlrs, curs; } spblock;
|
||||
Lex_spblock_st spblock;
|
||||
Lex_length_and_dec_st Lex_length_and_dec;
|
||||
Lex_cast_type_st Lex_cast_type;
|
||||
Lex_field_type_st Lex_field_type;
|
||||
|
@ -269,7 +269,6 @@ static bool push_sp_empty_label(THD *thd)
|
|||
class my_var *myvar;
|
||||
class sp_condition_value *spcondvalue;
|
||||
class sp_head *sphead;
|
||||
class sp_label *splabel;
|
||||
class sp_name *spname;
|
||||
class sp_variable *spvar;
|
||||
class With_clause *with_clause;
|
||||
|
@ -1048,6 +1047,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
|
||||
opt_constraint constraint opt_ident
|
||||
label_declaration_oracle ident_directly_assignable
|
||||
sp_block_label
|
||||
|
||||
%type <lex_string_with_metadata>
|
||||
TEXT_STRING
|
||||
|
@ -1332,7 +1332,6 @@ END_OF_INPUT
|
|||
%type <spblock> sp_decls sp_decl sp_decl_body
|
||||
%type <lex> sp_cursor_stmt
|
||||
%type <spname> sp_name
|
||||
%type <splabel> sp_block_content
|
||||
%type <spvar> sp_param_name sp_param_name_and_type
|
||||
%type <spvar_mode> sp_opt_inout
|
||||
%type <index_hint> index_hint_type
|
||||
|
@ -3373,34 +3372,43 @@ sp_opt_label:
|
|||
| label_ident { $$= $1; }
|
||||
;
|
||||
|
||||
sp_labeled_block:
|
||||
label_declaration_oracle BEGIN_SYM
|
||||
sp_block_label:
|
||||
label_declaration_oracle
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_label *lab= ctx->find_label($1);
|
||||
|
||||
if (lab)
|
||||
my_yyabort_error((ER_SP_LABEL_REDEFINE, MYF(0), $1.str));
|
||||
lex->name= $1;
|
||||
if (Lex->spcont->block_label_declare($1))
|
||||
MYSQL_YYABORT;
|
||||
$$= $1;
|
||||
}
|
||||
sp_block_content sp_opt_label
|
||||
;
|
||||
|
||||
sp_labeled_block:
|
||||
sp_block_label
|
||||
BEGIN_SYM
|
||||
{
|
||||
if ($5.str)
|
||||
{
|
||||
if (my_strcasecmp(system_charset_info, $5.str, $4->name.str) != 0)
|
||||
my_yyabort_error((ER_SP_LABEL_MISMATCH, MYF(0), $5.str));
|
||||
}
|
||||
Lex->sp_block_init(thd, $1);
|
||||
}
|
||||
sp_decls
|
||||
sp_proc_stmts
|
||||
END
|
||||
sp_opt_label
|
||||
{
|
||||
if (Lex->sp_block_finalize(thd, $4, $7))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
sp_unlabeled_block:
|
||||
BEGIN_SYM
|
||||
{
|
||||
Lex->name= empty_lex_str; // Unlabeled blocks get an empty label
|
||||
Lex->sp_block_init(thd);
|
||||
}
|
||||
sp_decls
|
||||
sp_proc_stmts
|
||||
END
|
||||
{
|
||||
if (Lex->sp_block_finalize(thd, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
sp_block_content
|
||||
{ }
|
||||
;
|
||||
|
||||
sp_unlabeled_block_not_atomic:
|
||||
|
@ -3408,49 +3416,14 @@ sp_unlabeled_block_not_atomic:
|
|||
{
|
||||
if (maybe_start_compound_statement(thd))
|
||||
MYSQL_YYABORT;
|
||||
Lex->name= empty_lex_str; // Unlabeled blocks get an empty label
|
||||
}
|
||||
sp_block_content
|
||||
{ }
|
||||
;
|
||||
|
||||
sp_block_content:
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_label *lab= lex->spcont->push_label(thd, lex->name,
|
||||
lex->sphead->instructions());
|
||||
lab->type= sp_label::BEGIN;
|
||||
lex->spcont= lex->spcont->push_context(thd,
|
||||
sp_pcontext::REGULAR_SCOPE);
|
||||
Lex->sp_block_init(thd);
|
||||
}
|
||||
sp_decls
|
||||
sp_proc_stmts
|
||||
END
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_instr *i;
|
||||
|
||||
sp->backpatch(ctx->last_label()); /* We always have a label */
|
||||
if ($2.hndlrs)
|
||||
{
|
||||
i= new (thd->mem_root)
|
||||
sp_instr_hpop(sp->instructions(), ctx, $2.hndlrs);
|
||||
if (i == NULL ||
|
||||
sp->add_instr(i))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
if ($2.curs)
|
||||
{
|
||||
i= new (thd->mem_root)
|
||||
sp_instr_cpop(sp->instructions(), ctx, $2.curs);
|
||||
if (i == NULL ||
|
||||
sp->add_instr(i))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
lex->spcont= ctx->pop_context();
|
||||
$$ = lex->spcont->pop_label();
|
||||
if (Lex->sp_block_finalize(thd, $5))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -628,5 +628,14 @@ public:
|
|||
int dyncol_type() const { return m_type; }
|
||||
};
|
||||
|
||||
struct Lex_spblock_st
|
||||
{
|
||||
public:
|
||||
int vars;
|
||||
int conds;
|
||||
int hndlrs;
|
||||
int curs;
|
||||
};
|
||||
|
||||
|
||||
#endif /* STRUCTS_INCLUDED */
|
||||
|
|
Loading…
Add table
Reference in a new issue