Below is the list of changes that have just been committed into a local
5.1 repository of martin. When martin does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-01-11 12:18:06+01:00, mhansson@stripped +3 -0
BUG # 20604
Fixed
The function that checks whether we can use keys for aggregates,
find_key_for_maxmin(), fails to check that keys are not disabled by
ALTER TABLE.
The fact that keys are disabled does not reveal itself in
keys_in_use_for_query, but rather in a field in its "table share", called
keys_in_use. The reasoning behind this is most likely that
a DISABLE KEYS is set on table level, as opposed to a
particular projection of a table.
Table level objects are known as "table shares" inside the code.
Projections of tables are known in the code as a "table".
Hence the set of indexes that can be used are the intersection of
those that this particular "table" object permits using and those that
the "table share" permits using.
mysql-test/r/key.result@stripped, 2007-01-11 12:18:04+01:00, mhansson@stripped +7 -0
This is the correct output for this query. It isn't actually that important because
this
set of commands will actually cause a failure to be reported from MyISAM when the bug
is active.
mysql-test/t/key.test@stripped, 2007-01-11 12:18:04+01:00, mhansson@stripped +11 -0
The minimal test case that reveals the bug. The optimizer for aggregates did not take
into account that keys might be the disabled on a table. The execution engine then
tries
to proceed and use the index, causing MyISAM to crash.
sql/opt_sum.cc@stripped, 2007-01-11 12:18:04+01:00, mhansson@stripped +3 -1
This shows where the aggregate optimizer decides which indexes it is free to use.
The comment preceding "if (!enabled_keys.is_set(idx))" was actually incorrect, because
the algorithm
did not look at whether keys where disabled via ALTER TABLE or not.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: mhansson
# Host: linux-st28.site
# Root: /home/martin/mysql/src/5.1o-dbg-bug20604
--- 1.58/sql/opt_sum.cc 2006-10-18 10:47:17 +02:00
+++ 1.59/sql/opt_sum.cc 2007-01-11 12:18:04 +01:00
@@ -743,6 +743,8 @@
uint idx= 0;
KEY *keyinfo,*keyinfo_end;
+ key_map enabled_keys= table->s->keys_in_use;
+ enabled_keys.intersect(table->keys_in_use_for_query);
for (keyinfo= table->key_info, keyinfo_end= keyinfo+table->s->keys ;
keyinfo != keyinfo_end;
keyinfo++,idx++)
@@ -753,7 +755,7 @@
Perform a check if index is not disabled by ALTER TABLE
or IGNORE INDEX.
*/
- if (!table->keys_in_use_for_query.is_set(idx))
+ if (!enabled_keys.is_set(idx))
continue;
uint jdx= 0;
*prefix_len= 0;
--- 1.40/mysql-test/r/key.result 2006-08-11 23:06:20 +02:00
+++ 1.41/mysql-test/r/key.result 2007-01-11 12:18:04 +01:00
@@ -482,3 +482,10 @@
alter table t1 add index i3 (c3), add index i2 (c2), add unique index i1 (c1);
ERROR 23000: Duplicate entry '1' for key 'i1'
drop table t1;
+CREATE TABLE t1( a TINYINT, KEY(a) ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES( 1 );
+ALTER TABLE t1 DISABLE KEYS;
+SELECT MAX(a) FROM t1 FORCE INDEX(a);
+MAX(a)
+1
+drop table t1;
--- 1.31/mysql-test/t/key.test 2006-07-20 20:41:52 +02:00
+++ 1.32/mysql-test/t/key.test 2007-01-11 12:18:04 +01:00
@@ -442,3 +442,14 @@
alter table t1 add index i3 (c3), add index i2 (c2), add unique index i1 (c1);
drop table t1;
+#
+# Bug #20604: Test for disabled keys with aggregate functions and FORCE INDEX.
+#
+
+CREATE TABLE t1( a TINYINT, KEY(a) ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES( 1 );
+ALTER TABLE t1 DISABLE KEYS;
+SELECT MAX(a) FROM t1 FORCE INDEX(a);
+
+drop table t1;
+
| Thread |
|---|
| • bk commit into 5.1 tree (mhansson:1.2359) BUG#20604 | mhansson | 11 Jan |