Commit 5861c6dc authored by unknown's avatar unknown

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

into mysql.com:/dbdata/psergey/mysql-5.0-bug5401-2


innobase/include/row0mysql.h:
  Auto merged
innobase/row/row0sel.c:
  Auto merged
sql/ha_innodb.cc:
  Auto merged
sql/opt_range.cc:
  Auto merged
parents dd3cfa8d c8807157
...@@ -531,10 +531,7 @@ struct row_prebuilt_struct { ...@@ -531,10 +531,7 @@ struct row_prebuilt_struct {
format */ format */
ulint hint_need_to_fetch_extra_cols; ulint hint_need_to_fetch_extra_cols;
/* normally this is set to 0; if this /* normally this is set to 0; if this
is set to ROW_RETRIEVE_PRIMARY_KEY is set to ROW_RETRIEVE_PRIMARY_KEY,
(that value is obsolete starting from
5.0.2, because we always fetch the
primary key cols),
then we should at least retrieve all then we should at least retrieve all
columns in the primary key; if this columns in the primary key; if this
is set to ROW_RETRIEVE_ALL_COLS, then is set to ROW_RETRIEVE_ALL_COLS, then
...@@ -607,9 +604,6 @@ struct row_prebuilt_struct { ...@@ -607,9 +604,6 @@ struct row_prebuilt_struct {
/* Values for hint_need_to_fetch_extra_cols */ /* Values for hint_need_to_fetch_extra_cols */
#define ROW_RETRIEVE_PRIMARY_KEY 1 #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 #define ROW_RETRIEVE_ALL_COLS 2
......
...@@ -2331,11 +2331,6 @@ row_sel_store_mysql_rec( ...@@ -2331,11 +2331,6 @@ row_sel_store_mysql_rec(
prebuilt->blob_heap = NULL; 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++) { for (i = 0; i < prebuilt->n_template; i++) {
templ = prebuilt->mysql_template + i; templ = prebuilt->mysql_template + i;
...@@ -2431,6 +2426,8 @@ row_sel_store_mysql_rec( ...@@ -2431,6 +2426,8 @@ row_sel_store_mysql_rec(
bug number 154 in the MySQL bug database: GROUP BY bug number 154 in the MySQL bug database: GROUP BY
and DISTINCT could treat NULL values inequal. */ 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 if (templ->type == DATA_VARCHAR
|| templ->type == DATA_CHAR || templ->type == DATA_CHAR
|| templ->type == DATA_BINARY || templ->type == DATA_BINARY
...@@ -2749,10 +2746,15 @@ row_sel_pop_cached_row_for_mysql( ...@@ -2749,10 +2746,15 @@ row_sel_pop_cached_row_for_mysql(
buf + templ->mysql_col_offset, buf + templ->mysql_col_offset,
cached_rec + templ->mysql_col_offset, cached_rec + templ->mysql_col_offset,
templ->mysql_col_len); templ->mysql_col_len);
/* Copy NULL bit of the current field from cached_rec
to buf */
if (templ->mysql_null_bit_mask) 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 else
......
...@@ -53,3 +53,71 @@ key1 key2 str1 zeroval str2 str3 ...@@ -53,3 +53,71 @@ key1 key2 str1 zeroval str2 str3
1 199 aaa 0 bbb 199-0_A 1 199 aaa 0 bbb 199-0_A
0 200 aaa 0 bbb 200-0_a 0 200 aaa 0 bbb 200-0_a
drop table t1; 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; ...@@ -51,4 +51,72 @@ select * from t1 where key1 < 5 or key2 > 197;
explain select * from t1 where key1 < 3 or key2 > 195; explain select * from t1 where key1 < 3 or key2 > 195;
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; 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;
...@@ -2285,13 +2285,7 @@ build_template( ...@@ -2285,13 +2285,7 @@ build_template(
ulint n_fields; ulint n_fields;
ulint n_requested_fields = 0; ulint n_requested_fields = 0;
ibool fetch_all_in_key = FALSE; ibool fetch_all_in_key = FALSE;
ibool fetch_primary_key_cols = TRUE; /* The ROR code in ibool fetch_primary_key_cols = FALSE;
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. */
ulint i; ulint i;
if (prebuilt->select_lock_type == LOCK_X) { if (prebuilt->select_lock_type == LOCK_X) {
......
...@@ -912,7 +912,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler) ...@@ -912,7 +912,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
{ {
DBUG_PRINT("info", ("Reusing handler %p", file)); DBUG_PRINT("info", ("Reusing handler %p", file));
if (file->extra(HA_EXTRA_KEYREAD) || if (file->extra(HA_EXTRA_KEYREAD) ||
file->extra(HA_EXTRA_RETRIEVE_ALL_COLS) | file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY) ||
init() || reset()) init() || reset())
{ {
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -937,7 +937,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler) ...@@ -937,7 +937,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
} }
if (file->extra(HA_EXTRA_KEYREAD) || if (file->extra(HA_EXTRA_KEYREAD) ||
file->extra(HA_EXTRA_RETRIEVE_ALL_COLS) || file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY) ||
init() || reset()) init() || reset())
{ {
file->close(); file->close();
...@@ -5619,7 +5619,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() ...@@ -5619,7 +5619,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::prepare_unique"); DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::prepare_unique");
/* We're going to just read rowids. */ /* 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 Make innodb retrieve all PK member fields, so
...@@ -5628,7 +5629,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() ...@@ -5628,7 +5629,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
(This also creates a deficiency - it is possible that we will retrieve (This also creates a deficiency - it is possible that we will retrieve
parts of key that are not used by current query at all.) 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_it.rewind();
cur_quick= cur_quick_it++; cur_quick= cur_quick_it++;
......
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