From 792221e36579dbbec0f4335b49198a25d2a2ffd0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 7 Sep 2005 22:38:36 +0400 Subject: [PATCH] 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 --- mysql-test/r/view.result | 9 +++++++++ mysql-test/t/view.test | 10 ++++++++++ sql/item.cc | 16 +++++++++------- sql/item.h | 4 ++++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index a544fb4b020..88c635509f5 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -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; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 97625632618..0e6fddf58ae 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -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; diff --git a/sql/item.cc b/sql/item.cc index b4992faa65e..1edf0a470d3 100644 --- a/sql/item.cc +++ b/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); } } diff --git a/sql/item.h b/sql/item.h index b934e1f9f3f..f128c72413d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -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; } };