summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasil Dimov <vasil.dimov@oracle.com>2010-06-25 11:03:38 +0300
committerVasil Dimov <vasil.dimov@oracle.com>2010-06-25 11:03:38 +0300
commitfc9e36eadb0379d5e3041644afed0f04ec0347d0 (patch)
tree50330bd96033d8b2a4a211afc6ca6d9e870040cc
parent9346aeb58ec5ae5619325464da268aa13740bce7 (diff)
parent42011fb716a751f3e71ce47191a93c6ac6d69d32 (diff)
downloadmariadb-git-fc9e36eadb0379d5e3041644afed0f04ec0347d0.tar.gz
Merge a lost changeset marko.makela@oracle.com-20100624104620-pklunowaigv7quu9
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb_bug54679.result91
-rw-r--r--mysql-test/suite/innodb_plugin/t/innodb_bug54679.test97
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc159
3 files changed, 268 insertions, 79 deletions
diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug54679.result b/mysql-test/suite/innodb_plugin/r/innodb_bug54679.result
new file mode 100644
index 00000000000..14fd32ca469
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/r/innodb_bug54679.result
@@ -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;
diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug54679.test b/mysql-test/suite/innodb_plugin/t/innodb_bug54679.test
new file mode 100644
index 00000000000..863d9847ac1
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/innodb_bug54679.test
@@ -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;
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index 3f8dc97e4b5..aa80814dbe0 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -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 */