diff --git a/ChangeLog b/ChangeLog index b9e47c08402..7781f0afaf7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-06-29 The InnoDB Team + + * handler/ha_innodb.cc, mysql-test/innodb_file_format.test, + mysql-test/innodb_file_format.result: + Do not crash on SET GLOBAL innodb_file_format=DEFAULT + or SET GLOBAL innodb_file_format_check=DEFAULT. + 2009-06-29 The InnoDB Team * buf/buf0buf.c, buf/buf0rea.c, lock/lock0lock.c: diff --git a/handler/ha_innodb.cc b/handler/ha_innodb.cc index b61e542691d..2b91dfb04dc 100644 --- a/handler/ha_innodb.cc +++ b/handler/ha_innodb.cc @@ -9345,11 +9345,12 @@ innodb_file_format_name_validate( if (format_id <= DICT_TF_FORMAT_MAX) { - *(uint*) save = format_id; + *static_cast(save) = file_format_input; return(0); } } + *static_cast(save) = NULL; return(1); } @@ -9368,13 +9369,24 @@ innodb_file_format_name_update( const void* save) /*!< in: immediate result from check function */ { + const char* format_name; + ut_a(var_ptr != NULL); ut_a(save != NULL); - ut_a((*(const uint*) save) <= DICT_TF_FORMAT_MAX); - srv_file_format = *(const uint*) save; + format_name = *static_cast(save); - *(const char**) var_ptr + if (format_name) { + uint format_id; + + format_id = innobase_file_format_name_lookup(format_name); + + if (format_id <= DICT_TF_FORMAT_MAX) { + srv_file_format = format_id; + } + } + + *static_cast(var_ptr) = trx_sys_file_format_id_to_name(srv_file_format); } @@ -9415,14 +9427,7 @@ innodb_file_format_check_validate( } else if (innobase_file_format_check_validate( file_format_input)) { - uint format_id; - - format_id = innobase_file_format_name_lookup( - file_format_input); - - ut_a(format_id <= DICT_TF_FORMAT_MAX); - - *(uint*) save = format_id; + *static_cast(save) = file_format_input; return(0); @@ -9436,6 +9441,7 @@ innodb_file_format_check_validate( } } + *static_cast(save) = NULL; return(1); } @@ -9454,19 +9460,39 @@ innodb_file_format_check_update( const void* save) /*!< in: immediate result from check function */ { - uint format_id; + const char* format_name_in; + const char** format_name_out; + uint format_id; ut_a(save != NULL); ut_a(var_ptr != NULL); - format_id = *(const uint*) save; + format_name_in = *static_cast(save); + + if (!format_name_in) { + + return; + } + + format_id = innobase_file_format_name_lookup(format_name_in); + + if (format_id > DICT_TF_FORMAT_MAX) { + /* DEFAULT is "on", which is invalid at runtime. */ + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WRONG_ARGUMENTS, + "Ignoring SET innodb_file_format=%s", + format_name_in); + return; + } + + format_name_out = static_cast(var_ptr); /* Update the max format id in the system tablespace. */ - if (trx_sys_file_format_max_set(format_id, (const char**) var_ptr)) { + if (trx_sys_file_format_max_set(format_id, format_name_out)) { ut_print_timestamp(stderr); fprintf(stderr, " [Info] InnoDB: the file format in the system " - "tablespace is now set to %s.\n", *(char**) var_ptr); + "tablespace is now set to %s.\n", *format_name_out); } } diff --git a/mysql-test/innodb_file_format.result b/mysql-test/innodb_file_format.result new file mode 100644 index 00000000000..9cfac5f001c --- /dev/null +++ b/mysql-test/innodb_file_format.result @@ -0,0 +1,44 @@ +select @@innodb_file_format; +@@innodb_file_format +Antelope +select @@innodb_file_format_check; +@@innodb_file_format_check +Antelope +set global innodb_file_format=antelope; +set global innodb_file_format=barracuda; +set global innodb_file_format=cheetah; +ERROR HY000: Incorrect arguments to SET +select @@innodb_file_format; +@@innodb_file_format +Barracuda +set global innodb_file_format=default; +select @@innodb_file_format; +@@innodb_file_format +Antelope +set global innodb_file_format=on; +ERROR HY000: Incorrect arguments to SET +set global innodb_file_format=off; +ERROR HY000: Incorrect arguments to SET +select @@innodb_file_format; +@@innodb_file_format +Antelope +set global innodb_file_format_check=antelope; +set global innodb_file_format_check=barracuda; +set global innodb_file_format_check=cheetah; +ERROR HY000: Incorrect arguments to SET +select @@innodb_file_format_check; +@@innodb_file_format_check +Barracuda +set global innodb_file_format_check=default; +Warnings: +Warning 1210 Ignoring SET innodb_file_format=on +select @@innodb_file_format_check; +@@innodb_file_format_check +Barracuda +set global innodb_file_format=on; +ERROR HY000: Incorrect arguments to SET +set global innodb_file_format=off; +ERROR HY000: Incorrect arguments to SET +select @@innodb_file_format_check; +@@innodb_file_format_check +Barracuda diff --git a/mysql-test/innodb_file_format.test b/mysql-test/innodb_file_format.test new file mode 100644 index 00000000000..62ce4157183 --- /dev/null +++ b/mysql-test/innodb_file_format.test @@ -0,0 +1,28 @@ +-- source include/have_innodb.inc + +select @@innodb_file_format; +select @@innodb_file_format_check; +set global innodb_file_format=antelope; +set global innodb_file_format=barracuda; +--error ER_WRONG_ARGUMENTS +set global innodb_file_format=cheetah; +select @@innodb_file_format; +set global innodb_file_format=default; +select @@innodb_file_format; +--error ER_WRONG_ARGUMENTS +set global innodb_file_format=on; +--error ER_WRONG_ARGUMENTS +set global innodb_file_format=off; +select @@innodb_file_format; +set global innodb_file_format_check=antelope; +set global innodb_file_format_check=barracuda; +--error ER_WRONG_ARGUMENTS +set global innodb_file_format_check=cheetah; +select @@innodb_file_format_check; +set global innodb_file_format_check=default; +select @@innodb_file_format_check; +--error ER_WRONG_ARGUMENTS +set global innodb_file_format=on; +--error ER_WRONG_ARGUMENTS +set global innodb_file_format=off; +select @@innodb_file_format_check;