summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <sergefp@mysql.com>2005-01-12 23:22:12 +0300
committerunknown <sergefp@mysql.com>2005-01-12 23:22:12 +0300
commit4596579c999c7dbf5e0f9152fb0d645e94e11e7c (patch)
treeb1069c3c3bbffb3caa2fc2f236c475494af3cc7c
parent4c9d5f80c1f84e66c7a6bde7bf370f199abbf4ee (diff)
parent5861c6dc172ec508ca85eaff437a2a6bab8825aa (diff)
downloadmariadb-git-4596579c999c7dbf5e0f9152fb0d645e94e11e7c.tar.gz
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
-rw-r--r--innobase/include/row0mysql.h8
-rw-r--r--innobase/row/row0sel.c18
-rw-r--r--mysql-test/r/index_merge_innodb.result68
-rw-r--r--mysql-test/t/index_merge_innodb.test68
-rw-r--r--sql/ha_innodb.cc8
-rw-r--r--sql/opt_range.cc10
6 files changed, 154 insertions, 26 deletions
diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h
index bd5ad3adba5..575d8ee67bb 100644
--- a/innobase/include/row0mysql.h
+++ b/innobase/include/row0mysql.h
@@ -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
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index 6cd265f23e3..f3a5f911171 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -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
diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result
index afa17c79a6e..d1914844839 100644
--- a/mysql-test/r/index_merge_innodb.result
+++ b/mysql-test/r/index_merge_innodb.result
@@ -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;
diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test
index 2da40c5719a..cc1a3169d0e 100644
--- a/mysql-test/t/index_merge_innodb.test
+++ b/mysql-test/t/index_merge_innodb.test
@@ -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;
+
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 02da7f876e2..9e044b7e056 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -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) {
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index d36ce743b05..4b0e5f036cb 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -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++;