summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/sp.result16
-rw-r--r--mysql-test/t/sp.test22
-rw-r--r--sql/protocol_cursor.cc3
-rw-r--r--sql/sp_rcontext.cc27
4 files changed, 55 insertions, 13 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 6d743bf5c71..f84b224b8e0 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -1833,6 +1833,22 @@ NULL
Warnings:
Warning 1311 Referring to uninitialized variable v
drop function bug4487|
+drop procedure if exists bug4941|
+create procedure bug4941(out x int)
+begin
+declare c cursor for select i from t2 limit 1;
+open c;
+fetch c into x;
+close c;
+end|
+insert into t2 values (null, null, null)|
+set @x = 42|
+call bug4941(@x)|
+select @x|
+@x
+NULL
+delete from t1|
+drop procedure bug4941|
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 1d7efab3841..e2c82c9f0da 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -2001,6 +2001,28 @@ drop function bug4487|
#
+# BUG#4941: Stored procedure crash fetching null value into variable.
+#
+--disable_warnings
+drop procedure if exists bug4941|
+--enable_warnings
+create procedure bug4941(out x int)
+begin
+ declare c cursor for select i from t2 limit 1;
+ open c;
+ fetch c into x;
+ close c;
+end|
+
+insert into t2 values (null, null, null)|
+set @x = 42|
+call bug4941(@x)|
+select @x|
+delete from t1|
+drop procedure bug4941|
+
+
+#
# Some "real" examples
#
diff --git a/sql/protocol_cursor.cc b/sql/protocol_cursor.cc
index 31eaa894045..8904aba7b88 100644
--- a/sql/protocol_cursor.cc
+++ b/sql/protocol_cursor.cc
@@ -112,7 +112,8 @@ bool Protocol_cursor::write()
for (; cur_field < fields_end; ++cur_field, ++data_tmp)
{
- if ((len= net_field_length((uchar **)&cp)) == 0)
+ if ((len= net_field_length((uchar **)&cp)) == 0 ||
+ len == NULL_LENGTH)
{
*data_tmp= 0;
}
diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
index 1bdd022470b..2f7bdbffa2b 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -230,21 +230,24 @@ sp_cursor::fetch(THD *thd, List<struct sp_pvar> *vars)
return -1;
}
s= row[fldcount];
- switch (sp_map_result_type(pv->type))
- {
- case INT_RESULT:
- it= new Item_int(s);
- break;
- case REAL_RESULT:
- it= new Item_real(s, strlen(s));
- break;
- default:
+ if (!s)
+ it= new Item_null();
+ else
+ switch (sp_map_result_type(pv->type))
{
- uint len= strlen(s);
- it= new Item_string(thd->strmake(s, len), len, thd->db_charset);
+ case INT_RESULT:
+ it= new Item_int(s);
break;
+ case REAL_RESULT:
+ it= new Item_real(s, strlen(s));
+ break;
+ default:
+ {
+ uint len= strlen(s);
+ it= new Item_string(thd->strmake(s, len), len, thd->db_charset);
+ break;
+ }
}
- }
thd->spcont->set_item(pv->offset, it);
}
if (fldcount < m_prot->get_field_count())