List:Commits« Previous MessageNext Message »
From:marko.makela Date:April 17 2012 2:08pm
Subject:bzr push into mysql-trunk-wl5545 branch (marko.makela:3890 to 3894)
View as plain text  
 3894 Marko Mäkelä	2012-04-17
      recv_recovery_from_checkpoint_start_func(): Remove a compiler warning.

    modified:
      storage/innobase/log/log0recv.cc
 3893 Marko Mäkelä	2012-04-17
      WL#5545 Allow multiple columns to be renamed to each other.
      Fix clashes with FTS_DOC_ID.
      
      merge_index_field_t: Replace field_name with col_no, so that
      column renaming will not interfere with index creation.
      
      dict_mem_table_col_rename(): Add the parameter nth_col, and remove the
      return status.
      
      innobase_create_key_defs(), prepare_inplace_alter_table_dict():
      Add the parameter fts_doc_id_col.
      
      innobase_fulltext_exist(): New predicated, for checking if a fulltext
      index exists on a table.
      
      ha_innobase::prepare_inplace_alter_table(): Prohibit renaming FTS_DOC_ID
      when fulltext indexes exist on the table. Prohibit renaming columns to
      internal column names defined in the InnoDB table object.
      
      innobase_rename_column(): Add the parameter nth_col. Rename the columns
      in the data dictionary based on old name and position.
      
      ha_innobase::commit_inplace_alter_table(): If an operation fails, roll
      back the data dictionary transaction.
      
      dict_table_get_index_by_max_id(): Merge with row_merge_dict_table_get_index(),
      and look up the columns by number, not by name.

    modified:
      mysql-test/suite/innodb/r/innodb-alter.result
      mysql-test/suite/innodb/t/innodb-alter.test
      storage/innobase/dict/dict0dict.cc
      storage/innobase/dict/dict0mem.cc
      storage/innobase/handler/handler0alter.cc
      storage/innobase/include/dict0dict.h
      storage/innobase/include/dict0mem.h
      storage/innobase/include/row0merge.h
      storage/innobase/row/row0merge.cc
 3892 Marko Mäkelä	2012-04-17
      Remove an extra initialization and add a debug assertion.

    modified:
      storage/innobase/include/row0upd.ic
 3891 Marko Mäkelä	2012-04-17
      Remove unused function innobase_create_fts_doc_id_idx().

    modified:
      storage/innobase/handler/handler0alter.cc
 3890 Marko Mäkelä	2012-04-16
      WL#5545: Test renaming to the reserved column names
      DB_ROW_ID, DB_TRX_ID, DB_ROLL_PTR.

    modified:
      mysql-test/suite/innodb/r/innodb-alter.result
      mysql-test/suite/innodb/t/innodb-alter.test
=== modified file 'mysql-test/suite/innodb/r/innodb-alter.result'
--- a/mysql-test/suite/innodb/r/innodb-alter.result	revid:marko.makela@strippedx9
+++ b/mysql-test/suite/innodb/r/innodb-alter.result	revid:marko.makela@stripped21
@@ -441,24 +441,93 @@ ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT
 ERROR 42000: Incorrect column name 'FTS_DOC_ID'
 ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT, ALGORITHM=COPY;
 ERROR 42000: Incorrect column name 'Fts_DOC_ID'
+ALTER TABLE t1n CHANGE FTS_DOC_ID c11 INT, ALGORITHM=INPLACE;
+ERROR 42S22: Unknown column 'FTS_DOC_ID' in 't1n'
 ALTER TABLE t1n CHANGE c1 FTS_DOC_ïD INT, ALGORITHM=INPLACE;
+ALTER TABLE t1n CHANGE FTS_DOC_ÏD c1 INT, ALGORITHM=INPLACE;
+ALTER TABLE t1n CHANGE c1 c2 INT, CHANGE c2 ct INT, CHANGE ct c1 TEXT,
+ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1n;
+Table	Create Table
+t1n	CREATE TABLE `t1n` (
+  `c2` int(11) NOT NULL DEFAULT '0',
+  `ct` int(11) DEFAULT NULL,
+  `c1` text,
+  PRIMARY KEY (`c2`),
+  FULLTEXT KEY `ct` (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1n CHANGE c2 c1 INT, CHANGE ct c2 INT, CHANGE c1 ct TEXT,
+ALGORITHM=COPY;
+SHOW CREATE TABLE t1n;
+Table	Create Table
+t1n	CREATE TABLE `t1n` (
+  `c1` int(11) NOT NULL DEFAULT '0',
+  `c2` int(11) DEFAULT NULL,
+  `ct` text,
+  PRIMARY KEY (`c1`),
+  FULLTEXT KEY `ct` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1n ADD INDEX(c2), CHANGE c2 c4 INT, ALGORITHM=INPLACE;
+ERROR 42000: Key column 'c2' doesn't exist in table
+ALTER TABLE t1n ADD INDEX(c2), CHANGE c2 c4 INT, ALGORITHM=COPY;
+ERROR 42000: Key column 'c2' doesn't exist in table
+ALTER TABLE t1n ADD INDEX(c4), CHANGE c2 c4 INT, ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1n;
+Table	Create Table
+t1n	CREATE TABLE `t1n` (
+  `c1` int(11) NOT NULL DEFAULT '0',
+  `c4` int(11) DEFAULT NULL,
+  `ct` text,
+  PRIMARY KEY (`c1`),
+  KEY `c4` (`c4`),
+  FULLTEXT KEY `ct` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1n DROP INDEX c4;
+ALTER TABLE t1n CHANGE c4 c1 INT, ADD INDEX(c1), ALGORITHM=INPLACE;
+ERROR 42S21: Duplicate column name 'c1'
+ALTER TABLE t1n CHANGE c4 c11 INT, ADD INDEX(c11), ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1n;
+Table	Create Table
+t1n	CREATE TABLE `t1n` (
+  `c1` int(11) NOT NULL DEFAULT '0',
+  `c11` int(11) DEFAULT NULL,
+  `ct` text,
+  PRIMARY KEY (`c1`),
+  KEY `c11` (`c11`),
+  FULLTEXT KEY `ct` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
 DROP TABLE t1n;
-ALTER TABLE t1o MODIFY c1 BIGINT NOT NULL;
-ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID BIGINT,
+ALTER TABLE t1o MODIFY c1 BIGINT UNSIGNED NOT NULL;
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
 ALGORITHM=INPLACE;
-ERROR HY000: Column 'FTS_DOC_ID' is of wrong type for an InnoDB FULLTEXT index
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL;
+ERROR HY000: Column 'foo_id' is of wrong type for an InnoDB FULLTEXT index
 SELECT sc.pos FROM information_schema.innodb_sys_columns sc
 INNER JOIN information_schema.innodb_sys_tables st
 ON sc.TABLE_ID=st.TABLE_ID
 WHERE st.NAME='test/t1o' AND sc.NAME='FTS_DOC_ID';
 pos
+0
+SHOW CREATE TABLE t1o;
+Table	Create Table
+t1o	CREATE TABLE `t1o` (
+  `FTS_DOC_ID` bigint(20) unsigned NOT NULL,
+  `c2` int(11) DEFAULT NULL,
+  `ct` text,
+  PRIMARY KEY (`FTS_DOC_ID`),
+  FULLTEXT KEY `ct` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+DROP INDEX ct, ALGORITHM=INPLACE;
+call mtr.add_suppression("InnoDB: Table test/t1o contains 2 indexes inside InnoDB, which is different from the number of indexes 1 defined in the MySQL");
 SHOW CREATE TABLE t1o;
 Table	Create Table
 t1o	CREATE TABLE `t1o` (
-  `c1` bigint(20) NOT NULL,
+  `foo_id` bigint(20) unsigned NOT NULL,
   `c2` int(11) DEFAULT NULL,
   `ct` text,
-  PRIMARY KEY (`c1`)
+  PRIMARY KEY (`foo_id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
 DROP TABLE t1c, t1p, sys_tables, sys_indexes, sys_foreign;
 CREATE TABLE sys_tables SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
@@ -471,14 +540,27 @@ SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.L
 FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
 INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
 NAME	POS	MTYPE	PRTYPE	LEN
-c1	0	6	1288	8
+foo_id	0	6	1800	8
 c2	1	6	1027	4
 ct	2	5	524540	10
 SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
 INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
 NAME	POS	NAME
-PRIMARY	0	c1
+PRIMARY	0	foo_id
+FTS_DOC_ID_INDEX	0	foo_id
 SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
 INNER JOIN sys_foreign sf ON i.ID = sf.ID;
 ID	FOR_COL_NAME	REF_COL_NAME	POS
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct);
+ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT index
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT index
+ALTER TABLE t1o CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(FTS_DOC_ID);
+ERROR 42000: Incorrect index name 'FTS_DOC_ID_INDEX'
+ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(FTS_DOC_ID),
+ALGORITHM=COPY;
+ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(FTS_DOC_ID);
+ERROR 42000: Duplicate key name 'FTS_DOC_ID_INDEX'
 DROP TABLE tt, t1o, sys_tables, sys_indexes, sys_foreign;

=== modified file 'mysql-test/suite/innodb/t/innodb-alter.test'
--- a/mysql-test/suite/innodb/t/innodb-alter.test	revid:marko.makela@stripped
+++ b/mysql-test/suite/innodb/t/innodb-alter.test	revid:marko.makela@oracle.com-20120417140601-q4xyu89kks7krh21
@@ -198,15 +198,41 @@ ALTER TABLE t1n ADD FULLTEXT INDEX(ct);
 ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT, ALGORITHM=INPLACE;
 --error ER_WRONG_COLUMN_NAME
 ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT, ALGORITHM=COPY;
+--error ER_BAD_FIELD_ERROR
+ALTER TABLE t1n CHANGE FTS_DOC_ID c11 INT, ALGORITHM=INPLACE;
 ALTER TABLE t1n CHANGE c1 FTS_DOC_ïD INT, ALGORITHM=INPLACE;
+
+ALTER TABLE t1n CHANGE FTS_DOC_ÏD c1 INT, ALGORITHM=INPLACE;
+ALTER TABLE t1n CHANGE c1 c2 INT, CHANGE c2 ct INT, CHANGE ct c1 TEXT,
+ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1n;
+ALTER TABLE t1n CHANGE c2 c1 INT, CHANGE ct c2 INT, CHANGE c1 ct TEXT,
+ALGORITHM=COPY;
+SHOW CREATE TABLE t1n;
+
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+ALTER TABLE t1n ADD INDEX(c2), CHANGE c2 c4 INT, ALGORITHM=INPLACE;
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+ALTER TABLE t1n ADD INDEX(c2), CHANGE c2 c4 INT, ALGORITHM=COPY;
+ALTER TABLE t1n ADD INDEX(c4), CHANGE c2 c4 INT, ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1n;
+ALTER TABLE t1n DROP INDEX c4;
+--error ER_DUP_FIELDNAME
+ALTER TABLE t1n CHANGE c4 c1 INT, ADD INDEX(c1), ALGORITHM=INPLACE;
+ALTER TABLE t1n CHANGE c4 c11 INT, ADD INDEX(c11), ALGORITHM=INPLACE;
+
+SHOW CREATE TABLE t1n;
 DROP TABLE t1n;
 
-ALTER TABLE t1o MODIFY c1 BIGINT NOT NULL;
+ALTER TABLE t1o MODIFY c1 BIGINT UNSIGNED NOT NULL;
 
---error ER_INNODB_FT_WRONG_DOCID_COLUMN
-ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID BIGINT,
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
 ALGORITHM=INPLACE;
 
+--error ER_INNODB_FT_WRONG_DOCID_COLUMN
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL;
+
 # This should not show duplicates.
 SELECT sc.pos FROM information_schema.innodb_sys_columns sc
 INNER JOIN information_schema.innodb_sys_tables st
@@ -215,6 +241,13 @@ WHERE st.NAME='test/t1o' AND sc.NAME='FT
 
 SHOW CREATE TABLE t1o;
 
+# This will leave an orphan FTS_DOC_ID_INDEX inside InnoDB.
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+DROP INDEX ct, ALGORITHM=INPLACE;
+call mtr.add_suppression("InnoDB: Table test/t1o contains 2 indexes inside InnoDB, which is different from the number of indexes 1 defined in the MySQL");
+
+SHOW CREATE TABLE t1o;
+
 DROP TABLE t1c, t1p, sys_tables, sys_indexes, sys_foreign;
 
 # Check the internal schemata of tt, t1o.
@@ -228,4 +261,30 @@ FROM INFORMATION_SCHEMA.INNODB_SYS_FOREI
 
 -- source suite/innodb/include/innodb_dict.inc
 
+# Now, there exists a hidden FTS_DOC_ID_INDEX on foo_id, not FTS_DOC_ID.
+# We must rename the foo_id to FTS_DOC_ID first.
+
+-- error ER_INNODB_FT_WRONG_DOCID_INDEX
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct);
+
+# Ideally, the renaming should work in the same statement with
+# the ADD FULLTEXT INDEX. This is what we get by defining FTS_DOC_ID
+# as a half-hidden column.
+-- error ER_INNODB_FT_WRONG_DOCID_INDEX
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+
+ALTER TABLE t1o CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+
+# InnoDB created FTS_DOC_ID_INDEX internally already.
+-- error ER_WRONG_NAME_FOR_INDEX
+ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(FTS_DOC_ID);
+
+# The ALGORITHM=COPY ignores the internally created index. */
+ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(FTS_DOC_ID),
+ALGORITHM=COPY;
+
+-- error ER_DUP_KEYNAME
+ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(FTS_DOC_ID);
+
 DROP TABLE tt, t1o, sys_tables, sys_indexes, sys_foreign;

=== modified file 'storage/innobase/dict/dict0dict.cc'
--- a/storage/innobase/dict/dict0dict.cc	revid:marko.makela@stripped20120416182457-jw98vli3ujodcmx9
+++ b/storage/innobase/dict/dict0dict.cc	revid:marko.makela@stripped601-q4xyu89kks7krh21
@@ -3150,65 +3150,6 @@ next_rec:
 }
 
 /**********************************************************************//**
-Returns an index object by matching on the name and column names and
-if more than one index matches return the index with the max id
-@return	matching index, NULL if not found */
-UNIV_INTERN
-dict_index_t*
-dict_table_get_index_by_max_id(
-/*===========================*/
-	dict_table_t*	table,	/*!< in: table */
-	const char*	name,	/*!< in: the index name to find */
-	const char**	columns,/*!< in: array of column names */
-	ulint		n_cols)	/*!< in: number of columns */
-{
-	dict_index_t*	index;
-	dict_index_t*	found;
-
-	found = NULL;
-	index = dict_table_get_first_index(table);
-
-	while (index != NULL) {
-		if (ut_strcmp(index->name, name) == 0
-		    && dict_index_get_n_ordering_defined_by_user(index)
-		    == n_cols) {
-
-			ulint		i;
-
-			for (i = 0; i < n_cols; i++) {
-				dict_field_t*	field;
-				const char*	col_name;
-
-				field = dict_index_get_nth_field(index, i);
-
-				col_name = dict_table_get_col_name(
-					table, dict_col_get_no(field->col));
-
-				if (0 != innobase_strcasecmp(
-					    columns[i], col_name)) {
-
-					break;
-				}
-			}
-
-			if (i == n_cols) {
-				/* We found a matching index, select
-				the index with the higher id*/
-
-				if (!found || index->id > found->id) {
-
-					found = index;
-				}
-			}
-		}
-
-		index = dict_table_get_next_index(index);
-	}
-
-	return(found);
-}
-
-/**********************************************************************//**
 Report an error in a foreign key definition. */
 static
 void

=== modified file 'storage/innobase/dict/dict0mem.cc'
--- a/storage/innobase/dict/dict0mem.cc	revid:marko.makela@strippedujodcmx9
+++ b/storage/innobase/dict/dict0mem.cc	revid:marko.makela@stripped
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -250,10 +250,10 @@ void
 dict_mem_table_col_rename_low(
 /*==========================*/
 	dict_table_t*	table,	/*!< in/out: table */
+	unsigned	i,	/*!< in: column offset corresponding to s */
 	const char*	from,	/*!< in: old column name */
 	const char*	to,	/*!< in: new column name */
-	const char*	s,	/*!< in: pointer to table->col_names */
-	unsigned	i)	/*!< in: column offset corresponding to s */
+	const char*	s)	/*!< in: pointer to table->col_names */
 {
 	size_t from_len = strlen(from), to_len = strlen(to);
 
@@ -357,33 +357,31 @@ dict_mem_table_col_rename_low(
 }
 
 /**********************************************************************//**
-Renames a column of a table in the data dictionary cache.
-@return whether the operation succeeded */
+Renames a column of a table in the data dictionary cache. */
 UNIV_INTERN
-bool
+void
 dict_mem_table_col_rename(
 /*======================*/
 	dict_table_t*	table,	/*!< in/out: table */
+	unsigned	nth_col,/*!< in: column index */
 	const char*	from,	/*!< in: old column name */
 	const char*	to)	/*!< in: new column name */
 {
-	unsigned	i;
 	const char*	s = table->col_names;
 
-	if (!s) {
-		return(false);
-	}
+	ut_ad(nth_col < table->n_def);
 
-	for (i = 0; i < table->n_def; i++) {
-		if (!strcmp(from, s)) {
-			dict_mem_table_col_rename_low(table, from, to, s, i);
-			return(true);
-		}
-
-		s += strlen(s) + 1;
+	for (unsigned i = 0; i < nth_col; i++) {
+		size_t	len = strlen(s);
+		ut_ad(len > 0);
+		s += len + 1;
 	}
 
-	return(false);
+	/* This could fail if the data dictionaries are out of sync.
+	Proceed with the renaming anyway. */
+	ut_ad(!strcmp(from, s));
+
+	dict_mem_table_col_rename_low(table, nth_col, from, to, s);
 }
 
 /**********************************************************************//**

=== modified file 'storage/innobase/handler/handler0alter.cc'
--- a/storage/innobase/handler/handler0alter.cc	revid:marko.makela@stripped-20120416182457-jw98vli3ujodcmx9
+++ b/storage/innobase/handler/handler0alter.cc	revid:marko.makela@stripped20417140601-q4xyu89kks7krh21
@@ -626,6 +626,8 @@ innobase_create_index_field_def(
 		: key_part->field;
 	ut_a(field);
 
+	index_field->col_no = key_part->fieldnr;
+
 	col_type = get_innobase_type_from_mysql_type(&is_unsigned, field);
 
 	if (DATA_BLOB == col_type
@@ -640,8 +642,6 @@ innobase_create_index_field_def(
 		index_field->prefix_len = 0;
 	}
 
-	index_field->field_name = mem_heap_strdup(heap, field->field_name);
-
 	DBUG_VOID_RETURN;
 }
 
@@ -935,6 +935,8 @@ innobase_create_key_defs(
 			/*!< in/out: number of indexes to be created */
 	bool				got_default_clust,
 			/*!< in: whether the table lacks a primary key */
+	ulint				fts_doc_id_col,
+			/*!< in: The column number for Doc ID */
 	bool				add_fts_doc_id,
 			/*!< in: whether we need to add new DOC ID
 			column for FTS index */
@@ -1057,13 +1059,14 @@ created_clustered:
 		index->fields = static_cast<merge_index_field_t*>(
 			mem_heap_alloc(heap, sizeof *index->fields));
 		index->n_fields = 1;
+		index->fields->col_no = fts_doc_id_col;
 		index->fields->prefix_len = 0;
-		index->fields->field_name = mem_heap_strdup(
-			heap, FTS_DOC_ID_COL_NAME);
 		index->ind_type = DICT_UNIQUE;
+
 		if (new_primary || add_fts_doc_id) {
 			index->name = mem_heap_strdup(
 				heap, FTS_DOC_ID_INDEX_NAME);
+			ut_ad(fts_doc_id_col == altered_table->s->fields);
 		} else {
 			char*	index_name;
 			index->name = index_name = static_cast<char*>(
@@ -1229,48 +1232,6 @@ no_match:
 #endif
 
 /********************************************************************//**
-This is to create FTS_DOC_ID_INDEX definition on the newly added Doc ID for
-the FTS indexes table
-@return	dict_index_t for the FTS_DOC_ID_INDEX */
-dict_index_t*
-innobase_create_fts_doc_id_idx(
-/*===========================*/
-	dict_table_t*	indexed_table,	/*!< in: Table where indexes are
-					created */
-	trx_t*		trx,		/*!< in: Transaction */
-	bool		new_clustered,	/*!< in: true if creating a
-					clustered index */
-	mem_heap_t*     heap)		/*!< Heap for index definitions */
-{
-	dict_index_t*		index;
-	merge_index_def_t	fts_index_def;
-	char*			index_name;
-
-	/* Create the temp index name for FTS_DOC_ID_INDEX */
-	fts_index_def.name = index_name = static_cast<char*>(
-		mem_heap_alloc(
-			heap, FTS_DOC_ID_INDEX_NAME_LEN + 1 + !new_clustered));
-	if (!new_clustered) {
-		*index_name++ = TEMP_INDEX_PREFIX;
-	}
-	memcpy(index_name, FTS_DOC_ID_INDEX_NAME,
-	       FTS_DOC_ID_INDEX_NAME_LEN);
-	index_name[FTS_DOC_ID_INDEX_NAME_LEN] = 0;
-
-	/* Only the Doc ID will be indexed */
-	fts_index_def.n_fields = 1;
-	fts_index_def.ind_type = DICT_UNIQUE;
-	fts_index_def.fields = static_cast<merge_index_field_t*>(
-		mem_heap_alloc(heap, sizeof *fts_index_def.fields));
-	fts_index_def.fields[0].prefix_len = 0;
-	fts_index_def.fields[0].field_name = mem_heap_strdup(
-		heap, FTS_DOC_ID_COL_NAME);
-
-	index = row_merge_create_index(trx, indexed_table, &fts_index_def);
-	return(index);
-}
-
-/********************************************************************//**
 Drop any indexes that we were not able to free previously due to
 open table handles. */
 static
@@ -1371,6 +1332,7 @@ while preparing ALTER TABLE.
 @param drop_foreign	Foreign key constraints to be dropped, or NULL
 @param n_drop_foreign	Number of foreign key constraints to drop
 @param num_fts_index	Number of full-text indexes to create
+@param fts_doc_id_col	The column number of FTS_DOC_ID
 @param add_fts_doc_id	Flag: add column FTS_DOC_ID?
 @param add_fts_doc_id_idx Flag: add index (FTS_DOC_ID)?
 
@@ -1392,6 +1354,7 @@ prepare_inplace_alter_table_dict(
 	dict_foreign_t**	drop_foreign,
 	ulint			n_drop_foreign,
 	unsigned		num_fts_index,
+	ulint			fts_doc_id_col,
 	bool			add_fts_doc_id,
 	bool			add_fts_doc_id_idx)
 {
@@ -1433,7 +1396,7 @@ prepare_inplace_alter_table_dict(
 	index_defs = innobase_create_key_defs(
 		heap, ha_alter_info, altered_table, n_add_index,
 		row_table_got_default_clust_index(indexed_table),
-		add_fts_doc_id, add_fts_doc_id_idx);
+		fts_doc_id_col, add_fts_doc_id, add_fts_doc_id_idx);
 
 	new_clustered = DICT_CLUSTERED & index_defs[0].ind_type;
 
@@ -1608,7 +1571,8 @@ col_fail:
 
 		if (add_fts_doc_id) {
 			fts_add_doc_id_column(indexed_table, heap);
-			indexed_table->fts->doc_col = altered_table->s->fields;
+			indexed_table->fts->doc_col = fts_doc_id_col;
+			ut_ad(fts_doc_id_col == altered_table->s->fields);
 		}
 
 		error = row_create_table_for_mysql(indexed_table, trx);
@@ -1875,6 +1839,24 @@ innobase_dropping_foreign(
 	return(false);
 }
 
+/** Determine if fulltext indexes exist in a given table.
+@param table_share	MySQL table
+@return			whether fulltext indexes exist on the table */
+static
+bool
+innobase_fulltext_exist(
+/*====================*/
+	const TABLE_SHARE*	table_share)
+{
+	for (uint i = 0; i < table_share->keys; i++) {
+		if (table_share->key_info[i].flags & HA_FULLTEXT) {
+			return(true);
+		}
+	}
+
+	return(false);
+}
+
 /** Allows InnoDB to update internal structures with concurrent
 writes blocked. Invoked before inplace_alter_table().
 
@@ -1900,6 +1882,7 @@ ha_innobase::prepare_inplace_alter_table
 	mem_heap_t*     heap;
 	int		error;
 	ulint		num_fts_index;
+	ulint		fts_doc_col_no;
 	bool		add_fts_doc_id		= false;
 	bool		add_fts_doc_id_idx	= false;
 
@@ -1963,8 +1946,7 @@ err_exit_no_heap:
 
 			const char* name = 0;
 
-			cf_it.init(ha_alter_info->alter_info
-				   ->create_list);
+			cf_it.init(ha_alter_info->alter_info->create_list);
 			while (Create_field* cf = cf_it++) {
 				if (cf->field == *fp) {
 					name = cf->field_name;
@@ -1974,9 +1956,28 @@ err_exit_no_heap:
 
 			ut_error;
 check_if_ok_to_rename:
+			/* Prohibit renaming a column from FTS_DOC_ID
+			if full-text indexes exist. */
+			if (!my_strcasecmp(system_charset_info,
+					   (*fp)->field_name,
+					   FTS_DOC_ID_COL_NAME)
+			    && innobase_fulltext_exist(altered_table->s)) {
+				my_error(ER_INNODB_FT_WRONG_DOCID_COLUMN,
+					 MYF(0), name);
+				goto err_exit_no_heap;
+			}
+
+			/* Prohibit renaming a column to an internal column. */
 			const char*	s = prebuilt->table->col_names;
+			unsigned j;
+			/* Skip user columns.
+			MySQL should have checked these already.
+			We want to allow renaming of c1 to c2, c2 to c1. */
+			for (j = 0; j < table->s->fields; j++) {
+				s += strlen(s) + 1;
+			}
 
-			for (unsigned i = 0; i < prebuilt->table->n_def; i++) {
+			for (; j < prebuilt->table->n_def; j++) {
 				if (!my_strcasecmp(
 					    system_charset_info, name, s)) {
 					my_error(ER_WRONG_COLUMN_NAME, MYF(0),
@@ -2226,10 +2227,10 @@ err_exit:
 	add a Doc ID hidden column and rebuild the primary index */
 	if (num_fts_index) {
 		ulint	doc_col_no;
-		ulint	fts_doc_col_no;
 
 		if (!innobase_fts_check_doc_id_col(
 			    prebuilt->table, altered_table, &fts_doc_col_no)) {
+			fts_doc_col_no = altered_table->s->fields;
 			add_fts_doc_id = true;
 			add_fts_doc_id_idx = true;
 
@@ -2270,6 +2271,7 @@ err_exit:
 			    prebuilt->trx, table_share->table_name.str,
 			    heap, drop_index, n_drop_index,
 			    drop_fk, n_drop_fk, num_fts_index,
+			    fts_doc_col_no,
 			    add_fts_doc_id, add_fts_doc_id_idx));
 }
 
@@ -2509,6 +2511,7 @@ innobase_drop_foreign(
 /** Rename a column.
 @param prebuilt		the prebuilt struct
 @param trx		data dictionary transaction
+@param nth_col		0-based index of the column
 @param from		old column name
 @param to		new column name
 @retval true		Failure
@@ -2519,9 +2522,13 @@ innobase_rename_column(
 /*===================*/
 	row_prebuilt_t*	prebuilt,
 	trx_t*		trx,
+	ulint		nth_col,
 	const char*	from,
 	const char*	to)
 {
+	pars_info_t*	info;
+	dberr_t		error;
+
 	DBUG_ENTER("innobase_rename_column");
 
 	DBUG_ASSERT(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX);
@@ -2531,94 +2538,156 @@ innobase_rename_column(
 	ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
 #endif /* UNIV_SYNC_DEBUG */
 
-	/* Rename the column in the data dictionary. */
-	static const char sql[] =
-		"PROCEDURE RENAME_COLUMN_PROC () IS\n"
-		"fid CHAR;\n"
-		"found INT;\n"
-
-		"DECLARE CURSOR index_cur IS\n"
-		" SELECT ID FROM SYS_INDEXES\n"
-		" WHERE TABLE_ID=:tableid;\n"
-
-		"DECLARE CURSOR for_cur IS\n"
-		" SELECT ID FROM SYS_FOREIGN\n"
-		" WHERE FOR_NAME=:table;\n"
-
-		"DECLARE CURSOR ref_cur IS\n"
-		" SELECT ID FROM SYS_FOREIGN\n"
-		" WHERE REF_NAME=:table;\n"
-
-		"BEGIN\n"
-		"found := 1;\n"
-		"OPEN index_cur;\n"
-		"WHILE found = 1 LOOP\n"
-		"  FETCH index_cur INTO fid;\n"
-		"  IF (SQL % NOTFOUND) THEN\n"
-		"    found := 0;\n"
-		"  ELSE\n"
-		"    UPDATE SYS_FIELDS SET COL_NAME=:new\n"
-		"    WHERE INDEX_ID=fid AND COL_NAME=:old;\n"
-		"  END IF;\n"
-		"END LOOP;\n"
-		"CLOSE index_cur;\n"
-
-		"UPDATE SYS_COLUMNS SET NAME=:new\n"
-		"WHERE TABLE_ID=:tableid AND NAME=:old;\n"
-
-		"found := 1;\n"
-		"OPEN for_cur;\n"
-		"WHILE found = 1 LOOP\n"
-		"  FETCH for_cur INTO fid;\n"
-		"  IF (SQL % NOTFOUND) THEN\n"
-		"    found := 0;\n"
-		"  ELSE\n"
-		"    UPDATE SYS_FOREIGN_COLS SET FOR_COL_NAME=:new\n"
-		"    WHERE ID=fid AND FOR_COL_NAME=:old;\n"
-		"  END IF;\n"
-		"END LOOP;\n"
-		"CLOSE for_cur;\n"
-
-		"found := 1;\n"
-		"OPEN ref_cur;\n"
-		"WHILE found = 1 LOOP\n"
-		"  FETCH ref_cur INTO fid;\n"
-		"  IF (SQL % NOTFOUND) THEN\n"
-		"    found := 0;\n"
-		"  ELSE\n"
-		"    UPDATE SYS_FOREIGN_COLS SET REF_COL_NAME=:new\n"
-		"    WHERE ID=fid AND REF_COL_NAME=:old;\n"
-		"  END IF;\n"
-		"END LOOP;\n"
-		"CLOSE ref_cur;\n"
-
-		"END;\n";
-	pars_info_t*	info	= pars_info_create();
-	dberr_t		error;
+	info = pars_info_create();
 
 	pars_info_add_ull_literal(info, "tableid", prebuilt->table->id);
-	pars_info_add_str_literal(info, "table", prebuilt->table->name);
+	pars_info_add_int4_literal(info, "nth", nth_col);
 	pars_info_add_str_literal(info, "old", from);
 	pars_info_add_str_literal(info, "new", to);
 
-	trx->op_info = "renaming column";
+	trx->op_info = "renaming column in SYS_COLUMNS";
 
-	error = que_eval_sql(info, sql, FALSE, trx);
-	trx->op_info = "";
+	error = que_eval_sql(
+		info,
+		"PROCEDURE RENAME_SYS_COLUMNS_PROC () IS\n"
+		"BEGIN\n"
+		"UPDATE SYS_COLUMNS SET NAME=:new\n"
+		"WHERE TABLE_ID=:tableid AND NAME=:old\n"
+		"AND POS=:nth;\n"
+
+		/* Try again, in case there is a prefix_len
+		encoded in SYS_COLUMNS.POS */
+
+		"UPDATE SYS_COLUMNS SET NAME=:new\n"
+		"WHERE TABLE_ID=:tableid AND NAME=:old\n"
+		"AND POS>=65536*:nth AND POS<65536*(:nth+1);\n"
+
+		"END;\n",
+		FALSE, trx);
 
 	if (error != DB_SUCCESS) {
+err_exit:
 		my_error_innodb(error, prebuilt->table->name, 0);
 		trx->error_state = DB_SUCCESS;
+		trx->op_info = "";
 		DBUG_RETURN(true);
 	}
 
-	/* Rename the column in the data dictionary cache. */
-	if (!dict_mem_table_col_rename(prebuilt->table, from, to)) {
-		DBUG_ASSERT(0);
-		my_error(ER_NOT_KEYFILE, MYF(0), prebuilt->table->name);
-		DBUG_RETURN(true);
+	trx->op_info = "renaming column in SYS_FIELDS";
+
+	for (dict_index_t* index = dict_table_get_first_index(prebuilt->table);
+	     index != NULL;
+	     index = dict_table_get_next_index(index)) {
+
+		for (ulint i = 0; i < dict_index_get_n_fields(index); i++) {
+			if (strcmp(dict_index_get_nth_field(index, i)->name,
+				   from)) {
+				continue;
+			}
+
+			info = pars_info_create();
+
+			pars_info_add_ull_literal(info, "indexid", index->id);
+			pars_info_add_int4_literal(info, "nth", i);
+			pars_info_add_str_literal(info, "old", from);
+			pars_info_add_str_literal(info, "new", to);
+
+			error = que_eval_sql(
+				info,
+				"PROCEDURE RENAME_SYS_FIELDS_PROC () IS\n"
+				"BEGIN\n"
+
+				"UPDATE SYS_FIELDS SET COL_NAME=:new\n"
+				"WHERE INDEX_ID=:indexid AND COL_NAME=:old\n"
+				"AND POS=:nth;\n"
+
+				/* Try again, in case there is a prefix_len
+				encoded in SYS_FIELDS.POS */
+
+				"UPDATE SYS_FIELDS SET COL_NAME=:new\n"
+				"WHERE INDEX_ID=:indexid AND COL_NAME=:old\n"
+				"AND POS>=65536*:nth AND POS<65536*(:nth+1);\n"
+
+				"END;\n",
+				FALSE, trx);
+
+			if (error != DB_SUCCESS) {
+				goto err_exit;
+			}
+		}
 	}
 
+	trx->op_info = "renaming column in SYS_FOREIGN_COLS";
+
+	for (dict_foreign_t* foreign = UT_LIST_GET_FIRST(
+		     prebuilt->table->foreign_list);
+	     foreign != NULL;
+	     foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
+		for (unsigned i = 0; i < foreign->n_fields; i++) {
+			if (strcmp(foreign->foreign_col_names[i], from)) {
+				continue;
+			}
+
+			info = pars_info_create();
+
+			pars_info_add_str_literal(info, "id", foreign->id);
+			pars_info_add_int4_literal(info, "nth", i);
+			pars_info_add_str_literal(info, "old", from);
+			pars_info_add_str_literal(info, "new", to);
+
+			error = que_eval_sql(
+				info,
+				"PROCEDURE RENAME_SYS_FOREIGN_F_PROC () IS\n"
+				"BEGIN\n"
+				"UPDATE SYS_FOREIGN_COLS\n"
+				"SET FOR_COL_NAME=:new\n"
+				"WHERE ID=:id AND POS=:nth\n"
+				"AND FOR_COL_NAME=:old;\n"
+				"END;\n",
+				FALSE, trx);
+
+			if (error != DB_SUCCESS) {
+				goto err_exit;
+			}
+		}
+	}
+
+	for (dict_foreign_t* foreign = UT_LIST_GET_FIRST(
+		     prebuilt->table->referenced_list);
+	     foreign != NULL;
+	     foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
+		for (unsigned i = 0; i < foreign->n_fields; i++) {
+			if (strcmp(foreign->referenced_col_names[i], from)) {
+				continue;
+			}
+
+			info = pars_info_create();
+
+			pars_info_add_str_literal(info, "id", foreign->id);
+			pars_info_add_int4_literal(info, "nth", i);
+			pars_info_add_str_literal(info, "old", from);
+			pars_info_add_str_literal(info, "new", to);
+
+			error = que_eval_sql(
+				info,
+				"PROCEDURE RENAME_SYS_FOREIGN_R_PROC () IS\n"
+				"BEGIN\n"
+				"UPDATE SYS_FOREIGN_COLS\n"
+				"SET REF_COL_NAME=:new\n"
+				"WHERE ID=:id AND POS=:nth\n"
+				"AND REF_COL_NAME=:old;\n"
+				"END;\n",
+				FALSE, trx);
+
+			if (error != DB_SUCCESS) {
+				goto err_exit;
+			}
+		}
+	}
+
+	trx->op_info = "";
+	/* Rename the column in the data dictionary cache. */
+	dict_mem_table_col_rename(prebuilt->table, nth_col, from, to);
 	DBUG_RETURN(false);
 }
 
@@ -2809,33 +2878,37 @@ ha_innobase::commit_inplace_alter_table(
 	    && (ha_alter_info->handler_flags
 		& Alter_inplace_info::ALTER_COLUMN_NAME)) {
 		List_iterator_fast<Create_field> cf_it;
+		uint i = 0;
+
+		for (Field** fp = table->field; *fp && err == 0; fp++, i++) {
+			if (!((*fp)->flags & FIELD_IS_RENAMED)) {
+				continue;
+			}
 
-		for (Field** fp = table->field; err == 0 && *fp; fp++) {
-			if ((*fp)->flags & FIELD_IS_RENAMED) {
-				cf_it.init(ha_alter_info->alter_info
-					   ->create_list);
-				while (Create_field* cf = cf_it++) {
-					if (cf->field == *fp) {
-						if (innobase_rename_column(
-							    prebuilt,
-							    trx,
-							    cf->field
-							    ->field_name,
-							    cf->field_name)) {
-							err = -1;
-						}
-						goto processed_field;
+			cf_it.init(ha_alter_info->alter_info->create_list);
+			while (Create_field* cf = cf_it++) {
+				if (cf->field == *fp) {
+					if (innobase_rename_column(
+						    prebuilt, trx, i,
+						    cf->field->field_name,
+						    cf->field_name)) {
+						err = -1;
 					}
+					goto processed_field;
 				}
-
-				ut_error;
 			}
+
+			ut_error;
 processed_field:
 			continue;
 		}
 	}
 
-	trx_commit_for_mysql(trx);
+	if (err == 0) {
+		trx_commit_for_mysql(trx);
+	} else {
+		trx_rollback_for_mysql(trx);
+	}
 
 	if (err == 0 && ctx) {
 		/* The changes were successfully performed. */

=== modified file 'storage/innobase/include/dict0dict.h'
--- a/storage/innobase/include/dict0dict.h	revid:marko.makela@strippedmx9
+++ b/storage/innobase/include/dict0dict.h	revid:marko.makela@stripped
@@ -542,19 +542,6 @@ dict_foreign_find_index(
 					NOT NULL */
 	__attribute__((nonnull(1,2), warn_unused_result));
 /**********************************************************************//**
-Returns an index object by matching on the name and column names and
-if more than one index matches return the index with the max id
-@return	matching index, NULL if not found */
-UNIV_INTERN
-dict_index_t*
-dict_table_get_index_by_max_id(
-/*===========================*/
-	dict_table_t*	table,	/*!< in: table */
-	const char*	name,	/*!< in: the index name to find */
-	const char**	columns,/*!< in: array of column names */
-	ulint		n_cols)	/*!< in: number of columns */
-	__attribute__((nonnull, warn_unused_result));
-/**********************************************************************//**
 Returns a column's name.
 @return column name. NOTE: not guaranteed to stay valid if table is
 modified in any way (columns added, etc.). */

=== modified file 'storage/innobase/include/dict0mem.h'
--- a/storage/innobase/include/dict0mem.h	revid:marko.makela@strippedujodcmx9
+++ b/storage/innobase/include/dict0mem.h	revid:marko.makela@stripped
@@ -253,13 +253,13 @@ dict_mem_table_add_col(
 	ulint		len)	/*!< in: precision */
 	__attribute__((nonnull(1)));
 /**********************************************************************//**
-Renames a column of a table in the data dictionary cache.
-@return whether the operation succeeded */
+Renames a column of a table in the data dictionary cache. */
 UNIV_INTERN
-bool
+void
 dict_mem_table_col_rename(
 /*======================*/
 	dict_table_t*	table,	/*!< in/out: table */
+	unsigned	nth_col,/*!< in: column index */
 	const char*	from,	/*!< in: old column name */
 	const char*	to)	/*!< in: new column name */
 	__attribute__((nonnull));

=== modified file 'storage/innobase/include/row0merge.h'
--- a/storage/innobase/include/row0merge.h	revid:marko.makela@strippedi3ujodcmx9
+++ b/storage/innobase/include/row0merge.h	revid:marko.makela@stripped1
@@ -96,9 +96,9 @@ typedef struct merge_file_struct	merge_f
 
 /** Index field definition */
 struct merge_index_field_struct {
+	ulint		col_no;		/*!< column offset */
 	ulint		prefix_len;	/*!< column prefix length, or 0
 					if indexing the whole column */
-	const char*	field_name;	/*!< field name */
 };
 
 /** Index field definition */

=== modified file 'storage/innobase/include/row0upd.ic'
--- a/storage/innobase/include/row0upd.ic	revid:marko.makela@stripped
+++ b/storage/innobase/include/row0upd.ic	revid:marko.makela@oracle.com-20120417140601-q4xyu89kks7krh21
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -45,7 +45,6 @@ upd_create(
 
 	update = (upd_t*) mem_heap_zalloc(heap, sizeof(upd_t));
 
-	update->info_bits = 0;
 	update->n_fields = n;
 	update->fields = (upd_field_t*)
 		mem_heap_zalloc(heap, sizeof(upd_field_t) * n);
@@ -110,6 +109,7 @@ upd_field_set_field_no(
 		fprintf(stderr, "\n"
 			"InnoDB: but index only has %lu fields\n",
 			(ulong) dict_index_get_n_fields(index));
+		ut_ad(0);
 	}
 
 	dict_col_copy_type(dict_index_get_nth_col(index, field_no),

=== modified file 'storage/innobase/log/log0recv.cc'
--- a/storage/innobase/log/log0recv.cc	revid:marko.makela@stripped
+++ b/storage/innobase/log/log0recv.cc	revid:marko.makela@strippedm-20120417140601-q4xyu89kks7krh21
@@ -2894,7 +2894,7 @@ recv_recovery_from_checkpoint_start_func
 	lsn_t		checkpoint_lsn;
 	ib_uint64_t	checkpoint_no;
 	lsn_t		old_scanned_lsn;
-	lsn_t		group_scanned_lsn;
+	lsn_t		group_scanned_lsn = 0;
 	lsn_t		contiguous_lsn;
 #ifdef UNIV_LOG_ARCHIVE
 	lsn_t		archived_lsn;

=== modified file 'storage/innobase/row/row0merge.cc'
--- a/storage/innobase/row/row0merge.cc	revid:marko.makela@strippedi3ujodcmx9
+++ b/storage/innobase/row/row0merge.cc	revid:marko.makela@stripped
@@ -798,30 +798,47 @@ row_merge_heap_create(
 Search an index object by name and column names.  If several indexes match,
 return the index with the max id.
 @return	matching index, NULL if not found */
-static
+static __attribute__((nonnull, warn_unused_result))
 dict_index_t*
 row_merge_dict_table_get_index(
 /*===========================*/
 	dict_table_t*		table,		/*!< in: table */
 	const merge_index_def_t*index_def)	/*!< in: index definition */
 {
-	ulint		i;
-	dict_index_t*	index;
-	const char**	column_names;
+	dict_index_t*	found	= NULL;
 
-	column_names = static_cast<const char**>(
-		mem_alloc(index_def->n_fields * sizeof *column_names));
+	found = NULL;
+	for (dict_index_t* index = dict_table_get_first_index(table);
+	     index != NULL;
+	     index = dict_table_get_next_index(index)) {
+
+		if (ut_strcmp(index->name, index_def->name) == 0
+		    && dict_index_get_n_ordering_defined_by_user(index)
+		    == index_def->n_fields) {
+
+			for (ulint i = 0; i < index_def->n_fields; i++) {
+				const dict_field_t*	field
+					= dict_index_get_nth_field(index, i);
+
+				if (dict_col_get_no(field->col) !=
+				    index_def->fields[i].col_no) {
+					goto next_index;
+				}
+			}
 
-	for (i = 0; i < index_def->n_fields; ++i) {
-		column_names[i] = index_def->fields[i].field_name;
-	}
+			/* We found a matching index, select
+			the index with the higher id*/
 
-	index = dict_table_get_index_by_max_id(
-		table, index_def->name, column_names, index_def->n_fields);
+			if (!found || index->id > found->id) {
 
-	mem_free((void*) column_names);
+				found = index;
+			}
+		}
+next_index:
+		continue;
+	}
 
-	return(index);
+	return(found);
 }
 
 /********************************************************************//**
@@ -3095,8 +3112,9 @@ row_merge_create_index(
 	for (i = 0; i < n_fields; i++) {
 		merge_index_field_t*	ifield = &index_def->fields[i];
 
-		dict_mem_index_add_field(index, ifield->field_name,
-					 ifield->prefix_len);
+		dict_mem_index_add_field(
+			index, dict_table_get_col_name(table, ifield->col_no),
+			ifield->prefix_len);
 	}
 
 	/* Add the index to SYS_INDEXES, using the index prototype. */

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk-wl5545 branch (marko.makela:3890 to 3894) marko.makela20 Apr