Commit bac27bb9 authored by unknown's avatar unknown
Browse files

Merge gkodinov@bk-internal.mysql.com:/home/bk/mysql-5.0-opt

into  magare.gmz:/home/kgeorge/mysql/autopush/B24484-5.0


mysql-test/r/subselect3.result:
  Auto merged
sql/item.h:
  Auto merged
sql/item_sum.cc:
  Auto merged
sql/opt_range.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_insert.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
parents 3798a7d5 9c89dd65
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -645,3 +645,56 @@ a b Z
2	2	0
3	3	1
drop table t1,t2;
CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
INSERT INTO t1 VALUES (1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'),(3,3,'j'), (3,2,'k'), (3,1,'l'),
(1,9,'m');
CREATE TABLE t2 (a int, b INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
INSERT INTO t2 SELECT * FROM t1;
SELECT a, MAX(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b))
as test FROM t1 GROUP BY a;
a	MAX(b)	test
1	9	m
2	3	h
3	4	i
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));
a	b	c
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;
a	AVG(b)	test
1	4.0000	NULL
2	2.0000	k
3	2.5000	NULL
SELECT a,b,c FROM t1 WHERE b in (9,3,4) ORDER BY b,c;
a	b	c
1	3	c
2	3	h
3	3	j
1	4	d
3	4	i
1	9	m
SELECT a, MAX(b),
(SELECT COUNT(DISTINCT t.c) FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) 
LIMIT 1) 
as cnt, 
(SELECT t.b FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1) 
as t_b,
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1) 
as t_b,
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) ORDER BY t.c LIMIT 1)
as t_b
FROM t1 GROUP BY a;
a	MAX(b)	cnt	t_b	t_b	t_b
1	9	1	9	m	m
2	3	1	3	h	h
3	4	1	4	i	i
SELECT a, MAX(b),
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1) as test 
FROM t1 GROUP BY a;
a	MAX(b)	test
1	9	m
2	3	h
3	4	i
DROP TABLE t1, t2;
+41 −0
Original line number Diff line number Diff line
@@ -489,3 +489,44 @@ select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1;

drop table t1,t2;

#
# Bug #24484: Aggregate function used in column list subquery gives erroneous 
# error
#
CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
INSERT INTO t1 VALUES (1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
  (2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'),(3,3,'j'), (3,2,'k'), (3,1,'l'),
  (1,9,'m');
CREATE TABLE t2 (a int, b INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
INSERT INTO t2 SELECT * FROM t1;

# Gives error, but should work since it is (a, b) is the PK so only one 
# given match possible
SELECT a, MAX(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b))
  as test FROM t1 GROUP BY a;
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));
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;

SELECT a, MAX(b),
 (SELECT COUNT(DISTINCT t.c) FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) 
  LIMIT 1) 
  as cnt, 
 (SELECT t.b FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1) 
  as t_b,
 (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1) 
  as t_b,
 (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) ORDER BY t.c LIMIT 1)
  as t_b
 FROM t1 GROUP BY a;

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


DROP TABLE t1, t2;
+5 −0
Original line number Diff line number Diff line
@@ -1898,6 +1898,11 @@ class Item_ref :public Item_ident
  {
    return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables(); 
  }
  void update_used_tables() 
  { 
    if (!depended_from) 
      (*ref)->update_used_tables(); 
  }
  table_map not_null_tables() const { return (*ref)->not_null_tables(); }
  void set_result_field(Field *field)	{ result_field= field; }
  bool is_result_field() { return 1; }
+30 −6
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ bool Item_sum::init_sum_func_check(THD *thd)
  /* Save a pointer to object to be used in items for nested set functions */
  thd->lex->in_sum_func= this;
  nest_level= thd->lex->current_select->nest_level;
  nest_level_tables_count= thd->lex->current_select->join->tables;
  ref_by= 0;
  aggr_level= -1;
  max_arg_level= -1;
@@ -176,6 +177,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
    */
    set_if_bigger(in_sum_func->max_sum_func_level, aggr_level);
  }
  update_used_tables();
  thd->lex->in_sum_func= in_sum_func;
  return FALSE;
}
@@ -271,8 +273,8 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
}


Item_sum::Item_sum(List<Item> &list)
  :arg_count(list.elements)
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements), 
  forced_const(FALSE)
{
  if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
  {
@@ -296,7 +298,10 @@ Item_sum::Item_sum(List<Item> &list)

Item_sum::Item_sum(THD *thd, Item_sum *item):
  Item_result_field(thd, item), arg_count(item->arg_count),
  quick_group(item->quick_group)
  nest_level(item->nest_level), aggr_level(item->aggr_level),
  quick_group(item->quick_group), used_tables_cache(item->used_tables_cache),
  forced_const(item->forced_const), 
  nest_level_tables_count(item->nest_level_tables_count)
{
  if (arg_count <= 2)
    args=tmp_args;
@@ -426,6 +431,26 @@ case DECIMAL_RESULT:
}


void Item_sum::update_used_tables ()
{
  if (!forced_const)
  {
    used_tables_cache= 0;
    for (uint i=0 ; i < arg_count ; i++)
    {
      args[i]->update_used_tables();
      used_tables_cache|= args[i]->used_tables();
    }

    used_tables_cache&= PSEUDO_TABLE_BITS;

    /* the aggregate function is aggregated into its local context */
    if (aggr_level == nest_level)
      used_tables_cache |=  (1 << nest_level_tables_count) - 1;
  }
}


String *
Item_sum_num::val_str(String *str)
{
@@ -485,7 +510,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
Item_sum_hybrid::Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
  :Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type),
  hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
  used_table_cache(item->used_table_cache), was_values(item->was_values)
  was_values(item->was_values)
{
  /* copy results from old value */
  switch (hybrid_type) {
@@ -1073,7 +1098,6 @@ void Item_sum_count::cleanup()
  DBUG_ENTER("Item_sum_count::cleanup");
  count= 0;
  Item_sum_int::cleanup();
  used_table_cache= ~(table_map) 0;
  DBUG_VOID_RETURN;
}

@@ -1554,7 +1578,7 @@ void Item_sum_hybrid::cleanup()
{
  DBUG_ENTER("Item_sum_hybrid::cleanup");
  Item_sum::cleanup();
  used_table_cache= ~(table_map) 0;
  forced_const= FALSE;

  /*
    by default it is TRUE to avoid TRUE reporting by
+36 −23
Original line number Diff line number Diff line
@@ -217,6 +217,8 @@
    
*/ 

class st_select_lex;

class Item_sum :public Item_result_field
{
public:
@@ -237,19 +239,26 @@ class Item_sum :public Item_result_field
  int8 max_sum_func_level;/* max level of aggregation for embedded functions */
  bool quick_group;			/* If incremental update of fields */

protected:  
  table_map used_tables_cache;
  bool forced_const;
  byte nest_level_tables_count;

public:  

  void mark_as_sum_func();
  Item_sum() :arg_count(0), quick_group(1) 
  Item_sum() :arg_count(0), quick_group(1), forced_const(FALSE)
  {
    mark_as_sum_func();
  }
  Item_sum(Item *a)
    :args(tmp_args), arg_count(1), quick_group(1)
  Item_sum(Item *a) :args(tmp_args), arg_count(1), quick_group(1), 
    forced_const(FALSE)
  {
    args[0]=a;
    mark_as_sum_func();
  }
  Item_sum( Item *a, Item *b )
    :args(tmp_args), arg_count(2), quick_group(1)
  Item_sum( Item *a, Item *b ) :args(tmp_args), arg_count(2), quick_group(1),
    forced_const(FALSE)
  {
    args[0]=a; args[1]=b;
    mark_as_sum_func();
@@ -319,10 +328,20 @@ class Item_sum :public Item_result_field
  virtual const char *func_name() const= 0;
  virtual Item *result_item(Field *field)
    { return new Item_field(field); }
  table_map used_tables() const { return ~(table_map) 0; } /* Not used */
  bool const_item() const { return 0; }
  table_map used_tables() const { return used_tables_cache; }
  void update_used_tables ();
  void cleanup() 
  { 
    Item::cleanup();
    forced_const= FALSE; 
  }
  bool is_null() { return null_value; }
  void update_used_tables() { }
  void make_const () 
  { 
    used_tables_cache= 0; 
    forced_const= TRUE; 
  }
  virtual bool const_item() const { return forced_const; }
  void make_field(Send_field *field);
  void print(String *str);
  void fix_num_length_and_dec();
@@ -509,23 +528,23 @@ class Item_sum_avg_distinct: public Item_sum_distinct
class Item_sum_count :public Item_sum_int
{
  longlong count;
  table_map used_table_cache;

  public:
  Item_sum_count(Item *item_par)
    :Item_sum_int(item_par),count(0),used_table_cache(~(table_map) 0)
    :Item_sum_int(item_par),count(0)
  {}
  Item_sum_count(THD *thd, Item_sum_count *item)
    :Item_sum_int(thd, item), count(item->count),
     used_table_cache(item->used_table_cache)
    :Item_sum_int(thd, item), count(item->count)
  {}
  table_map used_tables() const { return used_table_cache; }
  bool const_item() const { return !used_table_cache; }
  enum Sumfunctype sum_func () const { return COUNT_FUNC; }
  void clear();
  void no_rows_in_result() { count=0; }
  bool add();
  void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; }
  void make_const(longlong count_arg) 
  { 
    count=count_arg;
    Item_sum::make_const();
  }
  longlong val_int();
  void reset_field();
  void cleanup();
@@ -805,28 +824,22 @@ class Item_sum_hybrid :public Item_sum
  Item_result hybrid_type;
  enum_field_types hybrid_field_type;
  int cmp_sign;
  table_map used_table_cache;
  bool was_values;  // Set if we have found at least one row (for max/min only)

  public:
  Item_sum_hybrid(Item *item_par,int sign)
    :Item_sum(item_par), sum(0.0), sum_int(0),
    hybrid_type(INT_RESULT), hybrid_field_type(FIELD_TYPE_LONGLONG),
    cmp_sign(sign), used_table_cache(~(table_map) 0),
    was_values(TRUE)
    cmp_sign(sign), was_values(TRUE)
  { collation.set(&my_charset_bin); }
  Item_sum_hybrid(THD *thd, Item_sum_hybrid *item);
  bool fix_fields(THD *, Item **);
  table_map used_tables() const { return used_table_cache; }
  bool const_item() const { return !used_table_cache; }

  void clear();
  double val_real();
  longlong val_int();
  my_decimal *val_decimal(my_decimal *);
  void reset_field();
  String *val_str(String *);
  void make_const() { used_table_cache=0; }
  bool keep_field_type(void) const { return 1; }
  enum Item_result result_type () const { return hybrid_type; }
  enum enum_field_types field_type() const { return hybrid_field_type; }
Loading