summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy227
1 files changed, 128 insertions, 99 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index fbcb3de7907..e5e6dfbd6c1 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1350,41 +1350,11 @@ create_function_tail:
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
- LEX_STRING cmt = { 0, 0 };
- create_field *new_field;
- uint unused1= 0;
- int unused2= 0;
-
- if (!(new_field= new_create_field(YYTHD, (char*) "",
- (enum enum_field_types)$8,
- lex->length, lex->dec, lex->type,
- (Item *)0, (Item *) 0, &cmt, 0,
- &lex->interval_list,
- (lex->charset ? lex->charset :
- default_charset_info),
- lex->uint_geom_type)))
- YYABORT;
-
- sp->m_returns_cs= new_field->charset;
-
- if (new_field->interval_list.elements)
- {
- new_field->interval=
- sp->create_typelib(&new_field->interval_list);
- }
- sp_prepare_create_field(YYTHD, new_field);
-
- if (prepare_create_field(new_field, &unused1, &unused2, &unused2,
- HA_CAN_GEOMETRY))
- YYABORT;
- sp->m_returns= new_field->sql_type;
- sp->m_returns_cs= new_field->charset;
- sp->m_returns_len= new_field->length;
- sp->m_returns_pack= new_field->pack_flag;
- sp->m_returns_typelib= new_field->interval;
- sp->m_geom_returns= new_field->geom_type;
- new_field->interval= NULL;
+ if (sp->fill_field_definition(YYTHD, lex,
+ (enum enum_field_types) $8,
+ &sp->m_return_field_def))
+ YYABORT;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
}
@@ -1506,8 +1476,28 @@ sp_fdparams:
| sp_fdparam
;
+sp_init_param:
+ /* Empty */
+ {
+ LEX *lex= Lex;
+
+ lex->length= 0;
+ lex->dec= 0;
+ lex->type= 0;
+
+ lex->default_value= 0;
+ lex->on_update_value= 0;
+
+ lex->comment= null_lex_str;
+ lex->charset= NULL;
+
+ lex->interval_list.empty();
+ lex->uint_geom_type= 0;
+ }
+ ;
+
sp_fdparam:
- ident type
+ ident sp_init_param type
{
LEX *lex= Lex;
sp_pcontext *spc= lex->spcont;
@@ -1517,7 +1507,17 @@ sp_fdparam:
my_error(ER_SP_DUP_PARAM, MYF(0), $1.str);
YYABORT;
}
- spc->push_pvar(&$1, (enum enum_field_types)$2, sp_param_in);
+ sp_pvar_t *pvar= spc->push_pvar(&$1, (enum enum_field_types)$3,
+ sp_param_in);
+
+ if (lex->sphead->fill_field_definition(YYTHD, lex,
+ (enum enum_field_types) $3,
+ &pvar->field_def))
+ {
+ YYABORT;
+ }
+ pvar->field_def.field_name= pvar->name.str;
+ pvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
}
;
@@ -1533,18 +1533,27 @@ sp_pdparams:
;
sp_pdparam:
- sp_opt_inout ident type
+ sp_opt_inout sp_init_param ident type
{
LEX *lex= Lex;
sp_pcontext *spc= lex->spcont;
- if (spc->find_pvar(&$2, TRUE))
+ if (spc->find_pvar(&$3, TRUE))
{
- my_error(ER_SP_DUP_PARAM, MYF(0), $2.str);
+ my_error(ER_SP_DUP_PARAM, MYF(0), $3.str);
YYABORT;
}
- spc->push_pvar(&$2, (enum enum_field_types)$3,
- (sp_param_mode_t)$1);
+ sp_pvar_t *pvar= spc->push_pvar(&$3, (enum enum_field_types)$4,
+ (sp_param_mode_t)$1);
+
+ if (lex->sphead->fill_field_definition(YYTHD, lex,
+ (enum enum_field_types) $4,
+ &pvar->field_def))
+ {
+ YYABORT;
+ }
+ pvar->field_def.field_name= pvar->name.str;
+ pvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
}
;
@@ -1596,45 +1605,60 @@ sp_decls:
;
sp_decl:
- DECLARE_SYM sp_decl_idents type
+ DECLARE_SYM sp_decl_idents
{
LEX *lex= Lex;
lex->sphead->reset_lex(YYTHD);
lex->spcont->declare_var_boundary($2);
}
+ type
sp_opt_default
{
LEX *lex= Lex;
- sp_pcontext *ctx= lex->spcont;
- uint max= ctx->context_pvars();
- enum enum_field_types type= (enum enum_field_types)$3;
- Item *it= $5;
- bool has_default= (it != NULL);
-
- for (uint i = max-$2 ; i < max ; i++)
+ sp_pcontext *pctx= lex->spcont;
+ uint num_vars= pctx->context_pvars();
+ enum enum_field_types var_type= (enum enum_field_types) $4;
+ Item *dflt_value_item= $5;
+ create_field *create_field_op;
+
+ if (!dflt_value_item)
{
- sp_instr_set *in;
- uint off= ctx->pvar_context2index(i);
-
- ctx->set_type(off, type);
- if (! has_default)
- it= new Item_null(); /* QQ Set to the type with null_value? */
- in = new sp_instr_set(lex->sphead->instructions(),
- ctx,
- off,
- it, type, lex,
- (i == max - 1));
-
- /*
- The last instruction is assigned to be responsible for
- freeing LEX.
- */
- lex->sphead->add_instr(in);
- ctx->set_default(off, it);
+ dflt_value_item= new Item_null();
+ /* QQ Set to the var_type with null_value? */
+ }
+
+ for (uint i = num_vars-$2 ; i < num_vars ; i++)
+ {
+ uint var_idx= pctx->pvar_context2index(i);
+ sp_pvar_t *pvar= pctx->find_pvar(var_idx);
+
+ if (!pvar)
+ YYABORT;
+
+ pvar->type= var_type;
+ pvar->dflt= dflt_value_item;
+
+ if (lex->sphead->fill_field_definition(YYTHD, lex, var_type,
+ &pvar->field_def))
+ {
+ YYABORT;
+ }
+
+ pvar->field_def.field_name= pvar->name.str;
+ pvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
+
+ /* The last instruction is responsible for freeing LEX. */
+
+ lex->sphead->add_instr(
+ new sp_instr_set(lex->sphead->instructions(), pctx, var_idx,
+ dflt_value_item, var_type, lex,
+ (i == num_vars - 1)));
}
- ctx->declare_var_boundary(0);
+
+ pctx->declare_var_boundary(0);
lex->sphead->restore_lex(YYTHD);
+
$$.vars= $2;
$$.conds= $$.hndlrs= $$.curs= 0;
}
@@ -1857,6 +1881,8 @@ sp_hcond:
sp_decl_idents:
ident
{
+ /* NOTE: field definition is filled in sp_decl section. */
+
LEX *lex= Lex;
sp_pcontext *spc= lex->spcont;
@@ -1870,6 +1896,8 @@ sp_decl_idents:
}
| sp_decl_idents ',' ident
{
+ /* NOTE: field definition is filled in sp_decl section. */
+
LEX *lex= Lex;
sp_pcontext *spc= lex->spcont;
@@ -1947,8 +1975,8 @@ sp_proc_stmt:
{
sp_instr_freturn *i;
- i= new sp_instr_freturn(sp->instructions(), lex->spcont,
- $3, sp->m_returns, lex);
+ i= new sp_instr_freturn(sp->instructions(), lex->spcont, $3,
+ sp->m_return_field_def.sql_type, lex);
sp->add_instr(i);
sp->m_flags|= sp_head::HAS_RETURN;
}
@@ -1964,25 +1992,27 @@ sp_proc_stmt:
{ Lex->sphead->reset_lex(YYTHD); }
expr WHEN_SYM
{
- /* We "fake" this by using an anonymous variable which we
- set to the expression. Note that all WHENs are evaluate
- at the same frame level, so we then know that it's the
- top-most variable in the frame. */
LEX *lex= Lex;
- uint offset= lex->spcont->current_pvars();
- sp_instr_set *i = new sp_instr_set(lex->sphead->instructions(),
- lex->spcont, offset, $3,
- MYSQL_TYPE_STRING, lex, TRUE);
- LEX_STRING dummy={(char*)"", 0};
-
- lex->spcont->push_pvar(&dummy, MYSQL_TYPE_STRING, sp_param_in);
- lex->sphead->add_instr(i);
- lex->sphead->m_flags|= sp_head::IN_SIMPLE_CASE;
- lex->sphead->restore_lex(YYTHD);
+ sp_head *sp= lex->sphead;
+ sp_pcontext *parsing_ctx= lex->spcont;
+ int case_expr_id= parsing_ctx->register_case_expr();
+
+ if (parsing_ctx->push_case_expr_id(case_expr_id))
+ YYABORT;
+
+ sp->add_instr(
+ new sp_instr_set_case_expr(sp->instructions(),
+ parsing_ctx,
+ case_expr_id,
+ $3,
+ lex));
+
+ sp->m_flags|= sp_head::IN_SIMPLE_CASE;
+ sp->restore_lex(YYTHD);
}
sp_case END CASE_SYM
{
- Lex->spcont->pop_pvar();
+ Lex->spcont->pop_case_expr_id();
}
| sp_labeled_control
{}
@@ -2293,20 +2323,20 @@ sp_case:
i= new sp_instr_jump_if_not(ip, ctx, $2, lex);
else
{ /* Simple case: <caseval> = <whenval> */
- LEX_STRING ivar;
- ivar.str= (char *)"_tmp_";
- ivar.length= 5;
- Item_splocal *var= new Item_splocal(ivar,
- ctx->current_pvars()-1);
+ Item_case_expr *var;
+ Item *expr;
+
+ var= new Item_case_expr(ctx->get_current_case_expr_id());
+
#ifndef DBUG_OFF
if (var)
- var->owner= sp;
+ var->m_sp= sp;
#endif
- Item *expr= new Item_func_eq(var, $2);
+
+ expr= new Item_func_eq(var, $2);
i= new sp_instr_jump_if_not(ip, ctx, expr, lex);
- lex->variables_used= 1;
}
sp->push_backpatch(i, ctx->push_label((char *)"", 0));
sp->add_instr(i);
@@ -4406,11 +4436,9 @@ simple_expr:
{
if ($3->is_splocal())
{
- LEX_STRING *name;
Item_splocal *il= static_cast<Item_splocal *>($3);
- name= il->my_name(NULL);
- my_error(ER_WRONG_COLUMN_NAME, MYF(0), name->str);
+ my_error(ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str);
YYABORT;
}
$$= new Item_default_value(Lex->current_context(), $3);
@@ -5887,7 +5915,7 @@ select_var_ident:
var_list.push_back(var= new my_var($1,1,t->offset,t->type));
#ifndef DBUG_OFF
if (var)
- var->owner= lex->sphead;
+ var->sp= lex->sphead;
#endif
}
}
@@ -7189,11 +7217,12 @@ simple_ident:
{
/* We're compiling a stored procedure and found a variable */
Item_splocal *splocal;
- splocal= new Item_splocal($1, spv->offset, lex->tok_start_prev -
+ splocal= new Item_splocal($1, spv->offset, spv->type,
+ lex->tok_start_prev -
lex->sphead->m_tmp_query);
#ifndef DBUG_OFF
if (splocal)
- splocal->owner= lex->sphead;
+ splocal->m_sp= lex->sphead;
#endif
$$ = (Item*) splocal;
lex->variables_used= 1;