diff options
-rw-r--r-- | mysql-test/r/sp.result | 23 | ||||
-rw-r--r-- | mysql-test/t/sp.test | 27 | ||||
-rw-r--r-- | sql/sp_pcontext.cc | 1 | ||||
-rw-r--r-- | sql/sp_pcontext.h | 10 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 17 |
5 files changed, 75 insertions, 3 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 8c72186e618..fb563e60ac2 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -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) diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 9e31bdb5f14..58bfc8b7120 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -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 diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index b7e23c9f5ad..03333a2da72 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -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); } } diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 02134e3604f..a82cefa2e42 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -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); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4060554706d..79ede4dbfa7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -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; } |