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()
|
bug2772()
|
||||||
a
|
a
|
||||||
drop function bug2772|
|
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|
|
drop table if exists fac|
|
||||||
create table fac (n int unsigned not null primary key, f bigint unsigned)|
|
create table fac (n int unsigned not null primary key, f bigint unsigned)|
|
||||||
create procedure ifac(n int unsigned)
|
create procedure ifac(n int unsigned)
|
||||||
|
@ -1188,6 +1188,33 @@ create function bug2772() returns char(10) character set latin2
|
|||||||
select bug2772()|
|
select bug2772()|
|
||||||
drop function 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
|
# Some "real" examples
|
||||||
|
@ -118,6 +118,7 @@ sp_pcontext::push_pvar(LEX_STRING *name, enum enum_field_types type,
|
|||||||
p->mode= mode;
|
p->mode= mode;
|
||||||
p->offset= m_pvar.elements;
|
p->offset= m_pvar.elements;
|
||||||
p->isset= (mode == sp_param_out ? FALSE : TRUE);
|
p->isset= (mode == sp_param_out ? FALSE : TRUE);
|
||||||
|
p->dflt= NULL;
|
||||||
insert_dynamic(&m_pvar, (gptr)&p);
|
insert_dynamic(&m_pvar, (gptr)&p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ typedef struct sp_pvar
|
|||||||
sp_param_mode_t mode;
|
sp_param_mode_t mode;
|
||||||
uint offset; // Offset in current frame
|
uint offset; // Offset in current frame
|
||||||
my_bool isset;
|
my_bool isset;
|
||||||
|
Item *dflt;
|
||||||
} sp_pvar_t;
|
} sp_pvar_t;
|
||||||
|
|
||||||
typedef struct sp_label
|
typedef struct sp_label
|
||||||
@ -130,6 +131,15 @@ class sp_pcontext : public Sql_alloc
|
|||||||
p->isset= val;
|
p->isset= val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
set_default(uint i, Item *it)
|
||||||
|
{
|
||||||
|
sp_pvar_t *p= find_pvar(i);
|
||||||
|
|
||||||
|
if (p)
|
||||||
|
p->dflt= it;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
push_pvar(LEX_STRING *name, enum enum_field_types type, sp_param_mode_t mode);
|
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->sphead->add_instr(in);
|
||||||
lex->spcont->set_isset(i, TRUE);
|
lex->spcont->set_isset(i, TRUE);
|
||||||
|
lex->spcont->set_default(i, it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$$.vars= $2;
|
$$.vars= $2;
|
||||||
@ -6246,15 +6247,25 @@ option_value:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* An SP local variable */
|
{ /* An SP local variable */
|
||||||
|
sp_pvar_t *spv;
|
||||||
|
sp_instr_set *i;
|
||||||
|
Item *it;
|
||||||
|
|
||||||
if ($3 && $3->type() == Item::SUBSELECT_ITEM)
|
if ($3 && $3->type() == Item::SUBSELECT_ITEM)
|
||||||
{ /* QQ For now, just disallow subselects as values */
|
{ /* QQ For now, just disallow subselects as values */
|
||||||
send_error(lex->thd, ER_SP_SUBSELECT_NYI);
|
send_error(lex->thd, ER_SP_SUBSELECT_NYI);
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
sp_pvar_t *spv= lex->spcont->find_pvar(&$1.base_name);
|
spv= lex->spcont->find_pvar(&$1.base_name);
|
||||||
sp_instr_set *i= new sp_instr_set(lex->sphead->instructions(),
|
|
||||||
spv->offset, $3, spv->type);
|
|
||||||
|
|
||||||
|
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);
|
lex->sphead->add_instr(i);
|
||||||
spv->isset= TRUE;
|
spv->isset= TRUE;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user