From 728000b22514f97cca66126c6f9e86a5ce7a0d61 Mon Sep 17 00:00:00 2001 From: "pem@mysql.comhem.se" <> Date: Fri, 10 Sep 2004 16:28:11 +0200 Subject: [PATCH] Fixed BUG#4941: Stored procedure crash fetching null value into variable. --- mysql-test/r/sp.result | 16 ++++++++++++++++ mysql-test/t/sp.test | 22 ++++++++++++++++++++++ sql/protocol_cursor.cc | 3 ++- sql/sp_rcontext.cc | 27 +++++++++++++++------------ 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 @@ -2000,6 +2000,28 @@ select bug4487()| 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()) -- 2.30.9