Commit 5e46a059 authored by pem@mysql.comhem.se's avatar pem@mysql.comhem.se

Fixed BUG#1874: Don't call fix_fields() indiscriminately, it resets null_value

for some items, which made aggregates like MIN(), MAX() and SUM() fail.
parent 05f25fea
...@@ -6,9 +6,9 @@ id char(16) not null, ...@@ -6,9 +6,9 @@ id char(16) not null,
data int not null data int not null
); );
create table t2 ( create table t2 (
s char(16) not null, s char(16),
i int not null, i int,
d double not null d double
); );
create procedure foo42() create procedure foo42()
insert into test.t1 values ("foo", 42); insert into test.t1 values ("foo", 42);
...@@ -777,6 +777,30 @@ a ...@@ -777,6 +777,30 @@ a
2 2
drop table t3; drop table t3;
drop procedure bug1862; 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; drop table if exists fac;
create table fac (n int unsigned not null primary key, f bigint unsigned); create table fac (n int unsigned not null primary key, f bigint unsigned);
create procedure ifac(n int unsigned) create procedure ifac(n int unsigned)
......
...@@ -15,9 +15,9 @@ create table t1 ( ...@@ -15,9 +15,9 @@ create table t1 (
data int not null data int not null
); );
create table t2 ( create table t2 (
s char(16) not null, s char(16),
i int not null, i int,
d double not null d double
); );
...@@ -921,6 +921,31 @@ drop table t3| ...@@ -921,6 +921,31 @@ drop table t3|
drop procedure bug1862| 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 # Some "real" examples
# #
......
...@@ -54,26 +54,40 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) ...@@ -54,26 +54,40 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type)
it= it->this_item(); it= it->this_item();
DBUG_PRINT("info", ("type: %d", type)); 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_PRINT("info", ("fix_fields() failed"));
DBUG_RETURN(it); // Shouldn't happen? DBUG_RETURN(it); // Shouldn't happen?
} }
/* QQ How do we do this? Is there some better way? */ /* 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(); it= new Item_null();
else else
{ {
switch (sp_map_result_type(type)) { switch (sp_map_result_type(type)) {
case INT_RESULT: case INT_RESULT:
DBUG_PRINT("info", ("INT_RESULT: %d", it->val_int())); {
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()); it= new Item_int(it->val_int());
break; break;
}
case REAL_RESULT: case REAL_RESULT:
DBUG_PRINT("info", ("REAL_RESULT: %g", it->val())); {
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()); it= new Item_real(it->val());
break; break;
}
default: default:
{ {
char buffer[MAX_FIELD_WIDTH]; char buffer[MAX_FIELD_WIDTH];
...@@ -81,6 +95,9 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) ...@@ -81,6 +95,9 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type)
String *s= it->val_str(&tmp); String *s= it->val_str(&tmp);
DBUG_PRINT("info",("default result: %*s",s->length(),s->c_ptr_quick())); DBUG_PRINT("info",("default result: %*s",s->length(),s->c_ptr_quick()));
if (it->null_value)
it= new Item_null();
else
it= new Item_string(thd->strmake(s->c_ptr_quick(), s->length()), it= new Item_string(thd->strmake(s->c_ptr_quick(), s->length()),
s->length(), it->collation.collation); s->length(), it->collation.collation);
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment