List:Commits« Previous MessageNext Message »
From:marko.makela Date:June 5 2012 9:40pm
Subject:bzr push into mysql-trunk-wl6255 branch (marko.makela:3944 to 3946) WL#6255
View as plain text  
 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
 3945 Marko Mäkelä	2012-06-05
      Adjust main.alter_table for ADD COLUMN.

    modified:
      mysql-test/r/alter_table.result
      mysql-test/t/alter_table.test
 3944 Marko Mäkelä	2012-06-05
      WL#6255 ALTER_ADD_COLUMN (ALTER TABLE ... ADD COLUMN)
      
      innobase_build_col_map_add(): Convert a default value of an ADD COLUMN
      to the InnoDB format.
      
      ha_innobase_inplace_ctx(): Add add_cols.
      
      innobase_build_col_map(), row_merge_build_indexes(),
      row_log_table_apply(), row_build(), row_log_table_apply_convert_mrec(),
      row_log_table_apply_insert(), row_log_table_apply_update(),
      row_log_table_apply_op(), row_log_table_apply_ops(),
      row_merge_read_clustered_index(): Add the parameter add_cols.
      
      prepare_inplace_alter_table_dict(): When rebuilding a table, make it a
      *.ibd file if the original table was in an *.ibd file, or if
      innodb_file_per_table=1.

    modified:
      mysql-test/suite/innodb/r/innodb-create-options.result
      mysql-test/suite/innodb/r/innodb.result
      mysql-test/suite/innodb/t/innodb-create-options.test
      storage/innobase/handler/handler0alter.cc
      storage/innobase/include/row0log.h
      storage/innobase/include/row0merge.h
      storage/innobase/include/row0row.h
      storage/innobase/row/row0log.cc
      storage/innobase/row/row0merge.cc
      storage/innobase/row/row0row.cc
      storage/innobase/row/row0undo.cc
      storage/innobase/row/row0upd.cc
      storage/innobase/row/row0vers.cc
=== modified file 'mysql-test/r/alter_table.result'
--- a/mysql-test/r/alter_table.result	revid:marko.makela@stripped
+++ b/mysql-test/r/alter_table.result	revid:marko.makela@oracle.com-20120605213921-w1upm6qwwud13rsc
@@ -1543,8 +1543,7 @@ ALTER TABLE t1 ADD COLUMN (c1 INT);
 ALTER TABLE t1 ADD COLUMN (c2 INT), ALGORITHM= DEFAULT;
 ALTER TABLE t1 ADD COLUMN (c3 INT), ALGORITHM= COPY;
 ALTER TABLE t1 ADD COLUMN (c4 INT), ALGORITHM= INPLACE;
-ERROR 42000: This version of MySQL doesn't yet support 'ALTER TABLE t1 ADD COLUMN (c4 INT), ALGORITHM= INPLACE'
-ALTER TABLE t1 DROP COLUMN c1, DROP COLUMN c2, DROP COLUMN c3;
+ALTER TABLE t1 DROP COLUMN c1, DROP COLUMN c2, DROP COLUMN c3, DROP COLUMN c4;
 #
 # 4: Test LOCK keyword
 #
@@ -1646,26 +1645,26 @@ affected rows: 0
 ALTER TABLE tm1;
 affected rows: 0
 ALTER TABLE ti1 ADD COLUMN d VARCHAR(200);
-affected rows: 2
-info: Records: 2  Duplicates: 0  Warnings: 0
+affected rows: 0
+info: Records: 0  Duplicates: 0  Warnings: 0
 ALTER TABLE tm1 ADD COLUMN d VARCHAR(200);
 affected rows: 2
 info: Records: 2  Duplicates: 0  Warnings: 0
 ALTER TABLE ti1 ADD COLUMN d2 VARCHAR(200);
-affected rows: 2
-info: Records: 2  Duplicates: 0  Warnings: 0
+affected rows: 0
+info: Records: 0  Duplicates: 0  Warnings: 0
 ALTER TABLE tm1 ADD COLUMN d2 VARCHAR(200);
 affected rows: 2
 info: Records: 2  Duplicates: 0  Warnings: 0
 ALTER TABLE ti1 ADD COLUMN e ENUM('a', 'b') FIRST;
-affected rows: 2
-info: Records: 2  Duplicates: 0  Warnings: 0
+affected rows: 0
+info: Records: 0  Duplicates: 0  Warnings: 0
 ALTER TABLE tm1 ADD COLUMN e ENUM('a', 'b') FIRST;
 affected rows: 2
 info: Records: 2  Duplicates: 0  Warnings: 0
 ALTER TABLE ti1 ADD COLUMN f INT AFTER a;
-affected rows: 2
-info: Records: 2  Duplicates: 0  Warnings: 0
+affected rows: 0
+info: Records: 0  Duplicates: 0  Warnings: 0
 ALTER TABLE tm1 ADD COLUMN f INT AFTER a;
 affected rows: 2
 info: Records: 2  Duplicates: 0  Warnings: 0

=== modified file 'mysql-test/suite/innodb/r/innodb-table-online.result'
--- a/mysql-test/suite/innodb/r/innodb-table-online.result	revid:marko.makela@stripped43232-ned9z2rxx931s91t
+++ b/mysql-test/suite/innodb/r/innodb-table-online.result	revid:marko.makela@stripped120605213921-w1upm6qwwud13rsc
@@ -214,8 +214,9 @@ ALTER TABLE t1 ADD PRIMARY KEY(c22f), CH
 ERROR 42000: Multiple primary key defined
 ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c22f), CHANGE c2 c22f INT;
 ERROR 23000: Duplicate entry '5' for key 'PRIMARY'
-ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c1,c22f), CHANGE c2 c22f INT,
-CHANGE c3 c3 TEXT NULL, CHANGE c1 c1 INT AFTER c22f;
+ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c1,c22f,c4(5)),
+CHANGE c2 c22f INT, CHANGE c3 c3 TEXT NULL, CHANGE c1 c1 INT AFTER c22f,
+ADD COLUMN c4 VARCHAR(6) DEFAULT 'Online';
 SET DEBUG_SYNC = 'now WAIT_FOR rebuilt3';
 SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
 name	count
@@ -263,22 +264,26 @@ ALTER TABLE t1 MODIFY c3 TEXT NOT NULL;
 ERROR 22004: Invalid use of NULL value
 UPDATE t1 SET c3=CONCAT(c1,REPEAT('foo',c1)) WHERE c3 IS NULL;
 SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL c3p5_created0 WAIT_FOR ins_done0';
-ALTER TABLE t1 MODIFY c3 TEXT NOT NULL, DROP COLUMN c22f;
+ALTER TABLE t1 MODIFY c3 TEXT NOT NULL, DROP COLUMN c22f,
+ADD COLUMN c5 CHAR(5) DEFAULT 'tired' FIRST;
 SET DEBUG_SYNC = 'now WAIT_FOR c3p5_created0';
 BEGIN;
-INSERT INTO t1 VALUES(347,33101,'Pikku kakkosen posti');
-INSERT INTO t1 VALUES(33101,347,NULL);
+INSERT INTO t1 VALUES(347,33101,'Pikku kakkosen posti','YLETV2');
+INSERT INTO t1 VALUES(33101,347,NULL,'');
 SET DEBUG_SYNC = 'now SIGNAL ins_done0';
 ERROR 22004: Invalid use of NULL value
 ROLLBACK;
 ALTER TABLE t1 MODIFY c3 TEXT NOT NULL;
 SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL c3p5_created WAIT_FOR ins_done';
-ALTER TABLE t1 DROP PRIMARY KEY, DROP COLUMN c22f, ADD PRIMARY KEY c3p5(c3(5));
+ALTER TABLE t1 DROP PRIMARY KEY, DROP COLUMN c22f,
+ADD COLUMN c6 VARCHAR(1000) DEFAULT
+'I love tracking down hard-to-reproduce bugs.',
+ADD PRIMARY KEY c3p5(c3(5), c6(2));
 SET DEBUG_SYNC = 'now WAIT_FOR c3p5_created';
 SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL ins_done WAIT_FOR ddl_timed_out';
-INSERT INTO t1 VALUES(347,33101,NULL);
+INSERT INTO t1 VALUES(347,33101,NULL,'');
 ERROR 23000: Column 'c3' cannot be null
-INSERT INTO t1 VALUES(347,33101,'Pikku kakkosen posti');
+INSERT INTO t1 VALUES(347,33101,'Pikku kakkosen posti','');
 ERROR HY000: Lock wait timeout exceeded; try restarting transaction
 SET DEBUG_SYNC = 'now SIGNAL ddl_timed_out';
 SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
@@ -294,6 +299,18 @@ SET DEBUG_SYNC = 'row_log_table_apply1_b
 SET lock_wait_timeout = 1;
 ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
 SET DEBUG_SYNC = 'now WAIT_FOR rebuilt4';
+SELECT * FROM t1 LIMIT 10;
+c22f	c1	c3	c4
+5	1	1foo	Online
+6	2	2foofoo	Online
+7	3	3foofoofoo	Online
+8	4	4foofoofoofoo	Online
+9	5	5foofoofoofoofoo	Online
+5	6	6foofoofoofoofoofoo	Online
+6	7	7foofoofoofoofoofoofoo	Online
+7	8	8foofoofoofoofoofoofoofoo	Online
+8	9	9foofoofoofoofoofoofoofoofoo	Online
+9	10	10foofoofoofoofoofoofoofoofoofoo	Online
 SET lock_wait_timeout = 10;
 ALTER TABLE t1 DISCARD TABLESPACE;
 SET DEBUG_SYNC = 'now SIGNAL dml4_done';
@@ -304,11 +321,12 @@ t1	CREATE TABLE `t1` (
   `c22f` int(11) NOT NULL DEFAULT '0',
   `c1` int(11) NOT NULL DEFAULT '0',
   `c3` text NOT NULL,
-  PRIMARY KEY (`c1`,`c22f`)
+  `c4` varchar(6) NOT NULL DEFAULT 'Online',
+  PRIMARY KEY (`c1`,`c22f`,`c4`(5))
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
 ALTER TABLE t1 DROP COLUMN c3, ROW_FORMAT=REDUNDANT, ALGORITHM = INPLACE;
 SELECT * FROM t1;
-c22f	c1
+c22f	c1	c4
 SET DEBUG_SYNC = 'RESET';
 SET DEBUG = '';
 SET GLOBAL innodb_monitor_disable = module_ddl;

=== modified file 'mysql-test/suite/innodb/t/innodb-table-online.test'
--- a/mysql-test/suite/innodb/t/innodb-table-online.test	revid:marko.makela@stripped0120605143232-ned9z2rxx931s91t
+++ b/mysql-test/suite/innodb/t/innodb-table-online.test	revid:marko.makela@oracle.com-20120605213921-w1upm6qwwud13rsc
@@ -220,8 +220,9 @@ ALTER TABLE t1 ADD PRIMARY KEY(c22f), CH
 --error ER_DUP_ENTRY
 ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c22f), CHANGE c2 c22f INT;
 --send
-ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c1,c22f), CHANGE c2 c22f INT,
-CHANGE c3 c3 TEXT NULL, CHANGE c1 c1 INT AFTER c22f;
+ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c1,c22f,c4(5)),
+CHANGE c2 c22f INT, CHANGE c3 c3 TEXT NULL, CHANGE c1 c1 INT AFTER c22f,
+ADD COLUMN c4 VARCHAR(6) DEFAULT 'Online';
 
 connection default;
 SET DEBUG_SYNC = 'now WAIT_FOR rebuilt3';
@@ -262,14 +263,15 @@ UPDATE t1 SET c3=CONCAT(c1,REPEAT('foo',
 
 SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL c3p5_created0 WAIT_FOR ins_done0';
 --send
-ALTER TABLE t1 MODIFY c3 TEXT NOT NULL, DROP COLUMN c22f;
+ALTER TABLE t1 MODIFY c3 TEXT NOT NULL, DROP COLUMN c22f,
+ADD COLUMN c5 CHAR(5) DEFAULT 'tired' FIRST;
 
 connection default;
 
 SET DEBUG_SYNC = 'now WAIT_FOR c3p5_created0';
 BEGIN;
-INSERT INTO t1 VALUES(347,33101,'Pikku kakkosen posti');
-INSERT INTO t1 VALUES(33101,347,NULL);
+INSERT INTO t1 VALUES(347,33101,'Pikku kakkosen posti','YLETV2');
+INSERT INTO t1 VALUES(33101,347,NULL,'');
 SET DEBUG_SYNC = 'now SIGNAL ins_done0';
 
 connection con1;
@@ -284,16 +286,19 @@ ALTER TABLE t1 MODIFY c3 TEXT NOT NULL;
 
 SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL c3p5_created WAIT_FOR ins_done';
 --send
-ALTER TABLE t1 DROP PRIMARY KEY, DROP COLUMN c22f, ADD PRIMARY KEY c3p5(c3(5));
+ALTER TABLE t1 DROP PRIMARY KEY, DROP COLUMN c22f,
+ADD COLUMN c6 VARCHAR(1000) DEFAULT
+'I love tracking down hard-to-reproduce bugs.',
+ADD PRIMARY KEY c3p5(c3(5), c6(2));
 
 connection default;
 SET DEBUG_SYNC = 'now WAIT_FOR c3p5_created';
 
 SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL ins_done WAIT_FOR ddl_timed_out';
 --error ER_BAD_NULL_ERROR
-INSERT INTO t1 VALUES(347,33101,NULL);
+INSERT INTO t1 VALUES(347,33101,NULL,'');
 --send
-INSERT INTO t1 VALUES(347,33101,'Pikku kakkosen posti');
+INSERT INTO t1 VALUES(347,33101,'Pikku kakkosen posti','');
 
 connection con1;
 --error ER_LOCK_WAIT_TIMEOUT
@@ -314,6 +319,7 @@ ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
 
 connection con1;
 SET DEBUG_SYNC = 'now WAIT_FOR rebuilt4';
+SELECT * FROM t1 LIMIT 10;
 
 connect (con2,localhost,root,,);
 connection con2;

=== modified file 'mysql-test/t/alter_table.test'
--- a/mysql-test/t/alter_table.test	revid:marko.makela@stripped2-ned9z2rxx931s91t
+++ b/mysql-test/t/alter_table.test	revid:marko.makela@strippedsc
@@ -1317,10 +1317,9 @@ ALTER TABLE t1 DROP INDEX i1, DROP INDEX
 ALTER TABLE t1 ADD COLUMN (c1 INT);
 ALTER TABLE t1 ADD COLUMN (c2 INT), ALGORITHM= DEFAULT;
 ALTER TABLE t1 ADD COLUMN (c3 INT), ALGORITHM= COPY;
---error ER_NOT_SUPPORTED_YET
 ALTER TABLE t1 ADD COLUMN (c4 INT), ALGORITHM= INPLACE;
 
-ALTER TABLE t1 DROP COLUMN c1, DROP COLUMN c2, DROP COLUMN c3;
+ALTER TABLE t1 DROP COLUMN c1, DROP COLUMN c2, DROP COLUMN c3, DROP COLUMN c4;
 
 --echo #
 --echo # 4: Test LOCK keyword

=== modified file 'storage/innobase/handler/handler0alter.cc'
--- a/storage/innobase/handler/handler0alter.cc	revid:marko.makela@oracle.com-20120605143232-ned9z2rxx931s91t
+++ b/storage/innobase/handler/handler0alter.cc	revid:marko.makela@stripped-20120605213921-w1upm6qwwud13rsc
@@ -247,6 +247,9 @@ ha_innobase::check_if_supported_inplace_
 		DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
 	}
 
+	List_iterator_fast<Create_field> cf_it(
+		ha_alter_info->alter_info->create_list);
+
 	/* Fix the key parts. */
 	for (KEY* new_key = ha_alter_info->key_info_buffer;
 	     new_key < ha_alter_info->key_info_buffer
@@ -255,44 +258,28 @@ ha_innobase::check_if_supported_inplace_
 		for (KEY_PART_INFO* key_part = new_key->key_part;
 		     key_part < new_key->key_part + new_key->key_parts;
 		     key_part++) {
-			key_part->field = table->field[key_part->fieldnr];
-			/* TODO: Use altered_table for ADD_COLUMN.
-			What to do with ADD_COLUMN|DROP_COLUMN? */
-
-			if (dict_table_get_n_user_cols(prebuilt->table)
-			    <= key_part->fieldnr) {
-				/* This should never occur, unless
-				the .frm file gets out of sync with
-				the InnoDB data dictionary. */
-				sql_print_warning(
-					"InnoDB table '%s' has %u columns, "
-					"MySQL table '%s' has %u.",
-					prebuilt->table->name,
-					(unsigned) dict_table_get_n_user_cols(
-						prebuilt->table),
-					table->s->table_name.str,
-					table->s->fields);
-				ut_ad(0);
-				DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
-			}
-
-			dict_col_t* col = dict_table_get_nth_col(
-				prebuilt->table, key_part->fieldnr);
-
-			if (!(col->prtype & DATA_NOT_NULL)
-			    != !!key_part->field->null_ptr) {
-				sql_print_warning(
-					"InnoDB table '%s' column '%s' "
-					"attributes differ from "
-					"MySQL '%s'.'%s'.",
-					prebuilt->table->name,
-					dict_table_get_col_name(
-						prebuilt->table,
-						key_part->fieldnr),
-					table->s->table_name.str,
-					key_part->field->field_name);
-				ut_ad(0);
-				DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
+			const Create_field*	new_field;
+
+			DBUG_ASSERT(key_part->fieldnr
+				    < altered_table->s->fields);
+
+			cf_it.rewind();
+			for (uint fieldnr = 0; (new_field = cf_it++);
+			     fieldnr++) {
+				if (fieldnr == key_part->fieldnr) {
+					break;
+				}
+			}
+
+			DBUG_ASSERT(new_field);
+
+			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];
 			}
 		}
 	}
@@ -2022,10 +2009,11 @@ innobase_check_foreigns(
 	dict_foreign_t**	drop_fk,
 	ulint			n_drop_fk)
 {
-	List_iterator_fast<Create_field> cf_it;
+	List_iterator_fast<Create_field> cf_it(
+		ha_alter_info->alter_info->create_list);
 
 	for (Field** fp = old_table->field; *fp; fp++) {
-		cf_it.init(ha_alter_info->alter_info->create_list);
+		cf_it.rewind();
 		const Create_field* new_field;
 
 		ut_ad(!(*fp)->null_ptr == !!((*fp)->flags & NOT_NULL_FLAG));
@@ -2116,8 +2104,8 @@ innobase_build_col_map(
 	ulint*	col_map = static_cast<ulint*>(
 		mem_heap_alloc(heap, old_table->n_cols * sizeof *col_map));
 
-	List_iterator_fast<Create_field> cf_it;
-	cf_it.init(ha_alter_info->alter_info->create_list);
+	List_iterator_fast<Create_field> cf_it(
+		ha_alter_info->alter_info->create_list);
 	uint i = 0;
 
 	/* Any dropped columns will map to ULINT_UNDEFINED. */
@@ -2588,7 +2576,7 @@ col_fail:
 					goto error_handling;);
 			rw_lock_x_lock(&add_index[num_created]->lock);
 			bool ok = row_log_allocate(add_index[num_created],
-						   NULL, true);
+						   NULL, true, NULL, NULL);
 			rw_lock_x_unlock(&add_index[num_created]->lock);
 
 			if (!ok) {
@@ -2612,7 +2600,8 @@ col_fail:
 		bool ok = row_log_allocate(
 			clust_index, indexed_table,
 			!(ha_alter_info->handler_flags
-			  & Alter_inplace_info::ADD_PK_INDEX));
+			  & Alter_inplace_info::ADD_PK_INDEX),
+			add_cols, col_map);
 		rw_lock_x_unlock(&clust_index->lock);
 
 		if (!ok) {
@@ -2907,7 +2896,8 @@ err_exit_no_heap:
 	already contains. */
 	if (ha_alter_info->handler_flags
 	    & Alter_inplace_info::ALTER_COLUMN_NAME) {
-		List_iterator_fast<Create_field> cf_it;
+		List_iterator_fast<Create_field> cf_it(
+			ha_alter_info->alter_info->create_list);
 
 		for (Field** fp = table->field; *fp; fp++) {
 			if (!((*fp)->flags & FIELD_IS_RENAMED)) {
@@ -2916,7 +2906,7 @@ err_exit_no_heap:
 
 			const char* name = 0;
 
-			cf_it.init(ha_alter_info->alter_info->create_list);
+			cf_it.rewind();
 			while (Create_field* cf = cf_it++) {
 				if (cf->field == *fp) {
 					name = cf->field_name;
@@ -3003,7 +2993,7 @@ check_if_ok_to_rename:
 
 		List_iterator<Alter_drop> drop_it(
 			ha_alter_info->alter_info->drop_list);
-		drop_it.rewind();
+
 		while (Alter_drop* drop = drop_it++) {
 			if (drop->type != Alter_drop::FOREIGN_KEY) {
 				continue;
@@ -3414,8 +3404,7 @@ oom:
 	    && ctx->indexed_table != prebuilt->table) {
 		DEBUG_SYNC_C("row_log_table_apply1_before");
 		error = row_log_table_apply(
-			ctx->thr, prebuilt->table, table,
-			ctx->add_cols, ctx->col_map);
+			ctx->thr, prebuilt->table, table);
 	}
 
 	/* After an error, remove all those index definitions
@@ -3869,7 +3858,8 @@ innobase_rename_columns(
 	row_prebuilt_t*		prebuilt,
 	trx_t*			trx)
 {
-	List_iterator_fast<Create_field> cf_it;
+	List_iterator_fast<Create_field> cf_it(
+		ha_alter_info->alter_info->create_list);
 	uint i = 0;
 
 	for (Field** fp = table->field; *fp; fp++, i++) {
@@ -3877,7 +3867,7 @@ innobase_rename_columns(
 			continue;
 		}
 
-		cf_it.init(ha_alter_info->alter_info->create_list);
+		cf_it.rewind();
 		while (Create_field* cf = cf_it++) {
 			if (cf->field == *fp) {
 				if (innobase_rename_column(
@@ -4000,8 +3990,7 @@ ha_innobase::commit_inplace_alter_table(
 		if (ctx->online) {
 			DEBUG_SYNC_C("row_log_table_apply2_before");
 			error = row_log_table_apply(
-				ctx->thr, prebuilt->table, table,
-				ctx->add_cols, ctx->col_map);
+				ctx->thr, prebuilt->table, table);
 
 			switch (error) {
 				KEY*	dup_key;

=== modified file 'storage/innobase/include/row0log.h'
--- a/storage/innobase/include/row0log.h	revid:marko.makela@stripped3232-ned9z2rxx931s91t
+++ b/storage/innobase/include/row0log.h	revid:marko.makela@strippedqwwud13rsc
@@ -45,8 +45,13 @@ row_log_allocate(
 	dict_index_t*	index,	/*!< in/out: index */
 	dict_table_t*	table,	/*!< in/out: new table being rebuilt,
 				or NULL when creating a secondary index */
-	bool		same_pk)/*!< in: whether the definition of the
+	bool		same_pk,/*!< in: whether the definition of the
 				PRIMARY KEY has remained the same */
+	const dtuple_t*	add_cols,
+				/*!< in: default values of
+				added columns, or NULL */
+	const ulint*	col_map)/*!< in: mapping of old column
+				numbers to new ones, or NULL if !table */
 	__attribute__((nonnull(1), warn_unused_result));
 /******************************************************//**
 Free the row log for an index on which online creation was aborted. */
@@ -176,14 +181,9 @@ row_log_table_apply(
 	que_thr_t*	thr,	/*!< in: query graph */
 	dict_table_t*	old_table,
 				/*!< in: old table */
-	struct TABLE*	table,	/*!< in/out: MySQL table
+	struct TABLE*	table)	/*!< in/out: MySQL table
 				(for reporting duplicates) */
-	const dtuple_t*	add_cols,
-				/*!< in: default values of
-				added columns, or NULL */
-	const ulint*	col_map)/*!< in: mapping of old column
-				numbers to new ones, or NULL */
-	__attribute__((nonnull(1,2,3,5), warn_unused_result));
+	__attribute__((nonnull, warn_unused_result));
 
 /******************************************************//**
 Get the latest transaction ID that has invoked row_log_online_op()

=== modified file 'storage/innobase/row/row0log.cc'
--- a/storage/innobase/row/row0log.cc	revid:marko.makela@stripped0120605143232-ned9z2rxx931s91t
+++ b/storage/innobase/row/row0log.cc	revid:marko.makela@strippedw1upm6qwwud13rsc
@@ -95,6 +95,10 @@ struct row_log_t {
 				index that is being created online */
 	bool		same_pk;/*!< whether the definition of the PRIMARY KEY
 				has remained the same */
+	const dtuple_t*	add_cols;
+				/*!< default values of added columns, or NULL */
+	const ulint*	col_map;/*!< mapping of old column numbers to
+				new ones, or NULL if !table */
 	dberr_t		error;	/*!< error that occurred during online
 				table rebuild */
 	trx_id_t	max_trx;/*!< biggest observed trx_id in
@@ -796,8 +800,8 @@ row_log_table_get_pk(
 
 	/* index->online_log->error is protected by the above mutex. */
 	if (index->online_log->error == DB_SUCCESS) {
-		dict_table_t*	new_table
-			= index->online_log->table;
+		row_log_t*	log		= index->online_log;
+		dict_table_t*	new_table	= log->table;
 		dict_index_t*	new_index
 			= dict_table_get_first_index(new_table);
 		const ulint	new_n_uniq
@@ -835,18 +839,35 @@ row_log_table_get_pk(
 			dfield_t*		dfield;
 			const dict_col_t*	new_col;
 			const dict_col_t*	col;
+			ulint			col_no;
 			ulint			i;
 			ulint			len;
 			const byte*		field;
 
-			dfield = dtuple_get_nth_field(tuple, new_i);
 			ifield = dict_index_get_nth_field(new_index, new_i);
+			dfield = dtuple_get_nth_field(tuple, new_i);
 			new_col = dict_field_get_col(ifield);
+			col_no = new_col->ind;
+
+			for (ulint old_i = 0; old_i < index->table->n_cols;
+			     old_i++) {
+				if (col_no == log->col_map[old_i]) {
+					col_no = old_i;
+					goto copy_col;
+				}
+			}
+
+			/* No matching column was found in the old
+			table, so this must be an added column.
+			Copy the default value. */
+			ut_ad(log->add_cols);
+			dfield_copy(dfield,
+				    dtuple_get_nth_field(
+					    log->add_cols, col_no));
+			continue;
 
-			/* TODO: support ADD COLUMN, DROP COLUMN,
-			reordering columns */
-			col = dict_table_get_nth_col(
-				index->table, new_col->ind);
+copy_col:
+			col = dict_table_get_nth_col(index->table, col_no);
 
 			i = dict_col_get_clust_pos(col, index);
 
@@ -1002,37 +1023,32 @@ row_log_table_is_rollback(
 /******************************************************//**
 Converts a log record to a table row.
 @return converted row, or NULL if the conversion fails */
-static __attribute__((nonnull(1,2,3,5,6,7,8), warn_unused_result))
+static __attribute__((nonnull, warn_unused_result))
 const dtuple_t*
 row_log_table_apply_convert_mrec(
 /*=============================*/
 	const mrec_t*		mrec,		/*!< in: merge record */
 	const dict_index_t*	index,		/*!< in: index of mrec */
 	const ulint*		offsets,	/*!< in: offsets of mrec */
-	const dtuple_t*		add_cols,	/*!< in: default values of
-						added columns, or NULL */
-	const ulint*		col_map,	/*!< in: mapping of old column
-						numbers to new ones, or NULL */
+	const row_log_t*	log,		/*!< in: rebuild context */
 	mem_heap_t*		heap,		/*!< in/out: memory heap */
-	dict_table_t*		new_table,	/*!< in/out: table
-						being rebuilt */
 	dberr_t*		error)		/*!< out: DB_SUCCESS or
 						reason of failure */
 {
 	dtuple_t*	row;
 
 	/* This is based on row_build(). */
-	if (add_cols) {
-		row = dtuple_copy(add_cols, heap);
+	if (log->add_cols) {
+		row = dtuple_copy(log->add_cols, heap);
 		/* dict_table_copy_types() would set the fields to NULL */
-		for (ulint i = 0; i < dict_table_get_n_cols(new_table); i++) {
+		for (ulint i = 0; i < dict_table_get_n_cols(log->table); i++) {
 			dict_col_copy_type(
-				dict_table_get_nth_col(new_table, i),
+				dict_table_get_nth_col(log->table, i),
 				dfield_get_type(dtuple_get_nth_field(row, i)));
 		}
 	} else {
-		row = dtuple_create(heap, dict_table_get_n_cols(new_table));
-		dict_table_copy_types(row, new_table);
+		row = dtuple_create(heap, dict_table_get_n_cols(log->table));
+		dict_table_copy_types(row, log->table);
 	}
 
 	for (ulint i = 0; i < rec_offs_n_fields(offsets); i++) {
@@ -1052,7 +1068,7 @@ row_log_table_apply_convert_mrec(
 		const dict_col_t*	col
 			= dict_field_get_col(ind_field);
 		ulint			col_no
-			= col_map[dict_col_get_no(col)];
+			= log->col_map[dict_col_get_no(col)];
 
 		if (col_no == ULINT_UNDEFINED) {
 			/* dropped column */
@@ -1078,7 +1094,7 @@ row_log_table_apply_convert_mrec(
 
 		/* See if any columns were changed to NULL or NOT NULL. */
 		const dict_col_t*	new_col
-			= dict_table_get_nth_col(new_table, col_no);
+			= dict_table_get_nth_col(log->table, col_no);
 		ut_ad(new_col->mtype == col->mtype);
 
 		/* Assert that prtype matches except for nullability. */
@@ -1131,6 +1147,7 @@ row_log_table_apply_insert_low(
 	dict_index_t*	index	= dict_table_get_first_index(new_table);
 
 	ut_ad(dtuple_validate(row));
+	ut_ad(new_table == dup->index->online_log->table);
 
 #ifdef ROW_LOG_APPLY_PRINT
 	if (row_log_apply_print) {
@@ -1178,7 +1195,7 @@ row_log_table_apply_insert_low(
 /******************************************************//**
 Replays an insert operation on a table that was rebuilt.
 @return DB_SUCCESS or error code */
-static __attribute__((nonnull(1,2,3,4,6,7,8,9), warn_unused_result))
+static __attribute__((nonnull, warn_unused_result))
 dberr_t
 row_log_table_apply_insert(
 /*=======================*/
@@ -1187,26 +1204,20 @@ row_log_table_apply_insert(
 	const ulint*		offsets,	/*!< in: offsets of mrec */
 	mem_heap_t*		offsets_heap,	/*!< in/out: memory heap
 						that can be emptied */
-	const dtuple_t*		add_cols,	/*!< in: default values of
-						added columns, or NULL */
-	const ulint*		col_map,	/*!< in: mapping of old column
-						numbers to new ones, or NULL */
 	mem_heap_t*		heap,		/*!< in/out: memory heap */
-	dict_table_t*		new_table,	/*!< in/out: table
-						being rebuilt */
 	row_merge_dup_t*	dup)		/*!< in/out: for reporting
 						duplicate key errors */
 {
+	const row_log_t*log	= dup->index->online_log;
 	dberr_t		error;
 	const dtuple_t*	row	= row_log_table_apply_convert_mrec(
-		mrec, dup->index, offsets, add_cols, col_map, heap, new_table,
-		&error);
+		mrec, dup->index, offsets, log, heap, &error);
 
 	ut_ad(!row == (error != DB_SUCCESS));
 
 	if (row) {
 		error = row_log_table_apply_insert_low(
-			thr, row, offsets_heap, heap, new_table, dup);
+			thr, row, offsets_heap, heap, log->table, dup);
 	}
 
 	if (error != DB_SUCCESS) {
@@ -1403,7 +1414,7 @@ all_done:
 /******************************************************//**
 Replays an update operation on a table that was rebuilt.
 @return DB_SUCCESS or error code */
-static __attribute__((nonnull(1,4,5,6,8,9,10,11,12), warn_unused_result))
+static __attribute__((nonnull, warn_unused_result))
 dberr_t
 row_log_table_apply_update(
 /*=======================*/
@@ -1418,13 +1429,7 @@ row_log_table_apply_update(
 	const ulint*		offsets,	/*!< in: offsets of mrec */
 	mem_heap_t*		offsets_heap,	/*!< in/out: memory heap
 						that can be emptied */
-	const dtuple_t*		add_cols,	/*!< in: default values of
-						added columns, or NULL */
-	const ulint*		col_map,	/*!< in: mapping of old column
-						numbers to new ones, or NULL */
 	mem_heap_t*		heap,		/*!< in/out: memory heap */
-	dict_table_t*		new_table,	/*!< in/out: table
-						being rebuilt */
 	row_merge_dup_t*	dup,		/*!< in/out: for reporting
 						duplicate key errors */
 	const dtuple_t*		old_pk)		/*!< in: PRIMARY KEY and
@@ -1432,8 +1437,9 @@ row_log_table_apply_update(
 						of the old value,
 						or PRIMARY KEY if same_pk */
 {
+	const row_log_t*log	= dup->index->online_log;
 	const dtuple_t*	row;
-	dict_index_t*	index = dict_table_get_first_index(new_table);
+	dict_index_t*	index	= dict_table_get_first_index(log->table);
 	mtr_t		mtr;
 	btr_pcur_t	pcur;
 	dberr_t		error;
@@ -1445,8 +1451,7 @@ row_log_table_apply_update(
 	      + (dup->index->online_log->same_pk ? 0 : 2));
 
 	row = row_log_table_apply_convert_mrec(
-		mrec, dup->index, offsets, add_cols, col_map,
-		heap, new_table, &error);
+		mrec, dup->index, offsets, log, heap, &error);
 
 	ut_ad(!row == (error != DB_SUCCESS));
 
@@ -1477,7 +1482,7 @@ row_log_table_apply_update(
 insert:
 		/* The row was not found. Insert it. */
 		error = row_log_table_apply_insert_low(
-			thr, row, offsets_heap, heap, new_table, dup);
+			thr, row, offsets_heap, heap, log->table, dup);
 
 		if (error != DB_SUCCESS) {
 err_exit:
@@ -1576,8 +1581,9 @@ delete_insert:
 		the record. */
 		old_row = row_build(ROW_COPY_DATA, index,
 				    btr_pcur_get_rec(&pcur),
-				    cur_offsets, new_table,
-				    add_cols, col_map, &old_ext, heap);
+				    cur_offsets, log->table,
+				    log->add_cols, log->col_map,
+				    &old_ext, heap);
 		ut_ad(old_row);
 	} else {
 		old_row = NULL;
@@ -1667,7 +1673,7 @@ func_exit:
 Applies an operation to a table that was rebuilt.
 @return NULL on failure (mrec corruption) or when out of data;
 pointer to next record on success */
-static __attribute__((nonnull(1,4,6,7,8,9,10,11,12,13), warn_unused_result))
+static __attribute__((nonnull, warn_unused_result))
 const mrec_t*
 row_log_table_apply_op(
 /*===================*/
@@ -1676,12 +1682,6 @@ row_log_table_apply_op(
 						DB_TRX_ID in old index */
 	ulint			new_trx_id_col,	/*!< in: position of
 						DB_TRX_ID in new index */
-	dict_table_t*		new_table,	/*!< in/out: table
-						being rebuilt */
-	const dtuple_t*		add_cols,	/*!< in: default values of
-						added columns, or NULL */
-	const ulint*		col_map,	/*!< in: mapping of old column
-						numbers to new ones, or NULL */
 	row_merge_dup_t*	dup,		/*!< in/out: for reporting
 						duplicate key errors */
 	dberr_t*		error,		/*!< out: DB_SUCCESS
@@ -1694,13 +1694,14 @@ row_log_table_apply_op(
 	ulint*			offsets)	/*!< in/out: work area
 						for parsing mrec */
 {
-	dict_index_t*	new_index = dict_table_get_first_index(new_table);
+	const row_log_t*log	= dup->index->online_log;
+	dict_index_t*	new_index = dict_table_get_first_index(log->table);
 	ulint		extra_size;
 	const mrec_t*	next_mrec;
 	dtuple_t*	old_pk;
 
 	ut_ad(dict_index_is_clust(dup->index));
-	ut_ad(dup->index->table != new_table);
+	ut_ad(dup->index->table != log->table);
 
 	*error = DB_SUCCESS;
 
@@ -1747,8 +1748,7 @@ row_log_table_apply_op(
 				    trx_read_trx_id(db_trx_id))) {
 				*error = row_log_table_apply_insert(
 					thr, mrec, offsets, offsets_heap,
-					add_cols, col_map,
-					heap, new_table, dup);
+					heap, dup);
 			}
 		}
 		break;
@@ -1772,7 +1772,7 @@ row_log_table_apply_op(
 		*error = row_log_table_apply_delete(
 			thr, trx_id_col, new_trx_id_col,
 			mrec, offsets, offsets_heap, heap,
-			new_table);
+			log->table);
 		break;
 	case ROW_T_UPDATE:
 		/* Logically, the log entry consists of the
@@ -1918,8 +1918,7 @@ row_log_table_apply_op(
 				*error = row_log_table_apply_update(
 					thr, trx_id_col, new_trx_id_col,
 					mrec, offsets, offsets_heap,
-					add_cols, col_map,
-					heap, new_table, dup, old_pk);
+					heap, dup, old_pk);
 			}
 		}
 
@@ -1934,16 +1933,11 @@ row_log_table_apply_op(
 /******************************************************//**
 Applies operations to a table was rebuilt.
 @return DB_SUCCESS, or error code on failure */
-static __attribute__((nonnull(1,3,4), warn_unused_result))
+static __attribute__((nonnull, warn_unused_result))
 dberr_t
 row_log_table_apply_ops(
 /*====================*/
 	que_thr_t*	thr,	/*!< in: query graph */
-	const dtuple_t*	add_cols,
-				/*!< in: default values of
-				added columns, or NULL */
-	const ulint*	col_map,/*!< in: mapping of old column
-				numbers to new ones, or NULL */
 	row_merge_dup_t*dup)	/*!< in/out: for reporting duplicate key
 				errors */
 {
@@ -2118,7 +2112,6 @@ all_done:
 		       (&index->online_log->head.buf)[1] - mrec_end);
 		mrec = row_log_table_apply_op(
 			thr, trx_id_col, new_trx_id_col,
-			index->online_log->table, add_cols, col_map,
 			dup, &error, offsets_heap, heap,
 			index->online_log->head.buf,
 			(&index->online_log->head.buf)[1], offsets);
@@ -2217,7 +2210,6 @@ all_done:
 
 		next_mrec = row_log_table_apply_op(
 			thr, trx_id_col, new_trx_id_col,
-			index->online_log->table, add_cols, col_map,
 			dup, &error, offsets_heap, heap,
 			mrec, mrec_end, offsets);
 
@@ -2284,13 +2276,8 @@ row_log_table_apply(
 	que_thr_t*	thr,	/*!< in: query graph */
 	dict_table_t*	old_table,
 				/*!< in: old table */
-	struct TABLE*	table,	/*!< in/out: MySQL table
+	struct TABLE*	table)	/*!< in/out: MySQL table
 				(for reporting duplicates) */
-	const dtuple_t*	add_cols,
-				/*!< in: default values of
-				added columns, or NULL */
-	const ulint*	col_map)/*!< in: mapping of old column
-				numbers to new ones, or NULL */
 {
 	dberr_t		error;
 	dict_index_t*	clust_index;
@@ -2317,7 +2304,7 @@ row_log_table_apply(
 		ut_ad(0);
 		error = DB_ERROR;
 	} else {
-		error = row_log_table_apply_ops(thr, add_cols, col_map, &dup);
+		error = row_log_table_apply_ops(thr, &dup);
 	}
 
 	rw_lock_x_unlock(dict_index_get_lock(clust_index));
@@ -2335,8 +2322,13 @@ row_log_allocate(
 	dict_index_t*	index,	/*!< in/out: index */
 	dict_table_t*	table,	/*!< in/out: new table being rebuilt,
 				or NULL when creating a secondary index */
-	bool		same_pk)/*!< in: whether the definition of the
+	bool		same_pk,/*!< in: whether the definition of the
 				PRIMARY KEY has remained the same */
+	const dtuple_t*	add_cols,
+				/*!< in: default values of
+				added columns, or NULL */
+	const ulint*	col_map)/*!< in: mapping of old column
+				numbers to new ones, or NULL if !table */
 {
 	byte*		buf;
 	row_log_t*	log;
@@ -2346,6 +2338,8 @@ row_log_allocate(
 	ut_ad(dict_index_is_clust(index) == !!table);
 	ut_ad(!table || index->table != table);
 	ut_ad(same_pk || table);
+	ut_ad(!table || col_map);
+	ut_ad(!add_cols || col_map);
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_EX));
 #endif /* UNIV_SYNC_DEBUG */
@@ -2363,6 +2357,8 @@ row_log_allocate(
 	log->trx_rb = NULL;
 	log->table = table;
 	log->same_pk = same_pk;
+	log->add_cols = add_cols;
+	log->col_map = col_map;
 	log->error = DB_SUCCESS;
 	log->max_trx = 0;
 	log->head.block = buf;

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