Commit 8d332655 authored by unknown's avatar unknown

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

into moonbone.local:/home/evgen/bk-trees/mysql-4.1-opt

parents ce8b60b4 e815f93b
...@@ -916,3 +916,27 @@ select count(*), min(7), max(7) from t2m, t1i; ...@@ -916,3 +916,27 @@ select count(*), min(7), max(7) from t2m, t1i;
count(*) min(7) max(7) count(*) min(7) max(7)
0 NULL NULL 0 NULL NULL
drop table t1m, t1i, t2m, t2i; 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;
...@@ -2714,3 +2714,17 @@ select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 fro ...@@ -2714,3 +2714,17 @@ select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 fro
f1 f2 f1 f2
1 1 1 1
drop table t1,t2; drop table t1,t2;
CREATE TABLE t1(a int, b int, c int, KEY b(b), KEY c(c));
insert into t1 values (1,0,0),(2,0,0);
CREATE TABLE t2 (a int, b varchar(2), c varchar(2), PRIMARY KEY(a));
insert into t2 values (1,'',''), (2,'','');
CREATE TABLE t3 (a int, b int, PRIMARY KEY (a,b), KEY a (a), KEY b (b));
insert into t3 values (1,1),(1,2);
explain select straight_join DISTINCT t2.a,t2.b, t1.c from t1, t3, t2
where (t1.c=t2.a or (t1.c=t3.a and t2.a=t3.b)) and t1.b=556476786 and
t2.b like '%%' order by t2.b limit 0,1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref b,c b 5 const 1 Using where; Using temporary; Using filesort
1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index
1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
DROP TABLE t1,t2,t3;
...@@ -598,4 +598,23 @@ select count(*), min(7), max(7) from t2m, t1i; ...@@ -598,4 +598,23 @@ select count(*), min(7), max(7) from t2m, t1i;
drop table t1m, t1i, t2m, t2i; 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 # End of 4.1 tests
...@@ -2248,4 +2248,18 @@ insert into t2 values(1,1); ...@@ -2248,4 +2248,18 @@ insert into t2 values(1,1);
select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2)); select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2));
drop table t1,t2; drop table t1,t2;
#
# Bug #4981: 4.x and 5.x produce non-optimal execution path, 3.23 regression test failure
#
CREATE TABLE t1(a int, b int, c int, KEY b(b), KEY c(c));
insert into t1 values (1,0,0),(2,0,0);
CREATE TABLE t2 (a int, b varchar(2), c varchar(2), PRIMARY KEY(a));
insert into t2 values (1,'',''), (2,'','');
CREATE TABLE t3 (a int, b int, PRIMARY KEY (a,b), KEY a (a), KEY b (b));
insert into t3 values (1,1),(1,2);
# must have "range checked" for t2
explain select straight_join DISTINCT t2.a,t2.b, t1.c from t1, t3, t2
where (t1.c=t2.a or (t1.c=t3.a and t2.a=t3.b)) and t1.b=556476786 and
t2.b like '%%' order by t2.b limit 0,1;
DROP TABLE t1,t2,t3;
# End of 4.1 tests # End of 4.1 tests
...@@ -64,7 +64,7 @@ public: ...@@ -64,7 +64,7 @@ public:
uint8 min_flag, uint8 max_flag, uint8 maybe_flag); uint8 min_flag, uint8 max_flag, uint8 maybe_flag);
SEL_ARG(enum Type type_arg) SEL_ARG(enum Type type_arg)
:elements(1),use_count(1),left(0),next_key_part(0),color(BLACK), :elements(1),use_count(1),left(0),next_key_part(0),color(BLACK),
type(type_arg) type(type_arg),min_flag(0)
{} {}
inline bool is_same(SEL_ARG *arg) inline bool is_same(SEL_ARG *arg)
{ {
......
...@@ -582,7 +582,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, ...@@ -582,7 +582,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
} }
else 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) if (part->null_bit)
*key_ptr++= (byte) test(part->field->is_null()); *key_ptr++= (byte) test(part->field->is_null());
part->field->get_key_image((char*) key_ptr, part->length, part->field->get_key_image((char*) key_ptr, part->length,
...@@ -638,6 +639,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, ...@@ -638,6 +639,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
field BETWEEN const1 AND const2 field BETWEEN const1 AND const2
3. all references to the columns from the same table as column field 3. all references to the columns from the same table as column field
occur only in conjucts mentioned above. 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 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, returns the key value to find max/min for the field using the index,
...@@ -647,8 +650,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, ...@@ -647,8 +650,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
of the whole search key) of the whole search key)
NOTE NOTE
This function may set table->key_read to 1, which must be reset after This function may set table->key_read to 1, which must be reset after
index is used! (This can only happen when function returns 1) index is used! (This can only happen when function returns 1)
RETURN RETURN
0 Index can not be used to optimize MIN(field)/MAX(field) 0 Index can not be used to optimize MIN(field)/MAX(field)
...@@ -682,6 +685,10 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref, ...@@ -682,6 +685,10 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
if (!(table->file->index_flags(idx, jdx, 0) & HA_READ_ORDER)) if (!(table->file->index_flags(idx, jdx, 0) & HA_READ_ORDER))
return 0; 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)) if (field->eq(part->field))
{ {
ref->key= idx; ref->key= idx;
......
...@@ -3434,7 +3434,7 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables, ...@@ -3434,7 +3434,7 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
*/ */
bool bool
store_val_in_field(Field *field,Item *item) store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
{ {
bool error; bool error;
THD *thd=current_thd; THD *thd=current_thd;
...@@ -3445,7 +3445,7 @@ store_val_in_field(Field *field,Item *item) ...@@ -3445,7 +3445,7 @@ store_val_in_field(Field *field,Item *item)
with select_insert, which make count_cuted_fields= 1 with select_insert, which make count_cuted_fields= 1
*/ */
enum_check_fields old_count_cuted_fields= thd->count_cuted_fields; 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); error= item->save_in_field(field, 1);
thd->count_cuted_fields= old_count_cuted_fields; thd->count_cuted_fields= old_count_cuted_fields;
return error || cuted_fields != thd->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) ...@@ -7097,7 +7097,7 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
field->real_type() != FIELD_TYPE_VAR_STRING && field->real_type() != FIELD_TYPE_VAR_STRING &&
(field->type() != FIELD_TYPE_FLOAT || field->decimals() == 0)) (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);
} }
} }
} }
......
...@@ -335,7 +335,7 @@ extern const char *join_type_str[]; ...@@ -335,7 +335,7 @@ extern const char *join_type_str[];
void TEST_join(JOIN *join); void TEST_join(JOIN *join);
/* Extern functions in sql_select.cc */ /* 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, TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields, ORDER *group, bool distinct, bool save_sum_fields,
ulong select_options, ha_rows rows_limit, ulong select_options, ha_rows rows_limit,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment