List:Commits« Previous MessageNext Message »
From:marko.makela Date:May 15 2012 7:25am
Subject:bzr push into mysql-trunk-wl6255 branch (marko.makela:3829 to 3833) WL#6255
View as plain text  
 3833 Marko Mäkelä	2012-05-15
      WL#6255 preparation: Split row_ins_index_entry(), row_ins_index_entry_low().
      
      row_ins_clust_index_entry(): Insert a clustered index entry.
      row_ins_sec_index_entry(): Insert a secondary index entry.
      
      row_ins_clust_index_entry_low(): Insert a clustered index entry.
      row_ins_sec_index_entry_low(): Insert a secondary index entry.
      
      Remove the parameter foreign=TRUE from all functions and n_ext=0
      from the insert into secondary index.

    modified:
      storage/innobase/ibuf/ibuf0ibuf.cc
      storage/innobase/include/row0ins.h
      storage/innobase/row/row0ins.cc
      storage/innobase/row/row0upd.cc
 3832 Marko Mäkelä	2012-05-15
      Add function attributes.

    modified:
      storage/innobase/include/btr0cur.h
 3831 Marko Mäkelä	2012-05-14
      WL#6255: Allow ROW_FORMAT and KEY_BLOCK_SIZE to be changed in-place.
      
      create_options_are_valid(): Rename to create_options_are_invalid(), and
      change the return type from ibool to const char*.
      
      INNOBASE_ONLINE_CREATE, INNOBASE_INPLACE_REBUILD: New sets of
      supported in-place ALTER TABLE operations.
      
      innobase_need_rebuild(): Determine if ALTER TABLE needs to rebuild the
      table. We ignore other CHANGE_CREATE_OPTION flags than KEY_BLOCK_SIZE
      and ROW_FORMAT.
      
      ha_innobase::check_if_supported_inplace_alter(): Allow all
      INNOBASE_INPLACE_REBUILD operations. Replace ADD_PK_INDEX with
      INNOBASE_INPLACE_REBUILD.
      
      innobase_create_key_defs(): Rebuild the clustered index for
      INNOBASE_INPLACE_REBUILD.
      
      ha_innobase::prepare_inplace_alter_table(): Call
      create_options_are_invalid().
      
      ha_innobase::inplace_alter_table(): If no other operations than
      CHANGE_CREATE_OPTION are being performed and !innobase_need_rebuild(),
      do nothing.

    modified:
      mysql-test/suite/innodb/r/innodb-create-options.result
      mysql-test/suite/innodb/t/innodb-create-options.test
      storage/innobase/handler/ha_innodb.cc
      storage/innobase/handler/ha_innodb.h
      storage/innobase/handler/handler0alter.cc
 3830 Marko Mäkelä	2012-05-14
      Branch mysql-trunk-wl6255 from mysql-trunk.

    modified:
      .bzr-mysql/default.conf
 3829 Jorgen Loland	2012-05-14
      Bug#11754168 list bug-id from new bug system instead of old bug
      system in default.experimental

    modified:
      mysql-test/collections/default.experimental
=== modified file '.bzr-mysql/default.conf'
--- a/.bzr-mysql/default.conf	revid:jorgen.loland@stripped20120514093058-4vd4gc1iosh2n6ba
+++ b/.bzr-mysql/default.conf	revid:marko.makela@strippedpemt6kzrn
@@ -1,4 +1,4 @@
 [MYSQL]
 post_commit_to = "commits@stripped"
 post_push_to = "commits@strippedl.com"
-tree_name = "mysql-trunk"
+tree_name = "mysql-trunk-wl6255"

=== modified file 'mysql-test/suite/innodb/r/innodb-create-options.result'
--- a/mysql-test/suite/innodb/r/innodb-create-options.result	revid:jorgen.loland@oracle.com-20120514093058-4vd4gc1iosh2n6ba
+++ b/mysql-test/suite/innodb/r/innodb-create-options.result	revid:marko.makela@stripped
@@ -46,11 +46,11 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTI
 TABLE_NAME	ROW_FORMAT	CREATE_OPTIONS
 t1	Compact	
 ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ROW_TYPE'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: invalid ROW_FORMAT specifier.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'ROW_TYPE'
 SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1';
 TABLE_NAME	ROW_FORMAT	CREATE_OPTIONS
 t1	Compact	
@@ -104,29 +104,29 @@ t1	Compressed	KEY_BLOCK_SIZE=1
 DROP TABLE IF EXISTS t1;
 CREATE TABLE t1 ( i INT );
 ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ROW_TYPE'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: invalid ROW_FORMAT specifier.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'ROW_TYPE'
 ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=2;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=1;
 SHOW WARNINGS;
 Level	Code	Message
@@ -146,11 +146,11 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTI
 TABLE_NAME	ROW_FORMAT	CREATE_OPTIONS
 t1	Compact	row_format=COMPACT
 ALTER TABLE t1 KEY_BLOCK_SIZE=2;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
 SHOW WARNINGS;
 Level	Code	Message
@@ -158,11 +158,11 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTI
 TABLE_NAME	ROW_FORMAT	CREATE_OPTIONS
 t1	Redundant	row_format=REDUNDANT
 ALTER TABLE t1 KEY_BLOCK_SIZE=4;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
 SHOW WARNINGS;
 Level	Code	Message
@@ -170,11 +170,11 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTI
 TABLE_NAME	ROW_FORMAT	CREATE_OPTIONS
 t1	Dynamic	row_format=DYNAMIC
 ALTER TABLE t1 KEY_BLOCK_SIZE=2;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
 SHOW WARNINGS;
 Level	Code	Message
@@ -212,23 +212,23 @@ t1	CREATE TABLE `t1` (
   `f1` int(11) DEFAULT NULL
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2
 ALTER TABLE t1 ROW_FORMAT=COMPACT;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
 SHOW WARNINGS;
 Level	Code	Message
@@ -298,23 +298,23 @@ CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEF
 SHOW WARNINGS;
 Level	Code	Message
 ALTER TABLE t1 KEY_BLOCK_SIZE=2;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ROW_FORMAT'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'ROW_FORMAT'
 ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ROW_FORMAT'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'ROW_FORMAT'
 SET GLOBAL innodb_file_format=Barracuda;
 DROP TABLE IF EXISTS t1;
 CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
@@ -375,23 +375,23 @@ CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEF
 SHOW WARNINGS;
 Level	Code	Message
 ALTER TABLE t1 KEY_BLOCK_SIZE=1;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'KEY_BLOCK_SIZE'
 ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ROW_FORMAT'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'ROW_FORMAT'
 ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
-ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ROW_FORMAT'
 SHOW WARNINGS;
 Level	Code	Message
 Warning	1478	InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
-Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+Error	1478	Table storage engine 'InnoDB' does not support the create option 'ROW_FORMAT'
 ALTER TABLE t1 ROW_FORMAT=COMPACT;
 SHOW WARNINGS;
 Level	Code	Message

=== modified file 'mysql-test/suite/innodb/t/innodb-create-options.test'
--- a/mysql-test/suite/innodb/t/innodb-create-options.test	revid:jorgen.loland@strippedom-20120514093058-4vd4gc1iosh2n6ba
+++ b/mysql-test/suite/innodb/t/innodb-create-options.test	revid:marko.makela@oracle.com-20120515071932-5h01ee6pemt6kzrn
@@ -98,7 +98,7 @@ ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BL
 SHOW WARNINGS;
 SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1';
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
@@ -137,22 +137,22 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTI
 DROP TABLE IF EXISTS t1;
 CREATE TABLE t1 ( i INT );
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=2;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
@@ -169,7 +169,7 @@ DROP TABLE IF EXISTS t1;
 CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT;
 SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1';
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 KEY_BLOCK_SIZE=2;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
@@ -177,7 +177,7 @@ ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
 SHOW WARNINGS;
 SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1';
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 KEY_BLOCK_SIZE=4;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
@@ -185,7 +185,7 @@ ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
 SHOW WARNINGS;
 SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1';
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 KEY_BLOCK_SIZE=2;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
@@ -209,17 +209,17 @@ SHOW CREATE TABLE t1;
 ALTER TABLE t1 ADD COLUMN f1 INT;
 SHOW CREATE TABLE t1;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 ROW_FORMAT=COMPACT;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
@@ -264,17 +264,17 @@ DROP TABLE IF EXISTS t1;
 CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT;
 SHOW WARNINGS;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 KEY_BLOCK_SIZE=2;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
@@ -319,17 +319,17 @@ DROP TABLE IF EXISTS t1;
 CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT;
 SHOW WARNINGS;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 KEY_BLOCK_SIZE=1;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
 ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
 --replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
 SHOW WARNINGS;

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc	revid:jorgen.loland@stripped-20120514093058-4vd4gc1iosh2n6ba
+++ b/storage/innobase/handler/ha_innodb.cc	revid:marko.makela@stripped5071932-5h01ee6pemt6kzrn
@@ -8519,7 +8519,7 @@ get_row_format_name(
 			"InnoDB: ROW_FORMAT=%s requires"	\
 			" innodb_file_per_table.",		\
 			get_row_format_name(row_format));	\
-		ret = FALSE;					\
+		ret = "ROW_FORMAT";					\
 	}
 
 /** If file-format is Antelope, issue warning and set ret false */
@@ -8531,7 +8531,7 @@ get_row_format_name(
 			"InnoDB: ROW_FORMAT=%s requires"	\
 			" innodb_file_format > Antelope.",	\
 			get_row_format_name(row_format));	\
-		ret = FALSE;					\
+		ret = "ROW_FORMAT";				\
 	}
 
 
@@ -8540,11 +8540,11 @@ Validates the create options. We may bui
 in future. For now, it checks two specifiers:
 KEY_BLOCK_SIZE and ROW_FORMAT
 If innodb_strict_mode is not set then this function is a no-op
-@return	TRUE if valid. */
-static
-ibool
-create_options_are_valid(
-/*=====================*/
+@return	NULL if valid, string if not. */
+UNIV_INTERN
+const char*
+create_options_are_invalid(
+/*=======================*/
 	THD*		thd,		/*!< in: connection thread. */
 	TABLE*		form,		/*!< in: information on table
 					columns and indexes */
@@ -8552,14 +8552,14 @@ create_options_are_valid(
 	bool		use_tablespace)	/*!< in: srv_file_per_table */
 {
 	ibool	kbs_specified	= FALSE;
-	ibool	ret		= TRUE;
+	const char*	ret	= NULL;
 	enum row_type	row_format	= form->s->row_type;
 
 	ut_ad(thd != NULL);
 
 	/* If innodb_strict_mode is not set don't do any validation. */
 	if (!(THDVAR(thd, strict_mode))) {
-		return(TRUE);
+		return(NULL);
 	}
 
 	ut_ad(form != NULL);
@@ -8582,7 +8582,7 @@ create_options_are_valid(
 					ER_ILLEGAL_HA_CREATE_OPTION,
 					"InnoDB: KEY_BLOCK_SIZE requires"
 					" innodb_file_per_table.");
-				ret = FALSE;
+				ret = "KEY_BLOCK_SIZE";
 			}
 			if (srv_file_format < UNIV_FORMAT_B) {
 				push_warning(
@@ -8590,7 +8590,7 @@ create_options_are_valid(
 					ER_ILLEGAL_HA_CREATE_OPTION,
 					"InnoDB: KEY_BLOCK_SIZE requires"
 					" innodb_file_format > Antelope.");
-				ret = FALSE;
+				ret = "KEY_BLOCK_SIZE";
 			}
 
 			/* The maximum KEY_BLOCK_SIZE (KBS) is 16. But if
@@ -8607,7 +8607,7 @@ create_options_are_valid(
 					" cannot be larger than %ld.",
 					create_info->key_block_size,
 					kbs_max);
-				ret = FALSE;
+				ret = "KEY_BLOCK_SIZE";
 			}
 			break;
 		default:
@@ -8617,7 +8617,7 @@ create_options_are_valid(
 				"InnoDB: invalid KEY_BLOCK_SIZE = %lu."
 				" Valid values are [1, 2, 4, 8, 16]",
 				create_info->key_block_size);
-			ret = FALSE;
+			ret = "KEY_BLOCK_SIZE";
 			break;
 		}
 	}
@@ -8642,7 +8642,7 @@ create_options_are_valid(
 				"InnoDB: cannot specify ROW_FORMAT = %s"
 				" with KEY_BLOCK_SIZE.",
 				get_row_format_name(row_format));
-			ret = FALSE;
+			ret = "KEY_BLOCK_SIZE";
 		}
 		break;
 	case ROW_TYPE_DEFAULT:
@@ -8654,7 +8654,7 @@ create_options_are_valid(
 			thd, Sql_condition::WARN_LEVEL_WARN,
 			ER_ILLEGAL_HA_CREATE_OPTION,		\
 			"InnoDB: invalid ROW_FORMAT specifier.");
-		ret = FALSE;
+		ret = "ROW_TYPE";
 		break;
 	}
 
@@ -8991,7 +8991,7 @@ ha_innobase::create(
 	/* Create the table definition in InnoDB */
 
 	/* Validate create options if innodb_strict_mode is set. */
-	if (!create_options_are_valid(
+	if (create_options_are_invalid(
 			thd, form, create_info, use_tablespace)) {
 		DBUG_RETURN(ER_ILLEGAL_HA_CREATE_OPTION);
 	}

=== modified file 'storage/innobase/handler/ha_innodb.h'
--- a/storage/innobase/handler/ha_innodb.h	revid:jorgen.loland@stripped20514093058-4vd4gc1iosh2n6ba
+++ b/storage/innobase/handler/ha_innodb.h	revid:marko.makela@stripped32-5h01ee6pemt6kzrn
@@ -492,6 +492,23 @@ innobase_table_flags(
 	ulint*			flags2)		/*!< out: DICT_TF2 flags */
 	__attribute__((nonnull, warn_unused_result));
 
+/*****************************************************************//**
+Validates the create options. We may build on this function
+in future. For now, it checks two specifiers:
+KEY_BLOCK_SIZE and ROW_FORMAT
+If innodb_strict_mode is not set then this function is a no-op
+@return	NULL if valid, string if not. */
+UNIV_INTERN
+const char*
+create_options_are_invalid(
+/*=======================*/
+	THD*		thd,		/*!< in: connection thread. */
+	TABLE*		form,		/*!< in: information on table
+					columns and indexes */
+	HA_CREATE_INFO*	create_info,	/*!< in: create info. */
+	bool		use_tablespace)	/*!< in: srv_file_per_table */
+	__attribute__((nonnull, warn_unused_result));
+
 /*********************************************************************//**
 Retrieve the FTS Relevance Ranking result for doc with doc_id
 of prebuilt->fts_doc_id

=== modified file 'storage/innobase/handler/handler0alter.cc'
--- a/storage/innobase/handler/handler0alter.cc	revid:jorgen.loland@oracle.com-20120514093058-4vd4gc1iosh2n6ba
+++ b/storage/innobase/handler/handler0alter.cc	revid:marko.makela@oracle.com-20120515071932-5h01ee6pemt6kzrn
@@ -44,16 +44,35 @@ Smart ALTER TABLE
 #include "ha_innodb.h"
 
 /** Operations for creating an index in place */
-static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_INPLACE_CREATE
+static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ONLINE_CREATE
 	= Alter_inplace_info::ADD_INDEX
-	| Alter_inplace_info::ADD_UNIQUE_INDEX
-	| Alter_inplace_info::ADD_PK_INDEX;// not online
+	| Alter_inplace_info::ADD_UNIQUE_INDEX;
+
+/** Operations for rebuilding a table in place */
+static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_INPLACE_REBUILD
+	= Alter_inplace_info::ADD_PK_INDEX
+	| Alter_inplace_info::CHANGE_CREATE_OPTION
+	/*
+	| Alter_inplace_info::ALTER_COLUMN_NULLABLE
+	| Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE
+	| Alter_inplace_info::ALTER_COLUMN_TYPE
+	| Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH,
+	| Alter_inplace_info::ALTER_COLUMN_ORDER
+	| Alter_inplace_info::ADD_COLUMN
+	| Alter_inplace_info::DROP_COLUMN
+	*/
+	;
+
+/** Operations for creating indexes or rebuilding a table */
+static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_INPLACE_CREATE
+	= INNOBASE_ONLINE_CREATE | INNOBASE_INPLACE_REBUILD;
 
 /** Operations for altering a table that InnoDB does not care about */
 static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_INPLACE_IGNORE
 	= Alter_inplace_info::ALTER_COLUMN_DEFAULT
-	| Alter_inplace_info::ALTER_RENAME
-	| Alter_inplace_info::CHANGE_CREATE_OPTION;
+	| Alter_inplace_info::ALTER_COLUMN_COLUMN_FORMAT
+	| Alter_inplace_info::ALTER_COLUMN_STORAGE_TYPE
+	| Alter_inplace_info::ALTER_RENAME;
 
 /** Operations that InnoDB can perform online */
 static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ONLINE_OPERATIONS
@@ -135,6 +154,29 @@ my_error_innodb(
 	}
 }
 
+/*******************************************************************//**
+Determine if ALTER TABLE needs to rebuild the table.
+@param ha_alter_info		the DDL operation
+@return whether it is necessary to rebuild the table */
+static __attribute__((nonnull, warn_unused_result))
+bool
+innobase_need_rebuild(
+/*==================*/
+	const Alter_inplace_info*	ha_alter_info)
+{
+	if (ha_alter_info->handler_flags
+	    == Alter_inplace_info::CHANGE_CREATE_OPTION
+	    && !(ha_alter_info->create_info->used_fields
+		 & (HA_CREATE_USED_ROW_FORMAT
+		    | HA_CREATE_USED_KEY_BLOCK_SIZE))) {
+		/* Any other CHANGE_CREATE_OPTION than changing
+		ROW_FORMAT or KEY_BLOCK_SIZE is ignored. */
+		return(false);
+	}
+
+	return(!!(ha_alter_info->handler_flags & INNOBASE_INPLACE_REBUILD));
+}
+
 /** Check if InnoDB supports a particular alter table in-place
 @param altered_table	TABLE object for new version of table.
 @param ha_alter_info	Structure describing changes to be done
@@ -161,30 +203,11 @@ ha_innobase::check_if_supported_inplace_
 		DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
 	}
 
-	HA_CREATE_INFO* create_info = ha_alter_info->create_info;
-
 	if (ha_alter_info->handler_flags
-	    & ~(INNOBASE_ONLINE_OPERATIONS
-		| Alter_inplace_info::ADD_PK_INDEX)) {
+	    & ~(INNOBASE_ONLINE_OPERATIONS | INNOBASE_INPLACE_REBUILD)) {
 		DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
 	}
 
-	if (ha_alter_info->handler_flags
-	    & Alter_inplace_info::CHANGE_CREATE_OPTION) {
-		/* Changing ROW_FORMAT or KEY_BLOCK_SIZE should
-		rebuild the table. TODO: copy index-by-index instead
-		of row-by-row. */
-
-		if (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT
-		    && create_info->row_type != get_row_type()) {
-			DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
-		}
-
-		if (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE) {
-			DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
-		}
-	}
-
 	if (!(ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE)) {
 		DBUG_RETURN(HA_ALTER_INPLACE_NO_LOCK);
 	}
@@ -254,14 +277,9 @@ ha_innobase::check_if_supported_inplace_
 
 	prebuilt->trx->will_lock++;
 
-	/* TODO: Reject if creating a fulltext index and there is an
-	incompatible FTS_DOC_ID or FTS_DOC_ID_INDEX, either in the table
-	or in the ha_alter_info. We can and should reject this before
-	locking the data dictionary. */
-
-	/* Creating the primary key requires an exclusive lock on the
+	/* Rebuilding the clustered index requires an exclusive lock on the
 	table during the whole copying operation. */
-	if (ha_alter_info->handler_flags & Alter_inplace_info::ADD_PK_INDEX) {
+	if (innobase_need_rebuild(ha_alter_info)) {
 		DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK);
 	}
 
@@ -934,7 +952,7 @@ innobase_create_key_defs(
 			definitions are allocated */
 	const Alter_inplace_info*	ha_alter_info,
 			/*!< in: alter operation */
-	const TABLE*		altered_table,
+	const TABLE*			altered_table,
 			/*!< in: MySQL table that is being altered */
 	ulint&				n_add,
 			/*!< in/out: number of indexes to be created */
@@ -970,20 +988,21 @@ innobase_create_key_defs(
 	/* If there is a primary key, it is always the first index
 	defined for the innodb_table. */
 
-	new_primary = !my_strcasecmp(system_charset_info,
-				     key_info[*add].name, "PRIMARY");
+	new_primary = n_add > 0
+		&& !my_strcasecmp(system_charset_info,
+				  key_info[*add].name, "PRIMARY");
 
 	/* If there is a UNIQUE INDEX consisting entirely of NOT NULL
 	columns and if the index does not contain column prefix(es)
 	(only prefix/part of the column is indexed), MySQL will treat the
 	index as a PRIMARY KEY unless the table already has one. */
 
-	if (!new_primary && got_default_clust
+	if (n_add > 0 && !new_primary && got_default_clust
 	    && (key_info[*add].flags & HA_NOSAME)
 	    && !(key_info[*add].flags & HA_KEY_HAS_PART_KEY_SEG)) {
 		uint	key_part = key_info[*add].key_parts;
 
-		new_primary = TRUE;
+		new_primary = true;
 
 		while (key_part--) {
 			const uint	maybe_null
@@ -994,38 +1013,33 @@ innobase_create_key_defs(
 				    field->null_ptr);
 
 			if (maybe_null) {
-				new_primary = FALSE;
+				new_primary = false;
 				break;
 			}
 		}
 	}
 
-	if (new_primary || add_fts_doc_id) {
+	if (new_primary || add_fts_doc_id
+	    || innobase_need_rebuild(ha_alter_info)) {
 		ulint	primary_key_number;
 
 		if (new_primary) {
+			DBUG_ASSERT(n_add > 0);
 			primary_key_number = *add;
-		} else if (add_fts_doc_id) {
-			/* If DICT_TF2_FTS_ADD_DOC_ID is set, we will need to
-			rebuild the table to add the unique Doc ID column for
-			FTS index. And thus the clustered index would required
-			to be rebuilt. */
-
-			if (got_default_clust) {
-				/* Create the GEN_CLUST_INDEX */
-				merge_index_def_t*	index = indexdef++;
-
-				index->fields = NULL;
-				index->n_fields = 0;
-				index->ind_type = DICT_CLUSTERED;
-				index->name = mem_heap_strdup(
-					heap, innobase_index_reserve_name);
-				index->key_number = ~0;
-				primary_key_number = ULINT_UNDEFINED;
-				goto created_clustered;
-			} else {
-				primary_key_number = 0;
-			}
+		} else if (got_default_clust) {
+			/* Create the GEN_CLUST_INDEX */
+			merge_index_def_t*	index = indexdef++;
+
+			index->fields = NULL;
+			index->n_fields = 0;
+			index->ind_type = DICT_CLUSTERED;
+			index->name = mem_heap_strdup(
+				heap, innobase_index_reserve_name);
+			index->key_number = ~0;
+			primary_key_number = ULINT_UNDEFINED;
+			goto created_clustered;
+		} else {
+			primary_key_number = 0;
 		}
 
 		/* Create the PRIMARY key index definition */
@@ -1433,7 +1447,7 @@ prepare_inplace_alter_table_dict(
 	be exclusively locked when a full-text index is being created. */
 	DBUG_ASSERT(!!new_clustered
 		    == ((ha_alter_info->handler_flags
-			 & Alter_inplace_info::ADD_PK_INDEX)
+			 & INNOBASE_INPLACE_REBUILD)
 			|| add_fts_doc_id));
 
 	/* Allocate memory for dictionary index definitions */
@@ -1674,8 +1688,7 @@ col_fail:
 		will be exclusively locked anyway, the modification
 		log is unnecessary. */
 		if (!exclusive && !num_fts_index
-		    && !(ha_alter_info->handler_flags
-			 & ~INNOBASE_ONLINE_OPERATIONS)
+		    && !innobase_need_rebuild(ha_alter_info)
 		    && !user_table->ibd_file_missing
 		    && !user_table->tablespace_discarded) {
 			DBUG_EXECUTE_IF("innodb_OOM_prepare_inplace_alter",
@@ -1924,19 +1937,33 @@ ha_innobase::prepare_inplace_alter_table
 	}
 #endif /* UNIV_DEBUG */
 
+	ut_d(mutex_enter(&dict_sys->mutex));
+	ut_d(dict_table_check_for_dup_indexes(
+		     prebuilt->table, CHECK_ABORTED_OK));
+	ut_d(mutex_exit(&dict_sys->mutex));
+
 	if (!(ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE)) {
 		/* Nothing to do */
 		goto func_exit;
 	}
 
-	ut_d(mutex_enter(&dict_sys->mutex));
-	ut_d(dict_table_check_for_dup_indexes(
-		     prebuilt->table, CHECK_ABORTED_OK));
-	ut_d(mutex_exit(&dict_sys->mutex));
+	if (ha_alter_info->handler_flags
+	    == Alter_inplace_info::CHANGE_CREATE_OPTION
+	    && !innobase_need_rebuild(ha_alter_info)) {
+		goto func_exit;
+	}
 
-	/* In case MySQL calls this in the middle of a SELECT query, release
-	possible adaptive hash latch to avoid deadlocks of threads. */
-	trx_search_latch_release_if_reserved(prebuilt->trx);
+	if (ha_alter_info->handler_flags
+	    & Alter_inplace_info::CHANGE_CREATE_OPTION) {
+		if (const char* invalid_opt = create_options_are_invalid(
+			    user_thd, altered_table,
+			    ha_alter_info->create_info,
+			    prebuilt->table->space != 0)) {
+			my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
+				 table_type(), invalid_opt);
+			DBUG_RETURN(true);
+		}
+	}
 
 	/* Check if any index name is reserved. */
 	if (innobase_index_name_is_reserved(
@@ -2385,6 +2412,12 @@ ok_exit:
 		DBUG_RETURN(false);
 	}
 
+	if (ha_alter_info->handler_flags
+	    == Alter_inplace_info::CHANGE_CREATE_OPTION
+	    && !innobase_need_rebuild(ha_alter_info)) {
+		goto ok_exit;
+	}
+
 	class ha_innobase_inplace_ctx*	ctx
 		= static_cast<class ha_innobase_inplace_ctx*>
 		(ha_alter_info->handler_ctx);

=== modified file 'storage/innobase/ibuf/ibuf0ibuf.cc'
--- a/storage/innobase/ibuf/ibuf0ibuf.cc	revid:jorgen.loland@stripped093058-4vd4gc1iosh2n6ba
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc	revid:marko.makela@strippedee6pemt6kzrn
@@ -3939,7 +3939,7 @@ ibuf_set_del_mark(
 		/* Delete mark the old index record. According to a
 		comment in row_upd_sec_index_entry(), it can already
 		have been delete marked if a lock wait occurred in
-		row_ins_index_entry() in a previous invocation of
+		row_ins_sec_index_entry() in a previous invocation of
 		row_upd_sec_index_entry(). */
 
 		if (UNIV_LIKELY

=== modified file 'storage/innobase/include/btr0cur.h'
--- a/storage/innobase/include/btr0cur.h	revid:jorgen.loland@stripped120514093058-4vd4gc1iosh2n6ba
+++ b/storage/innobase/include/btr0cur.h	revid:marko.makela@stripped2-5h01ee6pemt6kzrn
@@ -220,11 +220,12 @@ btr_cur_optimistic_insert(
 				NULL */
 	ulint		n_ext,	/*!< in: number of externally stored columns */
 	que_thr_t*	thr,	/*!< in: query thread or NULL */
-	mtr_t*		mtr);	/*!< in: mtr; if this function returns
+	mtr_t*		mtr)	/*!< in: mtr; if this function returns
 				DB_SUCCESS on a leaf page of a secondary
 				index in a compressed tablespace, the
 				mtr must be committed before latching
 				any further pages */
+	__attribute__((nonnull(2,3,4,5,8), warn_unused_result));
 /*************************************************************//**
 Performs an insert on a page of an index tree. It is assumed that mtr
 holds an x-latch on the tree and on the cursor page. If the insert is
@@ -251,7 +252,8 @@ btr_cur_pessimistic_insert(
 				NULL */
 	ulint		n_ext,	/*!< in: number of externally stored columns */
 	que_thr_t*	thr,	/*!< in: query thread or NULL */
-	mtr_t*		mtr);	/*!< in: mtr */
+	mtr_t*		mtr)	/*!< in: mtr */
+	__attribute__((nonnull(2,3,4,5,8), warn_unused_result));
 /*************************************************************//**
 See if there is enough place in the page modification log to log
 an update-in-place.

=== modified file 'storage/innobase/include/row0ins.h'
--- a/storage/innobase/include/row0ins.h	revid:jorgen.loland@strippedm-20120514093058-4vd4gc1iosh2n6ba
+++ b/storage/innobase/include/row0ins.h	revid:marko.makela@stripped71932-5h01ee6pemt6kzrn
@@ -75,20 +75,32 @@ ins_node_set_new_row(
 	ins_node_t*	node,	/*!< in: insert node */
 	dtuple_t*	row);	/*!< in: new row (or first row) for the node */
 /***************************************************************//**
-Inserts an index entry to index. Tries first optimistic, then pessimistic
-descent down the tree. If the entry matches enough to a delete marked record,
-performs the insert by updating or delete unmarking the delete marked
-record.
+Inserts an entry into a clustered index. Tries first optimistic,
+then pessimistic descent down the tree. If the entry matches enough
+to a delete marked record, performs the insert by updating or delete
+unmarking the delete marked record.
 @return	DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
 UNIV_INTERN
 dberr_t
-row_ins_index_entry(
-/*================*/
-	dict_index_t*	index,	/*!< in: index */
+row_ins_clust_index_entry(
+/*======================*/
+	dict_index_t*	index,	/*!< in: clustered index */
+	dtuple_t*	entry,	/*!< in/out: index entry to insert */
+	que_thr_t*	thr,	/*!< in: query thread */
+	ulint		n_ext)	/*!< in: number of externally stored columns */
+	__attribute__((nonnull, warn_unused_result));
+/***************************************************************//**
+Inserts an entry into a secondary index. Tries first optimistic,
+then pessimistic descent down the tree. If the entry matches enough
+to a delete marked record, performs the insert by updating or delete
+unmarking the delete marked record.
+@return	DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
+UNIV_INTERN
+dberr_t
+row_ins_sec_index_entry(
+/*====================*/
+	dict_index_t*	index,	/*!< in: secondary index */
 	dtuple_t*	entry,	/*!< in/out: index entry to insert */
-	ulint		n_ext,	/*!< in: number of externally stored columns */
-	ibool		foreign,/*!< in: TRUE=check foreign key constraints
-				(foreign=FALSE only during CREATE INDEX) */
 	que_thr_t*	thr)	/*!< in: query thread */
 	__attribute__((nonnull, warn_unused_result));
 /***************************************************************//**

=== modified file 'storage/innobase/row/row0ins.cc'
--- a/storage/innobase/row/row0ins.cc	revid:jorgen.loland@strippedc1iosh2n6ba
+++ b/storage/innobase/row/row0ins.cc	revid:marko.makela@stripped
@@ -2120,32 +2120,27 @@ row_ins_must_modify_rec(
 }
 
 /***************************************************************//**
-Tries to insert an index entry to an index. If the index is clustered
-and a record with the same unique key is found, the other record is
-necessarily marked deleted by a committed transaction, or a unique key
-violation error occurs. The delete marked record is then updated to an
-existing record, and we must write an undo log record on the delete
-marked record. If the index is secondary, and a record with exactly the
-same fields is found, the other record is necessarily marked deleted.
-It is then unmarked. Otherwise, the entry is just inserted to the index.
-@return DB_SUCCESS, DB_LOCK_WAIT, DB_FAIL if pessimistic retry needed,
-or error code */
+Tries to insert an entry into a clustered index. If a record with the
+same unique key is found, the other record is necessarily marked
+deleted by a committed transaction, or a unique key violation error
+occurs. The delete marked record is then updated to an existing
+record, and we must write an undo log record on the delete marked
+record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_FAIL if pessimistic
+retry needed, or error code */
 static __attribute__((nonnull, warn_unused_result))
 dberr_t
-row_ins_index_entry_low(
-/*====================*/
+row_ins_clust_index_entry_low(
+/*==========================*/
 	ulint		mode,	/*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
 				depending on whether we wish optimistic or
 				pessimistic descent down the index tree */
-	dict_index_t*	index,	/*!< in: index */
+	dict_index_t*	index,	/*!< in: clustered index */
 	dtuple_t*	entry,	/*!< in/out: index entry to insert */
 	ulint		n_ext,	/*!< in: number of externally stored columns */
 	que_thr_t*	thr)	/*!< in: query thread */
 {
 	btr_cur_t	cursor;
-	ulint		search_mode;
-	ibool		modify			= FALSE;
-	rec_t*		insert_rec;
 	rec_t*		rec;
 	ulint*		offsets;
 	dberr_t		err;
@@ -2154,6 +2149,8 @@ row_ins_index_entry_low(
 	mtr_t		mtr;
 	mem_heap_t*	heap			= NULL;
 
+	ut_ad(dict_index_is_clust(index));
+
 	log_free_check();
 
 	mtr_start(&mtr);
@@ -2164,28 +2161,9 @@ row_ins_index_entry_low(
 	the function will return in both low_match and up_match of the
 	cursor sensible values */
 
-	if (dict_index_is_clust(index)) {
-		search_mode = mode;
-	} else if (!(thr_get_trx(thr)->check_unique_secondary)) {
-		search_mode = mode | BTR_INSERT | BTR_IGNORE_SEC_UNIQUE;
-	} else {
-		search_mode = mode | BTR_INSERT;
-	}
-
-	btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
-				    search_mode,
+	btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, mode,
 				    &cursor, 0, __FILE__, __LINE__, &mtr);
 
-	if (cursor.flag == BTR_CUR_INSERT_TO_IBUF) {
-		/* The insertion was made to the insert buffer already during
-		the search: we are done */
-
-		ut_ad(search_mode & BTR_INSERT);
-		err = DB_SUCCESS;
-
-		goto function_exit;
-	}
-
 #ifdef UNIV_DEBUG
 	{
 		page_t*	page = btr_cur_get_page(&cursor);
@@ -2203,126 +2181,98 @@ row_ins_index_entry_low(
 	if (dict_index_is_unique(index) && (cursor.up_match >= n_unique
 					    || cursor.low_match >= n_unique)) {
 
-		if (dict_index_is_clust(index)) {
-			/* Note that the following may return also
-			DB_LOCK_WAIT */
-
-			err = row_ins_duplicate_error_in_clust(
-				&cursor, entry, thr, &mtr);
-			if (err != DB_SUCCESS) {
-
-				goto function_exit;
-			}
-		} else {
-			mtr_commit(&mtr);
-			err = row_ins_scan_sec_index_for_duplicate(
-				index, entry, thr);
-			mtr_start(&mtr);
+		/* Note that the following may return also
+		DB_LOCK_WAIT */
 
-			if (err != DB_SUCCESS) {
-				goto function_exit;
-			}
+		err = row_ins_duplicate_error_in_clust(
+			&cursor, entry, thr, &mtr);
+		if (err != DB_SUCCESS) {
 
-			/* We did not find a duplicate and we have now
-			locked with s-locks the necessary records to
-			prevent any insertion of a duplicate by another
-			transaction. Let us now reposition the cursor and
-			continue the insertion. */
-
-			btr_cur_search_to_nth_level(index, 0, entry,
-						    PAGE_CUR_LE,
-						    mode | BTR_INSERT,
-						    &cursor, 0,
-						    __FILE__, __LINE__, &mtr);
+			goto function_exit;
 		}
 	}
 
-	modify = row_ins_must_modify_rec(&cursor);
-
-	if (modify) {
+	if (row_ins_must_modify_rec(&cursor)) {
 		/* There is already an index entry with a long enough common
 		prefix, we must convert the insert into a modify of an
 		existing record */
 
-		if (dict_index_is_clust(index)) {
-			err = row_ins_clust_index_entry_by_modify(
-				mode, &cursor, &heap, &big_rec, entry,
-				thr, &mtr);
-
-			if (big_rec) {
-				ut_a(err == DB_SUCCESS);
-				/* Write out the externally stored
-				columns while still x-latching
-				index->lock and block->lock. Allocate
-				pages for big_rec in the mtr that
-				modified the B-tree, but be sure to skip
-				any pages that were freed in mtr. We will
-				write out the big_rec pages before
-				committing the B-tree mini-transaction. If
-				the system crashes so that crash recovery
-				will not replay the mtr_commit(&mtr), the
-				big_rec pages will be left orphaned until
-				the pages are allocated for something else.
-
-				TODO: If the allocation extends the
-				tablespace, it will not be redo
-				logged, in either mini-transaction.
-				Tablespace extension should be
-				redo-logged in the big_rec
-				mini-transaction, so that recovery
-				will not fail when the big_rec was
-				written to the extended portion of the
-				file, in case the file was somehow
-				truncated in the crash. */
-
-				rec = btr_cur_get_rec(&cursor);
-				offsets = rec_get_offsets(
-					rec, index, NULL,
-					ULINT_UNDEFINED, &heap);
-
-				DEBUG_SYNC_C_IF_THD(
-					thr_get_trx(thr)->mysql_thd,
-					"before_row_ins_upd_extern");
-				err = btr_store_big_rec_extern_fields(
-					index, btr_cur_get_block(&cursor),
-					rec, offsets, big_rec, &mtr,
-					BTR_STORE_INSERT_UPDATE);
-				DEBUG_SYNC_C_IF_THD(
-					thr_get_trx(thr)->mysql_thd,
-					"after_row_ins_upd_extern");
-				/* If writing big_rec fails (for
-				example, because of DB_OUT_OF_FILE_SPACE),
-				the record will be corrupted. Even if
-				we did not update any externally
-				stored columns, our update could cause
-				the record to grow so that a
-				non-updated column was selected for
-				external storage. This non-update
-				would not have been written to the
-				undo log, and thus the record cannot
-				be rolled back.
-
-				However, because we have not executed
-				mtr_commit(mtr) yet, the update will
-				not be replayed in crash recovery, and
-				the following assertion failure will
-				effectively "roll back" the operation. */
-				ut_a(err == DB_SUCCESS);
-				mtr_commit(&mtr);
-				goto stored_big_rec;
-			}
-		} else {
-			ut_ad(!n_ext);
-			err = row_ins_sec_index_entry_by_modify(
-				mode, &cursor, entry, thr, &mtr);
+		err = row_ins_clust_index_entry_by_modify(
+			mode, &cursor, &heap, &big_rec, entry,
+			thr, &mtr);
+
+		if (big_rec) {
+			ut_a(err == DB_SUCCESS);
+			/* Write out the externally stored
+			columns while still x-latching
+			index->lock and block->lock. Allocate
+			pages for big_rec in the mtr that
+			modified the B-tree, but be sure to skip
+			any pages that were freed in mtr. We will
+			write out the big_rec pages before
+			committing the B-tree mini-transaction. If
+			the system crashes so that crash recovery
+			will not replay the mtr_commit(&mtr), the
+			big_rec pages will be left orphaned until
+			the pages are allocated for something else.
+
+			TODO: If the allocation extends the
+			tablespace, it will not be redo
+			logged, in either mini-transaction.
+			Tablespace extension should be
+			redo-logged in the big_rec
+			mini-transaction, so that recovery
+			will not fail when the big_rec was
+			written to the extended portion of the
+			file, in case the file was somehow
+			truncated in the crash. */
+
+			rec = btr_cur_get_rec(&cursor);
+			offsets = rec_get_offsets(
+				rec, index, NULL,
+				ULINT_UNDEFINED, &heap);
+
+			DEBUG_SYNC_C_IF_THD(
+				thr_get_trx(thr)->mysql_thd,
+				"before_row_ins_upd_extern");
+			err = btr_store_big_rec_extern_fields(
+				index, btr_cur_get_block(&cursor),
+				rec, offsets, big_rec, &mtr,
+				BTR_STORE_INSERT_UPDATE);
+			DEBUG_SYNC_C_IF_THD(
+				thr_get_trx(thr)->mysql_thd,
+				"after_row_ins_upd_extern");
+			/* If writing big_rec fails (for
+			example, because of DB_OUT_OF_FILE_SPACE),
+			the record will be corrupted. Even if
+			we did not update any externally
+			stored columns, our update could cause
+			the record to grow so that a
+			non-updated column was selected for
+			external storage. This non-update
+			would not have been written to the
+			undo log, and thus the record cannot
+			be rolled back.
+
+			However, because we have not executed
+			mtr_commit(mtr) yet, the update will
+			not be replayed in crash recovery, and
+			the following assertion failure will
+			effectively "roll back" the operation. */
+			ut_a(err == DB_SUCCESS);
+			mtr_commit(&mtr);
+			dtuple_big_rec_free(big_rec);
+			goto stored_big_rec;
 		}
 	} else {
+		rec_t*	insert_rec;
+
 		if (mode == BTR_MODIFY_LEAF) {
 			err = btr_cur_optimistic_insert(
 				0, &cursor, entry, &insert_rec, &big_rec,
 				n_ext, thr, &mtr);
 		} else {
-			ut_a(mode == BTR_MODIFY_TREE);
+			ut_ad(mode == BTR_MODIFY_TREE);
 			if (buf_LRU_buf_pool_running_out()) {
 
 				err = DB_LOCK_TABLE_FULL;
@@ -2345,17 +2295,139 @@ function_exit:
 		err = row_ins_index_entry_big_rec(
 			entry, big_rec, NULL, &heap, index,
 			thr_get_trx(thr)->mysql_thd, __FILE__, __LINE__);
+		dtuple_convert_back_big_rec(index, entry, big_rec);
+	}
 stored_big_rec:
-		if (modify) {
-			dtuple_big_rec_free(big_rec);
-		} else {
-			dtuple_convert_back_big_rec(index, entry, big_rec);
+	if (UNIV_LIKELY_NULL(heap)) {
+		mem_heap_free(heap);
+	}
+	return(err);
+}
+
+/***************************************************************//**
+Tries to insert an entry into a secondary index. If a record with exactly the
+same fields is found, the other record is necessarily marked deleted.
+It is then unmarked. Otherwise, the entry is just inserted to the index.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_FAIL if pessimistic retry needed,
+or error code */
+static __attribute__((nonnull, warn_unused_result))
+dberr_t
+row_ins_sec_index_entry_low(
+/*========================*/
+	ulint		mode,	/*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
+				depending on whether we wish optimistic or
+				pessimistic descent down the index tree */
+	dict_index_t*	index,	/*!< in: secondary index */
+	dtuple_t*	entry,	/*!< in/out: index entry to insert */
+	que_thr_t*	thr)	/*!< in: query thread */
+{
+	btr_cur_t	cursor;
+	ulint		search_mode;
+	dberr_t		err;
+	ulint		n_unique;
+	mtr_t		mtr;
+
+	ut_ad(!dict_index_is_clust(index));
+	ut_ad(!dict_index_is_online_ddl(index));
+
+	log_free_check();
+
+	mtr_start(&mtr);
+
+	cursor.thr = thr;
+
+	/* Note that we use PAGE_CUR_LE as the search mode, because then
+	the function will return in both low_match and up_match of the
+	cursor sensible values */
+
+	if (!thr_get_trx(thr)->check_unique_secondary) {
+		search_mode = mode | BTR_INSERT | BTR_IGNORE_SEC_UNIQUE;
+	} else {
+		search_mode = mode | BTR_INSERT;
+	}
+
+	btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
+				    search_mode,
+				    &cursor, 0, __FILE__, __LINE__, &mtr);
+
+	if (cursor.flag == BTR_CUR_INSERT_TO_IBUF) {
+		/* The insert was buffered during the search: we are done */
+
+		err = DB_SUCCESS;
+
+		goto function_exit;
+	}
+
+#ifdef UNIV_DEBUG
+	{
+		page_t*	page = btr_cur_get_page(&cursor);
+		rec_t*	first_rec = page_rec_get_next(
+			page_get_infimum_rec(page));
+
+		ut_ad(page_rec_is_supremum(first_rec)
+		      || rec_get_n_fields(first_rec, index)
+		      == dtuple_get_n_fields(entry));
+	}
+#endif
+
+	n_unique = dict_index_get_n_unique(index);
+
+	if (dict_index_is_unique(index) && (cursor.up_match >= n_unique
+					    || cursor.low_match >= n_unique)) {
+
+		mtr_commit(&mtr);
+		err = row_ins_scan_sec_index_for_duplicate(index, entry, thr);
+		mtr_start(&mtr);
+
+		if (err != DB_SUCCESS) {
+			goto function_exit;
 		}
+
+		/* We did not find a duplicate and we have now
+		locked with s-locks the necessary records to
+		prevent any insertion of a duplicate by another
+		transaction. Let us now reposition the cursor and
+		continue the insertion. */
+
+		btr_cur_search_to_nth_level(index, 0, entry,
+					    PAGE_CUR_LE,
+					    mode | BTR_INSERT,
+					    &cursor, 0,
+					    __FILE__, __LINE__, &mtr);
 	}
 
-	if (UNIV_LIKELY_NULL(heap)) {
-		mem_heap_free(heap);
+	if (row_ins_must_modify_rec(&cursor)) {
+		/* There is already an index entry with a long enough common
+		prefix, we must convert the insert into a modify of an
+		existing record */
+
+		err = row_ins_sec_index_entry_by_modify(
+			mode, &cursor, entry, thr, &mtr);
+	} else {
+		rec_t*		insert_rec;
+		big_rec_t*	big_rec;
+
+		if (mode == BTR_MODIFY_LEAF) {
+			err = btr_cur_optimistic_insert(
+				0, &cursor, entry, &insert_rec,
+				&big_rec, 0, thr, &mtr);
+		} else {
+			ut_ad(mode == BTR_MODIFY_TREE);
+			if (buf_LRU_buf_pool_running_out()) {
+
+				err = DB_LOCK_TABLE_FULL;
+			} else {
+				err = btr_cur_pessimistic_insert(
+					0, &cursor, entry, &insert_rec,
+					&big_rec, 0, thr, &mtr);
+			}
+		}
+
+		ut_ad(!big_rec);
 	}
+
+function_exit:
+	mtr_commit(&mtr);
 	return(err);
 }
 
@@ -2407,28 +2479,63 @@ row_ins_index_entry_big_rec_func(
 }
 
 /***************************************************************//**
-Inserts an index entry to index. Tries first optimistic, then pessimistic
-descent down the tree. If the entry matches enough to a delete marked record,
-performs the insert by updating or delete unmarking the delete marked
-record.
+Inserts an entry into a clustered index. Tries first optimistic,
+then pessimistic descent down the tree. If the entry matches enough
+to a delete marked record, performs the insert by updating or delete
+unmarking the delete marked record.
 @return	DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
 UNIV_INTERN
 dberr_t
-row_ins_index_entry(
-/*================*/
-	dict_index_t*	index,	/*!< in: index */
+row_ins_clust_index_entry(
+/*======================*/
+	dict_index_t*	index,	/*!< in: clustered index */
 	dtuple_t*	entry,	/*!< in/out: index entry to insert */
-	ulint		n_ext,	/*!< in: number of externally stored columns */
-	ibool		foreign,/*!< in: TRUE=check foreign key constraints
-				(foreign=FALSE only during CREATE INDEX) */
-	que_thr_t*	thr)	/*!< in: query thread */
+	que_thr_t*	thr,	/*!< in: query thread */
+	ulint		n_ext)	/*!< in: number of externally stored columns */
 {
 	dberr_t	err;
 
-	/* Only clustered indexes may contain externally stored columns. */
-	ut_ad(dict_index_is_clust(index) || !n_ext);
+	if (UT_LIST_GET_FIRST(index->table->foreign_list)) {
+		err = row_ins_check_foreign_constraints(
+			index->table, index, entry, thr);
+		if (err != DB_SUCCESS) {
+
+			return(err);
+		}
+	}
+
+	/* Try first optimistic descent to the B-tree */
+
+	err = row_ins_clust_index_entry_low(BTR_MODIFY_LEAF, index, entry,
+					    n_ext, thr);
+	if (err != DB_FAIL) {
+
+		return(err);
+	}
 
-	if (foreign && UT_LIST_GET_FIRST(index->table->foreign_list)) {
+	/* Try then pessimistic descent to the B-tree */
+
+	return(row_ins_clust_index_entry_low(BTR_MODIFY_TREE, index, entry,
+					     n_ext, thr));
+}
+
+/***************************************************************//**
+Inserts an entry into a secondary index. Tries first optimistic,
+then pessimistic descent down the tree. If the entry matches enough
+to a delete marked record, performs the insert by updating or delete
+unmarking the delete marked record.
+@return	DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
+UNIV_INTERN
+dberr_t
+row_ins_sec_index_entry(
+/*====================*/
+	dict_index_t*	index,	/*!< in: secondary index */
+	dtuple_t*	entry,	/*!< in/out: index entry to insert */
+	que_thr_t*	thr)	/*!< in: query thread */
+{
+	dberr_t	err;
+
+	if (UT_LIST_GET_FIRST(index->table->foreign_list)) {
 		err = row_ins_check_foreign_constraints(index->table, index,
 							entry, thr);
 		if (err != DB_SUCCESS) {
@@ -2439,14 +2546,12 @@ row_ins_index_entry(
 
 	if (dict_index_online_trylog(index, entry, thr_get_trx(thr)->id,
 				     ROW_OP_INSERT)) {
-
 		return(DB_SUCCESS);
 	}
 
 	/* Try first optimistic descent to the B-tree */
 
-	err = row_ins_index_entry_low(BTR_MODIFY_LEAF, index, entry,
-				      n_ext, thr);
+	err = row_ins_sec_index_entry_low(BTR_MODIFY_LEAF, index, entry, thr);
 	if (err != DB_FAIL) {
 
 		return(err);
@@ -2454,9 +2559,29 @@ row_ins_index_entry(
 
 	/* Try then pessimistic descent to the B-tree */
 
-	err = row_ins_index_entry_low(BTR_MODIFY_TREE, index, entry,
-				      n_ext, thr);
-	return(err);
+	return(row_ins_sec_index_entry_low(
+		       BTR_MODIFY_TREE, index, entry, thr));
+}
+
+/***************************************************************//**
+Inserts an index entry to index. Tries first optimistic, then pessimistic
+descent down the tree. If the entry matches enough to a delete marked record,
+performs the insert by updating or delete unmarking the delete marked
+record.
+@return	DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
+static
+dberr_t
+row_ins_index_entry(
+/*================*/
+	dict_index_t*	index,	/*!< in: index */
+	dtuple_t*	entry,	/*!< in/out: index entry to insert */
+	que_thr_t*	thr)	/*!< in: query thread */
+{
+	if (dict_index_is_clust(index)) {
+		return(row_ins_clust_index_entry(index, entry, thr, 0));
+	} else {
+		return(row_ins_sec_index_entry(index, entry, thr));
+	}
 }
 
 /***********************************************************//**
@@ -2533,7 +2658,7 @@ row_ins_index_entry_step(
 
 	ut_ad(dtuple_check_typed(node->entry));
 
-	err = row_ins_index_entry(node->index, node->entry, 0, TRUE, thr);
+	err = row_ins_index_entry(node->index, node->entry, thr);
 
 	return(err);
 }

=== modified file 'storage/innobase/row/row0upd.cc'
--- a/storage/innobase/row/row0upd.cc	revid:jorgen.loland@stripped-4vd4gc1iosh2n6ba
+++ b/storage/innobase/row/row0upd.cc	revid:marko.makela@strippedzrn
@@ -1734,7 +1734,7 @@ row_upd_sec_index_entry(
 	case ROW_FOUND:
 		/* Delete mark the old index record; it can already be
 		delete marked if we return after a lock wait in
-		row_ins_index_entry below */
+		row_ins_sec_index_entry() below */
 
 		if (!rec_get_deleted_flag(
 			rec, dict_table_is_comp(index->table))) {
@@ -1774,7 +1774,7 @@ row_upd_sec_index_entry(
 	ut_a(entry);
 
 	/* Insert new index entry */
-	err = row_ins_index_entry(index, entry, 0, TRUE, thr);
+	err = row_ins_sec_index_entry(index, entry, thr);
 
 func_exit:
 	mem_heap_free(heap);
@@ -2005,7 +2005,7 @@ row_upd_clust_rec_by_insert(
 	default:
 		ut_error;
 	case UPD_NODE_INSERT_BLOB:
-		/* A lock wait occurred in row_ins_index_entry() in
+		/* A lock wait occurred in row_ins_clust_index_entry() in
 		the previous invocation of this function. Mark the
 		off-page columns in the entry inherited. */
 
@@ -2014,7 +2014,7 @@ row_upd_clust_rec_by_insert(
 		ut_a(change_ownership);
 		/* fall through */
 	case UPD_NODE_INSERT_CLUSTERED:
-		/* A lock wait occurred in row_ins_index_entry() in
+		/* A lock wait occurred in row_ins_clust_index_entry() in
 		the previous invocation of this function. */
 		break;
 	case UPD_NODE_UPDATE_CLUSTERED:
@@ -2065,9 +2065,9 @@ err_exit:
 
 	mtr_commit(mtr);
 
-	err = row_ins_index_entry(index, entry,
-				  node->upd_ext ? node->upd_ext->n_ext : 0,
-				  TRUE, thr);
+	err = row_ins_clust_index_entry(
+		index, entry, thr,
+		node->upd_ext ? node->upd_ext->n_ext : 0);
 	node->state = change_ownership
 		? UPD_NODE_INSERT_BLOB
 		: UPD_NODE_INSERT_CLUSTERED;

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk-wl6255 branch (marko.makela:3829 to 3833) WL#6255marko.makela15 May