Commit 663757ea authored by unknown's avatar unknown
Browse files

Merge moonbone.local:/mnt/gentoo64/work/27321-bug-5.0-opt-mysql

into  moonbone.local:/mnt/gentoo64/work/bk-trees/mysql-5.1-opt


mysql-test/r/subselect3.result:
  Auto merged
sql/item.cc:
  Auto merged
sql/item.h:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_union.cc:
  Auto merged
mysql-test/r/subselect.result:
  Manual merge
mysql-test/t/subselect.test:
  Manual merge
parents ebb4e90c 3e8252ff
Loading
Loading
Loading
Loading
+66 −1
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3	DEPENDENT SUBQUERY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used
2	DERIVED	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used
Warnings:
Note	1276	Field or reference 'a' of SELECT #3 was resolved in SELECT #1
Note	1276	Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
Note	1276	Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
Note	1003	select 1 AS `1` from (select 1 AS `a`) `b` having ((select '1' AS `a`) = 1)
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
@@ -3924,6 +3924,71 @@ c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
3	3	4
1	4	2,2
DROP table t1,t2;
CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'),
(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'),
(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p');
SELECT a, MAX(b),
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test 
FROM t1 GROUP BY a;
a	MAX(b)	test
1	9	m
2	3	h
3	4	i
SELECT a x, MAX(b),
(SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test
FROM t1 GROUP BY a;
x	MAX(b)	test
1	9	m
2	3	h
3	4	i
SELECT a, AVG(b),
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test
FROM t1 WHERE t1.d=0 GROUP BY a;
a	AVG(b)	test
1	4.0000	d
2	2.0000	g
3	2.5000	NULL
SELECT tt.a,
(SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test 
FROM t1 as tt;
a	test
1	n
1	n
1	n
1	n
1	n
1	n
1	n
2	o
2	o
2	o
2	o
3	p
3	p
3	p
3	p
3	p
SELECT tt.a,
(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
LIMIT 1)
FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test 
FROM t1 as tt GROUP BY tt.a;
a	test
1	n
2	o
3	p
SELECT tt.a, MAX(
(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
LIMIT 1)
FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test 
FROM t1 as tt GROUP BY tt.a;
a	test
1	n
2	o
3	p
DROP TABLE t1;
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+2 −2
Original line number Diff line number Diff line
@@ -432,7 +432,7 @@ alter table t1 add index idx(oref,ie);
explain select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	7	
2	DEPENDENT SUBQUERY	t1	ref_or_null	idx	idx	10	t2.oref,func	4	Using where; Using index; Full scan on NULL key
2	DEPENDENT SUBQUERY	t1	ref_or_null	idx	idx	10	test.t2.oref,func	4	Using where; Using index; Full scan on NULL key
select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
oref	a	Z
ee	NULL	NULL
@@ -457,7 +457,7 @@ group by grp having min(ie) > 1) Z
from t2;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	7	
2	DEPENDENT SUBQUERY	t1	ref	idx	idx	5	t2.oref	2	Using where; Using temporary; Using filesort
2	DEPENDENT SUBQUERY	t1	ref	idx	idx	5	test.t2.oref	2	Using where; Using temporary; Using filesort
select oref, a, 
a in (select min(ie) from t1 where oref=t2.oref 
group by grp having min(ie) > 1) Z 
+37 −0
Original line number Diff line number Diff line
@@ -2783,6 +2783,43 @@ SELECT COUNT(*) c, a,

DROP table t1,t2;

#
# Bug#27321: Wrong subquery result in a grouping select
#
CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'),
(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'),
(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p');

SELECT a, MAX(b),
  (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test 
  FROM t1 GROUP BY a;
SELECT a x, MAX(b),
  (SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test
  FROM t1 GROUP BY a;
SELECT a, AVG(b),
  (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test
  FROM t1 WHERE t1.d=0 GROUP BY a;

SELECT tt.a,
 (SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
  LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test 
  FROM t1 as tt;

SELECT tt.a,
 (SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
  LIMIT 1)
  FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test 
  FROM t1 as tt GROUP BY tt.a;

SELECT tt.a, MAX(
 (SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
  LIMIT 1)
  FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test 
  FROM t1 as tt GROUP BY tt.a;

DROP TABLE t1;

#
# Bug #27348: SET FUNCTION used in  a subquery from WHERE condition 
#  
+0 −3
Original line number Diff line number Diff line
@@ -507,9 +507,6 @@ SELECT a, MAX(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b))
SELECT * FROM t1 GROUP by t1.a
  HAVING (MAX(t1.b) > (SELECT MAX(t2.b) FROM t2 WHERE t2.c < t1.c
                                                HAVING MAX(t2.b+t1.a) < 10));
#FIXME: Enable this test after fixing bug #27321
#SELECT a, AVG(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b))
#  AS test FROM t1 GROUP BY a;

SELECT a,b,c FROM t1 WHERE b in (9,3,4) ORDER BY b,c;

+39 −44
Original line number Diff line number Diff line
@@ -1644,7 +1644,7 @@ void Item_ident_for_show::make_field(Send_field *tmp_field)
Item_field::Item_field(Field *f)
  :Item_ident(0, NullS, *f->table_name, f->field_name),
   item_equal(0), no_const_subst(0),
   have_privileges(0), any_privileges(0), fixed_as_field(0)
   have_privileges(0), any_privileges(0)
{
  set_field(f);
  /*
@@ -1659,7 +1659,7 @@ Item_field::Item_field(THD *thd, Name_resolution_context *context_arg,
                       Field *f)
  :Item_ident(context_arg, f->table->s->db.str, *f->table_name, f->field_name),
   item_equal(0), no_const_subst(0),
   have_privileges(0), any_privileges(0), fixed_as_field(0)
   have_privileges(0), any_privileges(0)
{
  /*
    We always need to provide Item_field with a fully qualified field
@@ -1698,7 +1698,7 @@ Item_field::Item_field(Name_resolution_context *context_arg,
                       const char *field_name_arg)
  :Item_ident(context_arg, db_arg,table_name_arg,field_name_arg),
   field(0), result_field(0), item_equal(0), no_const_subst(0),
   have_privileges(0), any_privileges(0), fixed_as_field(0)
   have_privileges(0), any_privileges(0)
{
  SELECT_LEX *select= current_thd->lex->current_select;
  collation.set(DERIVATION_IMPLICIT);
@@ -1714,8 +1714,7 @@ Item_field::Item_field(THD *thd, Item_field *item)
   item_equal(item->item_equal),
   no_const_subst(item->no_const_subst),
   have_privileges(item->have_privileges),
   any_privileges(item->any_privileges),
   fixed_as_field(item->fixed_as_field)
   any_privileges(item->any_privileges)
{
  collation.set(DERIVATION_IMPLICIT);
}
@@ -3483,6 +3482,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
  Item **ref= (Item **) not_found_item;
  SELECT_LEX *current_sel= (SELECT_LEX *) thd->lex->current_select;
  Name_resolution_context *outer_context= 0;
  SELECT_LEX *select= 0;
  /* Currently derived tables cannot be correlated */
  if (current_sel->master_unit()->first_select()->linkage !=
      DERIVED_TABLE_TYPE)
@@ -3491,7 +3491,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
       outer_context;
       outer_context= outer_context->outer_context)
  {
    SELECT_LEX *select= outer_context->select_lex;
    select= outer_context->select_lex;
    Item_subselect *prev_subselect_item=
      last_checked_context->select_lex->master_unit()->item;
    last_checked_context= outer_context;
@@ -3534,45 +3534,28 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
        }
        if (*from_field != view_ref_found)
        {

          prev_subselect_item->used_tables_cache|= (*from_field)->table->map;
          prev_subselect_item->const_item_cache= 0;
          set_field(*from_field);
          if (!last_checked_context->select_lex->having_fix_field &&
              !fixed_as_field)
              select->group_list.elements)
          {
            Item_outer_ref *rf;
            Query_arena *arena= 0, backup;
            /*
              Each outer field is replaced for an Item_outer_ref object.
              This is done in order to get correct results when the outer
              select employs a temporary table.
              The original fields are saved in the inner_fields_list of the
              outer select. This list is created by the following reasons:
              1. We can't add field items to the outer select list directly
                 because the outer select hasn't been fully fixed yet.
              2. We need a location to refer to in the Item_ref object
                 so the inner_fields_list is used as such temporary
                 reference storage.
              The new Item_outer_ref object replaces the original field and is
              also saved in the inner_refs_list of the outer select. Here
              it is only created. It can be fixed only after the original
              field has been fixed and this is done in the fix_inner_refs()
              function.
            /*
              If an outer field is resolved in a grouping select then it
              is replaced for an Item_outer_ref object. Otherwise an
              Item_field object is used.
              The new Item_outer_ref object is saved in the inner_refs_list of
              the outer select. Here it is only created. It can be fixed only
              after the original field has been fixed and this is done in the
              fix_inner_refs() function.
            */
            set_field(*from_field);
            arena= thd->activate_stmt_arena_if_needed(&backup);
            rf= new Item_outer_ref(context, this);
            if (!rf)
            {
              if (arena)
                thd->restore_active_arena(arena, &backup);
            ;
            if (!(rf= new Item_outer_ref(context, this)))
              return -1;
            }
            *reference= rf;
            thd->change_item_tree(reference, rf);
            select->inner_refs_list.push_back(rf);
            if (arena)
              thd->restore_active_arena(arena, &backup);
            fixed_as_field= 1;
            rf->in_sum_func= thd->lex->in_sum_func;
          }
          if (thd->lex->in_sum_func &&
              thd->lex->in_sum_func->nest_level == 
@@ -3678,11 +3661,20 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
    rf= (place == IN_HAVING ?
         new Item_ref(context, ref, (char*) table_name,
                      (char*) field_name, alias_name_used) :
         (!select->group_list.elements ?
         new Item_direct_ref(context, ref, (char*) table_name,
                             (char*) field_name, alias_name_used));
                             (char*) field_name, alias_name_used) :
         new Item_outer_ref(context, ref, (char*) table_name,
                            (char*) field_name, alias_name_used)));
    *ref= save;
    if (!rf)
      return -1;

    if (place != IN_HAVING && select->group_list.elements)
    {
      outer_context->select_lex->inner_refs_list.push_back((Item_outer_ref*)rf);
      ((Item_outer_ref*)rf)->in_sum_func= thd->lex->in_sum_func;
    }
    thd->change_item_tree(reference, rf);
    /*
      rf is Item_ref => never substitute other items (in this case)
@@ -5640,16 +5632,19 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)

bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
{
  DBUG_ASSERT(*ref);
  /* outer_field->check_cols() will be made in Item_direct_ref::fix_fields */
  outer_field->fixed_as_field= 1;
  if (!outer_field->fixed &&
      (outer_field->fix_fields(thd, reference)))
  bool err;
  /* outer_ref->check_cols() will be made in Item_direct_ref::fix_fields */
  if ((*ref) && !(*ref)->fixed && ((*ref)->fix_fields(thd, reference)))
    return TRUE;
  table_name= outer_field->table_name;
  return Item_direct_ref::fix_fields(thd, reference);
  err= Item_direct_ref::fix_fields(thd, reference);
  if (!outer_ref)
    outer_ref= *ref;
  if ((*ref)->type() == Item::FIELD_ITEM)
    table_name= ((Item_field*)outer_ref)->table_name;
  return err;
}


/*
  Compare two view column references for equality.

Loading