diff --git a/mysql-test/r/constraints.result b/mysql-test/r/constraints.result index d4d525c8991f502da8991bf80afed75985830507..e2fb060781944820dc92fd791d13f2d8081d84a2 100644 --- a/mysql-test/r/constraints.result +++ b/mysql-test/r/constraints.result @@ -22,8 +22,6 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) default NULL, - UNIQUE KEY `constraint_1` (`a`), - UNIQUE KEY `key_1` (`a`), - UNIQUE KEY `key_2` (`a`) + UNIQUE KEY `constraint_1` (`a`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index b5f7da30bb3ab4488ad31a6349013bf3b25bbac1..81a222c482a67c18bfb9a19f76335c47a6d82ad6 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -155,37 +155,7 @@ t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL default '0', `b` int(11) default NULL, PRIMARY KEY (`a`), - KEY `b` (`b`), - KEY `b_2` (`b`), - KEY `b_3` (`b`), - KEY `b_4` (`b`), - KEY `b_5` (`b`), - KEY `b_6` (`b`), - KEY `b_7` (`b`), - KEY `b_8` (`b`), - KEY `b_9` (`b`), - KEY `b_10` (`b`), - KEY `b_11` (`b`), - KEY `b_12` (`b`), - KEY `b_13` (`b`), - KEY `b_14` (`b`), - KEY `b_15` (`b`), - KEY `b_16` (`b`), - KEY `b_17` (`b`), - KEY `b_18` (`b`), - KEY `b_19` (`b`), - KEY `b_20` (`b`), - KEY `b_21` (`b`), - KEY `b_22` (`b`), - KEY `b_23` (`b`), - KEY `b_24` (`b`), - KEY `b_25` (`b`), - KEY `b_26` (`b`), - KEY `b_27` (`b`), - KEY `b_28` (`b`), - KEY `b_29` (`b`), - KEY `b_30` (`b`), - KEY `b_31` (`b`) + KEY `b` (`b`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; create table t1 select if(1,'1','0'), month("2002-08-02"); diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 3c36571a8c20589d574324f140d52e48537bd915..07445cc86d728e188cb105d65b2e9f25f92577ce 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -371,7 +371,6 @@ t1 0 PRIMARY 2 b A # NULL NULL BTREE t1 0 c 1 c A # NULL NULL BTREE t1 0 b 1 b A # NULL NULL BTREE t1 1 a 1 a A # NULL NULL BTREE -t1 1 a_2 1 a A # NULL NULL BTREE drop table t1; create table t1 (col1 int not null, col2 char(4) not null, primary key(col1)); alter table t1 engine=innodb; diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index d1a5dd00370b1268f1deff76baf365911c7340fc..290e72d3b55bcfce0043ac8809c2593749df044c 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -249,18 +249,14 @@ explain select count(*) from t1 where x in (1,2); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range x x 5 NULL 2 Using where; Using index drop table t1; -CREATE TABLE t1 (key1 int(11) NOT NULL default '0', KEY i1 (key1), KEY i2 (key1)); +CREATE TABLE t1 (key1 int(11) NOT NULL default '0', KEY i1 (key1)); INSERT INTO t1 VALUES (0),(0),(1),(1); CREATE TABLE t2 (keya int(11) NOT NULL default '0', KEY j1 (keya)); INSERT INTO t2 VALUES (0),(0),(1),(1),(2),(2); explain select * from t1, t2 where (t1.key1 <t2.keya + 1) and t2.keya=3; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref j1 j1 4 const 1 Using where; Using index -1 SIMPLE t1 ALL i1,i2 NULL NULL NULL 4 Range checked for each record (index map: 0x3) -explain select * from t1 force index(i2), t2 where (t1.key1 <t2.keya + 1) and t2.keya=3; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref j1 j1 4 const 1 Using where; Using index -1 SIMPLE t1 ALL i2 NULL NULL NULL 4 Range checked for each record (index map: 0x2) +1 SIMPLE t1 ALL i1 NULL NULL NULL 4 Range checked for each record (index map: 0x1) DROP TABLE t1,t2; CREATE TABLE t1 ( a int(11) default NULL, diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 51b1f34ee794393e84ff575c668be554e2dd531b..4665cd02ed837a0c21db9dfa14a4210ac7f13df7 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -197,12 +197,11 @@ drop table t1; # # bug #1172 # -CREATE TABLE t1 (key1 int(11) NOT NULL default '0', KEY i1 (key1), KEY i2 (key1)); +CREATE TABLE t1 (key1 int(11) NOT NULL default '0', KEY i1 (key1)); INSERT INTO t1 VALUES (0),(0),(1),(1); CREATE TABLE t2 (keya int(11) NOT NULL default '0', KEY j1 (keya)); INSERT INTO t2 VALUES (0),(0),(1),(1),(2),(2); explain select * from t1, t2 where (t1.key1 <t2.keya + 1) and t2.keya=3; -explain select * from t1 force index(i2), t2 where (t1.key1 <t2.keya + 1) and t2.keya=3; DROP TABLE t1,t2; # diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 1b4c8bec416cc17c09b5e17e0118204bf54896cb..f297ddf2917cc421519e2f1b2605f7dbf25b51eb 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -79,6 +79,34 @@ extern "C" void free_user_var(user_var_entry *entry) } +bool key_part_spec::operator==(const key_part_spec& other) const +{ + return length == other.length && !strcmp(field_name, other.field_name); +} + +/* Equality comparison of keys (ignoring name) */ +bool Key::operator==(Key& other) +{ + if (type == other.type && + algorithm == other.algorithm && + columns.elements == other.columns.elements) + { + List_iterator<key_part_spec> col_it1(columns); + List_iterator<key_part_spec> col_it2(other.columns); + const key_part_spec *col1, *col2; + while ((col1 = col_it1++)) + { + col2 = col_it2++; + DBUG_ASSERT(col2 != NULL); + if (!(*col1 == *col2)) + return false; + } + return true; + } + return false; +} + + /**************************************************************************** ** Thread specific functions ****************************************************************************/ diff --git a/sql/sql_class.h b/sql/sql_class.h index d5eb7a9fd0eb2356071e8d0bbc627701f8d4028e..a2094d8fe7c4b4b7dc936a17862d47a1a5596806 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -210,6 +210,7 @@ class key_part_spec :public Sql_alloc { const char *field_name; uint length; key_part_spec(const char *name,uint len=0) :field_name(name), length(len) {} + bool operator==(const key_part_spec& other) const; }; @@ -245,6 +246,8 @@ class Key :public Sql_alloc { :type(type_par), algorithm(alg_par), columns(cols), name(name_arg) {} ~Key() {} + /* Equality comparison of keys (ignoring name) */ + bool operator==(Key& other); }; class Table_ident; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0d0be1b7e1002ecf9d9283b6eb551b32439d8628..156c26924880685981efddbbef4ece2937b5c4e0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -639,12 +639,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, /* Create keys */ - List_iterator<Key> key_iterator(keys); + List_iterator<Key> key_iterator(keys), key_iterator2(keys); uint key_parts=0, fk_key_count=0; - List<Key> keys_in_order; // Add new keys here bool primary_key=0,unique_key=0; - Key *key; + Key *key, *key2; uint tmp, key_number; + /* special marker for keys to be ignored */ + static char ignore_key[1]; /* Calculate number of key segements */ *key_count= 0; @@ -677,7 +678,21 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, my_error(ER_TOO_LONG_IDENT, MYF(0), key->name); DBUG_RETURN(-1); } - key_parts+=key->columns.elements; + key_iterator2.rewind (); + while ((key2 = key_iterator2++) != key) + { + if (*key == *key2) + { + /* TO DO: issue warning message */ + /* mark that the key should be ignored */ + key->name=ignore_key; + break; + } + } + if (key->name != ignore_key) + key_parts+=key->columns.elements; + else + (*key_count)--; if (key->name && !tmp_table && !my_strcasecmp(system_charset_info,key->name,primary_key_name)) { @@ -704,6 +719,16 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, uint key_length=0; key_part_spec *column; + if (key->name == ignore_key) + { + /* ignore redundant keys */ + do + key=key_iterator++; + while (key && key->name == ignore_key); + if (!key) + break; + } + switch(key->type){ case Key::MULTIPLE: key_info->flags = 0; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0d499a300db076a6436c1c941b39ed955210deee..0693d33c781e228db34534871b8dd93e5504f5b5 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1200,12 +1200,14 @@ key_def: | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references { LEX *lex=Lex; - lex->key_list.push_back(new foreign_key($4, lex->col_list, + lex->key_list.push_back(new foreign_key($4 ? $4:$1, lex->col_list, $8, lex->ref_list, lex->fk_delete_opt, lex->fk_update_opt, lex->fk_match_option)); + lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4:$1, + HA_KEY_ALG_UNDEF, lex->col_list)); lex->col_list.empty(); /* Alloced by sql_alloc */ } | constraint opt_check_constraint