summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2016-08-09 12:08:11 +0400
committerAlexander Barkov <bar@mariadb.org>2017-04-05 15:02:39 +0400
commit36b80caed12cd629c7b067eb9e3273832fe6a4d0 (patch)
tree53710060e4ed8fb8e585326326fb5e3f9bed9db2
parent0281757e824bfac4d68b24400d2cc74ced1093ca (diff)
downloadmariadb-git-36b80caed12cd629c7b067eb9e3273832fe6a4d0.tar.gz
Moving the code from *.yy to new methods to LEX and sp_context
Adding: LEX::sp_variable_declarations_init() LEX::sp_variable_declarations_finalize() LEX::sp_handler_declaration_init() LEX::sp_handler_declaration_finalize() LEX::sp_declare_cursor() sp_context::declare_condition()
-rw-r--r--sql/sp_pcontext.cc6
-rw-r--r--sql/sp_pcontext.h22
-rw-r--r--sql/sql_lex.cc123
-rw-r--r--sql/sql_lex.h8
-rw-r--r--sql/sql_yacc.yy151
-rw-r--r--sql/sql_yacc_ora.yy151
6 files changed, 185 insertions, 276 deletions
diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc
index 9a6353c9337..a2258e8db34 100644
--- a/sql/sp_pcontext.cc
+++ b/sql/sp_pcontext.cc
@@ -249,7 +249,7 @@ bool sp_pcontext::add_condition(THD *thd,
}
-sp_condition_value *sp_pcontext::find_condition(LEX_STRING name,
+sp_condition_value *sp_pcontext::find_condition(const LEX_STRING name,
bool current_scope_only) const
{
uint i= m_conditions.elements();
@@ -415,7 +415,7 @@ sp_pcontext::find_handler(const char *sql_state,
}
-bool sp_pcontext::add_cursor(LEX_STRING name)
+bool sp_pcontext::add_cursor(const LEX_STRING name)
{
if (m_cursors.elements() == m_max_cursor_index)
++m_max_cursor_index;
@@ -424,7 +424,7 @@ bool sp_pcontext::add_cursor(LEX_STRING name)
}
-bool sp_pcontext::find_cursor(LEX_STRING name,
+bool sp_pcontext::find_cursor(const LEX_STRING name,
uint *poff,
bool current_scope_only) const
{
diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h
index 2a080536b8a..1ef99219e8e 100644
--- a/sql/sp_pcontext.h
+++ b/sql/sp_pcontext.h
@@ -192,7 +192,7 @@ public:
sp_condition_value *value;
public:
- sp_condition(LEX_STRING _name, sp_condition_value *_value)
+ sp_condition(const LEX_STRING _name, sp_condition_value *_value)
:Sql_alloc(),
name(_name),
value(_value)
@@ -422,11 +422,22 @@ public:
// Conditions.
/////////////////////////////////////////////////////////////////////////
- bool add_condition(THD *thd, LEX_STRING name, sp_condition_value *value);
+ bool add_condition(THD *thd, const LEX_STRING name,
+ sp_condition_value *value);
/// See comment for find_variable() above.
- sp_condition_value *find_condition(LEX_STRING name,
+ sp_condition_value *find_condition(const LEX_STRING name,
bool current_scope_only) const;
+ bool declare_condition(THD *thd, const LEX_STRING name,
+ sp_condition_value *val)
+ {
+ if (find_condition(name, true))
+ {
+ my_error(ER_SP_DUP_COND, MYF(0), name.str);
+ return true;
+ }
+ return add_condition(thd, name, val);
+ }
/////////////////////////////////////////////////////////////////////////
// Handlers.
@@ -467,10 +478,11 @@ public:
// Cursors.
/////////////////////////////////////////////////////////////////////////
- bool add_cursor(LEX_STRING name);
+ bool add_cursor(const LEX_STRING name);
/// See comment for find_variable() above.
- bool find_cursor(LEX_STRING name, uint *poff, bool current_scope_only) const;
+ bool find_cursor(const LEX_STRING name,
+ uint *poff, bool current_scope_only) const;
/// Find cursor by offset (for debugging only).
const LEX_STRING *find_cursor(uint offset) const;
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 4be04cbde8d..bed046659a2 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -5185,6 +5185,129 @@ bool LEX::init_default_internal_variable(struct sys_var_with_base *variable,
return false;
}
+void LEX::sp_variable_declarations_init(THD *thd, int nvars)
+{
+ // get the last variable:
+ uint num_vars= spcont->context_var_count();
+ uint var_idx= spcont->var_context2runtime(num_vars - 1);
+ sp_variable *spvar= spcont->find_variable(var_idx);
+
+ sphead->reset_lex(thd);
+ spcont->declare_var_boundary(nvars);
+ thd->lex->init_last_field(&spvar->field_def, spvar->name.str,
+ thd->variables.collation_database);
+}
+
+bool LEX::sp_variable_declarations_finalize(THD *thd, int nvars,
+ const Lex_field_type_st &type,
+ Item *dflt_value_item)
+{
+ uint num_vars= spcont->context_var_count();
+
+ if (!dflt_value_item &&
+ !(dflt_value_item= new (thd->mem_root) Item_null(thd)))
+ return true;
+ /* QQ Set to the var_type with null_value? */
+
+ for (uint i= num_vars - nvars ; i < num_vars ; i++)
+ {
+ uint var_idx= spcont->var_context2runtime(i);
+ sp_variable *spvar= spcont->find_variable(var_idx);
+ bool last= i == num_vars - 1;
+
+ if (!spvar)
+ return true;
+
+ if (!last)
+ spvar->field_def= *last_field;
+
+ spvar->default_value= dflt_value_item;
+ spvar->field_def.field_name= spvar->name.str;
+
+ if (sphead->fill_field_definition(thd, &spvar->field_def))
+ return true;
+
+ spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
+
+ /* The last instruction is responsible for freeing LEX. */
+ sp_instr_set *is= new (this->thd->mem_root)
+ sp_instr_set(sphead->instructions(),
+ spcont, var_idx, dflt_value_item,
+ type.field_type(), this, last);
+ if (is == NULL || sphead->add_instr(is))
+ return true;
+ }
+
+ spcont->declare_var_boundary(0);
+ return sphead->restore_lex(thd);
+}
+
+
+bool LEX::sp_declare_cursor(THD *thd, const LEX_STRING name, LEX *cursor_stmt)
+{
+ uint offp;
+ sp_instr_cpush *i;
+
+ if (spcont->find_cursor(name, &offp, true))
+ {
+ my_error(ER_SP_DUP_CURS, MYF(0), name.str);
+ return true;
+ }
+ i= new (thd->mem_root)
+ sp_instr_cpush(sphead->instructions(), spcont, cursor_stmt,
+ spcont->current_cursor_count());
+ return i == NULL || sphead->add_instr(i) || spcont->add_cursor(name);
+}
+
+
+bool LEX::sp_handler_declaration_init(THD *thd, int type)
+{
+ sp_handler *h= spcont->add_handler(thd, (sp_handler::enum_type) type);
+
+ spcont= spcont->push_context(thd, sp_pcontext::HANDLER_SCOPE);
+
+ sp_instr_hpush_jump *i=
+ new (thd->mem_root) sp_instr_hpush_jump(sphead->instructions(), spcont, h);
+
+ if (i == NULL || sphead->add_instr(i))
+ return true;
+
+ /* For continue handlers, mark end of handler scope. */
+ if (type == sp_handler::CONTINUE &&
+ sphead->push_backpatch(thd, i, spcont->last_label()))
+ return true;
+
+ if (sphead->push_backpatch(thd, i, spcont->push_label(thd, empty_lex_str, 0)))
+ return true;
+
+ return false;
+}
+
+
+bool LEX::sp_handler_declaration_finalize(THD *thd, int type)
+{
+ sp_label *hlab= spcont->pop_label(); /* After this hdlr */
+ sp_instr_hreturn *i;
+
+ if (type == sp_handler::CONTINUE)
+ {
+ i= new (thd->mem_root) sp_instr_hreturn(sphead->instructions(), spcont);
+ if (i == NULL ||
+ sphead->add_instr(i))
+ return true;
+ }
+ else
+ { /* EXIT or UNDO handler, just jump to the end of the block */
+ i= new (thd->mem_root) sp_instr_hreturn(sphead->instructions(), spcont);
+ if (i == NULL ||
+ sphead->add_instr(i) ||
+ sphead->push_backpatch(thd, i, spcont->last_label())) /* Block end */
+ return true;
+ }
+ sphead->backpatch(hlab);
+ spcont= spcont->pop_context();
+ return false;
+}
#ifdef MYSQL_SERVER
uint binlog_unsafe_map[256];
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index a298bf33968..fd99489881d 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -3071,6 +3071,14 @@ public:
LEX_STRING dbname, LEX_STRING name);
bool init_default_internal_variable(struct sys_var_with_base *variable,
LEX_STRING name);
+ void sp_variable_declarations_init(THD *thd, int nvars);
+ bool sp_variable_declarations_finalize(THD *thd, int nvars,
+ const Lex_field_type_st &type,
+ Item *def);
+ bool sp_handler_declaration_init(THD *thd, int type);
+ bool sp_handler_declaration_finalize(THD *thd, int type);
+
+ bool sp_declare_cursor(THD *thd, const LEX_STRING name, LEX *cursor_stmt);
bool set_local_variable(sp_variable *spv, Item *val);
Item_splocal *create_item_for_sp_var(LEX_STRING name, sp_variable *spvar,
const char *start_in_q,
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 4c08c0fbc43..3f56cf42409 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1949,7 +1949,7 @@ END_OF_INPUT
%type <num> sp_decl_idents sp_handler_type sp_hcond_list
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
-%type <spblock> sp_decls sp_decl
+%type <spblock> sp_decls sp_decl sp_decl_body
%type <lex> sp_cursor_stmt
%type <spname> sp_name
%type <splabel> sp_block_content
@@ -2997,161 +2997,44 @@ sp_decls:
;
sp_decl:
- DECLARE_SYM sp_decl_idents
- {
- LEX *lex= Lex;
- sp_pcontext *pctx= lex->spcont;
-
- // get the last variable:
- uint num_vars= pctx->context_var_count();
- uint var_idx= pctx->var_context2runtime(num_vars - 1);
- sp_variable *spvar= pctx->find_variable(var_idx);
+ DECLARE_SYM sp_decl_body { $$= $2; }
+ ;
- lex->sphead->reset_lex(thd);
- pctx->declare_var_boundary($2);
- thd->lex->init_last_field(&spvar->field_def, spvar->name.str,
- thd->variables.collation_database);
+sp_decl_body:
+ sp_decl_idents
+ {
+ Lex->sp_variable_declarations_init(thd, $1);
}
type_with_opt_collate
sp_opt_default
{
- LEX *lex= Lex;
- sp_pcontext *pctx= lex->spcont;
- uint num_vars= pctx->context_var_count();
- Item *dflt_value_item= $5;
-
- if (!dflt_value_item)
- {
- dflt_value_item= new (thd->mem_root) Item_null(thd);
- if (dflt_value_item == NULL)
- MYSQL_YYABORT;
- /* QQ Set to the var_type with null_value? */
- }
-
- for (uint i = num_vars-$2 ; i < num_vars ; i++)
- {
- uint var_idx= pctx->var_context2runtime(i);
- sp_variable *spvar= pctx->find_variable(var_idx);
- bool last= i == num_vars - 1;
-
- if (!spvar)
- MYSQL_YYABORT;
-
- if (!last)
- spvar->field_def= *lex->last_field;
-
- spvar->default_value= dflt_value_item;
- spvar->field_def.field_name= spvar->name.str;
-
- if (lex->sphead->fill_field_definition(thd, &spvar->field_def))
- {
- MYSQL_YYABORT;
- }
-
- spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
-
- /* The last instruction is responsible for freeing LEX. */
-
- sp_instr_set *is= new (lex->thd->mem_root)
- sp_instr_set(lex->sphead->instructions(),
- pctx, var_idx, dflt_value_item,
- $4.field_type(), lex, last);
- if (is == NULL || lex->sphead->add_instr(is))
- MYSQL_YYABORT;
- }
-
- pctx->declare_var_boundary(0);
- if (lex->sphead->restore_lex(thd))
+ if (Lex->sp_variable_declarations_finalize(thd, $1, $3, $4))
MYSQL_YYABORT;
- $$.vars= $2;
+ $$.vars= $1;
$$.conds= $$.hndlrs= $$.curs= 0;
}
- | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond
+ | ident CONDITION_SYM FOR_SYM sp_cond
{
- LEX *lex= Lex;
- sp_pcontext *spc= lex->spcont;
-
- if (spc->find_condition($2, TRUE))
- my_yyabort_error((ER_SP_DUP_COND, MYF(0), $2.str));
- if(spc->add_condition(thd, $2, $5))
+ if (Lex->spcont->declare_condition(thd, $1, $4))
MYSQL_YYABORT;
$$.vars= $$.hndlrs= $$.curs= 0;
$$.conds= 1;
}
- | DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM
+ | sp_handler_type HANDLER_SYM FOR_SYM
{
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
-
- sp_handler *h= lex->spcont->add_handler(thd,
- (sp_handler::enum_type) $2);
-
- lex->spcont= lex->spcont->push_context(thd,
- sp_pcontext::HANDLER_SCOPE);
-
- sp_pcontext *ctx= lex->spcont;
- sp_instr_hpush_jump *i=
- new (thd->mem_root) sp_instr_hpush_jump(sp->instructions(),
- ctx, h);
-
- if (i == NULL || sp->add_instr(i))
- MYSQL_YYABORT;
-
- /* For continue handlers, mark end of handler scope. */
- if ($2 == sp_handler::CONTINUE &&
- sp->push_backpatch(thd, i, ctx->last_label()))
- MYSQL_YYABORT;
-
- if (sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)))
+ if (Lex->sp_handler_declaration_init(thd, $1))
MYSQL_YYABORT;
}
sp_hcond_list sp_proc_stmt
{
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *ctx= lex->spcont;
- sp_label *hlab= lex->spcont->pop_label(); /* After this hdlr */
- sp_instr_hreturn *i;
-
- if ($2 == sp_handler::CONTINUE)
- {
- i= new (thd->mem_root)
- sp_instr_hreturn(sp->instructions(), ctx);
- if (i == NULL ||
- sp->add_instr(i))
- MYSQL_YYABORT;
- }
- else
- { /* EXIT or UNDO handler, just jump to the end of the block */
- i= new (thd->mem_root)
- sp_instr_hreturn(sp->instructions(), ctx);
- if (i == NULL ||
- sp->add_instr(i) ||
- sp->push_backpatch(thd, i, lex->spcont->last_label())) /* Block end */
- MYSQL_YYABORT;
- }
- lex->sphead->backpatch(hlab);
-
- lex->spcont= ctx->pop_context();
-
+ if (Lex->sp_handler_declaration_finalize(thd, $1))
+ MYSQL_YYABORT;
$$.vars= $$.conds= $$.curs= 0;
$$.hndlrs= 1;
}
- | DECLARE_SYM ident CURSOR_SYM FOR_SYM sp_cursor_stmt
+ | ident CURSOR_SYM FOR_SYM sp_cursor_stmt
{
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *ctx= lex->spcont;
- uint offp;
- sp_instr_cpush *i;
-
- if (ctx->find_cursor($2, &offp, TRUE))
- my_yyabort_error((ER_SP_DUP_CURS, MYF(0), $2.str));
-
- i= new (thd->mem_root)
- sp_instr_cpush(sp->instructions(), ctx, $5,
- ctx->current_cursor_count());
- if (i == NULL || sp->add_instr(i) || ctx->add_cursor($2))
+ if (Lex->sp_declare_cursor(thd, $1, $4))
MYSQL_YYABORT;
$$.vars= $$.conds= $$.hndlrs= 0;
$$.curs= 1;
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index 5fee7673b86..4f089005a2e 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -1329,7 +1329,7 @@ END_OF_INPUT
%type <num> sp_decl_idents sp_handler_type sp_hcond_list
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
-%type <spblock> sp_decls sp_decl
+%type <spblock> sp_decls sp_decl sp_decl_body
%type <lex> sp_cursor_stmt
%type <spname> sp_name
%type <splabel> sp_block_content
@@ -2383,161 +2383,44 @@ sp_decls:
;
sp_decl:
- DECLARE_SYM sp_decl_idents
- {
- LEX *lex= Lex;
- sp_pcontext *pctx= lex->spcont;
-
- // get the last variable:
- uint num_vars= pctx->context_var_count();
- uint var_idx= pctx->var_context2runtime(num_vars - 1);
- sp_variable *spvar= pctx->find_variable(var_idx);
+ DECLARE_SYM sp_decl_body { $$= $2; }
+ ;
- lex->sphead->reset_lex(thd);
- pctx->declare_var_boundary($2);
- thd->lex->init_last_field(&spvar->field_def, spvar->name.str,
- thd->variables.collation_database);
+sp_decl_body:
+ sp_decl_idents
+ {
+ Lex->sp_variable_declarations_init(thd, $1);
}
type_with_opt_collate
sp_opt_default
{
- LEX *lex= Lex;
- sp_pcontext *pctx= lex->spcont;
- uint num_vars= pctx->context_var_count();
- Item *dflt_value_item= $5;
-
- if (!dflt_value_item)
- {
- dflt_value_item= new (thd->mem_root) Item_null(thd);
- if (dflt_value_item == NULL)
- MYSQL_YYABORT;
- /* QQ Set to the var_type with null_value? */
- }
-
- for (uint i = num_vars-$2 ; i < num_vars ; i++)
- {
- uint var_idx= pctx->var_context2runtime(i);
- sp_variable *spvar= pctx->find_variable(var_idx);
- bool last= i == num_vars - 1;
-
- if (!spvar)
- MYSQL_YYABORT;
-
- if (!last)
- spvar->field_def= *lex->last_field;
-
- spvar->default_value= dflt_value_item;
- spvar->field_def.field_name= spvar->name.str;
-
- if (lex->sphead->fill_field_definition(thd, &spvar->field_def))
- {
- MYSQL_YYABORT;
- }
-
- spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
-
- /* The last instruction is responsible for freeing LEX. */
-
- sp_instr_set *is= new (lex->thd->mem_root)
- sp_instr_set(lex->sphead->instructions(),
- pctx, var_idx, dflt_value_item,
- $4.field_type(), lex, last);
- if (is == NULL || lex->sphead->add_instr(is))
- MYSQL_YYABORT;
- }
-
- pctx->declare_var_boundary(0);
- if (lex->sphead->restore_lex(thd))
+ if (Lex->sp_variable_declarations_finalize(thd, $1, $3, $4))
MYSQL_YYABORT;
- $$.vars= $2;
+ $$.vars= $1;
$$.conds= $$.hndlrs= $$.curs= 0;
}
- | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond
+ | ident CONDITION_SYM FOR_SYM sp_cond
{
- LEX *lex= Lex;
- sp_pcontext *spc= lex->spcont;
-
- if (spc->find_condition($2, TRUE))
- my_yyabort_error((ER_SP_DUP_COND, MYF(0), $2.str));
- if(spc->add_condition(thd, $2, $5))
+ if (Lex->spcont->declare_condition(thd, $1, $4))
MYSQL_YYABORT;
$$.vars= $$.hndlrs= $$.curs= 0;
$$.conds= 1;
}
- | DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM
+ | sp_handler_type HANDLER_SYM FOR_SYM
{
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
-
- sp_handler *h= lex->spcont->add_handler(thd,
- (sp_handler::enum_type) $2);
-
- lex->spcont= lex->spcont->push_context(thd,
- sp_pcontext::HANDLER_SCOPE);
-
- sp_pcontext *ctx= lex->spcont;
- sp_instr_hpush_jump *i=
- new (thd->mem_root) sp_instr_hpush_jump(sp->instructions(),
- ctx, h);
-
- if (i == NULL || sp->add_instr(i))
- MYSQL_YYABORT;
-
- /* For continue handlers, mark end of handler scope. */
- if ($2 == sp_handler::CONTINUE &&
- sp->push_backpatch(thd, i, ctx->last_label()))
- MYSQL_YYABORT;
-
- if (sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)))
+ if (Lex->sp_handler_declaration_init(thd, $1))
MYSQL_YYABORT;
}
sp_hcond_list sp_proc_stmt
{
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *ctx= lex->spcont;
- sp_label *hlab= lex->spcont->pop_label(); /* After this hdlr */
- sp_instr_hreturn *i;
-
- if ($2 == sp_handler::CONTINUE)
- {
- i= new (thd->mem_root)
- sp_instr_hreturn(sp->instructions(), ctx);
- if (i == NULL ||
- sp->add_instr(i))
- MYSQL_YYABORT;
- }
- else
- { /* EXIT or UNDO handler, just jump to the end of the block */
- i= new (thd->mem_root)
- sp_instr_hreturn(sp->instructions(), ctx);
- if (i == NULL ||
- sp->add_instr(i) ||
- sp->push_backpatch(thd, i, lex->spcont->last_label())) /* Block end */
- MYSQL_YYABORT;
- }
- lex->sphead->backpatch(hlab);
-
- lex->spcont= ctx->pop_context();
-
+ if (Lex->sp_handler_declaration_finalize(thd, $1))
+ MYSQL_YYABORT;
$$.vars= $$.conds= $$.curs= 0;
$$.hndlrs= 1;
}
- | DECLARE_SYM ident CURSOR_SYM FOR_SYM sp_cursor_stmt
+ | ident CURSOR_SYM FOR_SYM sp_cursor_stmt
{
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *ctx= lex->spcont;
- uint offp;
- sp_instr_cpush *i;
-
- if (ctx->find_cursor($2, &offp, TRUE))
- my_yyabort_error((ER_SP_DUP_CURS, MYF(0), $2.str));
-
- i= new (thd->mem_root)
- sp_instr_cpush(sp->instructions(), ctx, $5,
- ctx->current_cursor_count());
- if (i == NULL || sp->add_instr(i) || ctx->add_cursor($2))
+ if (Lex->sp_declare_cursor(thd, $1, $4))
MYSQL_YYABORT;
$$.vars= $$.conds= $$.hndlrs= 0;
$$.curs= 1;