List:Commits« Previous MessageNext Message »
From:mhansson Date:January 22 2007 2:40pm
Subject:bk commit into 5.1 tree (mhansson:1.2359) BUG#20604
View as plain text  
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-22 15:40:44+01:00, mhansson@stripped +5 -0
  BUG # 20604: FORCE INDEX uses keys disabled by ALTER TABLE
  
  The function that checks whether we can use keys for aggregates,
  find_key_for_maxmin(), assumes that keys disabled by ALTER TABLE
  are not to be found in table->keys_in_use_for_query.
  
  The bug is that disabled keys still appear in keys_in_use_for_query,
  in the normal case. 
  
  The assumption for keys_is_use_for_query is as of now that disabled
  keys are _not_ included. This has also been put as a comment
  above the field.

  mysql-test/r/key.result@stripped, 2007-01-22 15:40:39+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-22 15:40:39+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/sql_base.cc@stripped, 2007-01-22 15:40:39+01:00, mhansson@stripped +1 -0
    This excludes the keys that were disabled with ALTER TABLE ... DISABLE_KEYS

  sql/sql_select.cc@stripped, 2007-01-22 15:40:39+01:00, mhansson@stripped +3 -4
    Corrected typo on line 2444.
    
    This operation is no longer necessary. The intersection operation 
    has already been performed in setup_tables.

  sql/table.h@stripped, 2007-01-22 15:40:39+01:00, mhansson@stripped +22 -2
    The semantics of TABLE::keys_in_use_for_query and TABLE_SHARE::keys_in_use was
    not commented before. After fixing this bug, we know that the claim in the new 
    comments hold.

# 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.368/sql/sql_base.cc	2006-12-04 20:02:33 +01:00
+++ 1.369/sql/sql_base.cc	2007-01-22 15:40:39 +01:00
@@ -5452,6 +5452,7 @@
     {
       key_map map;
       get_key_map_from_key_list(&map, table, table_list->use_index);
+      map.intersect(table->s->keys_in_use);
       if (map.is_set_all())
 	DBUG_RETURN(1);
       table->keys_in_use_for_query=map;

--- 1.473/sql/sql_select.cc	2006-11-30 21:38:09 +01:00
+++ 1.474/sql/sql_select.cc	2007-01-22 15:40:39 +01:00
@@ -2441,7 +2441,7 @@
 
   /* 
     Update info on indexes that can be used for search lookups as
-    reading const tables may has added new sargable predicates. 
+    reading const tables may have added new sargable predicates. 
   */
   if (const_count && sargables)
   {
@@ -12183,10 +12183,9 @@
   /*
     Check which keys can be used to resolve ORDER BY.
     We must not try to use disabled keys.
+    We must not consider keys that are disabled by IGNORE INDEX
   */
-  usable_keys= table->s->keys_in_use;
-  /* we must not consider keys that are disabled by IGNORE INDEX */
-  usable_keys.intersect(table->keys_in_use_for_query);
+  usable_keys= table->keys_in_use_for_query;
 
   for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
   {

--- 1.155/sql/table.h	2006-11-29 21:54:07 +01:00
+++ 1.156/sql/table.h	2007-01-22 15:40:39 +01:00
@@ -159,7 +159,11 @@
   LEX_STRING path;                	/* Path to .frm file (from datadir) */
   LEX_STRING normalized_path;		/* unpack_filename(path) */
   LEX_STRING connect_string;
-  key_map keys_in_use;                  /* Keys in use for table */
+
+  /* Set of keys in use for table, implemented as Bitmap.
+     Excludes keys disabled by ALTER TABLE ... DISABLE KEYS.
+   */
+  key_map keys_in_use;
   key_map keys_for_keyread;
   ha_rows min_rows, max_rows;		/* create information */
   ulong   avg_row_length;		/* create information */
@@ -180,6 +184,7 @@
   uint fields;				/* Number of fields */
   uint rec_buff_length;                 /* Size of table->record[] buffer */
   uint keys, key_parts;
+
   uint max_key_length, max_unique_length, total_key_length;
   uint uniques;                         /* Number of UNIQUE index */
   uint null_fields;			/* number of null fields */
@@ -314,7 +319,22 @@
   byte *write_row_record;		/* Used as optimisation in
 					   THD::write_row */
   byte *insert_values;                  /* used by INSERT ... UPDATE */
-  key_map quick_keys, used_keys, keys_in_use_for_query, merge_keys;
+
+  /*
+    A set of keys that can be used in the query where this table 
+    participates.
+
+    All indexes disabled on the table's TABLE_SHARE (see st_table.s)
+    will be subtracted from this set upon instantiation, i.e. for any 
+    st_table t it holds that t.keys_in_use_for_query is a subset of 
+    t.s.keys_in_use.
+
+    The set is implemented as a bitmap.
+   */
+  key_map keys_in_use_for_query;
+
+  key_map used_keys, quick_keys, merge_keys;
+
   KEY  *key_info;			/* data of keys in database */
 
   Field *next_number_field;		/* Set if next_number is activated */

--- 1.40/mysql-test/r/key.result	2006-08-11 23:06:20 +02:00
+++ 1.41/mysql-test/r/key.result	2007-01-22 15:40:39 +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-22 15:40:39 +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#20604mhansson22 Jan