Commit 085aa5c9 authored by unknown's avatar unknown
Browse files

Merge mysql.com:/home/timka/mysql/src/5.0-virgin

into  mysql.com:/home/timka/mysql/src/5.0-bug-16710


mysql-test/r/group_min_max.result:
  Auto merged
mysql-test/t/group_min_max.test:
  Auto merged
sql/item.cc:
  Auto merged
sql/item.h:
  Auto merged
sql/opt_range.cc:
  Auto merged
parents 86504f87 a01d48f9
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1954,6 +1954,15 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select sum(ord(a1)) from t1 where (a1 > 'a') group by a1,a2,b;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	index	idx_t1_0,idx_t1_1,idx_t1_2	idx_t1_1	163	NULL	128	Using where; Using index
explain select distinct(a1) from t1 where ord(a2) = 98;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	index	NULL	idx_t1_1	163	NULL	128	Using where; Using index
select distinct(a1) from t1 where ord(a2) = 98;
a1
a
b
c
d
explain select a1 from t1 where a2 = 'b' group by a1;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	range	NULL	idx_t1_1	130	NULL	5	Using where; Using index for group-by
+8 −0
Original line number Diff line number Diff line
@@ -641,6 +641,14 @@ explain select a1,a2,count(a2) from t1 group by a1,a2,b;
explain select a1,a2,count(a2) from t1 where (a1 > 'a') group by a1,a2,b;
explain select sum(ord(a1)) from t1 where (a1 > 'a') group by a1,a2,b;


#
# Bug #16710: select distinct doesn't return all it should
#

explain select distinct(a1) from t1 where ord(a2) = 98;
select distinct(a1) from t1 where ord(a2) = 98;

#
# BUG#11044: DISTINCT or GROUP BY queries with equality predicates instead of MIN/MAX.
#
+33 −1
Original line number Diff line number Diff line
@@ -496,7 +496,7 @@ bool Item_ident::remove_dependence_processor(byte * arg)
    arguments in a condition the method must return false.

  RETURN
    false to force the evaluation of collect_item_field_processor
    FALSE to force the evaluation of collect_item_field_processor
          for the subsequent items.
*/

@@ -517,6 +517,38 @@ bool Item_field::collect_item_field_processor(byte *arg)
}


/*
  Check if an Item_field references some field from a list of fields.

  SYNOPSIS
    Item_field::find_item_in_field_list_processor
    arg   Field being compared, arg must be of type Field

  DESCRIPTION
    Check whether the Item_field represented by 'this' references any
    of the fields in the keyparts passed via 'arg'. Used with the
    method Item::walk() to test whether any keypart in a sequence of
    keyparts is referenced in an expression.

  RETURN
    TRUE  if 'this' references the field 'arg'
    FALE  otherwise
*/
bool Item_field::find_item_in_field_list_processor(byte *arg)
{
  KEY_PART_INFO *first_non_group_part= *((KEY_PART_INFO **) arg);
  KEY_PART_INFO *last_part= *(((KEY_PART_INFO **) arg) + 1);
  KEY_PART_INFO *cur_part;

  for (cur_part= first_non_group_part; cur_part != last_part; cur_part++)
  {
    if (field->eq(cur_part->field))
      return TRUE;
  }
  return FALSE;
}


bool Item::check_cols(uint c)
{
  if (c != 1)
+2 −0
Original line number Diff line number Diff line
@@ -701,6 +701,7 @@ class Item {
  virtual bool remove_fixed(byte * arg) { fixed= 0; return 0; }
  virtual bool cleanup_processor(byte *arg);
  virtual bool collect_item_field_processor(byte * arg) { return 0; }
  virtual bool find_item_in_field_list_processor(byte *arg) { return 0; }
  virtual bool change_context_processor(byte *context) { return 0; }
  virtual bool reset_query_id_processor(byte *query_id) { return 0; }

@@ -1149,6 +1150,7 @@ class Item_field :public Item_ident
  bool is_null() { return field->is_null(); }
  Item *get_tmp_table_item(THD *thd);
  bool collect_item_field_processor(byte * arg);
  bool find_item_in_field_list_processor(byte *arg);
  bool reset_query_id_processor(byte *arg)
  {
    field->query_id= *((query_id_t *) arg);
+26 −0
Original line number Diff line number Diff line
@@ -6895,6 +6895,7 @@ cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
                   bool have_min, bool have_max,
                   double *read_cost, ha_rows *records);


/*
  Test if this access method is applicable to a GROUP query with MIN/MAX
  functions, and if so, construct a new TRP object.
@@ -7301,12 +7302,37 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
      }
      else if (min_max_arg_part &&
               (min_max_arg_part - first_non_group_part > 0))
      {
        /*
          There is a gap but no range tree, thus no predicates at all for the
          non-group keyparts.
        */
        goto next_index;
      }
      else if (first_non_group_part && join->conds)
      {
        /*
          If there is no MIN/MAX function in the query, but some index
          key part is referenced in the WHERE clause, then this index
          cannot be used because the WHERE condition over the keypart's
          field cannot be 'pushed' to the index (because there is no
          range 'tree'), and the WHERE clause must be evaluated before
          GROUP BY/DISTINCT.
        */
        /*
          Store the first and last keyparts that need to be analyzed
          into one array that can be passed as parameter.
        */
        KEY_PART_INFO *key_part_range[2];
        key_part_range[0]= first_non_group_part;
        key_part_range[1]= last_part;

        /* Check if cur_part is referenced in the WHERE clause. */
        if (join->conds->walk(&Item::find_item_in_field_list_processor,
                              (byte*) key_part_range))
          goto next_index;
      }
    }

    /*
      Test (WA1) partially - that no other keypart after the last infix part is