List:Commits« Previous MessageNext Message »
From:marko.makela Date:June 6 2012 5:24pm
Subject:bzr push into mysql-trunk-wl6255 branch (marko.makela:3946 to 3950) WL#6255
View as plain text  
 3950 Marko Mäkelä	2012-06-06
      WL#6255 rb:1105 Problem 6:
      
      Skip online rebuild log apply on fulltext indexes.

    modified:
      storage/innobase/row/row0log.cc
 3949 Marko Mäkelä	2012-06-06
      WL#6255 FTS_DOC_ID safety changes.
      
      ha_innobase::check_if_supported_inplace_alter(): Do not support inplace
      DDL operations that involve dropping or renaming FTS_DOC_ID or dropping
      FTS_DOC_ID_INDEX when FULLTEXT indexes are supposed to survive the operation.

    modified:
      mysql-test/suite/innodb/r/innodb-alter.result
      mysql-test/suite/innodb/t/innodb-alter.test
      storage/innobase/handler/handler0alter.cc
 3948 Marko Mäkelä	2012-06-06
      WL#5534 extension: Add FIELD_IS_DROPPED for indicating DROP COLUMN.
      
      fill_alter_inplace_info(): Initialize FIELD_IS_DROPPED in the same
      loop as FIELD_IS_RENAMED.
      
      Approved by Jon Olav Hauglid on IM.

    modified:
      include/mysql_com.h
      sql/sql_table.cc
 3947 Marko Mäkelä	2012-06-06
      WL#5526 bug fixes.
      
      prepare_inplace_alter_table_dict(),
      ha_innobase::prepare_inplace_alter_table(): Do not invoke fts_create()
      until it is really needed.
      
      rollback_inplace_alter_table(): If a full-text index does not survive the
      rollback, invoke fts_free().

    modified:
      storage/innobase/handler/handler0alter.cc
 3946 Marko Mäkelä	2012-06-06
      WL#6255 cleanup and fix for ADD COLUMN b, ADD PRIMARY KEY (a, c)
      
      row_log_t: Add add_cols, col_map.
      
      row_log_allocate(): Add the parameters add_cols, col_map.
      
      row_log_table_apply(), row_log_table_apply_ops(): Remove the
      parameters add_cols, col_map.
      
      row_log_table_apply_convert_mrec(), row_log_table_apply_insert(),
      row_log_table_apply_update(): Replace the parameters add_cols,
      col_map, new_table with row_log_t log.
      
      row_log_table_apply_op(): Remove the parameters new_table, add_cols,
      col_map.
      
      row_log_table_get_pk(): Map added and reordered columns.
      
      ha_innobase::check_if_supported_inplace_alter(): Initialize key_part->field
      to table->field[], or to altered_table->field[] for ADD COLUMN.

    modified:
      mysql-test/suite/innodb/r/innodb-table-online.result
      mysql-test/suite/innodb/t/innodb-table-online.test
      storage/innobase/handler/handler0alter.cc
      storage/innobase/include/row0log.h
      storage/innobase/row/row0log.cc
=== modified file 'include/mysql_com.h'
--- a/include/mysql_com.h	revid:marko.makela@strippedm6qwwud13rsc
+++ b/include/mysql_com.h	revid:marko.makela@oracle.com-20120606163922-o842n0k9q4h1jmr2
@@ -123,6 +123,7 @@ enum enum_server_command
 #define FIELD_FLAGS_STORAGE_MEDIA_MASK (3 << FIELD_FLAGS_STORAGE_MEDIA)
 #define FIELD_FLAGS_COLUMN_FORMAT 24    /* Field column format, bit 24-25 */
 #define FIELD_FLAGS_COLUMN_FORMAT_MASK (3 << FIELD_FLAGS_COLUMN_FORMAT)
+#define FIELD_IS_DROPPED (1<< 26)       /* Intern: Field is being dropped */
 
 #define REFRESH_GRANT		1	/* Refresh grant tables */
 #define REFRESH_LOG		2	/* Start on new log file */

=== modified file 'mysql-test/suite/innodb/r/innodb-alter.result'
--- a/mysql-test/suite/innodb/r/innodb-alter.result	revid:marko.makela@stripped
+++ b/mysql-test/suite/innodb/r/innodb-alter.result	revid:marko.makela@stripped
@@ -450,15 +450,44 @@ ALTER TABLE t1o CHANGE c1 DB_TRX_ID INT;
 ERROR 42000: Incorrect column name 'DB_TRX_ID'
 ALTER TABLE t1o CHANGE c1 db_roll_ptr INT;
 ERROR 42000: Incorrect column name 'DB_ROLL_PTR'
+ALTER TABLE t1o ADD COLUMN DB_TRX_ID INT;
+ERROR 42000: Incorrect column name 'DB_TRX_ID'
+ALTER TABLE t1o ADD COLUMN db_roll_ptr INT;
+ERROR 42000: Incorrect column name 'db_roll_ptr'
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN FTS_DOC_ID BIGINT;
+ERROR HY000: Column 'FTS_DOC_ID' is of wrong type for an InnoDB FULLTEXT index
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED;
+ERROR HY000: Column 'FTS_DOC_ID' is of wrong type for an InnoDB FULLTEXT index
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN FTS_DOC_ID INT;
+ERROR 42S21: Duplicate column name 'FTS_DOC_ID'
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, ALGORITHM=INPLACE;
+ERROR 42000: This version of MySQL doesn't yet support 'ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, ALGORITHM=INPLACE'
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, DROP INDEX ct, ALGORITHM=INPLACE;
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN cu TEXT;
+Warnings:
+Warning	124	InnoDB rebuilding table to add column FTS_DOC_ID
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu), ADD COLUMN FTS_DOC_ID BIGINT;
+ERROR HY000: Column 'FTS_DOC_ID' is of wrong type for an InnoDB FULLTEXT index
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu), ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED;
+ERROR HY000: Column 'FTS_DOC_ID' is of wrong type for an InnoDB FULLTEXT index
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu),
+ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+ERROR HY000: InnoDB presently supports one FULLTEXT index creation at a time
+ALTER TABLE t1o ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, ALGORITHM=INPLACE;
+ERROR 42000: This version of MySQL doesn't yet support 'ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, ALGORITHM=INPLACE'
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID;
 ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID INT,
 ALGORITHM=COPY;
 ERROR 42000: Incorrect column name 'FTS_DOC_ID'
 ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID INT,
 ALGORITHM=INPLACE;
-ERROR HY000: Column 'FTS_DOC_ID' is of wrong type for an InnoDB FULLTEXT index
+ERROR 42000: Incorrect column name 'FTS_DOC_ID'
 ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_Doc_ID INT,
 ALGORITHM=INPLACE;
-ERROR 42000: Incorrect column name 'FTS_Doc_ID'
+ERROR 42000: Incorrect column name 'FTS_DOC_ID'
 ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
 CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
 ALGORITHM=INPLACE;
@@ -467,8 +496,6 @@ CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT
 ALGORITHM=INPLACE'
 CREATE TABLE t1n LIKE t1o;
 ALTER TABLE t1n ADD FULLTEXT INDEX(ct);
-Warnings:
-Warning	124	InnoDB rebuilding table to add column FTS_DOC_ID
 ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT, ALGORITHM=INPLACE;
 ERROR 42000: Incorrect column name 'FTS_DOC_ID'
 ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT, ALGORITHM=COPY;
@@ -485,8 +512,10 @@ t1n	CREATE TABLE `t1n` (
   `c2` int(11) NOT NULL DEFAULT '0',
   `ct` int(11) DEFAULT NULL,
   `c1` text,
+  `cu` text,
   PRIMARY KEY (`c2`),
-  FULLTEXT KEY `ct` (`c1`)
+  FULLTEXT KEY `ct` (`c1`),
+  FULLTEXT KEY `ct_2` (`c1`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
 ALTER TABLE t1n CHANGE c2 c1 INT, CHANGE ct c2 INT, CHANGE c1 ct TEXT,
 ALGORITHM=COPY;
@@ -496,8 +525,10 @@ t1n	CREATE TABLE `t1n` (
   `c1` int(11) NOT NULL DEFAULT '0',
   `c2` int(11) DEFAULT NULL,
   `ct` text,
+  `cu` text,
   PRIMARY KEY (`c1`),
-  FULLTEXT KEY `ct` (`ct`)
+  FULLTEXT KEY `ct` (`ct`),
+  FULLTEXT KEY `ct_2` (`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
@@ -510,9 +541,11 @@ t1n	CREATE TABLE `t1n` (
   `c1` int(11) NOT NULL DEFAULT '0',
   `c4` int(11) DEFAULT NULL,
   `ct` text,
+  `cu` text,
   PRIMARY KEY (`c1`),
   KEY `c4` (`c4`),
-  FULLTEXT KEY `ct` (`ct`)
+  FULLTEXT KEY `ct` (`ct`),
+  FULLTEXT KEY `ct_2` (`ct`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
 ALTER TABLE t1n DROP INDEX c4;
 ALTER TABLE t1n CHANGE c4 c1 INT, ADD INDEX(c1), ALGORITHM=INPLACE;
@@ -524,17 +557,21 @@ t1n	CREATE TABLE `t1n` (
   `c1` int(11) NOT NULL DEFAULT '0',
   `c11` int(11) DEFAULT NULL,
   `ct` text,
+  `cu` text,
   PRIMARY KEY (`c1`),
   KEY `c11` (`c11`),
-  FULLTEXT KEY `ct` (`ct`)
+  FULLTEXT KEY `ct` (`ct`),
+  FULLTEXT KEY `ct_2` (`ct`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
 DROP TABLE t1n;
-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,
+ALTER TABLE t1o MODIFY c1 BIGINT UNSIGNED NOT NULL, DROP INDEX ct;
+ALTER TABLE t1o CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
 ALGORITHM=INPLACE;
-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
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ALGORITHM=INPLACE;
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+ERROR 42000: This version of MySQL doesn't yet support 'ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE'
 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
@@ -547,6 +584,7 @@ t1o	CREATE TABLE `t1o` (
   `FTS_DOC_ID` bigint(20) unsigned NOT NULL,
   `c2` int(11) DEFAULT NULL,
   `ct` text,
+  `cu` text,
   PRIMARY KEY (`FTS_DOC_ID`),
   FULLTEXT KEY `ct` (`ct`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
@@ -558,6 +596,7 @@ t1o	CREATE TABLE `t1o` (
   `foo_id` bigint(20) unsigned NOT NULL,
   `c2` int(11) DEFAULT NULL,
   `ct` text,
+  `cu` text,
   PRIMARY KEY (`foo_id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
 DROP TABLE t1c, t1p, sys_tables, sys_indexes, sys_foreign;
@@ -574,6 +613,7 @@ NAME	POS	MTYPE	PRTYPE	LEN
 foo_id	0	6	1800	8
 c2	1	6	1027	4
 ct	2	5	524540	10
+cu	3	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
@@ -591,8 +631,10 @@ ADD FULLTEXT INDEX(ct);
 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;
 CREATE FULLTEXT INDEX ct ON t1o (ct);
-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
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+ERROR 42000: This version of MySQL doesn't yet support 'ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE'
 DROP TABLE sys_indexes;
 CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
 INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
@@ -603,6 +645,7 @@ NAME	POS	MTYPE	PRTYPE	LEN
 FTS_DOC_ID	0	6	1800	8
 c2	1	6	1027	4
 ct	2	5	524540	10
+cu	3	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

=== modified file 'mysql-test/suite/innodb/t/innodb-alter.test'
--- a/mysql-test/suite/innodb/t/innodb-alter.test	revid:marko.makela@stripped21-w1upm6qwwud13rsc
+++ b/mysql-test/suite/innodb/t/innodb-alter.test	revid:marko.makela@stripped-o842n0k9q4h1jmr2
@@ -203,6 +203,50 @@ ALTER TABLE t1o CHANGE c1 dB_row_Id INT,
 ALTER TABLE t1o CHANGE c1 DB_TRX_ID INT;
 --error ER_WRONG_COLUMN_NAME
 ALTER TABLE t1o CHANGE c1 db_roll_ptr INT;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o ADD COLUMN DB_TRX_ID INT;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o ADD COLUMN db_roll_ptr INT;
+
+--error ER_INNODB_FT_WRONG_DOCID_COLUMN
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN FTS_DOC_ID BIGINT;
+--error ER_INNODB_FT_WRONG_DOCID_COLUMN
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED;
+
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+
+--error ER_DUP_FIELDNAME
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN FTS_DOC_ID INT;
+
+--error ER_NOT_SUPPORTED_YET
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, ALGORITHM=INPLACE;
+
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, DROP INDEX ct, ALGORITHM=INPLACE;
+
+# This creates a hidden FTS_DOC_ID column.
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN cu TEXT;
+
+--error ER_INNODB_FT_WRONG_DOCID_COLUMN
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu), ADD COLUMN FTS_DOC_ID BIGINT;
+--error ER_INNODB_FT_WRONG_DOCID_COLUMN
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu), ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED;
+
+# This would drop the hidden FTS_DOC_ID column and create
+# a fulltext index on ct and another fulltext index on cu.
+--error ER_INNODB_FT_LIMIT
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu),
+ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+
+# Replace the hidden FTS_DOC_ID column with a user-visible one.
+# This works if there is at most one fulltext index.
+ALTER TABLE t1o ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+
+# Replace the user-visible FTS_DOC_ID column with a hidden one.
+# We do not support this in-place.
+--error ER_NOT_SUPPORTED_YET
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, ALGORITHM=INPLACE;
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID;
 
 # FTS_DOC_ID is the internal row identifier for full-text search.
 # It should be of type BIGINT UNSIGNED NOT NULL.
@@ -210,7 +254,7 @@ ALTER TABLE t1o CHANGE c1 db_roll_ptr IN
 ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID INT,
 ALGORITHM=COPY;
 
---error ER_INNODB_FT_WRONG_DOCID_COLUMN
+--error ER_WRONG_COLUMN_NAME
 ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID INT,
 ALGORITHM=INPLACE;
 --error ER_WRONG_COLUMN_NAME
@@ -254,14 +298,16 @@ ALTER TABLE t1n CHANGE c4 c11 INT, ADD I
 SHOW CREATE TABLE t1n;
 DROP TABLE t1n;
 
-ALTER TABLE t1o MODIFY c1 BIGINT UNSIGNED NOT NULL;
+ALTER TABLE t1o MODIFY c1 BIGINT UNSIGNED NOT NULL, DROP INDEX ct;
 
-ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
-CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ALTER TABLE t1o 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;
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ALGORITHM=INPLACE;
+
+--error ER_NOT_SUPPORTED_YET
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
 
 # This should not show duplicates.
 SELECT sc.pos FROM information_schema.innodb_sys_columns sc
@@ -307,8 +353,9 @@ ADD FULLTEXT INDEX(ct);
 ALTER TABLE t1o CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
 CREATE FULLTEXT INDEX ct ON t1o (ct);
 
---error ER_INNODB_FT_WRONG_DOCID_COLUMN
-ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL;
+--error ER_NOT_SUPPORTED_YET
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
 
 DROP TABLE sys_indexes;
 CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	revid:marko.makela@stripped-20120605213921-w1upm6qwwud13rsc
+++ b/sql/sql_table.cc	revid:marko.makela@strippedmr2
@@ -5380,7 +5380,7 @@ static bool fill_alter_inplace_info(THD
   for (f_ptr= table->field; (field= *f_ptr); f_ptr++)
   {
     /* Clear marker for renamed field which we are going to set later. */
-    field->flags&= ~FIELD_IS_RENAMED;
+    field->flags&= ~(FIELD_IS_RENAMED | FIELD_IS_DROPPED);
 
     /* Use transformed info to evaluate flags for storage engine. */
     uint new_field_index= 0;
@@ -5478,6 +5478,7 @@ static bool fill_alter_inplace_info(THD
         Corresponding storage engine flag should be already set.
       */
       DBUG_ASSERT(ha_alter_info->handler_flags & Alter_inplace_info::DROP_COLUMN);
+      field->flags|= FIELD_IS_DROPPED;
     }
   }
 

=== modified file 'storage/innobase/handler/handler0alter.cc'
--- a/storage/innobase/handler/handler0alter.cc	revid:marko.makela@stripped
+++ b/storage/innobase/handler/handler0alter.cc	revid:marko.makela@stripped
@@ -159,6 +159,24 @@ my_error_innodb(
 	}
 }
 
+/** 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);
+}
+
 /*******************************************************************//**
 Determine if ALTER TABLE needs to rebuild the table.
 @param ha_alter_info		the DDL operation
@@ -275,11 +293,63 @@ ha_innobase::check_if_supported_inplace_
 
 			key_part->field = new_field->field;
 
-			if (!new_field->field) {
-				DBUG_ASSERT(ha_alter_info->handler_flags
-					    & Alter_inplace_info::ADD_COLUMN);
-				key_part->field = altered_table->field[
-					key_part->fieldnr];
+			if (new_field->field) {
+				continue;
+			}
+
+			/* This is an added column. */
+			DBUG_ASSERT(ha_alter_info->handler_flags
+				    & Alter_inplace_info::ADD_COLUMN);
+			key_part->field = altered_table->field[
+				key_part->fieldnr];
+
+			/* We cannot replace a hidden FTS_DOC_ID
+			with a user-visible FTS_DOC_ID. */
+			if (prebuilt->table->fts
+			    && innobase_fulltext_exist(altered_table->s)
+			    && !my_strcasecmp(
+				    system_charset_info,
+				    key_part->field->field_name,
+				    FTS_DOC_ID_COL_NAME)) {
+				DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
+			}
+		}
+	}
+
+	DBUG_ASSERT(!prebuilt->table->fts || prebuilt->table->fts->doc_col
+		    <= table->s->fields);
+	DBUG_ASSERT(!prebuilt->table->fts || prebuilt->table->fts->doc_col
+		    < dict_table_get_n_user_cols(prebuilt->table));
+
+	if (prebuilt->table->fts
+	    && innobase_fulltext_exist(altered_table->s)) {
+		/* FULLTEXT indexes are supposed to remain. */
+		/* Disallow DROP INDEX FTS_DOC_ID_INDEX */
+
+		for (uint i = 0; i < ha_alter_info->index_drop_count; i++) {
+			if (!my_strcasecmp(
+				    system_charset_info,
+				    ha_alter_info->index_drop_buffer[i]->name,
+				    FTS_DOC_ID_INDEX_NAME)) {
+				DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
+			}
+		}
+
+		/* InnoDB can have a hidden FTS_DOC_ID_INDEX on a
+		visible FTS_DOC_ID column as well. Prevent dropping or
+		renaming the FTS_DOC_ID. */
+
+		for (Field** fp = table->field; *fp; fp++) {
+			if (!((*fp)->flags
+			      & (FIELD_IS_RENAMED | FIELD_IS_DROPPED))) {
+				continue;
+			}
+
+			if (!my_strcasecmp(
+				    system_charset_info,
+				    (*fp)->field_name,
+				    FTS_DOC_ID_COL_NAME)) {
+				DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
 			}
 		}
 	}
@@ -2527,6 +2597,12 @@ col_fail:
 		DBUG_ASSERT(!innobase_need_rebuild(ha_alter_info));
 		col_map = NULL;
 		add_cols = NULL;
+
+		if (!indexed_table->fts
+		    && innobase_fulltext_exist(altered_table->s)) {
+			indexed_table->fts = fts_create(indexed_table);
+			indexed_table->fts->doc_col = fts_doc_id_col;
+		}
 	}
 
 	/* Assign table_id, so that no table id of
@@ -2781,24 +2857,6 @@ err_exit:
 	DBUG_RETURN(true);
 }
 
-/** 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().
 
@@ -3300,9 +3358,6 @@ err_exit:
 				FTS_DOC_ID_COL_NAME);
 		} else if (fts_doc_col_no == ULINT_UNDEFINED) {
 			goto err_exit;
-		} else if (!prebuilt->table->fts) {
-			prebuilt->table->fts = fts_create(prebuilt->table);
-			prebuilt->table->fts->doc_col = fts_doc_col_no;
 		}
 
 		switch (innobase_fts_check_doc_id_index(
@@ -3313,9 +3368,6 @@ err_exit:
 		case FTS_INCORRECT_DOC_ID_INDEX:
 			my_error(ER_INNODB_FT_WRONG_DOCID_INDEX, MYF(0),
 				 FTS_DOC_ID_INDEX_NAME);
-			if (prebuilt->table->fts) {
-				fts_free(prebuilt->table);
-			}
 			goto err_exit;
 		case FTS_EXIST_DOC_ID_INDEX:
 			DBUG_ASSERT(doc_col_no == fts_doc_col_no
@@ -3548,6 +3600,11 @@ rollback_inplace_alter_table(
 		trx_start_for_ddl(ctx->trx, TRX_DICT_OP_INDEX);
 
 		row_merge_drop_indexes(ctx->trx, prebuilt->table, FALSE);
+
+		if (prebuilt->table->fts
+		    && !innobase_fulltext_exist(table_share)) {
+			fts_free(prebuilt->table);
+		}
 	}
 
 	trx_commit_for_mysql(ctx->trx);

=== modified file 'storage/innobase/row/row0log.cc'
--- a/storage/innobase/row/row0log.cc	revid:marko.makela@strippedwwud13rsc
+++ b/storage/innobase/row/row0log.cc	revid:marko.makela@stripped
@@ -1183,6 +1183,10 @@ row_log_table_apply_insert_low(
 			break;
 		}
 
+		if (index->type & DICT_FTS) {
+			continue;
+		}
+
 		entry = row_build_index_entry(row, NULL, index, heap);
 		error = row_ins_sec_index_entry_low(
 			flags, BTR_MODIFY_TREE,
@@ -1267,6 +1271,10 @@ row_log_table_apply_delete_low(
 	}
 
 	while ((index = dict_table_get_next_index(index)) != NULL) {
+		if (index->type & DICT_FTS) {
+			continue;
+		}
+
 		const dtuple_t*	entry = row_build_index_entry(
 			row, ext, index, heap);
 		mtr_start(mtr);
@@ -1616,6 +1624,10 @@ delete_insert:
 			break;
 		}
 
+		if (index->type & DICT_FTS) {
+			continue;
+		}
+
 		if (!row_upd_changes_ord_field_binary(
 			    index, update, thr, row, NULL)) {
 			continue;

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk-wl6255 branch (marko.makela:3946 to 3950) WL#6255marko.makela6 Jun