summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/sp.result23
-rw-r--r--mysql-test/t/sp.test27
-rw-r--r--sql/sp_pcontext.cc1
-rw-r--r--sql/sp_pcontext.h10
-rw-r--r--sql/sql_yacc.yy17
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;
}