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