Fixed BUG#2776: Stored procedure crash if variable assigned to default.
Keep track on the default value and use it. (Or NULL, if not declared.)
This commit is contained in:
parent
eb7319e850
commit
4a6e6251e7
@ -1021,6 +1021,29 @@ select bug2772()|
|
||||
bug2772()
|
||||
a
|
||||
drop function bug2772|
|
||||
create procedure bug2776_1(out x int)
|
||||
begin
|
||||
declare v int;
|
||||
set v = default;
|
||||
set x = v;
|
||||
end|
|
||||
create procedure bug2776_2(out x int)
|
||||
begin
|
||||
declare v int default 42;
|
||||
set v = default;
|
||||
set x = v;
|
||||
end|
|
||||
set @x = 1|
|
||||
call bug2776_1(@x)|
|
||||
select @x|
|
||||
@x
|
||||
NULL
|
||||
call bug2776_2(@x)|
|
||||
select @x|
|
||||
@x
|
||||
42
|
||||
drop procedure bug2776_1|
|
||||
drop procedure bug2776_2|
|
||||
drop table if exists fac|
|
||||
create table fac (n int unsigned not null primary key, f bigint unsigned)|
|
||||
create procedure ifac(n int unsigned)
|
||||
|
@ -1188,6 +1188,33 @@ create function bug2772() returns char(10) character set latin2
|
||||
select bug2772()|
|
||||
drop function bug2772|
|
||||
|
||||
#
|
||||
# BUG#2776
|
||||
#
|
||||
create procedure bug2776_1(out x int)
|
||||
begin
|
||||
declare v int;
|
||||
|
||||
set v = default;
|
||||
set x = v;
|
||||
end|
|
||||
|
||||
create procedure bug2776_2(out x int)
|
||||
begin
|
||||
declare v int default 42;
|
||||
|
||||
set v = default;
|
||||
set x = v;
|
||||
end|
|
||||
|
||||
set @x = 1|
|
||||
call bug2776_1(@x)|
|
||||
select @x|
|
||||
call bug2776_2(@x)|
|
||||
select @x|
|
||||
drop procedure bug2776_1|
|
||||
drop procedure bug2776_2|
|
||||
|
||||
|
||||
#
|
||||
# Some "real" examples
|
||||
|
@ -118,6 +118,7 @@ sp_pcontext::push_pvar(LEX_STRING *name, enum enum_field_types type,
|
||||
p->mode= mode;
|
||||
p->offset= m_pvar.elements;
|
||||
p->isset= (mode == sp_param_out ? FALSE : TRUE);
|
||||
p->dflt= NULL;
|
||||
insert_dynamic(&m_pvar, (gptr)&p);
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ typedef struct sp_pvar
|
||||
sp_param_mode_t mode;
|
||||
uint offset; // Offset in current frame
|
||||
my_bool isset;
|
||||
Item *dflt;
|
||||
} sp_pvar_t;
|
||||
|
||||
typedef struct sp_label
|
||||
@ -130,6 +131,15 @@ class sp_pcontext : public Sql_alloc
|
||||
p->isset= val;
|
||||
}
|
||||
|
||||
inline void
|
||||
set_default(uint i, Item *it)
|
||||
{
|
||||
sp_pvar_t *p= find_pvar(i);
|
||||
|
||||
if (p)
|
||||
p->dflt= it;
|
||||
}
|
||||
|
||||
void
|
||||
push_pvar(LEX_STRING *name, enum enum_field_types type, sp_param_mode_t mode);
|
||||
|
||||
|
@ -1365,6 +1365,7 @@ sp_decl:
|
||||
|
||||
lex->sphead->add_instr(in);
|
||||
lex->spcont->set_isset(i, TRUE);
|
||||
lex->spcont->set_default(i, it);
|
||||
}
|
||||
}
|
||||
$$.vars= $2;
|
||||
@ -6246,15 +6247,25 @@ option_value:
|
||||
}
|
||||
else
|
||||
{ /* An SP local variable */
|
||||
sp_pvar_t *spv;
|
||||
sp_instr_set *i;
|
||||
Item *it;
|
||||
|
||||
if ($3 && $3->type() == Item::SUBSELECT_ITEM)
|
||||
{ /* QQ For now, just disallow subselects as values */
|
||||
send_error(lex->thd, ER_SP_SUBSELECT_NYI);
|
||||
YYABORT;
|
||||
}
|
||||
sp_pvar_t *spv= lex->spcont->find_pvar(&$1.base_name);
|
||||
sp_instr_set *i= new sp_instr_set(lex->sphead->instructions(),
|
||||
spv->offset, $3, spv->type);
|
||||
spv= lex->spcont->find_pvar(&$1.base_name);
|
||||
|
||||
if ($3)
|
||||
it= $3;
|
||||
else if (spv->dflt)
|
||||
it= spv->dflt;
|
||||
else
|
||||
it= new Item_null();
|
||||
i= new sp_instr_set(lex->sphead->instructions(),
|
||||
spv->offset, it, spv->type);
|
||||
lex->sphead->add_instr(i);
|
||||
spv->isset= TRUE;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user