Commit 7e5247aa authored by unknown's avatar unknown
Browse files

fixed Bug #4358 Problem with HAVING clause that uses alias

       from the select list and TEXT field 

make setup_copy_fields to insert Item_copy_string for blobs in 
the beginning of the copy_funcs (push_back instead of push_front)

the thing is that Item_copy_string::copy for function can call 
Item_copy_string::val_int for blob via Item_ref.
But if Item_copy_string::copy for blob isn't called before, 
it's value will be wrong.

So all the Item_copy_string::copy for blobs should be called before 
Item_copy_string::copy for functions.


mysql-test/r/having.result:
  added test case for
  Bug #4358 Problem with HAVING clause that uses
              alias from the select list and TEXT field
mysql-test/t/having.test:
  added test case for
  Bug #4358 Problem with HAVING clause that uses
              alias from the select list and TEXT field
sql/sql_select.cc:
  make setup_copy_fields to insert Item_copy_string for blobs in 
  the beginning of the copy_funcs (push_back instead of push_front)
  
  the thing is that Item_copy_string::copy for function can call 
  Item_copy_string::val_int for blob via Item_ref.
  But if Item_copy_string::copy for blob isn't called before, 
  it's value will be wrong.
  
  So all the Item_copy_string::copy for blobs should be called before 
  Item_copy_string::copy for functions.
  
  fixed 
  Bug #4358 Problem with HAVING clause that
             uses alias from the select list and TEXT field
parent cf8a6e52
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -78,3 +78,43 @@ sqty
5
9
drop table t1;
CREATE TABLE t1 (
`id` bigint(20) NOT NULL default '0',
`description` text
) TYPE=MyISAM;
CREATE TABLE t2 (
`id` bigint(20) NOT NULL default '0',
`description` varchar(20)
) TYPE=MyISAM;
INSERT INTO t1  VALUES (1, 'test');
INSERT INTO t2 VALUES (1, 'test');
CREATE TABLE t3 (
`id`       bigint(20) NOT NULL default '0',
`order_id` bigint(20) NOT NULL default '0'
) TYPE=MyISAM;
select
a.id, a.description,
count(b.id) as c 
from t1 a left join t3 b on a.id=b.order_id 
group by a.id, a.description 
having (a.description is not null) and (c=0);
id	description	c
1	test	0
select
a.*, 
count(b.id) as c 
from t2 a left join t3 b on a.id=b.order_id 
group by a.id, a.description
having (a.description is not null) and (c=0);
id	description	c
1	test	0
INSERT INTO t1  VALUES (2, 'test2');
select
a.id, a.description,
count(b.id) as c 
from t1 a left join t3 b on a.id=b.order_id 
group by a.id, a.description 
having (a.description is not null) and (c=0);
id	description	c
1	test	0
2	test2	0
+46 −0
Original line number Diff line number Diff line
@@ -66,3 +66,49 @@ select id, sum(qty) as sqty from t1 group by id having sqty>2;
select sum(qty) as sqty from t1 group by id having count(id) > 0;
select sum(qty) as sqty from t1 group by id having count(distinct id) > 0;
drop table t1;

#
# Test case for Bug #4358 Problem with HAVING clause that uses alias from the
#              select list and TEXT field 
#

CREATE TABLE t1 (
  `id` bigint(20) NOT NULL default '0',
  `description` text
) TYPE=MyISAM;

CREATE TABLE t2 (
  `id` bigint(20) NOT NULL default '0',
  `description` varchar(20)
) TYPE=MyISAM;

INSERT INTO t1  VALUES (1, 'test');
INSERT INTO t2 VALUES (1, 'test');

CREATE TABLE t3 (
  `id`       bigint(20) NOT NULL default '0',
  `order_id` bigint(20) NOT NULL default '0'
) TYPE=MyISAM;

select
	a.id, a.description,
	count(b.id) as c 
from t1 a left join t3 b on a.id=b.order_id 
group by a.id, a.description 
having (a.description is not null) and (c=0);

select
	a.*, 
	count(b.id) as c 
from t2 a left join t3 b on a.id=b.order_id 
group by a.id, a.description
having (a.description is not null) and (c=0);

INSERT INTO t1  VALUES (2, 'test2');

select
	a.id, a.description,
	count(b.id) as c 
from t1 a left join t3 b on a.id=b.order_id 
group by a.id, a.description 
having (a.description is not null) and (c=0);
+10 −1
Original line number Diff line number Diff line
@@ -7158,7 +7158,16 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields)
	if (!(pos=new Item_copy_string(pos)))
	  goto err;
	VOID(li.replace(pos));
	if (param->copy_funcs.push_back(pos))
       /*
         Item_copy_string::copy for function can call 
         Item_copy_string::val_int for blob via Item_ref.
         But if Item_copy_string::copy for blob isn't called before,
         it's value will be wrong
         so let's insert Item_copy_string for blobs in the beginning of 
         copy_funcs
         (to see full test case look at having.test, BUG #4358) 
       */
	if (param->copy_funcs.push_front(pos))
	  goto err;
	continue;
      }