diff options
author | unknown <sergefp@mysql.com> | 2005-01-12 23:22:12 +0300 |
---|---|---|
committer | unknown <sergefp@mysql.com> | 2005-01-12 23:22:12 +0300 |
commit | 4596579c999c7dbf5e0f9152fb0d645e94e11e7c (patch) | |
tree | b1069c3c3bbffb3caa2fc2f236c475494af3cc7c | |
parent | 4c9d5f80c1f84e66c7a6bde7bf370f199abbf4ee (diff) | |
parent | 5861c6dc172ec508ca85eaff437a2a6bab8825aa (diff) | |
download | mariadb-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.h | 8 | ||||
-rw-r--r-- | innobase/row/row0sel.c | 18 | ||||
-rw-r--r-- | mysql-test/r/index_merge_innodb.result | 68 | ||||
-rw-r--r-- | mysql-test/t/index_merge_innodb.test | 68 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 8 | ||||
-rw-r--r-- | sql/opt_range.cc | 10 |
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++; |