Merge spetrunia@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/dbdata/psergey/mysql-5.0-bug5401-2 sql/opt_range.cc: Auto merged sql/ha_innodb.cc: Auto merged
This commit is contained in:
commit
4596579c99
@ -531,10 +531,7 @@ struct row_prebuilt_struct {
|
||||
format */
|
||||
ulint hint_need_to_fetch_extra_cols;
|
||||
/* normally this is set to 0; if this
|
||||
is set to ROW_RETRIEVE_PRIMARY_KEY
|
||||
(that value is obsolete starting from
|
||||
5.0.2, because we always fetch the
|
||||
primary key cols),
|
||||
is set to ROW_RETRIEVE_PRIMARY_KEY,
|
||||
then we should at least retrieve all
|
||||
columns in the primary key; if this
|
||||
is set to ROW_RETRIEVE_ALL_COLS, then
|
||||
@ -607,9 +604,6 @@ struct row_prebuilt_struct {
|
||||
|
||||
/* Values for hint_need_to_fetch_extra_cols */
|
||||
#define ROW_RETRIEVE_PRIMARY_KEY 1
|
||||
/* value 1 is obsolete starting from
|
||||
5.0.2, because we always fetch the
|
||||
primary key cols */
|
||||
#define ROW_RETRIEVE_ALL_COLS 2
|
||||
|
||||
|
||||
|
@ -2331,11 +2331,6 @@ row_sel_store_mysql_rec(
|
||||
prebuilt->blob_heap = NULL;
|
||||
}
|
||||
|
||||
/* MySQL assumes that all columns have the SQL NULL bit set unless it
|
||||
is a nullable column with a non-NULL value */
|
||||
|
||||
memset(mysql_rec, 0xFF, prebuilt->null_bitmap_len);
|
||||
|
||||
for (i = 0; i < prebuilt->n_template; i++) {
|
||||
|
||||
templ = prebuilt->mysql_template + i;
|
||||
@ -2431,6 +2426,8 @@ row_sel_store_mysql_rec(
|
||||
bug number 154 in the MySQL bug database: GROUP BY
|
||||
and DISTINCT could treat NULL values inequal. */
|
||||
|
||||
mysql_rec[templ->mysql_null_byte_offset] |=
|
||||
(byte) (templ->mysql_null_bit_mask);
|
||||
if (templ->type == DATA_VARCHAR
|
||||
|| templ->type == DATA_CHAR
|
||||
|| templ->type == DATA_BINARY
|
||||
@ -2749,10 +2746,15 @@ row_sel_pop_cached_row_for_mysql(
|
||||
buf + templ->mysql_col_offset,
|
||||
cached_rec + templ->mysql_col_offset,
|
||||
templ->mysql_col_len);
|
||||
|
||||
/* Copy NULL bit of the current field from cached_rec
|
||||
to buf */
|
||||
if (templ->mysql_null_bit_mask)
|
||||
buf[templ->mysql_null_byte_offset] &=
|
||||
cached_rec[templ->mysql_null_byte_offset];
|
||||
{
|
||||
buf[templ->mysql_null_byte_offset] ^=
|
||||
(buf[templ->mysql_null_byte_offset] ^
|
||||
cached_rec[templ->mysql_null_byte_offset]) &
|
||||
(byte)templ->mysql_null_bit_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -53,3 +53,71 @@ key1 key2 str1 zeroval str2 str3
|
||||
1 199 aaa 0 bbb 199-0_A
|
||||
0 200 aaa 0 bbb 200-0_a
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
pk integer not null auto_increment primary key,
|
||||
key1 integer,
|
||||
key2 integer not null,
|
||||
filler char (200),
|
||||
index (key1),
|
||||
index (key2)
|
||||
) engine=innodb;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
explain select pk from t1 where key1 = 1 and key2 = 1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index_merge key1,key2 key1,key2 5,4 NULL 1 Using intersect(key1,key2); Using where; Using index
|
||||
select pk from t1 where key2 = 1 and key1 = 1;
|
||||
pk
|
||||
26
|
||||
select pk from t1 ignore index(key1,key2) where key2 = 1 and key1 = 1;
|
||||
pk
|
||||
26
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
pk int primary key auto_increment,
|
||||
key1a int,
|
||||
key2a int,
|
||||
key1b int,
|
||||
key2b int,
|
||||
dummy1 int,
|
||||
dummy2 int,
|
||||
dummy3 int,
|
||||
dummy4 int,
|
||||
key3a int,
|
||||
key3b int,
|
||||
filler1 char (200),
|
||||
index i1(key1a, key1b),
|
||||
index i2(key2a, key2b),
|
||||
index i3(key3a, key3b)
|
||||
) engine=innodb;
|
||||
create table t2 (a int);
|
||||
insert into t2 values (0),(1),(2),(3),(4),(NULL);
|
||||
insert into t1 (key1a, key1b, key2a, key2b, key3a, key3b)
|
||||
select A.a, B.a, C.a, D.a, C.a, D.a from t2 A,t2 B,t2 C, t2 D;
|
||||
insert into t1 (key1a, key1b, key2a, key2b, key3a, key3b)
|
||||
select key1a, key1b, key2a, key2b, key3a, key3b from t1;
|
||||
insert into t1 (key1a, key1b, key2a, key2b, key3a, key3b)
|
||||
select key1a, key1b, key2a, key2b, key3a, key3b from t1;
|
||||
analyze table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status OK
|
||||
select count(*) from t1;
|
||||
count(*)
|
||||
5184
|
||||
explain select count(*) from t1 where
|
||||
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL 3 Using intersect(i1,i2); Using where; Using index
|
||||
select count(*) from t1 where
|
||||
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
|
||||
count(*)
|
||||
4
|
||||
explain select count(*) from t1 where
|
||||
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL 3 Using intersect(i1,i3); Using where; Using index
|
||||
select count(*) from t1 where
|
||||
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
|
||||
count(*)
|
||||
4
|
||||
drop table t1,t2;
|
||||
|
@ -51,4 +51,72 @@ select * from t1 where key1 < 5 or key2 > 197;
|
||||
explain select * from t1 where key1 < 3 or key2 > 195;
|
||||
select * from t1 where key1 < 3 or key2 > 195;
|
||||
|
||||
# Test for BUG#5401
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
pk integer not null auto_increment primary key,
|
||||
key1 integer,
|
||||
key2 integer not null,
|
||||
filler char (200),
|
||||
index (key1),
|
||||
index (key2)
|
||||
) engine=innodb;
|
||||
show warnings;
|
||||
--disable_query_log
|
||||
let $1=30;
|
||||
while ($1)
|
||||
{
|
||||
eval insert into t1 (key1, key2, filler) values ($1/4, $1/8, 'filler-data');
|
||||
dec $1;
|
||||
}
|
||||
--enable_query_log
|
||||
explain select pk from t1 where key1 = 1 and key2 = 1;
|
||||
select pk from t1 where key2 = 1 and key1 = 1;
|
||||
select pk from t1 ignore index(key1,key2) where key2 = 1 and key1 = 1;
|
||||
|
||||
# More tests for BUG#5401.
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
pk int primary key auto_increment,
|
||||
key1a int,
|
||||
key2a int,
|
||||
key1b int,
|
||||
key2b int,
|
||||
dummy1 int,
|
||||
dummy2 int,
|
||||
dummy3 int,
|
||||
dummy4 int,
|
||||
key3a int,
|
||||
key3b int,
|
||||
filler1 char (200),
|
||||
index i1(key1a, key1b),
|
||||
index i2(key2a, key2b),
|
||||
index i3(key3a, key3b)
|
||||
) engine=innodb;
|
||||
|
||||
create table t2 (a int);
|
||||
insert into t2 values (0),(1),(2),(3),(4),(NULL);
|
||||
|
||||
insert into t1 (key1a, key1b, key2a, key2b, key3a, key3b)
|
||||
select A.a, B.a, C.a, D.a, C.a, D.a from t2 A,t2 B,t2 C, t2 D;
|
||||
insert into t1 (key1a, key1b, key2a, key2b, key3a, key3b)
|
||||
select key1a, key1b, key2a, key2b, key3a, key3b from t1;
|
||||
insert into t1 (key1a, key1b, key2a, key2b, key3a, key3b)
|
||||
select key1a, key1b, key2a, key2b, key3a, key3b from t1;
|
||||
analyze table t1;
|
||||
select count(*) from t1;
|
||||
|
||||
explain select count(*) from t1 where
|
||||
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
|
||||
|
||||
select count(*) from t1 where
|
||||
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
|
||||
|
||||
explain select count(*) from t1 where
|
||||
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
|
||||
|
||||
select count(*) from t1 where
|
||||
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
|
@ -2302,13 +2302,7 @@ build_template(
|
||||
ulint n_fields;
|
||||
ulint n_requested_fields = 0;
|
||||
ibool fetch_all_in_key = FALSE;
|
||||
ibool fetch_primary_key_cols = TRUE; /* The ROR code in
|
||||
opt_range.cc assumes that the
|
||||
primary key cols are always
|
||||
retrieved. Starting from
|
||||
MySQL-5.0.2, let us always
|
||||
fetch them, even though it
|
||||
wastes some CPU. */
|
||||
ibool fetch_primary_key_cols = FALSE;
|
||||
ulint i;
|
||||
|
||||
if (prebuilt->select_lock_type == LOCK_X) {
|
||||
|
@ -912,7 +912,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
|
||||
{
|
||||
DBUG_PRINT("info", ("Reusing handler %p", file));
|
||||
if (file->extra(HA_EXTRA_KEYREAD) ||
|
||||
file->extra(HA_EXTRA_RETRIEVE_ALL_COLS) |
|
||||
file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY) ||
|
||||
init() || reset())
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
@ -937,7 +937,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
|
||||
}
|
||||
|
||||
if (file->extra(HA_EXTRA_KEYREAD) ||
|
||||
file->extra(HA_EXTRA_RETRIEVE_ALL_COLS) ||
|
||||
file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY) ||
|
||||
init() || reset())
|
||||
{
|
||||
file->close();
|
||||
@ -5621,7 +5621,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
|
||||
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::prepare_unique");
|
||||
|
||||
/* We're going to just read rowids. */
|
||||
head->file->extra(HA_EXTRA_KEYREAD);
|
||||
if (head->file->extra(HA_EXTRA_KEYREAD))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/*
|
||||
Make innodb retrieve all PK member fields, so
|
||||
@ -5630,7 +5631,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
|
||||
(This also creates a deficiency - it is possible that we will retrieve
|
||||
parts of key that are not used by current query at all.)
|
||||
*/
|
||||
head->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
|
||||
if (head->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
cur_quick_it.rewind();
|
||||
cur_quick= cur_quick_it++;
|
||||
|
Loading…
x
Reference in New Issue
Block a user