Commit b5182e4b authored by unknown's avatar unknown
Browse files

Merge rurik.mysql.com:/home/igor/mysql-5.0

into  rurik.mysql.com:/home/igor/dev/mysql-5.0-2


mysql-test/r/func_gconcat.result:
  Auto merged
sql/item.cc:
  Auto merged
sql/item.h:
  Auto merged
sql/item_cmpfunc.cc:
  Auto merged
sql/item_func.cc:
  Auto merged
sql/item_sum.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_delete.cc:
  Auto merged
sql/sql_lex.h:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_prepare.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_update.cc:
  Auto merged
parents 61b86c59 bef391c8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -163,7 +163,7 @@ show warnings;
Level	Code	Message
Warning	1260	1 line(s) were cut by GROUP_CONCAT()
set group_concat_max_len = 1024;
select group_concat(sum(a)) from t1 group by grp;
select group_concat(sum(c)) from t1 group by grp;
ERROR HY000: Invalid use of group function
select grp,group_concat(c order by 2) from t1 group by grp;
ERROR 42S22: Unknown column '2' in 'order clause'
+143 −0
Original line number Diff line number Diff line
@@ -2988,3 +2988,146 @@ max(fld)
1
drop table t1;
purge master logs before (select adddate(current_timestamp(), interval -4 day));
CREATE TABLE t1 (a int, b int);
CREATE TABLE t2 (c int, d int);
CREATE TABLE t3 (e int);
INSERT INTO t1 VALUES 
(1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40);
INSERT INTO t2 VALUES
(2,10), (2,20), (4,10), (5,10), (3,20), (2,40);
INSERT INTO t3 VALUES (10), (30), (10), (20) ;
SELECT a, MAX(b), MIN(b) FROM t1 GROUP BY a;
a	MAX(b)	MIN(b)
1	20	10
2	30	10
3	20	20
4	40	40
SELECT * FROM t2;
c	d
2	10
2	20
4	10
5	10
3	20
2	40
SELECT * FROM t3;
e
10
30
10
20
SELECT a FROM t1 GROUP BY a
HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>20);
a
2
4
SELECT a FROM t1 GROUP BY a
HAVING a IN (SELECT c FROM t2 WHERE MAX(b)<d);
a
2
SELECT a FROM t1 GROUP BY a
HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>d);
a
2
4
SELECT a FROM t1 GROUP BY a
HAVING a IN (SELECT c FROM t2
WHERE d >= SOME(SELECT e FROM t3 WHERE MAX(b)=e));
a
2
3
SELECT a FROM t1 GROUP BY a
HAVING a IN (SELECT c FROM t2
WHERE  EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
a
2
3
SELECT a FROM t1 GROUP BY a
HAVING a IN (SELECT c FROM t2
WHERE d > SOME(SELECT e FROM t3 WHERE MAX(b)=e));
a
2
SELECT a FROM t1 GROUP BY a
HAVING a IN (SELECT c FROM t2
WHERE  EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e < d));
a
2
SELECT a FROM t1 GROUP BY a
HAVING a IN (SELECT c FROM t2
WHERE MIN(b) < d AND 
EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
a
2
SELECT a, SUM(a) FROM t1 GROUP BY a;
a	SUM(a)
1	2
2	6
3	3
4	4
SELECT a FROM t1
WHERE EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c) GROUP BY a;
a
3
4
SELECT a FROM t1 GROUP BY a
HAVING EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c);
a
1
3
4
SELECT a FROM t1
WHERE a < 3 AND
EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c) GROUP BY a;
a
1
2
SELECT a FROM t1
WHERE a < 3 AND
EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c);
a
1
2
1
2
2
SELECT t1.a FROM t1 GROUP BY t1.a
HAVING t1.a < ALL(SELECT t2.c FROM t2 GROUP BY t2.c
HAVING EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
HAVING SUM(t1.a+t2.c) < t3.e/4));
a
1
2
SELECT t1.a FROM t1 GROUP BY t1.a
HAVING t1.a > ALL(SELECT t2.c FROM t2
WHERE EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
HAVING SUM(t1.a+t2.c) < t3.e/4));
a
4
SELECT t1.a FROM t1 GROUP BY t1.a
HAVING t1.a > ALL(SELECT t2.c FROM t2
WHERE EXISTS(SELECT t3.e FROM t3 
WHERE SUM(t1.a+t2.c) < t3.e/4));
ERROR HY000: Invalid use of group function
SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20;
ERROR HY000: Invalid use of group function
SELECT t1.a FROM t1 GROUP BY t1.a
HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
HAVING AVG(t2.c+SUM(t1.b)) > 20);
a
2
3
4
SELECT t1.a FROM t1 GROUP BY t1.a
HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
HAVING AVG(SUM(t1.b)) > 20);
a
2
4
SELECT t1.a, SUM(b) AS sum  FROM t1 GROUP BY t1.a
HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
HAVING t2.c+sum > 20);
a	sum
2	60
3	20
4	40
DROP TABLE t1,t2,t3;
+1 −1
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ set group_concat_max_len = 1024;
# Test errors

--error 1111
select group_concat(sum(a)) from t1 group by grp;
select group_concat(sum(c)) from t1 group by grp;
--error 1054
select grp,group_concat(c order by 2) from t1 group by grp;

+83 −0
Original line number Diff line number Diff line
@@ -1968,3 +1968,86 @@ drop table t1;

purge master logs before (select adddate(current_timestamp(), interval -4 day));

#
# Test for bug #11762: subquery with an aggregate function in HAVING
#

CREATE TABLE t1 (a int, b int);
CREATE TABLE t2 (c int, d int);
CREATE TABLE t3 (e int);

INSERT INTO t1 VALUES 
  (1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40);
INSERT INTO t2 VALUES
  (2,10), (2,20), (4,10), (5,10), (3,20), (2,40);
INSERT INTO t3 VALUES (10), (30), (10), (20) ;

SELECT a, MAX(b), MIN(b) FROM t1 GROUP BY a;
SELECT * FROM t2;
SELECT * FROM t3;

SELECT a FROM t1 GROUP BY a
  HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>20);
SELECT a FROM t1 GROUP BY a
  HAVING a IN (SELECT c FROM t2 WHERE MAX(b)<d);
SELECT a FROM t1 GROUP BY a
  HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>d);
SELECT a FROM t1 GROUP BY a
  HAVING a IN (SELECT c FROM t2
                 WHERE d >= SOME(SELECT e FROM t3 WHERE MAX(b)=e));
SELECT a FROM t1 GROUP BY a
  HAVING a IN (SELECT c FROM t2
                 WHERE  EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
SELECT a FROM t1 GROUP BY a
  HAVING a IN (SELECT c FROM t2
                 WHERE d > SOME(SELECT e FROM t3 WHERE MAX(b)=e));
SELECT a FROM t1 GROUP BY a
  HAVING a IN (SELECT c FROM t2
                 WHERE  EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e < d));
SELECT a FROM t1 GROUP BY a
  HAVING a IN (SELECT c FROM t2
                 WHERE MIN(b) < d AND 
                       EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));

SELECT a, SUM(a) FROM t1 GROUP BY a;

SELECT a FROM t1
   WHERE EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c) GROUP BY a;
SELECT a FROM t1 GROUP BY a
   HAVING EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c);

SELECT a FROM t1
   WHERE a < 3 AND
         EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c) GROUP BY a;
SELECT a FROM t1
   WHERE a < 3 AND
         EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c);

SELECT t1.a FROM t1 GROUP BY t1.a
  HAVING t1.a < ALL(SELECT t2.c FROM t2 GROUP BY t2.c
                       HAVING EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
                                       HAVING SUM(t1.a+t2.c) < t3.e/4));
SELECT t1.a FROM t1 GROUP BY t1.a
       HAVING t1.a > ALL(SELECT t2.c FROM t2
                           WHERE EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
                                          HAVING SUM(t1.a+t2.c) < t3.e/4));
-- error 1111
SELECT t1.a FROM t1 GROUP BY t1.a
       HAVING t1.a > ALL(SELECT t2.c FROM t2
                           WHERE EXISTS(SELECT t3.e FROM t3 
                                          WHERE SUM(t1.a+t2.c) < t3.e/4));
-- error 1111 
SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20;

SELECT t1.a FROM t1 GROUP BY t1.a
  HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
                    HAVING AVG(t2.c+SUM(t1.b)) > 20);
SELECT t1.a FROM t1 GROUP BY t1.a
  HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
                    HAVING AVG(SUM(t1.b)) > 20);

SELECT t1.a, SUM(b) AS sum  FROM t1 GROUP BY t1.a
  HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
                    HAVING t2.c+sum > 20);

DROP TABLE t1,t2,t3;
+32 −20
Original line number Diff line number Diff line
@@ -1048,6 +1048,7 @@ void Item_name_const::print(String *str)
    ref_pointer_array	Pointer to array of reference fields
    fields		All fields in select
    ref			Pointer to item
    skip_registered     <=> the function must skipped for registered SUM items

  NOTES
   This is from split_sum_func2() for items that should be split
@@ -1060,8 +1061,13 @@ void Item_name_const::print(String *str)


void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
                           List<Item> &fields, Item **ref)
                           List<Item> &fields, Item **ref, 
                           bool skip_registered)
{
  /* An item of type Item_sum  is registered <=> ref_by != 0 */ 
  if (type() == SUM_FUNC_ITEM && skip_registered && 
      ((Item_sum *) this)->ref_by)
    return;                                                 
  if (type() != SUM_FUNC_ITEM && with_sum_func)
  {
    /* Will split complicated items and ignore simple ones */
@@ -3192,15 +3198,9 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
           there are outer queries
        {
          for each outer query Q_k beginning from the inner-most one
          {
            if - Q_k is not a group query AND
               - Q_k is not inside an aggregate function
               OR
               - Q_(k-1) is not in a HAVING or SELECT clause of Q_k
          {
            search for a column or derived column named col_ref_i
            [in table T_j] in the FROM clause of Q_k;
            }

            if such a column is not found
              Search for a column or derived column named col_ref_i
@@ -3279,18 +3279,11 @@ bool Item_field::fix_fields(THD *thd, Item **reference)

        place= prev_subselect_item->parsing_place;
        /*
          Check table fields only if the subquery is used somewhere out of
          HAVING, or the outer SELECT does not use grouping (i.e. tables are
          accessible).

          In case of a view, find_field_in_tables() writes the pointer to
          the found view field into '*reference', in other words, it
          substitutes this Item_field with the found expression.
        */
        if ((place != IN_HAVING ||
             (!select->with_sum_func &&
              select->group_list.elements == 0)) &&
            (from_field= find_field_in_tables(thd, this,
        if ((from_field= find_field_in_tables(thd, this,
                                              outer_context->
                                                first_name_resolution_table,
                                              outer_context->
@@ -3306,6 +3299,21 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
            {
              prev_subselect_item->used_tables_cache|= from_field->table->map;
              prev_subselect_item->const_item_cache= 0;
              if (thd->lex->in_sum_func &&
                  thd->lex->in_sum_func->nest_level == 
                  thd->lex->current_select->nest_level)
              {
                Item::Type type= (*reference)->type();
                set_if_bigger(thd->lex->in_sum_func->max_arg_level,
                              select->nest_level);
                set_field(from_field);
                fixed= 1;
                mark_as_dependent(thd, last_checked_context->select_lex,
                                  context->select_lex, this,
                                  ((type == REF_ITEM || type == FIELD_ITEM) ?
                                   (Item_ident*) (*reference) : 0));
                return FALSE;
              }
            }
            else
            {
@@ -3457,6 +3465,11 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
      return FALSE;

    set_field(from_field);
    if (thd->lex->in_sum_func &&
        thd->lex->in_sum_func->nest_level == 
        thd->lex->current_select->nest_level)
      set_if_bigger(thd->lex->in_sum_func->max_arg_level,
                    thd->lex->current_select->nest_level);
  }
  else if (thd->set_query_id && field->query_id != thd->query_id)
  {
@@ -4612,9 +4625,8 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
    aggregate function.
  */
  if (((*ref)->with_sum_func && name &&
       (depended_from ||
       !(current_sel->linkage != GLOBAL_OPTIONS_TYPE &&
          current_sel->having_fix_field))) ||
         current_sel->having_fix_field)) ||
      !(*ref)->fixed)
  {
    my_error(ER_ILLEGAL_REFERENCE, MYF(0),
Loading