Commit ccad0572 authored by unknown's avatar unknown
Browse files

Merge ibabaev@bk-internal.mysql.com:/home/bk/mysql-4.1-opt

into  rurik.mysql.com:/home/igor/mysql-4.1-opt

parents 3390eaa0 e3e06587
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -916,3 +916,27 @@ select count(*), min(7), max(7) from t2m, t1i;
count(*)	min(7)	max(7)
0	NULL	NULL
drop table t1m, t1i, t2m, t2i;
CREATE TABLE t1 (id int PRIMARY KEY, b char(3), INDEX(b));
INSERT INTO t1 VALUES (1,'xx'), (2,'aa');
SELECT * FROM t1;
id	b
1	xx
2	aa
SELECT MAX(b) FROM t1 WHERE b < 'ppppp';
MAX(b)
aa
SHOW WARNINGS;
Level	Code	Message
SELECT MAX(b) FROM t1 WHERE b < 'pp';
MAX(b)
aa
DROP TABLE t1;
CREATE TABLE t1 (id int PRIMARY KEY, b char(16), INDEX(b(4)));
INSERT INTO t1 VALUES (1, 'xxxxbbbb'), (2, 'xxxxaaaa');
SELECT MAX(b) FROM t1;
MAX(b)
xxxxbbbb
EXPLAIN SELECT MAX(b) FROM t1;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	
DROP TABLE t1;
+19 −0
Original line number Diff line number Diff line
@@ -598,4 +598,23 @@ select count(*), min(7), max(7) from t2m, t1i;

drop table t1m, t1i, t2m, t2i;

#
# Bug #18206: min/max optimization cannot be applied to partial index
#

CREATE TABLE t1 (id int PRIMARY KEY, b char(3), INDEX(b));
INSERT INTO t1 VALUES (1,'xx'), (2,'aa');
SELECT * FROM t1;

SELECT MAX(b) FROM t1 WHERE b < 'ppppp';
SHOW WARNINGS;
SELECT MAX(b) FROM t1 WHERE b < 'pp';
DROP TABLE t1;

CREATE TABLE t1 (id int PRIMARY KEY, b char(16), INDEX(b(4)));
INSERT INTO t1 VALUES (1, 'xxxxbbbb'), (2, 'xxxxaaaa');
SELECT MAX(b) FROM t1;
EXPLAIN SELECT MAX(b) FROM t1;
DROP TABLE t1;

# End of 4.1 tests
+14 −3
Original line number Diff line number Diff line
@@ -543,6 +543,10 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
      break;                        // Found a part od the key for the field
  }

#if 0
  if (part->length != (((Item_field*) args[0])->field)->field_length)
    return 0;
#endif
  bool is_field_part= part == field_part;
  if (!(is_field_part || eq_type))
    return 0;
@@ -582,7 +586,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
    }
    else
    {
      store_val_in_field(part->field, args[between && max_fl ? 2 : 1]);
      store_val_in_field(part->field, args[between && max_fl ? 2 : 1],
                         CHECK_FIELD_IGNORE);
      if (part->null_bit) 
        *key_ptr++= (byte) test(part->field->is_null());
      part->field->get_key_image((char*) key_ptr, part->length,
@@ -638,6 +643,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
        field BETWEEN const1 AND const2
     3. all references to the columns from the same table as column field
        occur only in conjucts mentioned above.
     4. each of k first components the index is not partial, i.e. is not
        defined on a fixed length proper prefix of the field.

     If such an index exists the function through the ref parameter
     returns the key value to find max/min for the field using the index,
@@ -682,6 +689,10 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
      if (!(table->file->index_flags(idx, jdx, 0) & HA_READ_ORDER))
        return 0;

        /* Check whether the index component is partial */
      if (part->length < table->field[part->fieldnr-1]->pack_length())
        break;

      if (field->eq(part->field))
      {
        ref->key= idx;
+3 −3
Original line number Diff line number Diff line
@@ -3434,7 +3434,7 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
*/

bool
store_val_in_field(Field *field,Item *item)
store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
{
  bool error;
  THD *thd=current_thd;
@@ -3445,7 +3445,7 @@ store_val_in_field(Field *field,Item *item)
    with select_insert, which make count_cuted_fields= 1
   */
  enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
  thd->count_cuted_fields= CHECK_FIELD_WARN;
  thd->count_cuted_fields= check_flag;
  error= item->save_in_field(field, 1);
  thd->count_cuted_fields= old_count_cuted_fields;
  return error || cuted_fields != thd->cuted_fields;
@@ -7097,7 +7097,7 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
	    field->real_type() != FIELD_TYPE_VAR_STRING &&
	    (field->type() != FIELD_TYPE_FLOAT || field->decimals() == 0))
	{
	  return !store_val_in_field(field,right_item);
	  return !store_val_in_field(field, right_item, CHECK_FIELD_WARN);
	}
      }
    }
+1 −1
Original line number Diff line number Diff line
@@ -335,7 +335,7 @@ extern const char *join_type_str[];
void TEST_join(JOIN *join);

/* Extern functions in sql_select.cc */
bool store_val_in_field(Field *field,Item *val);
bool store_val_in_field(Field *field, Item *val, enum_check_fields check_flag);
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
			ORDER *group, bool distinct, bool save_sum_fields,
			ulong select_options, ha_rows rows_limit,