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')
|
strcmp(f1,'a')
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1;
|
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;
|
select * from v1;
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1;
|
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 */
|
/* Will split complicated items and ignore simple ones */
|
||||||
split_sum_func(thd, ref_pointer_array, fields);
|
split_sum_func(thd, ref_pointer_array, fields);
|
||||||
}
|
}
|
||||||
else if ((type() == SUM_FUNC_ITEM ||
|
else if ((type() == SUM_FUNC_ITEM || (used_tables() & ~PARAM_TABLE_BIT)) &&
|
||||||
(used_tables() & ~PARAM_TABLE_BIT)) &&
|
(type() != REF_ITEM ||
|
||||||
type() != REF_ITEM)
|
((Item_ref*)this)->ref_type() == Item_ref::VIEW_REF))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Replace item with a reference so that we can easily calculate
|
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
|
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)
|
that are constants (PARAM_TABLE_BIT is in effect a constant)
|
||||||
or already referenced (for example an item in HAVING)
|
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;
|
uint el= fields.elements;
|
||||||
Item *new_item;
|
Item *new_item, *real_item= real_item();
|
||||||
ref_pointer_array[el]= this;
|
|
||||||
|
ref_pointer_array[el]= real_item;
|
||||||
if (!(new_item= new Item_ref(&thd->lex->current_select->context,
|
if (!(new_item= new Item_ref(&thd->lex->current_select->context,
|
||||||
ref_pointer_array + el, 0, name)))
|
ref_pointer_array + el, 0, name)))
|
||||||
return; // fatal_error is set
|
return; // fatal_error is set
|
||||||
fields.push_front(this);
|
fields.push_front(real_item);
|
||||||
ref_pointer_array[el]= this;
|
|
||||||
thd->change_item_tree(ref, new_item);
|
thd->change_item_tree(ref, new_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1537,6 +1537,7 @@ class Item_ref :public Item_ident
|
|||||||
protected:
|
protected:
|
||||||
void set_properties();
|
void set_properties();
|
||||||
public:
|
public:
|
||||||
|
enum Ref_Type { REF, DIRECT_REF, VIEW_REF };
|
||||||
Field *result_field; /* Save result here */
|
Field *result_field; /* Save result here */
|
||||||
Item **ref;
|
Item **ref;
|
||||||
Item_ref(Name_resolution_context *context_arg,
|
Item_ref(Name_resolution_context *context_arg,
|
||||||
@ -1617,6 +1618,7 @@ public:
|
|||||||
void cleanup();
|
void cleanup();
|
||||||
Item_field *filed_for_view_update()
|
Item_field *filed_for_view_update()
|
||||||
{ return (*ref)->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 val_bool();
|
||||||
bool is_null();
|
bool is_null();
|
||||||
bool get_date(TIME *ltime,uint fuzzydate);
|
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 fix_fields(THD *, Item **);
|
||||||
bool eq(const Item *item, bool binary_cmp) const;
|
bool eq(const Item *item, bool binary_cmp) const;
|
||||||
|
virtual Ref_Type ref_type() { return VIEW_REF; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user