diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index de21cc39444..e8bc7b85e98 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6,9 +6,9 @@ id char(16) not null, data int not null ); create table t2 ( -s char(16) not null, -i int not null, -d double not null +s char(16), +i int, +d double ); create procedure foo42() insert into test.t1 values ("foo", 42); @@ -777,6 +777,30 @@ a 2 drop table t3; drop procedure bug1862; +create procedure bug1874() +begin +declare x int; +declare y double; +select max(data) into x from t1; +insert into t2 values ("max", x, 0); +select min(data) into x from t1; +insert into t2 values ("min", x, 0); +select sum(data) into x from t1; +insert into t2 values ("sum", x, 0); +select avg(data) into y from t1; +insert into t2 values ("avg", 0, y); +end; +insert into t1 (data) values (3), (1), (5), (9), (4); +call bug1874(); +select * from t2; +s i d +max 9 0 +min 1 0 +sum 22 0 +avg 0 4.4 +delete from t1; +delete from t2; +drop procedure bug1874; 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 201104f36f8..d8530b5130b 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -15,9 +15,9 @@ create table t1 ( data int not null ); create table t2 ( - s char(16) not null, - i int not null, - d double not null + s char(16), + i int, + d double ); @@ -921,6 +921,31 @@ drop table t3| drop procedure bug1862| +# +# BUG#1874 +# +create procedure bug1874() +begin + declare x int; + declare y double; + select max(data) into x from t1; + insert into t2 values ("max", x, 0); + select min(data) into x from t1; + insert into t2 values ("min", x, 0); + select sum(data) into x from t1; + insert into t2 values ("sum", x, 0); + select avg(data) into y from t1; + insert into t2 values ("avg", 0, y); +end| + +insert into t1 (data) values (3), (1), (5), (9), (4)| +call bug1874()| +select * from t2| +delete from t1| +delete from t2| +drop procedure bug1874| + + # # Some "real" examples # diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 342c1ebd6b5..41db1f6dd70 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -54,26 +54,40 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) it= it->this_item(); DBUG_PRINT("info", ("type: %d", type)); - if (it->fix_fields(thd, 0, &it)) + if (!it->fixed && it->fix_fields(thd, 0, &it)) { DBUG_PRINT("info", ("fix_fields() failed")); DBUG_RETURN(it); // Shouldn't happen? } /* QQ How do we do this? Is there some better way? */ - if (type == MYSQL_TYPE_NULL || it->is_null()) + if (type == MYSQL_TYPE_NULL) it= new Item_null(); else { switch (sp_map_result_type(type)) { case INT_RESULT: - DBUG_PRINT("info", ("INT_RESULT: %d", it->val_int())); - it= new Item_int(it->val_int()); - break; + { + longlong i= it->val_int(); + + DBUG_PRINT("info", ("INT_RESULT: %d", i)); + if (it->null_value) + it= new Item_null(); + else + it= new Item_int(it->val_int()); + break; + } case REAL_RESULT: - DBUG_PRINT("info", ("REAL_RESULT: %g", it->val())); - it= new Item_real(it->val()); - break; + { + double d= it->val(); + + DBUG_PRINT("info", ("REAL_RESULT: %g", d)); + if (it->null_value) + it= new Item_null(); + else + it= new Item_real(it->val()); + break; + } default: { char buffer[MAX_FIELD_WIDTH]; @@ -81,8 +95,11 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) String *s= it->val_str(&tmp); DBUG_PRINT("info",("default result: %*s",s->length(),s->c_ptr_quick())); - it= new Item_string(thd->strmake(s->c_ptr_quick(), s->length()), - s->length(), it->collation.collation); + if (it->null_value) + it= new Item_null(); + else + it= new Item_string(thd->strmake(s->c_ptr_quick(), s->length()), + s->length(), it->collation.collation); break; } }