List:Commits« Previous MessageNext Message »
From:marko.makela Date:June 24 2010 10:49am
Subject:bzr push into mysql-5.1-innodb branch (marko.makela:3522 to 3524) Bug#54679
View as plain text  
 3524 Marko Mäkelä	2010-06-24
      Add ChangeLog entry for Bug#54679

    modified:
      storage/innodb_plugin/ChangeLog
 3523 Marko Mäkelä	2010-06-24
      Bug#54679: alter table causes compressed row_format to revert to compact
      
      ha_innobase::create(): Add the local variable row_type = form->s->row_type.
      Adjust it to ROW_TYPE_COMPRESSED when ROW_FORMAT is not specified or inherited
      but KEY_BLOCK_SIZE is. Observe the inherited ROW_FORMAT even when it is not
      explicitly specified.
      
      innodb_bug54679.test: New test, to test the bug and to ensure that there are
      no regressions. (The only difference in the test result without the patch
      applied is that the first ALTER TABLE changes ROW_FORMAT to Compact.)

    added:
      mysql-test/suite/innodb_plugin/r/innodb_bug54679.result
      mysql-test/suite/innodb_plugin/t/innodb_bug54679.test
    modified:
      storage/innodb_plugin/handler/ha_innodb.cc
 3522 Jimmy Yang	2010-06-23
      Move the fix for bug #54044 to security branch, and revert commit -r3520:3521.

    removed:
      mysql-test/suite/innodb/r/innodb_bug54044.result
      mysql-test/suite/innodb/t/innodb_bug54044.test
      mysql-test/suite/innodb_plugin/r/innodb_bug54044.result
      mysql-test/suite/innodb_plugin/t/innodb_bug54044.test
    modified:
      storage/innobase/handler/ha_innodb.cc
      storage/innodb_plugin/ChangeLog
      storage/innodb_plugin/handler/ha_innodb.cc
=== added file 'mysql-test/suite/innodb_plugin/r/innodb_bug54679.result'
--- a/mysql-test/suite/innodb_plugin/r/innodb_bug54679.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb_plugin/r/innodb_bug54679.result	revid:marko.makela@oracle.com-20100624104820-p4ojmxcmq8qeos6d
@@ -0,0 +1,91 @@
+SET GLOBAL innodb_file_format='Barracuda';
+SET GLOBAL innodb_file_per_table=ON;
+SET innodb_strict_mode=ON;
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
+WHERE TABLE_NAME='bug54679';
+TABLE_NAME	ROW_FORMAT	CREATE_OPTIONS
+bug54679	Compressed	row_format=COMPRESSED
+ALTER TABLE bug54679 ADD COLUMN b INT;
+SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
+WHERE TABLE_NAME='bug54679';
+TABLE_NAME	ROW_FORMAT	CREATE_OPTIONS
+bug54679	Compressed	row_format=COMPRESSED
+DROP TABLE bug54679;
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB;
+SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
+WHERE TABLE_NAME='bug54679';
+TABLE_NAME	ROW_FORMAT	CREATE_OPTIONS
+bug54679	Compact	
+ALTER TABLE bug54679 KEY_BLOCK_SIZE=1;
+SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
+WHERE TABLE_NAME='bug54679';
+TABLE_NAME	ROW_FORMAT	CREATE_OPTIONS
+bug54679	Compressed	KEY_BLOCK_SIZE=1
+ALTER TABLE bug54679 ROW_FORMAT=REDUNDANT;
+ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+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)
+DROP TABLE bug54679;
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
+WHERE TABLE_NAME='bug54679';
+TABLE_NAME	ROW_FORMAT	CREATE_OPTIONS
+bug54679	Redundant	row_format=REDUNDANT
+ALTER TABLE bug54679 KEY_BLOCK_SIZE=2;
+SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
+WHERE TABLE_NAME='bug54679';
+TABLE_NAME	ROW_FORMAT	CREATE_OPTIONS
+bug54679	Compressed	row_format=REDUNDANT KEY_BLOCK_SIZE=2
+SET GLOBAL innodb_file_format=Antelope;
+ALTER TABLE bug54679 KEY_BLOCK_SIZE=4;
+ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+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)
+ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC;
+ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+SHOW WARNINGS;
+Level	Code	Message
+Warning	1478	InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning	1478	InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
+Warning	1478	InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
+Error	1005	Can't create table '#sql-temporary' (errno: 1478)
+DROP TABLE bug54679;
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+ERROR HY000: Can't create table 'test.bug54679' (errno: 1478)
+SHOW WARNINGS;
+Level	Code	Message
+Warning	1478	InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
+Error	1005	Can't create table 'test.bug54679' (errno: 1478)
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB;
+SET GLOBAL innodb_file_format=Barracuda;
+SET GLOBAL innodb_file_per_table=OFF;
+ALTER TABLE bug54679 KEY_BLOCK_SIZE=4;
+ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+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)
+ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC;
+ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
+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)
+DROP TABLE bug54679;
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+ERROR HY000: Can't create table 'test.bug54679' (errno: 1478)
+SHOW WARNINGS;
+Level	Code	Message
+Warning	1478	InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
+Error	1005	Can't create table 'test.bug54679' (errno: 1478)
+SET GLOBAL innodb_file_per_table=ON;
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+DROP TABLE bug54679;
+SET GLOBAL innodb_file_format=Antelope;
+SET GLOBAL innodb_file_format_check=Antelope;
+SET GLOBAL innodb_file_per_table=0;

=== added file 'mysql-test/suite/innodb_plugin/t/innodb_bug54679.test'
--- a/mysql-test/suite/innodb_plugin/t/innodb_bug54679.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb_plugin/t/innodb_bug54679.test	revid:marko.makela@strippedp4ojmxcmq8qeos6d
@@ -0,0 +1,97 @@
+# Test Bug #54679 alter table causes compressed row_format to revert to compact
+
+--source include/have_innodb_plugin.inc
+
+let $file_format=`select @@innodb_file_format`;
+let $file_format_check=`select @@innodb_file_format_check`;
+let $file_per_table=`select @@innodb_file_per_table`;
+SET GLOBAL innodb_file_format='Barracuda';
+SET GLOBAL innodb_file_per_table=ON;
+SET innodb_strict_mode=ON;
+
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
+WHERE TABLE_NAME='bug54679';
+
+# The ROW_FORMAT of the table should be preserved when it is not specified
+# in ALTER TABLE.
+ALTER TABLE bug54679 ADD COLUMN b INT;
+SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
+WHERE TABLE_NAME='bug54679';
+
+DROP TABLE bug54679;
+
+# Check that the ROW_FORMAT conversion to/from COMPRESSED works.
+
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB;
+SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
+WHERE TABLE_NAME='bug54679';
+
+# KEY_BLOCK_SIZE implies COMPRESSED.
+ALTER TABLE bug54679 KEY_BLOCK_SIZE=1;
+SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
+WHERE TABLE_NAME='bug54679';
+
+--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
+--error ER_CANT_CREATE_TABLE
+ALTER TABLE bug54679 ROW_FORMAT=REDUNDANT;
+--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
+SHOW WARNINGS;
+DROP TABLE bug54679;
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
+WHERE TABLE_NAME='bug54679';
+
+ALTER TABLE bug54679 KEY_BLOCK_SIZE=2;
+SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
+WHERE TABLE_NAME='bug54679';
+
+# This prevents other than REDUNDANT or COMPACT ROW_FORMAT for new tables.
+SET GLOBAL innodb_file_format=Antelope;
+
+--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
+--error ER_CANT_CREATE_TABLE
+ALTER TABLE bug54679 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
+ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC;
+--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
+SHOW WARNINGS;
+DROP TABLE bug54679;
+--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
+--error ER_CANT_CREATE_TABLE
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
+SHOW WARNINGS;
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB;
+
+SET GLOBAL innodb_file_format=Barracuda;
+# This will prevent ROW_FORMAT=COMPRESSED, because the system tablespace
+# cannot be compressed.
+SET GLOBAL innodb_file_per_table=OFF;
+
+--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
+--error ER_CANT_CREATE_TABLE
+ALTER TABLE bug54679 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
+ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC;
+--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
+SHOW WARNINGS;
+DROP TABLE bug54679;
+--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
+--error ER_CANT_CREATE_TABLE
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
+SHOW WARNINGS;
+SET GLOBAL innodb_file_per_table=ON;
+CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+DROP TABLE bug54679;
+
+EVAL SET GLOBAL innodb_file_format=$file_format;
+EVAL SET GLOBAL innodb_file_format_check=$file_format_check;
+EVAL SET GLOBAL innodb_file_per_table=$file_per_table;

=== modified file 'storage/innodb_plugin/ChangeLog'
--- a/storage/innodb_plugin/ChangeLog	revid:jimmy.yang@stripped
+++ b/storage/innodb_plugin/ChangeLog	revid:marko.makela@oracle.com-20100624104820-p4ojmxcmq8qeos6d
@@ -1,3 +1,9 @@
+2010-06-24	The InnoDB Team
+
+	* handler/ha_innodb.cc:
+	Fix Bug#54679 alter table causes compressed row_format to revert
+	to compact
+
 2010-06-22	The InnoDB Team
 
 	* dict/dict0dict.c, dict/dict0mem.c, include/dict0mem.h,

=== modified file 'storage/innodb_plugin/handler/ha_innodb.cc'
--- a/storage/innodb_plugin/handler/ha_innodb.cc	revid:jimmy.yang@stripped
+++ b/storage/innodb_plugin/handler/ha_innodb.cc	revid:marko.makela@stripped
@@ -6460,6 +6460,7 @@ ha_innobase::create(
 	const ulint	file_format = srv_file_format;
 	const char*	stmt;
 	size_t		stmt_len;
+	enum row_type	row_type;
 
 	DBUG_ENTER("ha_innobase::create");
 
@@ -6580,94 +6581,94 @@ ha_innobase::create(
 		}
 	}
 
-	if (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) {
-		if (flags) {
-			/* KEY_BLOCK_SIZE was specified. */
-			if (form->s->row_type != ROW_TYPE_COMPRESSED) {
-				/* ROW_FORMAT other than COMPRESSED
-				ignores KEY_BLOCK_SIZE.  It does not
-				make sense to reject conflicting
-				KEY_BLOCK_SIZE and ROW_FORMAT, because
-				such combinations can be obtained
-				with ALTER TABLE anyway. */
-				push_warning_printf(
-					thd,
-					MYSQL_ERROR::WARN_LEVEL_WARN,
-					ER_ILLEGAL_HA_CREATE_OPTION,
-					"InnoDB: ignoring KEY_BLOCK_SIZE=%lu"
-					" unless ROW_FORMAT=COMPRESSED.",
-					create_info->key_block_size);
-				flags = 0;
-			}
-		} else {
-			/* No KEY_BLOCK_SIZE */
-			if (form->s->row_type == ROW_TYPE_COMPRESSED) {
-				/* ROW_FORMAT=COMPRESSED without
-				KEY_BLOCK_SIZE implies half the
-				maximum KEY_BLOCK_SIZE. */
-				flags = (DICT_TF_ZSSIZE_MAX - 1)
-					<< DICT_TF_ZSSIZE_SHIFT
-					| DICT_TF_COMPACT
-					| DICT_TF_FORMAT_ZIP
-					<< DICT_TF_FORMAT_SHIFT;
+	row_type = form->s->row_type;
+
+	if (flags) {
+		/* KEY_BLOCK_SIZE was specified. */
+		if (!(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) {
+			/* ROW_FORMAT was not specified;
+			default to ROW_FORMAT=COMPRESSED */
+			row_type = ROW_TYPE_COMPRESSED;
+		} else if (row_type != ROW_TYPE_COMPRESSED) {
+			/* ROW_FORMAT other than COMPRESSED
+			ignores KEY_BLOCK_SIZE.  It does not
+			make sense to reject conflicting
+			KEY_BLOCK_SIZE and ROW_FORMAT, because
+			such combinations can be obtained
+			with ALTER TABLE anyway. */
+			push_warning_printf(
+				thd,
+				MYSQL_ERROR::WARN_LEVEL_WARN,
+				ER_ILLEGAL_HA_CREATE_OPTION,
+				"InnoDB: ignoring KEY_BLOCK_SIZE=%lu"
+				" unless ROW_FORMAT=COMPRESSED.",
+				create_info->key_block_size);
+			flags = 0;
+		}
+	} else {
+		/* No KEY_BLOCK_SIZE */
+		if (row_type == ROW_TYPE_COMPRESSED) {
+			/* ROW_FORMAT=COMPRESSED without
+			KEY_BLOCK_SIZE implies half the
+			maximum KEY_BLOCK_SIZE. */
+			flags = (DICT_TF_ZSSIZE_MAX - 1)
+				<< DICT_TF_ZSSIZE_SHIFT
+				| DICT_TF_COMPACT
+				| DICT_TF_FORMAT_ZIP
+				<< DICT_TF_FORMAT_SHIFT;
 #if DICT_TF_ZSSIZE_MAX < 1
 # error "DICT_TF_ZSSIZE_MAX < 1"
 #endif
-			}
 		}
+	}
 
-		switch (form->s->row_type) {
-			const char* row_format_name;
-		case ROW_TYPE_REDUNDANT:
-			break;
-		case ROW_TYPE_COMPRESSED:
-		case ROW_TYPE_DYNAMIC:
-			row_format_name
-				= form->s->row_type == ROW_TYPE_COMPRESSED
-				? "COMPRESSED"
-				: "DYNAMIC";
-
-			if (!srv_file_per_table) {
-				push_warning_printf(
-					thd,
-					MYSQL_ERROR::WARN_LEVEL_WARN,
-					ER_ILLEGAL_HA_CREATE_OPTION,
-					"InnoDB: ROW_FORMAT=%s"
-					" requires innodb_file_per_table.",
-					row_format_name);
-			} else if (file_format < DICT_TF_FORMAT_ZIP) {
-				push_warning_printf(
-					thd,
-					MYSQL_ERROR::WARN_LEVEL_WARN,
-					ER_ILLEGAL_HA_CREATE_OPTION,
-					"InnoDB: ROW_FORMAT=%s"
-					" requires innodb_file_format >"
-					" Antelope.",
-					row_format_name);
-			} else {
-				flags |= DICT_TF_COMPACT
-					| (DICT_TF_FORMAT_ZIP
-					   << DICT_TF_FORMAT_SHIFT);
-				break;
-			}
+	switch (row_type) {
+		const char* row_format_name;
+	case ROW_TYPE_REDUNDANT:
+		break;
+	case ROW_TYPE_COMPRESSED:
+	case ROW_TYPE_DYNAMIC:
+		row_format_name
+			= row_type == ROW_TYPE_COMPRESSED
+			? "COMPRESSED"
+			: "DYNAMIC";
 
-			/* fall through */
-		case ROW_TYPE_NOT_USED:
-		case ROW_TYPE_FIXED:
-		default:
-			push_warning(thd,
-				     MYSQL_ERROR::WARN_LEVEL_WARN,
-				     ER_ILLEGAL_HA_CREATE_OPTION,
-				     "InnoDB: assuming ROW_FORMAT=COMPACT.");
-		case ROW_TYPE_DEFAULT:
-		case ROW_TYPE_COMPACT:
-			flags = DICT_TF_COMPACT;
+		if (!srv_file_per_table) {
+			push_warning_printf(
+				thd,
+				MYSQL_ERROR::WARN_LEVEL_WARN,
+				ER_ILLEGAL_HA_CREATE_OPTION,
+				"InnoDB: ROW_FORMAT=%s"
+				" requires innodb_file_per_table.",
+				row_format_name);
+		} else if (file_format < DICT_TF_FORMAT_ZIP) {
+			push_warning_printf(
+				thd,
+				MYSQL_ERROR::WARN_LEVEL_WARN,
+				ER_ILLEGAL_HA_CREATE_OPTION,
+				"InnoDB: ROW_FORMAT=%s"
+				" requires innodb_file_format >"
+				" Antelope.",
+				row_format_name);
+		} else {
+			flags |= DICT_TF_COMPACT
+				| (DICT_TF_FORMAT_ZIP
+				   << DICT_TF_FORMAT_SHIFT);
 			break;
 		}
-	} else if (!flags) {
-		/* No KEY_BLOCK_SIZE or ROW_FORMAT specified:
-		use ROW_FORMAT=COMPACT by default. */
+
+		/* fall through */
+	case ROW_TYPE_NOT_USED:
+	case ROW_TYPE_FIXED:
+	default:
+		push_warning(thd,
+			     MYSQL_ERROR::WARN_LEVEL_WARN,
+			     ER_ILLEGAL_HA_CREATE_OPTION,
+			     "InnoDB: assuming ROW_FORMAT=COMPACT.");
+	case ROW_TYPE_DEFAULT:
+	case ROW_TYPE_COMPACT:
 		flags = DICT_TF_COMPACT;
+		break;
 	}
 
 	/* Look for a primary key */

Attachment: [text/bzr-bundle] bzr/marko.makela@oracle.com-20100624104820-p4ojmxcmq8qeos6d.bundle
Thread
bzr push into mysql-5.1-innodb branch (marko.makela:3522 to 3524) Bug#54679marko.makela24 Jun