mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Fix bug #12922 if(sum(),...) with group from view returns wrong results
Fields of view represented by Item_direct_view_ref. When complex expression such as if(sum()>...,...) is splited in simpler parts by refs was ignored. Beside this direct ref doesn't use it's result_field and thus can't store it's result in tmp table which is needed for sum() ... group. All this results in reported bug. Item::split_sum_func2() now converts Item_direct_view_ref to Item_ref to make fields from view being storable in tmp table. sql/item.h: Fix bug #12922 if(sum(),...) with group from view returns wrong results Added function ref_type() to distinguish Item_ref subclasses sql/item.cc: Fix bug #12922 if(sum(),...) with group from view returns wrong results Item::split_sum_func2() now converts Item_direct_view_ref to Item_ref to make fields from view being storable in tmp table. mysql-test/t/view.test: Test case for bug#12922 if(sum(),...) with group from view returns wrong results mysql-test/r/view.result: Test case for bug#12922 if(sum(),...) with group from view returns wrong results
This commit is contained in:
@ -2151,3 +2151,12 @@ select * from v1;
|
||||
strcmp(f1,'a')
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
create table t1 (f1 int, f2 int,f3 int);
|
||||
insert into t1 values (1,10,20),(2,0,0);
|
||||
create view v1 as select * from t1;
|
||||
select if(sum(f1)>1,f2,f3) from v1 group by f1;
|
||||
if(sum(f1)>1,f2,f3)
|
||||
20
|
||||
0
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
|
@ -2018,3 +2018,13 @@ create view v1 as select strcmp(f1,'a') from t1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #12922 if(sum(),...) with group from view returns wrong results
|
||||
#
|
||||
create table t1 (f1 int, f2 int,f3 int);
|
||||
insert into t1 values (1,10,20),(2,0,0);
|
||||
create view v1 as select * from t1;
|
||||
select if(sum(f1)>1,f2,f3) from v1 group by f1;
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
|
16
sql/item.cc
16
sql/item.cc
@ -1022,9 +1022,9 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
|
||||
/* Will split complicated items and ignore simple ones */
|
||||
split_sum_func(thd, ref_pointer_array, fields);
|
||||
}
|
||||
else if ((type() == SUM_FUNC_ITEM ||
|
||||
(used_tables() & ~PARAM_TABLE_BIT)) &&
|
||||
type() != REF_ITEM)
|
||||
else if ((type() == SUM_FUNC_ITEM || (used_tables() & ~PARAM_TABLE_BIT)) &&
|
||||
(type() != REF_ITEM ||
|
||||
((Item_ref*)this)->ref_type() == Item_ref::VIEW_REF))
|
||||
{
|
||||
/*
|
||||
Replace item with a reference so that we can easily calculate
|
||||
@ -1033,15 +1033,17 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
|
||||
The test above is to ensure we don't do a reference for things
|
||||
that are constants (PARAM_TABLE_BIT is in effect a constant)
|
||||
or already referenced (for example an item in HAVING)
|
||||
Exception is Item_direct_view_ref which we need to convert to
|
||||
Item_ref to allow fields from view being stored in tmp table.
|
||||
*/
|
||||
uint el= fields.elements;
|
||||
Item *new_item;
|
||||
ref_pointer_array[el]= this;
|
||||
Item *new_item, *real_item= real_item();
|
||||
|
||||
ref_pointer_array[el]= real_item;
|
||||
if (!(new_item= new Item_ref(&thd->lex->current_select->context,
|
||||
ref_pointer_array + el, 0, name)))
|
||||
return; // fatal_error is set
|
||||
fields.push_front(this);
|
||||
ref_pointer_array[el]= this;
|
||||
fields.push_front(real_item);
|
||||
thd->change_item_tree(ref, new_item);
|
||||
}
|
||||
}
|
||||
|
@ -1537,6 +1537,7 @@ class Item_ref :public Item_ident
|
||||
protected:
|
||||
void set_properties();
|
||||
public:
|
||||
enum Ref_Type { REF, DIRECT_REF, VIEW_REF };
|
||||
Field *result_field; /* Save result here */
|
||||
Item **ref;
|
||||
Item_ref(Name_resolution_context *context_arg,
|
||||
@ -1617,6 +1618,7 @@ public:
|
||||
void cleanup();
|
||||
Item_field *filed_for_view_update()
|
||||
{ return (*ref)->filed_for_view_update(); }
|
||||
virtual Ref_Type ref_type() { return REF; }
|
||||
};
|
||||
|
||||
|
||||
@ -1641,6 +1643,7 @@ public:
|
||||
bool val_bool();
|
||||
bool is_null();
|
||||
bool get_date(TIME *ltime,uint fuzzydate);
|
||||
virtual Ref_Type ref_type() { return DIRECT_REF; }
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1660,6 +1663,7 @@ public:
|
||||
|
||||
bool fix_fields(THD *, Item **);
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
virtual Ref_Type ref_type() { return VIEW_REF; }
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user