summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgkodinov/kgeorge@magare.gmz <>2007-05-22 15:58:30 +0300
committergkodinov/kgeorge@magare.gmz <>2007-05-22 15:58:30 +0300
commit604ef46327cf0bb57f1fc4e7160783acd1707d54 (patch)
tree08d9d02d66f614e32a6d645cfda994fa73990360
parent4ac1e98630759c9b86bb73035b4f95cd6909a2a9 (diff)
downloadmariadb-git-604ef46327cf0bb57f1fc4e7160783acd1707d54.tar.gz
Bug #28476: force index on a disabled myisam index gives error 124
When processing the USE/FORCE index hints the optimizer was not checking if the indexes specified are enabled (see ALTER TABLE). Fixed by: Backporting the fix for bug 20604 to 5.0
-rw-r--r--mysql-test/r/key.result8
-rw-r--r--mysql-test/r/myisam.result26
-rw-r--r--mysql-test/t/key.test12
-rw-r--r--mysql-test/t/myisam.test16
-rw-r--r--sql/sql_base.cc7
-rw-r--r--sql/sql_select.cc7
-rw-r--r--sql/table.h23
7 files changed, 93 insertions, 6 deletions
diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result
index ec15eaa97f5..3abc95ec3bf 100644
--- a/mysql-test/r/key.result
+++ b/mysql-test/r/key.result
@@ -455,3 +455,11 @@ ORDER BY c.b, c.d
a b c d e f g h i j a b c d
2 2 1 2004-11-30 12:00:00 1 0 0 0 0 0 2 3388000 -553000 NULL
DROP TABLE t1, t2;
+CREATE TABLE t1( a TINYINT, KEY(a) ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES( 1 );
+ALTER TABLE t1 DISABLE KEYS;
+EXPLAIN SELECT MAX(a) FROM t1 FORCE INDEX(a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1
+DROP TABLE t1;
+End of 5.0 tests.
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 94f2f1f72b3..7fc29cd13ca 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -1780,4 +1780,30 @@ create table t3 (c1 int) engine=myisam pack_keys=default;
create table t4 (c1 int) engine=myisam pack_keys=2;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2' at line 1
drop table t1, t2, t3;
+CREATE TABLE t1(a INT, b INT, KEY inx (a), UNIQUE KEY uinx (b)) ENGINE=MyISAM;
+INSERT INTO t1(a,b) VALUES (1,1),(2,2),(3,3),(4,4),(5,5);
+SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
+a
+1
+ALTER TABLE t1 DISABLE KEYS;
+SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
+a
+1
+SELECT a FROM t1 USE INDEX (inx) WHERE a=1;
+a
+1
+SELECT b FROM t1 FORCE INDEX (uinx) WHERE b=1;
+b
+1
+SELECT b FROM t1 USE INDEX (uinx) WHERE b=1;
+b
+1
+SELECT a FROM t1 FORCE INDEX (inx,uinx) WHERE a=1;
+a
+1
+ALTER TABLE t1 ENABLE KEYS;
+SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
+a
+1
+DROP TABLE t1;
End of 5.0 tests
diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test
index e84b2071ab1..3d0e68dc0f3 100644
--- a/mysql-test/t/key.test
+++ b/mysql-test/t/key.test
@@ -432,3 +432,15 @@ ORDER BY c.b, c.d
;
DROP TABLE t1, t2;
+
+
+#
+# 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;
+EXPLAIN SELECT MAX(a) FROM t1 FORCE INDEX(a);
+DROP TABLE t1;
+
+--echo End of 5.0 tests.
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index 82d10059c65..12b9423be21 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -1145,4 +1145,20 @@ create table t3 (c1 int) engine=myisam pack_keys=default;
create table t4 (c1 int) engine=myisam pack_keys=2;
drop table t1, t2, t3;
+#
+# Bug#28476: force index on a disabled myisam index gives error 124
+#
+CREATE TABLE t1(a INT, b INT, KEY inx (a), UNIQUE KEY uinx (b)) ENGINE=MyISAM;
+INSERT INTO t1(a,b) VALUES (1,1),(2,2),(3,3),(4,4),(5,5);
+SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
+ALTER TABLE t1 DISABLE KEYS;
+SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
+SELECT a FROM t1 USE INDEX (inx) WHERE a=1;
+SELECT b FROM t1 FORCE INDEX (uinx) WHERE b=1;
+SELECT b FROM t1 USE INDEX (uinx) WHERE b=1;
+SELECT a FROM t1 FORCE INDEX (inx,uinx) WHERE a=1;
+ALTER TABLE t1 ENABLE KEYS;
+SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
+DROP TABLE t1;
+
--echo End of 5.0 tests
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 6e6611d54d2..59532b9fe96 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -4811,7 +4811,12 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
get_key_map_from_key_list(&map, table, table_list->use_index);
if (map.is_set_all())
DBUG_RETURN(1);
- table->keys_in_use_for_query=map;
+ /*
+ Don't introduce keys in keys_in_use_for_query that weren't there
+ before. FORCE/USE INDEX should not add keys, it should only remove
+ all keys except the key(s) specified in the hint.
+ */
+ table->keys_in_use_for_query.intersect(map);
}
if (table_list->ignore_index)
{
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index ea59cbbe9f2..607bbdc6cd6 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -12246,10 +12246,11 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
LINT_INIT(ref_key_parts);
/*
- Check which keys can be used to resolve ORDER BY.
- We must not try to use disabled keys.
+ Keys disabled by ALTER TABLE ... DISABLE KEYS should have already
+ been taken into account.
*/
- usable_keys= table->s->keys_in_use;
+ usable_keys= table->keys_in_use_for_query;
+ DBUG_ASSERT(usable_keys.is_subset(table->s->keys_in_use));
for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
{
diff --git a/sql/table.h b/sql/table.h
index 61232a39f0e..ebcafbd4dc7 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -137,7 +137,12 @@ typedef struct st_table_share
const char *table_name; /* Table name (for open) */
const char *path; /* Path to .frm file (from datadir) */
LEX_STRING connect_string;
- key_map keys_in_use; /* Keys in use for table */
+
+ /*
+ Set of keys in use, implemented as a Bitmap.
+ Excludes keys disabled by ALTER TABLE ... DISABLE KEYS.
+ */
+ key_map keys_in_use;
key_map keys_for_keyread;
ulong avg_row_length; /* create information */
ulong raid_chunksize;
@@ -206,7 +211,21 @@ struct st_table {
byte *record[2]; /* Pointer to records */
byte *insert_values; /* used by INSERT ... UPDATE */
- key_map quick_keys, used_keys, keys_in_use_for_query;
+ key_map quick_keys, used_keys;
+
+ /*
+ A set of keys that can be used in the query that references this
+ table
+
+ All indexes disabled on the table's TABLE_SHARE (see TABLE::s) will be
+ subtracted from this set upon instantiation. Thus for any TABLE t it holds
+ that t.keys_in_use_for_query is a subset of t.s.keys_in_use. Generally we
+ must not introduce any new keys here (see setup_tables).
+
+ The set is implemented as a bitmap.
+ */
+ key_map keys_in_use_for_query;
+ key_map merge_keys;
KEY *key_info; /* data of keys in database */
Field *next_number_field, /* Set if next_number is activated */