Commit ff014f21 authored by calvin's avatar calvin

branches/zip: Implementation of using animal names for innodb_file_format,

described in Mantis#30. Specifically:

- Allow innodb_file_format to take string arguments
- Make innodb_file_format system variable a string instead of a number
- Implement the callback functions
- Update warning messages

Three new functions are implemented:

file_format_name_lookup(): Validate the file format name and return
its corresponding id.

innodb_file_format_check(): Check if it is a valid file format. This
function is registered as a callback with MySQL.

innodb_file_format_update(): Update the global variable using the
"saved" value. This functions is registered as a callback with MySQL.
parent 3c2af842
......@@ -115,6 +115,36 @@ static const long AUTOINC_OLD_STYLE_LOCKING = 0;
static const long AUTOINC_NEW_STYLE_LOCKING = 1;
static const long AUTOINC_NO_LOCKING = 2;
/* List of animal names representing file format. */
const char* file_format_name_map[] = {
"Antelope",
"Barracuda",
"Cheetah",
"Dragon",
"Elk",
"Fox",
"Gazelle",
"Hornet",
"Impala",
"Jaguar",
"Kangaroo",
"Leopard",
"Moose",
"Nautilus",
"Ocelot",
"Porpoise",
"Quail",
"Rabbit",
"Shark",
"Tiger",
"Urchin",
"Viper",
"Whale",
"Xenops",
"Yak",
"Zebra"
};
static long innobase_mirrored_log_groups, innobase_log_files_in_group,
innobase_log_buffer_size,
innobase_additional_mem_pool_size, innobase_file_io_threads,
......@@ -129,6 +159,7 @@ are determined in innobase_init below: */
static char* innobase_data_home_dir = NULL;
static char* innobase_data_file_path = NULL;
static char* innobase_log_group_home_dir = NULL;
static char* innobase_file_format_name = NULL;
/* The following has a misleading name: starting from 4.0.5, this also
affects Windows: */
static char* innobase_unix_file_flush_method = NULL;
......@@ -181,6 +212,49 @@ static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
MEM_ROOT *mem_root);
/****************************************************************
Validate the file format name and return its corresponding id. */
static
uint
file_format_name_lookup(
/*====================*/
/* out: valid file format id*/
const char* format_name); /* in: pointer to file format name */
/*****************************************************************
Check if it is a valid file format. This function is registered as
a callback with MySQL. */
static
int
innodb_file_format_check(
/*=====================*/
/* out: 0 for valid file
format */
THD* thd, /* in: thread handle */
struct st_mysql_sys_var* var, /* in: pointer to system
variable */
void* save, /* out: immediate result
for update function */
struct st_mysql_value* value); /* in: incoming string */
/********************************************************************
Update the global variable using the "saved" value. This functions is
registered as a callback with MySQL. */
static
bool
innodb_file_format_update(
/*======================*/
/* out: should never
fail since it is
already validated */
THD* thd, /* in: thread handle */
struct st_mysql_sys_var* var, /* in: pointer to
system variable */
void* var_ptr, /* out: where the
formal string goes */
void* save); /* in: immediate result
from check function */
/********************************************************************
Return alter table flags supported in an InnoDB database. */
static
......@@ -1550,6 +1624,7 @@ innobase_init(
int err;
bool ret;
char *default_path;
uint format_id;
DBUG_ENTER("innobase_init");
handlerton *innobase_hton= (handlerton *)p;
......@@ -1732,6 +1807,25 @@ innobase_init(
goto error;
}
/* Validate the file format by animal name */
if (innobase_file_format_name != NULL) {
format_id = file_format_name_lookup(innobase_file_format_name);
if (format_id > DICT_TF_FORMAT_MAX) {
sql_print_error("InnoDB: wrong innodb_file_format.");
my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR));
goto error;
}
}
srv_file_format = format_id;
innobase_file_format_name =
(char*) file_format_name_map[srv_file_format];
/* --------------------------------------------------*/
srv_file_flush_method_str = innobase_unix_file_flush_method;
......@@ -5293,7 +5387,8 @@ create_options_are_valid(
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: KEY_BLOCK_SIZE"
" requires innodb_file_format > 0.");
" requires innodb_file_format >"
" Antelope.");
ret = FALSE;
}
......@@ -5328,7 +5423,8 @@ create_options_are_valid(
MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ROW_FORMAT=%s"
" requires innodb_file_format > 0.",
" requires innodb_file_format >"
" Antelope.",
row_format_name);
ret = FALSE;
}
......@@ -5542,7 +5638,8 @@ ha_innobase::create(
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: KEY_BLOCK_SIZE"
" requires innodb_file_format=1.");
" requires innodb_file_format >"
" Antelope.");
flags = 0;
}
......@@ -5612,7 +5709,8 @@ ha_innobase::create(
MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ROW_FORMAT=%s"
" requires innodb_file_format>0.",
" requires innodb_file_format >"
" Antelope.",
row_format_name);
} else {
flags |= DICT_TF_COMPACT
......@@ -8628,6 +8726,119 @@ ha_innobase::check_if_incompatible_data(
return(COMPATIBLE_DATA_YES);
}
/****************************************************************
Validate the file format name and return its corresponding id. */
static
uint
file_format_name_lookup(
/*====================*/
/* out: valid file format id*/
const char* format_name) /* in: pointer to file format name */
{
uint format_id;
char* endp;
ut_a(format_name != NULL);
/* The format name can contain the format id itself instead of
the name and we check for that. */
format_id = (uint) strtoul(format_name, &endp, 10);
/* Check for valid parse. */
if (*endp == '\0' && *format_name != '\0') {
if (format_id <= DICT_TF_FORMAT_MAX) {
return(format_id);
}
} else {
for (format_id = 0; format_id <= DICT_TF_FORMAT_MAX;
format_id++) {
const char* name;
name = file_format_name_map[format_id];
if (!innobase_strcasecmp(format_name, name)) {
return(format_id);
}
}
}
return(DICT_TF_FORMAT_MAX + 1);
}
/*****************************************************************
Check if it is a valid file format. This function is registered as
a callback with MySQL. */
static
int
innodb_file_format_check(
/*=====================*/
/* out: 0 for valid file
format */
THD* thd, /* in: thread handle */
struct st_mysql_sys_var* var, /* in: pointer to system
variable */
void* save, /* out: immediate result
for update function */
struct st_mysql_value* value) /* in: incoming string */
{
char buff[STRING_BUFFER_USUAL_SIZE];
const char* file_format_input;
int len = sizeof(buff);
ut_a(save != NULL);
ut_a(value != NULL);
file_format_input = value->val_str(value, buff, &len);
if (file_format_input != NULL) {
uint format_id;
format_id = file_format_name_lookup(file_format_input);
if (format_id <= DICT_TF_FORMAT_MAX) {
*(uint*) save = format_id;
return(0);
}
}
return(1);
}
/********************************************************************
Update the global variable using the "saved" value. This functions is
registered as a callback with MySQL. */
static
bool
innodb_file_format_update(
/*======================*/
/* out: should never
fail since it is
already validated */
THD* thd, /* in: thread handle */
struct st_mysql_sys_var* var, /* in: pointer to
system variable */
void* var_ptr, /* out: where the
formal string goes */
void* save) /* in: immediate result
from check function */
{
ut_a(var_ptr != NULL);
ut_a(save != NULL);
ut_a((*(uint*) save) <= DICT_TF_FORMAT_MAX);
srv_file_format = *(uint*) save;
(*(char**) var_ptr) = (char*) file_format_name_map[srv_file_format];
return(true);
}
static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
{
innodb_export_status();
......@@ -8679,10 +8890,11 @@ static MYSQL_SYSVAR_BOOL(file_per_table, srv_file_per_table,
"Stores each InnoDB table to an .ibd file in the database dir.",
NULL, NULL, FALSE);
static MYSQL_SYSVAR_UINT(file_format, srv_file_format,
static MYSQL_SYSVAR_STR(file_format, innobase_file_format_name,
PLUGIN_VAR_RQCMDARG,
"File format to use for new tables in .ibd files.",
NULL, NULL, DICT_TF_FORMAT_51, DICT_TF_FORMAT_51, DICT_TF_FORMAT_MAX, 0);
(mysql_var_check_func) &innodb_file_format_check,
(mysql_var_update_func) &innodb_file_format_update, "Antelope");
static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
PLUGIN_VAR_OPCMDARG,
......
set global innodb_file_per_table=off;
set global innodb_file_format=0;
set global innodb_file_format=`0`;
create table t0(a int primary key) engine=innodb row_format=compressed;
Warnings:
Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.
......@@ -8,7 +8,7 @@ create table t00(a int primary key) engine=innodb
key_block_size=4 row_format=compressed;
Warnings:
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format=1.
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4.
Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.
Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT.
......@@ -21,21 +21,21 @@ create table t3(a int primary key) engine=innodb row_format=compact;
create table t4(a int primary key) engine=innodb key_block_size=9;
Warnings:
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format=1.
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=9.
create table t5(a int primary key) engine=innodb
key_block_size=1 row_format=redundant;
Warnings:
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format=1.
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1.
set global innodb_file_per_table=on;
create table t6(a int primary key) engine=innodb
key_block_size=1 row_format=redundant;
Warnings:
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format=1.
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1.
set global innodb_file_format=1;
set global innodb_file_format=`1`;
create table t7(a int primary key) engine=innodb
key_block_size=1 row_format=redundant;
Warnings:
......@@ -131,8 +131,30 @@ INSERT INTO t1 VALUES(
'FOXajs|.7@IR[dmv(2<FPZdnx+5?IS]gq{.8BLV`jt~1;EOYcmw*4>HR\fpz-7AKU_is}0:DNXblv)3=GQ[eoy,6@JT^hr|/9CMWaku(3>IT_ju)4?JU`kv*5@KValw+6ALWbmx,7BMXcny-8CNYdoz.9DOZep{/:EP[fq|0;FQ\gr}1<GR]hs~2=HS^it(4@LXdp|1=IUamy.:FR^jv+7CO[gs(4@LXdp|1=IUamy.:FR^jv+7CO[gs(4@LXdp|1=IUamy.:FR^jv+7CO[gs(5BO\iv,9FS`mz0=JWdq~4AN[hu+8ER_ly/<IVcp}3@MZgt*7DQ^kx.;HUbo|2?LYfs)6CP]jw-:GTan{1>KXer(6DR`n|3AO]ky0>LZhv-;IWes*8FTbp~5CQ_m{2@N\jx/=KYgu,:HVdr)7ESao}4BP^lz1?M[iw.<JXft+9GUcq(7FUds+:IXgv.=L[jy1@O^m|4CRap(7FUds+:IXgv.=L[jy1@O^m|4CRap(7FUds+:IXgv.=L[jy1@O^m|4CRap(8HXhx1AQaq*:JZjz3CScs,<L\l|5EUeu.>N^n~7GWgw0@P`p)9IYiy2BRbr+;K[k{4DTdt-=M]m}6FVfv/?O_o(9J[l}7HYj{5FWhy3DUfw1BSdu/@Qbs->O`q+<M^o):K\m~8IZk|6GXiz4EVgx2CTev0ARct.?Par,=N_p*;L]n(:L^p+=Oas.@Rdv1CUgy4FXj|7I[m(:L^p+=Oas.@Rdv1CUgy4FXj|7');
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
drop table t1;
set global innodb_file_format=`0`;
select @@innodb_file_format;
@@innodb_file_format
Antelope
set global innodb_file_format=`1`;
select @@innodb_file_format;
@@innodb_file_format
Barracuda
set global innodb_file_format=`2`;
ERROR HY000: Incorrect arguments to SET
set global innodb_file_format=`-1`;
ERROR HY000: Incorrect arguments to SET
set global innodb_file_format=`Antelope`;
set global innodb_file_format=`Barracuda`;
set global innodb_file_format=`Cheetah`;
ERROR HY000: Incorrect arguments to SET
set global innodb_file_format=`abc`;
ERROR HY000: Incorrect arguments to SET
set global innodb_file_format=`1a`;
ERROR HY000: Incorrect arguments to SET
set global innodb_file_format=``;
ERROR HY000: Incorrect arguments to SET
set global innodb_file_per_table = on;
set global innodb_file_format = 1;
set global innodb_file_format = `1`;
set innodb_strict_mode = on;
create table t1 (id int primary key) engine = innodb key_block_size = 0;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
......@@ -282,48 +304,48 @@ test t8 Compact
test t9 Redundant
drop table t8, t9;
set global innodb_file_per_table = on;
set global innodb_file_format = 0;
set global innodb_file_format = `0`;
create table t1 (id int primary key) engine = innodb key_block_size = 1;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
show errors;
Level Code Message
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > 0.
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t1' (errno: 1478)
create table t2 (id int primary key) engine = innodb key_block_size = 2;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
show errors;
Level Code Message
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > 0.
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t3 (id int primary key) engine = innodb key_block_size = 4;
ERROR HY000: Can't create table 'test.t3' (errno: 1478)
show errors;
Level Code Message
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > 0.
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t3' (errno: 1478)
create table t4 (id int primary key) engine = innodb key_block_size = 8;
ERROR HY000: Can't create table 'test.t4' (errno: 1478)
show errors;
Level Code Message
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > 0.
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t4' (errno: 1478)
create table t5 (id int primary key) engine = innodb key_block_size = 16;
ERROR HY000: Can't create table 'test.t5' (errno: 1478)
show errors;
Level Code Message
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > 0.
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t5' (errno: 1478)
create table t6 (id int primary key) engine = innodb row_format = compressed;
ERROR HY000: Can't create table 'test.t6' (errno: 1478)
show errors;
Level Code Message
Error 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > 0.
Error 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t6' (errno: 1478)
create table t7 (id int primary key) engine = innodb row_format = dynamic;
ERROR HY000: Can't create table 'test.t7' (errno: 1478)
show errors;
Level Code Message
Error 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > 0.
Error 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t7' (errno: 1478)
create table t8 (id int primary key) engine = innodb row_format = compact;
create table t9 (id int primary key) engine = innodb row_format = redundant;
......@@ -334,5 +356,5 @@ test t8 Compact
test t9 Redundant
drop table t8, t9;
set global innodb_file_per_table=0;
set global innodb_file_format=0;
set global innodb_file_format=Antelope;
set innodb_strict_mode=0;
......@@ -4,7 +4,7 @@ let $per_table=`select @@innodb_file_per_table`;
let $format=`select @@innodb_file_format`;
let $mode=`select @@innodb_strict_mode`;
set global innodb_file_per_table=off;
set global innodb_file_format=0;
set global innodb_file_format=`0`;
create table t0(a int primary key) engine=innodb row_format=compressed;
create table t00(a int primary key) engine=innodb
......@@ -19,7 +19,7 @@ key_block_size=1 row_format=redundant;
set global innodb_file_per_table=on;
create table t6(a int primary key) engine=innodb
key_block_size=1 row_format=redundant;
set global innodb_file_format=1;
set global innodb_file_format=`1`;
create table t7(a int primary key) engine=innodb
key_block_size=1 row_format=redundant;
create table t8(a int primary key) engine=innodb
......@@ -100,10 +100,32 @@ INSERT INTO t1 VALUES(
'FOXajs|.7@IR[dmv(2<FPZdnx+5?IS]gq{.8BLV`jt~1;EOYcmw*4>HR\fpz-7AKU_is}0:DNXblv)3=GQ[eoy,6@JT^hr|/9CMWaku(3>IT_ju)4?JU`kv*5@KValw+6ALWbmx,7BMXcny-8CNYdoz.9DOZep{/:EP[fq|0;FQ\gr}1<GR]hs~2=HS^it(4@LXdp|1=IUamy.:FR^jv+7CO[gs(4@LXdp|1=IUamy.:FR^jv+7CO[gs(4@LXdp|1=IUamy.:FR^jv+7CO[gs(5BO\iv,9FS`mz0=JWdq~4AN[hu+8ER_ly/<IVcp}3@MZgt*7DQ^kx.;HUbo|2?LYfs)6CP]jw-:GTan{1>KXer(6DR`n|3AO]ky0>LZhv-;IWes*8FTbp~5CQ_m{2@N\jx/=KYgu,:HVdr)7ESao}4BP^lz1?M[iw.<JXft+9GUcq(7FUds+:IXgv.=L[jy1@O^m|4CRap(7FUds+:IXgv.=L[jy1@O^m|4CRap(7FUds+:IXgv.=L[jy1@O^m|4CRap(8HXhx1AQaq*:JZjz3CScs,<L\l|5EUeu.>N^n~7GWgw0@P`p)9IYiy2BRbr+;K[k{4DTdt-=M]m}6FVfv/?O_o(9J[l}7HYj{5FWhy3DUfw1BSdu/@Qbs->O`q+<M^o):K\m~8IZk|6GXiz4EVgx2CTev0ARct.?Par,=N_p*;L]n(:L^p+=Oas.@Rdv1CUgy4FXj|7I[m(:L^p+=Oas.@Rdv1CUgy4FXj|7');
drop table t1;
#
# Test innodb_file_format
#
set global innodb_file_format=`0`;
select @@innodb_file_format;
set global innodb_file_format=`1`;
select @@innodb_file_format;
-- error ER_WRONG_ARGUMENTS
set global innodb_file_format=`2`;
-- error ER_WRONG_ARGUMENTS
set global innodb_file_format=`-1`;
set global innodb_file_format=`Antelope`;
set global innodb_file_format=`Barracuda`;
-- error ER_WRONG_ARGUMENTS
set global innodb_file_format=`Cheetah`;
-- error ER_WRONG_ARGUMENTS
set global innodb_file_format=`abc`;
-- error ER_WRONG_ARGUMENTS
set global innodb_file_format=`1a`;
-- error ER_WRONG_ARGUMENTS
set global innodb_file_format=``;
#test strict mode.
--enable_errors
set global innodb_file_per_table = on;
set global innodb_file_format = 1;
set global innodb_file_format = `1`;
#set strict_mode
set innodb_strict_mode = on;
......@@ -215,7 +237,7 @@ drop table t8, t9;
#test valid values with innodb_file_format unset
set global innodb_file_per_table = on;
set global innodb_file_format = 0;
set global innodb_file_format = `0`;
--error ER_CANT_CREATE_TABLE
create table t1 (id int primary key) engine = innodb key_block_size = 1;
......
......@@ -89,7 +89,7 @@ UNIV_INTERN char* srv_arch_dir = NULL;
dictionary tables are in the system tablespace 0 */
UNIV_INTERN my_bool srv_file_per_table;
/* The file format to use on new *.ibd files. */
UNIV_INTERN uint srv_file_format;
UNIV_INTERN uint srv_file_format = 0;
#if DICT_TF_FORMAT_51
# error "DICT_TF_FORMAT_51 must be 0!"
#endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment