From 66a40d0b8ac73ece279d8a91e3da2aaa9f65ef09 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Fri, 24 Sep 2010 10:44:53 +0100 Subject: [PATCH 001/151] BUG#55263: assert in check_binlog_magic The procedure for setting up a fake binary log, by changing the relay log files manually, is run twice when we issue mtr with --repeat=2. However, when setting it up for the second time, neither the sql thread is reset nor the server is restarted. This means that previous stale relay log IO_CACHE metadata - from first run - is left around. As a consequence, when the test is run for the second time, the IO_CACHE for the relay log has position in file different than zero, triggering the assertion. We fix this by deploying a call to my_b_seek before calling check_binlog_magic in next_event. This prevents the server from asserting, in the cases that the SQL thread was reads from a hot log (relay.NNNNN), then is stopped, then is restarted from a previous cold log (relay.MMMMM), and then it reaches the hot log relay.NNNNN again, in which case, the read coordinates are not set to zero, but to the old values. Additionally, some comments to the source code were added. --- sql/rpl_rli.h | 10 ++++++++ sql/slave.cc | 64 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index 87516c366fb..69988fe5995 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -94,6 +94,16 @@ public: */ MYSQL_BIN_LOG relay_log; LOG_INFO linfo; + + /* + cur_log + Pointer that either points at relay_log.get_log_file() or + &rli->cache_buf, depending on whether the log is hot or there was + the need to open a cold relay_log. + + cache_buf + IO_CACHE used when opening cold relay logs. + */ IO_CACHE cache_buf,*cur_log; /* The following variables are safe to read any time */ diff --git a/sql/slave.cc b/sql/slave.cc index f1e0962e7e8..bd9017e6318 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4349,12 +4349,66 @@ static Log_event* next_event(Relay_log_info* rli) DBUG_ASSERT(rli->cur_log_fd == -1); /* - Read pointer has to be at the start since we are the only - reader. - We must keep the LOCK_log to read the 4 first bytes, as this is a hot - log (same as when we call read_log_event() above: for a hot log we - take the mutex). + When the SQL thread is [stopped and] (re)started the + following may happen: + + 1. Log was hot at stop time and remains hot at restart + + SQL thread reads again from hot_log (SQL thread was + reading from the active log when it was stopped and the + very same log is still active on SQL thread restart). + + In this case, my_b_seek is performed on cur_log, while + cur_log points to relay_log.get_log_file(); + + 2. Log was hot at stop time but got cold before restart + + The log was hot when SQL thread stopped, but it is not + anymore when the SQL thread restarts. + + In this case, the SQL thread reopens the log, using + cache_buf, ie, cur_log points to &cache_buf, and thence + its coordinates are reset. + + 3. Log was already cold at stop time + + The log was not hot when the SQL thread stopped, and, of + course, it will not be hot when it restarts. + + In this case, the SQL thread opens the cold log again, + using cache_buf, ie, cur_log points to &cache_buf, and + thence its coordinates are reset. + + 4. Log was hot at stop time, DBA changes to previous cold + log and restarts SQL thread + + The log was hot when the SQL thread was stopped, but the + user changed the coordinates of the SQL thread to + restart from a previous cold log. + + In this case, at start time, cur_log points to a cold + log, opened using &cache_buf as cache, and coordinates + are reset. However, as it moves on to the next logs, it + will eventually reach the hot log. If the hot log is the + same at the time the SQL thread was stopped, then + coordinates were not reset - the cur_log will point to + relay_log.get_log_file(), and not a freshly opened + IO_CACHE through cache_buf. For this reason we need to + deploy a my_b_seek before calling check_binlog_magic at + this point of the code (see: BUG#55263 for more + details). + + NOTES: + - We must keep the LOCK_log to read the 4 first bytes, as + this is a hot log (same as when we call read_log_event() + above: for a hot log we take the mutex). + + - Because of scenario #4 above, we need to have a + my_b_seek here. Otherwise, we might hit the assertion + inside check_binlog_magic. */ + + my_b_seek(cur_log, (my_off_t) 0); if (check_binlog_magic(cur_log,&errmsg)) { if (!hot_log) pthread_mutex_unlock(log_lock); From 37afe1b34a20ffebe98381629ec615bd5957518a Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Mon, 27 Sep 2010 16:55:09 +0400 Subject: [PATCH 002/151] WL#5341 - Sticky plugins This patch implements "permanent" load option for plugins as specified by WL#5341. mysql-test/r/plugin_load_option.result: A test case for WL#5341. mysql-test/t/plugin_load_option-master.opt: A test case for WL#5341. mysql-test/t/plugin_load_option.test: A test case for WL#5341. sql/share/errmsg-utf8.txt: An error message for WL#5341. sql/sql_plugin.cc: Added FORCE_PLUS_PERMANENT plugin load option. sql/sql_plugin.h: Expose and use plugin load option instead of is_mandatory flag. This is a requirement for to-be-implemented WL5496. --- mysql-test/r/plugin_load_option.result | 2 ++ mysql-test/t/plugin_load_option-master.opt | 3 ++ mysql-test/t/plugin_load_option.test | 5 +++ sql/share/errmsg-utf8.txt | 2 ++ sql/sql_plugin.cc | 39 +++++++++++++--------- sql/sql_plugin.h | 7 +++- 6 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 mysql-test/r/plugin_load_option.result create mode 100644 mysql-test/t/plugin_load_option-master.opt create mode 100644 mysql-test/t/plugin_load_option.test diff --git a/mysql-test/r/plugin_load_option.result b/mysql-test/r/plugin_load_option.result new file mode 100644 index 00000000000..3e49e3c6b47 --- /dev/null +++ b/mysql-test/r/plugin_load_option.result @@ -0,0 +1,2 @@ +UNINSTALL PLUGIN example; +ERROR HY000: Plugin 'example' is force_plus_permanent and can not be unloaded diff --git a/mysql-test/t/plugin_load_option-master.opt b/mysql-test/t/plugin_load_option-master.opt new file mode 100644 index 00000000000..3be53c3b713 --- /dev/null +++ b/mysql-test/t/plugin_load_option-master.opt @@ -0,0 +1,3 @@ +$EXAMPLE_PLUGIN_OPT +$EXAMPLE_PLUGIN_LOAD +--plugin-example=FORCE_PLUS_PERMANENT diff --git a/mysql-test/t/plugin_load_option.test b/mysql-test/t/plugin_load_option.test new file mode 100644 index 00000000000..604be30b561 --- /dev/null +++ b/mysql-test/t/plugin_load_option.test @@ -0,0 +1,5 @@ +--source include/not_windows_embedded.inc +--source include/have_example_plugin.inc + +--error ER_PLUGIN_IS_PERMANENT +UNINSTALL PLUGIN example; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 9e7fdbfeae5..b01b824f236 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6346,3 +6346,5 @@ ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN ER_FAILED_READ_FROM_PAR_FILE eng "Failed to read from the .par file" swe "Misslyckades läsa från .par filen" +ER_PLUGIN_IS_PERMANENT + eng "Plugin '%s' is force_plus_permanent and can not be unloaded" diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 956be657af2..71e2f844168 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -41,9 +41,8 @@ extern struct st_mysql_plugin *mysql_mandatory_plugins[]; @note The order of the enumeration is critical. @see construct_options */ -static const char *global_plugin_typelib_names[]= - { "OFF", "ON", "FORCE", NULL }; -enum enum_plugin_load_policy {PLUGIN_OFF, PLUGIN_ON, PLUGIN_FORCE}; +const char *global_plugin_typelib_names[]= + { "OFF", "ON", "FORCE", "FORCE_PLUS_PERMANENT", NULL }; static TYPELIB global_plugin_typelib= { array_elements(global_plugin_typelib_names)-1, "", global_plugin_typelib_names, NULL }; @@ -796,6 +795,7 @@ static bool plugin_add(MEM_ROOT *tmp_root, tmp.name.length= name_len; tmp.ref_count= 0; tmp.state= PLUGIN_IS_UNINITIALIZED; + tmp.load_option= PLUGIN_ON; if (test_plugin_options(tmp_root, &tmp, argc, argv)) tmp.state= PLUGIN_IS_DISABLED; @@ -1237,7 +1237,7 @@ int plugin_init(int *argc, char **argv, int flags) tmp.name.str= (char *)plugin->name; tmp.name.length= strlen(plugin->name); tmp.state= 0; - tmp.is_mandatory= mandatory; + tmp.load_option= mandatory ? PLUGIN_FORCE : PLUGIN_ON; /* If the performance schema is compiled in, @@ -1256,7 +1256,7 @@ int plugin_init(int *argc, char **argv, int flags) to work, by using '--skip-performance-schema' (the plugin) */ if (!my_strcasecmp(&my_charset_latin1, plugin->name, "PERFORMANCE_SCHEMA")) - tmp.is_mandatory= true; + tmp.load_option= PLUGIN_FORCE; free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE)); if (test_plugin_options(&tmp_root, &tmp, argc, argv)) @@ -1334,7 +1334,8 @@ int plugin_init(int *argc, char **argv, int flags) while ((plugin_ptr= *(--reap))) { mysql_mutex_unlock(&LOCK_plugin); - if (plugin_ptr->is_mandatory) + if (plugin_ptr->load_option == PLUGIN_FORCE || + plugin_ptr->load_option == PLUGIN_FORCE_PLUS_PERMANENT) reaped_mandatory_plugin= TRUE; plugin_deinitialize(plugin_ptr, true); mysql_mutex_lock(&LOCK_plugin); @@ -1844,6 +1845,11 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name) my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str); goto err; } + if (plugin->load_option == PLUGIN_FORCE_PLUS_PERMANENT) + { + my_error(ER_PLUGIN_IS_PERMANENT, MYF(0), name->str); + goto err; + } plugin->state= PLUGIN_IS_DELETED; if (plugin->ref_count) @@ -3054,7 +3060,8 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, plugin_dash.length + 1); strxmov(plugin_name_with_prefix_ptr, plugin_dash.str, plugin_name_ptr, NullS); - if (!tmp->is_mandatory) + if (tmp->load_option != PLUGIN_FORCE && + tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT) { /* support --skip-plugin-foo syntax */ options[0].name= plugin_name_ptr; @@ -3314,7 +3321,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, { struct sys_var_chain chain= { NULL, NULL }; bool disable_plugin; - enum_plugin_load_policy plugin_load_policy= tmp->is_mandatory ? PLUGIN_FORCE : PLUGIN_ON; + enum_plugin_load_option plugin_load_option= tmp->load_option; MEM_ROOT *mem_root= alloc_root_inited(&tmp->mem_root) ? &tmp->mem_root : &plugin_mem_root; @@ -3335,7 +3342,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, */ if (!(my_strcasecmp(&my_charset_latin1, tmp->name.str, "federated") && my_strcasecmp(&my_charset_latin1, tmp->name.str, "ndbcluster"))) - plugin_load_policy= PLUGIN_OFF; + plugin_load_option= PLUGIN_OFF; for (opt= tmp->plugin->system_vars; opt && *opt; opt++) count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */ @@ -3359,8 +3366,9 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, We adjust the default value to account for the hardcoded exceptions we have set for the federated and ndbcluster storage engines. */ - if (!tmp->is_mandatory) - opts[0].def_value= opts[1].def_value= plugin_load_policy; + if (tmp->load_option != PLUGIN_FORCE && + tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT) + opts[0].def_value= opts[1].def_value= plugin_load_option; error= handle_options(argc, &argv, opts, NULL); (*argc)++; /* add back one for the program name */ @@ -3375,12 +3383,13 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, Set plugin loading policy from option value. First element in the option list is always the option value. */ - if (!tmp->is_mandatory) - plugin_load_policy= (enum_plugin_load_policy)*(ulong*)opts[0].value; + if (tmp->load_option != PLUGIN_FORCE && + tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT) + plugin_load_option= (enum_plugin_load_option) *(ulong*) opts[0].value; } - disable_plugin= (plugin_load_policy == PLUGIN_OFF); - tmp->is_mandatory= (plugin_load_policy == PLUGIN_FORCE); + disable_plugin= (plugin_load_option == PLUGIN_OFF); + tmp->load_option= plugin_load_option; /* If the plugin is disabled it should not be initialized. diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index 079dc4e6dca..5fa9afb3066 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -32,6 +32,9 @@ class sys_var; enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED}; +enum enum_plugin_load_option { PLUGIN_OFF, PLUGIN_ON, PLUGIN_FORCE, + PLUGIN_FORCE_PLUS_PERMANENT }; +extern const char *global_plugin_typelib_names[]; #include @@ -95,7 +98,7 @@ struct st_plugin_int void *data; /* plugin type specific, e.g. handlerton */ MEM_ROOT mem_root; /* memory for dynamic plugin structures */ sys_var *system_vars; /* server variables for this plugin */ - bool is_mandatory; /* If true then plugin must not fail to load */ + enum enum_plugin_load_option load_option; /* OFF, ON, FORCE, F+PERMANENT */ }; @@ -110,6 +113,7 @@ typedef struct st_plugin_int *plugin_ref; #define plugin_data(pi,cast) ((cast)((pi)->data)) #define plugin_name(pi) (&((pi)->name)) #define plugin_state(pi) ((pi)->state) +#define plugin_load_option(pi) ((pi)->load_option) #define plugin_equals(p1,p2) ((p1) == (p2)) #else typedef struct st_plugin_int **plugin_ref; @@ -118,6 +122,7 @@ typedef struct st_plugin_int **plugin_ref; #define plugin_data(pi,cast) ((cast)((pi)[0]->data)) #define plugin_name(pi) (&((pi)[0]->name)) #define plugin_state(pi) ((pi)[0]->state) +#define plugin_load_option(pi) ((pi)[0]->load_option) #define plugin_equals(p1,p2) ((p1) && (p2) && (p1)[0] == (p2)[0]) #endif From d9aa82154b02ec2e6bccb0048f9e0c94b6b0af6b Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Mon, 27 Sep 2010 17:03:27 +0400 Subject: [PATCH 003/151] WL#5496 - Plugin LOAD_OPTION in INFORMATION_SCHEMA.PLUGINS This patch implements I_S.PLUGINS.LOAD_OPTION column as specified by WL#5496. mysql-test/r/plugin_load_option.result: A test case for WL#5496. mysql-test/suite/funcs_1/r/is_columns_is.result: Adjusted a test case according to WL#5496. mysql-test/t/plugin_load_option.test: A test case for WL#5496. sql/sql_show.cc: Added LOAD_OPTION column to I_S.PLUGINS. --- mysql-test/r/plugin_load_option.result | 5 +++++ mysql-test/suite/funcs_1/r/is_columns_is.result | 2 ++ mysql-test/t/plugin_load_option.test | 3 +++ sql/sql_show.cc | 6 ++++++ 4 files changed, 16 insertions(+) diff --git a/mysql-test/r/plugin_load_option.result b/mysql-test/r/plugin_load_option.result index 3e49e3c6b47..fec41bac8e6 100644 --- a/mysql-test/r/plugin_load_option.result +++ b/mysql-test/r/plugin_load_option.result @@ -1,2 +1,7 @@ UNINSTALL PLUGIN example; ERROR HY000: Plugin 'example' is force_plus_permanent and can not be unloaded +SELECT PLUGIN_NAME, PLUGIN_STATUS, LOAD_OPTION FROM INFORMATION_SCHEMA.PLUGINS +WHERE PLUGIN_NAME IN ('MyISAM', 'EXAMPLE'); +PLUGIN_NAME PLUGIN_STATUS LOAD_OPTION +MyISAM ACTIVE FORCE +EXAMPLE ACTIVE FORCE_PLUS_PERMANENT diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index ea13b8619ce..ba64ea0887e 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -165,6 +165,7 @@ def information_schema PARTITIONS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 def information_schema PARTITIONS TABLE_ROWS 13 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select def information_schema PARTITIONS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema PARTITIONS UPDATE_TIME 20 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select +def information_schema PLUGINS LOAD_OPTION 11 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select def information_schema PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select @@ -562,6 +563,7 @@ NULL information_schema PARTITIONS CHECKSUM bigint NULL NULL NULL NULL bigint(21 3.0000 information_schema PLUGINS PLUGIN_AUTHOR varchar 64 192 utf8 utf8_general_ci varchar(64) 1.0000 information_schema PLUGINS PLUGIN_DESCRIPTION longtext 4294967295 4294967295 utf8 utf8_general_ci longtext 3.0000 information_schema PLUGINS PLUGIN_LICENSE varchar 80 240 utf8 utf8_general_ci varchar(80) +3.0000 information_schema PLUGINS LOAD_OPTION varchar 64 192 utf8 utf8_general_ci varchar(64) NULL information_schema PROCESSLIST ID bigint NULL NULL NULL NULL bigint(4) 3.0000 information_schema PROCESSLIST USER varchar 16 48 utf8 utf8_general_ci varchar(16) 3.0000 information_schema PROCESSLIST HOST varchar 64 192 utf8 utf8_general_ci varchar(64) diff --git a/mysql-test/t/plugin_load_option.test b/mysql-test/t/plugin_load_option.test index 604be30b561..e49b693b5be 100644 --- a/mysql-test/t/plugin_load_option.test +++ b/mysql-test/t/plugin_load_option.test @@ -3,3 +3,6 @@ --error ER_PLUGIN_IS_PERMANENT UNINSTALL PLUGIN example; + +SELECT PLUGIN_NAME, PLUGIN_STATUS, LOAD_OPTION FROM INFORMATION_SCHEMA.PLUGINS +WHERE PLUGIN_NAME IN ('MyISAM', 'EXAMPLE'); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 6b24e3db7bc..10b918b2505 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -211,6 +211,11 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin, } table->field[9]->set_notnull(); + table->field[10]->store( + global_plugin_typelib_names[plugin_load_option(plugin)], + strlen(global_plugin_typelib_names[plugin_load_option(plugin)]), + cs); + return schema_table_store_record(thd, table); } @@ -7214,6 +7219,7 @@ ST_FIELD_INFO plugin_fields_info[]= {"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, {"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, {"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE}, + {"LOAD_OPTION", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; From 7a64d43ad091bcc7e140a1c7b5cb49158e25a801 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Mon, 4 Oct 2010 10:25:04 +0200 Subject: [PATCH 004/151] Bug #51099 Assertion in mysql_multi_delete_prepare() This assert was triggered if DELETE was done on a view that referenced another view which in turn (directly or indirectly) referenced more than one table. Delete from a view referencing more than one table (a join view) is not supported and is supposed to give ER_VIEW_DELETE_MERGE_VIEW error. Before this error was reported from the multi table delete code, an assert verified that the view from the DELETE statement had more than one underlying table. However, this assert did not take into account that the view could refer to another view which in turn referenced the actual tables. This patch fixes the problem by adjusting the assert to take this possibility into account. This problem was only noticeable on debug builds of the server. On release builds, ER_VIEW_DELETE_MERGE_VIEW was correctly reported. Test case added to delete.test. --- mysql-test/r/delete.result | 15 +++++++++++++++ mysql-test/t/delete.test | 26 ++++++++++++++++++++++++++ sql/sql_delete.cc | 4 +--- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result index 702b9348b7d..5e4adbbd6dc 100644 --- a/mysql-test/r/delete.result +++ b/mysql-test/r/delete.result @@ -509,3 +509,18 @@ CREATE TABLE t3 LIKE t1; DELETE FROM t1.*, test.t2.*, a.* USING t1, t2, t3 AS a; DROP TABLE t1, t2, t3; End of 5.1 tests +# +# Bug#51099 Assertion in mysql_multi_delete_prepare() +# +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1, v2; +CREATE TABLE t1(a INT); +CREATE TABLE t2(b INT); +CREATE VIEW v1 AS SELECT a, b FROM t1, t2; +CREATE VIEW v2 AS SELECT a FROM v1; +DELETE FROM v2; +ERROR HY000: Can not delete from join view 'test.v2' +DELETE v2 FROM v2; +ERROR HY000: Can not delete from join view 'test.v2' +DROP VIEW v2, v1; +DROP TABLE t1, t2; diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test index 15aade73ab7..6a72ae9c38b 100644 --- a/mysql-test/t/delete.test +++ b/mysql-test/t/delete.test @@ -554,3 +554,29 @@ DELETE FROM t1.*, test.t2.*, a.* USING t1, t2, t3 AS a; DROP TABLE t1, t2, t3; --echo End of 5.1 tests + + +--echo # +--echo # Bug#51099 Assertion in mysql_multi_delete_prepare() +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1, v2; +--enable_warnings + +CREATE TABLE t1(a INT); +CREATE TABLE t2(b INT); +CREATE VIEW v1 AS SELECT a, b FROM t1, t2; +CREATE VIEW v2 AS SELECT a FROM v1; + +# This is a normal delete +--error ER_VIEW_DELETE_MERGE_VIEW +DELETE FROM v2; +# This is a multi table delete, check that we get the same error +# This caused the assertion. +--error ER_VIEW_DELETE_MERGE_VIEW +DELETE v2 FROM v2; + +DROP VIEW v2, v1; +DROP TABLE t1, t2; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 2f69bac917e..685ce1c7b42 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -525,9 +525,7 @@ int mysql_multi_delete_prepare(THD *thd) if (!(target_tbl->table= target_tbl->correspondent_table->table)) { DBUG_ASSERT(target_tbl->correspondent_table->view && - target_tbl->correspondent_table->merge_underlying_list && - target_tbl->correspondent_table->merge_underlying_list-> - next_local); + target_tbl->correspondent_table->multitable_view); my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), target_tbl->correspondent_table->view_db.str, target_tbl->correspondent_table->view_name.str); From 94e6f3e4569e7159bceb216891acd1c19743b8fc Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 5 Oct 2010 14:18:16 +0200 Subject: [PATCH 005/151] Bug#55629 5.5.x goes into infinite loop and high cpu after error flushing io cache The reason for the error was incorrect return code from my_win_write() in case of error on 64 bit Windows. Error should be indicated by return code (size_t)-1 == 2^64 -1, but due to cast it was (DWORD)-1 = 2^32 -1 The caller of this function would fail to recognize the error and continue looping. Fix is to return correct error code (size_t)-1 in case of error as expected by caller. Also minimal cleanup is done : my_win_write() now uses the same parameter checks as related functions (0 and overflow handling for count parameter). --- mysys/my_winfile.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/mysys/my_winfile.c b/mysys/my_winfile.c index 6c0b191ca2c..4d80d774dad 100644 --- a/mysys/my_winfile.c +++ b/mysys/my_winfile.c @@ -97,7 +97,7 @@ HANDLE my_get_osfhandle(File fd) static int my_get_open_flags(File fd) { - DBUG_ENTER("my_get_osfhandle"); + DBUG_ENTER("my_get_open_flags"); DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit); DBUG_RETURN(my_file_info[fd].oflag); } @@ -321,7 +321,7 @@ size_t my_win_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset) if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE) DBUG_RETURN(0); /*return 0 at EOF*/ my_osmaperr(lastError); - DBUG_RETURN(-1); + DBUG_RETURN((size_t)-1); } DBUG_RETURN(nBytesRead); } @@ -352,7 +352,7 @@ size_t my_win_read(File Filedes, uchar *Buffer, size_t Count) if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE) DBUG_RETURN(0); /*return 0 at EOF*/ my_osmaperr(lastError); - DBUG_RETURN(-1); + DBUG_RETURN((size_t)-1); } DBUG_RETURN(nBytesRead); } @@ -386,7 +386,7 @@ size_t my_win_pwrite(File Filedes, const uchar *Buffer, size_t Count, if(!WriteFile(hFile, Buffer, (DWORD)Count, &nBytesWritten, &ov)) { my_osmaperr(GetLastError()); - DBUG_RETURN(-1); + DBUG_RETURN((size_t)-1); } else DBUG_RETURN(nBytesWritten); @@ -427,6 +427,15 @@ size_t my_win_write(File fd, const uchar *Buffer, size_t Count) DBUG_ENTER("my_win_write"); DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count %llu", fd, Buffer, (ulonglong)Count)); + + if(!Count) + DBUG_RETURN(0); + +#ifdef _WIN64 + if(Count > UINT_MAX) + Count= UINT_MAX; +#endif + if(my_get_open_flags(fd) & _O_APPEND) { /* @@ -442,10 +451,10 @@ size_t my_win_write(File fd, const uchar *Buffer, size_t Count) hFile= my_get_osfhandle(fd); if(!WriteFile(hFile, Buffer, (DWORD)Count, &nWritten, pov)) { - nWritten= (size_t)-1; my_osmaperr(GetLastError()); + DBUG_RETURN((size_t)-1); } - DBUG_RETURN((size_t)nWritten); + DBUG_RETURN(nWritten); } From 7381a8a38ff5bc765becae9a89fb31cc300af99c Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Tue, 5 Oct 2010 13:38:30 -0500 Subject: [PATCH 006/151] bug#56318: Replication aborts with ER_TOO_BIG_ROWSIZE if innodb parameters don't match Revert the changes of the default values of innodb_file_per_table and innobase_file_format in 5.5, until WL#5135 is implemented. --- .../sys_vars/r/innodb_file_format_basic.result | 14 +++++++------- storage/innobase/handler/ha_innodb.cc | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/innodb_file_format_basic.result b/mysql-test/suite/sys_vars/r/innodb_file_format_basic.result index 41369038cf6..58e009ea705 100644 --- a/mysql-test/suite/sys_vars/r/innodb_file_format_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_file_format_basic.result @@ -1,28 +1,28 @@ SET @start_global_value = @@global.innodb_file_format; SELECT @start_global_value; @start_global_value -Barracuda +Antelope Valid values are 'Antelope' and 'Barracuda' select @@global.innodb_file_format in ('Antelope', 'Barracuda'); @@global.innodb_file_format in ('Antelope', 'Barracuda') 1 select @@global.innodb_file_format; @@global.innodb_file_format -Barracuda +Antelope select @@session.innodb_file_format; ERROR HY000: Variable 'innodb_file_format' is a GLOBAL variable show global variables like 'innodb_file_format'; Variable_name Value -innodb_file_format Barracuda +innodb_file_format Antelope show session variables like 'innodb_file_format'; Variable_name Value -innodb_file_format Barracuda +innodb_file_format Antelope select * from information_schema.global_variables where variable_name='innodb_file_format'; VARIABLE_NAME VARIABLE_VALUE -INNODB_FILE_FORMAT Barracuda +INNODB_FILE_FORMAT Antelope select * from information_schema.session_variables where variable_name='innodb_file_format'; VARIABLE_NAME VARIABLE_VALUE -INNODB_FILE_FORMAT Barracuda +INNODB_FILE_FORMAT Antelope set global innodb_file_format='Antelope'; select @@global.innodb_file_format; @@global.innodb_file_format @@ -56,4 +56,4 @@ ERROR 42000: Variable 'innodb_file_format' can't be set to the value of 'Salmon' SET @@global.innodb_file_format = @start_global_value; SELECT @@global.innodb_file_format; @@global.innodb_file_format -Barracuda +Antelope diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index bbf3c5aa3c8..83fa1853e25 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -10835,13 +10835,13 @@ static MYSQL_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown, static MYSQL_SYSVAR_BOOL(file_per_table, srv_file_per_table, PLUGIN_VAR_NOCMDARG, "Stores each InnoDB table to an .ibd file in the database dir.", - NULL, NULL, TRUE); + NULL, NULL, FALSE); static MYSQL_SYSVAR_STR(file_format, innobase_file_format_name, PLUGIN_VAR_RQCMDARG, "File format to use for new tables in .ibd files.", innodb_file_format_name_validate, - innodb_file_format_name_update, "Barracuda"); + innodb_file_format_name_update, "Antelope"); /* "innobase_file_format_check" decides whether we would continue booting the server if the file format stamped on the system From e53e16a885937a902b10d4ab0293f3ec0905e355 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Wed, 6 Oct 2010 09:56:29 +0200 Subject: [PATCH 007/151] Bug #57002 Assert in upgrade_shared_lock_to_exclusive() for ALTER TABLE + MERGE tables The patch for Bug#56292 changed how metadata locks are taken for MERGE tables. After the patch, locking the MERGE table will also lock the children tables with the same metadata lock type. This means that LOCK TABLES on a MERGE table also will implicitly do LOCK TABLES on the children tables. A consequence of this change, is that it is possible to do LOCK TABLES on a child table both explicitly and implicitly with the same statement and that these two locks can be of different strength. For example, LOCK TABLES child READ, merge WRITE. In LOCK TABLES mode, we are not allowed to take new locks and each statement must therefore try to find an existing TABLE instance with a suitable lock. The code that searched for a suitable TABLE instance, only considered table level locks. If a child table was locked twice, it was therefore possible for this code to find a TABLE instance with suitable table level locks but without suitable metadata lock. This problem caused the assert in upgrade_shared_lock_to_exclusive() to be triggered as it tried to upgrade a MDL_SHARED lock to EXCLUSIVE. The problem was a regression caused by the patch for Bug#56292. This patch fixes the problem by partially reverting the changes done by Bug#56292. Now, the children tables will only use the same metadata lock as the MERGE table for MDL_SHARED_NO_WRITE when not in locked tables mode. This means that LOCK TABLE on a MERGE table will not implicitly lock the children tables. This still fixes the original problem in Bug#56292 without causing a regression. Test case added to merge.test. --- mysql-test/r/merge.result | 15 ++++++++++++++- mysql-test/t/merge.test | 24 +++++++++++++++++++++++- storage/myisammrg/ha_myisammrg.cc | 27 +++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index bb6af084f38..ace834a26c2 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -3486,12 +3486,13 @@ ALTER TABLE m1 ADD INDEX (c1); UNLOCK TABLES; DROP TABLE m1, t1; # -# Locking the merge table will implicitly lock children. +# Locking the merge table won't implicitly lock children. # CREATE TABLE t1 (c1 INT); CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1); LOCK TABLE m1 WRITE; ALTER TABLE t1 ADD INDEX (c1); +ERROR HY000: Table 't1' was locked with a READ lock and can't be updated LOCK TABLE m1 WRITE, t1 WRITE; ALTER TABLE t1 ADD INDEX (c1); UNLOCK TABLES; @@ -3661,4 +3662,16 @@ REPAIR TABLE t2 USE_FRM; Table Op Msg_type Msg_text test.t2 repair note The storage engine for the table doesn't support repair DROP TABLE t1, t2; +# +# Bug#57002 Assert in upgrade_shared_lock_to_exclusive() +# for ALTER TABLE + MERGE tables +# +DROP TABLE IF EXISTS t1, m1; +CREATE TABLE t1(a INT) engine=myisam; +CREATE TABLE m1(a INT) engine=merge UNION(t1); +LOCK TABLES t1 READ, m1 WRITE; +ALTER TABLE t1 engine=myisam; +ERROR HY000: Table 't1' was locked with a READ lock and can't be updated +UNLOCK TABLES; +DROP TABLE m1, t1; End of 6.0 tests diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index 34d0b5bf237..07839257a15 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -2600,11 +2600,12 @@ UNLOCK TABLES; DROP TABLE m1, t1; --echo # ---echo # Locking the merge table will implicitly lock children. +--echo # Locking the merge table won't implicitly lock children. --echo # CREATE TABLE t1 (c1 INT); CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1); LOCK TABLE m1 WRITE; +--error ER_TABLE_NOT_LOCKED_FOR_WRITE ALTER TABLE t1 ADD INDEX (c1); LOCK TABLE m1 WRITE, t1 WRITE; ALTER TABLE t1 ADD INDEX (c1); @@ -2776,6 +2777,27 @@ REPAIR TABLE t2 USE_FRM; DROP TABLE t1, t2; +--echo # +--echo # Bug#57002 Assert in upgrade_shared_lock_to_exclusive() +--echo # for ALTER TABLE + MERGE tables +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1, m1; +--enable_warnings + +CREATE TABLE t1(a INT) engine=myisam; +CREATE TABLE m1(a INT) engine=merge UNION(t1); +LOCK TABLES t1 READ, m1 WRITE; + +# This caused an assert +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +ALTER TABLE t1 engine=myisam; + +UNLOCK TABLES; +DROP TABLE m1, t1; + + --echo End of 6.0 tests --disable_result_log diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 466c66ec769..26e54d61101 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -478,8 +478,31 @@ int ha_myisammrg::add_children_list(void) /* Set the expected table version, to not cause spurious re-prepare. */ child_l->set_table_ref_id(mrg_child_def->get_child_table_ref_type(), mrg_child_def->get_child_def_version()); - /* Use the same metadata lock type for children. */ - child_l->mdl_request.set_type(parent_l->mdl_request.type); + /* + For statements which acquire a SNW metadata lock on a parent table and + then later try to upgrade it to an X lock (e.g. ALTER TABLE), SNW + locks should be also taken on the children tables. + + Otherwise we end up in a situation where the thread trying to upgrade SNW + to X lock on the parent also holds a SR metadata lock and a read + thr_lock.c lock on the child. As a result, another thread might be + blocked on the thr_lock.c lock for the child after successfully acquiring + a SR or SW metadata lock on it. If at the same time this second thread + has a shared metadata lock on the parent table or there is some other + thread which has a shared metadata lock on the parent and is waiting for + this second thread, we get a deadlock. This deadlock cannot be properly + detected by the MDL subsystem as part of the waiting happens within + thr_lock.c. By taking SNW locks on the child tables we ensure that any + thread which waits for a thread doing SNW -> X upgrade, does this within + the MDL subsystem and thus potential deadlocks are exposed to the deadlock + detector. + + We don't do the same thing for SNRW locks as this would allow + DDL on implicitly locked underlying tables of a MERGE table. + */ + if (! thd->locked_tables_mode && + parent_l->mdl_request.type == MDL_SHARED_NO_WRITE) + child_l->mdl_request.set_type(MDL_SHARED_NO_WRITE); /* Link TABLE_LIST object into the children list. */ if (this->children_last_l) child_l->prev_global= this->children_last_l; From 653f14c2659160b1fda7f3fceb0988fa90731d4d Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Wed, 6 Oct 2010 11:01:24 +0200 Subject: [PATCH 008/151] Bug#56452 Assertion failed: thd->transaction.stmt.is_empty() || thd->in_sub_stmt In a precursor patch for Bug#52044 (revid:bzr/kostja@stripped), a number of reorganizations of code was made. In addition some assertions were added to ensure the correct transactional state. The reorganization had a small glitch so statements that was active in the query cache was not followed by a statement commit/rollback (this code was removed). A section in the trans_commit_stmt/trans_rollback_stmt code is to clear the thd->transaction.stmt list of affected storage engines. When a new statement is initiated, an assert introduced by the 523044 patch checks if this list is cleared. When the query cache is accessed, this list may be populated, and since it's not committed it will not be cleared. This fix adds explicit statement commit or rollback for statements that is contained in the query cache. --- mysql-test/r/cache_innodb.result | 11 +++++++++++ mysql-test/t/cache_innodb.test | 15 +++++++++++++++ sql/sql_cache.cc | 10 ++++++++++ 3 files changed, 36 insertions(+) diff --git a/mysql-test/r/cache_innodb.result b/mysql-test/r/cache_innodb.result index 600ed84c3c9..293d7a3f412 100644 --- a/mysql-test/r/cache_innodb.result +++ b/mysql-test/r/cache_innodb.result @@ -220,3 +220,14 @@ Variable_name Value Qcache_hits 1 set GLOBAL query_cache_size=1048576; drop table t2; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +BEGIN; +INSERT INTO t1 VALUES(1); +ROLLBACK WORK AND CHAIN NO RELEASE; +SELECT a FROM t1; +a +ROLLBACK WORK AND CHAIN NO RELEASE; +SELECT a FROM t1; +a +ROLLBACK; +DROP TABLE t1; diff --git a/mysql-test/t/cache_innodb.test b/mysql-test/t/cache_innodb.test index 33a328d1d6c..f7102627506 100644 --- a/mysql-test/t/cache_innodb.test +++ b/mysql-test/t/cache_innodb.test @@ -14,3 +14,18 @@ let $engine_type= InnoDB; let $test_foreign_keys= 1; --source include/query_cache.inc + +# +# Bug#56452 Assertion failed: thd->transaction.stmt.is_empty() || +# thd->in_sub_stmt +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +BEGIN; + INSERT INTO t1 VALUES(1); +ROLLBACK WORK AND CHAIN NO RELEASE; +SELECT a FROM t1; +ROLLBACK WORK AND CHAIN NO RELEASE; +SELECT a FROM t1; +ROLLBACK; +DROP TABLE t1; + diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index b57c851edf4..a10e470afd4 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -341,6 +341,7 @@ TODO list: #include "../storage/myisammrg/ha_myisammrg.h" #include "../storage/myisammrg/myrg_def.h" #include "probes_mysql.h" +#include "transaction.h" #ifdef EMBEDDED_LIBRARY #include "emb_qcache.h" @@ -1683,6 +1684,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", } else thd->lex->safe_to_cache_query= 0; // Don't try to cache this + /* End the statement transaction potentially started by engine. */ + trans_rollback_stmt(thd); goto err_unlock; // Parse query } else @@ -1724,6 +1727,13 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", thd->limit_found_rows = query->found_rows(); thd->status_var.last_query_cost= 0.0; + /* + End the statement transaction potentially started by an + engine callback. We ignore the return value for now, + since as long as EOF packet is part of the query cache + response, we can't handle it anyway. + */ + (void) trans_commit_stmt(thd); if (!thd->stmt_da->is_set()) thd->stmt_da->disable_status(); From 9665bee50c08b0c63cafc010a0209f098eb77220 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Wed, 6 Oct 2010 11:19:51 +0100 Subject: [PATCH 009/151] BUG#57098 RBR breaks on changing user password on 5.1 master -> 5.5 slave Backported the patch for BUG#55452. --- sql/sql_acl.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index b507b70d1fb..ea002f59fe3 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1593,6 +1593,7 @@ bool change_password(THD *thd, const char *host, const char *user, /* Buffer should be extended when password length is extended. */ char buff[512]; ulong query_length; + bool save_binlog_row_based; uint new_password_len= (uint) strlen(new_password); bool result= 1; DBUG_ENTER("change_password"); @@ -1628,6 +1629,14 @@ bool change_password(THD *thd, const char *host, const char *user, if (!(table= open_ltable(thd, &tables, TL_WRITE, 0))) DBUG_RETURN(1); + /* + This statement will be replicated as a statement, even when using + row-based replication. The flag will be reset at the end of the + statement. + */ + if ((save_binlog_row_based= thd->current_stmt_binlog_row_based)) + thd->clear_current_stmt_binlog_row_based(); + VOID(pthread_mutex_lock(&acl_cache->lock)); ACL_USER *acl_user; if (!(acl_user= find_acl_user(host, user, TRUE))) @@ -1663,6 +1672,12 @@ bool change_password(THD *thd, const char *host, const char *user, } end: close_thread_tables(thd); + + /* Restore the state of binlog format */ + DBUG_ASSERT(!thd->current_stmt_binlog_row_based); + if (save_binlog_row_based) + thd->set_current_stmt_binlog_row_based(); + DBUG_RETURN(result); } From 6c97cdf39c74a5b2a0fd4d065ad3072765c07ae9 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Wed, 6 Oct 2010 11:48:46 +0100 Subject: [PATCH 010/151] BUG#52202: mysqlbinlog_row* fail in daily-trunk on Sol10 x86_64 debug_max Removed test cases affected by this bug from experimental list. --- mysql-test/collections/default.experimental | 3 --- 1 file changed, 3 deletions(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index b292356f1c7..48e10511b80 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -15,9 +15,6 @@ main.lock_multi_bug38499 # Bug#47448 2009-09-19 alik main.lock_m main.lock_multi_bug38691 @solaris # Bug#47792 2009-10-02 alik main.lock_multi_bug38691 times out sporadically on Solaris 10 main.log_tables # Bug#47924 2009-10-08 alik main.log_tables times out sporadically main.lowercase_table2 @darwin # Bug#55509 2010-07-26 alik main.lowercase_table2 fails on Mac OSX (again) -main.mysqlbinlog_row @solaris # Bug#52202 2010-03-22 alik mysqlbinlog_row* fail in daily-trunk on Sol10 x86_64 debug_max -main.mysqlbinlog_row_innodb @solaris # Bug#52202 2010-03-22 alik mysqlbinlog_row* fail in daily-trunk on Sol10 x86_64 debug_max -main.mysqlbinlog_row_myisam @solaris # Bug#52202 2010-03-22 alik mysqlbinlog_row* fail in daily-trunk on Sol10 x86_64 debug_max main.outfile_loaddata @solaris # Bug#46895 2010-01-20 alik Test "outfile_loaddata" fails (reproducible) main.signal_demo3 @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun main.sp @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun From c93eecdf0ad4d0c8fdee057ddb9eca258a29bd88 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Wed, 6 Oct 2010 12:23:46 +0100 Subject: [PATCH 011/151] BUG#38718: slave sql thread crashes when reading relay log Suprisingly, a Slave_log_event would show up in the binary log. This event is never used and should not appear in the logs. As such, when the slave (or the mysqlbinlog tool) reads the event, it will hit an invalid pointer (reference to the descriptor event when deserializing the Slave_log_event was purposodely set to NULL). The presence of the Slave_log_event denotes a corrupted log, but we cannot tell how the log got corrupted in the first place. However, we can make the server cope with such events when it reads them - in case of log corruption - and fail gracefully. This patch makes the server/mysqlbinlog to report that it has found an invalid log event when Slave_log_event is read. --- sql/log_event.cc | 14 ++++++++++---- sql/log_event.h | 4 +++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 7becdf51747..98ce3fbade8 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1225,7 +1225,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len, break; #ifdef HAVE_REPLICATION case SLAVE_EVENT: /* can never happen (unused event) */ - ev = new Slave_log_event(buf, event_len); + ev = new Slave_log_event(buf, event_len, description_event); break; #endif /* HAVE_REPLICATION */ case CREATE_FILE_EVENT: @@ -1313,8 +1313,10 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len, (because constructor is "void") ; so instead we leave the pointer we wanted to allocate (e.g. 'query') to 0 and we test it in is_valid(). Same for Format_description_log_event, member 'post_header_len'. + + SLAVE_EVENT is never used, so it should not be read ever. */ - if (!ev || !ev->is_valid()) + if (!ev || !ev->is_valid() || (event_type == SLAVE_EVENT)) { DBUG_PRINT("error",("Found invalid event in binary log")); @@ -5978,8 +5980,12 @@ void Slave_log_event::init_from_mem_pool(int data_size) /** This code is not used, so has not been updated to be format-tolerant. */ -Slave_log_event::Slave_log_event(const char* buf, uint event_len) - :Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0) +/* We are using description_event so that slave does not crash on Log_event + constructor */ +Slave_log_event::Slave_log_event(const char* buf, + uint event_len, + const Format_description_log_event* description_event) + :Log_event(buf,description_event),mem_pool(0),master_host(0) { if (event_len < LOG_EVENT_HEADER_LEN) return; diff --git a/sql/log_event.h b/sql/log_event.h index 816a241e55d..662fec23639 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1782,7 +1782,9 @@ public: void print(FILE* file, PRINT_EVENT_INFO* print_event_info); #endif - Slave_log_event(const char* buf, uint event_len); + Slave_log_event(const char* buf, + uint event_len, + const Format_description_log_event *description_event); ~Slave_log_event(); int get_data_size(); bool is_valid() const { return master_host != 0; } From 401e6c909caad8f4d43a28d02ef51264d08cab3a Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 6 Oct 2010 16:15:59 +0400 Subject: [PATCH 012/151] Bug#55744 GROUP_CONCAT + CASE + ucs return garbage Problem: CASE didn't work with a mixture of different character sets in THEN/ELSE in some cases. This happened because after character set aggregation newly created Item_func_conv_charset items corresponding to THEN/ELSE arguments were not put back to args[] array. Fix: put all Item_func_conv_charset back to args[]. @ mysql-test/include/ctype_numconv.inc @ mysql-test/r/ctype_ucs.result Adding tests @ sql/item_cmpfunc.cc Put "agg" back to args[] after character set aggregation. --- mysql-test/include/ctype_numconv.inc | 7 +------ mysql-test/r/ctype_ucs.result | 3 +++ sql/item_cmpfunc.cc | 8 ++++++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/mysql-test/include/ctype_numconv.inc b/mysql-test/include/ctype_numconv.inc index 06a9107e963..c4a39879947 100644 --- a/mysql-test/include/ctype_numconv.inc +++ b/mysql-test/include/ctype_numconv.inc @@ -1635,12 +1635,7 @@ CREATE TABLE t1 (a MEDIUMINT NULL) ENGINE=MYISAM; INSERT INTO t1 VALUES (1234567); SELECT GROUP_CONCAT(IFNULL(a,'')) FROM t1; SELECT GROUP_CONCAT(IF(a,a,'')) FROM t1; -if (`SELECT @@character_set_connection != 'ucs2'`) -{ - # Temporarily disable for ucs2 - # For details, see Bug#55744 GROUP_CONCAT + CASE + ucs return garbage - SELECT GROUP_CONCAT(CASE WHEN a THEN a ELSE '' END) FROM t1; -} +SELECT GROUP_CONCAT(CASE WHEN a THEN a ELSE '' END) FROM t1; --enable_metadata SELECT COALESCE(a,'') FROM t1 GROUP BY 1; --disable_metadata diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 1215eb1db02..c2fb90ecfa6 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -3853,6 +3853,9 @@ GROUP_CONCAT(IFNULL(a,'')) SELECT GROUP_CONCAT(IF(a,a,'')) FROM t1; GROUP_CONCAT(IF(a,a,'')) 1234567 +SELECT GROUP_CONCAT(CASE WHEN a THEN a ELSE '' END) FROM t1; +GROUP_CONCAT(CASE WHEN a THEN a ELSE '' END) +1234567 SELECT COALESCE(a,'') FROM t1 GROUP BY 1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def COALESCE(a,'') 253 9 7 Y 0 31 8 diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index b7aad733e67..b04ec105468 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -3029,6 +3029,14 @@ void Item_func_case::fix_length_and_dec() { if (agg_arg_charsets_for_string_result(collation, agg, nagg)) return; + /* + Copy all THEN and ELSE items back to args[] array. + Some of the items might have been changed to Item_func_conv_charset. + */ + for (nagg= 0 ; nagg < ncases / 2 ; nagg++) + args[nagg * 2 + 1]= agg[nagg]; + if (else_expr_num != -1) + args[else_expr_num]= agg[nagg++]; } else collation.set_numeric(); From 84662b98040ac335af659a7f5a36b887ffe57155 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 6 Oct 2010 15:15:27 +0200 Subject: [PATCH 013/151] Bug#55647:CMake build rebuilds some libraries twice for embedded A simple version of the patch : add WITH_PIC to debug compilation. Engines that are not dependent on internal stuff (like THD structure) will not be recompiled for embedded in debug mode. Examples of such engines are : archive, federated, innodb. Engines with dependencies on internals (myisam,heap,myisammrg) will still be fully recompiled. --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5eddad4ad15..ea544ebcbbf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,11 @@ SET(BUILDTYPE_DOCSTRING IF(WITH_DEBUG) SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING ${BUILDTYPE_DOCSTRING} FORCE) + IF(UNIX AND NOT APPLE) + # Compiling with PIC speeds up embedded build, on PIC sensitive systems + # Predefine it to ON, in case user chooses to build embedded. + SET(WITH_PIC ON CACHE BOOL "Compile with PIC") + ENDIF() SET(OLD_WITH_DEBUG 1 CACHE INTERNAL "" FORCE) ELSEIF(NOT HAVE_CMAKE_BUILD_TYPE OR OLD_WITH_DEBUG) IF(CUSTOM_C_FLAGS) From a5efb91deaf8a9c3bf53cd82ebd574be0cdabc5d Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 6 Oct 2010 11:34:28 -0300 Subject: [PATCH 014/151] Bug#49938: Failing assertion: inode or deadlock in fsp/fsp0fsp.c Bug#54678: InnoDB, TRUNCATE, ALTER, I_S SELECT, crash or deadlock - Incompatible change: truncate no longer resorts to a row by row delete if the storage engine does not support the truncate method. Consequently, the count of affected rows does not, in any case, reflect the actual number of rows. - Incompatible change: it is no longer possible to truncate a table that participates as a parent in a foreign key constraint, unless it is a self-referencing constraint (both parent and child are in the same table). To work around this incompatible change and still be able to truncate such tables, disable foreign checks with SET foreign_key_checks=0 before truncate. Alternatively, if foreign key checks are necessary, please use a DELETE statement without a WHERE condition. Problem description: The problem was that for storage engines that do not support truncate table via a external drop and recreate, such as InnoDB which implements truncate via a internal drop and recreate, the delete_all_rows method could be invoked with a shared metadata lock, causing problems if the engine needed exclusive access to some internal metadata. This problem originated with the fact that there is no truncate specific handler method, which ended up leading to a abuse of the delete_all_rows method that is primarily used for delete operations without a condition. Solution: The solution is to introduce a truncate handler method that is invoked when the engine does not support truncation via a table drop and recreate. This method is invoked under a exclusive metadata lock, so that there is only a single instance of the table when the method is invoked. Also, the method is not invoked and a error is thrown if the table is a parent in a non-self-referencing foreign key relationship. This was necessary to avoid inconsistency as some integrity checks are bypassed. This is inline with the fact that truncate is primarily a DDL operation that was designed to quickly remove all data from a table. mysql-test/suite/innodb/t/innodb-truncate.test: Add test cases for truncate and foreign key checks. Also test that InnoDB resets auto-increment on truncate. mysql-test/suite/innodb/t/innodb.test: FK is not necessary, test is related to auto-increment. Update error number, truncate is no longer invoked if table is parent in a FK relationship. mysql-test/suite/innodb/t/innodb_mysql.test: Update error number, truncate is no longer invoked if table is parent in a FK relationship. Use delete instead of truncate, test is used to check the interaction of FKs, triggers and delete. mysql-test/suite/parts/inc/partition_check.inc: Fix typo. mysql-test/suite/sys_vars/t/foreign_key_checks_func.test: Update error number, truncate is no longer invoked if table is parent in a FK relationship. mysql-test/t/mdl_sync.test: Modify test case to reflect and ensure that truncate takes a exclusive metadata lock. mysql-test/t/trigger-trans.test: Update error number, truncate is no longer invoked if table is parent in a FK relationship. sql/ha_partition.cc: Reorganize the various truncate methods. delete_all_rows is now passed directly to the underlying engines, so as truncate. The code responsible for truncating individual partitions is moved to ha_partition::truncate_partition, which is invoked when a ALTER TABLE t1 TRUNCATE PARTITION p statement is executed. Since the partition truncate no longer can be invoked via delete, the bitmap operations are not necessary anymore. The explicit reset of the auto-increment value is also removed as the underlying engines are now responsible for reseting the value. sql/handler.cc: Wire up the handler truncate method. sql/handler.h: Introduce and document the truncate handler method. It assumes certain use cases of delete_all_rows. Add method to retrieve the list of foreign keys referencing a table. Method is used to avoid truncating tables that are parent in a foreign key relationship. sql/share/errmsg-utf8.txt: Add error message for truncate and FK. sql/sql_lex.h: Introduce a flag so that the partition engine can detect when a partition is being truncated. Used to give a special error. sql/sql_parse.cc: Function mysql_truncate_table no longer exists. sql/sql_partition_admin.cc: Implement the TRUNCATE PARTITION statement. sql/sql_truncate.cc: Change the truncate table implementation to use the new truncate handler method and to not rely on row-by-row delete anymore. The truncate handler method is always invoked with a exclusive metadata lock. Also, it is no longer possible to truncate a table that is parent in some non-self-referencing foreign key. storage/archive/ha_archive.cc: Rename method as the description indicates that in the future this could be a truncate operation. storage/blackhole/ha_blackhole.cc: Implement truncate as no operation for the blackhole engine in order to remain compatible with older releases. storage/federated/ha_federated.cc: Introduce truncate method that invokes delete_all_rows. This is required to support partition truncate as this form of truncate does not implement the drop and recreate protocol. storage/heap/ha_heap.cc: Introduce truncate method that invokes delete_all_rows. This is required to support partition truncate as this form of truncate does not implement the drop and recreate protocol. storage/ibmdb2i/ha_ibmdb2i.cc: Introduce truncate method that invokes delete_all_rows. This is required to support partition truncate as this form of truncate does not implement the drop and recreate protocol. storage/innobase/handler/ha_innodb.cc: Rename delete_all_rows to truncate. InnoDB now does truncate under a exclusive metadata lock. Introduce and reorganize methods used to retrieve the list of foreign keys referenced by a or referencing a table. storage/myisammrg/ha_myisammrg.cc: Introduce truncate method that invokes delete_all_rows. This is required in order to remain compatible with earlier releases where truncate would resort to a row-by-row delete. --- mysql-test/r/mdl_sync.result | 10 +- mysql-test/r/sp_trans.result | 17 + mysql-test/r/trigger-trans.result | 5 + .../suite/innodb/r/innodb-truncate.result | 68 +++ mysql-test/suite/innodb/r/innodb.result | 12 +- mysql-test/suite/innodb/r/innodb_mysql.result | 21 +- .../suite/innodb/t/innodb-truncate.test | 65 +++ mysql-test/suite/innodb/t/innodb.test | 13 +- mysql-test/suite/innodb/t/innodb_mysql.test | 19 +- .../suite/parts/inc/partition_check.inc | 10 +- .../sys_vars/r/foreign_key_checks_func.result | 2 +- .../sys_vars/t/foreign_key_checks_func.test | 2 +- mysql-test/t/mdl_sync.test | 15 +- mysql-test/t/sp_trans.test | 24 + mysql-test/t/trigger-trans.test | 5 + sql/ha_partition.cc | 192 +++---- sql/ha_partition.h | 10 + sql/handler.cc | 15 + sql/handler.h | 58 ++- sql/share/errmsg-utf8.txt | 3 + sql/sql_lex.h | 1 + sql/sql_parse.cc | 3 +- sql/sql_partition_admin.cc | 95 +++- sql/sql_partition_admin.h | 6 +- sql/sql_show.cc | 12 +- sql/sql_string.h | 8 +- sql/sql_truncate.cc | 487 +++++++++--------- sql/sql_truncate.h | 23 +- sql/sql_yacc.yy | 2 +- sql/table.h | 4 +- storage/archive/ha_archive.cc | 4 +- storage/archive/ha_archive.h | 2 +- storage/blackhole/ha_blackhole.cc | 10 + storage/blackhole/ha_blackhole.h | 1 + storage/example/ha_example.cc | 93 ++-- storage/example/ha_example.h | 1 + storage/federated/ha_federated.cc | 10 + storage/federated/ha_federated.h | 1 + storage/heap/ha_heap.cc | 7 + storage/heap/ha_heap.h | 1 + storage/ibmdb2i/db2i_constraints.cc | 4 +- storage/ibmdb2i/ha_ibmdb2i.cc | 7 + storage/innobase/handler/ha_innodb.cc | 311 ++++++----- storage/innobase/handler/ha_innodb.h | 4 +- storage/innobase/row/row0mysql.c | 3 +- storage/myisam/ha_myisam.cc | 12 + storage/myisam/ha_myisam.h | 1 + storage/myisammrg/ha_myisammrg.cc | 16 + storage/myisammrg/ha_myisammrg.h | 1 + storage/perfschema/ha_perfschema.cc | 5 + storage/perfschema/ha_perfschema.h | 2 + 51 files changed, 1095 insertions(+), 608 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb-truncate.result create mode 100644 mysql-test/suite/innodb/t/innodb-truncate.test diff --git a/mysql-test/r/mdl_sync.result b/mysql-test/r/mdl_sync.result index de57e3859b7..d2a32c25201 100644 --- a/mysql-test/r/mdl_sync.result +++ b/mysql-test/r/mdl_sync.result @@ -2632,7 +2632,8 @@ DROP TABLE IF EXISTS t1; CREATE TABLE t1 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1),(2),(3); # Connection: con1 -SET debug_sync='lock_table_for_truncate SIGNAL parked_truncate WAIT_FOR go_truncate'; +LOCK TABLES t1 WRITE; +SET debug_sync='upgrade_lock_for_truncate SIGNAL parked_truncate WAIT_FOR go_truncate'; TRUNCATE TABLE t1; # Connection: default SET debug_sync='now WAIT_FOR parked_truncate'; @@ -2647,10 +2648,11 @@ FLUSH TABLES t1; # Connection: default SET debug_sync='now WAIT_FOR parked_flush'; SET debug_sync='now SIGNAL go_truncate'; -# Connection: con1 -# Reaping... -# Connection: default +# Ensure that truncate waits for a exclusive lock SET debug_sync= 'now SIGNAL go_show'; +# Connection: con1 (TRUNCATE) +# Reaping... +UNLOCK TABLES; # Connection: con2 (SHOW FIELDS FROM t1) # Reaping... Field Type Null Key Default Extra diff --git a/mysql-test/r/sp_trans.result b/mysql-test/r/sp_trans.result index 4fa91121f50..4163725a196 100644 --- a/mysql-test/r/sp_trans.result +++ b/mysql-test/r/sp_trans.result @@ -585,3 +585,20 @@ UPDATE t1_aux SET f2 = 2 WHERE f1 = f1_two_inserts()| ERROR 23000: Column 'f2' cannot be null DROP TABLE t1_aux, t1_not_null| DROP FUNCTION f1_two_inserts| +# +# Bug#49938: Failing assertion: inode or deadlock in fsp/fsp0fsp.c +# +DROP PROCEDURE IF EXISTS p1| +DROP TABLE IF EXISTS t1| +CREATE TABLE t1 (a INT) ENGINE=INNODB| +CREATE PROCEDURE p1() +BEGIN +TRUNCATE TABLE t1; +END| +LOCK TABLES t1 WRITE| +CALL p1()| +FLUSH TABLES; +UNLOCK TABLES| +CALL p1()| +DROP PROCEDURE p1| +DROP TABLE t1| diff --git a/mysql-test/r/trigger-trans.result b/mysql-test/r/trigger-trans.result index 2c4e355af9d..722ac79854d 100644 --- a/mysql-test/r/trigger-trans.result +++ b/mysql-test/r/trigger-trans.result @@ -151,9 +151,14 @@ CREATE TRIGGER t1_ad AFTER DELETE ON t1 FOR EACH ROW SET @b = 1; SET @a = 0; SET @b = 0; TRUNCATE t1; +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `test`.`t1` (`a`)) SELECT @a, @b; @a @b 0 0 +DELETE FROM t1; +SELECT @a, @b; +@a @b +1 1 INSERT INTO t1 VALUES (1); DELETE FROM t1; SELECT @a, @b; diff --git a/mysql-test/suite/innodb/r/innodb-truncate.result b/mysql-test/suite/innodb/r/innodb-truncate.result new file mode 100644 index 00000000000..f63e9272850 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-truncate.result @@ -0,0 +1,68 @@ +# +# TRUNCATE TABLE +# +# Truncating is disallowed for parent tables unless such table +# participates in self-referencing foreign keys only. +# +CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=INNODB; +CREATE TABLE t2 (fk INT NOT NULL, FOREIGN KEY (fk) REFERENCES t1 (pk)) ENGINE=INNODB; +TRUNCATE TABLE t1; +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fk`) REFERENCES `test`.`t1` (`pk`)) +# Truncation of child should succeed. +TRUNCATE TABLE t2; +DROP TABLE t2; +DROP TABLE t1; +CREATE TABLE t1 (pk INT PRIMARY KEY, fk INT, +FOREIGN KEY (fk) REFERENCES t1 (pk)) ENGINE=INNODB; +# Truncation of self-referencing table should succeed. +TRUNCATE TABLE t1; +DROP TABLE t1; +# +# Also, truncating such tables is allowed if foreign key +# checks are disabled. +# +SET @old_foreign_key_checks = @@SESSION.foreign_key_checks; +CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=INNODB; +CREATE TABLE t2 (fk INT NOT NULL, FOREIGN KEY (fk) REFERENCES t1 (pk)) ENGINE=INNODB; +CREATE TABLE t3 (pk INT PRIMARY KEY, fk INT, +FOREIGN KEY (fk) REFERENCES t1 (pk)) ENGINE=INNODB; +SET @@SESSION.foreign_key_checks = 0; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +SET @@SESSION.foreign_key_checks = 1; +TRUNCATE TABLE t1; +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fk`) REFERENCES `test`.`t1` (`pk`)) +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +LOCK TABLES t1 WRITE; +SET @@SESSION.foreign_key_checks = 0; +TRUNCATE TABLE t1; +SET @@SESSION.foreign_key_checks = 1; +TRUNCATE TABLE t1; +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fk`) REFERENCES `test`.`t1` (`pk`)) +UNLOCK TABLES; +DROP TABLE t3,t2,t1; +SET @@SESSION.foreign_key_checks = @old_foreign_key_checks; +# +# Test that TRUNCATE resets auto-increment. +# +CREATE TABLE t1 (a INT PRIMARY KEY NOT NULL AUTO_INCREMENT); +INSERT INTO t1 VALUES (NULL), (NULL); +SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't1'; +AUTO_INCREMENT +3 +SELECT * FROM t1 ORDER BY a; +a +1 +2 +TRUNCATE TABLE t1; +SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't1'; +AUTO_INCREMENT +1 +INSERT INTO t1 VALUES (NULL), (NULL); +SELECT * FROM t1 ORDER BY a; +a +1 +2 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index 2e5585ee7af..09a2c5b9ef4 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -2424,10 +2424,6 @@ drop table t1,t2; CREATE TABLE t1 ( id INTEGER NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) ENGINE=InnoDB; -CREATE TABLE t2 ( -id INTEGER NOT NULL, -FOREIGN KEY (id) REFERENCES t1 (id) -) ENGINE=InnoDB; INSERT INTO t1 (id) VALUES (NULL); SELECT * FROM t1; id @@ -2443,7 +2439,7 @@ INSERT INTO t1 (id) VALUES (NULL); SELECT * FROM t1; id 1 -DROP TABLE t2, t1; +DROP TABLE t1; CREATE TABLE t1 ( id INT PRIMARY KEY @@ -2621,13 +2617,15 @@ ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fail update t4 set a=2; ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`)) truncate t1; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)) +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`t1` (`a`)) truncate t3; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`)) +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`t3` (`a`)) truncate t2; truncate t4; truncate t1; +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`t1` (`a`)) truncate t3; +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`t3` (`a`)) drop table t4,t3,t2,t1; create table t1 (a varchar(255) character set utf8, b varchar(255) character set utf8, diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 14eb3f0a6a8..5a52ba0ee54 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -1941,7 +1941,7 @@ INSERT INTO t2 VALUES (3,2); SET AUTOCOMMIT = 0; START TRANSACTION; TRUNCATE TABLE t1; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`)) +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `test`.`t1` (`id`)) SELECT * FROM t1; id 1 @@ -1953,7 +1953,7 @@ id 2 START TRANSACTION; TRUNCATE TABLE t1; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`)) +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `test`.`t1` (`id`)) SELECT * FROM t1; id 1 @@ -1971,7 +1971,7 @@ id 2 COMMIT; TRUNCATE TABLE t1; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`)) +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `test`.`t1` (`id`)) SELECT * FROM t1; id 1 @@ -1983,9 +1983,12 @@ id 1 2 TRUNCATE TABLE t1; +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `test`.`t1` (`id`)) ROLLBACK; SELECT * FROM t1; id +1 +2 TRUNCATE TABLE t2; DROP TABLE t2; DROP TABLE t1; @@ -2077,9 +2080,9 @@ i i ** error handling inside a row iteration. ** DROP TRIGGER trg; -TRUNCATE TABLE t1; -TRUNCATE TABLE t2; -TRUNCATE TABLE t3; +DELETE FROM t1; +DELETE FROM t2; +DELETE FROM t3; INSERT INTO t1 VALUES (1),(2),(3),(4); INSERT INTO t3 VALUES (1),(2),(3),(4); INSERT INTO t4 VALUES (3,3),(4,4); @@ -2105,9 +2108,9 @@ DROP TRIGGER trg; ** ** Induce an error midway through an AFTER-trigger ** -TRUNCATE TABLE t4; -TRUNCATE TABLE t1; -TRUNCATE TABLE t3; +DELETE FROM t4; +DELETE FROM t1; +DELETE FROM t3; INSERT INTO t1 VALUES (1),(2),(3),(4); INSERT INTO t3 VALUES (1),(2),(3),(4); CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW diff --git a/mysql-test/suite/innodb/t/innodb-truncate.test b/mysql-test/suite/innodb/t/innodb-truncate.test new file mode 100644 index 00000000000..7629eb1a980 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-truncate.test @@ -0,0 +1,65 @@ +--source include/have_innodb.inc + +--echo # +--echo # TRUNCATE TABLE +--echo # +--echo # Truncating is disallowed for parent tables unless such table +--echo # participates in self-referencing foreign keys only. +--echo # +CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=INNODB; +CREATE TABLE t2 (fk INT NOT NULL, FOREIGN KEY (fk) REFERENCES t1 (pk)) ENGINE=INNODB; +--error ER_TRUNCATE_ILLEGAL_FK +TRUNCATE TABLE t1; +--echo # Truncation of child should succeed. +TRUNCATE TABLE t2; +DROP TABLE t2; +DROP TABLE t1; +CREATE TABLE t1 (pk INT PRIMARY KEY, fk INT, + FOREIGN KEY (fk) REFERENCES t1 (pk)) ENGINE=INNODB; +--echo # Truncation of self-referencing table should succeed. +TRUNCATE TABLE t1; +DROP TABLE t1; + +--echo # +--echo # Also, truncating such tables is allowed if foreign key +--echo # checks are disabled. +--echo # + +SET @old_foreign_key_checks = @@SESSION.foreign_key_checks; +CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=INNODB; +CREATE TABLE t2 (fk INT NOT NULL, FOREIGN KEY (fk) REFERENCES t1 (pk)) ENGINE=INNODB; +CREATE TABLE t3 (pk INT PRIMARY KEY, fk INT, + FOREIGN KEY (fk) REFERENCES t1 (pk)) ENGINE=INNODB; +SET @@SESSION.foreign_key_checks = 0; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +SET @@SESSION.foreign_key_checks = 1; +--error ER_TRUNCATE_ILLEGAL_FK +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +LOCK TABLES t1 WRITE; +SET @@SESSION.foreign_key_checks = 0; +TRUNCATE TABLE t1; +SET @@SESSION.foreign_key_checks = 1; +--error ER_TRUNCATE_ILLEGAL_FK +TRUNCATE TABLE t1; +UNLOCK TABLES; +DROP TABLE t3,t2,t1; +SET @@SESSION.foreign_key_checks = @old_foreign_key_checks; + +--echo # +--echo # Test that TRUNCATE resets auto-increment. +--echo # + +CREATE TABLE t1 (a INT PRIMARY KEY NOT NULL AUTO_INCREMENT); +INSERT INTO t1 VALUES (NULL), (NULL); +SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't1'; +SELECT * FROM t1 ORDER BY a; +TRUNCATE TABLE t1; +SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't1'; +INSERT INTO t1 VALUES (NULL), (NULL); +SELECT * FROM t1 ORDER BY a; +DROP TABLE t1; + diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test index a283cd26ccb..8c24457e07c 100644 --- a/mysql-test/suite/innodb/t/innodb.test +++ b/mysql-test/suite/innodb/t/innodb.test @@ -1471,11 +1471,6 @@ CREATE TABLE t1 ( id INTEGER NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) ENGINE=InnoDB; -CREATE TABLE t2 ( -id INTEGER NOT NULL, -FOREIGN KEY (id) REFERENCES t1 (id) -) ENGINE=InnoDB; - INSERT INTO t1 (id) VALUES (NULL); SELECT * FROM t1; TRUNCATE t1; @@ -1488,7 +1483,7 @@ DELETE FROM t1; TRUNCATE t1; INSERT INTO t1 (id) VALUES (NULL); SELECT * FROM t1; -DROP TABLE t2, t1; +DROP TABLE t1; # Test that foreign keys in temporary tables are not accepted (bug #12084) CREATE TABLE t1 @@ -1723,13 +1718,15 @@ update t2 set a=2; update t3 set a=2; -- error 1452 update t4 set a=2; --- error 1451 +-- error ER_TRUNCATE_ILLEGAL_FK truncate t1; --- error 1451 +-- error ER_TRUNCATE_ILLEGAL_FK truncate t3; truncate t2; truncate t4; +-- error ER_TRUNCATE_ILLEGAL_FK truncate t1; +-- error ER_TRUNCATE_ILLEGAL_FK truncate t3; drop table t4,t3,t2,t1; diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test index 8925f538c38..052db7d789a 100644 --- a/mysql-test/suite/innodb/t/innodb_mysql.test +++ b/mysql-test/suite/innodb/t/innodb_mysql.test @@ -151,14 +151,14 @@ INSERT INTO t2 VALUES (3,2); SET AUTOCOMMIT = 0; START TRANSACTION; ---error ER_ROW_IS_REFERENCED_2 +--error ER_TRUNCATE_ILLEGAL_FK TRUNCATE TABLE t1; SELECT * FROM t1; COMMIT; SELECT * FROM t1; START TRANSACTION; ---error ER_ROW_IS_REFERENCED_2 +--error ER_TRUNCATE_ILLEGAL_FK TRUNCATE TABLE t1; SELECT * FROM t1; ROLLBACK; @@ -170,13 +170,14 @@ START TRANSACTION; SELECT * FROM t1; COMMIT; ---error ER_ROW_IS_REFERENCED_2 +--error ER_TRUNCATE_ILLEGAL_FK TRUNCATE TABLE t1; SELECT * FROM t1; DELETE FROM t2 WHERE id = 3; START TRANSACTION; SELECT * FROM t1; +--error ER_TRUNCATE_ILLEGAL_FK TRUNCATE TABLE t1; ROLLBACK; SELECT * FROM t1; @@ -275,9 +276,9 @@ SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; --echo ** error handling inside a row iteration. --echo ** DROP TRIGGER trg; -TRUNCATE TABLE t1; -TRUNCATE TABLE t2; -TRUNCATE TABLE t3; +DELETE FROM t1; +DELETE FROM t2; +DELETE FROM t3; INSERT INTO t1 VALUES (1),(2),(3),(4); INSERT INTO t3 VALUES (1),(2),(3),(4); @@ -304,9 +305,9 @@ DROP TRIGGER trg; --echo ** --echo ** Induce an error midway through an AFTER-trigger --echo ** -TRUNCATE TABLE t4; -TRUNCATE TABLE t1; -TRUNCATE TABLE t3; +DELETE FROM t4; +DELETE FROM t1; +DELETE FROM t3; INSERT INTO t1 VALUES (1),(2),(3),(4); INSERT INTO t3 VALUES (1),(2),(3),(4); delimiter ||; diff --git a/mysql-test/suite/parts/inc/partition_check.inc b/mysql-test/suite/parts/inc/partition_check.inc index 19d548cc8ef..235764a034f 100644 --- a/mysql-test/suite/parts/inc/partition_check.inc +++ b/mysql-test/suite/parts/inc/partition_check.inc @@ -177,7 +177,7 @@ let $any_unique= `SELECT @my_errno IN ($ER_DUP_KEY,$ER_DUP_ENTRY)`; # @my_errno AS sql_errno; if (`SELECT @my_errno NOT IN (0,$ER_DUP_KEY,$ER_DUP_ENTRY)`) { - --echo # The last command got an unexepected error response. + --echo # The last command got an unexpected error response. --echo # Expected/handled SQL codes are 0,$ER_DUP_KEY,$ER_DUP_ENTRY SELECT '# SQL code we got was: ' AS "", @my_errno AS ""; --echo # Sorry, have to abort. @@ -219,7 +219,7 @@ if ($any_unique) # @my_errno AS sql_errno; if (`SELECT @my_errno NOT IN (0,$ER_DUP_KEY,$ER_DUP_ENTRY)`) { - --echo # The last command got an unexepected error response. + --echo # The last command got an unexpected error response. --echo # Expected/handled SQL codes are 0,$ER_DUP_KEY,$ER_DUP_ENTRY SELECT '# SQL code we got was: ' AS "", @my_errno AS ""; --echo # Sorry, have to abort. @@ -255,7 +255,7 @@ if ($any_unique) # @my_errno AS sql_errno; if (`SELECT @my_errno NOT IN (0,$ER_DUP_KEY,$ER_DUP_ENTRY)`) { - --echo # The last command got an unexepected error response. + --echo # The last command got an unexpected error response. --echo # Expected/handled SQL codes are 0,$ER_DUP_KEY,$ER_DUP_ENTRY SELECT '# SQL code we got was: ' AS "", @my_errno AS ""; --echo # Sorry, have to abort. @@ -503,7 +503,7 @@ if ($no_debug) eval SET @my_errno = $mysql_errno; if (`SELECT @my_errno NOT IN (0,$ER_SAME_NAME_PARTITION,$ER_NO_PARTITION_FOR_GIVEN_VALUE)`) { - --echo # The last command got an unexepected error response. + --echo # The last command got an unexpected error response. --echo # Expected/handled SQL codes are 0,$ER_SAME_NAME_PARTITION,$ER_NO_PARTITION_FOR_GIVEN_VALUE SELECT '# SQL code we got was: ' AS "", @my_errno AS ""; --echo # Sorry, have to abort. @@ -566,7 +566,7 @@ eval SET @my_errno = $mysql_errno; let $run= `SELECT @my_errno = 0`; if (`SELECT @my_errno NOT IN (0,$ER_BAD_NULL_ERROR)`) { - --echo # The last command got an unexepected error response. + --echo # The last command got an unexpected error response. --echo # Expected/handled SQL codes are 0,$ER_BAD_NULL_ERROR SELECT '# SQL code we got was: ' AS "", @my_errno AS ""; --echo # Sorry, have to abort. diff --git a/mysql-test/suite/sys_vars/r/foreign_key_checks_func.result b/mysql-test/suite/sys_vars/r/foreign_key_checks_func.result index 9b1736541c1..398a2a76eb8 100644 --- a/mysql-test/suite/sys_vars/r/foreign_key_checks_func.result +++ b/mysql-test/suite/sys_vars/r/foreign_key_checks_func.result @@ -26,7 +26,7 @@ INSERT INTO t2 values (20,22); ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `t1` (`a`)) '---Check when foreign_key_checks is disabled---' TRUNCATE t1; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `t1` (`a`)) +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `test`.`t1` (`a`)) SET @@session.foreign_key_checks = 0; TRUNCATE t1; TRUNCATE t2; diff --git a/mysql-test/suite/sys_vars/t/foreign_key_checks_func.test b/mysql-test/suite/sys_vars/t/foreign_key_checks_func.test index 5786b9283be..14134a5fb95 100644 --- a/mysql-test/suite/sys_vars/t/foreign_key_checks_func.test +++ b/mysql-test/suite/sys_vars/t/foreign_key_checks_func.test @@ -76,7 +76,7 @@ INSERT INTO t2 values (20,22); --echo '---Check when foreign_key_checks is disabled---' #=========================================================== ---Error ER_ROW_IS_REFERENCED_2 +--Error ER_TRUNCATE_ILLEGAL_FK TRUNCATE t1; SET @@session.foreign_key_checks = 0; diff --git a/mysql-test/t/mdl_sync.test b/mysql-test/t/mdl_sync.test index f7780d2003a..5c4fc20b428 100644 --- a/mysql-test/t/mdl_sync.test +++ b/mysql-test/t/mdl_sync.test @@ -3969,7 +3969,8 @@ INSERT INTO t1 VALUES (1),(2),(3); --echo # Connection: con1 connection con1; -SET debug_sync='lock_table_for_truncate SIGNAL parked_truncate WAIT_FOR go_truncate'; +LOCK TABLES t1 WRITE; +SET debug_sync='upgrade_lock_for_truncate SIGNAL parked_truncate WAIT_FOR go_truncate'; send TRUNCATE TABLE t1; connection default; @@ -3994,15 +3995,17 @@ connection default; --echo # Connection: default SET debug_sync='now WAIT_FOR parked_flush'; SET debug_sync='now SIGNAL go_truncate'; +--echo # Ensure that truncate waits for a exclusive lock +let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist + WHERE state='Waiting for table metadata lock' AND info='TRUNCATE TABLE t1'; +--source include/wait_condition.inc +SET debug_sync= 'now SIGNAL go_show'; connection con1; ---echo # Connection: con1 +--echo # Connection: con1 (TRUNCATE) --echo # Reaping... reap; - -connection default; ---echo # Connection: default -SET debug_sync= 'now SIGNAL go_show'; +UNLOCK TABLES; connection con2; --echo # Connection: con2 (SHOW FIELDS FROM t1) diff --git a/mysql-test/t/sp_trans.test b/mysql-test/t/sp_trans.test index c4915bdb87a..c114d397e43 100644 --- a/mysql-test/t/sp_trans.test +++ b/mysql-test/t/sp_trans.test @@ -636,6 +636,30 @@ UPDATE t1_aux SET f2 = 2 WHERE f1 = f1_two_inserts()| DROP TABLE t1_aux, t1_not_null| DROP FUNCTION f1_two_inserts| +--echo # +--echo # Bug#49938: Failing assertion: inode or deadlock in fsp/fsp0fsp.c +--echo # + +--disable_warnings +DROP PROCEDURE IF EXISTS p1| +DROP TABLE IF EXISTS t1| +--enable_warnings + +CREATE TABLE t1 (a INT) ENGINE=INNODB| + +CREATE PROCEDURE p1() +BEGIN + TRUNCATE TABLE t1; +END| + +LOCK TABLES t1 WRITE| +CALL p1()| +FLUSH TABLES; +UNLOCK TABLES| +CALL p1()| + +DROP PROCEDURE p1| +DROP TABLE t1| # # BUG#NNNN: New bug synopsis diff --git a/mysql-test/t/trigger-trans.test b/mysql-test/t/trigger-trans.test index 4d6e82dedcb..82bee7aa224 100644 --- a/mysql-test/t/trigger-trans.test +++ b/mysql-test/t/trigger-trans.test @@ -148,10 +148,15 @@ CREATE TRIGGER t1_ad AFTER DELETE ON t1 FOR EACH ROW SET @b = 1; SET @a = 0; SET @b = 0; +--error ER_TRUNCATE_ILLEGAL_FK TRUNCATE t1; SELECT @a, @b; +DELETE FROM t1; + +SELECT @a, @b; + INSERT INTO t1 VALUES (1); DELETE FROM t1; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 8bf35f79ba9..3d8d5ae9eb8 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -3337,113 +3337,123 @@ int ha_partition::delete_row(const uchar *buf) Called from sql_delete.cc by mysql_delete(). Called from sql_select.cc by JOIN::reinit(). Called from sql_union.cc by st_select_lex_unit::exec(). - - Also used for handle ALTER TABLE t TRUNCATE PARTITION ... - NOTE: auto increment value will be truncated in that partition as well! */ int ha_partition::delete_all_rows() { int error; - bool truncate= FALSE; handler **file; - THD *thd= ha_thd(); DBUG_ENTER("ha_partition::delete_all_rows"); - if (thd->lex->sql_command == SQLCOM_TRUNCATE) - { - Alter_info *alter_info= &thd->lex->alter_info; - /* TRUNCATE also means resetting auto_increment */ - lock_auto_increment(); - table_share->ha_part_data->next_auto_inc_val= 0; - table_share->ha_part_data->auto_inc_initialized= FALSE; - unlock_auto_increment(); - if (alter_info->flags & ALTER_ADMIN_PARTITION) - { - /* ALTER TABLE t TRUNCATE PARTITION ... */ - List_iterator part_it(m_part_info->partitions); - int saved_error= 0; - uint num_parts= m_part_info->num_parts; - uint num_subparts= m_part_info->num_subparts; - uint i= 0; - uint num_parts_set= alter_info->partition_names.elements; - uint num_parts_found= set_part_state(alter_info, m_part_info, - PART_ADMIN); - if (num_parts_set != num_parts_found && - (!(alter_info->flags & ALTER_ALL_PARTITION))) - DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND); - - /* - Cannot return HA_ERR_WRONG_COMMAND here without correct pruning - since that whould delete the whole table row by row in sql_delete.cc - */ - bitmap_clear_all(&m_part_info->used_partitions); - do - { - partition_element *part_elem= part_it++; - if (part_elem->part_state == PART_ADMIN) - { - if (m_is_sub_partitioned) - { - List_iterator - subpart_it(part_elem->subpartitions); - partition_element *sub_elem; - uint j= 0, part; - do - { - sub_elem= subpart_it++; - part= i * num_subparts + j; - bitmap_set_bit(&m_part_info->used_partitions, part); - if (!saved_error) - { - DBUG_PRINT("info", ("truncate subpartition %u (%s)", - part, sub_elem->partition_name)); - if ((error= m_file[part]->ha_delete_all_rows())) - saved_error= error; - /* If not reset_auto_increment is supported, just accept it */ - if (!saved_error && - (error= m_file[part]->ha_reset_auto_increment(0)) && - error != HA_ERR_WRONG_COMMAND) - saved_error= error; - } - } while (++j < num_subparts); - } - else - { - DBUG_PRINT("info", ("truncate partition %u (%s)", i, - part_elem->partition_name)); - bitmap_set_bit(&m_part_info->used_partitions, i); - if (!saved_error) - { - if ((error= m_file[i]->ha_delete_all_rows()) && !saved_error) - saved_error= error; - /* If not reset_auto_increment is supported, just accept it */ - if (!saved_error && - (error= m_file[i]->ha_reset_auto_increment(0)) && - error != HA_ERR_WRONG_COMMAND) - saved_error= error; - } - } - part_elem->part_state= PART_NORMAL; - } - } while (++i < num_parts); - DBUG_RETURN(saved_error); - } - truncate= TRUE; - } file= m_file; do { if ((error= (*file)->ha_delete_all_rows())) DBUG_RETURN(error); - /* Ignore the error */ - if (truncate) - (void) (*file)->ha_reset_auto_increment(0); } while (*(++file)); DBUG_RETURN(0); } +/** + Manually truncate the table. + + @retval 0 Success. + @retval > 0 Error code. +*/ + +int ha_partition::truncate() +{ + int error; + handler **file; + DBUG_ENTER("ha_partition::truncate"); + + /* + TRUNCATE also means resetting auto_increment. Hence, reset + it so that it will be initialized again at the next use. + */ + lock_auto_increment(); + table_share->ha_part_data->next_auto_inc_val= 0; + table_share->ha_part_data->auto_inc_initialized= FALSE; + unlock_auto_increment(); + + file= m_file; + do + { + if ((error= (*file)->ha_truncate())) + DBUG_RETURN(error); + } while (*(++file)); + DBUG_RETURN(0); +} + + +/** + Truncate a set of specific partitions. + + @remark Auto increment value will be truncated in that partition as well! + + ALTER TABLE t TRUNCATE PARTITION ... +*/ + +int ha_partition::truncate_partition(Alter_info *alter_info) +{ + int error= 0; + List_iterator part_it(m_part_info->partitions); + uint num_parts= m_part_info->num_parts; + uint num_subparts= m_part_info->num_subparts; + uint i= 0; + uint num_parts_set= alter_info->partition_names.elements; + uint num_parts_found= set_part_state(alter_info, m_part_info, + PART_ADMIN); + DBUG_ENTER("ha_partition::truncate_partition"); + + /* + TRUNCATE also means resetting auto_increment. Hence, reset + it so that it will be initialized again at the next use. + */ + lock_auto_increment(); + table_share->ha_part_data->next_auto_inc_val= 0; + table_share->ha_part_data->auto_inc_initialized= FALSE; + unlock_auto_increment(); + + if (num_parts_set != num_parts_found && + (!(alter_info->flags & ALTER_ALL_PARTITION))) + DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND); + + do + { + partition_element *part_elem= part_it++; + if (part_elem->part_state == PART_ADMIN) + { + if (m_is_sub_partitioned) + { + List_iterator + subpart_it(part_elem->subpartitions); + partition_element *sub_elem; + uint j= 0, part; + do + { + sub_elem= subpart_it++; + part= i * num_subparts + j; + DBUG_PRINT("info", ("truncate subpartition %u (%s)", + part, sub_elem->partition_name)); + if ((error= m_file[part]->ha_truncate())) + break; + } while (++j < num_subparts); + } + else + { + DBUG_PRINT("info", ("truncate partition %u (%s)", i, + part_elem->partition_name)); + error= m_file[i]->ha_truncate(); + } + part_elem->part_state= PART_NORMAL; + } + } while (!error && (++i < num_parts)); + DBUG_RETURN(error); +} + + /* Start a large batch of insert rows @@ -6327,8 +6337,8 @@ void ha_partition::print_error(int error, myf errflag) /* Should probably look for my own errors first */ DBUG_PRINT("enter", ("error: %d", error)); - if (error == HA_ERR_NO_PARTITION_FOUND && - thd->lex->sql_command != SQLCOM_TRUNCATE) + if ((error == HA_ERR_NO_PARTITION_FOUND) && + ! (thd->lex->alter_info.flags & ALTER_TRUNCATE_PARTITION)) m_part_info->print_no_partition_found(table); else { diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 353e0d17159..f1abc0cefe2 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -346,6 +346,7 @@ public: virtual int update_row(const uchar * old_data, uchar * new_data); virtual int delete_row(const uchar * buf); virtual int delete_all_rows(void); + virtual int truncate(); virtual void start_bulk_insert(ha_rows rows); virtual int end_bulk_insert(); private: @@ -354,6 +355,15 @@ private: long estimate_read_buffer_size(long original_size); public: + /* + Method for truncating a specific partition. + (i.e. ALTER TABLE t1 TRUNCATE PARTITION p). + + @remark This method is a partitioning-specific hook + and thus not a member of the general SE API. + */ + int truncate_partition(Alter_info *); + virtual bool is_fatal_error(int error, uint flags) { if (!handler::is_fatal_error(error, flags) || diff --git a/sql/handler.cc b/sql/handler.cc index 567dbe6ea49..1542dd99ec6 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3208,6 +3208,21 @@ handler::ha_delete_all_rows() } +/** + Truncate table: public interface. + + @sa handler::truncate() +*/ + +int +handler::ha_truncate() +{ + mark_trx_read_write(); + + return truncate(); +} + + /** Reset auto increment: public interface. diff --git a/sql/handler.h b/sql/handler.h index b1d64a1114b..325df003215 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1331,6 +1331,7 @@ public: int ha_bulk_update_row(const uchar *old_data, uchar *new_data, uint *dup_key_found); int ha_delete_all_rows(); + int ha_truncate(); int ha_reset_auto_increment(ulonglong value); int ha_optimize(THD* thd, HA_CHECK_OPT* check_opt); int ha_analyze(THD* thd, HA_CHECK_OPT* check_opt); @@ -1644,8 +1645,33 @@ public: { return(NULL);} /* gets tablespace name from handler */ /** used in ALTER TABLE; 1 if changing storage engine is allowed */ virtual bool can_switch_engines() { return 1; } - /** used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */ - virtual int get_foreign_key_list(THD *thd, List *f_key_list) + /** + Get the list of foreign keys in this table. + + @remark Returns the set of foreign keys where this table is the + dependent or child table. + + @param thd The thread handle. + @param f_key_list[out] The list of foreign keys. + + @return The handler error code or zero for success. + */ + virtual int + get_foreign_key_list(THD *thd, List *f_key_list) + { return 0; } + /** + Get the list of foreign keys referencing this table. + + @remark Returns the set of foreign keys where this table is the + referenced or parent table. + + @param thd The thread handle. + @param f_key_list[out] The list of foreign keys. + + @return The handler error code or zero for success. + */ + virtual int + get_parent_foreign_key_list(THD *thd, List *f_key_list) { return 0; } virtual uint referenced_by_foreign_key() { return 0;} virtual void init_table_handle_for_HANDLER() @@ -2010,16 +2036,34 @@ private: This is called to delete all rows in a table If the handler don't support this, then this function will return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one - by one. It should reset auto_increment if - thd->lex->sql_command == SQLCOM_TRUNCATE. + by one. */ virtual int delete_all_rows() { return (my_errno=HA_ERR_WRONG_COMMAND); } + /** + Quickly remove all rows from a table. + + @remark This method is responsible for implementing MySQL's TRUNCATE + TABLE statement, which is a DDL operation. As such, a engine + can bypass certain integrity checks and in some cases avoid + fine-grained locking (e.g. row locks) which would normally be + required for a DELETE statement. + + @remark Typically, truncate is not used if it can result in integrity + violation. For example, truncate is not used when a foreign + key references the table, but it might be used if foreign key + checks are disabled. + + @remark Engine is responsible for resetting the auto-increment counter. + + @remark The table is locked in exclusive mode. + */ + virtual int truncate() + { return HA_ERR_WRONG_COMMAND; } /** Reset the auto-increment counter to the given value, i.e. the next row - inserted will get the given value. This is called e.g. after TRUNCATE - is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is - returned by storage engines that don't support this operation. + inserted will get the given value. HA_ERR_WRONG_COMMAND is returned by + storage engines that don't support this operation. */ virtual int reset_auto_increment(ulonglong value) { return HA_ERR_WRONG_COMMAND; } diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 07f5589135d..c7d016b19ca 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6379,3 +6379,6 @@ ER_SET_PASSWORD_AUTH_PLUGIN ER_GRANT_PLUGIN_USER_EXISTS eng "GRANT with IDENTIFIED WITH is illegal because the user %-.*s already exists" + +ER_TRUNCATE_ILLEGAL_FK 42000 + eng "Cannot truncate a table referenced in a foreign key constraint (%.192s)" diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 3a559433e2d..0f93275434d 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -958,6 +958,7 @@ inline bool st_select_lex_unit::is_union () #define ALTER_ALL_PARTITION (1L << 21) #define ALTER_REMOVE_PARTITIONING (1L << 22) #define ALTER_FOREIGN_KEY (1L << 23) +#define ALTER_TRUNCATE_PARTITION (1L << 24) enum enum_alter_table_change_level { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e44d2563483..2f8a72ee25c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -34,7 +34,7 @@ #include "sql_locale.h" // my_locale_en_US #include "log.h" // flush_error_log #include "sql_view.h" // mysql_create_view, mysql_drop_view -#include "sql_delete.h" // mysql_truncate, mysql_delete +#include "sql_delete.h" // mysql_delete #include "sql_insert.h" // mysql_insert #include "sql_update.h" // mysql_update, mysql_multi_update #include "sql_partition.h" // struct partition_info @@ -49,7 +49,6 @@ // mysql_recreate_table, // mysql_backup_table, // mysql_restore_table -#include "sql_truncate.h" // mysql_truncate_table #include "sql_reload.h" // reload_acl_and_cache #include "sql_admin.h" // mysql_assign_to_keycache #include "sql_connect.h" // check_user, diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index fee33303a04..98750314a4a 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -16,10 +16,10 @@ #include "sql_parse.h" // check_one_table_access #include "sql_table.h" // mysql_alter_table, etc. #include "sql_lex.h" // Sql_statement -#include "sql_truncate.h" // mysql_truncate_table, - // Truncate_statement #include "sql_admin.h" // Analyze/Check/.._table_statement #include "sql_partition_admin.h" // Alter_table_*_partition +#include "ha_partition.h" // ha_partition +#include "sql_base.h" // open_and_lock_tables #ifndef WITH_PARTITION_STORAGE_ENGINE @@ -46,7 +46,7 @@ bool Alter_table_analyze_partition_statement::execute(THD *thd) m_lex->alter_info.flags|= ALTER_ADMIN_PARTITION; res= Analyze_table_statement::execute(thd); - + DBUG_RETURN(res); } @@ -104,36 +104,85 @@ bool Alter_table_repair_partition_statement::execute(THD *thd) bool Alter_table_truncate_partition_statement::execute(THD *thd) { + int error; + ha_partition *partition; + ulong timeout= thd->variables.lock_wait_timeout; TABLE_LIST *first_table= thd->lex->select_lex.table_list.first; - bool res; - enum_sql_command original_sql_command; DBUG_ENTER("Alter_table_truncate_partition_statement::execute"); - /* - Execute TRUNCATE PARTITION just like TRUNCATE TABLE. - Some storage engines (InnoDB, partition) checks thd_sql_command, - so we set it to SQLCOM_TRUNCATE during the execution. - */ - original_sql_command= m_lex->sql_command; - m_lex->sql_command= SQLCOM_TRUNCATE; - /* Flag that it is an ALTER command which administrates partitions, used by ha_partition. */ - m_lex->alter_info.flags|= ALTER_ADMIN_PARTITION; - - /* - Fix the lock types (not the same as ordinary ALTER TABLE). - */ + m_lex->alter_info.flags|= ALTER_ADMIN_PARTITION | + ALTER_TRUNCATE_PARTITION; + + /* Fix the lock types (not the same as ordinary ALTER TABLE). */ first_table->lock_type= TL_WRITE; - first_table->mdl_request.set_type(MDL_SHARED_NO_READ_WRITE); + first_table->mdl_request.set_type(MDL_EXCLUSIVE); - /* execute as a TRUNCATE TABLE */ - res= Truncate_statement::execute(thd); + /* + Check table permissions and open it with a exclusive lock. + Ensure it is a partitioned table and finally, upcast the + handler and invoke the partition truncate method. Lastly, + write the statement to the binary log if necessary. + */ - m_lex->sql_command= original_sql_command; - DBUG_RETURN(res); + if (check_one_table_access(thd, DROP_ACL, first_table)) + DBUG_RETURN(TRUE); + + if (open_and_lock_tables(thd, first_table, FALSE, 0)) + DBUG_RETURN(TRUE); + + /* + TODO: Add support for TRUNCATE PARTITION for NDB and other + engines supporting native partitioning. + */ + if (first_table->table->s->db_type() != partition_hton) + { + my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0)); + DBUG_RETURN(TRUE); + } + + /* + Under locked table modes this might still not be an exclusive + lock. Hence, upgrade the lock since the handler truncate method + mandates an exclusive metadata lock. + */ + MDL_ticket *ticket= first_table->table->mdl_ticket; + if (thd->mdl_context.upgrade_shared_lock_to_exclusive(ticket, timeout)) + DBUG_RETURN(TRUE); + + tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN, first_table->db, + first_table->table_name, FALSE); + + partition= (ha_partition *) first_table->table->file; + + /* Invoke the handler method responsible for truncating the partition. */ + if ((error= partition->truncate_partition(&thd->lex->alter_info))) + first_table->table->file->print_error(error, MYF(0)); + + /* + All effects of a truncate operation are committed even if the + operation fails. Thus, the query must be written to the binary + log. The only exception is a unimplemented truncate method. Also, + it is logged in statement format, regardless of the binlog format. + */ + if (error != HA_ERR_WRONG_COMMAND) + error|= write_bin_log(thd, !error, thd->query(), thd->query_length()); + + /* + A locked table ticket was upgraded to a exclusive lock. After the + the query has been written to the binary log, downgrade the lock + to a shared one. + */ + if (thd->locked_tables_mode) + ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE); + + if (! error) + my_ok(thd); + + DBUG_RETURN(error); } #endif /* WITH_PARTITION_STORAGE_ENGINE */ diff --git a/sql/sql_partition_admin.h b/sql/sql_partition_admin.h index 36bafec4202..564b8676be8 100644 --- a/sql/sql_partition_admin.h +++ b/sql/sql_partition_admin.h @@ -210,7 +210,7 @@ public: /** Class that represents the ALTER TABLE t1 TRUNCATE PARTITION p statement. */ -class Alter_table_truncate_partition_statement : public Truncate_statement +class Alter_table_truncate_partition_statement : public Sql_statement { public: /** @@ -218,10 +218,10 @@ public: @param lex the LEX structure for this statement. */ Alter_table_truncate_partition_statement(LEX *lex) - : Truncate_statement(lex) + : Sql_statement(lex) {} - ~Alter_table_truncate_partition_statement() + virtual ~Alter_table_truncate_partition_statement() {} /** diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 6b24e3db7bc..ba4b0ae7a0a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -5063,8 +5063,8 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, while ((f_key_info=it++)) { if (store_constraints(thd, table, db_name, table_name, - f_key_info->forein_id->str, - strlen(f_key_info->forein_id->str), + f_key_info->foreign_id->str, + strlen(f_key_info->foreign_id->str), "FOREIGN KEY", 11)) DBUG_RETURN(1); } @@ -5263,8 +5263,8 @@ static int get_schema_key_column_usage_record(THD *thd, f_idx++; restore_record(table, s->default_values); store_key_column_usage(table, db_name, table_name, - f_key_info->forein_id->str, - f_key_info->forein_id->length, + f_key_info->foreign_id->str, + f_key_info->foreign_id->length, f_info->str, f_info->length, (longlong) f_idx); table->field[8]->store((longlong) f_idx, TRUE); @@ -6053,8 +6053,8 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables, table->field[0]->store(STRING_WITH_LEN("def"), cs); table->field[1]->store(db_name->str, db_name->length, cs); table->field[9]->store(table_name->str, table_name->length, cs); - table->field[2]->store(f_key_info->forein_id->str, - f_key_info->forein_id->length, cs); + table->field[2]->store(f_key_info->foreign_id->str, + f_key_info->foreign_id->length, cs); table->field[3]->store(STRING_WITH_LEN("def"), cs); table->field[4]->store(f_key_info->referenced_db->str, f_key_info->referenced_db->length, cs); diff --git a/sql/sql_string.h b/sql/sql_string.h index d21b5353b76..845b7c280b1 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -265,8 +265,12 @@ public: CHARSET_INFO *csto, uint *errors); bool append(const String &s); bool append(const char *s); - bool append(const char *s,uint32 arg_length); - bool append(const char *s,uint32 arg_length, CHARSET_INFO *cs); + bool append(LEX_STRING *ls) + { + return append(ls->str, ls->length); + } + bool append(const char *s, uint32 arg_length); + bool append(const char *s, uint32 arg_length, CHARSET_INFO *cs); bool append_ulonglong(ulonglong val); bool append(IO_CACHE* file, uint32 arg_length); bool append_with_prefill(const char *s, uint32 arg_length, diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index c0bc726a188..0cff2875ac8 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -13,11 +13,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "sql_priv.h" -#include "transaction.h" -#include "debug_sync.h" -#include "records.h" // READ_RECORD -#include "table.h" // TABLE +#include "debug_sync.h" // DEBUG_SYNC +#include "table.h" // TABLE, FOREIGN_KEY_INFO #include "sql_class.h" // THD #include "sql_base.h" // open_and_lock_tables #include "sql_table.h" // write_bin_log @@ -29,145 +26,212 @@ #include "sql_truncate.h" -/* - Delete all rows of a locked table. +/** + Append a list of field names to a string. - @param thd Thread context. - @param table_list Table list element for the table. - @param rows_deleted Whether rows might have been deleted. + @param str The string. + @param fields The list of field names. - @retval FALSE Success. - @retval TRUE Error. + @return TRUE on failure, FALSE otherwise. +*/ + +static bool fk_info_append_fields(String *str, List *fields) +{ + bool res= FALSE; + LEX_STRING *field; + List_iterator_fast it(*fields); + + while ((field= it++)) + { + res|= str->append("`"); + res|= str->append(field); + res|= str->append("`, "); + } + + str->chop(); + str->chop(); + + return res; +} + + +/** + Generate a foreign key description suitable for a error message. + + @param thd Thread context. + @param fk_info The foreign key information. + + @return A human-readable string describing the foreign key. +*/ + +static const char *fk_info_str(THD *thd, FOREIGN_KEY_INFO *fk_info) +{ + bool res= FALSE; + char buffer[STRING_BUFFER_USUAL_SIZE*2]; + String str(buffer, sizeof(buffer), system_charset_info); + + str.length(0); + + /* + `db`.`tbl`, CONSTRAINT `id` FOREIGN KEY (`fk`) REFERENCES `db`.`tbl` (`fk`) + */ + + res|= str.append('`'); + res|= str.append(fk_info->foreign_db); + res|= str.append("`.`"); + res|= str.append(fk_info->foreign_table); + res|= str.append("`, CONSTRAINT `"); + res|= str.append(fk_info->foreign_id); + res|= str.append("` FOREIGN KEY ("); + res|= fk_info_append_fields(&str, &fk_info->foreign_fields); + res|= str.append(") REFERENCES `"); + res|= str.append(fk_info->referenced_db); + res|= str.append("`.`"); + res|= str.append(fk_info->referenced_table); + res|= str.append("` ("); + res|= fk_info_append_fields(&str, &fk_info->referenced_fields); + res|= str.append(')'); + + return res ? NULL : thd->strmake(str.ptr(), str.length()); +} + + +/** + Check and emit a fatal error if the table which is going to be + affected by TRUNCATE TABLE is a parent table in some non-self- + referencing foreign key. + + @remark The intention is to allow truncate only for tables that + are not dependent on other tables. + + @param thd Thread context. + @param table Table handle. + + @retval FALSE This table is not parent in a non-self-referencing foreign + key. Statement can proceed. + @retval TRUE This table is parent in a non-self-referencing foreign key, + error was emitted. */ static bool -delete_all_rows(THD *thd, TABLE *table) +fk_truncate_illegal_if_parent(THD *thd, TABLE *table) { - int error; - READ_RECORD info; - bool is_bulk_delete; - bool some_rows_deleted= FALSE; - bool save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); - DBUG_ENTER("delete_all_rows"); - - /* Replication of truncate table must be statement based. */ - thd->clear_current_stmt_binlog_format_row(); + FOREIGN_KEY_INFO *fk_info; + List fk_list; + List_iterator_fast it; /* - Update handler statistics (e.g. table->file->stats.records). - Might be used by the storage engine to aggregate information - necessary to allow deletion. Currently, this seems to be - meaningful only to the archive storage engine, which uses - the info method to set the number of records. Although - archive does not support deletion, it becomes necessary in - order to return a error if the table is not empty. + Bail out early if the table is not referenced by a foreign key. + In this case, the table could only be, if at all, a child table. */ - error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); - if (error && error != HA_ERR_WRONG_COMMAND) - { - table->file->print_error(error, MYF(0)); - goto end; - } + if (! table->file->referenced_by_foreign_key()) + return FALSE; /* - Attempt to delete all rows in the table. - If it is unsupported, switch to row by row deletion. + This table _is_ referenced by a foreign key. At this point, only + self-referencing keys are acceptable. For this reason, get the list + of foreign keys referencing this table in order to check the name + of the child (dependent) tables. */ - if (! (error= table->file->ha_delete_all_rows())) - goto end; + table->file->get_parent_foreign_key_list(thd, &fk_list); - if (error != HA_ERR_WRONG_COMMAND) - { - /* - If a transactional engine fails in the middle of deletion, - we expect it to be able to roll it back. Some reasons - for the engine to fail would be media failure or corrupted - data dictionary (i.e. in case of a partitioned table). We - have sufficiently strong metadata locks to rule out any - potential deadlocks. - - If a non-transactional engine fails here (that would - not be MyISAM, since MyISAM does TRUNCATE by recreate), - and binlog is on, replication breaks, since nothing gets - written to the binary log. (XXX: is this a bug?) - */ - table->file->print_error(error, MYF(0)); - goto end; - } - - /* - A workaround for Bug#53696 "Performance schema engine violates the - PSEA API by calling my_error()". - */ + /* Out of memory when building list. */ if (thd->is_error()) - goto end; + return TRUE; - /* Handler didn't support fast delete. Delete rows one by one. */ + it.init(fk_list); - init_read_record(&info, thd, table, NULL, TRUE, TRUE, FALSE); - - /* - Start bulk delete. If the engine does not support it, go on, - it's not an error. - */ - is_bulk_delete= ! table->file->start_bulk_delete(); - - table->mark_columns_needed_for_delete(); - - while (!(error= info.read_record(&info)) && !thd->killed) + /* Loop over the set of foreign keys for which this table is a parent. */ + while ((fk_info= it++)) { - if ((error= table->file->ha_delete_row(table->record[0]))) - { - table->file->print_error(error, MYF(0)); + DBUG_ASSERT(!my_strcasecmp(system_charset_info, + fk_info->referenced_db->str, + table->s->db.str)); + + DBUG_ASSERT(!my_strcasecmp(system_charset_info, + fk_info->referenced_table->str, + table->s->table_name.str)); + + if (my_strcasecmp(system_charset_info, fk_info->foreign_db->str, + table->s->db.str) || + my_strcasecmp(system_charset_info, fk_info->foreign_table->str, + table->s->table_name.str)) break; - } - - some_rows_deleted= TRUE; } - /* HA_ERR_END_OF_FILE */ - if (error == -1) - error= 0; - - /* Close down the bulk delete. */ - if (is_bulk_delete) + /* Table is parent in a non-self-referencing foreign key. */ + if (fk_info) { - int bulk_delete_error= table->file->end_bulk_delete(); - if (bulk_delete_error && !error) - { - table->file->print_error(bulk_delete_error, MYF(0)); - error= bulk_delete_error; - } + my_error(ER_TRUNCATE_ILLEGAL_FK, MYF(0), fk_info_str(thd, fk_info)); + return TRUE; } - end_read_record(&info); + return FALSE; +} + + +/* + Open and truncate a locked table. + + @param thd Thread context. + @param table_ref Table list element for the table to be truncated. + @param is_tmp_table True if element refers to a temp table. + + @retval 0 Success. + @retval > 0 Error code. +*/ + +int Truncate_statement::handler_truncate(THD *thd, TABLE_LIST *table_ref, + bool is_tmp_table) +{ + int error= 0; + uint flags; + DBUG_ENTER("Truncate_statement::handler_truncate"); /* - Regardless of the error status, the query must be written to the - binary log if rows of the table is non-transactional. + Can't recreate, the engine must mechanically delete all rows + in the table. Use open_and_lock_tables() to open a write cursor. */ - if (some_rows_deleted && !table->file->has_transactions()) + + /* If it is a temporary table, no need to take locks. */ + if (is_tmp_table) + flags= MYSQL_OPEN_TEMPORARY_ONLY; + else { - thd->transaction.stmt.modified_non_trans_table= TRUE; - thd->transaction.all.modified_non_trans_table= TRUE; + /* We don't need to load triggers. */ + DBUG_ASSERT(table_ref->trg_event_map == 0); + /* + Our metadata lock guarantees that no transaction is reading + or writing into the table. Yet, to open a write cursor we need + a thr_lock lock. Allow to open base tables only. + */ + table_ref->required_type= FRMTYPE_TABLE; + /* + Ignore pending FLUSH TABLES since we don't want to release + the MDL lock taken above and otherwise there is no way to + wait for FLUSH TABLES in deadlock-free fashion. + */ + flags= MYSQL_OPEN_IGNORE_FLUSH | MYSQL_OPEN_SKIP_TEMPORARY; + /* + Even though we have an MDL lock on the table here, we don't + pass MYSQL_OPEN_HAS_MDL_LOCK to open_and_lock_tables + since to truncate a MERGE table, we must open and lock + merge children, and on those we don't have an MDL lock. + Thus clear the ticket to satisfy MDL asserts. + */ + table_ref->mdl_request.ticket= NULL; } - if (error || thd->killed) - goto end; + /* Open the table as it will handle some required preparations. */ + if (open_and_lock_tables(thd, table_ref, FALSE, flags)) + DBUG_RETURN(1); - /* Truncate resets the auto-increment counter. */ - error= table->file->ha_reset_auto_increment(0); - if (error) - { - if (error != HA_ERR_WRONG_COMMAND) - table->file->print_error(error, MYF(0)); - else - error= 0; - } + /* Whether to truncate regardless of foreign keys. */ + if (! (thd->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS)) + error= fk_truncate_illegal_if_parent(thd, table_ref->table); -end: - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); + if (!error && (error= table_ref->table->file->ha_truncate())) + table_ref->table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -225,30 +289,29 @@ static bool recreate_temporary_table(THD *thd, TABLE *table) /* - Handle opening and locking if a base table for truncate. + Handle locking a base table for truncate. @param[in] thd Thread context. @param[in] table_ref Table list element for the table to be truncated. @param[out] hton_can_recreate Set to TRUE if table can be dropped and recreated. - @param[out] ticket_downgrade Set if a lock must be downgraded after - truncate is done. @retval FALSE Success. @retval TRUE Error. */ -static bool open_and_lock_table_for_truncate(THD *thd, TABLE_LIST *table_ref, - bool *hton_can_recreate, - MDL_ticket **ticket_downgrade) +bool Truncate_statement::lock_table(THD *thd, TABLE_LIST *table_ref, + bool *hton_can_recreate) { TABLE *table= NULL; - handlerton *table_type; - DBUG_ENTER("open_and_lock_table_for_truncate"); + DBUG_ENTER("Truncate_statement::lock_table"); + /* Lock types are set in the parser. */ DBUG_ASSERT(table_ref->lock_type == TL_WRITE); - DBUG_ASSERT(table_ref->mdl_request.type == MDL_SHARED_NO_READ_WRITE); + /* The handler truncate protocol dictates a exclusive lock. */ + DBUG_ASSERT(table_ref->mdl_request.type == MDL_EXCLUSIVE); + /* Before doing anything else, acquire a metadata lock on the table, or ensure we have one. We don't use open_and_lock_tables() @@ -268,103 +331,45 @@ static bool open_and_lock_table_for_truncate(THD *thd, TABLE_LIST *table_ref, table_ref->table_name, FALSE))) DBUG_RETURN(TRUE); - table_type= table->s->db_type(); - *hton_can_recreate= ha_check_storage_engine_flag(table_type, + *hton_can_recreate= ha_check_storage_engine_flag(table->s->db_type(), HTON_CAN_RECREATE); table_ref->mdl_request.ticket= table->mdl_ticket; } else { - /* - Even though we could use the previous execution branch here just as - well, we must not try to open the table: - */ + /* Acquire an exclusive lock. */ DBUG_ASSERT(table_ref->next_global == NULL); if (lock_table_names(thd, table_ref, NULL, thd->variables.lock_wait_timeout, MYSQL_OPEN_SKIP_TEMPORARY)) DBUG_RETURN(TRUE); - if (dd_frm_storage_engine(thd, table_ref->db, table_ref->table_name, - &table_type)) + if (dd_check_storage_engine_flag(thd, table_ref->db, table_ref->table_name, + HTON_CAN_RECREATE, hton_can_recreate)) DBUG_RETURN(TRUE); - *hton_can_recreate= ha_check_storage_engine_flag(table_type, - HTON_CAN_RECREATE); } -#ifdef WITH_PARTITION_STORAGE_ENGINE /* - TODO: Add support for TRUNCATE PARTITION for NDB and other engines - supporting native partitioning. + A storage engine can recreate or truncate the table only if there + are no references to it from anywhere, i.e. no cached TABLE in the + table cache. */ - if (thd->lex->alter_info.flags & ALTER_ADMIN_PARTITION && - table_type != partition_hton) + if (thd->locked_tables_mode) { - my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0)); - DBUG_RETURN(TRUE); - } -#endif - DEBUG_SYNC(thd, "lock_table_for_truncate"); - - if (*hton_can_recreate) - { - /* - Acquire an exclusive lock. The storage engine can recreate the - table only if there are no references to it from anywhere, i.e. - no cached TABLE in the table cache. To remove the table from the - cache we need an exclusive lock. - */ - if (thd->locked_tables_mode) - { - if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN)) - DBUG_RETURN(TRUE); - *ticket_downgrade= table->mdl_ticket; + DEBUG_SYNC(thd, "upgrade_lock_for_truncate"); + /* To remove the table from the cache we need an exclusive lock. */ + if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN)) + DBUG_RETURN(TRUE); + m_ticket_downgrade= table->mdl_ticket; + /* Close if table is going to be recreated. */ + if (*hton_can_recreate) close_all_tables_for_name(thd, table->s, FALSE); - } - else - { - ulong timeout= thd->variables.lock_wait_timeout; - if (thd->mdl_context. - upgrade_shared_lock_to_exclusive(table_ref->mdl_request.ticket, - timeout)) - DBUG_RETURN(TRUE); - tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_ref->db, - table_ref->table_name, FALSE); - } } else { - /* - Can't recreate, we must mechanically delete all rows in - the table. Our metadata lock guarantees that no transaction - is reading or writing into the table. Yet, to open a write - cursor we need a thr_lock lock. Use open_and_lock_tables() - to do the necessary job. - */ - - /* Allow to open base tables only. */ - table_ref->required_type= FRMTYPE_TABLE; - /* We don't need to load triggers. */ - DBUG_ASSERT(table_ref->trg_event_map == 0); - /* - Even though we have an MDL lock on the table here, we don't - pass MYSQL_OPEN_HAS_MDL_LOCK to open_and_lock_tables - since to truncate a MERGE table, we must open and lock - merge children, and on those we don't have an MDL lock. - Thus clear the ticket to satisfy MDL asserts. - */ - table_ref->mdl_request.ticket= NULL; - - /* - Open the table as it will handle some required preparations. - Ignore pending FLUSH TABLES since we don't want to release - the MDL lock taken above and otherwise there is no way to - wait for FLUSH TABLES in deadlock-free fashion. - */ - if (open_and_lock_tables(thd, table_ref, FALSE, - MYSQL_OPEN_IGNORE_FLUSH | - MYSQL_OPEN_SKIP_TEMPORARY)) - DBUG_RETURN(TRUE); + /* Table is already locked exclusively. Remove cached instances. */ + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_ref->db, + table_ref->table_name, FALSE); } DBUG_RETURN(FALSE); @@ -385,14 +390,17 @@ static bool open_and_lock_table_for_truncate(THD *thd, TABLE_LIST *table_ref, @retval TRUE Error. */ -bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref) +bool Truncate_statement::truncate_table(THD *thd, TABLE_LIST *table_ref) { + int error; TABLE *table; - bool error= TRUE, binlog_stmt; - MDL_ticket *mdl_ticket= NULL; - DBUG_ENTER("mysql_truncate_table"); + bool binlog_stmt; + DBUG_ENTER("Truncate_statement::truncate_table"); - /* Remove tables from the HANDLER's hash. */ + /* Initialize, or reinitialize in case of reexecution (SP). */ + m_ticket_downgrade= NULL; + + /* Remove table from the HANDLER's hash. */ mysql_ha_rm_tables(thd, table_ref); /* If it is a temporary table, no need to take locks. */ @@ -413,14 +421,11 @@ bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref) { /* The engine does not support truncate-by-recreate. Open the - table and delete all rows. In such a manner this can in fact - open several tables if it's a temporary MyISAMMRG table. + table and invoke the handler truncate. In such a manner this + can in fact open several tables if it's a temporary MyISAMMRG + table. */ - if (open_and_lock_tables(thd, table_ref, FALSE, - MYSQL_OPEN_TEMPORARY_ONLY)) - DBUG_RETURN(TRUE); - - error= delete_all_rows(thd, table_ref->table); + error= handler_truncate(thd, table_ref, TRUE); } /* @@ -434,8 +439,7 @@ bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref) { bool hton_can_recreate; - if (open_and_lock_table_for_truncate(thd, table_ref, - &hton_can_recreate, &mdl_ticket)) + if (lock_table(thd, table_ref, &hton_can_recreate)) DBUG_RETURN(TRUE); if (hton_can_recreate) @@ -454,13 +458,18 @@ bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref) } else { - error= delete_all_rows(thd, table_ref->table); + /* + The engine does not support truncate-by-recreate. + Attempt to use the handler truncate method. + */ + error= handler_truncate(thd, table_ref, FALSE); /* - Regardless of the error status, the query must be written to the - binary log if rows of a non-transactional table were deleted. + All effects of a TRUNCATE TABLE operation are committed even if + truncation fails. Thus, the query must be written to the binary + log. The only exception is a unimplemented truncate method. */ - binlog_stmt= !error || thd->transaction.stmt.modified_non_trans_table; + binlog_stmt= !error || error != HA_ERR_WRONG_COMMAND; } query_cache_invalidate3(thd, table_ref, FALSE); @@ -470,50 +479,38 @@ bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref) if (binlog_stmt) error|= write_bin_log(thd, !error, thd->query(), thd->query_length()); - /* - All effects of a TRUNCATE TABLE operation are rolled back if a row - by row deletion fails. Otherwise, it is automatically committed at - the end. - */ - if (error) - { - trans_rollback_stmt(thd); - trans_rollback(thd); - } - /* A locked table ticket was upgraded to a exclusive lock. After the the query has been written to the binary log, downgrade the lock to a shared one. */ - if (mdl_ticket) - mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE); + if (m_ticket_downgrade) + m_ticket_downgrade->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE); - DBUG_PRINT("exit", ("error: %d", error)); - DBUG_RETURN(test(error)); + DBUG_RETURN(error); } +/** + Execute a TRUNCATE statement at runtime. + + @param thd The current thread. + + @return FALSE on success. +*/ + bool Truncate_statement::execute(THD *thd) { - TABLE_LIST *first_table= thd->lex->select_lex.table_list.first; bool res= TRUE; + TABLE_LIST *first_table= thd->lex->select_lex.table_list.first; DBUG_ENTER("Truncate_statement::execute"); if (check_one_table_access(thd, DROP_ACL, first_table)) - goto error; - /* - Don't allow this within a transaction because we want to use - re-generate table - */ - if (thd->in_active_multi_stmt_transaction()) - { - my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, - ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); - goto error; - } - if (! (res= mysql_truncate_table(thd, first_table))) + DBUG_RETURN(res); + + if (! (res= truncate_table(thd, first_table))) my_ok(thd); -error: + DBUG_RETURN(res); } + diff --git a/sql/sql_truncate.h b/sql/sql_truncate.h index b8b1d3da53d..95a2f35df4f 100644 --- a/sql/sql_truncate.h +++ b/sql/sql_truncate.h @@ -18,13 +18,15 @@ class THD; struct TABLE_LIST; -bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref); - /** Truncate_statement represents the TRUNCATE statement. */ class Truncate_statement : public Sql_statement { +private: + /* Set if a lock must be downgraded after truncate is done. */ + MDL_ticket *m_ticket_downgrade; + public: /** Constructor, used to represent a ALTER TABLE statement. @@ -34,7 +36,7 @@ public: : Sql_statement(lex) {} - ~Truncate_statement() + virtual ~Truncate_statement() {} /** @@ -43,7 +45,20 @@ public: @return false on success. */ bool execute(THD *thd); + +protected: + /** Handle locking a base table for truncate. */ + bool lock_table(THD *, TABLE_LIST *, bool *); + + /** Truncate table via the handler method. */ + int handler_truncate(THD *, TABLE_LIST *, bool); + + /** + Optimized delete of all rows by doing a full regenerate of the table. + Depending on the storage engine, it can be accomplished through a + drop and recreate or via the handler truncate method. + */ + bool truncate_table(THD *, TABLE_LIST *); }; - #endif diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 7c24f18aa6a..2fc39757511 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -10770,7 +10770,7 @@ truncate: lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED; lex->select_lex.init_order(); YYPS->m_lock_type= TL_WRITE; - YYPS->m_mdl_type= MDL_SHARED_NO_READ_WRITE; + YYPS->m_mdl_type= MDL_EXCLUSIVE; } table_name { diff --git a/sql/table.h b/sql/table.h index 6723293c1ec..c8e1ad8e658 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1170,7 +1170,9 @@ enum enum_schema_table_state typedef struct st_foreign_key_info { - LEX_STRING *forein_id; + LEX_STRING *foreign_id; + LEX_STRING *foreign_db; + LEX_STRING *foreign_table; LEX_STRING *referenced_db; LEX_STRING *referenced_table; LEX_STRING *update_method; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index ef907b035b5..c24fbc21f94 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1650,9 +1650,9 @@ int ha_archive::end_bulk_insert() This is done for security reasons. In a later version we will enable this by allowing the user to select a different row format. */ -int ha_archive::delete_all_rows() +int ha_archive::truncate() { - DBUG_ENTER("ha_archive::delete_all_rows"); + DBUG_ENTER("ha_archive::truncate"); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h index b258b403c3c..fec41c12b81 100644 --- a/storage/archive/ha_archive.h +++ b/storage/archive/ha_archive.h @@ -115,7 +115,7 @@ public: int close(void); int write_row(uchar * buf); int real_write_row(uchar *buf, azio_stream *writer); - int delete_all_rows(); + int truncate(); int rnd_init(bool scan=1); int rnd_next(uchar *buf); int rnd_pos(uchar * buf, uchar *pos); diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc index 6591c3a2c78..04560d89be3 100644 --- a/storage/blackhole/ha_blackhole.cc +++ b/storage/blackhole/ha_blackhole.cc @@ -87,6 +87,16 @@ int ha_blackhole::create(const char *name, TABLE *table_arg, DBUG_RETURN(0); } +/* + Intended to support partitioning. + Allows a particular partition to be truncated. +*/ +int ha_blackhole::truncate() +{ + DBUG_ENTER("ha_blackhole::truncate"); + DBUG_RETURN(0); +} + const char *ha_blackhole::index_type(uint key_number) { DBUG_ENTER("ha_blackhole::index_type"); diff --git a/storage/blackhole/ha_blackhole.h b/storage/blackhole/ha_blackhole.h index 9de3c22c614..17066b6edce 100644 --- a/storage/blackhole/ha_blackhole.h +++ b/storage/blackhole/ha_blackhole.h @@ -76,6 +76,7 @@ public: uint max_supported_key_part_length() const { return BLACKHOLE_MAX_KEY_LENGTH; } int open(const char *name, int mode, uint test_if_locked); int close(void); + int truncate(); int rnd_init(bool scan); int rnd_next(uchar *buf); int rnd_pos(uchar * buf, uchar *pos); diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index 306f8eaeccd..6af471494af 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -356,14 +356,14 @@ int ha_example::close(void) is happening. buf() is a byte array of data. You can use the field information to extract the data from the native byte array type. - @details + @details Example of this would be: - @code + @code for (Field **field=table->field ; *field ; field++) { ... } - @endcode + @endcode See ha_tina.cc for an example of extracting all of the data as strings. ha_berekly.cc has an example of how to store it intact by "packing" it @@ -375,7 +375,7 @@ int ha_example::close(void) Called from item_sum.cc, item_sum.cc, sql_acl.cc, sql_insert.cc, sql_insert.cc, sql_select.cc, sql_table.cc, sql_udf.cc, and sql_update.cc. - @see + @see item_sum.cc, item_sum.cc, sql_acl.cc, sql_insert.cc, sql_insert.cc, sql_select.cc, sql_table.cc, sql_udf.cc and sql_update.cc */ @@ -400,19 +400,19 @@ int ha_example::write_row(uchar *buf) Keep in mind that the server can do updates based on ordering if an ORDER BY clause was used. Consecutive ordering is not guaranteed. - @details + @details Currently new_data will not have an updated auto_increament record, or and updated timestamp field. You can do these for example by doing: - @code + @code if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); if (table->next_number_field && record == table->record[0]) update_auto_increment(); - @endcode + @endcode Called from sql_select.cc, sql_acl.cc, sql_update.cc, and sql_insert.cc. - @see + @see sql_select.cc, sql_acl.cc, sql_update.cc and sql_insert.cc */ int ha_example::update_row(const uchar *old_data, uchar *new_data) @@ -507,10 +507,10 @@ int ha_example::index_prev(uchar *buf) @brief index_first() asks for the first key in the index. - @details + @details Called from opt_range.cc, opt_sum.cc, sql_handler.cc, and sql_select.cc. - @see + @see opt_range.cc, opt_sum.cc, sql_handler.cc and sql_select.cc */ int ha_example::index_first(uchar *buf) @@ -528,10 +528,10 @@ int ha_example::index_first(uchar *buf) @brief index_last() asks for the last key in the index. - @details + @details Called from opt_range.cc, opt_sum.cc, sql_handler.cc, and sql_select.cc. - @see + @see opt_range.cc, opt_sum.cc, sql_handler.cc and sql_select.cc */ int ha_example::index_last(uchar *buf) @@ -551,11 +551,11 @@ int ha_example::index_last(uchar *buf) scan. See the example in the introduction at the top of this file to see when rnd_init() is called. - @details + @details Called from filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc, and sql_update.cc. - @see + @see filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc and sql_update.cc */ int ha_example::rnd_init(bool scan) @@ -578,11 +578,11 @@ int ha_example::rnd_end() The Field structure for the table is the key to getting data into buf in a manner that will allow the server to understand it. - @details + @details Called from filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc, and sql_update.cc. - @see + @see filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc and sql_update.cc */ int ha_example::rnd_next(uchar *buf) @@ -602,11 +602,11 @@ int ha_example::rnd_next(uchar *buf) position() is called after each call to rnd_next() if the data needs to be ordered. You can do something like the following to store the position: - @code + @code my_store_ptr(ref, ref_length, current_position); - @endcode + @endcode - @details + @details The server uses ref to store data. ref_length in the above case is the size needed to store current_position. ref is just a byte array that the server will maintain. If you are using offsets to mark rows, then @@ -615,7 +615,7 @@ int ha_example::rnd_next(uchar *buf) Called from filesort.cc, sql_select.cc, sql_delete.cc, and sql_update.cc. - @see + @see filesort.cc, sql_select.cc, sql_delete.cc and sql_update.cc */ void ha_example::position(const uchar *record) @@ -632,10 +632,10 @@ void ha_example::position(const uchar *record) ref. You can use ha_get_ptr(pos,ref_length) to retrieve whatever key or position you saved when position() was called. - @details + @details Called from filesort.cc, records.cc, sql_insert.cc, sql_select.cc, and sql_update.cc. - @see + @see filesort.cc, records.cc, sql_insert.cc, sql_select.cc and sql_update.cc */ int ha_example::rnd_pos(uchar *buf, uchar *pos) @@ -655,15 +655,15 @@ int ha_example::rnd_pos(uchar *buf, uchar *pos) ::info() is used to return information to the optimizer. See my_base.h for the complete description. - @details + @details Currently this table handler doesn't implement most of the fields really needed. SHOW also makes use of this data. You will probably want to have the following in your code: - @code + @code if (records < 2) records = 2; - @endcode + @endcode The reason is that the server will optimize for cases of only a single record. If, in a table scan, you don't know the number of records, it will probably be better to set records to two so you can return as many @@ -682,7 +682,7 @@ int ha_example::rnd_pos(uchar *buf, uchar *pos) sql_select.cc, sql_select.cc, sql_show.cc, sql_show.cc, sql_show.cc, sql_show.cc, sql_table.cc, sql_union.cc, and sql_update.cc. - @see + @see filesort.cc, ha_heap.cc, item_sum.cc, opt_sum.cc, sql_delete.cc, sql_delete.cc, sql_derived.cc, sql_select.cc, sql_select.cc, sql_select.cc, sql_select.cc, sql_select.cc, sql_show.cc, sql_show.cc, sql_show.cc, sql_show.cc, sql_table.cc, @@ -716,14 +716,14 @@ int ha_example::extra(enum ha_extra_function operation) Used to delete all rows in a table, including cases of truncate and cases where the optimizer realizes that all rows will be removed as a result of an SQL statement. - @details + @details Called from item_sum.cc by Item_func_group_concat::clear(), Item_sum_count_distinct::clear(), and Item_func_group_concat::clear(). Called from sql_delete.cc by mysql_delete(). Called from sql_select.cc by JOIN::reinit(). Called from sql_union.cc by st_select_lex_unit::exec(). - @see + @see Item_func_group_concat::clear(), Item_sum_count_distinct::clear() and Item_func_group_concat::clear() in item_sum.cc; mysql_delete() in sql_delete.cc; @@ -737,6 +737,29 @@ int ha_example::delete_all_rows() } +/** + @brief + Used for handler specific truncate table. The table is locked in + exclusive mode and handler is responsible for reseting the auto- + increment counter. + + @details + Called from Truncate_statement::handler_truncate. + Not used if the handlerton supports HTON_CAN_RECREATE, unless this + engine can be used as a partition. In this case, it is invoked when + a particular partition is to be truncated. + + @see + Truncate_statement in sql_truncate.cc + Remarks in handler::truncate. +*/ +int ha_example::truncate() +{ + DBUG_ENTER("ha_example::truncate"); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); +} + + /** @brief This create a lock on the table. If you are implementing a storage engine @@ -745,11 +768,11 @@ int ha_example::delete_all_rows() here. Hint: Read the section "locking functions for mysql" in lock.cc to understand this. - @details + @details Called from lock.cc by lock_external() and unlock_external(). Also called from sql_table.cc by copy_data_between_tables(). - @see + @see lock.cc by lock_external() and unlock_external() in lock.cc; the section "locking functions for mysql" in lock.cc; copy_data_between_tables() in sql_table.cc. @@ -767,7 +790,7 @@ int ha_example::external_lock(THD *thd, int lock_type) should be needed for the table. For updates/deletes/inserts we get WRITE locks, for SELECT... we get read locks. - @details + @details Before adding the lock into the table lock handler (see thr_lock.c), mysqld calls store lock with the requested locks. Store lock can now modify a write lock to a read lock (or some other lock), ignore the @@ -790,12 +813,12 @@ int ha_example::external_lock(THD *thd, int lock_type) Called from lock.cc by get_lock_data(). - @note + @note In this method one should NEVER rely on table->in_use, it may, in fact, refer to a different thread! (this happens if get_lock_data() is called from mysql_lock_abort_for_thread() function) - @see + @see get_lock_data() in lock.cc */ THR_LOCK_DATA **ha_example::store_lock(THD *thd, @@ -816,7 +839,7 @@ THR_LOCK_DATA **ha_example::store_lock(THD *thd, shared references released). The variable name will just be the name of the table. You will need to remove any files you have created at this point. - @details + @details If you do not implement this, the default delete_table() is called from handler.cc and it will delete all files with the file extensions returned by bas_ext(). @@ -825,7 +848,7 @@ THR_LOCK_DATA **ha_example::store_lock(THD *thd, during create if the table_flag HA_DROP_BEFORE_CREATE was specified for the storage engine. - @see + @see delete_table and ha_create_table() in handler.cc */ int ha_example::delete_table(const char *name) diff --git a/storage/example/ha_example.h b/storage/example/ha_example.h index 12e088f5f05..5555a10930b 100644 --- a/storage/example/ha_example.h +++ b/storage/example/ha_example.h @@ -245,6 +245,7 @@ public: int extra(enum ha_extra_function operation); int external_lock(THD *thd, int lock_type); ///< required int delete_all_rows(void); + int truncate(); ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); int delete_table(const char *from); diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index b1ae276dce8..fb10ce82334 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -3041,6 +3041,16 @@ int ha_federated::delete_all_rows() } +/* + Used to manually truncate the table via a delete of all rows in a table. +*/ + +int ha_federated::truncate() +{ + return delete_all_rows(); +} + + /* The idea with handler::store_lock() is the following: diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h index 0f4c0201bd7..e39bac525b5 100644 --- a/storage/federated/ha_federated.h +++ b/storage/federated/ha_federated.h @@ -248,6 +248,7 @@ public: int optimize(THD* thd, HA_CHECK_OPT* check_opt); int delete_all_rows(void); + int truncate(); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); //required ha_rows records_in_range(uint inx, key_range *start_key, diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index 481257def1d..fc870d33fb2 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -455,6 +455,13 @@ int ha_heap::delete_all_rows() } +int ha_heap::truncate() +{ + int error= delete_all_rows(); + return error ? error : reset_auto_increment(0); +} + + int ha_heap::reset_auto_increment(ulonglong value) { file->s->auto_increment= value; diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h index 7185fbc7720..5f3d66cd53c 100644 --- a/storage/heap/ha_heap.h +++ b/storage/heap/ha_heap.h @@ -99,6 +99,7 @@ public: int reset(); int external_lock(THD *thd, int lock_type); int delete_all_rows(void); + int truncate(); int reset_auto_increment(ulonglong value); int disable_indexes(uint mode); int enable_indexes(uint mode); diff --git a/storage/ibmdb2i/db2i_constraints.cc b/storage/ibmdb2i/db2i_constraints.cc index 3afa12032d0..5b9d3600393 100644 --- a/storage/ibmdb2i/db2i_constraints.cc +++ b/storage/ibmdb2i/db2i_constraints.cc @@ -494,10 +494,10 @@ int ha_ibmdb2i::get_foreign_key_list(THD *thd, List *f_key_lis convFromEbcdic(FKCstDef->CstName.Name, convName,FKCstDef->CstName.Len); if (convName[0] == '"') // If quoted, exclude quotes. - f_key_info.forein_id = thd_make_lex_string(thd, 0, + f_key_info.foreign_id = thd_make_lex_string(thd, 0, convName + 1, (uint) (FKCstDef->CstName.Len - 2), 1); else // Not quoted - f_key_info.forein_id = thd_make_lex_string(thd, 0, + f_key_info.foreign_id = thd_make_lex_string(thd, 0, convName, (uint) FKCstDef->CstName.Len, 1); /* Process the names of the foreign keys. */ diff --git a/storage/ibmdb2i/ha_ibmdb2i.cc b/storage/ibmdb2i/ha_ibmdb2i.cc index 947df8ad2fe..e5eccad1573 100644 --- a/storage/ibmdb2i/ha_ibmdb2i.cc +++ b/storage/ibmdb2i/ha_ibmdb2i.cc @@ -1806,6 +1806,13 @@ int ha_ibmdb2i::delete_all_rows() } +int ha_ibmdb2i::truncate() +{ + int error = delete_all_rows(); + return error ? error : reset_auto_increment(0); +} + + int ha_ibmdb2i::external_lock(THD *thd, int lock_type) { int rc = 0; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index eafc73b4f87..d68fcadffad 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7081,33 +7081,21 @@ Deletes all rows of an InnoDB table. @return error number */ UNIV_INTERN int -ha_innobase::delete_all_rows(void) +ha_innobase::truncate(void) /*==============================*/ { int error; - DBUG_ENTER("ha_innobase::delete_all_rows"); + DBUG_ENTER("ha_innobase::truncate"); /* Get the transaction associated with the current thd, or create one if not yet created, and update prebuilt->trx */ update_thd(ha_thd()); - if (thd_sql_command(user_thd) != SQLCOM_TRUNCATE) { - fallback: - /* We only handle TRUNCATE TABLE t as a special case. - DELETE FROM t will have to use ha_innobase::delete_row(), - because DELETE is transactional while TRUNCATE is not. */ - DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND); - } - /* Truncate the table in InnoDB */ error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx); - if (error == DB_ERROR) { - /* Cannot truncate; resort to ha_innobase::delete_row() */ - goto fallback; - } error = convert_error_code_to_mysql(error, prebuilt->table->flags, NULL); @@ -8315,136 +8303,199 @@ ha_innobase::get_foreign_key_create_info(void) } +/***********************************************************************//** +Maps a InnoDB foreign key constraint to a equivalent MySQL foreign key info. +@return pointer to foreign key info */ +static +FOREIGN_KEY_INFO* +get_foreign_key_info( +/*=================*/ + THD* thd, /*!< in: user thread handle */ + dict_foreign_t* foreign) /*!< in: foreign key constraint */ +{ + FOREIGN_KEY_INFO f_key_info; + FOREIGN_KEY_INFO* pf_key_info; + uint i = 0; + ulint len; + char tmp_buff[NAME_LEN+1]; + char name_buff[NAME_LEN+1]; + const char* ptr; + LEX_STRING* referenced_key_name; + LEX_STRING* name = NULL; + + ptr = dict_remove_db_name(foreign->id); + f_key_info.foreign_id = thd_make_lex_string(thd, 0, ptr, + (uint) strlen(ptr), 1); + + /* Name format: database name, '/', table name, '\0' */ + + /* Referenced (parent) database name */ + len = dict_get_db_name_len(foreign->referenced_table_name); + ut_a(len < sizeof(tmp_buff)); + ut_memcpy(tmp_buff, foreign->referenced_table_name, len); + tmp_buff[len] = 0; + + len = filename_to_tablename(tmp_buff, name_buff, sizeof(name_buff)); + f_key_info.referenced_db = thd_make_lex_string(thd, 0, name_buff, len, 1); + + /* Referenced (parent) table name */ + ptr = dict_remove_db_name(foreign->referenced_table_name); + len = filename_to_tablename(ptr, name_buff, sizeof(name)); + f_key_info.referenced_table = thd_make_lex_string(thd, 0, name_buff, len, 1); + + /* Dependent (child) database name */ + len = dict_get_db_name_len(foreign->foreign_table_name); + ut_a(len < sizeof(tmp_buff)); + ut_memcpy(tmp_buff, foreign->foreign_table_name, len); + tmp_buff[len] = 0; + + len = filename_to_tablename(tmp_buff, name_buff, sizeof(name_buff)); + f_key_info.foreign_db = thd_make_lex_string(thd, 0, name_buff, len, 1); + + /* Dependent (child) table name */ + ptr = dict_remove_db_name(foreign->foreign_table_name); + len = filename_to_tablename(ptr, name_buff, sizeof(name_buff)); + f_key_info.foreign_table = thd_make_lex_string(thd, 0, name_buff, len, 1); + + do { + ptr = foreign->foreign_col_names[i]; + name = thd_make_lex_string(thd, name, ptr, + (uint) strlen(ptr), 1); + f_key_info.foreign_fields.push_back(name); + ptr = foreign->referenced_col_names[i]; + name = thd_make_lex_string(thd, name, ptr, + (uint) strlen(ptr), 1); + f_key_info.referenced_fields.push_back(name); + } while (++i < foreign->n_fields); + + if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE) { + len = 7; + ptr = "CASCADE"; + } else if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) { + len = 8; + ptr = "SET NULL"; + } else if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) { + len = 9; + ptr = "NO ACTION"; + } else { + len = 8; + ptr = "RESTRICT"; + } + + f_key_info.delete_method = thd_make_lex_string(thd, + f_key_info.delete_method, + ptr, len, 1); + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) { + len = 7; + ptr = "CASCADE"; + } else if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) { + len = 8; + ptr = "SET NULL"; + } else if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) { + len = 9; + ptr = "NO ACTION"; + } else { + len = 8; + ptr = "RESTRICT"; + } + + f_key_info.update_method = thd_make_lex_string(thd, + f_key_info.update_method, + ptr, len, 1); + + if (foreign->referenced_index && foreign->referenced_index->name) { + referenced_key_name = thd_make_lex_string(thd, + f_key_info.referenced_key_name, + foreign->referenced_index->name, + (uint) strlen(foreign->referenced_index->name), + 1); + } else { + referenced_key_name = NULL; + } + + f_key_info.referenced_key_name = referenced_key_name; + + pf_key_info = (FOREIGN_KEY_INFO *) thd_memdup(thd, &f_key_info, + sizeof(FOREIGN_KEY_INFO)); + + return(pf_key_info); +} + +/*******************************************************************//** +Gets the list of foreign keys in this table. +@return always 0, that is, always succeeds */ UNIV_INTERN int -ha_innobase::get_foreign_key_list(THD *thd, List *f_key_list) +ha_innobase::get_foreign_key_list( +/*==============================*/ + THD* thd, /*!< in: user thread handle */ + List* f_key_list) /*!< out: foreign key list */ { - dict_foreign_t* foreign; + FOREIGN_KEY_INFO* pf_key_info; + dict_foreign_t* foreign; - DBUG_ENTER("get_foreign_key_list"); - ut_a(prebuilt != NULL); - update_thd(ha_thd()); - prebuilt->trx->op_info = (char*)"getting list of foreign keys"; - trx_search_latch_release_if_reserved(prebuilt->trx); - mutex_enter(&(dict_sys->mutex)); - foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list); + ut_a(prebuilt != NULL); + update_thd(ha_thd()); - while (foreign != NULL) { - uint i; - FOREIGN_KEY_INFO f_key_info; - LEX_STRING *name= 0; - uint ulen; - char uname[NAME_LEN+1]; /* Unencoded name */ - char db_name[NAME_LEN+1]; - const char *tmp_buff; + prebuilt->trx->op_info = "getting list of foreign keys"; - tmp_buff= foreign->id; - i= 0; - while (tmp_buff[i] != '/') - i++; - tmp_buff+= i + 1; - f_key_info.forein_id = thd_make_lex_string(thd, 0, - tmp_buff, (uint) strlen(tmp_buff), 1); - tmp_buff= foreign->referenced_table_name; + trx_search_latch_release_if_reserved(prebuilt->trx); - /* Database name */ - i= 0; - while (tmp_buff[i] != '/') - { - db_name[i]= tmp_buff[i]; - i++; - } - db_name[i]= 0; - ulen= filename_to_tablename(db_name, uname, sizeof(uname)); - f_key_info.referenced_db = thd_make_lex_string(thd, 0, - uname, ulen, 1); + mutex_enter(&(dict_sys->mutex)); - /* Table name */ - tmp_buff+= i + 1; - ulen= filename_to_tablename(tmp_buff, uname, sizeof(uname)); - f_key_info.referenced_table = thd_make_lex_string(thd, 0, - uname, ulen, 1); + for (foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list); + foreign != NULL; + foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) { + pf_key_info = get_foreign_key_info(thd, foreign); + if (pf_key_info) { + f_key_list->push_back(pf_key_info); + } + } - for (i= 0;;) { - tmp_buff= foreign->foreign_col_names[i]; - name = thd_make_lex_string(thd, name, - tmp_buff, (uint) strlen(tmp_buff), 1); - f_key_info.foreign_fields.push_back(name); - tmp_buff= foreign->referenced_col_names[i]; - name = thd_make_lex_string(thd, name, - tmp_buff, (uint) strlen(tmp_buff), 1); - f_key_info.referenced_fields.push_back(name); - if (++i >= foreign->n_fields) - break; - } + mutex_exit(&(dict_sys->mutex)); - ulong length; - if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE) - { - length=7; - tmp_buff= "CASCADE"; - } - else if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) - { - length=8; - tmp_buff= "SET NULL"; - } - else if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) - { - length=9; - tmp_buff= "NO ACTION"; - } - else - { - length=8; - tmp_buff= "RESTRICT"; - } - f_key_info.delete_method = thd_make_lex_string( - thd, f_key_info.delete_method, tmp_buff, length, 1); + prebuilt->trx->op_info = ""; + return(0); +} - if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) - { - length=7; - tmp_buff= "CASCADE"; - } - else if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) - { - length=8; - tmp_buff= "SET NULL"; - } - else if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) - { - length=9; - tmp_buff= "NO ACTION"; - } - else - { - length=8; - tmp_buff= "RESTRICT"; - } - f_key_info.update_method = thd_make_lex_string( - thd, f_key_info.update_method, tmp_buff, length, 1); - if (foreign->referenced_index && - foreign->referenced_index->name) - { - f_key_info.referenced_key_name = thd_make_lex_string( - thd, f_key_info.referenced_key_name, - foreign->referenced_index->name, - (uint) strlen(foreign->referenced_index->name), 1); - } - else - f_key_info.referenced_key_name= 0; +/*******************************************************************//** +Gets the set of foreign keys where this table is the referenced table. +@return always 0, that is, always succeeds */ +UNIV_INTERN +int +ha_innobase::get_parent_foreign_key_list( +/*=====================================*/ + THD* thd, /*!< in: user thread handle */ + List* f_key_list) /*!< out: foreign key list */ +{ + FOREIGN_KEY_INFO* pf_key_info; + dict_foreign_t* foreign; - FOREIGN_KEY_INFO *pf_key_info = (FOREIGN_KEY_INFO *) - thd_memdup(thd, &f_key_info, sizeof(FOREIGN_KEY_INFO)); - f_key_list->push_back(pf_key_info); - foreign = UT_LIST_GET_NEXT(foreign_list, foreign); - } - mutex_exit(&(dict_sys->mutex)); - prebuilt->trx->op_info = (char*)""; + ut_a(prebuilt != NULL); + update_thd(ha_thd()); - DBUG_RETURN(0); + prebuilt->trx->op_info = "getting list of referencing foreign keys"; + + trx_search_latch_release_if_reserved(prebuilt->trx); + + mutex_enter(&(dict_sys->mutex)); + + for (foreign = UT_LIST_GET_FIRST(prebuilt->table->referenced_list); + foreign != NULL; + foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) { + pf_key_info = get_foreign_key_info(thd, foreign); + if (pf_key_info) { + f_key_list->push_back(pf_key_info); + } + } + + mutex_exit(&(dict_sys->mutex)); + + prebuilt->trx->op_info = ""; + + return(0); } /*****************************************************************//** diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 8f118199ad8..4e128178f2b 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -178,13 +178,15 @@ class ha_innobase: public handler void update_create_info(HA_CREATE_INFO* create_info); int create(const char *name, register TABLE *form, HA_CREATE_INFO *create_info); - int delete_all_rows(); + int truncate(); int delete_table(const char *name); int rename_table(const char* from, const char* to); int check(THD* thd, HA_CHECK_OPT* check_opt); char* update_table_comment(const char* comment); char* get_foreign_key_create_info(); int get_foreign_key_list(THD *thd, List *f_key_list); + int get_parent_foreign_key_list(THD *thd, + List *f_key_list); bool can_switch_engines(); uint referenced_by_foreign_key(); void free_foreign_key_create_info(char* str); diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index c12970b40ed..62f9ab07af9 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -2985,8 +2985,7 @@ next_rec: dict_table_change_id_in_cache(table, new_id); } - /* MySQL calls ha_innobase::reset_auto_increment() which does - the same thing. */ + /* Reset auto-increment. */ dict_table_autoinc_lock(table); dict_table_autoinc_initialize(table, 1); dict_table_autoinc_unlock(table); diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 87de58076cd..2ba62d03c6b 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1788,6 +1788,18 @@ int ha_myisam::delete_all_rows() return mi_delete_all_rows(file); } + +/* + Intended to support partitioning. + Allows a particular partition to be truncated. +*/ + +int ha_myisam::truncate() +{ + int error= delete_all_rows(); + return error ? error : reset_auto_increment(0); +} + int ha_myisam::reset_auto_increment(ulonglong value) { file->s->state.auto_increment= value; diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index 1a8246ae882..46b732512ac 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -107,6 +107,7 @@ class ha_myisam: public handler int reset(void); int external_lock(THD *thd, int lock_type); int delete_all_rows(void); + int truncate(); int reset_auto_increment(ulonglong value); int disable_indexes(uint mode); int enable_indexes(uint mode); diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 26e54d61101..79696cad721 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -1226,6 +1226,22 @@ ha_rows ha_myisammrg::records_in_range(uint inx, key_range *min_key, } +int ha_myisammrg::truncate() +{ + int err= 0; + MYRG_TABLE *table; + DBUG_ENTER("ha_myisammrg::truncate"); + + for (table= file->open_tables; table != file->end_table; table++) + { + if ((err= mi_delete_all_rows(table->table))) + break; + } + + DBUG_RETURN(err); +} + + int ha_myisammrg::info(uint flag) { MYMERGE_INFO mrg_info; diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h index 4ff24c69071..cae4bd17f50 100644 --- a/storage/myisammrg/ha_myisammrg.h +++ b/storage/myisammrg/ha_myisammrg.h @@ -131,6 +131,7 @@ public: int rnd_pos(uchar * buf, uchar *pos); void position(const uchar *record); ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); + int truncate(); int info(uint); int reset(void); int extra(enum ha_extra_function operation); diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc index e5e324d6c6b..896117397a2 100644 --- a/storage/perfschema/ha_perfschema.cc +++ b/storage/perfschema/ha_perfschema.cc @@ -345,6 +345,11 @@ int ha_perfschema::delete_all_rows(void) DBUG_RETURN(result); } +int ha_perfschema::truncate() +{ + return delete_all_rows(); +} + THR_LOCK_DATA **ha_perfschema::store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type) diff --git a/storage/perfschema/ha_perfschema.h b/storage/perfschema/ha_perfschema.h index 2c7b45fbbf7..1a0c16541be 100644 --- a/storage/perfschema/ha_perfschema.h +++ b/storage/perfschema/ha_perfschema.h @@ -127,6 +127,8 @@ public: int delete_all_rows(void); + int truncate(); + int delete_table(const char *from); int rename_table(const char * from, const char * to); From 985fa88f8b07743dd3a848c11bc1d93b826d3d62 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 6 Oct 2010 19:06:13 +0400 Subject: [PATCH 015/151] Fix for Bug#57094 (Copyright notice incorrect?). The fix is to: - introduce ORACLE_WELCOME_COPYRIGHT_NOTICE define to have a single place to specify copyright notice; - replace custom copyright notices with ORACLE_WELCOME_COPYRIGHT_NOTICE in programs. --- client/mysql.cc | 10 +++------- client/mysql_upgrade.c | 5 ++++- client/mysqladmin.cc | 9 ++++----- client/mysqlbinlog.cc | 8 +++----- client/mysqlcheck.c | 9 +++------ client/mysqldump.c | 7 ++++--- client/mysqlimport.c | 7 ++++--- client/mysqlshow.c | 6 +++--- client/mysqlslap.c | 13 ++++--------- client/mysqltest.cc | 7 ++++--- include/welcome_copyright_notice.h | 31 ++++++++++++++++++++++++++++++ sql/mysqld.cc | 11 ++++------- 12 files changed, 71 insertions(+), 52 deletions(-) create mode 100644 include/welcome_copyright_notice.h diff --git a/client/mysql.cc b/client/mysql.cc index 14473ba4b51..4a8579bbd4d 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -13,11 +13,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define COPYRIGHT_NOTICE "\ -Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.\n\ -This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL v2 license\n" - /* mysql command tool * Commands compatible with mSQL by David J. Hughes * @@ -110,6 +105,7 @@ extern "C" { #endif #include "completion_hash.h" +#include // ORACLE_WELCOME_COPYRIGHT_NOTICE #define PROMPT_CHAR '\\' #define DEFAULT_DELIMITER ";" @@ -1177,7 +1173,7 @@ int main(int argc,char *argv[]) mysql_thread_id(&mysql), server_version_string(&mysql)); put_info((char*) glob_buffer.ptr(),INFO_INFO); - put_info(COPYRIGHT_NOTICE, INFO_INFO); + put_info(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010"), INFO_INFO); #ifdef HAVE_READLINE initialize_readline((char*) my_progname); @@ -1595,7 +1591,7 @@ static void usage(int version) if (version) return; - printf("%s", COPYRIGHT_NOTICE); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); printf("Usage: %s [OPTIONS] [database]\n", my_progname); my_print_help(my_long_options); print_defaults("my", load_default_groups); diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 882350f813b..4fbf08102bd 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,6 +17,8 @@ #include #include "../scripts/mysql_fix_privilege_tables_sql.c" +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ + #define VER "1.1" #ifdef HAVE_SYS_WAIT_H @@ -232,6 +234,7 @@ get_one_option(int optid, const struct my_option *opt, case '?': printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); puts("MySQL utility for upgrading databases to new MySQL versions.\n"); my_print_help(my_long_options); exit(0); diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 69381b749a1..342a67fbc29 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,6 +23,7 @@ #include #include #include +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ #define ADMIN_VERSION "8.42" #define MAX_MYSQL_VAR 512 @@ -671,8 +672,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) case ADMIN_VER: new_line=1; print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); printf("Server version\t\t%s\n", mysql_get_server_info(mysql)); printf("Protocol version\t%d\n", mysql_get_proto_info(mysql)); printf("Connection\t\t%s\n",mysql_get_host_info(mysql)); @@ -1070,8 +1070,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); puts("Administration program for the mysqld daemon."); printf("Usage: %s [OPTIONS] command command....\n", my_progname); my_print_help(my_long_options); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 277c2d62544..226776e4404 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2004 MySQL AB +/* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -34,6 +34,7 @@ #include "sql_priv.h" #include "log_event.h" #include "sql_common.h" +#include // ORACLE_WELCOME_COPYRIGHT_NOTICE #define BIN_LOG_HEADER_SIZE 4 #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) @@ -1239,10 +1240,7 @@ static void print_version() static void usage() { print_version(); - puts("By Monty and Sasha, for your professional use\n\ -This software comes with NO WARRANTY: This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license.\n"); - + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2001, 2010")); printf("\ Dumps a MySQL binary log in a format usable for viewing or for piping to\n\ the mysql command line client.\n\n"); diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index ce733e57db6..aebe80b9ba6 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB, 2009 Sun Microsystems, Inc +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,8 +13,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* By Jani Tolonen, 2001-04-20, MySQL Development Team */ - #define CHECK_VERSION "2.5.0" #include "client_priv.h" @@ -22,6 +20,7 @@ #include #include #include +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ /* Exit codes */ @@ -215,9 +214,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("By Jani Tolonen, 2001-04-20, MySQL Development Team.\n"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); - puts("and you are welcome to modify and redistribute it under the GPL license.\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); puts("This program can be used to CHECK (-c, -m, -C), REPAIR (-r), ANALYZE (-a),"); puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be"); puts("used at the same time. Not all options are supported by all storage engines."); diff --git a/client/mysqldump.c b/client/mysqldump.c index ac704f152de..b47d88290a5 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc. +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -51,6 +51,8 @@ #include "mysql_version.h" #include "mysqld_error.h" +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ + /* Exit codes */ #define EX_USAGE 1 @@ -584,8 +586,7 @@ static void short_usage_sub(void) static void usage(void) { print_version(); - puts("By Igor Romanenko, Monty, Jani & Sinisa."); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license.\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); puts("Dumping structure and contents of MySQL databases and tables."); short_usage_sub(); print_defaults("my",load_default_groups); diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 3d71e437e40..aea1cb79e74 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB, 2009 Sun Microsystems, Inc. +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,6 +32,8 @@ #include #endif +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ + /* Global Thread counter */ uint counter; @@ -191,8 +193,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license.\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); printf("\ Loads tables from text files in various formats. The base name of the\n\ text file must be the name of the table that should be used.\n\ diff --git a/client/mysqlshow.c b/client/mysqlshow.c index bb05400e0d8..8cd70db1424 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,6 +25,7 @@ #include #include #include +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ static char * host=0, *opt_password=0, *user=0; static my_bool opt_show_keys= 0, opt_compress= 0, opt_count=0, opt_status= 0; @@ -247,8 +248,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license.\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010)")); puts("Shows the structure of a MySQL database (databases, tables, and columns).\n"); printf("Usage: %s [OPTIONS] [database [table [column]]]\n",my_progname); puts("\n\ diff --git a/client/mysqlslap.c b/client/mysqlslap.c index e605e2d522c..4e8e4f1aa67 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 MySQL AB, 2009 Sun Microsystems, Inc. +/* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,12 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - original idea: Brian Aker via playing with ab for too many years - coded by: Patrick Galbraith -*/ - + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* MySQL Slap @@ -94,6 +89,7 @@ TODO: #include #endif #include +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ #ifdef __WIN__ #define srandom srand @@ -686,8 +682,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright (C) 2005 MySQL AB"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license.\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2005, 2010")); puts("Run a query multiple times against the server.\n"); printf("Usage: %s [OPTIONS]\n",my_progname); print_defaults("my",load_default_groups); diff --git a/client/mysqltest.cc b/client/mysqltest.cc index b75fae7b685..376ce0fa59d 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -52,6 +52,8 @@ #include #include +#include // ORACLE_WELCOME_COPYRIGHT_NOTICE + #ifdef __WIN__ #include #define SIGNAL_FMT "exception 0x%x" @@ -6260,8 +6262,7 @@ void print_version(void) void usage() { print_version(); - printf("MySQL AB, by Sasha, Matt, Monty & Jani\n"); - printf("This software comes with ABSOLUTELY NO WARRANTY\n\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); printf("Runs a test against the mysql server and compares output with a results file.\n\n"); printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname); my_print_help(my_long_options); diff --git a/include/welcome_copyright_notice.h b/include/welcome_copyright_notice.h new file mode 100644 index 00000000000..c3ffad1527d --- /dev/null +++ b/include/welcome_copyright_notice.h @@ -0,0 +1,31 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _welcome_copyright_notice_h_ +#define _welcome_copyright_notice_h_ + +/* + This define specifies copyright notice which is displayed by every MySQL + program on start, or on help screen. +*/ + +#define ORACLE_WELCOME_COPYRIGHT_NOTICE(years) \ + "Copyright (c) " years ", Oracle and/or its affiliates. All rights reserved.\n" \ + "\n" \ + "Oracle is a registered trademark of Oracle Corporation and/or its\n" \ + "affiliates. Other names may be trademarks of their respective\n" \ + "owners.\n" + +#endif /* _welcome_copyright_notice_h_ */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1ab335eb106..e43320f12a5 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -265,6 +265,8 @@ extern "C" sig_handler handle_segfault(int sig); /* Constants */ +#include // ORACLE_WELCOME_COPYRIGHT_NOTICE + const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"}; static const char *tc_heuristic_recover_names[]= @@ -6593,13 +6595,8 @@ static void usage(void) if (!default_collation_name) default_collation_name= (char*) default_charset_info->name; print_version(); - puts("\ -Copyright (C) 2000-2008 MySQL AB, by Monty and others.\n\ -Copyright (C) 2008,2009 Sun Microsystems, Inc.\n\ -This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license\n\n\ -Starts the MySQL database server.\n"); - + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); + puts("Starts the MySQL database server.\n"); printf("Usage: %s [OPTIONS]\n", my_progname); if (!opt_verbose) puts("\nFor more help options (several pages), use mysqld --verbose --help."); From 8642812c98b37f91f1cbbc58e0964702d1d37e23 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Wed, 6 Oct 2010 19:20:18 +0200 Subject: [PATCH 016/151] Bug #52131: SET and ENUM stored endian-dependent in binary log Replication SET and ENUM fields from a big-endian to a little- endian machine (or the opposite) that are represented using more than 1 byte (SET fields with more than 8 members or ENUM fields with more than 256 constants) will fail to replicate correctly when using row-based replication. The reason is that there are no pack() or unpack() functions for Field_set or Field_enum, which make them rely on Field::pack and Field::unpack. These functions pack data as strings, but since Field_set and Field_enum use integral types for representation, the fields are stored incorrectly on big-endian machines. This patch adds Field_enum::pack and Field_enum::unpack functions that store the integral value correctly in the binary log even on big-endian machines. Since Field_set inherits from Field_enum, it will use the same functions for packing and unpacking the field. sql/field.cc: Removing some obsolete debug printouts and adding Field_enum::pack and Field_enum::unpack functions. sql/field.h: Adding helper functions for packing and unpacking 16- and 24-bit integral types. Field_short::pack and Field_short::unpack now use these functions. sql/rpl_record.cc: Removing some obsolete debug printouts and adding some more useful ones. --- sql/field.cc | 53 +++++++++++++++++++---- sql/field.h | 106 +++++++++++++++++++++++++++++++++------------- sql/rpl_record.cc | 10 +++-- 3 files changed, 127 insertions(+), 42 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index 728cd7e4090..b83b2bfae5a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7725,12 +7725,6 @@ void Field_blob::sql_type(String &res) const uchar *Field_blob::pack(uchar *to, const uchar *from, uint max_length, bool low_byte_first) { - DBUG_ENTER("Field_blob::pack"); - DBUG_PRINT("enter", ("to: 0x%lx; from: 0x%lx;" - " max_length: %u; low_byte_first: %d", - (ulong) to, (ulong) from, - max_length, low_byte_first)); - DBUG_DUMP("record", from, table->s->reclength); uchar *save= ptr; ptr= (uchar*) from; uint32 length=get_length(); // Length of from string @@ -7751,8 +7745,7 @@ uchar *Field_blob::pack(uchar *to, const uchar *from, memcpy(to+packlength, from,length); } ptr=save; // Restore org row pointer - DBUG_DUMP("packed", to, packlength + length); - DBUG_RETURN(to+packlength+length); + return to+packlength+length; } @@ -8396,6 +8389,50 @@ uint Field_enum::is_equal(Create_field *new_field) } +uchar *Field_enum::pack(uchar *to, const uchar *from, + uint max_length, bool low_byte_first) +{ + DBUG_ENTER("Field_enum::pack"); + DBUG_PRINT("debug", ("packlength: %d", packlength)); + DBUG_DUMP("from", from, packlength); + + switch (packlength) + { + case 1: + *to = *from; + DBUG_RETURN(to + 1); + case 2: DBUG_RETURN(pack_int16(to, from, low_byte_first)); + case 3: DBUG_RETURN(pack_int24(to, from, low_byte_first)); + case 4: DBUG_RETURN(pack_int32(to, from, low_byte_first)); + case 8: DBUG_RETURN(pack_int64(to, from, low_byte_first)); + default: + DBUG_ASSERT(0); + } +} + +const uchar *Field_enum::unpack(uchar *to, const uchar *from, + uint param_data, bool low_byte_first) +{ + DBUG_ENTER("Field_enum::unpack"); + DBUG_PRINT("debug", ("packlength: %d", packlength)); + DBUG_DUMP("from", from, packlength); + + switch (packlength) + { + case 1: + *to = *from; + DBUG_RETURN(from + 1); + + case 2: DBUG_RETURN(unpack_int16(to, from, low_byte_first)); + case 3: DBUG_RETURN(unpack_int24(to, from, low_byte_first)); + case 4: DBUG_RETURN(unpack_int32(to, from, low_byte_first)); + case 8: DBUG_RETURN(unpack_int64(to, from, low_byte_first)); + default: + DBUG_ASSERT(0); + } +} + + /** @return returns 1 if the fields are equally defined diff --git a/sql/field.h b/sql/field.h index 7b250c34fe4..d854b78f9a3 100644 --- a/sql/field.h +++ b/sql/field.h @@ -554,6 +554,48 @@ private: { return 0; } protected: + static void handle_int16(uchar *to, const uchar *from, + bool low_byte_first_from, bool low_byte_first_to) + { + int16 val; +#ifdef WORDS_BIGENDIAN + if (low_byte_first_from) + val = sint2korr(from); + else +#endif + shortget(val, from); + +#ifdef WORDS_BIGENDIAN + if (low_byte_first_to) + int2store(to, val); + else +#endif + shortstore(to, val); + } + + static void handle_int24(uchar *to, const uchar *from, + bool low_byte_first_from, bool low_byte_first_to) + { + int32 val; +#ifdef WORDS_BIGENDIAN + if (low_byte_first_from) + val = sint3korr(from); + else +#endif + val= (from[0] << 16) + (from[1] << 8) + from[2]; + +#ifdef WORDS_BIGENDIAN + if (low_byte_first_to) + int2store(to, val); + else +#endif + { + to[0]= 0xFF & (val >> 16); + to[1]= 0xFF & (val >> 8); + to[2]= 0xFF & val; + } + } + /* Helper function to pack()/unpack() int32 values */ @@ -598,6 +640,32 @@ protected: longlongstore(to, val); } + uchar *pack_int16(uchar *to, const uchar *from, bool low_byte_first_to) + { + handle_int16(to, from, table->s->db_low_byte_first, low_byte_first_to); + return to + sizeof(int16); + } + + const uchar *unpack_int16(uchar* to, const uchar *from, + bool low_byte_first_from) + { + handle_int16(to, from, low_byte_first_from, table->s->db_low_byte_first); + return from + sizeof(int16); + } + + uchar *pack_int24(uchar *to, const uchar *from, bool low_byte_first_to) + { + handle_int24(to, from, table->s->db_low_byte_first, low_byte_first_to); + return to + 3; + } + + const uchar *unpack_int24(uchar* to, const uchar *from, + bool low_byte_first_from) + { + handle_int24(to, from, low_byte_first_from, table->s->db_low_byte_first); + return from + 3; + } + uchar *pack_int32(uchar *to, const uchar *from, bool low_byte_first_to) { handle_int32(to, from, table->s->db_low_byte_first, low_byte_first_to); @@ -918,41 +986,13 @@ public: virtual uchar *pack(uchar* to, const uchar *from, uint max_length, bool low_byte_first) { - int16 val; -#ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) - val = sint2korr(from); - else -#endif - shortget(val, from); - -#ifdef WORDS_BIGENDIAN - if (low_byte_first) - int2store(to, val); - else -#endif - shortstore(to, val); - return to + sizeof(val); + return pack_int16(to, from, low_byte_first); } virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data, bool low_byte_first) { - int16 val; -#ifdef WORDS_BIGENDIAN - if (low_byte_first) - val = sint2korr(from); - else -#endif - shortget(val, from); - -#ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) - int2store(to, val); - else -#endif - shortstore(to, val); - return from + sizeof(val); + return unpack_int16(to, from, low_byte_first); } }; @@ -1895,6 +1935,12 @@ public: bool has_charset(void) const { return TRUE; } /* enum and set are sorted as integers */ CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; } + + virtual uchar *pack(uchar *to, const uchar *from, + uint max_length, bool low_byte_first); + virtual const uchar *unpack(uchar *to, const uchar *from, + uint param_data, bool low_byte_first); + private: int do_save_field_metadata(uchar *first_byte); uint is_equal(Create_field *new_field); diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index 8219f70727e..dd16318303d 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -78,8 +78,6 @@ pack_row(TABLE *table, MY_BITMAP const* cols, unsigned int null_mask= 1U; for ( ; (field= *p_field) ; p_field++) { - DBUG_PRINT("debug", ("null_mask=%d; null_ptr=%p; row_data=%p; null_byte_count=%d", - null_mask, null_ptr, row_data, null_byte_count)); if (bitmap_is_set(cols, p_field - table->field)) { my_ptrdiff_t offset; @@ -110,6 +108,7 @@ pack_row(TABLE *table, MY_BITMAP const* cols, field->field_name, field->real_type(), (ulong) old_pack_ptr, (ulong) pack_ptr, (int) (pack_ptr - old_pack_ptr))); + DBUG_DUMP("packed_data", old_pack_ptr, pack_ptr - old_pack_ptr); } null_mask <<= 1; @@ -380,8 +379,11 @@ unpack_row(Relay_log_info const *rli, } DBUG_ASSERT(null_mask & 0xFF); // One of the 8 LSB should be set - if (!((null_bits & null_mask) && tabledef->maybe_null(i))) - pack_ptr+= tabledef->calc_field_size(i, (uchar *) pack_ptr); + if (!((null_bits & null_mask) && tabledef->maybe_null(i))) { + uint32 len= tabledef->calc_field_size(i, (uchar *) pack_ptr); + DBUG_DUMP("field_data", pack_ptr, len); + pack_ptr+= len; + } null_mask <<= 1; } } From d51cd894dac501d808da0c3bc08636f387014eb3 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Wed, 6 Oct 2010 18:03:27 -0600 Subject: [PATCH 017/151] Bug#57154 Rename THREADS.ID to THREADS.PROCESSLIST_ID in 5.5 This change is to align the 5.5 performance_schema.THREADS table definition with the 5.6 performance_schema.THREADS table, to facilitate the 5.5 -> 5.6 migration later. In the table performance_schema.THREADS: - renamed ID to PROCESSLIST_ID, removed not null - changed NAME from varchar(64) to varchar(128) to match the columns definitions from 5.6 Adjusted the test cases accordingly. Note: this fix is for 5.5 only, to null merge into 5.6 --- .../suite/perfschema/include/setup_helper.inc | 12 ++--- .../suite/perfschema/r/dml_threads.result | 6 +-- .../suite/perfschema/r/func_file_io.result | 17 +------ mysql-test/suite/perfschema/r/selects.result | 18 ++++---- .../suite/perfschema/t/dml_threads.test | 8 ++-- .../suite/perfschema/t/func_file_io.test | 46 +++++++++---------- mysql-test/suite/perfschema/t/selects.test | 16 +++---- .../suite/perfschema/t/thread_cache.test | 12 ++--- scripts/mysql_system_tables.sql | 4 +- storage/perfschema/table_threads.cc | 11 +++-- storage/perfschema/table_threads.h | 4 +- 11 files changed, 70 insertions(+), 84 deletions(-) diff --git a/mysql-test/suite/perfschema/include/setup_helper.inc b/mysql-test/suite/perfschema/include/setup_helper.inc index 1c8d4e412d5..195b9cf960a 100644 --- a/mysql-test/suite/perfschema/include/setup_helper.inc +++ b/mysql-test/suite/perfschema/include/setup_helper.inc @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Sun Microsystems, Inc +# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -10,8 +10,8 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# along with this program; if not, write to the Free Software Foundation, +# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA # Tests for PERFORMANCE_SCHEMA @@ -26,17 +26,17 @@ update performance_schema.SETUP_CONSUMERS set enabled='YES'; connect (con1, localhost, root, , ); let $con1_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID in (select connection_id())`; + where PROCESSLIST_ID = connection_id()`; connect (con2, localhost, root, , ); let $con2_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID in (select connection_id())`; + where PROCESSLIST_ID = connection_id()`; connect (con3, localhost, root, , ); let $con3_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID in (select connection_id())`; + where PROCESSLIST_ID = connection_id()`; connection default; diff --git a/mysql-test/suite/perfschema/r/dml_threads.result b/mysql-test/suite/perfschema/r/dml_threads.result index b4fa8705c95..261e7977aa5 100644 --- a/mysql-test/suite/perfschema/r/dml_threads.result +++ b/mysql-test/suite/perfschema/r/dml_threads.result @@ -1,12 +1,12 @@ select * from performance_schema.THREADS where name like 'Thread/%' limit 1; -THREAD_ID ID NAME +THREAD_ID PROCESSLIST_ID NAME # # # select * from performance_schema.THREADS where name='FOO'; -THREAD_ID ID NAME +THREAD_ID PROCESSLIST_ID NAME insert into performance_schema.THREADS -set name='FOO', thread_id=1, id=2; +set name='FOO', thread_id=1, processlist_id=2; ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'THREADS' update performance_schema.THREADS set thread_id=12; diff --git a/mysql-test/suite/perfschema/r/func_file_io.result b/mysql-test/suite/perfschema/r/func_file_io.result index 201254aca21..655ce1394f9 100644 --- a/mysql-test/suite/perfschema/r/func_file_io.result +++ b/mysql-test/suite/perfschema/r/func_file_io.result @@ -94,24 +94,9 @@ FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME WHERE COUNT_STAR > 0 ORDER BY SUM_TIMER_WAIT DESC LIMIT 10; -SELECT i.user, SUM(TIMER_WAIT) SUM_WAIT -# ((TIME_TO_SEC(TIMEDIFF(NOW(), i.startup_time)) * 1000) / SUM(TIMER_WAIT)) * 100 WAIT_PERCENTAGE -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h -INNER JOIN performance_schema.THREADS p USING (THREAD_ID) -LEFT JOIN information_schema.PROCESSLIST i USING (ID) -GROUP BY i.user -ORDER BY SUM_WAIT DESC -LIMIT 20; SELECT h.EVENT_NAME, SUM(h.TIMER_WAIT) TOTAL_WAIT FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h INNER JOIN performance_schema.THREADS p USING (THREAD_ID) -WHERE p.ID = 1 +WHERE p.PROCESSLIST_ID = 1 GROUP BY h.EVENT_NAME HAVING TOTAL_WAIT > 0; -SELECT i.user, h.operation, SUM(NUMBER_OF_BYTES) bytes -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h -INNER JOIN performance_schema.THREADS p USING (THREAD_ID) -LEFT JOIN information_schema.PROCESSLIST i USING (ID) -GROUP BY i.user, h.operation -HAVING BYTES > 0 -ORDER BY i.user, h.operation; diff --git a/mysql-test/suite/perfschema/r/selects.result b/mysql-test/suite/perfschema/r/selects.result index dfc9007c740..6d596ba8d9a 100644 --- a/mysql-test/suite/perfschema/r/selects.result +++ b/mysql-test/suite/perfschema/r/selects.result @@ -84,22 +84,22 @@ id c 13 [EVENT_ID] DROP TRIGGER t_ps_trigger; DROP PROCEDURE IF EXISTS t_ps_proc; -CREATE PROCEDURE t_ps_proc(IN tid INT, OUT pid INT) +CREATE PROCEDURE t_ps_proc(IN conid INT, OUT pid INT) BEGIN -SELECT id FROM performance_schema.THREADS -WHERE THREAD_ID = tid INTO pid; +SELECT thread_id FROM performance_schema.THREADS +WHERE PROCESSLIST_ID = conid INTO pid; END; | -CALL t_ps_proc(0, @p_id); +CALL t_ps_proc(connection_id(), @p_id); DROP FUNCTION IF EXISTS t_ps_proc; -CREATE FUNCTION t_ps_func(tid INT) RETURNS int +CREATE FUNCTION t_ps_func(conid INT) RETURNS int BEGIN -return (SELECT id FROM performance_schema.THREADS -WHERE THREAD_ID = tid); +return (SELECT thread_id FROM performance_schema.THREADS +WHERE PROCESSLIST_ID = conid); END; | -SELECT t_ps_func(0) = @p_id; -t_ps_func(0) = @p_id +SELECT t_ps_func(connection_id()) = @p_id; +t_ps_func(connection_id()) = @p_id 1 SELECT * FROM t_event; EVENT_ID diff --git a/mysql-test/suite/perfschema/t/dml_threads.test b/mysql-test/suite/perfschema/t/dml_threads.test index 6ea456fee69..b6a65b57733 100644 --- a/mysql-test/suite/perfschema/t/dml_threads.test +++ b/mysql-test/suite/perfschema/t/dml_threads.test @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Sun Microsystems, Inc +# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -10,8 +10,8 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# along with this program; if not, write to the Free Software Foundation, +# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA # Tests for PERFORMANCE_SCHEMA @@ -28,7 +28,7 @@ select * from performance_schema.THREADS --replace_result '\'threads' '\'THREADS' --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.THREADS - set name='FOO', thread_id=1, id=2; + set name='FOO', thread_id=1, processlist_id=2; --replace_result '\'threads' '\'THREADS' --error ER_TABLEACCESS_DENIED_ERROR diff --git a/mysql-test/suite/perfschema/t/func_file_io.test b/mysql-test/suite/perfschema/t/func_file_io.test index 6b6335ac424..dc9a7a09e40 100644 --- a/mysql-test/suite/perfschema/t/func_file_io.test +++ b/mysql-test/suite/perfschema/t/func_file_io.test @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2009 Sun Microsystems, Inc +# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -10,8 +10,8 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# along with this program; if not, write to the Free Software Foundation, +# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA ## ## WL#4814, 4.1.4 FILE IO @@ -154,16 +154,16 @@ LIMIT 10; # Total and average wait time for different users # ---disable_result_log -SELECT i.user, SUM(TIMER_WAIT) SUM_WAIT -# ((TIME_TO_SEC(TIMEDIFF(NOW(), i.startup_time)) * 1000) / SUM(TIMER_WAIT)) * 100 WAIT_PERCENTAGE -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h -INNER JOIN performance_schema.THREADS p USING (THREAD_ID) -LEFT JOIN information_schema.PROCESSLIST i USING (ID) -GROUP BY i.user -ORDER BY SUM_WAIT DESC -LIMIT 20; ---enable_result_log +## --disable_result_log +## SELECT i.user, SUM(TIMER_WAIT) SUM_WAIT +## # ((TIME_TO_SEC(TIMEDIFF(NOW(), i.startup_time)) * 1000) / SUM(TIMER_WAIT)) * 100 WAIT_PERCENTAGE +## FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h +## INNER JOIN performance_schema.THREADS p USING (THREAD_ID) +## LEFT JOIN information_schema.PROCESSLIST i USING (ID) +## GROUP BY i.user +## ORDER BY SUM_WAIT DESC +## LIMIT 20; +## --enable_result_log # # Total and average wait times for different events for a session @@ -172,7 +172,7 @@ LIMIT 20; SELECT h.EVENT_NAME, SUM(h.TIMER_WAIT) TOTAL_WAIT FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h INNER JOIN performance_schema.THREADS p USING (THREAD_ID) -WHERE p.ID = 1 +WHERE p.PROCESSLIST_ID = 1 GROUP BY h.EVENT_NAME HAVING TOTAL_WAIT > 0; --enable_result_log @@ -181,12 +181,12 @@ HAVING TOTAL_WAIT > 0; # Which user reads and writes data # ---disable_result_log -SELECT i.user, h.operation, SUM(NUMBER_OF_BYTES) bytes -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h -INNER JOIN performance_schema.THREADS p USING (THREAD_ID) -LEFT JOIN information_schema.PROCESSLIST i USING (ID) -GROUP BY i.user, h.operation -HAVING BYTES > 0 -ORDER BY i.user, h.operation; ---enable_result_log +## --disable_result_log +## SELECT i.user, h.operation, SUM(NUMBER_OF_BYTES) bytes +## FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h +## INNER JOIN performance_schema.THREADS p USING (THREAD_ID) +## LEFT JOIN information_schema.PROCESSLIST i USING (ID) +## GROUP BY i.user, h.operation +## HAVING BYTES > 0 +## ORDER BY i.user, h.operation; +## --enable_result_log diff --git a/mysql-test/suite/perfschema/t/selects.test b/mysql-test/suite/perfschema/t/selects.test index b673c896024..d0249fe654c 100644 --- a/mysql-test/suite/perfschema/t/selects.test +++ b/mysql-test/suite/perfschema/t/selects.test @@ -136,17 +136,17 @@ DROP PROCEDURE IF EXISTS t_ps_proc; --enable_warnings delimiter |; -CREATE PROCEDURE t_ps_proc(IN tid INT, OUT pid INT) +CREATE PROCEDURE t_ps_proc(IN conid INT, OUT pid INT) BEGIN - SELECT id FROM performance_schema.THREADS - WHERE THREAD_ID = tid INTO pid; + SELECT thread_id FROM performance_schema.THREADS + WHERE PROCESSLIST_ID = conid INTO pid; END; | delimiter ;| -CALL t_ps_proc(0, @p_id); +CALL t_ps_proc(connection_id(), @p_id); # FUNCTION @@ -155,17 +155,17 @@ DROP FUNCTION IF EXISTS t_ps_proc; --enable_warnings delimiter |; -CREATE FUNCTION t_ps_func(tid INT) RETURNS int +CREATE FUNCTION t_ps_func(conid INT) RETURNS int BEGIN - return (SELECT id FROM performance_schema.THREADS - WHERE THREAD_ID = tid); + return (SELECT thread_id FROM performance_schema.THREADS + WHERE PROCESSLIST_ID = conid); END; | delimiter ;| -SELECT t_ps_func(0) = @p_id; +SELECT t_ps_func(connection_id()) = @p_id; # We might reach this point too early which means the event scheduler has not # execute our "t_ps_event". Therefore we poll till the record was inserted diff --git a/mysql-test/suite/perfschema/t/thread_cache.test b/mysql-test/suite/perfschema/t/thread_cache.test index 5560f66babb..a59f568e8a2 100644 --- a/mysql-test/suite/perfschema/t/thread_cache.test +++ b/mysql-test/suite/perfschema/t/thread_cache.test @@ -31,14 +31,14 @@ connect (con1, localhost, root, , ); let $con1_ID=`select connection_id()`; let $con1_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID = connection_id()`; + where PROCESSLIST_ID = connection_id()`; connect (con2, localhost, root, , ); let $con2_ID=`select connection_id()`; let $con2_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID = connection_id()`; + where PROCESSLIST_ID = connection_id()`; connection default; @@ -59,7 +59,7 @@ connect (con3, localhost, root, , ); let $con3_ID=`select connection_id()`; let $con3_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID = connection_id()`; + where PROCESSLIST_ID = connection_id()`; disconnect con3; disconnect con1; @@ -83,14 +83,14 @@ connect (con1, localhost, root, , ); let $con1_ID=`select connection_id()`; let $con1_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID = connection_id()`; + where PROCESSLIST_ID = connection_id()`; connect (con2, localhost, root, , ); let $con2_ID=`select connection_id()`; let $con2_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID = connection_id()`; + where PROCESSLIST_ID = connection_id()`; connection default; @@ -109,7 +109,7 @@ connect (con3, localhost, root, , ); let $con3_ID=`select connection_id()`; let $con3_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID = connection_id()`; + where PROCESSLIST_ID = connection_id()`; disconnect con3; disconnect con1; diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index 977907c9c14..d5dd20542ff 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -467,8 +467,8 @@ DROP PREPARE stmt; SET @l1="CREATE TABLE performance_schema.THREADS("; SET @l2="THREAD_ID INTEGER not null,"; -SET @l3="ID INTEGER not null,"; -SET @l4="NAME VARCHAR(64) not null"; +SET @l3="PROCESSLIST_ID INTEGER,"; +SET @l4="NAME VARCHAR(128) not null"; SET @l5=")ENGINE=PERFORMANCE_SCHEMA;"; SET @cmd=concat(@l1,@l2,@l3,@l4,@l5); diff --git a/storage/perfschema/table_threads.cc b/storage/perfschema/table_threads.cc index bba7806cab9..d9aa600a21e 100644 --- a/storage/perfschema/table_threads.cc +++ b/storage/perfschema/table_threads.cc @@ -34,13 +34,13 @@ static const TABLE_FIELD_TYPE field_types[]= { NULL, 0} }, { - { C_STRING_WITH_LEN("ID") }, + { C_STRING_WITH_LEN("PROCESSLIST_ID") }, { C_STRING_WITH_LEN("int(11)") }, { NULL, 0} }, { { C_STRING_WITH_LEN("NAME") }, - { C_STRING_WITH_LEN("varchar(64)") }, + { C_STRING_WITH_LEN("varchar(128)") }, { NULL, 0} } }; @@ -140,7 +140,7 @@ void table_threads::make_row(PFS_thread *pfs) } int table_threads::read_row_values(TABLE *table, - unsigned char *, + unsigned char *buf, Field **fields, bool read_all) { @@ -150,7 +150,8 @@ int table_threads::read_row_values(TABLE *table, return HA_ERR_RECORD_DELETED; /* Set the null bits */ - DBUG_ASSERT(table->s->null_bytes == 0); + DBUG_ASSERT(table->s->null_bytes == 1); + buf[0]= 0; for (; (f= *fields) ; fields++) { @@ -161,7 +162,7 @@ int table_threads::read_row_values(TABLE *table, case 0: /* THREAD_ID */ set_field_ulong(f, m_row.m_thread_internal_id); break; - case 1: /* ID */ + case 1: /* PROCESSLIST_ID */ set_field_ulong(f, m_row.m_thread_id); break; case 2: /* NAME */ diff --git a/storage/perfschema/table_threads.h b/storage/perfschema/table_threads.h index 9df323f6d82..fb239007069 100644 --- a/storage/perfschema/table_threads.h +++ b/storage/perfschema/table_threads.h @@ -36,7 +36,7 @@ struct row_threads { /** Column THREAD_ID. */ ulong m_thread_internal_id; - /** Column ID. */ + /** Column PROCESSLIST_ID. */ ulong m_thread_id; /** Column NAME. */ const char *m_name; @@ -79,7 +79,7 @@ private: /** Current row. */ row_threads m_row; - /** True is the current row exists. */ + /** True if the current row exists. */ bool m_row_exists; /** Current position. */ PFS_simple_index m_pos; From 3c9c7efb3b9f505e3db5b2dc2fdef30893f7d5f0 Mon Sep 17 00:00:00 2001 From: Evgeny Potemkin Date: Thu, 7 Oct 2010 11:07:56 +0400 Subject: [PATCH 018/151] Bug#57039: constant subtime expression returns incorrect result. The subtime function wasn't able to produce correct int representation of its result. For constant expressions the Item_datetime_cache is used to speedup evaluation and Item_datetime_cache expects underlying item to return correct int representation of DATETIME value. These two factors combined led to a wrong query result. Now the Item_func_add_time has function val_datetime which performs the calculation and saves result into given MYSQL_TIME struct, it also sets null_value to appropriate value. val_int and val_str member functions convert the result obtained from val_datetime to int or string respectively and returns it. mysql-test/r/func_time.result: Added a test case for the bug#57039. mysql-test/t/func_time.test: Added a test case for the bug#57039. sql/item_timefunc.cc: Bug#57039: constant subtime expression returns incorrect result. Now the Item_func_add_time has function val_datetime which performs the calculation and saves result into given MYSQL_TIME struct, it also sets null_value to appropriate value. val_int and val_str member functions convert the result obtained from val_datetime to int or string respectively and returns it. sql/item_timefunc.h: Bug#57039: constant subtime expression returns incorrect result. --- mysql-test/r/func_time.result | 11 ++++++ mysql-test/t/func_time.test | 11 ++++++ sql/item_timefunc.cc | 70 +++++++++++++++++++++++++---------- sql/item_timefunc.h | 2 + 4 files changed, 74 insertions(+), 20 deletions(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index f2c26110d8a..f1b2196ebfa 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1316,3 +1316,14 @@ SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a); 1 DROP TABLE t1; End of 5.1 tests +# +# Bug#57039: constant subtime expression returns incorrect result. +# +CREATE TABLE t1 (`date_date` datetime NOT NULL); +INSERT INTO t1 VALUES ('2008-01-03 00:00:00'), ('2008-01-03 00:00:00'); +SELECT * FROM t1 WHERE date_date >= subtime(now(), "00:30:00"); +date_date +SELECT * FROM t1 WHERE date_date <= addtime(date_add("2000-1-1", INTERVAL "1:1:1" HOUR_SECOND), "00:20:00"); +date_date +DROP TABLE t1; +# diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 1f6001219a3..08c09adb093 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -833,3 +833,14 @@ SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a); DROP TABLE t1; --echo End of 5.1 tests + +--echo # +--echo # Bug#57039: constant subtime expression returns incorrect result. +--echo # +CREATE TABLE t1 (`date_date` datetime NOT NULL); +INSERT INTO t1 VALUES ('2008-01-03 00:00:00'), ('2008-01-03 00:00:00'); +SELECT * FROM t1 WHERE date_date >= subtime(now(), "00:30:00"); +SELECT * FROM t1 WHERE date_date <= addtime(date_add("2000-1-1", INTERVAL "1:1:1" HOUR_SECOND), "00:20:00"); +DROP TABLE t1; +--echo # + diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index cc363398fdd..e53558a3385 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2857,10 +2857,11 @@ void Item_func_add_time::fix_length_and_dec() Result: Time value or datetime value */ -String *Item_func_add_time::val_str(String *str) +MYSQL_TIME *Item_func_add_time::val_datetime(MYSQL_TIME *time, + date_time_format_types *format) { DBUG_ASSERT(fixed == 1); - MYSQL_TIME l_time1, l_time2, l_time3; + MYSQL_TIME l_time1, l_time2; bool is_time= 0; long days, microseconds; longlong seconds; @@ -2886,41 +2887,38 @@ String *Item_func_add_time::val_str(String *str) if (l_time1.neg != l_time2.neg) l_sign= -l_sign; - bzero((char *)&l_time3, sizeof(l_time3)); + bzero((char *)time, sizeof(MYSQL_TIME)); - l_time3.neg= calc_time_diff(&l_time1, &l_time2, -l_sign, - &seconds, µseconds); + time->neg= calc_time_diff(&l_time1, &l_time2, -l_sign, + &seconds, µseconds); /* If first argument was negative and diff between arguments is non-zero we need to swap sign to get proper result. */ if (l_time1.neg && (seconds || microseconds)) - l_time3.neg= 1-l_time3.neg; // Swap sign of result + time->neg= 1 - time->neg; // Swap sign of result - if (!is_time && l_time3.neg) + if (!is_time && time->neg) goto null_date; days= (long)(seconds/86400L); - calc_time_from_sec(&l_time3, (long)(seconds%86400L), microseconds); + calc_time_from_sec(time, (long)(seconds%86400L), microseconds); if (!is_time) { - get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day); - if (l_time3.day && - !make_datetime(l_time1.second_part || l_time2.second_part ? - DATE_TIME_MICROSECOND : DATE_TIME, - &l_time3, str)) - return str; + get_date_from_daynr(days, &time->year, &time->month, &time->day); + *format= l_time1.second_part || l_time2.second_part ? + DATE_TIME_MICROSECOND : DATE_TIME; + if (time->day) + return time; goto null_date; } - - l_time3.hour+= days*24; - if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ? - TIME_MICROSECOND : TIME_ONLY, - &l_time3, str)) - return str; + *format= l_time1.second_part || l_time2.second_part ? + TIME_MICROSECOND : TIME_ONLY; + time->hour+= days*24; + return time; null_date: null_value=1; @@ -2928,6 +2926,38 @@ null_date: } +String *Item_func_add_time::val_str(String *str) +{ + MYSQL_TIME ltime; + date_time_format_types format; + + val_datetime(<ime, &format); + + if (null_value) + return 0; + + if (!make_datetime_with_warn(format, <ime, str)) + return str; + + null_value= 1; + return 0; +} + + +longlong Item_func_add_time::val_int() +{ + MYSQL_TIME ltime; + date_time_format_types format; + + val_datetime(<ime, &format); + + if (null_value) + return 0; + + return TIME_to_ulonglong_datetime(<ime); +} + + void Item_func_add_time::print(String *str, enum_query_type query_type) { if (is_date) diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 6e31b5c6705..d82a8f9e969 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -949,6 +949,8 @@ public: return save_date_in_field(field); return Item_str_func::save_in_field(field, no_conversions); } + longlong val_int(); + MYSQL_TIME *val_datetime(MYSQL_TIME *time, date_time_format_types *format); }; class Item_func_timediff :public Item_str_timefunc From 30f57b33233baf08741aa91f9c0209b1e77689f9 Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Thu, 7 Oct 2010 10:13:11 +0200 Subject: [PATCH 019/151] Bug#56423: Different count with SELECT and CREATE SELECT queries This is a regression from the fix for bug no 38999. A storage engine capable of reading only a subset of a table's columns updates corresponding bits in the read buffer to signal that it has read NULL values for the corresponding columns. It cannot, and should not, update any other bits. Bug no 38999 occurred because the implementation of UPDATE statements compare the NULL bits using memcmp, inadvertently comparing bits that were never requested from the storage engine. The regression was caused by the storage engine trying to alleviate the situation by writing to all NULL bits, even those that it had no knowledge of. This has devastating effects for the index merge algorithm, which relies on all NULL bits, except those explicitly requested, being left unchanged. The fix reverts the fix for bug no 38999 in both InnoDB and InnoDB plugin and changes the server's method of comparing records. For engines that always read entire rows, we proceed as usual. For engines capable of reading only select columns, the record buffers are now compared on a column by column basis. An assertion was also added so that non comparable buffers are never read. Some relevant copy-pasted code was also consolidated in a new function. --- mysql-test/include/index_merge2.inc | 52 ++++++++++++++ mysql-test/r/index_merge_innodb.result | 55 +++++++++++++++ mysql-test/r/index_merge_myisam.result | 55 +++++++++++++++ sql/mysql_priv.h | 3 +- sql/sql_insert.cc | 4 +- sql/sql_update.cc | 93 +++++++++++++++++--------- storage/innobase/row/row0sel.c | 6 -- storage/innodb_plugin/row/row0sel.c | 6 -- 8 files changed, 227 insertions(+), 47 deletions(-) diff --git a/mysql-test/include/index_merge2.inc b/mysql-test/include/index_merge2.inc index d65115eac0f..d21562d000c 100644 --- a/mysql-test/include/index_merge2.inc +++ b/mysql-test/include/index_merge2.inc @@ -343,3 +343,55 @@ explain select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 4 select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 40); drop table t1; +--echo # +--echo # Bug#56423: Different count with SELECT and CREATE SELECT queries +--echo # + +CREATE TABLE t1 ( + a INT, + b INT, + c INT, + d INT, + PRIMARY KEY (a), + KEY (c), + KEY bd (b,d) +); + +INSERT INTO t1 VALUES +(1, 0, 1, 0), +(2, 1, 1, 1), +(3, 1, 1, 1), +(4, 0, 1, 1); + +EXPLAIN +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; + +CREATE TABLE t2 ( a INT ) +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; + +SELECT * FROM t2; + +DROP TABLE t1, t2; + +CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) ); +INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2); +SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2; + +DROP TABLE t1; + +--echo # Code coverage of fix. +CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT); +INSERT INTO t1 (b) VALUES (1); +UPDATE t1 SET b = 2 WHERE a = 1; +SELECT * FROM t1; + +CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) ); +INSERT INTO t2 (b) VALUES ('a'); +UPDATE t2 SET b = 'b' WHERE a = 1; +SELECT * FROM t2; + +DROP TABLE t1, t2; diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result index 58ed99b1e67..eaff7df280d 100644 --- a/mysql-test/r/index_merge_innodb.result +++ b/mysql-test/r/index_merge_innodb.result @@ -324,6 +324,61 @@ key1 key2 key3 38 38 38 39 39 39 drop table t1; +# +# Bug#56423: Different count with SELECT and CREATE SELECT queries +# +CREATE TABLE t1 ( +a INT, +b INT, +c INT, +d INT, +PRIMARY KEY (a), +KEY (c), +KEY bd (b,d) +); +INSERT INTO t1 VALUES +(1, 0, 1, 0), +(2, 1, 1, 1), +(3, 1, 1, 1), +(4, 0, 1, 1); +EXPLAIN +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge c,bd c,bd 5,10 NULL 1 Using intersect(c,bd); Using where; Using index +CREATE TABLE t2 ( a INT ) +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; +SELECT * FROM t2; +a +2 +3 +DROP TABLE t1, t2; +CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) ); +INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2); +SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2; +a b +1 2 +1 2 +1 2 +1 2 +DROP TABLE t1; +# Code coverage of fix. +CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT); +INSERT INTO t1 (b) VALUES (1); +UPDATE t1 SET b = 2 WHERE a = 1; +SELECT * FROM t1; +a b +1 2 +CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) ); +INSERT INTO t2 (b) VALUES ('a'); +UPDATE t2 SET b = 'b' WHERE a = 1; +SELECT * FROM t2; +a b +1 b +DROP TABLE t1, t2; #---------------- 2-sweeps read Index merge test 2 ------------------------------- SET SESSION STORAGE_ENGINE = InnoDB; drop table if exists t1; diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index 6bfec69fad9..1ebc94dff5d 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -1158,6 +1158,61 @@ key1 key2 key3 38 38 38 39 39 39 drop table t1; +# +# Bug#56423: Different count with SELECT and CREATE SELECT queries +# +CREATE TABLE t1 ( +a INT, +b INT, +c INT, +d INT, +PRIMARY KEY (a), +KEY (c), +KEY bd (b,d) +); +INSERT INTO t1 VALUES +(1, 0, 1, 0), +(2, 1, 1, 1), +(3, 1, 1, 1), +(4, 0, 1, 1); +EXPLAIN +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c,bd bd 10 const,const 2 Using where +CREATE TABLE t2 ( a INT ) +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; +SELECT * FROM t2; +a +2 +3 +DROP TABLE t1, t2; +CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) ); +INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2); +SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2; +a b +1 2 +1 2 +1 2 +1 2 +DROP TABLE t1; +# Code coverage of fix. +CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT); +INSERT INTO t1 (b) VALUES (1); +UPDATE t1 SET b = 2 WHERE a = 1; +SELECT * FROM t1; +a b +1 2 +CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) ); +INSERT INTO t2 (b) VALUES ('a'); +UPDATE t2 SET b = 'b' WHERE a = 1; +SELECT * FROM t2; +a b +1 b +DROP TABLE t1, t2; #---------------- 2-sweeps read Index merge test 2 ------------------------------- SET SESSION STORAGE_ENGINE = MyISAM; drop table if exists t1; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 9f2c0b04f2c..709a49b2036 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1047,7 +1047,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, char* packet, uint packet_length); void log_slow_statement(THD *thd); bool check_dup(const char *db, const char *name, TABLE_LIST *tables); -bool compare_record(TABLE *table); +bool records_are_comparable(const TABLE *table); +bool compare_records(const TABLE *table); bool append_file_to_dir(THD *thd, const char **filename_ptr, const char *table_name); void wait_while_table_is_used(THD *thd, TABLE *table, diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 567c7ff2b30..f0735a9e093 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1483,9 +1483,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) table->file->adjust_next_insert_id_after_explicit_value( table->next_number_field->val_int()); info->touched++; - if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ && - !bitmap_is_subset(table->write_set, table->read_set)) || - compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { if ((error=table->file->ha_update_row(table->record[1], table->record[0])) && diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 7da8a68546f..01c70a7a268 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -25,11 +25,68 @@ #include "sql_trigger.h" #include "debug_sync.h" -/* Return 0 if row hasn't changed */ -bool compare_record(TABLE *table) +/** + True if the table's input and output record buffers are comparable using + compare_records(TABLE*). + */ +bool records_are_comparable(const TABLE *table) { + return ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) == 0) || + bitmap_is_subset(table->write_set, table->read_set); +} + + +/** + Compares the input and outbut record buffers of the table to see if a row + has changed. The algorithm iterates over updated columns and if they are + nullable compares NULL bits in the buffer before comparing actual + data. Special care must be taken to compare only the relevant NULL bits and + mask out all others as they may be undefined. The storage engine will not + and should not touch them. + + @param table The table to evaluate. + + @return true if row has changed. + @return false otherwise. +*/ +bool compare_records(const TABLE *table) { + DBUG_ASSERT(records_are_comparable(table)); + + if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) != 0) + { + /* + Storage engine may not have read all columns of the record. Fields + (including NULL bits) not in the write_set may not have been read and + can therefore not be compared. + */ + for (Field **ptr= table->field ; *ptr != NULL; ptr++) + { + Field *field= *ptr; + if (bitmap_is_set(table->write_set, field->field_index)) + { + if (field->real_maybe_null()) + { + uchar null_byte_index= field->null_ptr - table->record[0]; + + if (((table->record[0][null_byte_index]) & field->null_bit) != + ((table->record[1][null_byte_index]) & field->null_bit)) + return TRUE; + } + if (field->cmp_binary_offset(table->s->rec_buff_length)) + return TRUE; + } + } + return FALSE; + } + + /* + The storage engine has read all columns, so it's safe to compare all bits + including those not in the write_set. This is cheaper than the field-by-field + comparison done above. + */ if (table->s->blob_fields + table->s->varchar_fields == 0) + // Fixed-size record: do bitwise comparison of the records return cmp_record(table,record[1]); /* Compare null bits */ if (memcmp(table->null_flags, @@ -186,7 +243,6 @@ int mysql_update(THD *thd, bool using_limit= limit != HA_POS_ERROR; bool safe_update= test(thd->options & OPTION_SAFE_UPDATES); bool used_key_is_modified, transactional_table, will_batch; - bool can_compare_record; int res; int error, loc_error; uint used_index= MAX_KEY, dup_key_found; @@ -575,15 +631,6 @@ int mysql_update(THD *thd, if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) table->prepare_for_position(); - /* - We can use compare_record() to optimize away updates if - the table handler is returning all columns OR if - if all updated columns are read - */ - can_compare_record= (!(table->file->ha_table_flags() & - HA_PARTIAL_COLUMN_READ) || - bitmap_is_subset(table->write_set, table->read_set)); - while (!(error=info.read_record(&info)) && !thd->killed) { thd->examined_row_count++; @@ -601,7 +648,7 @@ int mysql_update(THD *thd, found++; - if (!can_compare_record || compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { if ((res= table_list->view_check_option(thd, ignore)) != VIEW_CHECK_OK) @@ -1695,18 +1742,8 @@ bool multi_update::send_data(List ¬_used_values) if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED)) continue; - /* - We can use compare_record() to optimize away updates if - the table handler is returning all columns OR if - if all updated columns are read - */ if (table == table_to_update) { - bool can_compare_record; - can_compare_record= (!(table->file->ha_table_flags() & - HA_PARTIAL_COLUMN_READ) || - bitmap_is_subset(table->write_set, - table->read_set)); table->status|= STATUS_UPDATED; store_record(table,record[1]); if (fill_record_n_invoke_before_triggers(thd, *fields_for_table[offset], @@ -1721,7 +1758,7 @@ bool multi_update::send_data(List ¬_used_values) */ table->auto_increment_field_not_null= FALSE; found++; - if (!can_compare_record || compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { int error; if ((error= cur_table->view_check_option(thd, ignore)) != @@ -1908,7 +1945,6 @@ int multi_update::do_updates() DBUG_RETURN(0); for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local) { - bool can_compare_record; uint offset= cur_table->shared; table = cur_table->table; @@ -1945,11 +1981,6 @@ int multi_update::do_updates() if ((local_error = tmp_table->file->ha_rnd_init(1))) goto err; - can_compare_record= (!(table->file->ha_table_flags() & - HA_PARTIAL_COLUMN_READ) || - bitmap_is_subset(table->write_set, - table->read_set)); - for (;;) { if (thd->killed && trans_safe) @@ -1990,7 +2021,7 @@ int multi_update::do_updates() TRG_ACTION_BEFORE, TRUE)) goto err2; - if (!can_compare_record || compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { int error; if ((error= cur_table->view_check_option(thd, ignore)) != diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index a64dd3151ee..ecc5b47d377 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -2621,12 +2621,6 @@ row_sel_store_mysql_rec( prebuilt->blob_heap = NULL; } - /* init null bytes with default values as they might be - left uninitialized in some cases and this uninited bytes - might be copied into mysql record buffer that leads to - valgrind warnings */ - memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len); - for (i = 0; i < prebuilt->n_template; i++) { templ = prebuilt->mysql_template + i; diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c index 8b17bdc6ad3..b19651735d8 100644 --- a/storage/innodb_plugin/row/row0sel.c +++ b/storage/innodb_plugin/row/row0sel.c @@ -2696,12 +2696,6 @@ row_sel_store_mysql_rec( prebuilt->blob_heap = NULL; } - /* init null bytes with default values as they might be - left uninitialized in some cases and these uninited bytes - might be copied into mysql record buffer that leads to - valgrind warnings */ - memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len); - for (i = 0; i < prebuilt->n_template; i++) { templ = prebuilt->mysql_template + i; From 0093705b4d1d9472cf9a5cf3a320e2789eeeccca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Bl=C3=A5udd?= Date: Thu, 7 Oct 2010 11:02:16 +0200 Subject: [PATCH 020/151] WL#5503 SEAGULL: Move config/ac-macros/ha_ndbcluster.m4 to storage/ndb/ - Move file ha_ndbcluster.m4 - Move "sinclude" directive from configure.in to storag/ndb/plug.in --- configure.in | 1 - .../ac-macros/ha_ndbcluster.m4 => storage/ndb/ndb_configure.m4 | 0 storage/ndb/plug.in | 2 ++ 3 files changed, 2 insertions(+), 1 deletion(-) rename config/ac-macros/ha_ndbcluster.m4 => storage/ndb/ndb_configure.m4 (100%) diff --git a/configure.in b/configure.in index a5fe8d292da..c272efe9214 100644 --- a/configure.in +++ b/configure.in @@ -87,7 +87,6 @@ sinclude(config/ac-macros/character_sets.m4) sinclude(config/ac-macros/compiler_flag.m4) sinclude(config/ac-macros/plugins.m4) sinclude(config/ac-macros/dtrace.m4) -sinclude(config/ac-macros/ha_ndbcluster.m4) sinclude(config/ac-macros/large_file.m4) sinclude(config/ac-macros/misc.m4) sinclude(config/ac-macros/readline.m4) diff --git a/config/ac-macros/ha_ndbcluster.m4 b/storage/ndb/ndb_configure.m4 similarity index 100% rename from config/ac-macros/ha_ndbcluster.m4 rename to storage/ndb/ndb_configure.m4 diff --git a/storage/ndb/plug.in b/storage/ndb/plug.in index a7e351417b1..d3395b66771 100644 --- a/storage/ndb/plug.in +++ b/storage/ndb/plug.in @@ -1,3 +1,5 @@ +sinclude(storage/ndb/ndb_configure.m4) + MYSQL_STORAGE_ENGINE(ndbcluster, ndbcluster, [Cluster Storage Engine], [High Availability Clustered tables], [max]) MYSQL_PLUGIN_DIRECTORY(ndbcluster,[storage/ndb]) From 9c7bd5146ed5315a44eea167fe86487357074fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Bl=C3=A5udd?= Date: Thu, 7 Oct 2010 11:13:30 +0200 Subject: [PATCH 021/151] Bug#56397 The version of NDB in MySQL Server should be constant - Fix the version of NDB in MySQL Server to 5.5.7(although it's actually 6.2.18) --- storage/ndb/ndb_configure.m4 | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/storage/ndb/ndb_configure.m4 b/storage/ndb/ndb_configure.m4 index 533dba09feb..21e4627515f 100644 --- a/storage/ndb/ndb_configure.m4 +++ b/storage/ndb/ndb_configure.m4 @@ -2,10 +2,16 @@ dnl --------------------------------------------------------------------------- dnl Macro: MYSQL_CHECK_NDBCLUSTER dnl --------------------------------------------------------------------------- -NDB_VERSION_MAJOR=`echo $MYSQL_NUMERIC_VERSION | cut -d. -f1` -NDB_VERSION_MINOR=`echo $MYSQL_NUMERIC_VERSION | cut -d. -f2` -NDB_VERSION_BUILD=`echo $MYSQL_NUMERIC_VERSION | cut -d. -f3` -NDB_VERSION_STATUS=`echo $VERSION | sed 's/^[[-.0-9]]*//'` +# The version of NDB in this version of MySQL is currently fixed +# and not supposed to be changed unless major changes happen in +# storage/ndb directory. +# NOTE! To avoid mixup with MySQL Cluster's version numbers +# this version of NDB is set to 5.5.7 although it's basically +# a copy of MySQL Cluster 6.2.18 +NDB_VERSION_MAJOR=5 +NDB_VERSION_MINOR=5 +NDB_VERSION_BUILD=7 +NDB_VERSION_STATUS="" TEST_NDBCLUSTER="" dnl for build ndb docs From 95f8d9a2a4fdb84c652ec46857948b19eac9f274 Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Thu, 7 Oct 2010 12:01:51 +0200 Subject: [PATCH 022/151] Bug#56423: Different count with SELECT and CREATE SELECT queries This is the 5.5 version of the fix. The 5.1 version was too complicated to merge and was null merged. This is a regression from the fix for bug no 38999. A storage engine capable of reading only a subset of a table's columns updates corresponding bits in the read buffer to signal that it has read NULL values for the corresponding columns. It cannot, and should not, update any other bits. Bug no 38999 occurred because the implementation of UPDATE statements compare the NULL bits using memcmp, inadvertently comparing bits that were never requested from the storage engine. The regression was caused by the storage engine trying to alleviate the situation by writing to all NULL bits, even those that it had no knowledge of. This has devastating effects for the index merge algorithm, which relies on all NULL bits, except those explicitly requested, being left unchanged. The fix reverts the fix for bug no 38999 in both InnoDB and InnoDB plugin and changes the server's method of comparing records. For engines that always read entire rows, we proceed as usual. For engines capable of reading only select columns, the record buffers are now compared on a column by column basis. An assertion was also added so that non comparable buffers are never read. Some relevant copy-pasted code was also consolidated in a new function. --- mysql-test/include/index_merge2.inc | 112 +++++++++++++++++++++++++ mysql-test/r/index_merge_myisam.result | 55 ++++++++++++ sql/sql_insert.cc | 4 +- sql/sql_update.cc | 93 +++++++++++++------- sql/sql_update.h | 3 +- storage/innobase/row/row0sel.c | 6 -- 6 files changed, 232 insertions(+), 41 deletions(-) diff --git a/mysql-test/include/index_merge2.inc b/mysql-test/include/index_merge2.inc index 9b98eb3ebf2..23c8c6466c7 100644 --- a/mysql-test/include/index_merge2.inc +++ b/mysql-test/include/index_merge2.inc @@ -351,3 +351,115 @@ explain select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 4 select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 40); drop table t1; +--echo # +--echo # Bug#56423: Different count with SELECT and CREATE SELECT queries +--echo # + +CREATE TABLE t1 ( + a INT, + b INT, + c INT, + d INT, + PRIMARY KEY (a), + KEY (c), + KEY bd (b,d) +); + +INSERT INTO t1 VALUES +(1, 0, 1, 0), +(2, 1, 1, 1), +(3, 1, 1, 1), +(4, 0, 1, 1); + +EXPLAIN +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; + +CREATE TABLE t2 ( a INT ) +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; + +SELECT * FROM t2; + +DROP TABLE t1, t2; + +CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) ); +INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2); +SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2; + +DROP TABLE t1; + +--echo # Code coverage of fix. +CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT); +INSERT INTO t1 (b) VALUES (1); +UPDATE t1 SET b = 2 WHERE a = 1; +SELECT * FROM t1; + +CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) ); +INSERT INTO t2 (b) VALUES ('a'); +UPDATE t2 SET b = 'b' WHERE a = 1; +SELECT * FROM t2; + +DROP TABLE t1, t2; + +# The test was inactive for InnoDB at the time of pushing. The following is +# expected result for the Bug#56423 test. It can be uncommented and pasted +# into result file when reactivating the test. + +## +## Bug#56423: Different count with SELECT and CREATE SELECT queries +## +#CREATE TABLE t1 ( +#a INT, +#b INT, +#c INT, +#d INT, +#PRIMARY KEY (a), +#KEY (c), +#KEY bd (b,d) +#); +#INSERT INTO t1 VALUES +#(1, 0, 1, 0), +#(2, 1, 1, 1), +#(3, 1, 1, 1), +#(4, 0, 1, 1); +#EXPLAIN +#SELECT a +#FROM t1 +#WHERE c = 1 AND b = 1 AND d = 1; +#id select_type table type possible_keys key key_len ref rows Extra +#1 SIMPLE t1 ref c,bd bd 10 const,const 2 Using where +#CREATE TABLE t2 ( a INT ) +#SELECT a +#FROM t1 +#WHERE c = 1 AND b = 1 AND d = 1; +#SELECT * FROM t2; +#a +#2 +#3 +#DROP TABLE t1, t2; +#CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) ); +#INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2); +#SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2; +#a b +#1 2 +#1 2 +#1 2 +#1 2 +#DROP TABLE t1; +## Code coverage of fix. +#CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT); +#INSERT INTO t1 (b) VALUES (1); +#UPDATE t1 SET b = 2 WHERE a = 1; +#SELECT * FROM t1; +#a b +#1 2 +#CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) ); +#INSERT INTO t2 (b) VALUES ('a'); +#UPDATE t2 SET b = 'b' WHERE a = 1; +#SELECT * FROM t2; +#a b +#1 b +#DROP TABLE t1, t2; diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index 7377b450872..cfe0c841c0c 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -1156,6 +1156,61 @@ key1 key2 key3 38 38 38 39 39 39 drop table t1; +# +# Bug#56423: Different count with SELECT and CREATE SELECT queries +# +CREATE TABLE t1 ( +a INT, +b INT, +c INT, +d INT, +PRIMARY KEY (a), +KEY (c), +KEY bd (b,d) +); +INSERT INTO t1 VALUES +(1, 0, 1, 0), +(2, 1, 1, 1), +(3, 1, 1, 1), +(4, 0, 1, 1); +EXPLAIN +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c,bd bd 10 const,const 2 Using where +CREATE TABLE t2 ( a INT ) +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; +SELECT * FROM t2; +a +2 +3 +DROP TABLE t1, t2; +CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) ); +INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2); +SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2; +a b +1 2 +1 2 +1 2 +1 2 +DROP TABLE t1; +# Code coverage of fix. +CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT); +INSERT INTO t1 (b) VALUES (1); +UPDATE t1 SET b = 2 WHERE a = 1; +SELECT * FROM t1; +a b +1 2 +CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) ); +INSERT INTO t2 (b) VALUES ('a'); +UPDATE t2 SET b = 'b' WHERE a = 1; +SELECT * FROM t2; +a b +1 b +DROP TABLE t1, t2; #---------------- 2-sweeps read Index merge test 2 ------------------------------- SET SESSION STORAGE_ENGINE = MyISAM; drop table if exists t1; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 3ac6cf28c90..1f8da3fab5c 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1620,9 +1620,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) table->file->adjust_next_insert_id_after_explicit_value( table->next_number_field->val_int()); info->touched++; - if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ && - !bitmap_is_subset(table->write_set, table->read_set)) || - compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { if ((error=table->file->ha_update_row(table->record[1], table->record[0])) && diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 68440f6623a..96b1ac67b49 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -42,11 +42,68 @@ // mysql_handle_derived, // mysql_derived_filling -/* Return 0 if row hasn't changed */ -bool compare_record(TABLE *table) +/** + True if the table's input and output record buffers are comparable using + compare_records(TABLE*). + */ +bool records_are_comparable(const TABLE *table) { + return ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) == 0) || + bitmap_is_subset(table->write_set, table->read_set); +} + + +/** + Compares the input and outbut record buffers of the table to see if a row + has changed. The algorithm iterates over updated columns and if they are + nullable compares NULL bits in the buffer before comparing actual + data. Special care must be taken to compare only the relevant NULL bits and + mask out all others as they may be undefined. The storage engine will not + and should not touch them. + + @param table The table to evaluate. + + @return true if row has changed. + @return false otherwise. +*/ +bool compare_records(const TABLE *table) { + DBUG_ASSERT(records_are_comparable(table)); + + if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) != 0) + { + /* + Storage engine may not have read all columns of the record. Fields + (including NULL bits) not in the write_set may not have been read and + can therefore not be compared. + */ + for (Field **ptr= table->field ; *ptr != NULL; ptr++) + { + Field *field= *ptr; + if (bitmap_is_set(table->write_set, field->field_index)) + { + if (field->real_maybe_null()) + { + uchar null_byte_index= field->null_ptr - table->record[0]; + + if (((table->record[0][null_byte_index]) & field->null_bit) != + ((table->record[1][null_byte_index]) & field->null_bit)) + return TRUE; + } + if (field->cmp_binary_offset(table->s->rec_buff_length)) + return TRUE; + } + } + return FALSE; + } + + /* + The storage engine has read all columns, so it's safe to compare all bits + including those not in the write_set. This is cheaper than the field-by-field + comparison done above. + */ if (table->s->blob_fields + table->s->varchar_fields == 0) + // Fixed-size record: do bitwise comparison of the records return cmp_record(table,record[1]); /* Compare null bits */ if (memcmp(table->null_flags, @@ -204,7 +261,6 @@ int mysql_update(THD *thd, bool using_limit= limit != HA_POS_ERROR; bool safe_update= test(thd->variables.option_bits & OPTION_SAFE_UPDATES); bool used_key_is_modified= FALSE, transactional_table, will_batch; - bool can_compare_record; int res; int error, loc_error; uint used_index, dup_key_found; @@ -579,15 +635,6 @@ int mysql_update(THD *thd, if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) table->prepare_for_position(); - /* - We can use compare_record() to optimize away updates if - the table handler is returning all columns OR if - if all updated columns are read - */ - can_compare_record= (!(table->file->ha_table_flags() & - HA_PARTIAL_COLUMN_READ) || - bitmap_is_subset(table->write_set, table->read_set)); - while (!(error=info.read_record(&info)) && !thd->killed) { thd->examined_row_count++; @@ -605,7 +652,7 @@ int mysql_update(THD *thd, found++; - if (!can_compare_record || compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { if ((res= table_list->view_check_option(thd, ignore)) != VIEW_CHECK_OK) @@ -1645,18 +1692,8 @@ bool multi_update::send_data(List ¬_used_values) if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED)) continue; - /* - We can use compare_record() to optimize away updates if - the table handler is returning all columns OR if - if all updated columns are read - */ if (table == table_to_update) { - bool can_compare_record; - can_compare_record= (!(table->file->ha_table_flags() & - HA_PARTIAL_COLUMN_READ) || - bitmap_is_subset(table->write_set, - table->read_set)); table->status|= STATUS_UPDATED; store_record(table,record[1]); if (fill_record_n_invoke_before_triggers(thd, *fields_for_table[offset], @@ -1671,7 +1708,7 @@ bool multi_update::send_data(List ¬_used_values) */ table->auto_increment_field_not_null= FALSE; found++; - if (!can_compare_record || compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { int error; if ((error= cur_table->view_check_option(thd, ignore)) != @@ -1860,7 +1897,6 @@ int multi_update::do_updates() DBUG_RETURN(0); for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local) { - bool can_compare_record; uint offset= cur_table->shared; table = cur_table->table; @@ -1897,11 +1933,6 @@ int multi_update::do_updates() if ((local_error = tmp_table->file->ha_rnd_init(1))) goto err; - can_compare_record= (!(table->file->ha_table_flags() & - HA_PARTIAL_COLUMN_READ) || - bitmap_is_subset(table->write_set, - table->read_set)); - for (;;) { if (thd->killed && trans_safe) @@ -1942,7 +1973,7 @@ int multi_update::do_updates() TRG_ACTION_BEFORE, TRUE)) goto err2; - if (!can_compare_record || compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { int error; if ((error= cur_table->view_check_option(thd, ignore)) != diff --git a/sql/sql_update.h b/sql/sql_update.h index 6bf022a171c..50ff50f025d 100644 --- a/sql/sql_update.h +++ b/sql/sql_update.h @@ -38,6 +38,7 @@ bool mysql_multi_update(THD *thd, TABLE_LIST *table_list, enum enum_duplicates handle_duplicates, bool ignore, SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex, multi_update **result); -bool compare_record(TABLE *table); +bool records_are_comparable(const TABLE *table); +bool compare_records(const TABLE *table); #endif /* SQL_UPDATE_INCLUDED */ diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index 61ef4edb7a6..0bbca7c2147 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -2688,12 +2688,6 @@ row_sel_store_mysql_rec( prebuilt->blob_heap = NULL; } - /* init null bytes with default values as they might be - left uninitialized in some cases and these uninited bytes - might be copied into mysql record buffer that leads to - valgrind warnings */ - memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len); - for (i = 0; i < prebuilt->n_template; i++) { templ = prebuilt->mysql_template + i; From 11f68c01e693b0b4b75d5e1dbda53efbbb9b433d Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Thu, 7 Oct 2010 06:00:22 -0500 Subject: [PATCH 023/151] bug#56318: adjust the result files. --- mysql-test/suite/innodb/r/innodb-index.result | 6 +++--- mysql-test/suite/innodb/r/innodb-zip.result | 4 ++-- mysql-test/suite/innodb/r/innodb_bug52745.result | 4 ++-- mysql-test/suite/innodb/r/innodb_bug53591.result | 4 ++-- mysql-test/suite/innodb/r/innodb_file_format.result | 8 ++++---- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result index 1aeca2c226a..e43f70a2365 100644 --- a/mysql-test/suite/innodb/r/innodb-index.result +++ b/mysql-test/suite/innodb/r/innodb-index.result @@ -918,9 +918,9 @@ ERROR HY000: Too big row alter table t1 row_format=compact; create index t1u on t1 (u(1)); drop table t1; -set global innodb_file_per_table=1; -set global innodb_file_format=Barracuda; -set global innodb_file_format_max=Barracuda; +set global innodb_file_per_table=0; +set global innodb_file_format=Antelope; +set global innodb_file_format_max=Antelope; SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; CREATE TABLE t1( diff --git a/mysql-test/suite/innodb/r/innodb-zip.result b/mysql-test/suite/innodb/r/innodb-zip.result index da2be2bb07d..18fdb63d889 100644 --- a/mysql-test/suite/innodb/r/innodb-zip.result +++ b/mysql-test/suite/innodb/r/innodb-zip.result @@ -394,8 +394,8 @@ table_schema table_name row_format test t8 Compact test t9 Redundant drop table t8, t9; -set global innodb_file_per_table=1; -set global innodb_file_format=Barracuda; +set global innodb_file_per_table=0; +set global innodb_file_format=Antelope; set global innodb_file_per_table=on; set global innodb_file_format=`Barracuda`; set global innodb_file_format_max=`Antelope`; diff --git a/mysql-test/suite/innodb/r/innodb_bug52745.result b/mysql-test/suite/innodb/r/innodb_bug52745.result index 16dd356997e..d746fb427b5 100644 --- a/mysql-test/suite/innodb/r/innodb_bug52745.result +++ b/mysql-test/suite/innodb/r/innodb_bug52745.result @@ -125,6 +125,6 @@ Warning 1264 Out of range value for column 'col78' at row 1 Warning 1265 Data truncated for column 'col79' at row 1 Warning 1264 Out of range value for column 'col84' at row 1 DROP TABLE bug52745; -SET GLOBAL innodb_file_format=Barracuda; +SET GLOBAL innodb_file_format=Antelope; SET GLOBAL innodb_file_format_max=Antelope; -SET GLOBAL innodb_file_per_table=1; +SET GLOBAL innodb_file_per_table=0; diff --git a/mysql-test/suite/innodb/r/innodb_bug53591.result b/mysql-test/suite/innodb/r/innodb_bug53591.result index 8573fb60718..d3f8dfeafc2 100644 --- a/mysql-test/suite/innodb/r/innodb_bug53591.result +++ b/mysql-test/suite/innodb/r/innodb_bug53591.result @@ -11,6 +11,6 @@ Error 139 Too big row Error 1118 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 Error 1030 Got error 139 from storage engine DROP TABLE bug53591; -SET GLOBAL innodb_file_format=Barracuda; +SET GLOBAL innodb_file_format=Antelope; SET GLOBAL innodb_file_format_max=Antelope; -SET GLOBAL innodb_file_per_table=1; +SET GLOBAL innodb_file_per_table=0; diff --git a/mysql-test/suite/innodb/r/innodb_file_format.result b/mysql-test/suite/innodb/r/innodb_file_format.result index 447e13f0d60..70cfc9e4f47 100644 --- a/mysql-test/suite/innodb/r/innodb_file_format.result +++ b/mysql-test/suite/innodb/r/innodb_file_format.result @@ -1,6 +1,6 @@ select @@innodb_file_format; @@innodb_file_format -Barracuda +Antelope select @@innodb_file_format_check; @@innodb_file_format_check 1 @@ -17,14 +17,14 @@ Barracuda set global innodb_file_format=default; select @@innodb_file_format; @@innodb_file_format -Barracuda +Antelope set global innodb_file_format=on; ERROR 42000: Variable 'innodb_file_format' can't be set to the value of 'ON' set global innodb_file_format=off; ERROR 42000: Variable 'innodb_file_format' can't be set to the value of 'off' select @@innodb_file_format; @@innodb_file_format -Barracuda +Antelope set global innodb_file_format_max=antelope; set global innodb_file_format_max=barracuda; set global innodb_file_format_max=cheetah; @@ -46,5 +46,5 @@ Antelope set global innodb_file_format_max=antelope; set global innodb_file_format_check=off; ERROR HY000: Variable 'innodb_file_format_check' is a read only variable -SET GLOBAL innodb_file_format=Barracuda; +SET GLOBAL innodb_file_format=Antelope; SET GLOBAL innodb_file_format_max=Antelope; From 60d558d89d35664faf48ddc3eb4c95d0c39014f7 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Thu, 7 Oct 2010 18:57:12 +0700 Subject: [PATCH 024/151] Fixed bug#45445 - cannot execute procedures with thread_stack set to 128k. mysql-test/collections/default.experimental: Re-enabled test rpl.rpl_row_sp011*. sql/sp_head.cc: sp_head::execute() modified: pass constant value 2 * STACK_MIN_SIZE instead of 8 * STACK_MIN_SIZE as a second argument value in call to check_stack_overrun. --- mysql-test/collections/default.experimental | 1 - sql/sp_head.cc | 23 +++++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index b292356f1c7..47b2c215ac1 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -29,7 +29,6 @@ rpl.rpl_heartbeat_2slaves # BUG#43828 2009-10-22 luis fails spora rpl.rpl_innodb_bug28430* # Bug#46029 rpl.rpl_innodb_bug30888* @solaris # Bug#47646 2009-09-25 alik rpl.rpl_innodb_bug30888 fails sporadically on Solaris rpl.rpl_killed_ddl @windows # Bug#47638 2010-01-20 alik The rpl_killed_ddl test fails on Windows -rpl.rpl_row_sp011* @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun sys_vars.max_sp_recursion_depth_func @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun sys_vars.slow_query_log_func @solaris # Bug#54819 2010-06-26 alik sys_vars.slow_query_log_func fails sporadically on Solaris 10 diff --git a/sql/sp_head.cc b/sql/sp_head.cc index a95bbe094c0..e25b10957ac 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1213,8 +1213,27 @@ sp_head::execute(THD *thd) Object_creation_ctx *saved_creation_ctx; Warning_info *saved_warning_info, warning_info(thd->warning_info->warn_id()); - /* Use some extra margin for possible SP recursion and functions */ - if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet)) + /* + Just reporting a stack overrun error + (@sa check_stack_overrun()) requires stack memory for error + message buffer. Thus, we have to put the below check + relatively close to the beginning of the execution stack, + where available stack margin is still big. As long as the check + has to be fairly high up the call stack, the amount of memory + we "book" for has to stay fairly high as well, and hence + not very accurate. The number below has been calculated + by trial and error, and reflects the amount of memory necessary + to execute a single stored procedure instruction, be it either + an SQL statement, or, heaviest of all, a CALL, which involves + parsing and loading of another stored procedure into the cache + (@sa db_load_routine() and Bug#10100). + At the time of measuring, a recursive SP invocation required + 3232 bytes of stack on 32 bit Linux and 6016 bytes on 64 bit Mac. + The same with db_load_routine() required circa 7k bytes and + 14k bytes accordingly. Hence, here we book the stack with some + reasonable margin. + */ + if (check_stack_overrun(thd, 2 * STACK_MIN_SIZE, (uchar*)&old_packet)) DBUG_RETURN(TRUE); /* init per-instruction memroot */ From ec830356d78a8ca99a6397e95f3cf70493556257 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 7 Oct 2010 17:28:17 +0300 Subject: [PATCH 025/151] bumped the version to 5.1.53 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index c1672557bd1..7680a60226a 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.52], [], [mysql]) +AC_INIT([MySQL Server], [5.1.53], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 06e921818af65572b30b8521140e967a48dca62d Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 7 Oct 2010 16:38:23 +0100 Subject: [PATCH 026/151] BUG#54144: ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE is hard coded The error message for ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE was hard coded. Additionally, the same error was used in three separate error symptoms: 1. when heartbeat period exceeds the value of slave_net_timeout, 2. when it is smaller than 1 milisecond and 3. when it was not in range, ie, either negative or greater than the maximum allowed. We fix this by splitting into three distinct errors and by removing the message from the source code and moving it to the errmsg-utf8.txt file. --- mysql-test/suite/rpl/r/rpl_heartbeat.result | 10 +++--- .../suite/rpl/r/rpl_heartbeat_basic.result | 14 ++++----- sql/share/errmsg-utf8.txt | 9 +++++- sql/sql_yacc.yy | 31 +++++++------------ sql/sys_vars.cc | 7 ++--- 5 files changed, 34 insertions(+), 37 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_heartbeat.result b/mysql-test/suite/rpl/r/rpl_heartbeat.result index 05d37dc7d04..99e873be90c 100644 --- a/mysql-test/suite/rpl/r/rpl_heartbeat.result +++ b/mysql-test/suite/rpl/r/rpl_heartbeat.result @@ -6,19 +6,19 @@ show status like 'Slave_heartbeat_period';; Variable_name Slave_heartbeat_period Value 5.000 change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root', master_heartbeat_period= 4294968; -ERROR HY000: The requested value for the heartbeat period is negative or exceeds the maximum 4294967 seconds +ERROR HY000: The requested value for the heartbeat period is either negative or exceeds the maximum allowed (4294967 seconds). show status like 'Slave_heartbeat_period';; Variable_name Slave_heartbeat_period Value 5.000 change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root', master_heartbeat_period= 0.0009999; Warnings: -Warning 1624 The requested value for the heartbeat period is less than 1 msec. The period is reset to zero which means no heartbeats will be sending +Warning 1701 The requested value for the heartbeat period is less than 1 millisecond. The value is reset to 0, meaning that heartbeating will effectively be disabled. show status like 'Slave_heartbeat_period';; Variable_name Slave_heartbeat_period Value 0.000 change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root', master_heartbeat_period= 4294967; Warnings: -Warning 1624 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' sec. A sensible value for the period should be less than the timeout. +Warning 1702 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout. show status like 'Slave_heartbeat_period';; Variable_name Slave_heartbeat_period Value 4294967.000 @@ -30,7 +30,7 @@ reset slave; set @@global.slave_net_timeout= 5; change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root', master_heartbeat_period= 5.001; Warnings: -Warning 1624 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' sec. A sensible value for the period should be less than the timeout. +Warning 1702 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout. show status like 'Slave_heartbeat_period';; Variable_name Slave_heartbeat_period Value 5.001 @@ -42,7 +42,7 @@ Variable_name Slave_heartbeat_period Value 4.000 set @@global.slave_net_timeout= 3 /* must be a warning */; Warnings: -Warning 1624 The current value for master_heartbeat_period exceeds the new value of `slave_net_timeout' sec. A sensible value for the period should be less than the timeout. +Warning 1702 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout. reset slave; drop table if exists t1; set @@global.slave_net_timeout= 10; diff --git a/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result b/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result index b54602663d8..a78b84e209d 100644 --- a/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result +++ b/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result @@ -38,14 +38,14 @@ RESET SLAVE; *** Warning if updated slave_net_timeout < slave_heartbeat_timeout *** SET @@global.slave_net_timeout=FLOOR(SLAVE_HEARTBEAT_TIMEOUT)-1; Warnings: -Warning 1624 The current value for master_heartbeat_period exceeds the new value of `slave_net_timeout' sec. A sensible value for the period should be less than the timeout. +Warning 1702 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout. SET @@global.slave_net_timeout=@restore_slave_net_timeout; RESET SLAVE; *** Warning if updated slave_heartbeat_timeout > slave_net_timeout *** CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=SLAVE_NET_TIMEOUT; Warnings: -Warning 1624 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' sec. A sensible value for the period should be less than the timeout. +Warning 1702 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout. RESET SLAVE; *** CHANGE MASTER statement only updates slave_heartbeat_period *** @@ -140,7 +140,7 @@ Slave_heartbeat_period 0.001 RESET SLAVE; CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.0009; Warnings: -Warning 1624 The requested value for the heartbeat period is less than 1 msec. The period is reset to zero which means no heartbeats will be sending +Warning 1701 The requested value for the heartbeat period is less than 1 millisecond. The period is reset to 0, meaning that heartbeating will effectively be disabled. SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; Variable_name Value Slave_heartbeat_period 0.000 @@ -149,19 +149,19 @@ RESET SLAVE; *** Max slave_heartbeat_timeout *** CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=4294967; Warnings: -Warning 1624 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' sec. A sensible value for the period should be less than the timeout. +Warning 1702 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout. SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; Variable_name Value Slave_heartbeat_period 4294967.000 RESET SLAVE; CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=4294968; -ERROR HY000: The requested value for the heartbeat period is negative or exceeds the maximum 4294967 seconds +ERROR HY000: The requested value for the heartbeat period is either negative or exceeds the maximum allowed (4294967 seconds). RESET SLAVE; CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=8589935; -ERROR HY000: The requested value for the heartbeat period is negative or exceeds the maximum 4294967 seconds +ERROR HY000: The requested value for the heartbeat period is either negative or exceeds the maximum allowed (4294967 seconds). RESET SLAVE; CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=4294967296; -ERROR HY000: The requested value for the heartbeat period is negative or exceeds the maximum 4294967 seconds +ERROR HY000: The requested value for the heartbeat period is either negative or exceeds the maximum allowed (4294967 seconds). RESET SLAVE; *** Misc incorrect values *** diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 07f5589135d..c0ce32e68d8 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6152,7 +6152,7 @@ ER_WARN_ENGINE_TRANSACTION_ROLLBACK ER_SLAVE_HEARTBEAT_FAILURE eng "Unexpected master's heartbeat data: %s" ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE - eng "The requested value for the heartbeat period %s %s" + eng "The requested value for the heartbeat period is either negative or exceeds the maximum allowed (%s seconds)." ER_NDB_REPLICATION_SCHEMA_ERROR eng "Bad schema for mysql.ndb_replication table. Message: %-.64s" @@ -6379,3 +6379,10 @@ ER_SET_PASSWORD_AUTH_PLUGIN ER_GRANT_PLUGIN_USER_EXISTS eng "GRANT with IDENTIFIED WITH is illegal because the user %-.*s already exists" + +ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN + eng "The requested value for the heartbeat period is less than 1 millisecond. The value is reset to 0, meaning that heartbeating will effectively be disabled." + +ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX + eng "The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout." + diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 7c24f18aa6a..dc482caa29c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1933,35 +1933,28 @@ master_def: | MASTER_HEARTBEAT_PERIOD_SYM EQ NUM_literal { Lex->mi.heartbeat_period= (float) $3->val_real(); - if (Lex->mi.heartbeat_period > SLAVE_MAX_HEARTBEAT_PERIOD || - Lex->mi.heartbeat_period < 0.0) - { - const char format[]= "%d seconds"; - char buf[4*sizeof(SLAVE_MAX_HEARTBEAT_PERIOD) + sizeof(format)]; - sprintf(buf, format, SLAVE_MAX_HEARTBEAT_PERIOD); - my_error(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE, - MYF(0), " is negative or exceeds the maximum ", buf); - MYSQL_YYABORT; + if (Lex->mi.heartbeat_period > SLAVE_MAX_HEARTBEAT_PERIOD || + Lex->mi.heartbeat_period < 0.0) + { + const char format[]= "%d"; + char buf[4*sizeof(SLAVE_MAX_HEARTBEAT_PERIOD) + sizeof(format)]; + sprintf(buf, format, SLAVE_MAX_HEARTBEAT_PERIOD); + my_error(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE, MYF(0), buf); + MYSQL_YYABORT; } if (Lex->mi.heartbeat_period > slave_net_timeout) { push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE, - ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE), - " exceeds the value of `slave_net_timeout' sec.", - " A sensible value for the period should be" - " less than the timeout."); + ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX, + ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX)); } if (Lex->mi.heartbeat_period < 0.001) { if (Lex->mi.heartbeat_period != 0.0) { push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE, - ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE), - " is less than 1 msec.", - " The period is reset to zero which means" - " no heartbeats will be sending"); + ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN, + ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN)); Lex->mi.heartbeat_period= 0.0; } Lex->mi.heartbeat_opt= LEX_MASTER_INFO::LEX_MI_DISABLE; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 69a01259fc0..b8b73bc0387 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2943,11 +2943,8 @@ static bool fix_slave_net_timeout(sys_var *self, THD *thd, enum_var_type type) (active_mi? active_mi->heartbeat_period : 0.0))); if (active_mi && slave_net_timeout < active_mi->heartbeat_period) push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE, - "The current value for master_heartbeat_period" - " exceeds the new value of `slave_net_timeout' sec." - " A sensible value for the period should be" - " less than the timeout."); + ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX, + ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX)); mysql_mutex_unlock(&LOCK_active_mi); return false; } From eaae675279435c06974c166b183cc5bd9232eddc Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Thu, 7 Oct 2010 20:01:17 +0400 Subject: [PATCH 027/151] Fix for bug#57061 "User without privilege on routine can discover its existence". The problem was that user without any privileges on routine was able to find out whether it existed or not. DROP FUNCTION and DROP PROCEDURE statements were checking if routine being dropped existed and reported ER_SP_DOES_NOT_EXIST error/warning before checking if user had enough privileges to drop it. This patch solves this problem by changing code not to check if routine exists before checking if user has enough privileges to drop it. Moreover we no longer perform this check using a separate call instead we rely on sp_drop_routine() returning SP_KEY_NOT_FOUND if routine doesn't exist. This change also simplifies one of upcoming patches refactoring global read lock implementation. mysql-test/r/grant.result: Updated test case after fixing bug#57061 "User without privilege on routine can discover its existence". Removed DROP PROCEDURE/FUNCTION statements which have started to fail after this fix (correctly). There is no need in dropping routines in freshly created database anyway. mysql-test/r/sp-security.result: Added new test case for bug#57061 "User without privilege on routine can discover its existence". Updated existing tests according to new behaviour. mysql-test/suite/funcs_1/r/innodb_storedproc_06.result: Updated test case after fixing bug#57061 "User without privilege on routine can discover its existence". Now we drop routines under user which has enough privileges to do so. mysql-test/suite/funcs_1/r/memory_storedproc_06.result: Updated test case after fixing bug#57061 "User without privilege on routine can discover its existence". Now we drop routines under user which has enough privileges to do so. mysql-test/suite/funcs_1/r/myisam_storedproc_06.result: Updated test case after fixing bug#57061 "User without privilege on routine can discover its existence". Now we drop routines under user which has enough privileges to do so. mysql-test/suite/funcs_1/storedproc/storedproc_06.inc: Updated test case after fixing bug#57061 "User without privilege on routine can discover its existence". Now we drop routines under user which has enough privileges to do so. mysql-test/t/grant.test: Updated test case after fixing bug#57061 "User without privilege on routine can discover its existence". Removed DROP PROCEDURE/FUNCTION statements which have started to fail after this fix (correctly). There is no need in dropping routines in freshly created database anyway. mysql-test/t/sp-security.test: Added new test case for bug#57061 "User without privilege on routine can discover its existence". Updated existing tests according to new behaviour. sql/sp.cc: Removed sp_routine_exists_in_table() which is no longer used. sql/sp.h: Removed sp_routine_exists_in_table() which is no longer used. sql/sql_parse.cc: When dropping routine we no longer check if routine exists before checking if user has enough privileges to do so. Moreover we no longer perform this check using a separate call instead we rely on sp_drop_routine() returning SP_KEY_NOT_FOUND if routine doesn't exist. --- mysql-test/r/grant.result | 2 - mysql-test/r/sp-security.result | 29 ++++++++- .../funcs_1/r/innodb_storedproc_06.result | 4 +- .../funcs_1/r/memory_storedproc_06.result | 4 +- .../funcs_1/r/myisam_storedproc_06.result | 4 +- .../funcs_1/storedproc/storedproc_06.inc | 10 +-- mysql-test/t/grant.test | 5 -- mysql-test/t/sp-security.test | 37 ++++++++++- sql/sp.cc | 32 ---------- sql/sp.h | 3 - sql/sql_parse.cc | 64 ++++++++----------- 11 files changed, 100 insertions(+), 94 deletions(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 84cac386b57..37074e9a32f 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1448,8 +1448,6 @@ CREATE USER 'userbug33464'@'localhost'; GRANT CREATE ROUTINE ON dbbug33464.* TO 'userbug33464'@'localhost'; userbug33464@localhost dbbug33464 -DROP PROCEDURE IF EXISTS sp3; -DROP FUNCTION IF EXISTS fn1; CREATE PROCEDURE sp3(v1 char(20)) BEGIN SELECT * from dbbug33464.t6 where t6.f2= 'xyz'; diff --git a/mysql-test/r/sp-security.result b/mysql-test/r/sp-security.result index 4ea26d1021a..c09579b13eb 100644 --- a/mysql-test/r/sp-security.result +++ b/mysql-test/r/sp-security.result @@ -44,7 +44,7 @@ ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table 't1' create procedure db1_secret.dummy() begin end; ERROR 42000: Access denied for user 'user1'@'localhost' to database 'db1_secret' drop procedure db1_secret.dummy; -ERROR 42000: PROCEDURE db1_secret.dummy does not exist +ERROR 42000: alter routine command denied to user 'user1'@'localhost' for routine 'db1_secret.dummy' drop procedure db1_secret.stamp; ERROR 42000: alter routine command denied to user 'user1'@'localhost' for routine 'db1_secret.stamp' drop function db1_secret.db; @@ -58,7 +58,7 @@ ERROR 42000: SELECT command denied to user ''@'localhost' for table 't1' create procedure db1_secret.dummy() begin end; ERROR 42000: Access denied for user ''@'%' to database 'db1_secret' drop procedure db1_secret.dummy; -ERROR 42000: PROCEDURE db1_secret.dummy does not exist +ERROR 42000: alter routine command denied to user ''@'%' for routine 'db1_secret.dummy' drop procedure db1_secret.stamp; ERROR 42000: alter routine command denied to user ''@'%' for routine 'db1_secret.stamp' drop function db1_secret.db; @@ -567,3 +567,28 @@ DROP USER 'tester'; DROP USER 'Tester'; DROP DATABASE B48872; End of 5.0 tests. +# +# Test for bug#57061 "User without privilege on routine can discover +# its existence." +# +drop database if exists mysqltest_db; +create database mysqltest_db; +# Create user with no privileges on mysqltest_db database. +create user bug57061_user@localhost; +create function mysqltest_db.f1() returns int return 0; +create procedure mysqltest_db.p1() begin end; +# Connect as user 'bug57061_user@localhost' +# Attempt to drop routine on which user doesn't have privileges +# should result in the same 'access denied' type of error whether +# routine exists or not. +drop function if exists mysqltest_db.f_does_not_exist; +ERROR 42000: alter routine command denied to user 'bug57061_user'@'localhost' for routine 'mysqltest_db.f_does_not_exist' +drop procedure if exists mysqltest_db.p_does_not_exist; +ERROR 42000: alter routine command denied to user 'bug57061_user'@'localhost' for routine 'mysqltest_db.p_does_not_exist' +drop function if exists mysqltest_db.f1; +ERROR 42000: alter routine command denied to user 'bug57061_user'@'localhost' for routine 'mysqltest_db.f1' +drop procedure if exists mysqltest_db.p1; +ERROR 42000: alter routine command denied to user 'bug57061_user'@'localhost' for routine 'mysqltest_db.p1' +# Connection 'default'. +drop user bug57061_user@localhost; +drop database mysqltest_db; diff --git a/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result b/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result index ee1548fe012..f19030834c8 100644 --- a/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result +++ b/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result @@ -110,10 +110,10 @@ Ensure that root always has the GRANT CREATE ROUTINE privilege. -------------------------------------------------------------------------------- grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; flush privileges; +DROP PROCEDURE IF EXISTS db_storedproc_1.sp3; +DROP FUNCTION IF EXISTS db_storedproc_1.fn1; user_1@localhost db_storedproc_1 -DROP PROCEDURE IF EXISTS sp3; -DROP FUNCTION IF EXISTS fn1; CREATE PROCEDURE sp3(v1 char(20)) BEGIN SELECT * from db_storedproc_1.t6 where t6.f2= 'xyz'; diff --git a/mysql-test/suite/funcs_1/r/memory_storedproc_06.result b/mysql-test/suite/funcs_1/r/memory_storedproc_06.result index 096cbd1261e..0a117c830ee 100644 --- a/mysql-test/suite/funcs_1/r/memory_storedproc_06.result +++ b/mysql-test/suite/funcs_1/r/memory_storedproc_06.result @@ -111,10 +111,10 @@ Ensure that root always has the GRANT CREATE ROUTINE privilege. -------------------------------------------------------------------------------- grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; flush privileges; +DROP PROCEDURE IF EXISTS db_storedproc_1.sp3; +DROP FUNCTION IF EXISTS db_storedproc_1.fn1; user_1@localhost db_storedproc_1 -DROP PROCEDURE IF EXISTS sp3; -DROP FUNCTION IF EXISTS fn1; CREATE PROCEDURE sp3(v1 char(20)) BEGIN SELECT * from db_storedproc_1.t6 where t6.f2= 'xyz'; diff --git a/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result b/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result index 096cbd1261e..0a117c830ee 100644 --- a/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result +++ b/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result @@ -111,10 +111,10 @@ Ensure that root always has the GRANT CREATE ROUTINE privilege. -------------------------------------------------------------------------------- grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; flush privileges; +DROP PROCEDURE IF EXISTS db_storedproc_1.sp3; +DROP FUNCTION IF EXISTS db_storedproc_1.fn1; user_1@localhost db_storedproc_1 -DROP PROCEDURE IF EXISTS sp3; -DROP FUNCTION IF EXISTS fn1; CREATE PROCEDURE sp3(v1 char(20)) BEGIN SELECT * from db_storedproc_1.t6 where t6.f2= 'xyz'; diff --git a/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc b/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc index 4ecca63351d..0695a0724d8 100644 --- a/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc +++ b/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc @@ -117,15 +117,15 @@ create user 'user_1'@'localhost'; grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; flush privileges; +--disable_warnings +DROP PROCEDURE IF EXISTS db_storedproc_1.sp3; +DROP FUNCTION IF EXISTS db_storedproc_1.fn1; +--enable_warnings + # disconnect default; connect (user2, localhost, user_1, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc ---disable_warnings -DROP PROCEDURE IF EXISTS sp3; -DROP FUNCTION IF EXISTS fn1; ---enable_warnings - delimiter //; CREATE PROCEDURE sp3(v1 char(20)) BEGIN diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index e73f45a6c53..aad0c42a5b3 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1419,11 +1419,6 @@ GRANT CREATE ROUTINE ON dbbug33464.* TO 'userbug33464'@'localhost'; connect (connbug33464, localhost, userbug33464, , dbbug33464); --source suite/funcs_1/include/show_connection.inc ---disable_warnings -DROP PROCEDURE IF EXISTS sp3; -DROP FUNCTION IF EXISTS fn1; ---enable_warnings - delimiter //; CREATE PROCEDURE sp3(v1 char(20)) BEGIN diff --git a/mysql-test/t/sp-security.test b/mysql-test/t/sp-security.test index 96f82c92248..d7ea829bf50 100644 --- a/mysql-test/t/sp-security.test +++ b/mysql-test/t/sp-security.test @@ -82,7 +82,7 @@ select * from db1_secret.t1; # ...and not this --error ER_DBACCESS_DENIED_ERROR create procedure db1_secret.dummy() begin end; ---error ER_SP_DOES_NOT_EXIST +--error ER_PROCACCESS_DENIED_ERROR drop procedure db1_secret.dummy; --error ER_PROCACCESS_DENIED_ERROR drop procedure db1_secret.stamp; @@ -106,7 +106,7 @@ select * from db1_secret.t1; # ...and not this --error ER_DBACCESS_DENIED_ERROR create procedure db1_secret.dummy() begin end; ---error ER_SP_DOES_NOT_EXIST +--error ER_PROCACCESS_DENIED_ERROR drop procedure db1_secret.dummy; --error ER_PROCACCESS_DENIED_ERROR drop procedure db1_secret.stamp; @@ -926,6 +926,39 @@ DROP DATABASE B48872; --echo End of 5.0 tests. + +--echo # +--echo # Test for bug#57061 "User without privilege on routine can discover +--echo # its existence." +--echo # +--disable_warnings +drop database if exists mysqltest_db; +--enable_warnings +create database mysqltest_db; +--echo # Create user with no privileges on mysqltest_db database. +create user bug57061_user@localhost; +create function mysqltest_db.f1() returns int return 0; +create procedure mysqltest_db.p1() begin end; +--echo # Connect as user 'bug57061_user@localhost' +connect (conn1, localhost, bug57061_user,,); +--echo # Attempt to drop routine on which user doesn't have privileges +--echo # should result in the same 'access denied' type of error whether +--echo # routine exists or not. +--error ER_PROCACCESS_DENIED_ERROR +drop function if exists mysqltest_db.f_does_not_exist; +--error ER_PROCACCESS_DENIED_ERROR +drop procedure if exists mysqltest_db.p_does_not_exist; +--error ER_PROCACCESS_DENIED_ERROR +drop function if exists mysqltest_db.f1; +--error ER_PROCACCESS_DENIED_ERROR +drop procedure if exists mysqltest_db.p1; +--echo # Connection 'default'. +connection default; +disconnect conn1; +drop user bug57061_user@localhost; +drop database mysqltest_db; + + # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc diff --git a/sql/sp.cc b/sql/sp.cc index 8821dc9365d..87eb40c29ac 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1636,38 +1636,6 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any) } -/** - Check if a routine exists in the mysql.proc table, without actually - parsing the definition. (Used for dropping). - - @param thd thread context - @param name name of procedure - - @retval - 0 Success - @retval - non-0 Error; SP_OPEN_TABLE_FAILED or SP_KEY_NOT_FOUND -*/ - -int -sp_routine_exists_in_table(THD *thd, int type, sp_name *name) -{ - TABLE *table; - int ret; - Open_tables_backup open_tables_state_backup; - - if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup))) - ret= SP_OPEN_TABLE_FAILED; - else - { - if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK) - ret= SP_KEY_NOT_FOUND; - close_system_tables(thd, &open_tables_state_backup); - } - return ret; -} - - extern "C" uchar* sp_sroutine_key(const uchar *ptr, size_t *plen, my_bool first) { diff --git a/sql/sp.h b/sql/sp.h index 10e70261b86..5d0490586a1 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -100,9 +100,6 @@ sp_cache_routine(THD *thd, int type, sp_name *name, bool sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any); -int -sp_routine_exists_in_table(THD *thd, int type, sp_name *name); - bool sp_show_create_routine(THD *thd, int type, sp_name *name); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2f8a72ee25c..0f3338cb6a6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4023,49 +4023,39 @@ create_sp_error: int sp_result; int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ? TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION); + char *db= lex->spname->m_db.str; + char *name= lex->spname->m_name.str; - /* - @todo: here we break the metadata locking protocol by - looking up the information about the routine without - a metadata lock. Rewrite this piece to make sp_drop_routine - return whether the routine existed or not. - */ - sp_result= sp_routine_exists_in_table(thd, type, lex->spname); - thd->warning_info->opt_clear_warning_info(thd->query_id); - if (sp_result == SP_OK) - { - char *db= lex->spname->m_db.str; - char *name= lex->spname->m_name.str; + if (check_routine_access(thd, ALTER_PROC_ACL, db, name, + lex->sql_command == SQLCOM_DROP_PROCEDURE, 0)) + goto error; - if (check_routine_access(thd, ALTER_PROC_ACL, db, name, - lex->sql_command == SQLCOM_DROP_PROCEDURE, 0)) - goto error; - - /* Conditionally writes to binlog */ - sp_result= sp_drop_routine(thd, type, lex->spname); + /* Conditionally writes to binlog */ + sp_result= sp_drop_routine(thd, type, lex->spname); #ifndef NO_EMBEDDED_ACCESS_CHECKS - /* - We're going to issue an implicit REVOKE statement. - It takes metadata locks and updates system tables. - Make sure that sp_create_routine() did not leave any - locks in the MDL context, so there is no risk to - deadlock. - */ - close_mysql_tables(thd); + /* + We're going to issue an implicit REVOKE statement. + It takes metadata locks and updates system tables. + Make sure that sp_create_routine() did not leave any + locks in the MDL context, so there is no risk to + deadlock. + */ + close_mysql_tables(thd); - if (sp_automatic_privileges && !opt_noacl && - sp_revoke_privileges(thd, db, name, - lex->sql_command == SQLCOM_DROP_PROCEDURE)) - { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_PROC_AUTO_REVOKE_FAIL, - ER(ER_PROC_AUTO_REVOKE_FAIL)); - /* If this happens, an error should have been reported. */ - goto error; - } -#endif + if (sp_result != SP_KEY_NOT_FOUND && + sp_automatic_privileges && !opt_noacl && + sp_revoke_privileges(thd, db, name, + lex->sql_command == SQLCOM_DROP_PROCEDURE)) + { + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_PROC_AUTO_REVOKE_FAIL, + ER(ER_PROC_AUTO_REVOKE_FAIL)); + /* If this happens, an error should have been reported. */ + goto error; } +#endif + res= sp_result; switch (sp_result) { case SP_OK: From 731dcfc7ff5f787f391553f31ea5bcdca3ed13e5 Mon Sep 17 00:00:00 2001 From: Evgeny Potemkin Date: Thu, 7 Oct 2010 20:16:30 +0400 Subject: [PATCH 028/151] Bug#57095: Wrongly chosen expression cache type led to a wrong result. The coalesce function returned DATETIME type due to a DATETIME argument, but since it's not a date/time function it can't return correct int value for it. Nevertheless Item_datetime_cache was chosen to cache coalesce's result and that led to a wrong result. Now Item_datetime_cache is used only for those function that could return correct int representation of DATETIME values. mysql-test/r/type_datetime.result: Added a test case for the bug#57095. mysql-test/t/type_datetime.test: Added a test case for the bug#57095. sql/item.cc: Bug#57095: Wrongly chosen expression cache type led to a wrong result. Now Item_datetime_cache is used only for those function that could return correct int representation of DATETIME values. --- mysql-test/r/type_datetime.result | 12 ++++++++++++ mysql-test/t/type_datetime.test | 10 ++++++++++ sql/item.cc | 8 +++++--- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index f7bfba0accd..958285d6a23 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -680,5 +680,17 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 const PRIMARY PRIMARY 8 const 1 Using index DROP TABLE t1,t2; # +# Bug#57095: Wrongly chosen expression cache type led to a wrong +# result. +# +CREATE TABLE t1 (`b` datetime ); +INSERT INTO t1 VALUES ('2010-01-01 00:00:00'), ('2010-01-01 00:00:00'); +SELECT * FROM t1 WHERE b <= coalesce(NULL, now()); +b +2010-01-01 00:00:00 +2010-01-01 00:00:00 +DROP TABLE t1; +# +# # End of 5.5 tests # diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index 6e40c9ccfa0..ca2a7804907 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -484,6 +484,16 @@ explain select * from t2 where f1=STR_TO_DATE('4/1/2010', '%m/%d/%Y'); DROP TABLE t1,t2; +--echo # +--echo # Bug#57095: Wrongly chosen expression cache type led to a wrong +--echo # result. +--echo # +CREATE TABLE t1 (`b` datetime ); +INSERT INTO t1 VALUES ('2010-01-01 00:00:00'), ('2010-01-01 00:00:00'); +SELECT * FROM t1 WHERE b <= coalesce(NULL, now()); +DROP TABLE t1; +--echo # + --echo # --echo # End of 5.5 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index e782e90b874..fff7511015f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7356,9 +7356,11 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type) case DECIMAL_RESULT: return new Item_cache_decimal(); case STRING_RESULT: - if (item->field_type() == MYSQL_TYPE_DATE || - item->field_type() == MYSQL_TYPE_DATETIME || - item->field_type() == MYSQL_TYPE_TIME) + /* Not all functions that return DATE/TIME are actually DATE/TIME funcs. */ + if ((item->field_type() == MYSQL_TYPE_DATE || + item->field_type() == MYSQL_TYPE_DATETIME || + item->field_type() == MYSQL_TYPE_TIME) && + (const_cast(item))->result_as_longlong()) return new Item_cache_datetime(item->field_type()); return new Item_cache_str(item); case ROW_RESULT: From 36051b0106544a5650326cf69895b61163ad72c2 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 7 Oct 2010 19:51:37 -0300 Subject: [PATCH 029/151] Bug#56822: Add a thread state for sessions waiting on the query cache lock The problem was that threads waiting on the query cache lock are not easily seen due to the lack of a state indicating that the thread is waiting on the said lock. This made it difficult for users to quickly spot (for example, via SHOW PROCESSLIST) a query cache contention problem. The solution is to update the thread state when the query cache lock needs to be acquired. Whenever the lock is to be acquired, the thread state is updated to "Waiting for query cache lock" and is reset once the lock is granted or the wait is interrupted. The intention is to make query cache related hangs more evident. To further investigate query cache related locking problems, one may use PERFORMANCE_SCHEMA to track the overhead associated with the locking bits and determine which particular lock is being a contention point. sql/sql_cache.cc: Set and reset the thread state whenever a attempt to lock the query cache is made. Use DEBUG_SYNC instead of the now unnecessary wait_for_kill hack. --- mysql-test/r/query_cache_debug.result | 75 +++++++++++---- mysql-test/t/query_cache_debug.test | 126 ++++++++++++++++++-------- sql/sql_cache.cc | 74 +++++++-------- 3 files changed, 180 insertions(+), 95 deletions(-) diff --git a/mysql-test/r/query_cache_debug.result b/mysql-test/r/query_cache_debug.result index eb59e62c8ba..30996e5e86b 100644 --- a/mysql-test/r/query_cache_debug.result +++ b/mysql-test/r/query_cache_debug.result @@ -5,20 +5,24 @@ drop table if exists t1; create table t1 (a varchar(100)); insert into t1 values ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); Activate debug hook and attempt to retrieve the statement from the cache. -set session debug='+d,wait_in_query_cache_insert'; +set debug_sync="wait_in_query_cache_insert SIGNAL parked WAIT_FOR go"; select SQL_CACHE * from t1;; +set debug_sync="now WAIT_FOR parked"; On a second connection; clear the query cache. show status like 'Qcache_queries_in_cache'; Variable_name Value Qcache_queries_in_cache 1 set global query_cache_size= 0; Signal the debug hook to release the lock. -select id from information_schema.processlist where state='wait_in_query_cache_insert' into @thread_id; -kill query @thread_id; +set debug_sync="now SIGNAL go"; Show query cache status. show status like 'Qcache_queries_in_cache'; Variable_name Value Qcache_queries_in_cache 0 +a +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +set debug_sync= 'RESET'; set global query_cache_size= 0; use test; drop table t1; @@ -32,11 +36,12 @@ SET GLOBAL concurrent_insert= 1; SET GLOBAL query_cache_size= 1024*512; SET GLOBAL query_cache_type= ON; # Switch to connection con1 -SET SESSION debug='+d,wait_after_query_cache_invalidate'; +SET DEBUG_SYNC = "wait_after_query_cache_invalidate SIGNAL parked WAIT_FOR go"; # Send concurrent insert, will wait in the query cache table invalidate INSERT INTO t1 VALUES (4); # Switch to connection default # Wait for concurrent insert to reach the debug point +SET DEBUG_SYNC = "now WAIT_FOR parked"; # Switch to connection con2 # Send SELECT that shouldn't be cached SELECT * FROM t1; @@ -46,9 +51,7 @@ a 3 # Switch to connection default # Notify the concurrent insert to proceed -SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST -WHERE STATE = 'wait_after_query_cache_invalidate' INTO @thread_id; -KILL QUERY @thread_id; +SET DEBUG_SYNC = "now SIGNAL go"; # Switch to connection con1 # Gather insert result SHOW STATUS LIKE "Qcache_queries_in_cache"; @@ -66,6 +69,7 @@ Variable_name Value Qcache_queries_in_cache 1 # Disconnect # Restore defaults +SET DEBUG_SYNC= 'RESET'; RESET QUERY CACHE; DROP TABLE t1,t2; SET GLOBAL concurrent_insert= DEFAULT; @@ -108,43 +112,44 @@ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ** before the mutex lock in invalidate_table_internal. ** This will allow new result sets to be written into the QC. ** -SET SESSION debug='+d,wait_in_query_cache_invalidate1'; -SET SESSION debug='+d,wait_in_query_cache_invalidate2'; +SET DEBUG_SYNC="wait_in_query_cache_invalidate1 SIGNAL parked1_1 WAIT_FOR go1_1"; +SET DEBUG_SYNC="wait_in_query_cache_invalidate2 SIGNAL parked1_2 WAIT_FOR go1_2"; DELETE FROM t1 WHERE a like '%a%';; =================================== Connection default ** Assert that the expect process status is obtained. +SET DEBUG_SYNC="now WAIT_FOR parked1_1"; ** =================================== Connection thd2 ** On THD2: Insert a result into the cache. This attempt will be blocked ** because of a debug hook placed just before the mutex lock after which ** the first part of the result set is written. -SET SESSION debug='+d,wait_in_query_cache_insert'; +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2"; SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3; =================================== Connection thd3 ** On THD3: Insert another result into the cache and block on the same ** debug hook. -SET SESSION debug='+d,wait_in_query_cache_insert'; +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3"; SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5;; =================================== Connection default ** Assert that the two SELECT-stmt threads to reach the hook. +SET DEBUG_SYNC="now WAIT_FOR parked2"; +SET DEBUG_SYNC="now WAIT_FOR parked3"; ** ** ** Signal the DELETE thread, THD1, to continue. It will enter the mutex ** lock and set query cache status to TABLE_FLUSH_IN_PROGRESS and then ** unlock the mutex before stopping on the next debug hook. -SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_invalidate1' LIMIT 1 INTO @flush_thread_id; -KILL QUERY @flush_thread_id; +SET DEBUG_SYNC="now SIGNAL go1_1"; ** Assert that we reach the next debug hook. +SET DEBUG_SYNC="now WAIT_FOR parked1_2"; ** ** Signal the remaining debug hooks blocking THD2 and THD3. ** The threads will grab the guard mutex enter the wait condition and ** and finally release the mutex. The threads will continue to wait ** until a broadcast signal reaches them causing both threads to ** come alive and check the condition. -SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' ORDER BY id ASC LIMIT 1 INTO @thread_id; -KILL QUERY @thread_id; -SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' ORDER BY id DESC LIMIT 1 INTO @thread_id; -KILL QUERY @thread_id; +SET DEBUG_SYNC="now SIGNAL go2"; +SET DEBUG_SYNC="now SIGNAL go3"; ** ** Finally signal the DELETE statement on THD1 one last time. ** The stmt will complete the query cache invalidation and return @@ -152,8 +157,7 @@ KILL QUERY @thread_id; ** One signal will be sent to the thread group waiting for executing ** invalidations and a broadcast signal will be sent to the thread ** group holding result set writers. -SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_invalidate2' LIMIT 1 INTO @flush_thread_id; -KILL QUERY @flush_thread_id; +SET DEBUG_SYNC="now SIGNAL go1_2"; ** ************************************************************************* ** No tables should be locked @@ -172,6 +176,7 @@ DELETE FROM t4; DELETE FROM t5; =================================== Connection thd1 ** Done. +SET DEBUG_SYNC= 'RESET'; SET GLOBAL query_cache_size= 0; # Restore defaults RESET QUERY CACHE; @@ -179,3 +184,35 @@ FLUSH STATUS; DROP TABLE t1,t2,t3,t4,t5; SET GLOBAL query_cache_size= DEFAULT; SET GLOBAL query_cache_type= DEFAULT; +# +# Bug#56822: Add a thread state for sessions waiting on the query cache lock +# +SET @old_query_cache_size= @@GLOBAL.query_cache_size; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +SET GLOBAL concurrent_insert= 1; +SET GLOBAL query_cache_size= 1024*512; +SET GLOBAL query_cache_type= ON; +# Switch to connection con1 +SET DEBUG_SYNC = "wait_in_query_cache_invalidate2 SIGNAL parked WAIT_FOR go"; +# Send INSERT, will wait in the query cache table invalidation +INSERT INTO t1 VALUES (4);; +# Switch to connection default +# Wait for insert to reach the debug point +SET DEBUG_SYNC = "now WAIT_FOR parked"; +# Switch to connection con2 +# Send a query that should wait on the query cache lock +RESET QUERY CACHE; +# Switch to connection default +# Wait for the state to be reflected in the processlist +# Signal that the query cache can be unlocked +SET DEBUG_SYNC="now SIGNAL go"; +# Reap con1 and disconnect +# Reap con2 and disconnect +# Restore defaults +SET DEBUG_SYNC= 'RESET'; +RESET QUERY CACHE; +DROP TABLE t1; +SET GLOBAL query_cache_size= DEFAULT; +SET GLOBAL query_cache_type= DEFAULT; diff --git a/mysql-test/t/query_cache_debug.test b/mysql-test/t/query_cache_debug.test index ce62b931a93..77e714aa6f5 100644 --- a/mysql-test/t/query_cache_debug.test +++ b/mysql-test/t/query_cache_debug.test @@ -1,6 +1,6 @@ --source include/not_embedded.inc --source include/have_query_cache.inc ---source include/have_debug.inc +--source include/have_debug_sync.inc # # Bug #30887 Server crashes on SET GLOBAL query_cache_size=0 @@ -18,12 +18,11 @@ connect (bug30887con2, localhost, root, ,test); connection bug30887con1; --echo Activate debug hook and attempt to retrieve the statement from the cache. -set session debug='+d,wait_in_query_cache_insert'; +set debug_sync="wait_in_query_cache_insert SIGNAL parked WAIT_FOR go"; --send select SQL_CACHE * from t1; connection default; -let $wait_condition= select count(*)= 1 from information_schema.processlist where state= 'wait_in_query_cache_insert'; ---source include/wait_condition.inc +set debug_sync="now WAIT_FOR parked"; connection bug30887con2; --echo On a second connection; clear the query cache. @@ -32,14 +31,18 @@ set global query_cache_size= 0; connection default; --echo Signal the debug hook to release the lock. -select id from information_schema.processlist where state='wait_in_query_cache_insert' into @thread_id; -kill query @thread_id; +set debug_sync="now SIGNAL go"; --echo Show query cache status. show status like 'Qcache_queries_in_cache'; +connection bug30887con1; +--reap + disconnect bug30887con1; disconnect bug30887con2; +connection default; +set debug_sync= 'RESET'; set global query_cache_size= 0; use test; drop table t1; @@ -67,18 +70,14 @@ connect(con2,localhost,root,,test,,); connection con1; --echo # Switch to connection con1 -SET SESSION debug='+d,wait_after_query_cache_invalidate'; +SET DEBUG_SYNC = "wait_after_query_cache_invalidate SIGNAL parked WAIT_FOR go"; --echo # Send concurrent insert, will wait in the query cache table invalidate --send INSERT INTO t1 VALUES (4) connection default; --echo # Switch to connection default --echo # Wait for concurrent insert to reach the debug point -let $wait_condition= - SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST - WHERE STATE = "wait_after_query_cache_invalidate" AND - INFO = "INSERT INTO t1 VALUES (4)"; ---source include/wait_condition.inc +SET DEBUG_SYNC = "now WAIT_FOR parked"; connection con2; --echo # Switch to connection con2 @@ -88,9 +87,7 @@ SELECT * FROM t1; connection default; --echo # Switch to connection default --echo # Notify the concurrent insert to proceed -SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST - WHERE STATE = 'wait_after_query_cache_invalidate' INTO @thread_id; -KILL QUERY @thread_id; +SET DEBUG_SYNC = "now SIGNAL go"; connection con1; --echo # Switch to connection con1 @@ -107,6 +104,7 @@ disconnect con2; connection default; --echo # Restore defaults +SET DEBUG_SYNC= 'RESET'; RESET QUERY CACHE; DROP TABLE t1,t2; SET GLOBAL concurrent_insert= DEFAULT; @@ -157,15 +155,14 @@ SELECT SQL_CACHE * FROM t1; --echo ** before the mutex lock in invalidate_table_internal. --echo ** This will allow new result sets to be written into the QC. --echo ** -SET SESSION debug='+d,wait_in_query_cache_invalidate1'; -SET SESSION debug='+d,wait_in_query_cache_invalidate2'; +SET DEBUG_SYNC="wait_in_query_cache_invalidate1 SIGNAL parked1_1 WAIT_FOR go1_1"; +SET DEBUG_SYNC="wait_in_query_cache_invalidate2 SIGNAL parked1_2 WAIT_FOR go1_2"; --send DELETE FROM t1 WHERE a like '%a%'; connection default; --echo =================================== Connection default --echo ** Assert that the expect process status is obtained. -LET $wait_condition= SELECT SQL_NO_CACHE COUNT(*)= 1 FROM information_schema.processlist WHERE state= 'wait_in_query_cache_invalidate1'; ---source include/wait_condition.inc +SET DEBUG_SYNC="now WAIT_FOR parked1_1"; -- echo ** connection thd2; @@ -173,32 +170,30 @@ connection thd2; --echo ** On THD2: Insert a result into the cache. This attempt will be blocked --echo ** because of a debug hook placed just before the mutex lock after which --echo ** the first part of the result set is written. -SET SESSION debug='+d,wait_in_query_cache_insert'; +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2"; --send SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3 connection thd3; --echo =================================== Connection thd3 --echo ** On THD3: Insert another result into the cache and block on the same --echo ** debug hook. -SET SESSION debug='+d,wait_in_query_cache_insert'; +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3"; --send SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5; connection default; --echo =================================== Connection default --echo ** Assert that the two SELECT-stmt threads to reach the hook. -LET $wait_condition= SELECT SQL_NO_CACHE COUNT(*)= 2 FROM information_schema.processlist WHERE state='wait_in_query_cache_insert'; ---source include/wait_condition.inc +SET DEBUG_SYNC="now WAIT_FOR parked2"; +SET DEBUG_SYNC="now WAIT_FOR parked3"; --echo ** --echo ** --echo ** Signal the DELETE thread, THD1, to continue. It will enter the mutex --echo ** lock and set query cache status to TABLE_FLUSH_IN_PROGRESS and then --echo ** unlock the mutex before stopping on the next debug hook. -SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_invalidate1' LIMIT 1 INTO @flush_thread_id; -KILL QUERY @flush_thread_id; +SET DEBUG_SYNC="now SIGNAL go1_1"; --echo ** Assert that we reach the next debug hook. -LET $wait_condition= SELECT SQL_NO_CACHE COUNT(*)= 1 FROM information_schema.processlist WHERE state='wait_in_query_cache_invalidate2'; ---source include/wait_condition.inc +SET DEBUG_SYNC="now WAIT_FOR parked1_2"; --echo ** --echo ** Signal the remaining debug hooks blocking THD2 and THD3. @@ -206,10 +201,8 @@ LET $wait_condition= SELECT SQL_NO_CACHE COUNT(*)= 1 FROM information_schema.pro --echo ** and finally release the mutex. The threads will continue to wait --echo ** until a broadcast signal reaches them causing both threads to --echo ** come alive and check the condition. -SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' ORDER BY id ASC LIMIT 1 INTO @thread_id; -KILL QUERY @thread_id; -SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' ORDER BY id DESC LIMIT 1 INTO @thread_id; -KILL QUERY @thread_id; +SET DEBUG_SYNC="now SIGNAL go2"; +SET DEBUG_SYNC="now SIGNAL go3"; --echo ** --echo ** Finally signal the DELETE statement on THD1 one last time. @@ -218,11 +211,7 @@ KILL QUERY @thread_id; --echo ** One signal will be sent to the thread group waiting for executing --echo ** invalidations and a broadcast signal will be sent to the thread --echo ** group holding result set writers. -SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_invalidate2' LIMIT 1 INTO @flush_thread_id; -KILL QUERY @flush_thread_id; - -LET $wait_condition= SELECT SQL_NO_CACHE COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE Id = @flush_thread_id AND Command = 'Sleep'; ---source include/wait_condition.inc +SET DEBUG_SYNC="now SIGNAL go1_2"; --echo ** --echo ************************************************************************* @@ -250,6 +239,7 @@ connection default; disconnect thd1; disconnect thd2; disconnect thd3; +SET DEBUG_SYNC= 'RESET'; SET GLOBAL query_cache_size= 0; connection default; @@ -259,4 +249,66 @@ FLUSH STATUS; DROP TABLE t1,t2,t3,t4,t5; SET GLOBAL query_cache_size= DEFAULT; SET GLOBAL query_cache_type= DEFAULT; -exit; + +--echo # +--echo # Bug#56822: Add a thread state for sessions waiting on the query cache lock +--echo # + +SET @old_query_cache_size= @@GLOBAL.query_cache_size; + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); + +SET GLOBAL concurrent_insert= 1; +SET GLOBAL query_cache_size= 1024*512; +SET GLOBAL query_cache_type= ON; + +connect(con1,localhost,root,,test,,); +connect(con2,localhost,root,,test,,); + +connection con1; +--echo # Switch to connection con1 +SET DEBUG_SYNC = "wait_in_query_cache_invalidate2 SIGNAL parked WAIT_FOR go"; +--echo # Send INSERT, will wait in the query cache table invalidation +--send INSERT INTO t1 VALUES (4); + +connection default; +--echo # Switch to connection default +--echo # Wait for insert to reach the debug point +SET DEBUG_SYNC = "now WAIT_FOR parked"; + +connection con2; +--echo # Switch to connection con2 +--echo # Send a query that should wait on the query cache lock +--send RESET QUERY CACHE + +connection default; +--echo # Switch to connection default +--echo # Wait for the state to be reflected in the processlist +let $wait_condition= + SELECT COUNT(*) = 1 FROM information_schema.processlist + WHERE state = "Waiting for query cache lock" AND info = "RESET QUERY CACHE"; +--source include/wait_condition.inc +--echo # Signal that the query cache can be unlocked +SET DEBUG_SYNC="now SIGNAL go"; + +connection con1; +--echo # Reap con1 and disconnect +--reap +disconnect con1; + +connection con2; +--echo # Reap con2 and disconnect +--reap +disconnect con2; + +connection default; +--echo # Restore defaults +SET DEBUG_SYNC= 'RESET'; +RESET QUERY CACHE; +DROP TABLE t1; +SET GLOBAL query_cache_size= DEFAULT; +SET GLOBAL query_cache_type= DEFAULT; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index a10e470afd4..b68355206b5 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -334,6 +334,7 @@ TODO list: #include "tztime.h" // struct Time_zone #include "sql_acl.h" // SELECT_ACL #include "sql_base.h" // TMP_TABLE_KEY_EXTRA +#include "debug_sync.h" // DEBUG_SYNC #ifdef HAVE_QUERY_CACHE #include #include @@ -372,30 +373,32 @@ TODO list: #define DUMP(C) DBUG_EXECUTE("qcache", {\ (C)->cache_dump(); (C)->queries_dump();(C)->tables_dump();}) - /** - Causes the thread to wait in a spin lock for a query kill signal. - This function is used by the test frame work to identify race conditions. - - The signal is caught and ignored and the thread is not killed. + Thread state to be used when the query cache lock needs to be acquired. + Sets the thread state name in the constructor, resets on destructor. */ -static void debug_wait_for_kill(const char *info) +struct Query_cache_wait_state { - DBUG_ENTER("debug_wait_for_kill"); - const char *prev_info; - THD *thd; - thd= current_thd; - prev_info= thd->proc_info; - thd->proc_info= info; - sql_print_information("%s", info); - while(!thd->killed) - my_sleep(1000); - thd->killed= THD::NOT_KILLED; - sql_print_information("Exit debug_wait_for_kill"); - thd->proc_info= prev_info; - DBUG_VOID_RETURN; -} + THD *m_thd; + const char *m_proc_info; + + Query_cache_wait_state(THD *thd, const char *func, + const char *file, unsigned int line) + : m_thd(thd) + { + if (m_thd) + m_proc_info= set_thd_proc_info(m_thd, + "Waiting for query cache lock", + func, file, line); + } + + ~Query_cache_wait_state() + { + if (m_thd) + set_thd_proc_info(m_thd, m_proc_info, NULL, NULL, 0); + } +}; #else #define RW_WLOCK(M) mysql_rwlock_wrlock(M) @@ -429,6 +432,8 @@ static void debug_wait_for_kill(const char *info) bool Query_cache::try_lock(bool use_timeout) { bool interrupt= FALSE; + THD *thd= current_thd; + Query_cache_wait_state wait_state(thd, __func__, __FILE__, __LINE__); DBUG_ENTER("Query_cache::try_lock"); mysql_mutex_lock(&structure_guard_mutex); @@ -438,7 +443,6 @@ bool Query_cache::try_lock(bool use_timeout) { m_cache_lock_status= Query_cache::LOCKED; #ifndef DBUG_OFF - THD *thd= current_thd; if (thd) m_cache_lock_thread_id= thd->thread_id; #endif @@ -497,6 +501,8 @@ bool Query_cache::try_lock(bool use_timeout) void Query_cache::lock_and_suspend(void) { + THD *thd= current_thd; + Query_cache_wait_state wait_state(thd, __func__, __FILE__, __LINE__); DBUG_ENTER("Query_cache::lock_and_suspend"); mysql_mutex_lock(&structure_guard_mutex); @@ -504,7 +510,6 @@ void Query_cache::lock_and_suspend(void) mysql_cond_wait(&COND_cache_status_changed, &structure_guard_mutex); m_cache_lock_status= Query_cache::LOCKED_NO_WAIT; #ifndef DBUG_OFF - THD *thd= current_thd; if (thd) m_cache_lock_thread_id= thd->thread_id; #endif @@ -525,6 +530,8 @@ void Query_cache::lock_and_suspend(void) void Query_cache::lock(void) { + THD *thd= current_thd; + Query_cache_wait_state wait_state(thd, __func__, __FILE__, __LINE__); DBUG_ENTER("Query_cache::lock"); mysql_mutex_lock(&structure_guard_mutex); @@ -532,7 +539,6 @@ void Query_cache::lock(void) mysql_cond_wait(&COND_cache_status_changed, &structure_guard_mutex); m_cache_lock_status= Query_cache::LOCKED; #ifndef DBUG_OFF - THD *thd= current_thd; if (thd) m_cache_lock_thread_id= thd->thread_id; #endif @@ -872,9 +878,7 @@ Query_cache::insert(Query_cache_tls *query_cache_tls, if (is_disabled() || query_cache_tls->first_query_block == NULL) DBUG_VOID_RETURN; - DBUG_EXECUTE_IF("wait_in_query_cache_insert", - debug_wait_for_kill("wait_in_query_cache_insert"); ); - + DEBUG_SYNC(current_thd, "wait_in_query_cache_insert"); if (try_lock()) DBUG_VOID_RETURN; @@ -1779,8 +1783,7 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used, invalidate_table(thd, tables_used); } - DBUG_EXECUTE_IF("wait_after_query_cache_invalidate", - debug_wait_for_kill("wait_after_query_cache_invalidate");); + DEBUG_SYNC(thd, "wait_after_query_cache_invalidate"); DBUG_VOID_RETURN; } @@ -1971,8 +1974,7 @@ void Query_cache::flush() if (is_disabled()) DBUG_VOID_RETURN; - DBUG_EXECUTE_IF("wait_in_query_cache_flush1", - debug_wait_for_kill("wait_in_query_cache_flush1");); + DEBUG_SYNC(current_thd, "wait_in_query_cache_flush1"); lock_and_suspend(); if (query_cache_size > 0) @@ -2312,9 +2314,7 @@ void Query_cache::free_cache() void Query_cache::flush_cache() { - - DBUG_EXECUTE_IF("wait_in_query_cache_flush2", - debug_wait_for_kill("wait_in_query_cache_flush2");); + DEBUG_SYNC(current_thd, "wait_in_query_cache_flush2"); my_hash_reset(&queries); while (queries_blocks != 0) @@ -2760,8 +2760,7 @@ void Query_cache::invalidate_table(THD *thd, TABLE *table) void Query_cache::invalidate_table(THD *thd, uchar * key, uint32 key_length) { - DBUG_EXECUTE_IF("wait_in_query_cache_invalidate1", - debug_wait_for_kill("wait_in_query_cache_invalidate1"); ); + DEBUG_SYNC(thd, "wait_in_query_cache_invalidate1"); /* Lock the query cache and queue all invalidation attempts to avoid @@ -2769,9 +2768,7 @@ void Query_cache::invalidate_table(THD *thd, uchar * key, uint32 key_length) */ lock(); - DBUG_EXECUTE_IF("wait_in_query_cache_invalidate2", - debug_wait_for_kill("wait_in_query_cache_invalidate2"); ); - + DEBUG_SYNC(thd, "wait_in_query_cache_invalidate2"); if (query_cache_size > 0) invalidate_table_internal(thd, key, key_length); @@ -2821,7 +2818,6 @@ Query_cache::invalidate_query_block_list(THD *thd, Query_cache_block *query_block= list_root->next->block(); BLOCK_LOCK_WR(query_block); free_query(query_block); - DBUG_EXECUTE_IF("debug_cache_locks", sleep(10);); } } From 28be8f919f768542465b07099f711632e3334f6e Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 7 Oct 2010 21:05:23 -0300 Subject: [PATCH 030/151] Bug#56822: Add a thread state for sessions waiting on the query cache lock Move Query_cache_wait_state declaration out of a debug block. --- sql/sql_cache.cc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index b68355206b5..8c3abdbf1b0 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -372,6 +372,17 @@ TODO list: __LINE__,(ulong)(B)));B->query()->unlock_reading();} #define DUMP(C) DBUG_EXECUTE("qcache", {\ (C)->cache_dump(); (C)->queries_dump();(C)->tables_dump();}) +#else +#define RW_WLOCK(M) mysql_rwlock_wrlock(M) +#define RW_RLOCK(M) mysql_rwlock_rdlock(M) +#define RW_UNLOCK(M) mysql_rwlock_unlock(M) +#define BLOCK_LOCK_WR(B) B->query()->lock_writing() +#define BLOCK_LOCK_RD(B) B->query()->lock_reading() +#define BLOCK_UNLOCK_WR(B) B->query()->unlock_writing() +#define BLOCK_UNLOCK_RD(B) B->query()->unlock_reading() +#define DUMP(C) +#endif + /** Thread state to be used when the query cache lock needs to be acquired. @@ -400,16 +411,6 @@ struct Query_cache_wait_state } }; -#else -#define RW_WLOCK(M) mysql_rwlock_wrlock(M) -#define RW_RLOCK(M) mysql_rwlock_rdlock(M) -#define RW_UNLOCK(M) mysql_rwlock_unlock(M) -#define BLOCK_LOCK_WR(B) B->query()->lock_writing() -#define BLOCK_LOCK_RD(B) B->query()->lock_reading() -#define BLOCK_UNLOCK_WR(B) B->query()->unlock_writing() -#define BLOCK_UNLOCK_RD(B) B->query()->unlock_reading() -#define DUMP(C) -#endif /** Serialize access to the query cache. From 754471060b2dfdfd4929f1b04560e3fd66755763 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 7 Oct 2010 21:53:00 -0300 Subject: [PATCH 031/151] Bug#45288: pb2 returns a lot of compilation warnings on linux Fix warnings related to the use of the deprecated gets() function and passing NULL to non-pointer argument of the sys_var constructor. plugin/auth/dialog.c: Do not use the deprecated gets() function. sql/sys_vars.h: Do not pass NULL to a non-pointer argument of the sys_var constructor. --- plugin/auth/dialog.c | 17 ++++++++++------- sql/sys_vars.h | 8 +++----- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/plugin/auth/dialog.c b/plugin/auth/dialog.c index b7c65b3d601..54f88dd9b4e 100644 --- a/plugin/auth/dialog.c +++ b/plugin/auth/dialog.c @@ -1,15 +1,15 @@ /* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -181,7 +181,7 @@ mysql_declare_plugin_end; To support all this variety, the dialog plugin has a callback function "authentication_dialog_ask". If the client has a function of this name dialog plugin will use it for communication with the user. Otherwise - a default gets() based implementation will be used. + a default fgets() based implementation will be used. */ /** @@ -208,12 +208,15 @@ static mysql_authentication_dialog_ask_t ask; static char *builtin_ask(MYSQL *mysql __attribute__((unused)), int type __attribute__((unused)), const char *prompt, - char *buf, int buf_len __attribute__((unused))) + char *buf, int buf_len) { + char *ptr; fputs(prompt, stdout); fputc(' ', stdout); - if (gets(buf) == 0) - return 0; + if (fgets(buf, buf_len, stdin) == NULL) + return NULL; + if ((ptr= strchr(buf, '\n'))) + *ptr= 0; return buf; } diff --git a/sql/sys_vars.h b/sql/sys_vars.h index 89e2bdfdf60..e16bd3c5330 100644 --- a/sql/sys_vars.h +++ b/sql/sys_vars.h @@ -458,12 +458,10 @@ class Sys_var_proxy_user: public sys_var public: Sys_var_proxy_user(const char *name_arg, const char *comment, enum charset_enum is_os_charset_arg) - : sys_var(&all_sys_vars, name_arg, comment, + : sys_var(&all_sys_vars, name_arg, comment, sys_var::READONLY+sys_var::ONLY_SESSION, 0, -1, - NO_ARG, SHOW_CHAR, (intptr)NULL, - 0, VARIABLE_NOT_IN_BINLOG, - 0, 0, - 0, 0, PARSE_NORMAL) + NO_ARG, SHOW_CHAR, 0, NULL, VARIABLE_NOT_IN_BINLOG, + NULL, NULL, 0, NULL, PARSE_NORMAL) { is_os_charset= is_os_charset_arg == IN_FS_CHARSET; option.var_type= GET_STR; From 42dc7264c009fb8f32bce88b80f74bcaae6f63b4 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Fri, 8 Oct 2010 12:09:47 +0500 Subject: [PATCH 032/151] Bug#35269 mysqlcheck behaves different depending on order of parameters Issue an error if user specifies multiple commands to run. Also there was an unnoticed bug that DO_CHECK was actually 0 which lead to wrong actions in some cases. The mysqlcheck.test contained commands with the suspicious meaning for the above reason. Extra commands removed from there. per-file commands: client/mysqlcheck.c Bug#35269 mysqlcheck behaves different depending on order of parameters Drop with an error if multiple commands. mysql-test/r/mysqlcheck.result Bug#35269 mysqlcheck behaves different depending on order of parameters result completed. mysql-test/t/mysqlcheck.test Bug#35269 mysqlcheck behaves different depending on order of parameters testcase added. not-working commands removed from some mysqlcheck calls. --- client/mysqlcheck.c | 11 +++++- mysql-test/r/mysqlcheck.result | 64 ++++++++++++++++++++++++++++++++-- mysql-test/t/mysqlcheck.test | 29 +++++++++++---- 3 files changed, 95 insertions(+), 9 deletions(-) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index aebe80b9ba6..7b188d7ce18 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -47,7 +47,7 @@ static char *shared_memory_base_name=0; #endif static uint opt_protocol=0; -enum operations { DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE }; +enum operations { DO_CHECK=1, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE }; static struct my_option my_long_options[] = { @@ -241,6 +241,8 @@ static my_bool get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char *argument) { + int orig_what_to_do= what_to_do; + switch(optid) { case 'a': what_to_do = DO_ANALYZE; @@ -315,6 +317,13 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), opt->name); break; } + + if (orig_what_to_do && (what_to_do != orig_what_to_do)) + { + fprintf(stderr, "Error: %s doesn't support multiple contradicting commands.\n", + my_progname); + return 1; + } return 0; } diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index c51d71510f4..241c92f0aa6 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -8,7 +8,7 @@ mysql.db OK mysql.event OK mysql.func OK mysql.general_log -note : The storage engine for the table doesn't support optimize +note : The storage engine for the table doesn't support analyze mysql.help_category OK mysql.help_keyword OK mysql.help_relation OK @@ -21,7 +21,7 @@ mysql.procs_priv OK mysql.proxy_priv OK mysql.servers OK mysql.slow_log -note : The storage engine for the table doesn't support optimize +note : The storage engine for the table doesn't support analyze mysql.tables_priv OK mysql.time_zone OK mysql.time_zone_leap_second OK @@ -29,6 +29,8 @@ mysql.time_zone_name OK mysql.time_zone_transition OK mysql.time_zone_transition_type OK mysql.user OK +mtr.global_suppressions Table is already up to date +mtr.test_suppressions Table is already up to date mysql.columns_priv OK mysql.db OK mysql.event OK @@ -55,10 +57,64 @@ mysql.time_zone_name OK mysql.time_zone_transition OK mysql.time_zone_transition_type OK mysql.user OK +mysql.columns_priv OK +mysql.db OK +mysql.event OK +mysql.func OK +mysql.general_log +note : The storage engine for the table doesn't support analyze +mysql.help_category OK +mysql.help_keyword OK +mysql.help_relation OK +mysql.help_topic OK +mysql.host OK +mysql.ndb_binlog_index OK +mysql.plugin OK +mysql.proc OK +mysql.procs_priv OK +mysql.proxy_priv OK +mysql.servers OK +mysql.slow_log +note : The storage engine for the table doesn't support analyze +mysql.tables_priv OK +mysql.time_zone OK +mysql.time_zone_leap_second OK +mysql.time_zone_name OK +mysql.time_zone_transition OK +mysql.time_zone_transition_type OK +mysql.user OK +mysql.columns_priv Table is already up to date +mysql.db Table is already up to date +mysql.event Table is already up to date +mysql.func Table is already up to date +mysql.general_log +note : The storage engine for the table doesn't support optimize +mysql.help_category Table is already up to date +mysql.help_keyword Table is already up to date +mysql.help_relation Table is already up to date +mysql.help_topic Table is already up to date +mysql.host Table is already up to date +mysql.ndb_binlog_index Table is already up to date +mysql.plugin Table is already up to date +mysql.proc Table is already up to date +mysql.procs_priv Table is already up to date +mysql.proxy_priv Table is already up to date +mysql.servers Table is already up to date +mysql.slow_log +note : The storage engine for the table doesn't support optimize +mysql.tables_priv Table is already up to date +mysql.time_zone Table is already up to date +mysql.time_zone_leap_second Table is already up to date +mysql.time_zone_name Table is already up to date +mysql.time_zone_transition Table is already up to date +mysql.time_zone_transition_type Table is already up to date +mysql.user Table is already up to date create table t1 (a int); create view v1 as select * from t1; test.t1 OK +test.t1 Table is already up to date test.t1 OK +test.t1 Table is already up to date drop view v1; drop table t1; create table `t``1`(a int); @@ -127,6 +183,7 @@ Tables_in_test t1 #mysql50#v-1 v1 +test.t1 OK show tables; Tables_in_test t1 @@ -200,3 +257,6 @@ Tables_in_test (t1-1) t1-1 drop table `t1-1`; End of 5.1 tests +# +# Bug #35269: mysqlcheck behaves different depending on order of parameters +# diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index 831aba72fb5..dd113cb4e74 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -23,10 +23,13 @@ drop database if exists client_test_db; # Bug #13783 mysqlcheck tries to optimize and analyze information_schema # --replace_result 'Table is already up to date' OK ---exec $MYSQL_CHECK --all-databases --analyze --optimize +--exec $MYSQL_CHECK --all-databases --analyze +--exec $MYSQL_CHECK --all-databases --optimize --replace_result 'Table is already up to date' OK ---exec $MYSQL_CHECK --analyze --optimize --databases test information_schema mysql ---exec $MYSQL_CHECK --analyze --optimize information_schema schemata +--exec $MYSQL_CHECK --analyze --databases test information_schema mysql +--exec $MYSQL_CHECK --optimize --databases test information_schema mysql +--exec $MYSQL_CHECK --analyze information_schema schemata +--exec $MYSQL_CHECK --optimize information_schema schemata # # Bug #16502: mysqlcheck tries to check views @@ -34,9 +37,11 @@ drop database if exists client_test_db; create table t1 (a int); create view v1 as select * from t1; --replace_result 'Table is already up to date' OK ---exec $MYSQL_CHECK --analyze --optimize --databases test +--exec $MYSQL_CHECK --analyze --databases test +--exec $MYSQL_CHECK --optimize --databases test --replace_result 'Table is already up to date' OK ---exec $MYSQL_CHECK --all-in-1 --analyze --optimize --databases test +--exec $MYSQL_CHECK --all-in-1 --analyze --databases test +--exec $MYSQL_CHECK --all-in-1 --optimize --databases test drop view v1; drop table t1; @@ -113,7 +118,8 @@ show tables; let $MYSQLD_DATADIR= `select @@datadir`; --copy_file $MYSQLD_DATADIR/test/v1.frm $MYSQLD_DATADIR/test/v-1.frm show tables; ---exec $MYSQL_CHECK --check-upgrade --fix-table-names --databases test +--exec $MYSQL_CHECK --check-upgrade --databases test +--exec $MYSQL_CHECK --fix-table-names --databases test show tables; drop view v1, `v-1`; drop table t1; @@ -212,3 +218,14 @@ show tables like 't1-1'; drop table `t1-1`; --echo End of 5.1 tests + + +--echo # +--echo # Bug #35269: mysqlcheck behaves different depending on order of parameters +--echo # + +--error 13 +--exec $MYSQL_CHECK -a --fix-table-names test "#mysql50#t1-1" +--error 1 +--exec $MYSQL_CHECK -aoc test "#mysql50#t1-1" + From 5f318d4ad9e9b279134564de8f350864c6254c3b Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Fri, 8 Oct 2010 12:12:18 +0500 Subject: [PATCH 033/151] Bug#30025 Mysqld prints out warnings/errors being run with --no-defaults --help now do no initializations for the --help. Do it for --verbose --help though. per-file comments: sql/mysqld.cc Bug#30025 Mysqld prints out warnings/errors being run with --no-defaults --help quit with the help message at once as --help was given --- sql/mysqld.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e43320f12a5..e489d466d5f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3202,6 +3202,11 @@ static int init_common_variables() return 1; set_server_version(); +#ifndef EMBEDDED_LIBRARY + if (opt_help && !opt_verbose) + unireg_abort(0); +#endif /*!EMBEDDED_LIBRARY*/ + DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname, server_version, SYSTEM_TYPE,MACHINE_TYPE)); From 8284a3786d92158fcd5cc4fe5a305a87816562b5 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 8 Oct 2010 13:20:42 +0400 Subject: [PATCH 034/151] Fixed plugin_load_option failure, when example storage engine is not available. We need to add loose prefix to example load option. --- mysql-test/t/plugin_load_option-master.opt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/plugin_load_option-master.opt b/mysql-test/t/plugin_load_option-master.opt index 3be53c3b713..e22ecb4ff3a 100644 --- a/mysql-test/t/plugin_load_option-master.opt +++ b/mysql-test/t/plugin_load_option-master.opt @@ -1,3 +1,3 @@ $EXAMPLE_PLUGIN_OPT $EXAMPLE_PLUGIN_LOAD ---plugin-example=FORCE_PLUS_PERMANENT +--loose-plugin-example=FORCE_PLUS_PERMANENT From f9e19fe487dce02e777a5381f47b84b1e022af7b Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 8 Oct 2010 12:34:08 +0300 Subject: [PATCH 035/151] Adjust results files after innodb_file_per_table became 0. In calvin.sun@oracle.com-20101005183830-p81bemgffq8l2en9 the default value of innodb_file_per_table was changed from 1 to 0. --- .../parts/r/partition_alter3_innodb.result | 94 ---- .../parts/r/partition_basic_innodb.result | 432 ------------------ 2 files changed, 526 deletions(-) diff --git a/mysql-test/suite/parts/r/partition_alter3_innodb.result b/mysql-test/suite/parts/r/partition_alter3_innodb.result index c5750e007e6..7825a2350b0 100644 --- a/mysql-test/suite/parts/r/partition_alter3_innodb.result +++ b/mysql-test/suite/parts/r/partition_alter3_innodb.result @@ -57,7 +57,6 @@ t1 CREATE TABLE `t1` ( `f_varchar` varchar(30) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 t1.frm -t1.ibd EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 20 Using where @@ -79,7 +78,6 @@ t1 CREATE TABLE `t1` ( `f_varchar` varchar(30) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (YEAR(f_date)) */ -t1#P#p0.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -98,7 +96,6 @@ t1 CREATE TABLE `t1` ( `f_varchar` varchar(30) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (DAYOFYEAR(f_date)) */ -t1#P#p0.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -115,7 +112,6 @@ t1 CREATE TABLE `t1` ( `f_varchar` varchar(30) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (YEAR(f_date)) */ -t1#P#p0.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -141,9 +137,6 @@ t1 CREATE TABLE `t1` ( (PARTITION p0 ENGINE = InnoDB, PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#part1.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -168,10 +161,6 @@ t1 CREATE TABLE `t1` ( PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB, PARTITION part2 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -197,14 +186,6 @@ t1 CREATE TABLE `t1` ( PARTITION p5 ENGINE = InnoDB, PARTITION p6 ENGINE = InnoDB, PARTITION p7 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#p4.ibd -t1#P#p5.ibd -t1#P#p6.ibd -t1#P#p7.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -241,13 +222,6 @@ t1 CREATE TABLE `t1` ( PARTITION p4 ENGINE = InnoDB, PARTITION p5 ENGINE = InnoDB, PARTITION p6 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#p4.ibd -t1#P#p5.ibd -t1#P#p6.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -270,12 +244,6 @@ t1 CREATE TABLE `t1` ( PARTITION part2 ENGINE = InnoDB, PARTITION p4 ENGINE = InnoDB, PARTITION p5 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#p4.ibd -t1#P#p5.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -297,11 +265,6 @@ t1 CREATE TABLE `t1` ( PARTITION part7 ENGINE = InnoDB, PARTITION part2 ENGINE = InnoDB, PARTITION p4 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#p4.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -322,10 +285,6 @@ t1 CREATE TABLE `t1` ( PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB, PARTITION part2 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -345,9 +304,6 @@ t1 CREATE TABLE `t1` ( (PARTITION p0 ENGINE = InnoDB, PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#part1.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -366,8 +322,6 @@ t1 CREATE TABLE `t1` ( /*!50100 PARTITION BY HASH (YEAR(f_date)) (PARTITION p0 ENGINE = InnoDB, PARTITION part1 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#part1.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -385,7 +339,6 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (YEAR(f_date)) (PARTITION p0 ENGINE = InnoDB) */ -t1#P#p0.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -406,7 +359,6 @@ t1 CREATE TABLE `t1` ( `f_varchar` varchar(30) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 t1.frm -t1.ibd EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 20 Using where @@ -446,7 +398,6 @@ t1 CREATE TABLE `t1` ( `f_charbig` varchar(1000) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 t1.frm -t1.ibd EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 20 Using where @@ -469,7 +420,6 @@ t1 CREATE TABLE `t1` ( `f_charbig` varchar(1000) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) */ -t1#P#p0.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -498,9 +448,6 @@ t1 CREATE TABLE `t1` ( (PARTITION p0 ENGINE = InnoDB, PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#part1.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -525,10 +472,6 @@ t1 CREATE TABLE `t1` ( PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB, PARTITION part2 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -557,14 +500,6 @@ t1 CREATE TABLE `t1` ( PARTITION p5 ENGINE = InnoDB, PARTITION p6 ENGINE = InnoDB, PARTITION p7 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#p4.ibd -t1#P#p5.ibd -t1#P#p6.ibd -t1#P#p7.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -599,13 +534,6 @@ t1 CREATE TABLE `t1` ( PARTITION p4 ENGINE = InnoDB, PARTITION p5 ENGINE = InnoDB, PARTITION p6 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#p4.ibd -t1#P#p5.ibd -t1#P#p6.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -631,12 +559,6 @@ t1 CREATE TABLE `t1` ( PARTITION part2 ENGINE = InnoDB, PARTITION p4 ENGINE = InnoDB, PARTITION p5 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#p4.ibd -t1#P#p5.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -661,11 +583,6 @@ t1 CREATE TABLE `t1` ( PARTITION part7 ENGINE = InnoDB, PARTITION part2 ENGINE = InnoDB, PARTITION p4 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#p4.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -689,10 +606,6 @@ t1 CREATE TABLE `t1` ( PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB, PARTITION part2 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -715,9 +628,6 @@ t1 CREATE TABLE `t1` ( (PARTITION p0 ENGINE = InnoDB, PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#part1.ibd -t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -739,8 +649,6 @@ t1 CREATE TABLE `t1` ( /*!50100 PARTITION BY KEY (f_int1) (PARTITION p0 ENGINE = InnoDB, PARTITION part1 ENGINE = InnoDB) */ -t1#P#p0.ibd -t1#P#part1.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -761,7 +669,6 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) (PARTITION p0 ENGINE = InnoDB) */ -t1#P#p0.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -785,7 +692,6 @@ t1 CREATE TABLE `t1` ( `f_charbig` varchar(1000) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 t1.frm -t1.ibd EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 20 Using where diff --git a/mysql-test/suite/parts/r/partition_basic_innodb.result b/mysql-test/suite/parts/r/partition_basic_innodb.result index c6a89e970b3..21c5d70e6e3 100644 --- a/mysql-test/suite/parts/r/partition_basic_innodb.result +++ b/mysql-test/suite/parts/r/partition_basic_innodb.result @@ -77,8 +77,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd t1.frm t1.par @@ -534,11 +532,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd -t1#P#p2.ibd -t1#P#p3.ibd -t1#P#p4.ibd t1.frm t1.par @@ -1009,14 +1002,6 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist -t1#P#part0.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part3.ibd -t1#P#part_1.ibd -t1#P#part_2.ibd -t1#P#part_3.ibd -t1#P#part_N.ibd t1.frm t1.par @@ -1483,12 +1468,6 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta.ibd -t1#P#partb.ibd -t1#P#partc.ibd -t1#P#partd.ibd -t1#P#parte.ibd -t1#P#partf.ibd t1.frm t1.par @@ -1951,14 +1930,6 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta#SP#partasp0.ibd -t1#P#parta#SP#partasp1.ibd -t1#P#partb#SP#partbsp0.ibd -t1#P#partb#SP#partbsp1.ibd -t1#P#partc#SP#partcsp0.ibd -t1#P#partc#SP#partcsp1.ibd -t1#P#partd#SP#partdsp0.ibd -t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -2434,14 +2405,6 @@ SUBPARTITION BY KEY (f_int1) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#subpart11.ibd -t1#P#part1#SP#subpart12.ibd -t1#P#part2#SP#subpart21.ibd -t1#P#part2#SP#subpart22.ibd -t1#P#part3#SP#subpart31.ibd -t1#P#part3#SP#subpart32.ibd -t1#P#part4#SP#subpart41.ibd -t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -2919,14 +2882,6 @@ SUBPARTITION BY HASH (f_int1 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#sp11.ibd -t1#P#part1#SP#sp12.ibd -t1#P#part2#SP#sp21.ibd -t1#P#part2#SP#sp22.ibd -t1#P#part3#SP#sp31.ibd -t1#P#part3#SP#sp32.ibd -t1#P#part4#SP#sp41.ibd -t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -3390,15 +3345,6 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist -t1#P#part1#SP#part1sp0.ibd -t1#P#part1#SP#part1sp1.ibd -t1#P#part1#SP#part1sp2.ibd -t1#P#part2#SP#part2sp0.ibd -t1#P#part2#SP#part2sp1.ibd -t1#P#part2#SP#part2sp2.ibd -t1#P#part3#SP#part3sp0.ibd -t1#P#part3#SP#part3sp1.ibd -t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -3856,8 +3802,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd t1.frm t1.par @@ -4313,11 +4257,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd -t1#P#p2.ibd -t1#P#p3.ibd -t1#P#p4.ibd t1.frm t1.par @@ -4788,14 +4727,6 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist -t1#P#part0.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part3.ibd -t1#P#part_1.ibd -t1#P#part_2.ibd -t1#P#part_3.ibd -t1#P#part_N.ibd t1.frm t1.par @@ -5262,12 +5193,6 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta.ibd -t1#P#partb.ibd -t1#P#partc.ibd -t1#P#partd.ibd -t1#P#parte.ibd -t1#P#partf.ibd t1.frm t1.par @@ -5730,14 +5655,6 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta#SP#partasp0.ibd -t1#P#parta#SP#partasp1.ibd -t1#P#partb#SP#partbsp0.ibd -t1#P#partb#SP#partbsp1.ibd -t1#P#partc#SP#partcsp0.ibd -t1#P#partc#SP#partcsp1.ibd -t1#P#partd#SP#partdsp0.ibd -t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -6211,14 +6128,6 @@ SUBPARTITION BY KEY (f_int2) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#subpart11.ibd -t1#P#part1#SP#subpart12.ibd -t1#P#part2#SP#subpart21.ibd -t1#P#part2#SP#subpart22.ibd -t1#P#part3#SP#subpart31.ibd -t1#P#part3#SP#subpart32.ibd -t1#P#part4#SP#subpart41.ibd -t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -6692,14 +6601,6 @@ SUBPARTITION BY HASH (f_int2 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#sp11.ibd -t1#P#part1#SP#sp12.ibd -t1#P#part2#SP#sp21.ibd -t1#P#part2#SP#sp22.ibd -t1#P#part3#SP#sp31.ibd -t1#P#part3#SP#sp32.ibd -t1#P#part4#SP#sp41.ibd -t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -7163,15 +7064,6 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist -t1#P#part1#SP#part1sp0.ibd -t1#P#part1#SP#part1sp1.ibd -t1#P#part1#SP#part1sp2.ibd -t1#P#part2#SP#part2sp0.ibd -t1#P#part2#SP#part2sp1.ibd -t1#P#part2#SP#part2sp2.ibd -t1#P#part3#SP#part3sp0.ibd -t1#P#part3#SP#part3sp1.ibd -t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -7635,8 +7527,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd t1.frm t1.par @@ -8129,11 +8019,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd -t1#P#p2.ibd -t1#P#p3.ibd -t1#P#p4.ibd t1.frm t1.par @@ -8641,14 +8526,6 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist -t1#P#part0.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part3.ibd -t1#P#part_1.ibd -t1#P#part_2.ibd -t1#P#part_3.ibd -t1#P#part_N.ibd t1.frm t1.par @@ -9152,12 +9029,6 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta.ibd -t1#P#partb.ibd -t1#P#partc.ibd -t1#P#partd.ibd -t1#P#parte.ibd -t1#P#partf.ibd t1.frm t1.par @@ -9657,14 +9528,6 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta#SP#partasp0.ibd -t1#P#parta#SP#partasp1.ibd -t1#P#partb#SP#partbsp0.ibd -t1#P#partb#SP#partbsp1.ibd -t1#P#partc#SP#partcsp0.ibd -t1#P#partc#SP#partcsp1.ibd -t1#P#partd#SP#partdsp0.ibd -t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -10177,14 +10040,6 @@ SUBPARTITION BY KEY (f_int1) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#subpart11.ibd -t1#P#part1#SP#subpart12.ibd -t1#P#part2#SP#subpart21.ibd -t1#P#part2#SP#subpart22.ibd -t1#P#part3#SP#subpart31.ibd -t1#P#part3#SP#subpart32.ibd -t1#P#part4#SP#subpart41.ibd -t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -10699,14 +10554,6 @@ SUBPARTITION BY HASH (f_int1 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#sp11.ibd -t1#P#part1#SP#sp12.ibd -t1#P#part2#SP#sp21.ibd -t1#P#part2#SP#sp22.ibd -t1#P#part3#SP#sp31.ibd -t1#P#part3#SP#sp32.ibd -t1#P#part4#SP#sp41.ibd -t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -11207,15 +11054,6 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist -t1#P#part1#SP#part1sp0.ibd -t1#P#part1#SP#part1sp1.ibd -t1#P#part1#SP#part1sp2.ibd -t1#P#part2#SP#part2sp0.ibd -t1#P#part2#SP#part2sp1.ibd -t1#P#part2#SP#part2sp2.ibd -t1#P#part3#SP#part3sp0.ibd -t1#P#part3#SP#part3sp1.ibd -t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -11709,8 +11547,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd t1.frm t1.par @@ -12203,11 +12039,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd -t1#P#p2.ibd -t1#P#p3.ibd -t1#P#p4.ibd t1.frm t1.par @@ -12715,14 +12546,6 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist -t1#P#part0.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part3.ibd -t1#P#part_1.ibd -t1#P#part_2.ibd -t1#P#part_3.ibd -t1#P#part_N.ibd t1.frm t1.par @@ -13226,12 +13049,6 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta.ibd -t1#P#partb.ibd -t1#P#partc.ibd -t1#P#partd.ibd -t1#P#parte.ibd -t1#P#partf.ibd t1.frm t1.par @@ -13731,14 +13548,6 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta#SP#partasp0.ibd -t1#P#parta#SP#partasp1.ibd -t1#P#partb#SP#partbsp0.ibd -t1#P#partb#SP#partbsp1.ibd -t1#P#partc#SP#partcsp0.ibd -t1#P#partc#SP#partcsp1.ibd -t1#P#partd#SP#partdsp0.ibd -t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -14251,14 +14060,6 @@ SUBPARTITION BY KEY (f_int1) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#subpart11.ibd -t1#P#part1#SP#subpart12.ibd -t1#P#part2#SP#subpart21.ibd -t1#P#part2#SP#subpart22.ibd -t1#P#part3#SP#subpart31.ibd -t1#P#part3#SP#subpart32.ibd -t1#P#part4#SP#subpart41.ibd -t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -14773,14 +14574,6 @@ SUBPARTITION BY HASH (f_int1 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#sp11.ibd -t1#P#part1#SP#sp12.ibd -t1#P#part2#SP#sp21.ibd -t1#P#part2#SP#sp22.ibd -t1#P#part3#SP#sp31.ibd -t1#P#part3#SP#sp32.ibd -t1#P#part4#SP#sp41.ibd -t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -15281,15 +15074,6 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist -t1#P#part1#SP#part1sp0.ibd -t1#P#part1#SP#part1sp1.ibd -t1#P#part1#SP#part1sp2.ibd -t1#P#part2#SP#part2sp0.ibd -t1#P#part2#SP#part2sp1.ibd -t1#P#part2#SP#part2sp2.ibd -t1#P#part3#SP#part3sp0.ibd -t1#P#part3#SP#part3sp1.ibd -t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -15783,8 +15567,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd t1.frm t1.par @@ -16293,11 +16075,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd -t1#P#p2.ibd -t1#P#p3.ibd -t1#P#p4.ibd t1.frm t1.par @@ -16821,14 +16598,6 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist -t1#P#part0.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part3.ibd -t1#P#part_1.ibd -t1#P#part_2.ibd -t1#P#part_3.ibd -t1#P#part_N.ibd t1.frm t1.par @@ -17348,12 +17117,6 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta.ibd -t1#P#partb.ibd -t1#P#partc.ibd -t1#P#partd.ibd -t1#P#parte.ibd -t1#P#partf.ibd t1.frm t1.par @@ -17869,14 +17632,6 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta#SP#partasp0.ibd -t1#P#parta#SP#partasp1.ibd -t1#P#partb#SP#partbsp0.ibd -t1#P#partb#SP#partbsp1.ibd -t1#P#partc#SP#partcsp0.ibd -t1#P#partc#SP#partcsp1.ibd -t1#P#partd#SP#partdsp0.ibd -t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -18405,14 +18160,6 @@ SUBPARTITION BY KEY (f_int1) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#subpart11.ibd -t1#P#part1#SP#subpart12.ibd -t1#P#part2#SP#subpart21.ibd -t1#P#part2#SP#subpart22.ibd -t1#P#part3#SP#subpart31.ibd -t1#P#part3#SP#subpart32.ibd -t1#P#part4#SP#subpart41.ibd -t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -18943,14 +18690,6 @@ SUBPARTITION BY HASH (f_int1 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#sp11.ibd -t1#P#part1#SP#sp12.ibd -t1#P#part2#SP#sp21.ibd -t1#P#part2#SP#sp22.ibd -t1#P#part3#SP#sp31.ibd -t1#P#part3#SP#sp32.ibd -t1#P#part4#SP#sp41.ibd -t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -19467,15 +19206,6 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist -t1#P#part1#SP#part1sp0.ibd -t1#P#part1#SP#part1sp1.ibd -t1#P#part1#SP#part1sp2.ibd -t1#P#part2#SP#part2sp0.ibd -t1#P#part2#SP#part2sp1.ibd -t1#P#part2#SP#part2sp2.ibd -t1#P#part3#SP#part3sp0.ibd -t1#P#part3#SP#part3sp1.ibd -t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -19990,8 +19720,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd t1.frm t1.par @@ -20484,11 +20212,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd -t1#P#p2.ibd -t1#P#p3.ibd -t1#P#p4.ibd t1.frm t1.par @@ -20996,14 +20719,6 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist -t1#P#part0.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part3.ibd -t1#P#part_1.ibd -t1#P#part_2.ibd -t1#P#part_3.ibd -t1#P#part_N.ibd t1.frm t1.par @@ -21507,12 +21222,6 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta.ibd -t1#P#partb.ibd -t1#P#partc.ibd -t1#P#partd.ibd -t1#P#parte.ibd -t1#P#partf.ibd t1.frm t1.par @@ -22012,14 +21721,6 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta#SP#partasp0.ibd -t1#P#parta#SP#partasp1.ibd -t1#P#partb#SP#partbsp0.ibd -t1#P#partb#SP#partbsp1.ibd -t1#P#partc#SP#partcsp0.ibd -t1#P#partc#SP#partcsp1.ibd -t1#P#partd#SP#partdsp0.ibd -t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -22530,14 +22231,6 @@ SUBPARTITION BY KEY (f_int2) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#subpart11.ibd -t1#P#part1#SP#subpart12.ibd -t1#P#part2#SP#subpart21.ibd -t1#P#part2#SP#subpart22.ibd -t1#P#part3#SP#subpart31.ibd -t1#P#part3#SP#subpart32.ibd -t1#P#part4#SP#subpart41.ibd -t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -23048,14 +22741,6 @@ SUBPARTITION BY HASH (f_int2 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#sp11.ibd -t1#P#part1#SP#sp12.ibd -t1#P#part2#SP#sp21.ibd -t1#P#part2#SP#sp22.ibd -t1#P#part3#SP#sp31.ibd -t1#P#part3#SP#sp32.ibd -t1#P#part4#SP#sp41.ibd -t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -23556,15 +23241,6 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist -t1#P#part1#SP#part1sp0.ibd -t1#P#part1#SP#part1sp1.ibd -t1#P#part1#SP#part1sp2.ibd -t1#P#part2#SP#part2sp0.ibd -t1#P#part2#SP#part2sp1.ibd -t1#P#part2#SP#part2sp2.ibd -t1#P#part3#SP#part3sp0.ibd -t1#P#part3#SP#part3sp1.ibd -t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -24058,8 +23734,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd t1.frm t1.par @@ -24552,11 +24226,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd -t1#P#p2.ibd -t1#P#p3.ibd -t1#P#p4.ibd t1.frm t1.par @@ -25064,14 +24733,6 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist -t1#P#part0.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part3.ibd -t1#P#part_1.ibd -t1#P#part_2.ibd -t1#P#part_3.ibd -t1#P#part_N.ibd t1.frm t1.par @@ -25575,12 +25236,6 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta.ibd -t1#P#partb.ibd -t1#P#partc.ibd -t1#P#partd.ibd -t1#P#parte.ibd -t1#P#partf.ibd t1.frm t1.par @@ -26080,14 +25735,6 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta#SP#partasp0.ibd -t1#P#parta#SP#partasp1.ibd -t1#P#partb#SP#partbsp0.ibd -t1#P#partb#SP#partbsp1.ibd -t1#P#partc#SP#partcsp0.ibd -t1#P#partc#SP#partcsp1.ibd -t1#P#partd#SP#partdsp0.ibd -t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -26598,14 +26245,6 @@ SUBPARTITION BY KEY (f_int2) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#subpart11.ibd -t1#P#part1#SP#subpart12.ibd -t1#P#part2#SP#subpart21.ibd -t1#P#part2#SP#subpart22.ibd -t1#P#part3#SP#subpart31.ibd -t1#P#part3#SP#subpart32.ibd -t1#P#part4#SP#subpart41.ibd -t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -27116,14 +26755,6 @@ SUBPARTITION BY HASH (f_int2 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#sp11.ibd -t1#P#part1#SP#sp12.ibd -t1#P#part2#SP#sp21.ibd -t1#P#part2#SP#sp22.ibd -t1#P#part3#SP#sp31.ibd -t1#P#part3#SP#sp32.ibd -t1#P#part4#SP#sp41.ibd -t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -27624,15 +27255,6 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist -t1#P#part1#SP#part1sp0.ibd -t1#P#part1#SP#part1sp1.ibd -t1#P#part1#SP#part1sp2.ibd -t1#P#part2#SP#part2sp0.ibd -t1#P#part2#SP#part2sp1.ibd -t1#P#part2#SP#part2sp2.ibd -t1#P#part3#SP#part3sp0.ibd -t1#P#part3#SP#part3sp1.ibd -t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -28126,8 +27748,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd t1.frm t1.par @@ -28636,11 +28256,6 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist -t1#P#p0.ibd -t1#P#p1.ibd -t1#P#p2.ibd -t1#P#p3.ibd -t1#P#p4.ibd t1.frm t1.par @@ -29164,14 +28779,6 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist -t1#P#part0.ibd -t1#P#part1.ibd -t1#P#part2.ibd -t1#P#part3.ibd -t1#P#part_1.ibd -t1#P#part_2.ibd -t1#P#part_3.ibd -t1#P#part_N.ibd t1.frm t1.par @@ -29691,12 +29298,6 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta.ibd -t1#P#partb.ibd -t1#P#partc.ibd -t1#P#partd.ibd -t1#P#parte.ibd -t1#P#partf.ibd t1.frm t1.par @@ -30212,14 +29813,6 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist -t1#P#parta#SP#partasp0.ibd -t1#P#parta#SP#partasp1.ibd -t1#P#partb#SP#partbsp0.ibd -t1#P#partb#SP#partbsp1.ibd -t1#P#partc#SP#partcsp0.ibd -t1#P#partc#SP#partcsp1.ibd -t1#P#partd#SP#partdsp0.ibd -t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -30746,14 +30339,6 @@ SUBPARTITION BY KEY (f_int2) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#subpart11.ibd -t1#P#part1#SP#subpart12.ibd -t1#P#part2#SP#subpart21.ibd -t1#P#part2#SP#subpart22.ibd -t1#P#part3#SP#subpart31.ibd -t1#P#part3#SP#subpart32.ibd -t1#P#part4#SP#subpart41.ibd -t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -31280,14 +30865,6 @@ SUBPARTITION BY HASH (f_int2 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist -t1#P#part1#SP#sp11.ibd -t1#P#part1#SP#sp12.ibd -t1#P#part2#SP#sp21.ibd -t1#P#part2#SP#sp22.ibd -t1#P#part3#SP#sp31.ibd -t1#P#part3#SP#sp32.ibd -t1#P#part4#SP#sp41.ibd -t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -31804,15 +31381,6 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist -t1#P#part1#SP#part1sp0.ibd -t1#P#part1#SP#part1sp1.ibd -t1#P#part1#SP#part1sp2.ibd -t1#P#part2#SP#part2sp0.ibd -t1#P#part2#SP#part2sp1.ibd -t1#P#part2#SP#part2sp2.ibd -t1#P#part3#SP#part3sp0.ibd -t1#P#part3#SP#part3sp1.ibd -t1#P#part3#SP#part3sp2.ibd t1.frm t1.par From c8d7a31f35bc988362ec07c2e2520a0dc511eebe Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Fri, 8 Oct 2010 11:52:09 +0200 Subject: [PATCH 036/151] Bug#57209 valgrind + Assertion failed: dst > buf Buffer overrun when trying to format DBL_MAX mysql-test/r/func_math.result: Add test case for Bug#57209 mysql-test/t/func_math.test: Add test case for Bug#57209 sql/item_strfunc.cc: Allocate a larger buffer for the result. --- mysql-test/r/func_math.result | 7 +++++++ mysql-test/t/func_math.test | 6 ++++++ sql/item_strfunc.cc | 5 +++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index 307f1714132..bfb3af0afff 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -600,3 +600,10 @@ NULL SELECT -9223372036854775808 MOD -1; -9223372036854775808 MOD -1 0 +# +# Bug #57209 valgrind + Assertion failed: dst > buf +# +SELECT floor(log10(format(concat_ws(5445796E25, 5306463, 30837), -358821))) +as foo; +foo +2 diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index 44af2f5ad3f..efdf7201a40 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -458,3 +458,9 @@ SELECT 2 DIV -2; SELECT -(1 DIV 0); # Crashed the server with SIGFPE before the bugfix SELECT -9223372036854775808 MOD -1; + +--echo # +--echo # Bug #57209 valgrind + Assertion failed: dst > buf +--echo # +SELECT floor(log10(format(concat_ws(5445796E25, 5306463, 30837), -358821))) +as foo; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 6d3514bf356..89c1e785c71 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2299,7 +2299,8 @@ String *Item_func_format::val_str_ascii(String *str) if (lc->grouping[0] > 0 && str_length >= dec_length + 1 + lc->grouping[0]) { - char buf[DECIMAL_MAX_STR_LENGTH * 2]; /* 2 - in the worst case when grouping=1 */ + /* We need space for ',' between each group of digits as well. */ + char buf[2 * FLOATING_POINT_BUFFER]; int count; const char *grouping= lc->grouping; char sign_length= *str->ptr() == '-' ? 1 : 0; @@ -2323,7 +2324,7 @@ String *Item_func_format::val_str_ascii(String *str) count will be initialized to -1 and we'll never get into this "if" anymore. */ - if (!count) + if (count == 0) { *--dst= lc->thousand_sep; if (grouping[1]) From 15ccca1d5520eca44fd63925fdd2020428965985 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 8 Oct 2010 09:16:20 -0300 Subject: [PATCH 037/151] Bug#56822: Add a thread state for sessions waiting on the query cache lock Only wait for a single debug signal at a time as the signal state is global. Also, do not activate the query cache debug sync points if the thread has no associated THD session. mysql-test/t/query_cache_debug.test: Only wait for a single debug signal at a time as the signal state is global. sql/sql_cache.cc: Do not execute the debug sync point if the thread has no associated THD session. This scenario happens for federated threads. --- mysql-test/r/query_cache_debug.result | 14 +++++++++----- mysql-test/t/query_cache_debug.test | 16 +++++++++++----- sql/sql_cache.cc | 22 +++++++++++++++++++--- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/query_cache_debug.result b/mysql-test/r/query_cache_debug.result index 30996e5e86b..50a3a02fe4d 100644 --- a/mysql-test/r/query_cache_debug.result +++ b/mysql-test/r/query_cache_debug.result @@ -123,16 +123,20 @@ SET DEBUG_SYNC="now WAIT_FOR parked1_1"; ** On THD2: Insert a result into the cache. This attempt will be blocked ** because of a debug hook placed just before the mutex lock after which ** the first part of the result set is written. -SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2"; +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2 EXECUTE 1"; SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3; +=================================== Connection default +** Assert that the SELECT-stmt thread reaches the sync point. +SET DEBUG_SYNC="now WAIT_FOR parked2"; +** +** =================================== Connection thd3 ** On THD3: Insert another result into the cache and block on the same ** debug hook. -SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3"; -SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5;; +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3 EXECUTE 1"; +SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5; =================================== Connection default -** Assert that the two SELECT-stmt threads to reach the hook. -SET DEBUG_SYNC="now WAIT_FOR parked2"; +** Assert that the SELECT-stmt thread reaches the sync point. SET DEBUG_SYNC="now WAIT_FOR parked3"; ** ** diff --git a/mysql-test/t/query_cache_debug.test b/mysql-test/t/query_cache_debug.test index 77e714aa6f5..2f85813d1ef 100644 --- a/mysql-test/t/query_cache_debug.test +++ b/mysql-test/t/query_cache_debug.test @@ -170,20 +170,26 @@ connection thd2; --echo ** On THD2: Insert a result into the cache. This attempt will be blocked --echo ** because of a debug hook placed just before the mutex lock after which --echo ** the first part of the result set is written. -SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2"; +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2 EXECUTE 1"; --send SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3 +connection default; +--echo =================================== Connection default +--echo ** Assert that the SELECT-stmt thread reaches the sync point. +SET DEBUG_SYNC="now WAIT_FOR parked2"; +--echo ** +--echo ** + connection thd3; --echo =================================== Connection thd3 --echo ** On THD3: Insert another result into the cache and block on the same --echo ** debug hook. -SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3"; ---send SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5; +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3 EXECUTE 1"; +--send SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5 connection default; --echo =================================== Connection default ---echo ** Assert that the two SELECT-stmt threads to reach the hook. -SET DEBUG_SYNC="now WAIT_FOR parked2"; +--echo ** Assert that the SELECT-stmt thread reaches the sync point. SET DEBUG_SYNC="now WAIT_FOR parked3"; --echo ** --echo ** diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 8c3abdbf1b0..9876c46bbb3 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -384,6 +384,22 @@ TODO list: #endif +/** + Macro that executes the requested action at a synchronization point + only if the thread has a associated THD session. +*/ +#if defined(ENABLED_DEBUG_SYNC) +#define QC_DEBUG_SYNC(name) \ + do { \ + THD *thd= current_thd; \ + if (thd) \ + DEBUG_SYNC(thd, name); \ + } while (0) +#else +#define QC_DEBUG_SYNC(name) +#endif + + /** Thread state to be used when the query cache lock needs to be acquired. Sets the thread state name in the constructor, resets on destructor. @@ -879,7 +895,7 @@ Query_cache::insert(Query_cache_tls *query_cache_tls, if (is_disabled() || query_cache_tls->first_query_block == NULL) DBUG_VOID_RETURN; - DEBUG_SYNC(current_thd, "wait_in_query_cache_insert"); + QC_DEBUG_SYNC("wait_in_query_cache_insert"); if (try_lock()) DBUG_VOID_RETURN; @@ -1975,7 +1991,7 @@ void Query_cache::flush() if (is_disabled()) DBUG_VOID_RETURN; - DEBUG_SYNC(current_thd, "wait_in_query_cache_flush1"); + QC_DEBUG_SYNC("wait_in_query_cache_flush1"); lock_and_suspend(); if (query_cache_size > 0) @@ -2315,7 +2331,7 @@ void Query_cache::free_cache() void Query_cache::flush_cache() { - DEBUG_SYNC(current_thd, "wait_in_query_cache_flush2"); + QC_DEBUG_SYNC("wait_in_query_cache_flush2"); my_hash_reset(&queries); while (queries_blocks != 0) From 96daec35d1b639f5d0f87df295a932fb907c088f Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Fri, 8 Oct 2010 14:22:22 +0200 Subject: [PATCH 038/151] Bug #57338: Extreneous server variable thread_pool_size The server contained code for the server variable and option thread_pool_size, but this server variable where not used anywhere. The variable is probably remains from backporting too much from 6.0 (specifically, the thread pool implementation was not backported from 6.0, which this variable is associated with). This patch eliminates the variable from the server. --- sql/sys_vars.cc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index b8b73bc0387..5c9df82ddac 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2014,15 +2014,6 @@ static Sys_var_ulong Sys_thread_cache_size( GLOBAL_VAR(thread_cache_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 16384), DEFAULT(0), BLOCK_SIZE(1)); -#if HAVE_POOL_OF_THREADS == 1 -static Sys_var_ulong Sys_thread_pool_size( - "thread_pool_size", - "How many threads we should create to handle query requests in " - "case of 'thread_handling=pool-of-threads'", - GLOBAL_VAR(thread_pool_size), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(1, 16384), DEFAULT(20), BLOCK_SIZE(0)); -#endif - /** Can't change the 'next' tx_isolation if we are already in a transaction. From 0a9c39684e01038f4bde6adfab1860b92df684f8 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Fri, 8 Oct 2010 14:44:57 +0200 Subject: [PATCH 039/151] WL#5363: Thread Pool Service Interface Adding a comment to scheduler_types on the default values used. --- sql/scheduler.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sql/scheduler.h b/sql/scheduler.h index 40f0e28bc2c..b5a175434b6 100644 --- a/sql/scheduler.h +++ b/sql/scheduler.h @@ -57,6 +57,13 @@ struct scheduler_functions */ enum scheduler_types { + /* + The default of --thread-handling is the first one in the + thread_handling_names array, this array has to be consistent with + the order in this array, so to change default one has to change + the first entry in this enum and the first entry in the + thread_handling_names array. + */ SCHEDULER_ONE_THREAD_PER_CONNECTION=0, SCHEDULER_NO_THREADS, SCHEDULER_TYPES_COUNT From c192be206ae36398804b473f7b0e4ee4431b71da Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 8 Oct 2010 10:30:58 -0300 Subject: [PATCH 040/151] Bug#42733: Type-punning warnings when compiling MySQL -- strict aliasing violations. Due to the extent of aliasing violations in the MySQL source code, at this time it is safer to disable strict aliasing related optimizations in release builds. As of this patch, only GCC enables strict aliasing by default. Hence, use the -fno-strict-aliasing option to disable the aliasing rules. cmake/build_configurations/mysql_release.cmake: Add -fno-strict-aliasing to release builds. --- cmake/build_configurations/mysql_release.cmake | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index 9d010ef7f2a..48d3765ea67 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -131,16 +131,16 @@ IF(UNIX) # Default GCC flags IF(CMAKE_COMPILER_IS_GNUCC) - SET(COMMON_C_FLAGS "-g -static-libgcc -fno-omit-frame-pointer") + SET(COMMON_C_FLAGS "-g -static-libgcc -fno-omit-frame-pointer -fno-strict-aliasing") SET(CMAKE_C_FLAGS_DEBUG "-O ${COMMON_C_FLAGS}") SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 ${COMMON_C_FLAGS}") ENDIF() IF(CMAKE_COMPILER_IS_GNUCXX) - SET(COMMON_CXX_FLAGS "-g -static-libgcc -fno-omit-frame-pointer") + SET(COMMON_CXX_FLAGS "-g -static-libgcc -fno-omit-frame-pointer -fno-strict-aliasing") SET(CMAKE_CXX_FLAGS_DEBUG "-O ${COMMON_CXX_FLAGS}") SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 ${COMMON_CXX_FLAGS}") ENDIF() - + # HPUX flags IF(CMAKE_SYSTEM_NAME MATCHES "HP-UX") IF(CMAKE_C_COMPILER_ID MATCHES "HP") @@ -156,7 +156,7 @@ IF(UNIX) ENDIF() SET(WITH_SSL no) ENDIF() - + # Linux flags IF(CMAKE_SYSTEM_NAME MATCHES "Linux") IF(CMAKE_C_COMPILER_ID MATCHES "Intel") @@ -173,18 +173,18 @@ IF(UNIX) SET(WITH_SSL no) ENDIF() ENDIF() - + # OSX flags IF(APPLE) - SET(COMMON_C_FLAGS "-g -fno-common") + SET(COMMON_C_FLAGS "-g -fno-common -fno-strict-aliasing") # XXX: why are we using -felide-constructors on OSX? - SET(COMMON_CXX_FLAGS "-g -fno-common -felide-constructors") + SET(COMMON_CXX_FLAGS "-g -fno-common -felide-constructors -fno-strict-aliasing") SET(CMAKE_C_FLAGS_DEBUG "-O ${COMMON_C_FLAGS}") SET(CMAKE_CXX_FLAGS_DEBUG "-O ${COMMON_CXX_FLAGS}") SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os ${COMMON_C_FLAGS}") SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Os ${COMMON_CXX_FLAGS}") ENDIF() - + # Solaris flags IF(CMAKE_SYSTEM_NAME MATCHES "SunOS") IF(CMAKE_SYSTEM_VERSION VERSION_GREATER "5.9") @@ -219,7 +219,7 @@ IF(UNIX) ENDIF() ENDIF() ENDIF() - + IF(CMAKE_C_FLAGS_DEBUG) SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}" CACHE STRING "Debug C compile flags") From 3fdcf2060d85a14f39b59f9e59e3e2f842f2f8a5 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 8 Oct 2010 18:06:31 +0400 Subject: [PATCH 041/151] The fix for Bug#55744 GROUP_CONCAT + CASE + ucs return garbage revealed problems in how character set aggregation code works with prepared statements. This patch fixes (hopefully) the problems. --- sql/item.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index fff7511015f..b166f3e645f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1783,8 +1783,7 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname, In case we're in statement prepare, create conversion item in its memory: it will be reused on each execute. */ - arena= thd->is_stmt_prepare() ? thd->activate_stmt_arena_if_needed(&backup) - : NULL; + arena= thd->activate_stmt_arena_if_needed(&backup); for (i= 0, arg= args; i < nargs; i++, arg+= item_sep) { From f60106f82db102dd8e5161de6dea48c940e39efe Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 8 Oct 2010 11:52:39 -0300 Subject: [PATCH 042/151] Bug#45288: pb2 returns a lot of compilation warnings on linux Fix assorted compiler warnings. sql/mysqld.cc: Do not declare max_page_size twice. If large pages support is enabled, the code expects the size in max_desired_page_size. storage/innobase/include/ibuf0ibuf.h: Remove trailing comma. Only present in C99. Approved by: Vasil (via IRC) storage/innobase/include/row0row.h: Remove trailing comma. Only present in C99. Approved by: Vasil (via IRC) strings/my_vsnprintf.c: No need to assert the obvious. --- sql/mysqld.cc | 7 +++---- storage/innobase/include/ibuf0ibuf.h | 2 +- storage/innobase/include/row0row.h | 2 +- strings/my_vsnprintf.c | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e489d466d5f..99754e8b7f6 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3244,12 +3244,11 @@ static int init_common_variables() desired page sizes. */ int nelem; - int max_desired_page_size; - int max_page_size; + size_t max_desired_page_size; if (opt_super_large_pages) - max_page_size= SUPER_LARGE_PAGESIZE; + max_desired_page_size= SUPER_LARGE_PAGESIZE; else - max_page_size= LARGE_PAGESIZE; + max_desired_page_size= LARGE_PAGESIZE; nelem = getpagesizes(NULL, 0); if (nelem > 0) { diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h index 0f1631fde77..4bb59be6a3e 100644 --- a/storage/innobase/include/ibuf0ibuf.h +++ b/storage/innobase/include/ibuf0ibuf.h @@ -43,7 +43,7 @@ typedef enum { IBUF_OP_DELETE = 2, /* Number of different operation types. */ - IBUF_OP_COUNT = 3, + IBUF_OP_COUNT = 3 } ibuf_op_t; /** Combinations of operations that can be buffered. Because the enum diff --git a/storage/innobase/include/row0row.h b/storage/innobase/include/row0row.h index 195691a420b..110525ecfed 100644 --- a/storage/innobase/include/row0row.h +++ b/storage/innobase/include/row0row.h @@ -267,7 +267,7 @@ enum row_search_result { secondary index leaf page was not in the buffer pool, and the operation was enqueued in the insert/delete buffer */ - ROW_NOT_DELETED_REF, /*!< BTR_DELETE was specified, and + ROW_NOT_DELETED_REF /*!< BTR_DELETE was specified, and row_purge_poss_sec() failed */ }; diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index 1284203f739..e9786dacfdc 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -513,7 +513,7 @@ start: arg_count= max(arg_count, arg_index); goto start; } - DBUG_ASSERT(0); + return 0; } From 10812c0782da89df87843ea37f7ef3cef193e725 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 9 Oct 2010 15:05:43 +0800 Subject: [PATCH 043/151] Bug#55375 Transaction bigger than max_binlog_cache_size crashes slave When slave executes a transaction bigger than slave's max_binlog_cache_size, slave will crash. It is caused by the assert that server should only roll back the statement but not the whole transaction if the error ER_TRANS_CACHE_FULL happens. But slave sql thread always rollbacks the whole transaction when an error happens. Ather this patch, we always clear any error set in sql thread(it is different from the error in 'SHOW SLAVE STATUS') and it is cleared before rolling back the transaction. mysql-test/suite/rpl/r/rpl_binlog_max_cache_size.result: SET binlog_cache_size and max_binlog_cache_size for all test cases. Add test case for bug#55375. mysql-test/suite/rpl/t/rpl_binlog_max_cache_size-master.opt: binlog_cache_size and max_binlog_cache_size can be set in the client connection. so remove this option file. mysql-test/suite/rpl/t/rpl_binlog_max_cache_size.test: SET binlog_cache_size and max_binlog_cache_size for all test cases. Add test case for bug#55375. sql/log_event.cc: Some functions don't return the error code, so it is a wrong error code. The error should always be set into thd->main_da. So we use slave_rows_error_report to report the right error. sql/slave.cc: exec_relay_log_event() need call cleanup_context() to clear context. clearup_context() will call end_trans(). Clear thd's error before cleanup_context. It avoid to trigger the assert which cause this bug. --- .../rpl/r/rpl_binlog_max_cache_size.result | 47 ++++++-- .../t/rpl_binlog_max_cache_size-master.opt | 1 - .../rpl/t/rpl_binlog_max_cache_size.test | 105 ++++++++++++++---- sql/log_event.cc | 40 +++---- sql/slave.cc | 3 +- 5 files changed, 144 insertions(+), 52 deletions(-) delete mode 100644 mysql-test/suite/rpl/t/rpl_binlog_max_cache_size-master.opt diff --git a/mysql-test/suite/rpl/r/rpl_binlog_max_cache_size.result b/mysql-test/suite/rpl/r/rpl_binlog_max_cache_size.result index 0e3f83d0aa5..f9e492db6bc 100644 --- a/mysql-test/suite/rpl/r/rpl_binlog_max_cache_size.result +++ b/mysql-test/suite/rpl/r/rpl_binlog_max_cache_size.result @@ -4,6 +4,8 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam; CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; @@ -15,11 +17,14 @@ Got one of the listed errors *** Single statement on non-transactional table *** *** After WL#2687 the difference between STATEMENT/MIXED and ROW will not exist. *** Got one of the listed errors +--source include/wait_for_slave_sql_error_and_skip.inc +include/start_slave.inc *** Single statement on both transactional and non-transactional tables. *** *** After WL#2687 we will be able to change the order of the tables. *** Got one of the listed errors -SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -START SLAVE SQL_THREAD; +--source include/wait_for_slave_sql_error_and_skip.inc +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +include/start_slave.inc TRUNCATE TABLE t1; TRUNCATE TABLE t2; TRUNCATE TABLE t3; @@ -116,6 +121,37 @@ COMMIT; BEGIN; Got one of the listed errors COMMIT; +--source include/wait_for_slave_sql_error_and_skip.inc +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +include/start_slave.inc +######################################################################## +# 8 - Bug#55375(Regression Bug) Transaction bigger than +# max_binlog_cache_size crashes slave +######################################################################## +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; +include/stop_slave.inc +include/start_slave.inc +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*"); +TRUNCATE t1; +SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +BEGIN; +Repeat statement 'INSERT INTO t1 VALUES($n, repeat("a", 32))' 128 times +COMMIT; +SELECT count(*) FROM t1; +count(*) +0 +show binlog events in 'slave-bin.000001' from ; +Log_name Pos Event_type Server_id End_log_pos Info +SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +include/stop_slave.inc +include/start_slave.inc +SELECT count(*) FROM t1; +count(*) +128 ######################################################################################## # CLEAN ######################################################################################## @@ -126,10 +162,3 @@ DROP TABLE IF EXISTS t4; DROP TABLE IF EXISTS t5; DROP TABLE IF EXISTS t6; DROP PROCEDURE p1; -DROP TABLE t1; -DROP TABLE t2; -DROP TABLE t3; -DROP TABLE IF EXISTS t4; -DROP TABLE IF EXISTS t5; -DROP TABLE IF EXISTS t6; -DROP PROCEDURE p1; diff --git a/mysql-test/suite/rpl/t/rpl_binlog_max_cache_size-master.opt b/mysql-test/suite/rpl/t/rpl_binlog_max_cache_size-master.opt deleted file mode 100644 index 45631525481..00000000000 --- a/mysql-test/suite/rpl/t/rpl_binlog_max_cache_size-master.opt +++ /dev/null @@ -1 +0,0 @@ ---binlog_cache_size=4096 --max_binlog_cache_size=7680 diff --git a/mysql-test/suite/rpl/t/rpl_binlog_max_cache_size.test b/mysql-test/suite/rpl/t/rpl_binlog_max_cache_size.test index e1f1f8c54bb..9dca61d8f75 100644 --- a/mysql-test/suite/rpl/t/rpl_binlog_max_cache_size.test +++ b/mysql-test/suite/rpl/t/rpl_binlog_max_cache_size.test @@ -30,6 +30,16 @@ --source include/not_embedded.inc --source include/not_windows.inc +let $old_max_binlog_cache_size= query_get_value(SHOW VARIABLES LIKE "max_binlog_cache_size", Value, 1); +let $old_binlog_cache_size= query_get_value(SHOW VARIABLES LIKE "binlog_cache_size", Value, 1); + +SET GLOBAL max_binlog_cache_size = 4096; +# Becuase of bug#55377, we have to set binlog_cache_size until the bug is +# fixed. +SET GLOBAL binlog_cache_size = 4096; +disconnect master; +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); + CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam; CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; @@ -57,25 +67,23 @@ if (`SELECT @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`) { eval INSERT INTO t2 (a, data) VALUES (2, CONCAT($data, $data, $data, $data, $data, $data)); + # Below code fakes the result of 'ROW' mode. --echo Got one of the listed errors + --echo --source include/wait_for_slave_sql_error_and_skip.inc + --echo include/start_slave.inc } if (`SELECT @@binlog_format = 'ROW'`) { --error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE eval INSERT INTO t2 (a, data) VALUES (2, CONCAT($data, $data, $data, $data, $data, $data)); - - connection slave; - --source include/wait_for_slave_sql_to_stop.inc - SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; - START SLAVE SQL_THREAD; - --source include/wait_for_slave_sql_to_start.inc + # Incident event + --let $slave_sql_errno=1590 + --source include/wait_for_slave_sql_error_and_skip.inc } --enable_warnings --enable_query_log -connection master; - --disable_query_log eval INSERT INTO t1 (a, data) VALUES (3, $data); eval INSERT INTO t1 (a, data) VALUES (4, $data); @@ -93,11 +101,9 @@ eval UPDATE t2, t1 SET t2.data = CONCAT($data, $data, $data, $data), t1.data = CONCAT($data, $data, $data, $data); --enable_query_log -connection slave; ---source include/wait_for_slave_sql_to_stop.inc -SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -START SLAVE SQL_THREAD; ---source include/wait_for_slave_sql_to_start.inc +# Incident event +--let $slave_sql_errno=1590 +--source include/wait_for_slave_sql_error_and_skip.inc #--echo ######################################################################################## #--echo # 2 - BEGIN - IMPLICIT COMMIT by DDL @@ -368,8 +374,70 @@ BEGIN; --enable_query_log COMMIT; +# Incident event +--let $slave_sql_errno=1590 +--source include/wait_for_slave_sql_error_and_skip.inc + +sync_slave_with_master; + +--echo ######################################################################## +--echo # 8 - Bug#55375(Regression Bug) Transaction bigger than +--echo # max_binlog_cache_size crashes slave +--echo ######################################################################## + +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; + +source include/stop_slave.inc; +source include/start_slave.inc; +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*"); + +connection master; +TRUNCATE t1; + +sync_slave_with_master; +--let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1) +--let binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) + +connection master; +--replace_result $old_max_binlog_cache_size ORIGINAL_VALUE +--eval SET GLOBAL max_binlog_cache_size= $old_max_binlog_cache_size +--replace_result $old_binlog_cache_size ORIGINAL_VALUE +--eval SET GLOBAL binlog_cache_size= $old_binlog_cache_size +disconnect master; +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); + +--let $n=128 +BEGIN; +--disable_query_log +--echo Repeat statement 'INSERT INTO t1 VALUES(\$n, repeat("a", 32))' $n times +while ($n) +{ + --eval INSERT INTO t1 VALUES ($n, repeat("a", 32)) + --dec $n +} +--enable_query_log +COMMIT; + connection slave; ---source include/wait_for_slave_sql_to_stop.inc +--let $slave_sql_errno= 1197 +source include/wait_for_slave_sql_error.inc; + +SELECT count(*) FROM t1; +source include/show_binlog_events.inc; + +--replace_result $old_max_binlog_cache_size ORIGINAL_VALUE +--eval SET GLOBAL max_binlog_cache_size= $old_max_binlog_cache_size +--replace_result $old_binlog_cache_size ORIGINAL_VALUE +--eval SET GLOBAL binlog_cache_size= $old_binlog_cache_size + +source include/stop_slave.inc; +source include/start_slave.inc; + +connection master; +sync_slave_with_master; +SELECT count(*) FROM t1; --echo ######################################################################################## --echo # CLEAN @@ -384,12 +452,5 @@ DROP TABLE IF EXISTS t4; DROP TABLE IF EXISTS t5; DROP TABLE IF EXISTS t6; DROP PROCEDURE p1; -connection slave; -DROP TABLE t1; -DROP TABLE t2; -DROP TABLE t3; -DROP TABLE IF EXISTS t4; -DROP TABLE IF EXISTS t5; -DROP TABLE IF EXISTS t6; -DROP PROCEDURE p1; --enable_warnings +source include/master-slave-end.inc; diff --git a/sql/log_event.cc b/sql/log_event.cc index 7becdf51747..e3ce216ab70 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -144,16 +144,21 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error, len= my_snprintf(slider, buff_end - slider, " %s, Error_code: %d;", err->msg, err->code); } - - rli->report(level, thd->is_error()? thd->main_da.sql_errno() : 0, - "Could not execute %s event on table %s.%s;" - "%s handler error %s; " - "the event's master log %s, end_log_pos %lu", - type, table->s->db.str, - table->s->table_name.str, - buff, - handler_error == NULL? "" : handler_error, - log_name, pos); + + if (ha_error != 0) + rli->report(level, thd->is_error() ? thd->main_da.sql_errno() : 0, + "Could not execute %s event on table %s.%s;" + "%s handler error %s; " + "the event's master log %s, end_log_pos %lu", + type, table->s->db.str, table->s->table_name.str, + buff, handler_error == NULL ? "" : handler_error, + log_name, pos); + else + rli->report(level, thd->is_error() ? thd->main_da.sql_errno() : 0, + "Could not execute %s event on table %s.%s;" + "%s the event's master log %s, end_log_pos %lu", + type, table->s->db.str, table->s->table_name.str, + buff, log_name, pos); } #endif @@ -7649,7 +7654,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) get_type_str(), RPL_LOG_NAME, (ulong) log_pos); thd->reset_current_stmt_binlog_row_based(); - const_cast(rli)->cleanup_context(thd, error); thd->is_slave_error= 1; DBUG_RETURN(error); } @@ -7680,14 +7684,12 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) const_cast(rli)->last_event_start_time= my_time(0); } - if (get_flags(STMT_END_F)) - if ((error= rows_event_stmt_cleanup(rli, thd))) - rli->report(ERROR_LEVEL, error, - "Error in %s event: commit of row events failed, " - "table `%s`.`%s`", - get_type_str(), m_table->s->db.str, - m_table->s->table_name.str); - + if (get_flags(STMT_END_F) && (error= rows_event_stmt_cleanup(rli, thd))) + slave_rows_error_report(ERROR_LEVEL, + thd->is_error() ? 0 : error, + rli, thd, table, + get_type_str(), + RPL_LOG_NAME, (ulong) log_pos); DBUG_RETURN(error); } diff --git a/sql/slave.cc b/sql/slave.cc index f1e0962e7e8..353d4913208 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2343,7 +2343,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli) else { exec_res= 0; - end_trans(thd, ROLLBACK); + rli->cleanup_context(thd, 1); /* chance for concurrent connection to get more locks */ safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE), (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli); @@ -3158,6 +3158,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ request is detected only by the present function, not by events), so we must "proactively" clear playgrounds: */ + thd->clear_error(); rli->cleanup_context(thd, 1); /* Some extra safety, which should not been needed (normally, event deletion From f40acd9a0ed0336ccc8c0fc189e420dad053baf1 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Oct 2010 10:49:00 +0800 Subject: [PATCH 044/151] Postfix for BUG#55375 Removed option file and changed result file. --- .../r/rpl_mixed_binlog_max_cache_size.result | 42 ++++++++++++++++--- ...rpl_mixed_binlog_max_cache_size-master.opt | 1 - 2 files changed, 37 insertions(+), 6 deletions(-) delete mode 100644 mysql-test/suite/rpl/t/rpl_mixed_binlog_max_cache_size-master.opt diff --git a/mysql-test/suite/rpl/r/rpl_mixed_binlog_max_cache_size.result b/mysql-test/suite/rpl/r/rpl_mixed_binlog_max_cache_size.result index 1ad34fbe961..479caed8e6b 100644 --- a/mysql-test/suite/rpl/r/rpl_mixed_binlog_max_cache_size.result +++ b/mysql-test/suite/rpl/r/rpl_mixed_binlog_max_cache_size.result @@ -5,6 +5,8 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam; CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; @@ -15,13 +17,14 @@ CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; Got one of the listed errors *** Single statement on non-transactional table *** Got one of the listed errors -SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -START SLAVE SQL_THREAD; +--source include/wait_for_slave_sql_error_and_skip.inc +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +include/start_slave.inc *** Single statement on both transactional and non-transactional tables. *** Got one of the listed errors -SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -START SLAVE SQL_THREAD; -source include/diff_master_slave.inc; +--source include/wait_for_slave_sql_error_and_skip.inc +SET GLOBAL SQL_SLAVE_SKIP_COUNTER= 1; +include/start_slave.inc ######################################################################################## # 2 - BEGIN - IMPLICIT COMMIT by DDL ######################################################################################## @@ -119,6 +122,35 @@ BEGIN; Got one of the listed errors COMMIT; source include/diff_master_slave.inc; +######################################################################## +# 8 - Bug#55375(Regression Bug) Transaction bigger than +# max_binlog_cache_size crashes slave +######################################################################## +# [ On Slave ] +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; +include/stop_slave.inc +include/start_slave.inc +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*"); +TRUNCATE t1; +SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +BEGIN; +Repeat statement 'INSERT INTO t1 VALUES($n, repeat("a", 32))' 128 times +COMMIT; +SELECT count(*) FROM t1; +count(*) +0 +show binlog events in 'slave-bin.000001' from ; +Log_name Pos Event_type Server_id End_log_pos Info +SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +include/stop_slave.inc +include/start_slave.inc +SELECT count(*) FROM t1; +count(*) +128 ######################################################################################## # CLEAN ######################################################################################## diff --git a/mysql-test/suite/rpl/t/rpl_mixed_binlog_max_cache_size-master.opt b/mysql-test/suite/rpl/t/rpl_mixed_binlog_max_cache_size-master.opt deleted file mode 100644 index 45631525481..00000000000 --- a/mysql-test/suite/rpl/t/rpl_mixed_binlog_max_cache_size-master.opt +++ /dev/null @@ -1 +0,0 @@ ---binlog_cache_size=4096 --max_binlog_cache_size=7680 From 42f8d2f249ea4d0acc2fdd7c03b3ea9d44f92027 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Oct 2010 11:08:49 +0800 Subject: [PATCH 045/151] Bug#56226 Table map set to 0 after altering MyISAM table After ALTER TABLE which changed only table's metadata, row-based binlog sometimes got corrupted since the tablemap was unexpectedly set to 0 for subsequent updates to the same table. ALTER TABLE which changed only table's metadata always reset table_map_id for the table share to 0. Despite the fact that 0 is a valid value for table_map_id, this step caused problems as it could have created situation in which we had more than one table share with table_map_id equal 0. If more than one table with table_map_id are 0 were updated in the same statement, updates to these different tables were written into the same rows event. This caused slave server to crash. This bug happens only on 5.1. It doesn't affect 5.5+. This patch solves this problem by ensuring that ALTER TABLE statements which change metadata only never reset table_map_id to 0. To do this it changes reopen_table() to correctly use refreshed table_map_id value instead of using the old one/ resetting it. mysql-test/suite/rpl/r/rpl_alter.result: Add test for BUG#56226 mysql-test/suite/rpl/t/rpl_alter.test: Add test for BUG#56226 --- mysql-test/suite/rpl/r/rpl_alter.result | 20 +++++++++ mysql-test/suite/rpl/t/rpl_alter.test | 59 ++++++++++++++++++++++--- sql/sql_base.cc | 2 - 3 files changed, 73 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_alter.result b/mysql-test/suite/rpl/r/rpl_alter.result index 6ef5ce3462a..cedb6854239 100644 --- a/mysql-test/suite/rpl/r/rpl_alter.result +++ b/mysql-test/suite/rpl/r/rpl_alter.result @@ -19,3 +19,23 @@ select * from mysqltest.t3; n 45 drop database mysqltest; + +# BUG#56226 Table map set to 0 after altering MyISAM table + +SET SESSION binlog_format='ROW'; +USE test; +CREATE TABLE t1 (a INT, b INT) ENGINE MyISAM; +CREATE TABLE t2 (a VARCHAR(255), b VARCHAR(255)) ENGINE MyISAM; +CREATE TRIGGER trg_t1ai +AFTER INSERT ON t1 FOR EACH ROW +BEGIN +INSERT INTO t2 (a) VALUES (NEW.a); +END;// +ALTER TABLE t1 CHANGE b c INT; +ALTER TABLE t2 CHANGE b c VARCHAR(255); + +INSERT INTO t1 (a) VALUES(2); +Comparing tables master:test.t1 and slave:test.t1 +Comparing tables master:test.t2 and slave:test.t2 + +DROP TABLE t1, t2; diff --git a/mysql-test/suite/rpl/t/rpl_alter.test b/mysql-test/suite/rpl/t/rpl_alter.test index 576376a0264..bc42476244a 100644 --- a/mysql-test/suite/rpl/t/rpl_alter.test +++ b/mysql-test/suite/rpl/t/rpl_alter.test @@ -10,15 +10,62 @@ insert into mysqltest.t1 values (1,2); create table mysqltest.t2 (n int); insert into mysqltest.t2 values (45); rename table mysqltest.t2 to mysqltest.t3, mysqltest.t1 to mysqltest.t2; -save_master_pos; -connection slave; -sync_with_master; + +sync_slave_with_master; select * from mysqltest.t2; select * from mysqltest.t3; + connection master; drop database mysqltest; -save_master_pos; -connection slave; -sync_with_master; +sync_slave_with_master; +--echo +--echo # BUG#56226 Table map set to 0 after altering MyISAM table +--echo +connection master; +SET SESSION binlog_format='ROW'; +USE test; + +CREATE TABLE t1 (a INT, b INT) ENGINE MyISAM; +CREATE TABLE t2 (a VARCHAR(255), b VARCHAR(255)) ENGINE MyISAM; + +--delimiter // +CREATE TRIGGER trg_t1ai + AFTER INSERT ON t1 FOR EACH ROW +BEGIN + INSERT INTO t2 (a) VALUES (NEW.a); +END;// +--delimiter ; + +ALTER TABLE t1 CHANGE b c INT; +ALTER TABLE t2 CHANGE b c VARCHAR(255); +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +INSERT INTO t1 (a) VALUES(2); +let _info= query_get_value(SHOW BINLOG EVENTS IN '$binlog_file' FROM $binlog_start, Info, 2); +# Table map id should not be 0. +if (`SELECT 'table_id: 0 (test.t1)' = '$_info'`) +{ + --echo test.t1's table map id is 0; + --die test.t1's table map id is 0; +} +let _info= query_get_value(SHOW BINLOG EVENTS IN '$binlog_file' FROM $binlog_start, Info, 3); +if (`SELECT 'table_id: 0 (test.t2)' = '$_info'`) +{ + --echo test.t2's table map id is 0; + --die test.t2's table map id is 0; +} + +let diff_table= test.t1; +source include/rpl_diff_tables.inc; +let diff_table= test.t2; +source include/rpl_diff_tables.inc; + +--echo +connection master; +DROP TABLE t1, t2; + +source include/master-slave-end.inc; # End of 4.1 tests diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c38526a6d0b..3766ff18293 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3082,8 +3082,6 @@ bool reopen_table(TABLE *table) tmp.maybe_null= table->maybe_null; tmp.status= table->status; - tmp.s->table_map_id= table->s->table_map_id; - /* Get state */ tmp.in_use= thd; tmp.reginfo.lock_type=table->reginfo.lock_type; From 86de24edee2db6b1c3f29f197ba4972b0e4f5acf Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Mon, 11 Oct 2010 15:50:14 +0100 Subject: [PATCH 046/151] Fix for crash in mysqld --verbose --help while initializing option for --init-rpl-role. Problem: There are two variables involved in this issue, rpl_status and rpl_role_type. The former is an array containing the description of the possible values for the latter. rpl_status is declared as an enumeration and is stored in a 4 bytes integer. On the other hand, my_getopt, reads enum values into a ulong: *(ulong*)value= arg; This is overwriting the memory used for rpl_role_type, corrupting the first entry in the array. Fix: We fix this by re-declaring rpl_status as a ulong, so that it has space to accommodate the value "parsed" in my_getopt . --- sql/repl_failsafe.cc | 4 ++-- sql/repl_failsafe.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 47eb2f7031d..540b62b9d3b 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -41,7 +41,7 @@ #define SLAVE_ERRMSG_SIZE (FN_REFLEN+64) -RPL_STATUS rpl_status=RPL_NULL; +ulong rpl_status=RPL_NULL; mysql_mutex_t LOCK_rpl_status; mysql_cond_t COND_rpl_status; HASH slave_list; @@ -68,7 +68,7 @@ static Slave_log_event* find_slave_event(IO_CACHE* log, functions like register_slave()) are working. */ -void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status) +void change_rpl_status(ulong from_status, ulong to_status) { mysql_mutex_lock(&LOCK_rpl_status); if (rpl_status == from_status || rpl_status == RPL_ANY) diff --git a/sql/repl_failsafe.h b/sql/repl_failsafe.h index c6d00de47cb..a0c41686696 100644 --- a/sql/repl_failsafe.h +++ b/sql/repl_failsafe.h @@ -26,7 +26,7 @@ typedef enum {RPL_AUTH_MASTER=0,RPL_IDLE_SLAVE,RPL_ACTIVE_SLAVE, RPL_LOST_SOLDIER,RPL_TROOP_SOLDIER, RPL_RECOVERY_CAPTAIN,RPL_NULL /* inactive */, RPL_ANY /* wild card used by change_rpl_status */ } RPL_STATUS; -extern RPL_STATUS rpl_status; +extern ulong rpl_status; extern mysql_mutex_t LOCK_rpl_status; extern mysql_cond_t COND_rpl_status; @@ -34,7 +34,7 @@ extern TYPELIB rpl_role_typelib; extern const char* rpl_role_type[], *rpl_status_type[]; pthread_handler_t handle_failsafe_rpl(void *arg); -void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status); +void change_rpl_status(ulong from_status, ulong to_status); int find_recovery_captain(THD* thd, MYSQL* mysql); int update_slave_list(MYSQL* mysql, Master_info* mi); From 10bc97de5c819eb8f89b98504724251bd854b78d Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 11 Oct 2010 19:44:35 +0200 Subject: [PATCH 047/151] Do not accept invalid INSTALL_LAYOUT parameter --- cmake/install_layout.cmake | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index ade6cdb747f..fcc1a2054b1 100644 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -59,13 +59,16 @@ # - INSTALL_SUPPORTFILESDIR (various extra support files) # # - INSTALL_MYSQLDATADIR (data directory) +# +# When changing this page, _please_ do not forget to update public Wiki +# http://forge.mysql.com/wiki/CMake#Fine-tuning_installation_paths IF(NOT INSTALL_LAYOUT) SET(DEFAULT_INSTALL_LAYOUT "STANDALONE") ENDIF() SET(INSTALL_LAYOUT "${DEFAULT_INSTALL_LAYOUT}" -CACHE STRING "Installation directory layout. Options are: STANDALONE (as in zip or tar.gz installer) or UNIX") +CACHE STRING "Installation directory layout. Options are: STANDALONE (as in zip or tar.gz installer), RPM, DEB, SVR4") IF(UNIX) IF(INSTALL_LAYOUT MATCHES "RPM") @@ -83,6 +86,13 @@ IF(UNIX) SET(CMAKE_INSTALL_PREFIX ${default_prefix} CACHE PATH "install prefix" FORCE) ENDIF() + SET(VALID_INSTALL_LAYOUTS "RPM" "STANDALONE" "DEB" "SVR5") + LIST(FIND VALID_INSTALL_LAYOUTS "${INSTALL_LAYOUT}" ind) + IF(ind EQUAL -1) + MESSAGE(FATAL_ERROR "Invalid INSTALL_LAYOUT parameter:${INSTALL_LAYOUT}." + " Choose between ${VALID_INSTALL_LAYOUTS}" ) + ENDIF() + SET(SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/etc" CACHE PATH "config directory (for my.cnf)") MARK_AS_ADVANCED(SYSCONFDIR) From de3d279372527ed028524933817269218e102a21 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Tue, 12 Oct 2010 14:07:13 +0400 Subject: [PATCH 048/151] Fix compilation warnings. --- sql-common/client.c | 2 +- sql/sql_acl.cc | 2 +- sql/sql_cache.cc | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sql-common/client.c b/sql-common/client.c index 0a30ef150e1..e8ca74eba37 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -2923,7 +2923,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, uint port, const char *unix_socket,ulong client_flag) { char buff[NAME_LEN+USERNAME_LENGTH+100]; - int scramble_data_len, pkt_scramble_len; + int scramble_data_len, pkt_scramble_len= 0; char *end,*host_info= 0, *server_version_end, *pkt_end; char *scramble_data; const char *scramble_plugin; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 571a7890116..5583e9a29f1 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3936,7 +3936,7 @@ bool mysql_grant(THD *thd, const char *db, List &list, ulong rights, bool revoke_grant, bool is_proxy) { List_iterator str_list (list); - LEX_USER *Str, *tmp_Str, *proxied_user; + LEX_USER *Str, *tmp_Str, *proxied_user= NULL; char tmp_db[NAME_LEN+1]; bool create_new_users=0; TABLE_LIST tables[2]; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 9876c46bbb3..0dadc0f0cd4 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -412,7 +412,8 @@ struct Query_cache_wait_state Query_cache_wait_state(THD *thd, const char *func, const char *file, unsigned int line) - : m_thd(thd) + : m_thd(thd), + m_proc_info(NULL) { if (m_thd) m_proc_info= set_thd_proc_info(m_thd, From 0e1dd99c71360d6a7c9af6cdf7f9929e79758f80 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Tue, 12 Oct 2010 14:07:49 +0400 Subject: [PATCH 049/151] Remove NDB test suites from default-test-suites in MTR. --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index baf179a4ae6..88719ff5bb2 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -162,7 +162,7 @@ our $opt_vs_config = $ENV{'MTR_VS_CONFIG'}; # If you add a new suite, please check TEST_DIRS in Makefile.am. # -my $DEFAULT_SUITES= "main,sys_vars,binlog,federated,rpl,rpl_ndb,ndb,innodb,perfschema"; +my $DEFAULT_SUITES= "main,sys_vars,binlog,federated,rpl,innodb,perfschema"; my $opt_suites; our $opt_verbose= 0; # Verbose output, enable with --verbose From 0bf40b3e4c3181a0f576155baedb31696d4c6afb Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 12 Oct 2010 13:13:23 +0200 Subject: [PATCH 050/151] Bug #40406 Please make mtr print better messages when servers fail to start Added some more details to warning messages, this should be enough. --- mysql-test/lib/mtr_process.pl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index a42627c93cd..26a95fa13ab 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -116,18 +116,20 @@ sub sleep_until_file_created ($$$) { return 1; } + my $seconds= ($loop * $sleeptime) / 1000; + # Check if it died after the fork() was successful if ( defined $proc and ! $proc->wait_one(0) ) { - mtr_warning("Process $proc died"); + mtr_warning("Process $proc died after mysql-test-run waited $seconds " . + "seconds for $pidfile to be created."); return 0; } mtr_debug("Sleep $sleeptime milliseconds waiting for $pidfile"); # Print extra message every 60 seconds - my $seconds= ($loop * $sleeptime) / 1000; - if ( $seconds > 1 and int($seconds * 10) % 600 == 0 ) + if ( $seconds > 1 && int($seconds * 10) % 600 == 0 && $seconds < $timeout ) { my $left= $timeout - $seconds; mtr_warning("Waited $seconds seconds for $pidfile to be created, " . @@ -138,6 +140,8 @@ sub sleep_until_file_created ($$$) { } + mtr_warning("Timeout after mysql-test-run waited $timeout seconds " . + "for the process $proc to create a pid file."); return 0; } From cd81c833a8a27df3cf037e084917a1a58e76f70b Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Tue, 12 Oct 2010 19:19:33 +0700 Subject: [PATCH 051/151] A follow up for the patch for Bug#45445, increase stack size to fix an sp-error.test failure on Sun Sparc system. --- sql/sp_head.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index e25b10957ac..52f658cbe0e 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1228,12 +1228,13 @@ sp_head::execute(THD *thd) parsing and loading of another stored procedure into the cache (@sa db_load_routine() and Bug#10100). At the time of measuring, a recursive SP invocation required - 3232 bytes of stack on 32 bit Linux and 6016 bytes on 64 bit Mac. + 3232 bytes of stack on 32 bit Linux, 6016 bytes on 64 bit Mac + and 11152 on 64 bit Solaris sparc. The same with db_load_routine() required circa 7k bytes and 14k bytes accordingly. Hence, here we book the stack with some reasonable margin. */ - if (check_stack_overrun(thd, 2 * STACK_MIN_SIZE, (uchar*)&old_packet)) + if (check_stack_overrun(thd, 4 * STACK_MIN_SIZE, (uchar*)&old_packet)) DBUG_RETURN(TRUE); /* init per-instruction memroot */ From cfcafcf5c4d89a7e947ea570ebaef91fdbbfc838 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Oct 2010 12:07:09 -0500 Subject: [PATCH 052/151] Bug#56632 - The warning code related to KEY_BLOCK_SIZE and ROW_FORMAT when innodb_strict_mode=OFF is improved in order to take into account whether the KEY_BLOCK_SIZE is specified on the current ALTER statement or the previous CREATE statement. The testcase shows the expected results of 12 different combinations of these settings. --- .../suite/innodb/r/innodb_bug56632.result | 294 ++++++++++++++++++ .../suite/innodb/t/innodb_bug56632.test | 216 +++++++++++++ storage/innobase/handler/ha_innodb.cc | 17 +- 3 files changed, 519 insertions(+), 8 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug56632.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug56632.test diff --git a/mysql-test/suite/innodb/r/innodb_bug56632.result b/mysql-test/suite/innodb/r/innodb_bug56632.result new file mode 100644 index 00000000000..8236b37676b --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug56632.result @@ -0,0 +1,294 @@ +SET storage_engine=InnoDB; +SET GLOBAL innodb_file_format=`Barracuda`; +SET GLOBAL innodb_file_per_table=ON; +SET SESSION innodb_strict_mode = ON; +# Test 1) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +Warnings: +Note 1051 Unknown table 'bug56632' +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +ERROR HY000: Can't create table 'test.bug56632' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. +Error 1005 Can't create table 'test.bug56632' (errno: 1478) +# Test 2) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +Warnings: +Note 1051 Unknown table 'bug56632' +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 3) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +# Test 4) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact +# Test 5) CREATE with KEY_BLOCK_SIZE=3 (invalid). +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +ERROR HY000: Can't create table 'test.bug56632' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 3. Valid values are [1, 2, 4, 8, 16] +Error 1005 Can't create table 'test.bug56632' (errno: 1478) +SET SESSION innodb_strict_mode = OFF; +# Test 6) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +Warnings: +Note 1051 Unknown table 'bug56632' +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +ALTER TABLE bug56632 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL, + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 7) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 8) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 9) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +ALTER TABLE bug56632 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL, + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +# Test 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=3 +# Test 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +# Cleanup +DROP TABLE IF EXISTS bug56632; diff --git a/mysql-test/suite/innodb/t/innodb_bug56632.test b/mysql-test/suite/innodb/t/innodb_bug56632.test new file mode 100644 index 00000000000..60703814da2 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug56632.test @@ -0,0 +1,216 @@ +# +# Bug#56632: ALTER TABLE implicitly changes ROW_FORMAT to COMPRESSED +# http://bugs.mysql.com/56632 +# +# Innodb automatically uses compressed mode when the KEY_BLOCK_SIZE +# parameter is used, except if the ROW_FORMAT is also specified, in +# which case the KEY_BLOCK_SIZE is ignored and a warning is shown. +# But Innodb was getting confused when neither of those parameters +# was used on the ALTER statement after they were both used on the +# CREATE. +# +# This will test the results of all 4 combinations of these two +# parameters of the CREATE and ALTER. +# +# Tests 1-5 use INNODB_STRICT_MODE=1 which returns an error +# if there is anything wrong with the statement. +# +# 1) CREATE with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1, ALTER with neither. +# Result; CREATE; fails with error ER_CANT_CREATE_TABLE +# 2) CREATE with ROW_FORMAT=COMPACT, ALTER with KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER quietly converts ROW_FORMAT to compressed. +# 3) CREATE with KEY_BLOCK_SIZE=1, ALTER with ROW_FORMAT=COMPACT +# Result; CREATE quietly converts ROW_FORMAT to compressed, +# ALTER fails with error ER_CANT_CREATE_TABLE. +# 4) CREATE with neither, ALTER with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER; fails with error ER_CANT_CREATE_TABLE +# 5) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +# Result; CREATE; fails with error ER_CANT_CREATE_TABLE +# +# Tests 6-11 use INNODB_STRICT_MODE=0 which automatically makes +# adjustments if the prameters are incompatible. +# +# 6) CREATE with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1, ALTER with neither. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE is ignored. +# ALTER succeeds, no warnings. +# 7) CREATE with ROW_FORMAT=COMPACT, ALTER with KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER quietly converts ROW_FORMAT to compressed. +# 8) CREATE with KEY_BLOCK_SIZE=1, ALTER with ROW_FORMAT=COMPACT +# Result; CREATE quietly converts ROW_FORMAT to compressed, +# ALTER succeeds, warns that KEY_BLOCK_SIZE is ignored. +# 9) CREATE with neither, ALTER with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER succeeds, warns that KEY_BLOCK_SIZE is ignored. +# 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# ALTER succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# ALTER succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# ALTER succeeds, quietly converts ROW_FORMAT to compressed. + +-- source include/have_innodb.inc + +SET storage_engine=InnoDB; + +--disable_query_log +# These values can change during the test +LET $innodb_file_format_orig=`select @@innodb_file_format`; +LET $innodb_file_format_max_orig=`select @@innodb_file_format_max`; +LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +LET $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; +--enable_query_log + +SET GLOBAL innodb_file_format=`Barracuda`; +SET GLOBAL innodb_file_per_table=ON; + +# Innodb strict mode will cause an error on the CREATE or ALTER when; +# 1. both ROW_FORMAT=COMPACT and KEY_BLOCK_SIZE=1, +# 2. KEY_BLOCK_SIZE is not a valid number (0,1,2,4,8,16). +# With innodb_strict_mode = OFF, These errors are corrected +# and just a warning is returned. +SET SESSION innodb_strict_mode = ON; + +--echo # Test 1) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +--error ER_CANT_CREATE_TABLE +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; + +--echo # Test 2) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 3) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +--disable_result_log +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +--enable_result_log +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 4) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +--disable_result_log +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +--enable_result_log +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 5) CREATE with KEY_BLOCK_SIZE=3 (invalid). +DROP TABLE IF EXISTS bug56632; +--error ER_CANT_CREATE_TABLE +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; + +SET SESSION innodb_strict_mode = OFF; + +--echo # Test 6) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ADD COLUMN f1 INT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 7) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 8) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 9) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ADD COLUMN f1 INT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Cleanup +DROP TABLE IF EXISTS bug56632; + +--disable_query_log +EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +EVAL SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; +EVAL SET GLOBAL innodb_file_format=$innodb_file_format_orig; +EVAL SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; +--enable_query_log + diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 567cbca868e..21afe2d0bee 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6556,8 +6556,8 @@ create_options_are_valid( ? "COMPRESSED" : "DYNAMIC"; - /* These two ROW_FORMATs require - srv_file_per_table and srv_file_format */ + /* These two ROW_FORMATs require srv_file_per_table + and srv_file_format > Antelope */ if (!srv_file_per_table) { push_warning_printf( thd, @@ -6567,7 +6567,6 @@ create_options_are_valid( " requires innodb_file_per_table.", row_format_name); ret = FALSE; - } if (srv_file_format < DICT_TF_FORMAT_ZIP) { @@ -6766,6 +6765,8 @@ ha_innobase::create( ulint ssize, ksize; ulint key_block_size = create_info->key_block_size; + /* Set 'flags' to the correct key_block_size. + It will be zero if key_block_size is an invalid number.*/ for (ssize = ksize = 1; ssize <= DICT_TF_ZSSIZE_MAX; ssize++, ksize <<= 1) { if (key_block_size == ksize) { @@ -6806,10 +6807,10 @@ ha_innobase::create( 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 */ + /* if KEY_BLOCK_SIZE was specified on this statement and + ROW_FORMAT was not, automatically change ROW_FORMAT to COMPRESSED.*/ + if ( (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE) + && !(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) { row_type = ROW_TYPE_COMPRESSED; } else if (row_type != ROW_TYPE_COMPRESSED) { /* ROW_FORMAT other than COMPRESSED @@ -6828,7 +6829,7 @@ ha_innobase::create( flags = 0; } } else { - /* No KEY_BLOCK_SIZE */ + /* flags == 0 means no KEY_BLOCK_SIZE.*/ if (row_type == ROW_TYPE_COMPRESSED) { /* ROW_FORMAT=COMPRESSED without KEY_BLOCK_SIZE implies half the From 891bbf224a41e8f97b4c40ddb671da69536af12f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Oct 2010 12:59:33 -0500 Subject: [PATCH 053/151] Bug#56632 - The warning code related to KEY_BLOCK_SIZE and ROW_FORMAT when innodb_strict_mode=OFF is improved in order to take into account whether the KEY_BLOCK_SIZE is specified on the current ALTER statement or the previous CREATE statement. The testcase shows the expected results of 12 different combinations of these settings. --- .../innodb_plugin/r/innodb_bug56632.result | 294 ++++++++++++++++++ .../innodb_plugin/t/innodb_bug56632.test | 216 +++++++++++++ storage/innodb_plugin/handler/ha_innodb.cc | 17 +- 3 files changed, 519 insertions(+), 8 deletions(-) create mode 100755 mysql-test/suite/innodb_plugin/r/innodb_bug56632.result create mode 100755 mysql-test/suite/innodb_plugin/t/innodb_bug56632.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug56632.result b/mysql-test/suite/innodb_plugin/r/innodb_bug56632.result new file mode 100755 index 00000000000..8236b37676b --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug56632.result @@ -0,0 +1,294 @@ +SET storage_engine=InnoDB; +SET GLOBAL innodb_file_format=`Barracuda`; +SET GLOBAL innodb_file_per_table=ON; +SET SESSION innodb_strict_mode = ON; +# Test 1) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +Warnings: +Note 1051 Unknown table 'bug56632' +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +ERROR HY000: Can't create table 'test.bug56632' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. +Error 1005 Can't create table 'test.bug56632' (errno: 1478) +# Test 2) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +Warnings: +Note 1051 Unknown table 'bug56632' +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 3) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +# Test 4) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact +# Test 5) CREATE with KEY_BLOCK_SIZE=3 (invalid). +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +ERROR HY000: Can't create table 'test.bug56632' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 3. Valid values are [1, 2, 4, 8, 16] +Error 1005 Can't create table 'test.bug56632' (errno: 1478) +SET SESSION innodb_strict_mode = OFF; +# Test 6) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +Warnings: +Note 1051 Unknown table 'bug56632' +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +ALTER TABLE bug56632 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL, + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 7) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 8) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 9) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +ALTER TABLE bug56632 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL, + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +# Test 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=3 +# Test 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +# Cleanup +DROP TABLE IF EXISTS bug56632; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test b/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test new file mode 100755 index 00000000000..60703814da2 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test @@ -0,0 +1,216 @@ +# +# Bug#56632: ALTER TABLE implicitly changes ROW_FORMAT to COMPRESSED +# http://bugs.mysql.com/56632 +# +# Innodb automatically uses compressed mode when the KEY_BLOCK_SIZE +# parameter is used, except if the ROW_FORMAT is also specified, in +# which case the KEY_BLOCK_SIZE is ignored and a warning is shown. +# But Innodb was getting confused when neither of those parameters +# was used on the ALTER statement after they were both used on the +# CREATE. +# +# This will test the results of all 4 combinations of these two +# parameters of the CREATE and ALTER. +# +# Tests 1-5 use INNODB_STRICT_MODE=1 which returns an error +# if there is anything wrong with the statement. +# +# 1) CREATE with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1, ALTER with neither. +# Result; CREATE; fails with error ER_CANT_CREATE_TABLE +# 2) CREATE with ROW_FORMAT=COMPACT, ALTER with KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER quietly converts ROW_FORMAT to compressed. +# 3) CREATE with KEY_BLOCK_SIZE=1, ALTER with ROW_FORMAT=COMPACT +# Result; CREATE quietly converts ROW_FORMAT to compressed, +# ALTER fails with error ER_CANT_CREATE_TABLE. +# 4) CREATE with neither, ALTER with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER; fails with error ER_CANT_CREATE_TABLE +# 5) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +# Result; CREATE; fails with error ER_CANT_CREATE_TABLE +# +# Tests 6-11 use INNODB_STRICT_MODE=0 which automatically makes +# adjustments if the prameters are incompatible. +# +# 6) CREATE with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1, ALTER with neither. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE is ignored. +# ALTER succeeds, no warnings. +# 7) CREATE with ROW_FORMAT=COMPACT, ALTER with KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER quietly converts ROW_FORMAT to compressed. +# 8) CREATE with KEY_BLOCK_SIZE=1, ALTER with ROW_FORMAT=COMPACT +# Result; CREATE quietly converts ROW_FORMAT to compressed, +# ALTER succeeds, warns that KEY_BLOCK_SIZE is ignored. +# 9) CREATE with neither, ALTER with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER succeeds, warns that KEY_BLOCK_SIZE is ignored. +# 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# ALTER succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# ALTER succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# ALTER succeeds, quietly converts ROW_FORMAT to compressed. + +-- source include/have_innodb.inc + +SET storage_engine=InnoDB; + +--disable_query_log +# These values can change during the test +LET $innodb_file_format_orig=`select @@innodb_file_format`; +LET $innodb_file_format_max_orig=`select @@innodb_file_format_max`; +LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +LET $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; +--enable_query_log + +SET GLOBAL innodb_file_format=`Barracuda`; +SET GLOBAL innodb_file_per_table=ON; + +# Innodb strict mode will cause an error on the CREATE or ALTER when; +# 1. both ROW_FORMAT=COMPACT and KEY_BLOCK_SIZE=1, +# 2. KEY_BLOCK_SIZE is not a valid number (0,1,2,4,8,16). +# With innodb_strict_mode = OFF, These errors are corrected +# and just a warning is returned. +SET SESSION innodb_strict_mode = ON; + +--echo # Test 1) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +--error ER_CANT_CREATE_TABLE +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; + +--echo # Test 2) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 3) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +--disable_result_log +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +--enable_result_log +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 4) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +--disable_result_log +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +--enable_result_log +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 5) CREATE with KEY_BLOCK_SIZE=3 (invalid). +DROP TABLE IF EXISTS bug56632; +--error ER_CANT_CREATE_TABLE +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; + +SET SESSION innodb_strict_mode = OFF; + +--echo # Test 6) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ADD COLUMN f1 INT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 7) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 8) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 9) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ADD COLUMN f1 INT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Cleanup +DROP TABLE IF EXISTS bug56632; + +--disable_query_log +EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +EVAL SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; +EVAL SET GLOBAL innodb_file_format=$innodb_file_format_orig; +EVAL SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; +--enable_query_log + diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 95778eb0744..9a9cc32c81b 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -6355,8 +6355,8 @@ create_options_are_valid( ? "COMPRESSED" : "DYNAMIC"; - /* These two ROW_FORMATs require - srv_file_per_table and srv_file_format */ + /* These two ROW_FORMATs require srv_file_per_table + and srv_file_format > Antelope */ if (!srv_file_per_table) { push_warning_printf( thd, @@ -6366,7 +6366,6 @@ create_options_are_valid( " requires innodb_file_per_table.", row_format_name); ret = FALSE; - } if (srv_file_format < DICT_TF_FORMAT_ZIP) { @@ -6565,6 +6564,8 @@ ha_innobase::create( ulint ssize, ksize; ulint key_block_size = create_info->key_block_size; + /* Set 'flags' to the correct key_block_size. + It will be zero if key_block_size is an invalid number.*/ for (ssize = ksize = 1; ssize <= DICT_TF_ZSSIZE_MAX; ssize++, ksize <<= 1) { if (key_block_size == ksize) { @@ -6605,10 +6606,10 @@ ha_innobase::create( 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 */ + /* if KEY_BLOCK_SIZE was specified on this statement and + ROW_FORMAT was not, automatically change ROW_FORMAT to COMPRESSED.*/ + if ( (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE) + && !(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) { row_type = ROW_TYPE_COMPRESSED; } else if (row_type != ROW_TYPE_COMPRESSED) { /* ROW_FORMAT other than COMPRESSED @@ -6627,7 +6628,7 @@ ha_innobase::create( flags = 0; } } else { - /* No KEY_BLOCK_SIZE */ + /* flags == 0 means no KEY_BLOCK_SIZE.*/ if (row_type == ROW_TYPE_COMPRESSED) { /* ROW_FORMAT=COMPRESSED without KEY_BLOCK_SIZE implies half the From 8169faec2797511e649bd98329c69a6cb0c9a857 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Wed, 13 Oct 2010 12:28:58 +0700 Subject: [PATCH 054/151] Fixed bug#36742 - GRANT hostname case handling inconsistent. mysql-test/r/grant.result: It was added result for test case for bug#36742. mysql-test/t/grant.test: It was added test case for bug#36742. sql/sql_yacc.yy: It was added convertation of host name part of user name to lowercase. --- mysql-test/r/grant.result | 11 +++++++++++ mysql-test/t/grant.test | 10 ++++++++++ sql/sql_yacc.yy | 6 ++++++ 3 files changed, 27 insertions(+) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 6831ef6183d..f6277323964 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1429,3 +1429,14 @@ DROP USER 'testbug'@localhost; DROP TABLE db2.t1; DROP DATABASE db1; DROP DATABASE db2; +# +# Bug #36742 +# +grant usage on Foo.* to myuser@Localhost identified by 'foo'; +grant select on Foo.* to myuser@localhost; +select host,user from mysql.user where User='myuser'; +host user +localhost myuser +revoke select on Foo.* from myuser@localhost; +delete from mysql.user where User='myuser'; +flush privileges; diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index cb8d3c63be8..2fafeb7d264 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1550,5 +1550,15 @@ DROP TABLE db2.t1; DROP DATABASE db1; DROP DATABASE db2; +--echo # +--echo # Bug #36742 +--echo # +grant usage on Foo.* to myuser@Localhost identified by 'foo'; +grant select on Foo.* to myuser@localhost; +select host,user from mysql.user where User='myuser'; +revoke select on Foo.* from myuser@localhost; +delete from mysql.user where User='myuser'; +flush privileges; + # Wait till we reached the initial number of concurrent sessions --source include/wait_until_count_sessions.inc diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index aa41a408e5b..4e24e69af42 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -11567,6 +11567,12 @@ user: system_charset_info, 0) || check_host_name(&$$->host)) MYSQL_YYABORT; + /* + Convert hostname part of username to lowercase. + It's OK to use in-place lowercase as long as + the character set is utf8. + */ + my_casedn_str(system_charset_info, $$->host.str); } | CURRENT_USER optional_braces { From eb882fe41b96bd2736dafe86a59b7f7a823ba07f Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Wed, 13 Oct 2010 12:48:08 +0400 Subject: [PATCH 055/151] Fix Bug#56443 remove last 'mysqld_show_column_type' remains sql/sql_show.h: Remove an unused declaration. --- sql/sql_show.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/sql_show.h b/sql/sql_show.h index d1323ede8c1..de8f2525baa 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -104,7 +104,6 @@ bool mysqld_show_storage_engines(THD *thd); bool mysqld_show_authors(THD *thd); bool mysqld_show_contributors(THD *thd); bool mysqld_show_privileges(THD *thd); -bool mysqld_show_column_types(THD *thd); char *make_backup_log_name(char *buff, const char *name, const char* log_ext); void calc_sum_of_all_status(STATUS_VAR *to); void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user, From 1450cddf92e3a847b528f8882ec1723c1a658122 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 13 Oct 2010 13:29:34 +0400 Subject: [PATCH 056/151] Reverting a patch for Bug#45445 (cannot execute procedures with thread_stack set to 128k). Some platforms don't work with 4 * STACK_MIN_SIZE. Thus, reverting back to 8 * STACK_MIN_SIZE and waiting for another fix. --- sql/sp_head.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 52f658cbe0e..1fd4e9302c4 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1233,8 +1233,11 @@ sp_head::execute(THD *thd) The same with db_load_routine() required circa 7k bytes and 14k bytes accordingly. Hence, here we book the stack with some reasonable margin. + + Reverting back to 8 * STACK_MIN_SIZE until further fix. + 8 * STACK_MIN_SIZE is required on some exotic platforms. */ - if (check_stack_overrun(thd, 4 * STACK_MIN_SIZE, (uchar*)&old_packet)) + if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet)) DBUG_RETURN(TRUE); /* init per-instruction memroot */ From 609bc2c4077f4c1244763a796aa52a5d9d363e15 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 13 Oct 2010 13:34:02 +0400 Subject: [PATCH 057/151] Reverting a patch for Bug#45445 (cannot execute procedures with thread_stack set to 128k). Some platforms don't work with 4 * STACK_MIN_SIZE. Thus, reverting back to 8 * STACK_MIN_SIZE and waiting for another fix. --- sql/sp_head.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 52f658cbe0e..1fd4e9302c4 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1233,8 +1233,11 @@ sp_head::execute(THD *thd) The same with db_load_routine() required circa 7k bytes and 14k bytes accordingly. Hence, here we book the stack with some reasonable margin. + + Reverting back to 8 * STACK_MIN_SIZE until further fix. + 8 * STACK_MIN_SIZE is required on some exotic platforms. */ - if (check_stack_overrun(thd, 4 * STACK_MIN_SIZE, (uchar*)&old_packet)) + if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet)) DBUG_RETURN(TRUE); /* init per-instruction memroot */ From e8fd5b58bff9bc06012c8758ce76b39ba51e6712 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 13 Oct 2010 13:07:28 +0200 Subject: [PATCH 058/151] Bug #55968 MTR does not clean up properly and chokes on its discharge Added --clean-vardir to empty vardir if no failures Also added variable $MTR_CLEAN_VARDIR --- mysql-test/mysql-test-run.pl | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 494ec7a9be3..e6d988dfba6 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -195,6 +195,7 @@ sub using_extern { return (keys %opts_extern > 0);}; our $opt_fast= 0; our $opt_force; our $opt_mem= $ENV{'MTR_MEM'}; +our $opt_clean_vardir= $ENV{'MTR_CLEAN_VARDIR'}; our $opt_gcov; our $opt_gcov_exe= "gcov"; @@ -476,6 +477,8 @@ sub main { mtr_report_stats("Completed", $completed); + remove_vardir_subs() if $opt_clean_vardir; + exit(0); } @@ -946,6 +949,7 @@ sub command_line_setup { 'tmpdir=s' => \$opt_tmpdir, 'vardir=s' => \$opt_vardir, 'mem' => \$opt_mem, + 'clean-vardir' => \$opt_clean_vardir, 'client-bindir=s' => \$path_client_bindir, 'client-libdir=s' => \$path_client_libdir, @@ -2202,6 +2206,12 @@ sub environment_setup { } +sub remove_vardir_subs() { + foreach my $sdir ( glob("$opt_vardir/*") ) { + mtr_verbose("Removing subdir $sdir"); + rmtree($sdir); + } +} # # Remove var and any directories in var/ created by previous @@ -2246,11 +2256,7 @@ sub remove_stale_vardir () { mtr_error("The destination for symlink $opt_vardir does not exist") if ! -d readlink($opt_vardir); - foreach my $bin ( glob("$opt_vardir/*") ) - { - mtr_verbose("Removing bin $bin"); - rmtree($bin); - } + remove_vardir_subs(); } } else @@ -5502,6 +5508,8 @@ Options to control directories to use for tmpfs (/dev/shm) The option can also be set using environment variable MTR_MEM=[DIR] + clean-vardir Clean vardir if tests were successful and if + running in "memory". Otherwise this option is ignored client-bindir=PATH Path to the directory where client binaries are located client-libdir=PATH Path to the directory where client libraries are located From ec505e95708ab1bacd0c6afa8e83e411dbe4b0f7 Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Wed, 13 Oct 2010 15:21:45 +0400 Subject: [PATCH 059/151] Fix for bug #57422 "rpl_row_sp003 sporadically fails under heavy load". rpl_row_sp003.test has sporadically failed when run on machine under heavy load or on slow hardware. This patch fixes races in the test which were causing these failures and also removes unnecessary 100 second wait from it. --- mysql-test/extra/rpl_tests/rpl_row_sp003.test | 18 ++++++++++++++++-- mysql-test/suite/rpl/r/rpl_row_sp003.result | 10 +++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_row_sp003.test b/mysql-test/extra/rpl_tests/rpl_row_sp003.test index 7bc326a3791..d2c2ea0caf3 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_sp003.test +++ b/mysql-test/extra/rpl_tests/rpl_row_sp003.test @@ -35,10 +35,23 @@ connection master1; send CALL test.p1(); connection master; -# To make sure tha the call on master1 arrived at the get_lock -sleep 1; +# Make sure that the call on master1 arrived at the get_lock. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'User lock' and + info = 'SELECT get_lock("test", 100)'; +--source include/wait_condition.inc CALL test.p2(); SELECT release_lock("test"); + +connection master1; +# Reap CALL test.p1() to ensure that it has fully completed +# before doing any selects on test.t1. +--reap +# Release lock acquired by it. +SELECT release_lock("test"); + +connection master; SELECT * FROM test.t1; #show binlog events; --source include/wait_for_ndb_to_binlog.inc @@ -51,6 +64,7 @@ DROP TABLE IF EXISTS test.t1; eval CREATE TABLE test.t1(a INT,PRIMARY KEY(a))ENGINE=$engine_type; CALL test.p2(); CALL test.p1(); +SELECT release_lock("test"); SELECT * FROM test.t1; sync_slave_with_master; diff --git a/mysql-test/suite/rpl/r/rpl_row_sp003.result b/mysql-test/suite/rpl/r/rpl_row_sp003.result index df3e2a7ceed..c3e2dc57740 100644 --- a/mysql-test/suite/rpl/r/rpl_row_sp003.result +++ b/mysql-test/suite/rpl/r/rpl_row_sp003.result @@ -26,6 +26,11 @@ CALL test.p2(); SELECT release_lock("test"); release_lock("test") 1 +get_lock("test", 100) +1 +SELECT release_lock("test"); +release_lock("test") +1 SELECT * FROM test.t1; a 5 @@ -37,7 +42,10 @@ CREATE TABLE test.t1(a INT,PRIMARY KEY(a))ENGINE=INNODB; CALL test.p2(); CALL test.p1(); get_lock("test", 100) -0 +1 +SELECT release_lock("test"); +release_lock("test") +1 SELECT * FROM test.t1; a 8 From b5be2fbc8df3c8e7131d88adb06bad408e446df7 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Wed, 13 Oct 2010 16:15:28 +0200 Subject: [PATCH 060/151] Bug #55930 Assertion `thd->transaction.stmt.is_empty() || thd->in_sub_stmt || (thd->state.. OPTIMIZE TABLE is not directly supported by InnoDB. Instead, recreate and analyze of the table is done. After recreate, the table is closed and locks are released before the table is reopened and locks re-acquired for the analyze phase. This assertion was triggered if OPTIMIZE TABLE failed to acquire thr_lock locks before starting the analyze phase. The assertion tests (among other things) that there no active statement transaction. However, as part of acquiring the thr_lock lock, external_lock() is called for InnoDB tables and this causes a statement transaction to be started. If thr_multi_lock() later fails (e.g. due to timeout), the failure handling code causes this assert to be triggered. This patch fixes the problem by doing rollback of the current statement transaction in case open_ltable (used by OPTIMIZE TABLE) fails to acquire thr_lock locks. Test case added to lock_sync.test. --- mysql-test/r/lock_sync.result | 34 ++++++++++++++++++++++ mysql-test/t/lock_sync.test | 55 +++++++++++++++++++++++++++++++++++ sql/sql_base.cc | 3 ++ 3 files changed, 92 insertions(+) diff --git a/mysql-test/r/lock_sync.result b/mysql-test/r/lock_sync.result index 3682f0df26a..726b754eaa8 100644 --- a/mysql-test/r/lock_sync.result +++ b/mysql-test/r/lock_sync.result @@ -704,3 +704,37 @@ SET DEBUG_SYNC="now SIGNAL query"; # Connection default DROP EVENT e2; SET DEBUG_SYNC="RESET"; +# +# Bug#55930 Assertion `thd->transaction.stmt.is_empty() || +# thd->in_sub_stmt || (thd->state.. +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(a INT) engine=InnoDB; +INSERT INTO t1 VALUES (1), (2); +# Connection con1 +SET SESSION lock_wait_timeout= 1; +SET DEBUG_SYNC= 'ha_admin_open_ltable SIGNAL opti_recreate WAIT_FOR opti_analyze'; +# Sending: +OPTIMIZE TABLE t1; +# Connection con2 +SET DEBUG_SYNC= 'now WAIT_FOR opti_recreate'; +SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL thrlock WAIT_FOR release_thrlock'; +# Sending: +INSERT INTO t1 VALUES (3); +# Connection default +SET DEBUG_SYNC= 'now WAIT_FOR thrlock'; +SET DEBUG_SYNC= 'now SIGNAL opti_analyze'; +# Connection con1 +# Reaping: OPTIMIZE TABLE t1 +Table Op Msg_type Msg_text +test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize error Lock wait timeout exceeded; try restarting transaction +test.t1 optimize status Operation failed +Warnings: +Error 1205 Lock wait timeout exceeded; try restarting transaction +SET DEBUG_SYNC= 'now SIGNAL release_thrlock'; +# Connection con2 +# Reaping: INSERT INTO t1 VALUES (3) +# Connection default +DROP TABLE t1; +SET DEBUG_SYNC= 'RESET'; diff --git a/mysql-test/t/lock_sync.test b/mysql-test/t/lock_sync.test index 49f8f59ec5a..7131e2cde31 100644 --- a/mysql-test/t/lock_sync.test +++ b/mysql-test/t/lock_sync.test @@ -1023,6 +1023,61 @@ DROP EVENT e2; SET DEBUG_SYNC="RESET"; +--echo # +--echo # Bug#55930 Assertion `thd->transaction.stmt.is_empty() || +--echo # thd->in_sub_stmt || (thd->state.. +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1(a INT) engine=InnoDB; +INSERT INTO t1 VALUES (1), (2); + +connect (con1, localhost, root); +connect (con2, localhost, root); + +--echo # Connection con1 +connection con1; +SET SESSION lock_wait_timeout= 1; +SET DEBUG_SYNC= 'ha_admin_open_ltable SIGNAL opti_recreate WAIT_FOR opti_analyze'; +--echo # Sending: +--send OPTIMIZE TABLE t1 + +--echo # Connection con2 +connection con2; +SET DEBUG_SYNC= 'now WAIT_FOR opti_recreate'; +SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL thrlock WAIT_FOR release_thrlock'; +--echo # Sending: +--send INSERT INTO t1 VALUES (3) + +--echo # Connection default +connection default; +SET DEBUG_SYNC= 'now WAIT_FOR thrlock'; +SET DEBUG_SYNC= 'now SIGNAL opti_analyze'; + +--echo # Connection con1 +connection con1; +--echo # Reaping: OPTIMIZE TABLE t1 +--reap +SET DEBUG_SYNC= 'now SIGNAL release_thrlock'; +disconnect con1; +--source include/wait_until_disconnected.inc + +--echo # Connection con2 +connection con2; +--echo # Reaping: INSERT INTO t1 VALUES (3) +--reap +disconnect con2; +--source include/wait_until_disconnected.inc + +--echo # Connection default +connection default; +DROP TABLE t1; +SET DEBUG_SYNC= 'RESET'; + + # Check that all connections opened by test cases in this file are really # gone so execution of other tests won't be affected by their presence. --source include/wait_until_count_sessions.inc diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8305283cd17..8090d8a9288 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5319,7 +5319,10 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type, end: if (table == NULL) + { + trans_rollback_stmt(thd); close_thread_tables(thd); + } thd_proc_info(thd, 0); DBUG_RETURN(table); } From 215e967ace1c5cbcdcaf82d1b00b31bc9f132393 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 13 Oct 2010 12:11:29 -0300 Subject: [PATCH 061/151] Use a guard macro to prevent the inclusion of system headers when checking the ABI with the C Preprocessor. Also, add the new hearders to the cmake based ABI check. cmake/abi_check.cmake: Add headers which were added to the autotools ABI check. Remove trailing spaces. include/mysql/client_plugin.h: Guard the inclusion of system headers. --- Makefile.am | 2 ++ cmake/abi_check.cmake | 6 ++++-- include/mysql/client_plugin.h | 2 ++ include/mysql/client_plugin.h.pp | 2 -- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index fadd73d5094..c47d8e780cf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -263,6 +263,8 @@ test-full-qa: # # Headers which need to be checked for abi/api compatibility. # +# Attention: do not forget to also add to cmake/abi_check.cmake +# API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin_audit.h \ $(top_srcdir)/include/mysql/plugin_ftparser.h \ diff --git a/cmake/abi_check.cmake b/cmake/abi_check.cmake index b9ff9f7af73..2488bcefe33 100644 --- a/cmake/abi_check.cmake +++ b/cmake/abi_check.cmake @@ -27,12 +27,14 @@ IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_SYSTEM_NAME MATCHES "Linux") ELSE() SET(COMPILER ${CMAKE_C_COMPILER}) ENDIF() - SET(API_PREPROCESSOR_HEADER + SET(API_PREPROCESSOR_HEADER ${CMAKE_SOURCE_DIR}/include/mysql/plugin_audit.h ${CMAKE_SOURCE_DIR}/include/mysql/plugin_ftparser.h ${CMAKE_SOURCE_DIR}/include/mysql.h - ${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v1.h + ${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v1.h ${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v2.h + ${CMAKE_SOURCE_DIR}/include/mysql/client_plugin.h + ${CMAKE_SOURCE_DIR}/include/mysql/plugin_auth.h ) ADD_CUSTOM_TARGET(abi_check ALL diff --git a/include/mysql/client_plugin.h b/include/mysql/client_plugin.h index ddd3b64ca56..d9c0dd02008 100644 --- a/include/mysql/client_plugin.h +++ b/include/mysql/client_plugin.h @@ -23,8 +23,10 @@ */ #define MYSQL_CLIENT_PLUGIN_INCLUDED +#ifndef MYSQL_ABI_CHECK #include #include +#endif /* known plugin types */ #define MYSQL_CLIENT_reserved1 0 diff --git a/include/mysql/client_plugin.h.pp b/include/mysql/client_plugin.h.pp index 58627e06f09..e508f821aad 100644 --- a/include/mysql/client_plugin.h.pp +++ b/include/mysql/client_plugin.h.pp @@ -1,5 +1,3 @@ -#include -#include struct st_mysql_client_plugin { int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; const char *license; void *mysql_api; int (*init)(char *, size_t, int, va_list); int (*deinit)(); int (*options)(const char *option, const void *); From d5055f4e8ad6872f585e1dc57b60d6eb461c9d2f Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 13 Oct 2010 21:17:00 -0700 Subject: [PATCH 062/151] Fix Bug #57397 io_handler_thread() will never cleanup rb://483 approved by Inaam --- storage/innodb_plugin/ChangeLog | 4 ++++ storage/innodb_plugin/srv/srv0start.c | 6 ++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 3b1f202c8ac..d193dcd321c 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,7 @@ +2010-10-14 The InnoDB Team + * srv/srv0start.c + Fix Bug #57397 io_handler_thread() will never cleanup + 2010-10-11 The InnoDB Team * row/row0sel.c Fix Bug #57345 btr_pcur_store_position abort for load with diff --git a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c index ba9fc831b39..2d339596013 100644 --- a/storage/innodb_plugin/srv/srv0start.c +++ b/storage/innodb_plugin/srv/srv0start.c @@ -471,7 +471,7 @@ io_handler_thread( fprintf(stderr, "Io handler thread %lu starts, id %lu\n", segment, os_thread_pf(os_thread_get_curr_id())); #endif - for (i = 0;; i++) { + while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) { fil_aio_wait(segment); mutex_enter(&ios_mutex); @@ -479,8 +479,6 @@ io_handler_thread( mutex_exit(&ios_mutex); } - thr_local_free(os_thread_get_curr_id()); - /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. The thread actually never comes here because it is exited in an @@ -1894,7 +1892,7 @@ innobase_shutdown_for_mysql(void) #ifdef __NETWARE__ if (!panic_shutdown) #endif - logs_empty_and_mark_files_at_shutdown(); + logs_empty_and_mark_files_at_shutdown(); if (srv_conc_n_threads != 0) { fprintf(stderr, From 4c14da79754db219d063bc7fc29b8a3abfa34ba7 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 13 Oct 2010 20:18:59 +0300 Subject: [PATCH 063/151] Fix Bug#56143 too many foreign keys causes output of show create table to become invalid Just remove the check whether the file is "too big". A similar code exists in ha_innobase::update_table_comment() but that method does not seem to be used. --- .../suite/innodb/r/innodb_bug56143.result | 560 ++++++++++++++++++ .../suite/innodb/t/innodb_bug56143.test | 29 + storage/innobase/handler/ha_innodb.cc | 2 - 3 files changed, 589 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug56143.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug56143.test diff --git a/mysql-test/suite/innodb/r/innodb_bug56143.result b/mysql-test/suite/innodb/r/innodb_bug56143.result new file mode 100644 index 00000000000..cfff4d60d1b --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug56143.result @@ -0,0 +1,560 @@ +SHOW CREATE TABLE bug56143; +Table Create Table +bug56143 CREATE TABLE `bug56143` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + KEY `a` (`a`), + KEY `b` (`b`), + KEY `c` (`c`), + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa100` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa103` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa104` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa105` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa106` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa107` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa108` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa109` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa110` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa111` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa112` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa113` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa114` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa115` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa116` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa117` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa118` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa119` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa120` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa121` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa122` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa124` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa125` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa126` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa127` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa128` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa129` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa13` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa130` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa131` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa132` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa133` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa134` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa135` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa136` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa137` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa138` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa139` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa14` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa140` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa141` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa142` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa143` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa144` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa145` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa146` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa147` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa148` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa149` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa15` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa150` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa151` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa152` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa153` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa154` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa155` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa156` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa157` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa158` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa159` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa16` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa160` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa161` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa162` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa163` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa164` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa165` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa166` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa167` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa168` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa169` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa17` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa170` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa171` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa172` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa173` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa174` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa175` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa176` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa177` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa178` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa179` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa18` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa180` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa181` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa182` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa183` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa184` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa185` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa186` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa187` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa188` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa189` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa19` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa190` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa191` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa192` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa193` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa194` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa195` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa196` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa197` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa198` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa199` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa200` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa201` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa202` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa203` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa204` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa205` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa206` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa207` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa208` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa209` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa21` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa210` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa211` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa212` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa213` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa214` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa215` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa216` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa217` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa218` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa219` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa22` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa220` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa221` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa222` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa223` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa224` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa225` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa226` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa227` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa228` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa229` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa23` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa230` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa231` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa232` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa233` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa234` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa235` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa236` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa237` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa238` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa239` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa24` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa240` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa241` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa242` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa243` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa244` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa245` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa246` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa247` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa248` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa249` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa25` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa250` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa251` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa252` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa253` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa254` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa255` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa256` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa257` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa258` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa259` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa26` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa260` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa261` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa262` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa263` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa264` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa265` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa266` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa267` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa268` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa269` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa27` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa270` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa271` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa272` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa273` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa274` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa275` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa276` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa277` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa278` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa279` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa28` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa280` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa281` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa282` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa283` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa284` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa285` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa286` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa287` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa288` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa289` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa29` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa290` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa291` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa292` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa293` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa294` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa295` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa296` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa297` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa298` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa299` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa30` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa300` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa301` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa302` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa303` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa304` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa305` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa306` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa307` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa308` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa309` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa31` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa310` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa311` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa312` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa313` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa314` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa315` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa316` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa317` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa318` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa319` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa32` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa320` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa321` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa322` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa323` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa324` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa325` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa326` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa327` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa328` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa329` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa33` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa330` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa331` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa332` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa333` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa334` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa335` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa336` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa337` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa338` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa339` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa34` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa340` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa341` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa342` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa343` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa344` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa345` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa346` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa347` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa348` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa349` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa35` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa350` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa351` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa352` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa353` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa354` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa355` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa356` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa357` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa358` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa359` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa36` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa360` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa361` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa362` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa363` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa364` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa365` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa366` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa367` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa368` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa369` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa37` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa370` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa371` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa372` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa373` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa374` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa375` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa376` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa377` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa378` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa379` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa38` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa380` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa381` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa382` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa383` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa384` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa385` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa386` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa387` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa388` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa389` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa39` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa390` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa391` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa392` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa393` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa394` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa395` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa396` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa397` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa398` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa399` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa40` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa400` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa401` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa402` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa403` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa404` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa405` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa406` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa407` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa408` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa409` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa41` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa410` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa411` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa412` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa413` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa414` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa415` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa416` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa417` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa418` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa419` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa42` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa420` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa421` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa422` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa423` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa424` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa425` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa426` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa427` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa428` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa429` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa43` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa430` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa431` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa432` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa433` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa434` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa435` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa436` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa437` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa438` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa439` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa44` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa440` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa441` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa442` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa443` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa444` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa445` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa446` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa447` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa448` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa449` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa45` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa450` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa451` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa452` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa453` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa454` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa455` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa456` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa457` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa458` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa459` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa46` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa460` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa461` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa462` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa463` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa464` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa465` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa466` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa467` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa468` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa469` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa47` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa470` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa471` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa472` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa473` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa474` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa475` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa476` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa477` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa478` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa479` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa48` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa480` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa481` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa482` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa483` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa484` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa485` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa486` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa487` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa488` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa489` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa49` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa490` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa491` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa492` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa493` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa494` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa495` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa496` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa497` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa498` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa499` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa50` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa500` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa501` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa502` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa503` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa504` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa505` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa506` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa507` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa508` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa509` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa51` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa510` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa511` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa512` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa513` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa514` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa515` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa516` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa517` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa518` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa519` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa52` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa520` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa521` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa522` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa523` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa524` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa525` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa526` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa527` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa528` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa529` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa53` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa530` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa531` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa532` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa533` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa534` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa535` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa536` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa537` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa538` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa539` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa54` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa540` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa541` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa542` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa543` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa544` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa545` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa546` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa547` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa548` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa549` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa55` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa550` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa56` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa57` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa58` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa59` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa60` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa61` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa62` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa63` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa64` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa65` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa66` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa67` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa68` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa69` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa7` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa70` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa71` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa72` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa73` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa74` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa75` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa76` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa77` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa78` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa79` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa80` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa81` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa82` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa83` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa84` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa85` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa86` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa87` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa88` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa89` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa90` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa91` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa92` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa93` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa94` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa95` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa96` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa97` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa98` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa99` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 diff --git a/mysql-test/suite/innodb/t/innodb_bug56143.test b/mysql-test/suite/innodb/t/innodb_bug56143.test new file mode 100644 index 00000000000..45c174fd280 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug56143.test @@ -0,0 +1,29 @@ +# +# Bug#56143 too many foreign keys causes output of show create table to become invalid +# http://bugs.mysql.com/56143 +# + +-- source include/have_innodb.inc + +-- disable_query_log +-- disable_result_log + +SET foreign_key_checks=0; +DROP TABLE IF EXISTS bug56143; +CREATE TABLE bug56143 (a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) ENGINE=INNODB; + +let $i = 550; +while ($i) +{ + eval ALTER TABLE `bug56143` ADD CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$i` FOREIGN KEY (`b`) REFERENCES `bug56143`(`b`) ON UPDATE SET NULL; + dec $i; +} + +-- enable_query_log +-- enable_result_log + +SHOW CREATE TABLE bug56143; + +-- disable_query_log +-- disable_result_log +DROP TABLE bug56143; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index cfd4b229ce0..aac0a291223 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6788,8 +6788,6 @@ ha_innobase::get_foreign_key_create_info(void) flen = ftell(srv_dict_tmpfile); if (flen < 0) { flen = 0; - } else if (flen > 64000 - 1) { - flen = 64000 - 1; } /* allocate buffer for the string, and From aeb24b635a32748b37b9789bf35c47044b8bb0fe Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 13 Oct 2010 21:25:41 +0400 Subject: [PATCH 064/151] Bump version after 5.5.7 clone-off. --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index c272efe9214..4725008b473 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.5.7-rc], [], [mysql]) +AC_INIT([MySQL Server], [5.5.8-ga], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 895506247de07b247086d267d9468f32a07de7f1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Oct 2010 13:32:10 -0500 Subject: [PATCH 065/151] Bug#55632 - Fix testcase for 5.1 plugin --- mysql-test/suite/innodb_plugin/t/innodb_bug56632.test | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test b/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test index 60703814da2..7f1c41cddfa 100755 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test @@ -54,14 +54,14 @@ # Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. # ALTER succeeds, quietly converts ROW_FORMAT to compressed. --- source include/have_innodb.inc +-- source include/have_innodb_plugin.inc SET storage_engine=InnoDB; --disable_query_log # These values can change during the test LET $innodb_file_format_orig=`select @@innodb_file_format`; -LET $innodb_file_format_max_orig=`select @@innodb_file_format_max`; +LET $innodb_file_format_check_orig=`select @@innodb_file_format_check`; LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; LET $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; --enable_query_log @@ -209,8 +209,8 @@ DROP TABLE IF EXISTS bug56632; --disable_query_log EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; -EVAL SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; EVAL SET GLOBAL innodb_file_format=$innodb_file_format_orig; +EVAL SET GLOBAL innodb_file_format_check=$innodb_file_format_check_orig; EVAL SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; --enable_query_log From 8a30cc4a79908452c5dabe50f93900c2eb873f66 Mon Sep 17 00:00:00 2001 From: smenon Date: Wed, 13 Oct 2010 21:54:45 +0200 Subject: [PATCH 066/151] Raise version number after cloning 5.5.7-rc --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index c272efe9214..dca7e548e50 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.5.7-rc], [], [mysql]) +AC_INIT([MySQL Server], [5.5.8-rc], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 1d43e72a0b98ed89b990965313c4c31d5d262890 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 13 Oct 2010 22:54:07 -0300 Subject: [PATCH 067/151] Bug#56096: STOP SLAVE hangs if executed in parallel with user sleep The root of the problem is that to interrupt a slave SQL thread wait, the STOP SLAVE implementation uses thd->awake(THD::NOT_KILLED). This appears as a spurious wakeup (e.g. from a sleep on a condition variable) to the code that the slave SQL thread is executing at the time of the STOP. If the code is not written to be spurious-wakeup safe, unexpected behavior can occur. For the reported case, this problem led to an infinite loop around the interruptible_wait() function in item_func.cc (SLEEP() function implementation). The loop was not being properly restarted and, consequently, would not come to an end. Since the SLEEP function sleeps on a timed event in order to be killable and to perform periodic checks until the requested time has elapsed, the spurious wake up was causing the requested sleep time to be reset every two seconds. The solution is to calculate the requested absolute time only once and to ensure that the thread only sleeps until this time is elapsed. In case of a spurious wake up, the sleep is restarted using the previously calculated absolute time. This restores the behavior present in previous releases. If a slave thread is executing a SLEEP function, a STOP SLAVE statement will wait until the time requested in the sleep function has elapsed. mysql-test/extra/rpl_tests/rpl_start_stop_slave.test: Add test case for Bug#56096. mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result: Add test case result for Bug#56096. sql/item_func.cc: Reorganize interruptible_wait into a class so that the absolute time can be preserved across calls to the wait function. This allows the sleep to be properly restarted in the presence of spurious wake ups, including those generated by a STOP SLAVE. --- .../extra/rpl_tests/rpl_start_stop_slave.test | 56 +++++++++++ .../rpl/r/rpl_stm_start_stop_slave.result | 22 +++++ sql/item_func.cc | 96 ++++++++++++++----- 3 files changed, 151 insertions(+), 23 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test b/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test index 05836737717..5c99fa1bc74 100644 --- a/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test +++ b/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test @@ -122,4 +122,60 @@ drop table t1i, t2m; sync_slave_with_master; +--echo # +--echo # Bug#56096 STOP SLAVE hangs if executed in parallel with user sleep +--echo # + +--connection master + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (a INT ); + +sync_slave_with_master; + +--connection slave1 +--echo # Slave1: lock table for synchronization +LOCK TABLES t1 WRITE; + +--connection master +--echo # Master: insert into the table +INSERT INTO t1 SELECT SLEEP(4); + +--connection slave +--echo # Slave: wait for the insert +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST + WHERE STATE = "Waiting for table metadata lock" + AND INFO = "INSERT INTO t1 SELECT SLEEP(4)"; +--source include/wait_condition.inc + +--echo # Slave: send slave stop +--send STOP SLAVE + +--connection slave1 +--echo # Slave1: wait for stop slave +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST + WHERE INFO = "STOP SLAVE"; +--source include/wait_condition.inc + +--echo # Slave1: unlock the table +UNLOCK TABLES; + +--connection slave +--echo # Slave: wait for the slave to stop +--reap +--source include/wait_for_slave_to_stop.inc + +--echo # Start slave again +--source include/start_slave.inc + +--echo # Clean up +--connection master +DROP TABLE t1; +sync_slave_with_master; + # End of tests diff --git a/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result b/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result index 71ad0177bae..8bb8b0bdf08 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result +++ b/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result @@ -43,3 +43,25 @@ one 1 include/start_slave.inc drop table t1i, t2m; +# +# Bug#56096 STOP SLAVE hangs if executed in parallel with user sleep +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a INT ); +# Slave1: lock table for synchronization +LOCK TABLES t1 WRITE; +# Master: insert into the table +INSERT INTO t1 SELECT SLEEP(4); +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. +# Slave: wait for the insert +# Slave: send slave stop +STOP SLAVE; +# Slave1: wait for stop slave +# Slave1: unlock the table +UNLOCK TABLES; +# Slave: wait for the slave to stop +# Start slave again +include/start_slave.inc +# Clean up +DROP TABLE t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 7906ed71bc7..afb09ff5b17 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3691,48 +3691,92 @@ longlong Item_master_pos_wait::val_int() } +/** + Enables a session to wait on a condition until a timeout or a network + disconnect occurs. + + @remark The connection is polled every m_interrupt_interval nanoseconds. +*/ + +class Interruptible_wait +{ + THD *m_thd; + struct timespec m_abs_timeout; + static const ulonglong m_interrupt_interval; + + public: + Interruptible_wait(THD *thd) + : m_thd(thd) {} + + ~Interruptible_wait() {} + + public: + /** + Set the absolute timeout. + + @param timeout The amount of time in nanoseconds to wait + */ + void set_timeout(ulonglong timeout) + { + /* + Calculate the absolute system time at the start so it can + be controlled in slices. It relies on the fact that once + the absolute time passes, the timed wait call will fail + automatically with a timeout error. + */ + set_timespec_nsec(m_abs_timeout, timeout); + } + + /** The timed wait. */ + int wait(mysql_cond_t *, mysql_mutex_t *); +}; + + +/** Time to wait before polling the connection status. */ +const ulonglong Interruptible_wait::m_interrupt_interval= 5 * ULL(1000000000); + /** - Wait for a given condition to be signaled within the specified timeout. + Wait for a given condition to be signaled. - @param cond the condition variable to wait on - @param lock the associated mutex - @param abstime the amount of time in seconds to wait + @param cond The condition variable to wait on. + @param mutex The associated mutex. + + @remark The absolute timeout is preserved across calls. @retval return value from mysql_cond_timedwait */ -#define INTERRUPT_INTERVAL (5 * ULL(1000000000)) - -static int interruptible_wait(THD *thd, mysql_cond_t *cond, - mysql_mutex_t *lock, double time) +int Interruptible_wait::wait(mysql_cond_t *cond, mysql_mutex_t *mutex) { int error; - struct timespec abstime; - ulonglong slice, timeout= (ulonglong) (time * 1000000000.0); + struct timespec timeout; - do + while (1) { /* Wait for a fixed interval. */ - if (timeout > INTERRUPT_INTERVAL) - slice= INTERRUPT_INTERVAL; - else - slice= timeout; + set_timespec_nsec(timeout, m_interrupt_interval); - timeout-= slice; - set_timespec_nsec(abstime, slice); - error= mysql_cond_timedwait(cond, lock, &abstime); + /* But only if not past the absolute timeout. */ + if (cmp_timespec(timeout, m_abs_timeout) > 0) + timeout= m_abs_timeout; + + error= mysql_cond_timedwait(cond, mutex, &timeout); if (error == ETIMEDOUT || error == ETIME) { /* Return error if timed out or connection is broken. */ - if (!timeout || !thd->is_connected()) + if (!cmp_timespec(timeout, m_abs_timeout) || !m_thd->is_connected()) break; } - } while (error && timeout); + /* Otherwise, propagate status to the caller. */ + else + break; + } return error; } + /** Get a user level lock. If the thread has an old lock this is first released. @@ -3748,10 +3792,11 @@ longlong Item_func_get_lock::val_int() { DBUG_ASSERT(fixed == 1); String *res=args[0]->val_str(&value); - double timeout= args[1]->val_real(); + ulonglong timeout= args[1]->val_int(); THD *thd=current_thd; User_level_lock *ull; int error; + Interruptible_wait timed_cond(thd); DBUG_ENTER("Item_func_get_lock::val_int"); /* @@ -3812,11 +3857,13 @@ longlong Item_func_get_lock::val_int() thd->mysys_var->current_mutex= &LOCK_user_locks; thd->mysys_var->current_cond= &ull->cond; + timed_cond.set_timeout(timeout * ULL(1000000000)); + error= 0; while (ull->locked && !thd->killed) { DBUG_PRINT("info", ("waiting on lock")); - error= interruptible_wait(thd, &ull->cond, &LOCK_user_locks, timeout); + error= timed_cond.wait(&ull->cond, &LOCK_user_locks); if (error == ETIMEDOUT || error == ETIME) { DBUG_PRINT("info", ("lock wait timeout")); @@ -4011,6 +4058,7 @@ void Item_func_benchmark::print(String *str, enum_query_type query_type) longlong Item_func_sleep::val_int() { THD *thd= current_thd; + Interruptible_wait timed_cond(thd); mysql_cond_t cond; double timeout; int error; @@ -4030,6 +4078,8 @@ longlong Item_func_sleep::val_int() if (timeout < 0.00001) return 0; + timed_cond.set_timeout((ulonglong) (timeout * 1000000000.0)); + mysql_cond_init(key_item_func_sleep_cond, &cond, NULL); mysql_mutex_lock(&LOCK_user_locks); @@ -4040,7 +4090,7 @@ longlong Item_func_sleep::val_int() error= 0; while (!thd->killed) { - error= interruptible_wait(thd, &cond, &LOCK_user_locks, timeout); + error= timed_cond.wait(&cond, &LOCK_user_locks); if (error == ETIMEDOUT || error == ETIME) break; error= 0; From e16a61c6a652941c62e9133cfdb885ec5858cf02 Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Thu, 14 Oct 2010 14:12:02 +1100 Subject: [PATCH 068/151] Bug# 55681 - MTR slowdown after default storage engine was changed to InnoDB Add new function os_cond_wait_timed(). Change the os_thread_sleep() calls to timed conditional waits. Signal the background threads during the shutdown phase so that we avoid waiting for the sleep to timeout thus saving some time. rb://439 -- Approved by Jimmy Yang --- storage/innobase/include/os0sync.h | 22 +++++ storage/innobase/include/srv0srv.h | 9 ++ storage/innobase/log/log0log.c | 9 +- storage/innobase/os/os0sync.c | 151 +++++++++++++++++++++++++++++ storage/innobase/srv/srv0srv.c | 95 +++++++++++------- 5 files changed, 250 insertions(+), 36 deletions(-) diff --git a/storage/innobase/include/os0sync.h b/storage/innobase/include/os0sync.h index ec5ccee3e27..b294d7421c8 100644 --- a/storage/innobase/include/os0sync.h +++ b/storage/innobase/include/os0sync.h @@ -76,6 +76,12 @@ struct os_event_struct { /*!< list of all created events */ }; +/** Denotes an infinite delay for os_event_wait_time() */ +#define OS_SYNC_INFINITE_TIME ULINT_UNDEFINED + +/** Return value of os_event_wait_time() when the time is exceeded */ +#define OS_SYNC_TIME_EXCEEDED 1 + /** Operating system mutex */ typedef struct os_mutex_struct os_mutex_str_t; /** Operating system mutex handle */ @@ -173,7 +179,23 @@ os_event_wait_low( os_event_reset(). */ #define os_event_wait(event) os_event_wait_low(event, 0) +#define os_event_wait_time(e, t) os_event_wait_time_low(event, t, 0) +/**********************************************************//** +Waits for an event object until it is in the signaled state or +a timeout is exceeded. In Unix the timeout is always infinite. +@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */ +UNIV_INTERN +ulint +os_event_wait_time_low( +/*===================*/ + os_event_t event, /*!< in: event to wait */ + ulint time_in_usec, /*!< in: timeout in + microseconds, or + OS_SYNC_INFINITE_TIME */ + ib_int64_t reset_sig_count); /*!< in: zero or the value + returned by previous call of + os_event_reset(). */ /*********************************************************//** Creates an operating system mutex semaphore. Because these are slow, the mutex semaphore of InnoDB itself (mutex_t) should be used where possible. diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 5d2fb808dc9..98b07f5e893 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -57,6 +57,15 @@ extern const char srv_mysql50_table_name_prefix[9]; thread starts running */ extern os_event_t srv_lock_timeout_thread_event; +/* The monitor thread waits on this event. */ +extern os_event_t srv_monitor_event; + +/* The lock timeout thread waits on this event. */ +extern os_event_t srv_timeout_event; + +/* The error monitor thread waits on this event. */ +extern os_event_t srv_error_event; + /* If the last data file is auto-extended, we add this many pages to it at a time */ #define SRV_AUTO_EXTEND_INCREMENT \ diff --git a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c index 401cede1d8f..3fef4ee4fc5 100644 --- a/storage/innobase/log/log0log.c +++ b/storage/innobase/log/log0log.c @@ -3098,10 +3098,15 @@ loop: if (srv_fast_shutdown < 2 && (srv_error_monitor_active - || srv_lock_timeout_active || srv_monitor_active)) { + || srv_lock_timeout_active + || srv_monitor_active)) { mutex_exit(&kernel_mutex); + os_event_set(srv_error_event); + os_event_set(srv_monitor_event); + os_event_set(srv_timeout_event); + goto loop; } @@ -3128,6 +3133,8 @@ loop: log_buffer_flush_to_disk(); + mutex_exit(&kernel_mutex); + return; /* We SKIP ALL THE REST !! */ } diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 3c70e93aae0..975c66ad1e1 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -72,6 +72,9 @@ UNIV_INTERN ulint os_event_count = 0; UNIV_INTERN ulint os_mutex_count = 0; UNIV_INTERN ulint os_fast_mutex_count = 0; +/* The number of microsecnds in a second. */ +static const ulint MICROSECS_IN_A_SECOND = 1000000; + /* Because a mutex is embedded inside an event and there is an event embedded inside a mutex, on free, this generates a recursive call. This version of the free event function doesn't acquire the global lock */ @@ -121,6 +124,47 @@ os_cond_init( #endif } +/*********************************************************//** +Do a timed wait on condition variable. +@return TRUE if timed out, FALSE otherwise */ +UNIV_INLINE +ibool +os_cond_wait_timed( +/*===============*/ + os_cond_t* cond, /*!< in: condition variable. */ + os_fast_mutex_t* mutex, /*!< in: fast mutex */ +#ifndef __WIN__ + const struct timespec* abstime /*!< in: timeout */ +#else + ulint time_in_ms /*!< in: timeout in + milliseconds */ +#endif /* !__WIN__ */ +) +{ +#ifdef __WIN__ + BOOL ret; + + ut_a(sleep_condition_variable != NULL); + + ret = sleep_condition_variable(cond, mutex, time_in_ms); + + if (!ret && GetLastError() == WAIT_TIMEOUT) { + return(TRUE); + } + + ut_a(ret); + + return(FALSE); +#else + int ret; + + ret = pthread_cond_timedwait(cond, mutex, abstime); + + ut_a(ret == 0 || ret == ETIMEDOUT); + + return(ret == ETIMEDOUT); +#endif +} /*********************************************************//** Wait on condition variable */ UNIV_INLINE @@ -572,6 +616,113 @@ os_event_wait_low( } } +/**********************************************************//** +Waits for an event object until it is in the signaled state or +a timeout is exceeded. +@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */ +UNIV_INTERN +ulint +os_event_wait_time_low( +/*===================*/ + os_event_t event, /*!< in: event to wait */ + ulint time_in_usec, /*!< in: timeout in + microseconds, or + OS_SYNC_INFINITE_TIME */ + ib_int64_t reset_sig_count) /*!< in: zero or the value + returned by previous call of + os_event_reset(). */ + +{ + ibool timed_out; + ib_int64_t old_signal_count; + +#ifdef __WIN__ + DWORD time_in_ms = time_in_usec / 1000; + + if (!srv_use_native_conditions) { + DWORD err; + + ut_a(event); + + if (time_in_ms != OS_SYNC_INFINITE_TIME) { + err = WaitForSingleObject(event->handle, time_in_ms); + } else { + err = WaitForSingleObject(event->handle, INFINITE); + } + + if (err == WAIT_OBJECT_0) { + return(0); + } else if (err == WAIT_TIMEOUT) { + return(OS_SYNC_TIME_EXCEEDED); + } + + ut_error; + /* Dummy value to eliminate compiler warning. */ + return(42); + } else { + ut_a(sleep_condition_variable != NULL); + } +#else + struct timeval tv; + ulint sec; + ulint usec; + int ret; + struct timespec abstime; + + ret = ut_usectime(&sec, &usec); + ut_a(ret == 0); + + tv.tv_sec = sec; + tv.tv_usec = usec; + + tv.tv_usec += time_in_usec; + + if ((ulint) tv.tv_usec > MICROSECS_IN_A_SECOND) { + tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND; + tv.tv_usec %= MICROSECS_IN_A_SECOND; + } + + /* Convert to nano seconds. We ignore overflow. */ + abstime.tv_sec = tv.tv_sec; + abstime.tv_nsec = tv.tv_usec * 1000; +#endif /* __WIN__ */ + + os_fast_mutex_lock(&event->os_mutex); + + if (reset_sig_count) { + old_signal_count = reset_sig_count; + } else { + old_signal_count = event->signal_count; + } + + do { + if (event->is_set == TRUE + || event->signal_count != old_signal_count) { + + break; + } + + timed_out = os_cond_wait_timed( + &event->cond_var, &event->os_mutex, +#ifndef __WIN__ + &abstime +#else + time_in_ms +#endif /* !__WIN__ */ + ); + + } while (!timed_out); + + os_fast_mutex_unlock(&event->os_mutex); + + if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { + + os_thread_exit(NULL); + } + + return(timed_out ? OS_SYNC_TIME_EXCEEDED : 0); +} + /*********************************************************//** Creates an operating system mutex semaphore. Because these are slow, the mutex semaphore of InnoDB itself (mutex_t) should be used where possible. diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 83355bd1322..2ac5c8ce4fc 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -695,6 +695,12 @@ struct srv_slot_struct{ /* Table for MySQL threads where they will be suspended to wait for locks */ UNIV_INTERN srv_slot_t* srv_mysql_table = NULL; +UNIV_INTERN os_event_t srv_timeout_event; + +UNIV_INTERN os_event_t srv_monitor_event; + +UNIV_INTERN os_event_t srv_error_event; + UNIV_INTERN os_event_t srv_lock_timeout_thread_event; UNIV_INTERN srv_sys_t* srv_sys = NULL; @@ -1012,6 +1018,12 @@ srv_init(void) ut_a(slot->event); } + srv_error_event = os_event_create(NULL); + + srv_timeout_event = os_event_create(NULL); + + srv_monitor_event = os_event_create(NULL); + srv_lock_timeout_thread_event = os_event_create(NULL); for (i = 0; i < SRV_MASTER + 1; i++) { @@ -2049,6 +2061,7 @@ srv_monitor_thread( /*!< in: a dummy parameter required by os_thread_create */ { + ib_int64_t sig_count; double time_elapsed; time_t current_time; time_t last_table_monitor_time; @@ -2067,26 +2080,28 @@ srv_monitor_thread( #endif UT_NOT_USED(arg); - srv_last_monitor_time = time(NULL); - last_table_monitor_time = time(NULL); - last_tablespace_monitor_time = time(NULL); - last_monitor_time = time(NULL); + srv_last_monitor_time = ut_time(); + last_table_monitor_time = ut_time(); + last_tablespace_monitor_time = ut_time(); + last_monitor_time = ut_time(); mutex_skipped = 0; last_srv_print_monitor = srv_print_innodb_monitor; loop: srv_monitor_active = TRUE; /* Wake up every 5 seconds to see if we need to print - monitor information. */ + monitor information or if signalled at shutdown. */ - os_thread_sleep(5000000); + sig_count = os_event_reset(srv_monitor_event); - current_time = time(NULL); + os_event_wait_time_low(srv_monitor_event, 5000000, sig_count); + + current_time = ut_time(); time_elapsed = difftime(current_time, last_monitor_time); if (time_elapsed > 15) { - last_monitor_time = time(NULL); + last_monitor_time = ut_time(); if (srv_print_innodb_monitor) { /* Reset mutex_skipped counter everytime @@ -2130,7 +2145,7 @@ loop: if (srv_print_innodb_tablespace_monitor && difftime(current_time, last_tablespace_monitor_time) > 60) { - last_tablespace_monitor_time = time(NULL); + last_tablespace_monitor_time = ut_time(); fputs("========================" "========================\n", @@ -2156,7 +2171,7 @@ loop: if (srv_print_innodb_table_monitor && difftime(current_time, last_table_monitor_time) > 60) { - last_table_monitor_time = time(NULL); + last_table_monitor_time = ut_time(); fputs("===========================================\n", stderr); @@ -2216,16 +2231,20 @@ srv_lock_timeout_thread( ibool some_waits; double wait_time; ulint i; + ib_int64_t sig_count; #ifdef UNIV_PFS_THREAD pfs_register_thread(srv_lock_timeout_thread_key); #endif loop: + /* When someone is waiting for a lock, we wake up every second and check if a timeout has passed for a lock wait */ - os_thread_sleep(1000000); + sig_count = os_event_reset(srv_timeout_event); + + os_event_wait_time_low(srv_timeout_event, 1000000, sig_count); srv_lock_timeout_active = TRUE; @@ -2320,6 +2339,7 @@ srv_error_monitor_thread( ulint fatal_cnt = 0; ib_uint64_t old_lsn; ib_uint64_t new_lsn; + ib_int64_t sig_count; old_lsn = srv_start_lsn; @@ -2395,7 +2415,9 @@ loop: fflush(stderr); - os_thread_sleep(1000000); + sig_count = os_event_reset(srv_error_event); + + os_event_wait_time_low(srv_error_event, 1000000, sig_count); if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) { @@ -2646,28 +2668,6 @@ loop: for (i = 0; i < 10; i++) { ulint cur_time = ut_time_ms(); - buf_get_total_stat(&buf_stat); - - n_ios_old = log_sys->n_log_ios + buf_stat.n_pages_read - + buf_stat.n_pages_written; - - srv_main_thread_op_info = "sleeping"; - srv_main_1_second_loops++; - - if (next_itr_time > cur_time) { - - /* Get sleep interval in micro seconds. We use - ut_min() to avoid long sleep in case of - wrap around. */ - os_thread_sleep(ut_min(1000000, - (next_itr_time - cur_time) - * 1000)); - srv_main_sleeps++; - } - - /* Each iteration should happen at 1 second interval. */ - next_itr_time = ut_time_ms() + 1000; - /* ALTER TABLE in MySQL requires on Unix that the table handler can drop tables lazily after there no longer are SELECT queries to them. */ @@ -2683,6 +2683,29 @@ loop: goto background_loop; } + buf_get_total_stat(&buf_stat); + + n_ios_old = log_sys->n_log_ios + buf_stat.n_pages_read + + buf_stat.n_pages_written; + + srv_main_thread_op_info = "sleeping"; + srv_main_1_second_loops++; + + if (next_itr_time > cur_time + && srv_shutdown_state == SRV_SHUTDOWN_NONE) { + + /* Get sleep interval in micro seconds. We use + ut_min() to avoid long sleep in case of + wrap around. */ + os_thread_sleep(ut_min(1000000, + (next_itr_time - cur_time) + * 1000)); + srv_main_sleeps++; + } + + /* Each iteration should happen at 1 second interval. */ + next_itr_time = ut_time_ms() + 1000; + /* Flush logs if needed */ srv_sync_log_buffer_in_background(); @@ -2860,7 +2883,9 @@ background_loop: MySQL tries to drop a table while there are still open handles to it and we had to put it to the background drop queue.) */ - os_thread_sleep(100000); + if (srv_shutdown_state == SRV_SHUTDOWN_NONE) { + os_thread_sleep(100000); + } } if (srv_n_purge_threads == 0) { From 5a57a45c663e460911f204173921cf9981158c14 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Thu, 14 Oct 2010 11:02:37 +0200 Subject: [PATCH 069/151] Follow-up for Bug #55930 Assertion `thd->transaction.stmt.is_empty() || thd->in_sub_stmt || (thd->state.. Don't rollback statement transactions if we are in a sub-statement. This could for example happen for open_ltable() when opening the general log during execution of a stored procedure. --- sql/sql_base.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8090d8a9288..fe7ec83b845 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5320,7 +5320,8 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type, end: if (table == NULL) { - trans_rollback_stmt(thd); + if (!thd->in_sub_stmt) + trans_rollback_stmt(thd); close_thread_tables(thd); } thd_proc_info(thd, 0); From f918ad4381a0b3586e780749fb82c3bea3b5a82e Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 14 Oct 2010 12:28:25 +0300 Subject: [PATCH 070/151] Fix Bug#56143 too many foreign keys causes output of show create table to become invalid This is a port of the following changeset from 5.1/storage/innobase to 5.1/storage/innodb_plugin: ------------------------------------------------------------ revno: 3626 revision-id: vasil.dimov@oracle.com-20101013171859-gi9n558yj89x9v3w parent: klewis@mysql.com-20101012175933-ce9kkgl0z8oeqffa committer: Vasil Dimov branch nick: mysql-5.1-innodb timestamp: Wed 2010-10-13 20:18:59 +0300 message: Fix Bug#56143 too many foreign keys causes output of show create table to become invalid Just remove the check whether the file is "too big". A similar code exists in ha_innobase::update_table_comment() but that method does not seem to be used. Also use a CREATE statement with all the FKs instead of ALTERing the table 550 times because it is faster. --- .../innodb_plugin/r/innodb_bug56143.result | 556 +++++++++++++++++ .../innodb_plugin/t/innodb_bug56143.test | 581 ++++++++++++++++++ storage/innodb_plugin/handler/ha_innodb.cc | 2 - 3 files changed, 1137 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug56143.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug56143.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug56143.result b/mysql-test/suite/innodb_plugin/r/innodb_bug56143.result new file mode 100644 index 00000000000..1efec7e8887 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug56143.result @@ -0,0 +1,556 @@ +SHOW CREATE TABLE bug56143_2; +Table Create Table +bug56143_2 CREATE TABLE `bug56143_2` ( + `a` int(11) DEFAULT NULL, + KEY `a` (`a`), + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa100` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa103` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa104` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa105` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa106` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa107` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa108` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa109` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa110` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa111` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa112` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa113` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa114` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa115` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa116` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa117` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa118` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa119` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa120` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa121` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa122` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa124` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa125` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa126` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa127` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa128` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa129` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa13` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa130` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa131` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa132` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa133` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa134` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa135` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa136` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa137` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa138` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa139` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa14` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa140` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa141` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa142` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa143` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa144` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa145` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa146` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa147` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa148` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa149` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa15` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa150` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa151` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa152` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa153` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa154` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa155` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa156` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa157` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa158` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa159` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa16` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa160` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa161` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa162` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa163` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa164` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa165` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa166` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa167` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa168` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa169` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa17` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa170` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa171` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa172` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa173` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa174` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa175` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa176` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa177` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa178` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa179` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa18` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa180` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa181` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa182` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa183` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa184` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa185` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa186` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa187` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa188` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa189` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa19` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa190` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa191` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa192` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa193` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa194` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa195` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa196` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa197` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa198` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa199` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa200` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa201` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa202` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa203` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa204` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa205` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa206` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa207` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa208` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa209` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa21` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa210` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa211` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa212` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa213` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa214` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa215` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa216` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa217` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa218` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa219` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa22` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa220` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa221` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa222` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa223` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa224` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa225` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa226` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa227` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa228` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa229` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa23` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa230` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa231` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa232` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa233` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa234` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa235` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa236` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa237` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa238` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa239` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa24` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa240` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa241` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa242` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa243` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa244` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa245` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa246` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa247` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa248` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa249` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa25` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa250` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa251` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa252` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa253` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa254` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa255` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa256` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa257` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa258` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa259` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa26` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa260` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa261` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa262` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa263` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa264` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa265` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa266` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa267` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa268` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa269` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa27` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa270` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa271` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa272` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa273` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa274` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa275` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa276` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa277` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa278` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa279` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa28` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa280` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa281` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa282` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa283` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa284` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa285` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa286` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa287` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa288` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa289` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa29` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa290` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa291` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa292` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa293` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa294` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa295` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa296` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa297` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa298` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa299` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa30` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa300` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa301` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa302` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa303` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa304` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa305` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa306` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa307` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa308` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa309` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa31` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa310` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa311` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa312` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa313` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa314` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa315` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa316` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa317` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa318` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa319` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa32` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa320` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa321` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa322` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa323` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa324` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa325` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa326` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa327` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa328` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa329` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa33` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa330` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa331` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa332` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa333` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa334` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa335` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa336` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa337` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa338` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa339` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa34` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa340` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa341` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa342` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa343` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa344` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa345` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa346` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa347` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa348` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa349` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa35` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa350` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa351` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa352` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa353` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa354` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa355` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa356` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa357` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa358` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa359` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa36` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa360` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa361` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa362` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa363` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa364` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa365` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa366` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa367` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa368` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa369` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa37` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa370` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa371` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa372` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa373` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa374` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa375` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa376` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa377` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa378` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa379` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa38` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa380` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa381` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa382` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa383` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa384` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa385` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa386` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa387` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa388` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa389` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa39` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa390` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa391` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa392` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa393` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa394` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa395` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa396` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa397` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa398` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa399` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa40` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa400` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa401` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa402` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa403` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa404` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa405` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa406` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa407` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa408` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa409` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa41` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa410` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa411` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa412` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa413` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa414` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa415` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa416` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa417` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa418` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa419` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa42` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa420` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa421` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa422` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa423` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa424` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa425` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa426` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa427` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa428` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa429` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa43` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa430` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa431` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa432` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa433` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa434` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa435` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa436` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa437` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa438` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa439` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa44` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa440` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa441` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa442` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa443` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa444` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa445` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa446` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa447` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa448` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa449` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa45` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa450` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa451` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa452` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa453` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa454` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa455` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa456` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa457` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa458` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa459` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa46` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa460` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa461` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa462` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa463` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa464` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa465` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa466` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa467` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa468` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa469` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa47` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa470` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa471` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa472` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa473` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa474` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa475` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa476` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa477` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa478` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa479` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa48` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa480` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa481` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa482` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa483` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa484` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa485` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa486` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa487` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa488` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa489` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa49` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa490` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa491` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa492` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa493` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa494` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa495` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa496` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa497` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa498` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa499` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa50` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa500` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa501` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa502` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa503` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa504` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa505` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa506` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa507` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa508` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa509` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa51` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa510` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa511` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa512` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa513` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa514` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa515` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa516` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa517` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa518` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa519` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa52` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa520` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa521` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa522` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa523` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa524` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa525` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa526` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa527` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa528` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa529` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa53` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa530` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa531` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa532` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa533` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa534` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa535` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa536` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa537` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa538` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa539` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa54` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa540` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa541` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa542` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa543` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa544` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa545` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa546` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa547` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa548` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa549` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa55` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa550` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa56` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa57` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa58` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa59` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa60` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa61` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa62` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa63` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa64` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa65` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa66` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa67` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa68` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa69` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa7` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa70` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa71` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa72` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa73` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa74` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa75` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa76` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa77` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa78` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa79` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa80` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa81` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa82` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa83` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa84` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa85` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa86` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa87` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa88` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa89` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa90` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa91` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa92` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa93` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa94` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa95` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa96` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa97` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa98` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa99` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug56143.test b/mysql-test/suite/innodb_plugin/t/innodb_bug56143.test new file mode 100644 index 00000000000..7c7472303db --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug56143.test @@ -0,0 +1,581 @@ +# +# Bug#56143 too many foreign keys causes output of show create table to become invalid +# http://bugs.mysql.com/56143 +# + +-- source include/have_innodb_plugin.inc + +-- disable_query_log +-- disable_result_log + +SET foreign_key_checks=0; + +DROP TABLE IF EXISTS bug56143_1; +DROP TABLE IF EXISTS bug56143_2; + +CREATE TABLE bug56143_1 (a INT, KEY(a)) ENGINE=INNODB; + +CREATE TABLE `bug56143_2` ( + `a` int(11) DEFAULT NULL, + KEY `a` (`a`), + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa100` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa103` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa104` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa105` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa106` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa107` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa108` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa109` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa110` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa111` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa112` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa113` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa114` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa115` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa116` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa117` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa118` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa119` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa120` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa121` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa122` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa124` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa125` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa126` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa127` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa128` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa129` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa13` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa130` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa131` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa132` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa133` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa134` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa135` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa136` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa137` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa138` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa139` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa14` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa140` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa141` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa142` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa143` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa144` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa145` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa146` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa147` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa148` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa149` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa15` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa150` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa151` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa152` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa153` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa154` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa155` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa156` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa157` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa158` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa159` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa16` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa160` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa161` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa162` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa163` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa164` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa165` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa166` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa167` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa168` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa169` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa17` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa170` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa171` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa172` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa173` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa174` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa175` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa176` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa177` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa178` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa179` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa18` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa180` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa181` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa182` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa183` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa184` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa185` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa186` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa187` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa188` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa189` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa19` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa190` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa191` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa192` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa193` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa194` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa195` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa196` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa197` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa198` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa199` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa200` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa201` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa202` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa203` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa204` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa205` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa206` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa207` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa208` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa209` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa21` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa210` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa211` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa212` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa213` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa214` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa215` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa216` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa217` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa218` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa219` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa22` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa220` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa221` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa222` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa223` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa224` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa225` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa226` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa227` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa228` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa229` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa23` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa230` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa231` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa232` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa233` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa234` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa235` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa236` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa237` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa238` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa239` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa24` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa240` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa241` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa242` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa243` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa244` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa245` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa246` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa247` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa248` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa249` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa25` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa250` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa251` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa252` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa253` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa254` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa255` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa256` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa257` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa258` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa259` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa26` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa260` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa261` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa262` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa263` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa264` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa265` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa266` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa267` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa268` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa269` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa27` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa270` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa271` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa272` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa273` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa274` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa275` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa276` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa277` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa278` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa279` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa28` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa280` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa281` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa282` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa283` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa284` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa285` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa286` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa287` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa288` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa289` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa29` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa290` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa291` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa292` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa293` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa294` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa295` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa296` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa297` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa298` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa299` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa30` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa300` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa301` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa302` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa303` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa304` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa305` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa306` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa307` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa308` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa309` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa31` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa310` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa311` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa312` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa313` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa314` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa315` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa316` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa317` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa318` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa319` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa32` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa320` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa321` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa322` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa323` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa324` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa325` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa326` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa327` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa328` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa329` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa33` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa330` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa331` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa332` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa333` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa334` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa335` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa336` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa337` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa338` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa339` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa34` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa340` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa341` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa342` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa343` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa344` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa345` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa346` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa347` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa348` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa349` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa35` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa350` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa351` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa352` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa353` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa354` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa355` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa356` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa357` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa358` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa359` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa36` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa360` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa361` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa362` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa363` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa364` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa365` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa366` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa367` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa368` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa369` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa37` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa370` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa371` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa372` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa373` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa374` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa375` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa376` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa377` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa378` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa379` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa38` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa380` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa381` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa382` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa383` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa384` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa385` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa386` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa387` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa388` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa389` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa39` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa390` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa391` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa392` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa393` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa394` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa395` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa396` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa397` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa398` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa399` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa40` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa400` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa401` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa402` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa403` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa404` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa405` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa406` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa407` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa408` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa409` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa41` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa410` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa411` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa412` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa413` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa414` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa415` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa416` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa417` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa418` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa419` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa42` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa420` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa421` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa422` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa423` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa424` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa425` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa426` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa427` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa428` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa429` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa43` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa430` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa431` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa432` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa433` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa434` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa435` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa436` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa437` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa438` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa439` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa44` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa440` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa441` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa442` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa443` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa444` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa445` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa446` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa447` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa448` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa449` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa45` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa450` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa451` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa452` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa453` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa454` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa455` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa456` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa457` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa458` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa459` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa46` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa460` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa461` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa462` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa463` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa464` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa465` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa466` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa467` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa468` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa469` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa47` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa470` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa471` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa472` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa473` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa474` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa475` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa476` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa477` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa478` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa479` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa48` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa480` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa481` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa482` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa483` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa484` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa485` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa486` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa487` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa488` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa489` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa49` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa490` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa491` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa492` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa493` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa494` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa495` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa496` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa497` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa498` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa499` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa50` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa500` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa501` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa502` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa503` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa504` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa505` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa506` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa507` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa508` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa509` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa51` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa510` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa511` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa512` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa513` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa514` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa515` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa516` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa517` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa518` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa519` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa52` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa520` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa521` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa522` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa523` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa524` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa525` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa526` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa527` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa528` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa529` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa53` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa530` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa531` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa532` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa533` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa534` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa535` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa536` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa537` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa538` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa539` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa54` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa540` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa541` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa542` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa543` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa544` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa545` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa546` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa547` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa548` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa549` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa55` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa550` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa56` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa57` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa58` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa59` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa60` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa61` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa62` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa63` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa64` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa65` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa66` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa67` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa68` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa69` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa7` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa70` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa71` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa72` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa73` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa74` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa75` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa76` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa77` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa78` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa79` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa80` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa81` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa82` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa83` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa84` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa85` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa86` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa87` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa88` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa89` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa90` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa91` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa92` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa93` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa94` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa95` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa96` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa97` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa98` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa99` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL +) ENGINE=InnoDB; + +-- enable_query_log +-- enable_result_log + +SHOW CREATE TABLE bug56143_2; + +-- disable_query_log +-- disable_result_log +DROP TABLE bug56143_1; +DROP TABLE bug56143_2; diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 9a9cc32c81b..bb6d192bc79 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -8097,8 +8097,6 @@ ha_innobase::get_foreign_key_create_info(void) flen = ftell(srv_dict_tmpfile); if (flen < 0) { flen = 0; - } else if (flen > 64000 - 1) { - flen = 64000 - 1; } /* allocate buffer for the string, and From c8163ef1dc7e1e726303bac8ca9638886e0d51a2 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 14 Oct 2010 12:33:56 +0300 Subject: [PATCH 071/151] Tune the test for Bug#56143 too many foreign keys causes output of show create table to become invalid Use a CREATE statement with all the FKs instead of ALTERing the table many times because it is faster (11 seconds vs 3 seconds). --- .../suite/innodb/t/innodb_bug56143.test | 566 +++++++++++++++++- 1 file changed, 558 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/innodb/t/innodb_bug56143.test b/mysql-test/suite/innodb/t/innodb_bug56143.test index 45c174fd280..1218ae6621c 100644 --- a/mysql-test/suite/innodb/t/innodb_bug56143.test +++ b/mysql-test/suite/innodb/t/innodb_bug56143.test @@ -10,14 +10,564 @@ SET foreign_key_checks=0; DROP TABLE IF EXISTS bug56143; -CREATE TABLE bug56143 (a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) ENGINE=INNODB; - -let $i = 550; -while ($i) -{ - eval ALTER TABLE `bug56143` ADD CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$i` FOREIGN KEY (`b`) REFERENCES `bug56143`(`b`) ON UPDATE SET NULL; - dec $i; -} +CREATE TABLE `bug56143` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + KEY `a` (`a`), + KEY `b` (`b`), + KEY `c` (`c`), + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa100` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa103` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa104` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa105` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa106` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa107` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa108` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa109` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa110` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa111` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa112` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa113` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa114` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa115` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa116` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa117` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa118` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa119` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa120` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa121` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa122` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa124` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa125` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa126` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa127` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa128` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa129` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa13` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa130` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa131` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa132` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa133` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa134` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa135` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa136` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa137` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa138` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa139` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa14` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa140` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa141` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa142` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa143` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa144` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa145` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa146` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa147` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa148` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa149` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa15` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa150` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa151` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa152` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa153` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa154` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa155` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa156` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa157` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa158` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa159` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa16` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa160` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa161` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa162` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa163` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa164` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa165` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa166` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa167` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa168` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa169` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa17` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa170` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa171` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa172` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa173` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa174` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa175` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa176` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa177` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa178` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa179` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa18` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa180` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa181` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa182` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa183` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa184` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa185` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa186` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa187` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa188` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa189` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa19` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa190` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa191` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa192` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa193` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa194` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa195` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa196` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa197` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa198` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa199` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa200` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa201` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa202` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa203` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa204` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa205` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa206` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa207` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa208` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa209` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa21` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa210` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa211` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa212` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa213` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa214` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa215` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa216` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa217` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa218` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa219` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa22` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa220` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa221` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa222` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa223` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa224` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa225` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa226` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa227` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa228` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa229` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa23` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa230` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa231` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa232` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa233` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa234` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa235` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa236` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa237` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa238` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa239` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa24` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa240` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa241` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa242` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa243` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa244` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa245` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa246` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa247` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa248` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa249` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa25` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa250` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa251` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa252` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa253` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa254` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa255` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa256` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa257` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa258` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa259` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa26` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa260` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa261` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa262` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa263` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa264` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa265` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa266` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa267` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa268` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa269` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa27` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa270` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa271` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa272` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa273` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa274` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa275` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa276` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa277` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa278` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa279` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa28` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa280` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa281` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa282` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa283` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa284` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa285` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa286` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa287` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa288` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa289` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa29` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa290` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa291` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa292` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa293` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa294` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa295` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa296` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa297` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa298` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa299` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa30` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa300` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa301` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa302` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa303` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa304` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa305` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa306` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa307` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa308` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa309` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa31` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa310` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa311` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa312` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa313` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa314` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa315` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa316` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa317` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa318` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa319` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa32` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa320` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa321` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa322` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa323` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa324` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa325` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa326` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa327` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa328` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa329` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa33` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa330` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa331` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa332` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa333` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa334` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa335` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa336` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa337` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa338` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa339` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa34` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa340` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa341` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa342` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa343` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa344` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa345` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa346` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa347` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa348` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa349` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa35` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa350` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa351` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa352` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa353` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa354` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa355` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa356` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa357` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa358` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa359` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa36` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa360` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa361` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa362` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa363` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa364` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa365` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa366` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa367` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa368` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa369` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa37` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa370` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa371` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa372` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa373` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa374` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa375` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa376` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa377` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa378` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa379` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa38` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa380` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa381` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa382` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa383` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa384` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa385` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa386` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa387` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa388` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa389` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa39` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa390` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa391` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa392` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa393` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa394` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa395` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa396` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa397` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa398` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa399` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa40` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa400` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa401` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa402` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa403` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa404` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa405` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa406` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa407` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa408` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa409` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa41` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa410` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa411` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa412` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa413` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa414` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa415` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa416` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa417` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa418` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa419` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa42` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa420` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa421` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa422` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa423` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa424` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa425` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa426` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa427` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa428` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa429` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa43` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa430` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa431` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa432` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa433` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa434` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa435` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa436` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa437` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa438` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa439` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa44` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa440` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa441` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa442` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa443` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa444` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa445` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa446` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa447` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa448` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa449` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa45` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa450` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa451` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa452` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa453` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa454` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa455` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa456` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa457` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa458` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa459` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa46` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa460` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa461` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa462` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa463` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa464` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa465` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa466` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa467` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa468` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa469` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa47` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa470` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa471` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa472` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa473` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa474` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa475` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa476` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa477` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa478` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa479` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa48` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa480` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa481` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa482` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa483` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa484` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa485` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa486` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa487` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa488` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa489` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa49` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa490` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa491` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa492` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa493` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa494` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa495` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa496` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa497` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa498` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa499` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa50` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa500` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa501` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa502` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa503` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa504` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa505` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa506` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa507` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa508` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa509` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa51` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa510` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa511` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa512` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa513` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa514` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa515` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa516` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa517` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa518` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa519` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa52` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa520` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa521` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa522` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa523` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa524` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa525` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa526` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa527` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa528` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa529` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa53` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa530` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa531` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa532` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa533` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa534` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa535` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa536` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa537` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa538` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa539` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa54` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa540` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa541` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa542` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa543` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa544` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa545` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa546` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa547` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa548` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa549` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa55` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa550` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa56` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa57` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa58` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa59` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa60` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa61` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa62` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa63` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa64` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa65` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa66` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa67` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa68` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa69` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa7` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa70` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa71` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa72` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa73` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa74` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa75` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa76` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa77` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa78` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa79` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa80` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa81` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa82` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa83` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa84` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa85` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa86` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa87` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa88` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa89` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa90` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa91` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa92` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa93` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa94` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa95` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa96` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa97` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa98` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa99` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL +) ENGINE=InnoDB; -- enable_query_log -- enable_result_log From 650e4c25db94273bdf2300ddb987294f0d4edd72 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Thu, 14 Oct 2010 14:05:59 +0400 Subject: [PATCH 072/151] A patch for Bug#48874 (Test "is_triggers" fails because of wrong charset info). The thing is that the following attributes are fixed (remembered) when a trigger is created: - character_set_client - character_set_results - collation_connection There are two triggers created in mysql-test/include/mtr_warnings.sql. They were created using "current default" character set / collation. is_triggers.test shows definition of these triggers including recorded character set information. The problem was that if "current default" changed, the recorded character set information was not accurate. There might be two ways to fix that: a) update is_triggers.test so that it does not put character-set information into result-file; b) update mtr_warnings.sql so that the triggers are created using hard-coded character sets. This patch implements option b). --- mysql-test/include/mtr_warnings.sql | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql index bf0a58788d6..f793ff54e86 100644 --- a/mysql-test/include/mtr_warnings.sql +++ b/mysql-test/include/mtr_warnings.sql @@ -16,6 +16,12 @@ CREATE TABLE test_suppressions ( -- no invalid patterns can be inserted -- into test_suppressions -- +SET @character_set_client_saved = @@character_set_client|| +SET @character_set_results_saved = @@character_set_results|| +SET @collation_connection_saved = @@collation_connection|| +SET @@character_set_client = latin1|| +SET @@character_set_results = latin1|| +SET @@collation_connection = latin1_swedish_ci|| /*!50002 CREATE DEFINER=root@localhost TRIGGER ts_insert BEFORE INSERT ON test_suppressions @@ -24,6 +30,9 @@ FOR EACH ROW BEGIN SELECT "" REGEXP NEW.pattern INTO dummy; END */|| +SET @@character_set_client = @character_set_client_saved|| +SET @@character_set_results = @character_set_results_saved|| +SET @@collation_connection = @collation_connection_saved|| -- @@ -38,6 +47,12 @@ CREATE TABLE global_suppressions ( -- no invalid patterns can be inserted -- into global_suppressions -- +SET @character_set_client_saved = @@character_set_client|| +SET @character_set_results_saved = @@character_set_results|| +SET @collation_connection_saved = @@collation_connection|| +SET @@character_set_client = latin1|| +SET @@character_set_results = latin1|| +SET @@collation_connection = latin1_swedish_ci|| /*!50002 CREATE DEFINER=root@localhost TRIGGER gs_insert BEFORE INSERT ON global_suppressions @@ -46,6 +61,9 @@ FOR EACH ROW BEGIN SELECT "" REGEXP NEW.pattern INTO dummy; END */|| +SET @@character_set_client = @character_set_client_saved|| +SET @@character_set_results = @character_set_results_saved|| +SET @@collation_connection = @collation_connection_saved|| From 27c80dd4242be8a04c17df5a4235ac6a5de45635 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 14 Oct 2010 04:19:52 -0700 Subject: [PATCH 073/151] Remove an unused counter variable in io_handler_thread(). --- storage/innodb_plugin/srv/srv0start.c | 1 - 1 file changed, 1 deletion(-) diff --git a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c index 2d339596013..f823b72fbc1 100644 --- a/storage/innodb_plugin/srv/srv0start.c +++ b/storage/innodb_plugin/srv/srv0start.c @@ -463,7 +463,6 @@ io_handler_thread( the aio array */ { ulint segment; - ulint i; segment = *((ulint*)arg); From 248625d910dda9848c99f28c5c73c4e4a9bfc4ae Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Thu, 14 Oct 2010 20:56:56 +0400 Subject: [PATCH 074/151] A fix and a test case for Bug#56540 "Exception (crash) in sql_show.cc during rqg_info_schema test on Windows". Ensure we do not access freed memory when filling information_schema.views when one of the views could not be properly opened. mysql-test/r/information_schema.result: Update results - a fix for Bug#56540. mysql-test/t/information_schema.test: Add a test case for Bug#56540 sql/sql_base.cc: Push an error into the Diagnostics area when we return an error. This directs get_all_tables() to the execution branch which doesn't involve 'process_table()' when no table/view was opened. sql/sql_show.cc: Do not try to access underlying table fields when opening of a view failed. The underlying table is closed in that case, and accessing its fields may lead to dereferencing a damaged pointer. --- mysql-test/r/information_schema.result | 44 +++++++++++++++++++++ mysql-test/t/information_schema.test | 53 ++++++++++++++++++++++++++ sql/sql_base.cc | 10 ++++- sql/sql_show.cc | 25 ++++++++---- 4 files changed, 124 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index aa47b8c437e..bab60774b32 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1807,3 +1807,47 @@ USING (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME) WHERE COLUMNS.TABLE_SCHEMA = 'test' AND COLUMNS.TABLE_NAME = 't1'; TABLE_SCHEMA TABLE_NAME COLUMN_NAME CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG ORDINAL_POSITION POSITION_IN_UNIQUE_CONSTRAINT REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME TABLE_CATALOG ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT +# +# A test case for Bug#56540 "Exception (crash) in sql_show.cc +# during rqg_info_schema test on Windows" +# Ensure that we never access memory of a closed table, +# in particular, never access table->field[] array. +# Before the fix, the below test case, produced +# valgrind errors. +# +drop table if exists t1; +drop view if exists v1; +create table t1 (a int, b int); +create view v1 as select t1.a, t1.b from t1; +alter table t1 change b c int; +lock table t1 read; +# --> connection con1 +flush tables; +# --> connection default +select * from information_schema.views; +TABLE_CATALOG def +TABLE_SCHEMA test +TABLE_NAME v1 +VIEW_DEFINITION select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` +CHECK_OPTION NONE +IS_UPDATABLE +DEFINER root@localhost +SECURITY_TYPE DEFINER +CHARACTER_SET_CLIENT latin1 +COLLATION_CONNECTION latin1_swedish_ci +Warnings: +Level Warning +Code 1356 +Message View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +unlock tables; +# +# Cleanup. +# +# --> connection con1 +# Reaping 'flush tables' +# --> connection default +drop table t1; +drop view v1; +# +# End of 5.5 tests +# diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index f5fab966bdd..bc73e8411ca 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1555,3 +1555,56 @@ WHERE COLUMNS.TABLE_SCHEMA = 'test' AND COLUMNS.TABLE_NAME = 't1'; +--echo # +--echo # A test case for Bug#56540 "Exception (crash) in sql_show.cc +--echo # during rqg_info_schema test on Windows" +--echo # Ensure that we never access memory of a closed table, +--echo # in particular, never access table->field[] array. +--echo # Before the fix, the below test case, produced +--echo # valgrind errors. +--echo # + +--disable_warnings +drop table if exists t1; +drop view if exists v1; +--enable_warnings + +create table t1 (a int, b int); +create view v1 as select t1.a, t1.b from t1; +alter table t1 change b c int; +lock table t1 read; +connect(con1, localhost, root,,); +--echo # --> connection con1 +connection con1; +send flush tables; +--echo # --> connection default +connection default; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table flush" and + info = "flush tables"; +--source include/wait_condition.inc +--vertical_results +select * from information_schema.views; +--horizontal_results +unlock tables; + +--echo # +--echo # Cleanup. +--echo # + +--echo # --> connection con1 +connection con1; +--echo # Reaping 'flush tables' +reap; +disconnect con1; +--source include/wait_until_disconnected.inc +--echo # --> connection default +connection default; +drop table t1; +drop view v1; + + +--echo # +--echo # End of 5.5 tests +--echo # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index fe7ec83b845..8caae3ee406 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2902,8 +2902,12 @@ retry_share: */ if (check_and_update_table_version(thd, table_list, share)) goto err_unlock; - if (table_list->i_s_requested_object & OPEN_TABLE_ONLY) + if (table_list->i_s_requested_object & OPEN_TABLE_ONLY) + { + my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, + table_list->table_name); goto err_unlock; + } /* Open view */ if (open_new_frm(thd, share, alias, @@ -2931,7 +2935,11 @@ retry_share: */ if (table_list->i_s_requested_object & OPEN_VIEW_ONLY) + { + my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, + table_list->table_name); goto err_unlock; + } if (!(flags & MYSQL_OPEN_IGNORE_FLUSH)) { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 16deb50b17c..a25cfcdedc8 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4934,18 +4934,29 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, else table->field[4]->store(STRING_WITH_LEN("NONE"), cs); - if (table->pos_in_table_list->table_open_method & - OPEN_FULL_TABLE) + /* + Only try to fill in the information about view updatability + if it is requested as part of the top-level query (i.e. + it's select * from i_s.views, as opposed to, say, select + security_type from i_s.views). Do not try to access the + underlying tables if there was an error when opening the + view: all underlying tables are released back to the table + definition cache on error inside open_normal_and_derived_tables(). + If a field is not assigned explicitly, it defaults to NULL. + */ + if (res == FALSE && + table->pos_in_table_list->table_open_method & OPEN_FULL_TABLE) { updatable_view= 0; if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE) { /* - We should use tables->view->select_lex.item_list here and - can not use Field_iterator_view because the view always uses - temporary algorithm during opening for I_S and - TABLE_LIST fields 'field_translation' & 'field_translation_end' - are uninitialized is this case. + We should use tables->view->select_lex.item_list here + and can not use Field_iterator_view because the view + always uses temporary algorithm during opening for I_S + and TABLE_LIST fields 'field_translation' + & 'field_translation_end' are uninitialized is this + case. */ List *fields= &tables->view->select_lex.item_list; List_iterator it(*fields); From 3ce802d5d8ef92469bf5eeec649c2dca55ac4944 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 15 Oct 2010 17:26:58 +0300 Subject: [PATCH 075/151] Fix the formatting in storage/innodb_plugin/ChangeLog --- storage/innodb_plugin/ChangeLog | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index d193dcd321c..69506b621f2 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,36 +1,39 @@ 2010-10-14 The InnoDB Team - * srv/srv0start.c - Fix Bug #57397 io_handler_thread() will never cleanup + + * srv/srv0start.c: + Fix Bug#57397 io_handler_thread() will never cleanup 2010-10-11 The InnoDB Team - * row/row0sel.c - Fix Bug #57345 btr_pcur_store_position abort for load with - concurrent lock/unlock tables + + * row/row0sel.c: + Fix Bug#57345 btr_pcur_store_position abort for load with concurrent + lock/unlock tables 2010-09-27 The InnoDB Team * row/row0sel.c, innodb_bug56716.result, innodb_bug56716.test: - Fix Bug #56716 InnoDB locks a record gap without locking the table + Fix Bug#56716 InnoDB locks a record gap without locking the table 2010-09-06 The InnoDB Team - * dict/dict0load.c, innodb_bug53756.test innodb_bug53756.result - Fix Bug #53756 ALTER TABLE ADD PRIMARY KEY affects crash recovery + + * dict/dict0load.c, innodb_bug53756.test innodb_bug53756.result: + Fix Bug#53756 ALTER TABLE ADD PRIMARY KEY affects crash recovery 2010-08-24 The InnoDB Team * handler/ha_innodb.c, dict/dict0dict.c: - Fix Bug #55832 selects crash too easily when innodb_force_recovery>3 + Fix Bug#55832 selects crash too easily when innodb_force_recovery>3 2010-08-03 The InnoDB Team * include/ut0mem.h, ut/ut0mem.c: - Fix Bug #55627 segv in ut_free pars_lexer_close innobase_shutdown + Fix Bug#55627 segv in ut_free pars_lexer_close innobase_shutdown innodb-use-sys-malloc=0 2010-08-01 The InnoDB Team - * handler/ha_innodb.cc - Fix Bug #55382 Assignment with SELECT expressions takes unexpected + * handler/ha_innodb.cc: + Fix Bug#55382 Assignment with SELECT expressions takes unexpected S locks in READ COMMITTED 2010-07-27 The InnoDB Team @@ -52,8 +55,8 @@ 2010-06-29 The InnoDB Team - * btr/btr0cur.c, include/btr0cur.h, - include/row0mysql.h, row/row0merge.c, row/row0sel.c: + * btr/btr0cur.c, include/btr0cur.h, include/row0mysql.h, + row/row0merge.c, row/row0sel.c: Fix Bug#54358 READ UNCOMMITTED access failure of off-page DYNAMIC or COMPRESSED columns From 74b42d8daad141cab6bb4933708e990d4b9d5f11 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 15 Oct 2010 17:30:32 +0300 Subject: [PATCH 076/151] Add InnoDB Plugin ChangeLog entry for Bug#56143 --- storage/innodb_plugin/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 69506b621f2..4441d30420f 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-10-14 The InnoDB Team + + * handler/ha_innodb.cc, innodb_bug56143.result, innodb_bug56143.test: + Fix Bug#56143 too many foreign keys causes output of show create + table to become invalid + 2010-10-14 The InnoDB Team * srv/srv0start.c: From ef858cc463983629394c4aa9a6be3aaeaa585fd6 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 15 Oct 2010 17:50:45 +0300 Subject: [PATCH 077/151] Remove leftover conflict marker It was added in jimmy.yang@oracle.com-20100902004302-m5ax9qo0ne2msdfx --- storage/innodb_plugin/ChangeLog | 1 - 1 file changed, 1 deletion(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index e2aa279dc9b..0adb71fcba2 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -54,7 +54,6 @@ * handler/ha_innodb.cc: Fix Bug#55382 Assignment with SELECT expressions takes unexpected S locks in READ COMMITTED ->>>>>>> MERGE-SOURCE 2010-07-27 The InnoDB Team From 211552ccee98e381a14dfaae754528d9f6ed0494 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Oct 2010 20:03:44 +0800 Subject: [PATCH 078/151] Bug#56118 STOP SLAVE does not wait till trx with CREATE TMP TABLE ends, replication aborts When recieving a 'SLAVE STOP' command, slave SQL thread will roll back the transaction and stop immidiately if there is only transactional table updated, even through 'CREATE|DROP TEMPOARY TABLE' statement are in it. But These statements can never be rolled back. Because the temporary tables to the user session mapping remain until 'RESET SLAVE', Therefore it will abort SQL thread with an error that the table already exists or doesn't exist, when it restarts and executes the whole transaction again. After this patch, SQL thread always waits till the transaction ends and then stops, if 'CREATE|DROP TEMPOARY TABLE' statement are in it. mysql-test/extra/rpl_tests/rpl_stop_slave.test: Auxiliary file which is used to test this bug. mysql-test/suite/rpl/t/rpl_stop_slave.test: Test case for this bug. sql/slave.cc: Checking if OPTION_KEEP_LOG is set. If it is set, SQL thread should wait until the transaction ends. sql/sql_parse.cc: Add a debug point for testing this bug. --- .../extra/rpl_tests/rpl_stop_slave.test | 61 +++++++++ mysql-test/suite/rpl/r/rpl_stop_slave.result | 127 ++++++++++++++++++ mysql-test/suite/rpl/t/rpl_stop_slave.test | 60 +++++++++ sql/slave.cc | 11 +- sql/sql_parse.cc | 10 ++ 5 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 mysql-test/extra/rpl_tests/rpl_stop_slave.test create mode 100644 mysql-test/suite/rpl/r/rpl_stop_slave.result create mode 100644 mysql-test/suite/rpl/t/rpl_stop_slave.test diff --git a/mysql-test/extra/rpl_tests/rpl_stop_slave.test b/mysql-test/extra/rpl_tests/rpl_stop_slave.test new file mode 100644 index 00000000000..7c88afe3532 --- /dev/null +++ b/mysql-test/extra/rpl_tests/rpl_stop_slave.test @@ -0,0 +1,61 @@ +# +# Auxiliary file which is used to test BUG#56118 +# +# Slave should apply all statements in the transaction before stop if any +# temporary table is created or dropped. +# +# USEAGE: +# --let $tmp_table_stm= a SQL statement +# --source extra/rpl_tests/rpl_stop_slave.test +# + +if (`SELECT "$tmp_table_stm" = ''`) +{ + --echo \$tmp_table_stm is NULL + --die $tmp_table_stm is NULL +} + +--echo +--echo [ On Master ] +connection master; +BEGIN; +DELETE FROM t1; +eval $tmp_table_stm; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE tt1; +COMMIT; + +--echo +--echo [ On Slave ] +connection slave; + +# To check if slave SQL thread is applying INSERT statement +let $show_statement= SHOW PROCESSLIST; +let $field= Info; +let $condition= LIKE 'INSERT%'; +source include/wait_show_condition.inc; + +send STOP SLAVE SQL_THREAD; + +--echo +--echo [ On Slave1 ] +connection slave1; +--echo # To resume slave SQL thread +SET DEBUG_SYNC= 'now SIGNAL signal.continue'; +SET DEBUG_SYNC= 'RESET'; + +--echo +--echo [ On Slave ] +connection slave; +reap; +source include/wait_for_slave_sql_to_stop.inc; + +--echo # Slave should stop after the transaction has committed. +--echo # So t1 on master is same to t1 on slave. +let diff_table_1=master:test.t1; +let diff_table_2=slave:test.t1; +source include/diff_tables.inc; + +connection slave; +START SLAVE SQL_THREAD; +source include/wait_for_slave_sql_to_start.inc; diff --git a/mysql-test/suite/rpl/r/rpl_stop_slave.result b/mysql-test/suite/rpl/r/rpl_stop_slave.result new file mode 100644 index 00000000000..49146417ab7 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_stop_slave.result @@ -0,0 +1,127 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; + +# BUG#56118 STOP SLAVE does not wait till trx with CREATE TMP TABLE ends +# +# If a temporary table is created or dropped, the transaction should be +# regarded similarly that a non-transactional table is modified. So +# STOP SLAVE should wait until the transaction has finished. +CREATE TABLE t1(c1 INT) ENGINE=InnoDB; +CREATE TABLE t2(c1 INT) ENGINE=InnoDB; +SET DEBUG_SYNC= 'RESET'; +include/stop_slave.inc + +# Suspend the INSERT statement in current transaction on SQL thread. +# It guarantees that SQL thread is applying the transaction when +# STOP SLAVE command launchs. +SET GLOBAL debug= 'd,after_mysql_insert'; +include/start_slave.inc + +# CREATE TEMPORARY TABLE with InnoDB engine +# ----------------------------------------- + +[ On Master ] +BEGIN; +DELETE FROM t1; +CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE tt1; +COMMIT; + +[ On Slave ] +STOP SLAVE SQL_THREAD; + +[ On Slave1 ] +# To resume slave SQL thread +SET DEBUG_SYNC= 'now SIGNAL signal.continue'; +SET DEBUG_SYNC= 'RESET'; + +[ On Slave ] +# Slave should stop after the transaction has committed. +# So t1 on master is same to t1 on slave. +Comparing tables master:test.t1 and slave:test.t1 +START SLAVE SQL_THREAD; + +# CREATE TEMPORARY TABLE with MyISAM engine +# ----------------------------------------- + +[ On Master ] +BEGIN; +DELETE FROM t1; +CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = MyISAM; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE tt1; +COMMIT; + +[ On Slave ] +STOP SLAVE SQL_THREAD; + +[ On Slave1 ] +# To resume slave SQL thread +SET DEBUG_SYNC= 'now SIGNAL signal.continue'; +SET DEBUG_SYNC= 'RESET'; + +[ On Slave ] +# Slave should stop after the transaction has committed. +# So t1 on master is same to t1 on slave. +Comparing tables master:test.t1 and slave:test.t1 +START SLAVE SQL_THREAD; + +# CREATE TEMPORARY TABLE ... SELECT with InnoDB engine +# ---------------------------------------------------- + +[ On Master ] +BEGIN; +DELETE FROM t1; +CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB +SELECT c1 FROM t2; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE tt1; +COMMIT; + +[ On Slave ] +STOP SLAVE SQL_THREAD; + +[ On Slave1 ] +# To resume slave SQL thread +SET DEBUG_SYNC= 'now SIGNAL signal.continue'; +SET DEBUG_SYNC= 'RESET'; + +[ On Slave ] +# Slave should stop after the transaction has committed. +# So t1 on master is same to t1 on slave. +Comparing tables master:test.t1 and slave:test.t1 +START SLAVE SQL_THREAD; + +# CREATE TEMPORARY TABLE ... SELECT with MyISAM engine +# ---------------------------------------------------- + +[ On Master ] +BEGIN; +DELETE FROM t1; +CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = MyISAM +SELECT 1 AS c1; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE tt1; +COMMIT; + +[ On Slave ] +STOP SLAVE SQL_THREAD; + +[ On Slave1 ] +# To resume slave SQL thread +SET DEBUG_SYNC= 'now SIGNAL signal.continue'; +SET DEBUG_SYNC= 'RESET'; + +[ On Slave ] +# Slave should stop after the transaction has committed. +# So t1 on master is same to t1 on slave. +Comparing tables master:test.t1 and slave:test.t1 +START SLAVE SQL_THREAD; +# Test end +SET GLOBAL debug= '$debug_save'; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/rpl/t/rpl_stop_slave.test b/mysql-test/suite/rpl/t/rpl_stop_slave.test new file mode 100644 index 00000000000..e44cf3e94b7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_stop_slave.test @@ -0,0 +1,60 @@ +source include/master-slave.inc; +source include/have_innodb.inc; +source include/have_debug.inc; +source include/have_debug_sync.inc; +source include/have_binlog_format_mixed_or_statement.inc; + +--echo +--echo # BUG#56118 STOP SLAVE does not wait till trx with CREATE TMP TABLE ends +--echo # +--echo # If a temporary table is created or dropped, the transaction should be +--echo # regarded similarly that a non-transactional table is modified. So +--echo # STOP SLAVE should wait until the transaction has finished. + +CREATE TABLE t1(c1 INT) ENGINE=InnoDB; +CREATE TABLE t2(c1 INT) ENGINE=InnoDB; + +sync_slave_with_master; +SET DEBUG_SYNC= 'RESET'; +source include/stop_slave.inc; + +--echo +--echo # Suspend the INSERT statement in current transaction on SQL thread. +--echo # It guarantees that SQL thread is applying the transaction when +--echo # STOP SLAVE command launchs. +let $debug_save= `SELECT @@GLOBAL.debug`; +SET GLOBAL debug= 'd,after_mysql_insert'; +source include/start_slave.inc; + +--echo +--echo # CREATE TEMPORARY TABLE with InnoDB engine +--echo # ----------------------------------------- +let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB; +source extra/rpl_tests/rpl_stop_slave.test; + +--echo +--echo # CREATE TEMPORARY TABLE with MyISAM engine +--echo # ----------------------------------------- +let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = MyISAM; +source extra/rpl_tests/rpl_stop_slave.test; + +--echo +--echo # CREATE TEMPORARY TABLE ... SELECT with InnoDB engine +--echo # ---------------------------------------------------- +let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB + SELECT c1 FROM t2; +source extra/rpl_tests/rpl_stop_slave.test; + +--echo +--echo # CREATE TEMPORARY TABLE ... SELECT with MyISAM engine +--echo # ---------------------------------------------------- +let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = MyISAM + SELECT 1 AS c1; +source extra/rpl_tests/rpl_stop_slave.test; + +--echo # Test end +SET GLOBAL debug= '$debug_save'; + +connection master; +DROP TABLE t1, t2; +source include/master-slave-end.inc; diff --git a/sql/slave.cc b/sql/slave.cc index 964adfdbf53..57d673ea1f4 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -740,8 +740,17 @@ static bool sql_slave_killed(THD* thd, Relay_log_info* rli) DBUG_ASSERT(rli->slave_running == 1);// tracking buffer overrun if (abort_loop || thd->killed || rli->abort_slave) { + /* + The transaction should always be binlogged if OPTION_KEEP_LOG is set + (it implies that something can not be rolled back). And such case + should be regarded similarly as modifing a non-transactional table + because retrying of the transaction will lead to an error or inconsistency + as well. + Example: OPTION_KEEP_LOG is set if a temporary table is created or dropped. + */ if (rli->abort_slave && rli->is_in_group() && - thd->transaction.all.modified_non_trans_table) + (thd->transaction.all.modified_non_trans_table || + (thd->options & OPTION_KEEP_LOG))) DBUG_RETURN(0); /* If we are in an unsafe situation (stopping could corrupt replication), diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index fbe9c9753d9..b38cdf4a983 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -27,6 +27,7 @@ #include "sp_cache.h" #include "events.h" #include "sql_trigger.h" +#include "debug_sync.h" /** @defgroup Runtime_Environment Runtime Environment @@ -3258,6 +3259,15 @@ end_with_restore_list: thd->first_successful_insert_id_in_cur_stmt= thd->first_successful_insert_id_in_prev_stmt; + DBUG_EXECUTE_IF("after_mysql_insert", + { + const char act[]= + "now " + "wait_for signal.continue"; + DBUG_ASSERT(opt_debug_sync_timeout > 0); + DBUG_ASSERT(!debug_sync_set_action(current_thd, + STRING_WITH_LEN(act))); + };); break; } case SQLCOM_REPLACE_SELECT: From 8776f964078403947a8581d6a61b71a33f5890c7 Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Mon, 18 Oct 2010 17:05:44 +1100 Subject: [PATCH 079/151] Fix bug encountered during testing on BSD. In the original fix for bug# 55681 the check for overflow was wrong and the OS_SYNC_INFINITE_TIME was handled incorrectly. Approved by Jimmy Yang (IM) --- storage/innobase/os/os0sync.c | 63 ++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 975c66ad1e1..5c400ae31c5 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -137,7 +137,7 @@ os_cond_wait_timed( const struct timespec* abstime /*!< in: timeout */ #else ulint time_in_ms /*!< in: timeout in - milliseconds */ + milliseconds*/ #endif /* !__WIN__ */ ) { @@ -160,7 +160,17 @@ os_cond_wait_timed( ret = pthread_cond_timedwait(cond, mutex, abstime); - ut_a(ret == 0 || ret == ETIMEDOUT); + switch (ret) { + case 0: + case ETIMEDOUT: + break; + + default: + fprintf(stderr, " InnoDB: pthread_cond_timedwait() returned: " + "%d: abstime={%lu,%lu}\n", + ret, abstime->tv_sec, abstime->tv_nsec); + ut_error; + } return(ret == ETIMEDOUT); #endif @@ -637,14 +647,15 @@ os_event_wait_time_low( ib_int64_t old_signal_count; #ifdef __WIN__ - DWORD time_in_ms = time_in_usec / 1000; + DWORD time_in_ms; if (!srv_use_native_conditions) { DWORD err; ut_a(event); - if (time_in_ms != OS_SYNC_INFINITE_TIME) { + if (time_in_usec != OS_SYNC_INFINITE_TIME) { + time_in_ms = time_in_ms / 1000; err = WaitForSingleObject(event->handle, time_in_ms); } else { err = WaitForSingleObject(event->handle, INFINITE); @@ -661,30 +672,44 @@ os_event_wait_time_low( return(42); } else { ut_a(sleep_condition_variable != NULL); + + if (time_in_usec != OS_SYNC_INFINITE_TIME) { + time_in_ms = time_in_usec / 1000; + } else { + time_in_ms = INFINITE; + } } #else - struct timeval tv; - ulint sec; - ulint usec; - int ret; struct timespec abstime; - ret = ut_usectime(&sec, &usec); - ut_a(ret == 0); + if (time_in_usec != OS_SYNC_INFINITE_TIME) { + struct timeval tv; + int ret; + ulint sec; + ulint usec; - tv.tv_sec = sec; - tv.tv_usec = usec; + ret = ut_usectime(&sec, &usec); + ut_a(ret == 0); - tv.tv_usec += time_in_usec; + tv.tv_sec = sec; + tv.tv_usec = usec; - if ((ulint) tv.tv_usec > MICROSECS_IN_A_SECOND) { - tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND; - tv.tv_usec %= MICROSECS_IN_A_SECOND; + tv.tv_usec += time_in_usec; + + if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) { + tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND; + tv.tv_usec %= MICROSECS_IN_A_SECOND; + } + + abstime.tv_sec = tv.tv_sec; + abstime.tv_nsec = tv.tv_usec * 1000; + } else { + abstime.tv_nsec = 999999999; + abstime.tv_sec = (time_t) ULINT_MAX; } - /* Convert to nano seconds. We ignore overflow. */ - abstime.tv_sec = tv.tv_sec; - abstime.tv_nsec = tv.tv_usec * 1000; + ut_a(abstime.tv_nsec <= 999999999); + #endif /* __WIN__ */ os_fast_mutex_lock(&event->os_mutex); From 902b13fa5725b8f19f52f962d5a98b65018cce5b Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 18 Oct 2010 13:48:11 +0300 Subject: [PATCH 080/151] Fix Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE In order to fix this bug we need to distinguish whether ha_innobase::info() has been called from ::analyze() or not. Rename ::info() to ::info_low() and add a boolean parameter that tells whether the call is from ::analyze() or not. Create a new simple ::info() that just calls ::info_low(false => not called from analyze). From ::analyze() instead of ::info() call ::info_low(true => called from analyze). Approved by: Jimmy (rb://487) --- .../suite/innodb/r/innodb_bug57252.result | 6 +++ .../suite/innodb/t/innodb_bug57252.test | 46 +++++++++++++++++++ storage/innobase/handler/ha_innodb.cc | 26 +++++++++-- storage/innobase/handler/ha_innodb.h | 1 + 4 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug57252.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug57252.test diff --git a/mysql-test/suite/innodb/r/innodb_bug57252.result b/mysql-test/suite/innodb/r/innodb_bug57252.result new file mode 100644 index 00000000000..efa50c742e0 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug57252.result @@ -0,0 +1,6 @@ +cardinality +10 +Table Op Msg_type Msg_text +test.bug57252 analyze status OK +cardinality +10 diff --git a/mysql-test/suite/innodb/t/innodb_bug57252.test b/mysql-test/suite/innodb/t/innodb_bug57252.test new file mode 100644 index 00000000000..04c3ed0cea7 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug57252.test @@ -0,0 +1,46 @@ +# +# Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE +# http://bugs.mysql.com/57252 +# + +-- source include/have_innodb.inc + +-- disable_query_log +-- disable_result_log + +SET @innodb_stats_on_metadata_orig = @@innodb_stats_on_metadata; + +CREATE TABLE bug57252 (a INT, KEY akey (a)) ENGINE=INNODB; + +BEGIN; +let $i = 10; +while ($i) { + eval INSERT INTO bug57252 VALUES ($i); + dec $i; +} +COMMIT; + +-- enable_result_log + +SET GLOBAL innodb_stats_on_metadata=0; + +# this calls ::info() without HA_STATUS_CONST and so +# index->stat_n_diff_key_vals[] is not copied to the mysql-visible +# rec_per_key +SELECT cardinality FROM information_schema.statistics +WHERE table_name='bug57252' AND index_name='akey'; + +# this calls ::info() with HA_STATUS_CONST and so +# index->stat_n_diff_key_vals[] is copied to the mysql-visible +# rec_per_key at the end; when the bug is present dict_update_statistics() +# is not called beforehand and so index->stat_n_diff_key_vals[] contains +# an outdated data and thus we get an outdated data in the result when the +# bug is present +ANALYZE TABLE bug57252; + +SELECT cardinality FROM information_schema.statistics +WHERE table_name='bug57252' AND index_name='akey'; + +DROP TABLE bug57252; + +SET GLOBAL innodb_stats_on_metadata = @innodb_stats_on_metadata_orig; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index d5944864ad9..5a8f5479223 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6367,9 +6367,12 @@ Returns statistics information of the table to the MySQL interpreter, in various fields of the handle object. */ int -ha_innobase::info( -/*==============*/ - uint flag) /* in: what information MySQL requests */ +ha_innobase::info_low( +/*==================*/ + uint flag, /* in: what information MySQL + requests */ + bool called_from_analyze) /* in: TRUE if called from + ::analyze() */ { dict_table_t* ib_table; dict_index_t* index; @@ -6400,7 +6403,7 @@ ha_innobase::info( ib_table = prebuilt->table; if (flag & HA_STATUS_TIME) { - if (innobase_stats_on_metadata) { + if (called_from_analyze || innobase_stats_on_metadata) { /* In sql_show we call with this flag: update then statistics so that they are up-to-date */ @@ -6616,6 +6619,18 @@ func_exit: DBUG_RETURN(0); } +/************************************************************************* +Returns statistics information of the table to the MySQL interpreter, +in various fields of the handle object. */ + +int +ha_innobase::info( +/*==============*/ + uint flag) /* in: what information MySQL requests */ +{ + return(info_low(flag, false /* not called from analyze */)); +} + /************************************************************************** Updates index cardinalities of the table, based on 8 random dives into each index tree. This does NOT calculate exact statistics on the table. */ @@ -6632,7 +6647,8 @@ ha_innobase::analyze( pthread_mutex_lock(&analyze_mutex); /* Simply call ::info() with all the flags */ - info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE); + info_low(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE, + true /* called from analyze */); pthread_mutex_unlock(&analyze_mutex); diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index eb9199b8955..8b91f7d4c51 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -80,6 +80,7 @@ class ha_innobase: public handler ulong innobase_update_autoinc(ulonglong auto_inc); void innobase_initialize_autoinc(); dict_index_t* innobase_get_index(uint keynr); + int info_low(uint flag, bool called_from_analyze); /* Init values for the class: */ public: From 78804bc8bd251a4b5f87c6d5086bbf1a19844bee Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 18 Oct 2010 14:20:16 +0300 Subject: [PATCH 081/151] Fix Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE This is a merge from 5.1/builtin to 5.1/plugin of: -------------- revision-id: vasil.dimov@oracle.com-20101018104811-nwqhg9vav17kl5s1 committer: Vasil Dimov timestamp: Mon 2010-10-18 13:48:11 +0300 message: Fix Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE In order to fix this bug we need to distinguish whether ha_innobase::info() has been called from ::analyze() or not. Rename ::info() to ::info_low() and add a boolean parameter that tells whether the call is from ::analyze() or not. Create a new simple ::info() that just calls ::info_low(false => not called from analyze). From ::analyze() instead of ::info() call ::info_low(true => called from analyze). Approved by: Jimmy (rb://487) -------------- --- .../innodb_plugin/r/innodb_bug57252.result | 6 +++ .../innodb_plugin/t/innodb_bug57252.test | 46 +++++++++++++++++++ storage/innodb_plugin/ChangeLog | 6 +++ storage/innodb_plugin/handler/ha_innodb.cc | 26 +++++++++-- storage/innodb_plugin/handler/ha_innodb.h | 1 + 5 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug57252.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug57252.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug57252.result b/mysql-test/suite/innodb_plugin/r/innodb_bug57252.result new file mode 100644 index 00000000000..efa50c742e0 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug57252.result @@ -0,0 +1,6 @@ +cardinality +10 +Table Op Msg_type Msg_text +test.bug57252 analyze status OK +cardinality +10 diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug57252.test b/mysql-test/suite/innodb_plugin/t/innodb_bug57252.test new file mode 100644 index 00000000000..d66cf79ef41 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug57252.test @@ -0,0 +1,46 @@ +# +# Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE +# http://bugs.mysql.com/57252 +# + +-- source include/have_innodb_plugin.inc + +-- disable_query_log +-- disable_result_log + +SET @innodb_stats_on_metadata_orig = @@innodb_stats_on_metadata; + +CREATE TABLE bug57252 (a INT, KEY akey (a)) ENGINE=INNODB; + +BEGIN; +let $i = 10; +while ($i) { + eval INSERT INTO bug57252 VALUES ($i); + dec $i; +} +COMMIT; + +-- enable_result_log + +SET GLOBAL innodb_stats_on_metadata=0; + +# this calls ::info() without HA_STATUS_CONST and so +# index->stat_n_diff_key_vals[] is not copied to the mysql-visible +# rec_per_key +SELECT cardinality FROM information_schema.statistics +WHERE table_name='bug57252' AND index_name='akey'; + +# this calls ::info() with HA_STATUS_CONST and so +# index->stat_n_diff_key_vals[] is copied to the mysql-visible +# rec_per_key at the end; when the bug is present dict_update_statistics() +# is not called beforehand and so index->stat_n_diff_key_vals[] contains +# an outdated data and thus we get an outdated data in the result when the +# bug is present +ANALYZE TABLE bug57252; + +SELECT cardinality FROM information_schema.statistics +WHERE table_name='bug57252' AND index_name='akey'; + +DROP TABLE bug57252; + +SET GLOBAL innodb_stats_on_metadata = @innodb_stats_on_metadata_orig; diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 0adb71fcba2..488669346fd 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-10-18 The InnoDB Team + + * handler/ha_innodb.cc, handler/ha_innodb.h, innodb_bug57252.result, + innodb_bug57252.test: + Fix Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE + 2010-10-14 The InnoDB Team * handler/ha_innodb.cc, innodb_bug56143.result, innodb_bug56143.test: diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index c5c8a0f848a..35f1a4974e2 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -7523,9 +7523,12 @@ Returns statistics information of the table to the MySQL interpreter, in various fields of the handle object. */ UNIV_INTERN int -ha_innobase::info( -/*==============*/ - uint flag) /*!< in: what information MySQL requests */ +ha_innobase::info_low( +/*==================*/ + uint flag, /*!< in: what information MySQL + requests */ + bool called_from_analyze) /* in: TRUE if called from + ::analyze() */ { dict_table_t* ib_table; dict_index_t* index; @@ -7556,7 +7559,7 @@ ha_innobase::info( ib_table = prebuilt->table; if (flag & HA_STATUS_TIME) { - if (innobase_stats_on_metadata) { + if (called_from_analyze || innobase_stats_on_metadata) { /* In sql_show we call with this flag: update then statistics so that they are up-to-date */ @@ -7804,6 +7807,18 @@ func_exit: DBUG_RETURN(0); } +/*********************************************************************//** +Returns statistics information of the table to the MySQL interpreter, +in various fields of the handle object. */ +UNIV_INTERN +int +ha_innobase::info( +/*==============*/ + uint flag) /*!< in: what information MySQL requests */ +{ + return(info_low(flag, false /* not called from analyze */)); +} + /**********************************************************************//** Updates index cardinalities of the table, based on 8 random dives into each index tree. This does NOT calculate exact statistics on the table. @@ -7816,7 +7831,8 @@ ha_innobase::analyze( HA_CHECK_OPT* check_opt) /*!< in: currently ignored */ { /* Simply call ::info() with all the flags */ - info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE); + info_low(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE, + true /* called from analyze */); return(0); } diff --git a/storage/innodb_plugin/handler/ha_innodb.h b/storage/innodb_plugin/handler/ha_innodb.h index 9789e4ba639..7a8f29853de 100644 --- a/storage/innodb_plugin/handler/ha_innodb.h +++ b/storage/innodb_plugin/handler/ha_innodb.h @@ -109,6 +109,7 @@ class ha_innobase: public handler ulint innobase_update_autoinc(ulonglong auto_inc); void innobase_initialize_autoinc(); dict_index_t* innobase_get_index(uint keynr); + int info_low(uint flag, bool called_from_analyze); /* Init values for the class: */ public: From 9074307102644d43b934ce52cc0661890098698b Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Mon, 18 Oct 2010 13:24:34 +0200 Subject: [PATCH 082/151] Bug#52172 test binlog.binlog_index needs --skip-core-file to avoid leaving core files For crash testing: kill the server without generating core file. include/my_dbug.h Use kill(getpid(), SIGKILL) which cannot be caught by signal handlers. All DBUG_XXX macros should be no-ops in optimized mode, do that for DBUG_ABORT as well. sql/handler.cc Kill server without generating core. sql/log.cc Kill server without generating core. --- dbug/dbug.c | 8 ++++++++ include/my_dbug.h | 51 +++++++++++++++++++++++++++++++++++++++++++---- sql/handler.cc | 10 +++++----- sql/log.cc | 18 ++++++++--------- 4 files changed, 69 insertions(+), 18 deletions(-) diff --git a/dbug/dbug.c b/dbug/dbug.c index 76723fa8767..7278acca2a9 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -2267,6 +2267,14 @@ static void dbug_flush(CODE_STATE *cs) } /* dbug_flush */ +void _db_flush_() +{ + CODE_STATE *cs; + get_code_state_or_return; + (void) fflush(cs->stack->out_file); +} + + void _db_lock_file_() { CODE_STATE *cs=0; diff --git a/include/my_dbug.h b/include/my_dbug.h index 0ba72b2210d..f08e94a1882 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,8 +13,18 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _dbug_h -#define _dbug_h +#ifndef MY_DBUG_INCLUDED +#define MY_DBUG_INCLUDED + +#ifndef __WIN__ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#endif /* not __WIN__ */ #if defined(__cplusplus) && !defined(DBUG_OFF) class Dbug_violation_helper @@ -69,6 +79,7 @@ extern void _db_end_(void); extern void _db_lock_file_(void); extern void _db_unlock_file_(void); extern FILE *_db_fp_(void); +extern void _db_flush_(); #ifdef __cplusplus @@ -124,6 +135,34 @@ extern FILE *_db_fp_(void); #define DBUG_EXPLAIN(buf,len) _db_explain_(0, (buf),(len)) #define DBUG_EXPLAIN_INITIAL(buf,len) _db_explain_init_((buf),(len)) #define IF_DBUG(A) A +#ifndef __WIN__ +#define DBUG_ABORT() (_db_flush_(), abort()) +#else +/* + Avoid popup with abort/retry/ignore buttons. When BUG#31745 is fixed we can + call abort() instead of _exit(3) (now it would cause a "test signal" popup). +*/ +#include +#define DBUG_ABORT() (_db_flush_(),\ + (void)_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE),\ + (void)_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR),\ + _exit(3)) +#endif + +/* + Make the program fail, without creating a core file. + abort() will send SIGABRT which (most likely) generates core. + Use SIGKILL instead, which cannot be caught. + We also pause the current thread, until the signal is actually delivered. + An alternative would be to use _exit(EXIT_FAILURE), + but then valgrind would report lots of memory leaks. + */ +#ifdef __WIN__ +#define DBUG_SUICIDE() DBUG_ABORT() +#else +#define DBUG_SUICIDE() (_db_flush_(), kill(getpid(), SIGKILL), pause()) +#endif + #else /* No debugger */ #define DBUG_ENTER(a1) @@ -152,8 +191,12 @@ extern FILE *_db_fp_(void); #define DBUG_EXPLAIN(buf,len) #define DBUG_EXPLAIN_INITIAL(buf,len) #define IF_DBUG(A) +#define DBUG_ABORT() do { } while(0) +#define DBUG_SUICIDE() do { } while(0) + #endif #ifdef __cplusplus } #endif -#endif + +#endif /* MY_DBUG_INCLUDED */ diff --git a/sql/handler.cc b/sql/handler.cc index 19f397ef09f..a47a5fd8a3c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1127,7 +1127,7 @@ int ha_commit_trans(THD *thd, bool all) uint rw_ha_count; bool rw_trans; - DBUG_EXECUTE_IF("crash_commit_before", abort();); + DBUG_EXECUTE_IF("crash_commit_before", DBUG_SUICIDE();); /* Close all cursors that can not survive COMMIT */ if (is_real_trans) /* not a statement commit */ @@ -1179,7 +1179,7 @@ int ha_commit_trans(THD *thd, bool all) } status_var_increment(thd->status_var.ha_prepare_count); } - DBUG_EXECUTE_IF("crash_commit_after_prepare", abort();); + DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE();); if (error || (is_real_trans && xid && (error= !(cookie= tc_log->log_xid(thd, xid))))) { @@ -1187,13 +1187,13 @@ int ha_commit_trans(THD *thd, bool all) error= 1; goto end; } - DBUG_EXECUTE_IF("crash_commit_after_log", abort();); + DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_SUICIDE();); } error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0; - DBUG_EXECUTE_IF("crash_commit_before_unlog", abort();); + DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_SUICIDE();); if (cookie) tc_log->unlog(cookie, xid); - DBUG_EXECUTE_IF("crash_commit_after", abort();); + DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE();); end: if (rw_trans) start_waiting_global_read_lock(thd); diff --git a/sql/log.cc b/sql/log.cc index 56f151fe2ab..2d5b62a5b2b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2600,7 +2600,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name, sql_print_error("MSYQL_BIN_LOG::open failed to sync the index file."); DBUG_RETURN(1); } - DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", abort();); + DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", DBUG_SUICIDE();); #endif write_error= 0; @@ -2697,7 +2697,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name, if (write_file_name_to_index_file) { #ifdef HAVE_REPLICATION - DBUG_EXECUTE_IF("crash_create_critical_before_update_index", abort();); + DBUG_EXECUTE_IF("crash_create_critical_before_update_index", DBUG_SUICIDE();); #endif DBUG_ASSERT(my_b_inited(&index_file) != 0); @@ -2716,7 +2716,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name, goto err; #ifdef HAVE_REPLICATION - DBUG_EXECUTE_IF("crash_create_after_update_index", abort();); + DBUG_EXECUTE_IF("crash_create_after_update_index", DBUG_SUICIDE();); #endif } } @@ -3168,7 +3168,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included) /* Store where we are in the new file for the execution thread */ flush_relay_log_info(rli); - DBUG_EXECUTE_IF("crash_before_purge_logs", abort();); + DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE();); pthread_mutex_lock(&rli->log_space_lock); rli->relay_log.purge_logs(to_purge_if_included, included, @@ -3296,7 +3296,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, break; } - DBUG_EXECUTE_IF("crash_purge_before_update_index", abort();); + DBUG_EXECUTE_IF("crash_purge_before_update_index", DBUG_SUICIDE();); if ((error= sync_purge_index_file())) { @@ -3311,7 +3311,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, goto err; } - DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", abort();); + DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", DBUG_SUICIDE();); err: /* Read each entry from purge_index_file and delete the file. */ @@ -3321,7 +3321,7 @@ err: " that would be purged."); close_purge_index_file(); - DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", abort();); + DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", DBUG_SUICIDE();); if (need_mutex) pthread_mutex_unlock(&LOCK_index); @@ -4832,7 +4832,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event, DBUG_PRINT("info", ("error writing binlog cache: %d", write_error)); DBUG_PRINT("info", ("crashing before writing xid")); - abort(); + DBUG_SUICIDE(); }); if ((write_error= write_cache(cache, false, false))) @@ -4846,7 +4846,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event, if (flush_and_sync()) goto err; - DBUG_EXECUTE_IF("half_binlogged_transaction", abort();); + DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_SUICIDE();); if (cache->error) // Error on read { sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno); From cdddc7bfd58f900d63b21a811ad768849311c7b7 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Mon, 18 Oct 2010 21:03:53 +0700 Subject: [PATCH 083/151] Follow up for bug#36742. Changed test case for bug#19828 because currently hostname stored in db in lowercase. --- mysql-test/r/grant3.result | 25 +++++-------------------- mysql-test/t/grant3.test | 5 +++++ 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/mysql-test/r/grant3.result b/mysql-test/r/grant3.result index 59c64ee84ae..fd51a83d4b2 100644 --- a/mysql-test/r/grant3.result +++ b/mysql-test/r/grant3.result @@ -21,123 +21,108 @@ grant select on test.* to CUser@LOCALHOST; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; user host db select_priv -CUser LOCALHOST test Y CUser localhost test Y REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; user host db select_priv -CUser localhost test Y REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; user host db select_priv DROP USER CUser@localhost; DROP USER CUser@LOCALHOST; +ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost' create table t1 (a int); grant select on test.t1 to CUser@localhost; grant select on test.t1 to CUser@LOCALHOST; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv -CUser LOCALHOST test t1 Select CUser localhost test t1 Select REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv -CUser localhost test t1 Select REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv DROP USER CUser@localhost; DROP USER CUser@LOCALHOST; +ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost' grant select(a) on test.t1 to CUser@localhost; grant select(a) on test.t1 to CUser@LOCALHOST; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv -CUser LOCALHOST test t1 Select CUser localhost test t1 Select REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv -CUser localhost test t1 Select REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv DROP USER CUser@localhost; DROP USER CUser@LOCALHOST; +ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost' drop table t1; grant select on test.* to CUser2@localhost; grant select on test.* to CUser2@LOCALHOST; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; user host -CUser2 LOCALHOST CUser2 localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; user host db select_priv -CUser2 LOCALHOST test Y CUser2 localhost test Y REVOKE SELECT ON test.* FROM 'CUser2'@'LOCALHOST'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; user host -CUser2 LOCALHOST CUser2 localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; user host db select_priv -CUser2 localhost test Y REVOKE SELECT ON test.* FROM 'CUser2'@'localhost'; +ERROR 42000: There is no such grant defined for user 'CUser2' on host 'localhost' flush privileges; SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; user host -CUser2 LOCALHOST CUser2 localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; user host db select_priv DROP USER CUser2@localhost; DROP USER CUser2@LOCALHOST; +ERROR HY000: Operation DROP USER failed for 'CUser2'@'localhost' CREATE DATABASE mysqltest_1; CREATE TABLE mysqltest_1.t1 (a INT); CREATE USER 'mysqltest1'@'%'; diff --git a/mysql-test/t/grant3.test b/mysql-test/t/grant3.test index 437fc9a278f..d24b2de17eb 100644 --- a/mysql-test/t/grant3.test +++ b/mysql-test/t/grant3.test @@ -64,6 +64,7 @@ SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; DROP USER CUser@localhost; +--error ER_CANNOT_USER DROP USER CUser@LOCALHOST; #### table grants @@ -88,6 +89,7 @@ SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; DROP USER CUser@localhost; +--error ER_CANNOT_USER DROP USER CUser@LOCALHOST; ### column grants @@ -112,6 +114,7 @@ SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; DROP USER CUser@localhost; +--error ER_CANNOT_USER DROP USER CUser@LOCALHOST; drop table t1; @@ -131,6 +134,7 @@ flush privileges; SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; +--error ER_NONEXISTING_GRANT REVOKE SELECT ON test.* FROM 'CUser2'@'localhost'; flush privileges; @@ -138,6 +142,7 @@ SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; DROP USER CUser2@localhost; +--error ER_CANNOT_USER DROP USER CUser2@LOCALHOST; From 4053a5a44832552090218fb7ca685c1c2a2ae006 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Mon, 18 Oct 2010 23:20:26 +0700 Subject: [PATCH 084/151] Follow-up for bug#36742: changed results for test ipv4_as_ipv6 because hostname is case-insensitive. --- mysql-test/r/ipv4_as_ipv6.result | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/mysql-test/r/ipv4_as_ipv6.result b/mysql-test/r/ipv4_as_ipv6.result index 8523dc82f02..82bca393d71 100644 --- a/mysql-test/r/ipv4_as_ipv6.result +++ b/mysql-test/r/ipv4_as_ipv6.result @@ -32,9 +32,9 @@ mysqld is alive CREATE USER testuser@'0:0:0:0:0:FFFF:127.0.0.1' identified by '1234'; GRANT ALL ON test.* TO testuser@'0:0:0:0:0:FFFF:127.0.0.1'; SHOW GRANTS FOR testuser@'0:0:0:0:0:FFFF:127.0.0.1'; -Grants for testuser@0:0:0:0:0:FFFF:127.0.0.1 -GRANT USAGE ON *.* TO 'testuser'@'0:0:0:0:0:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' -GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0:0:0:0:FFFF:127.0.0.1' +Grants for testuser@0:0:0:0:0:ffff:127.0.0.1 +GRANT USAGE ON *.* TO 'testuser'@'0:0:0:0:0:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' +GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0:0:0:0:ffff:127.0.0.1' SET @nip= inet_aton('0:0:0:0:0:FFFF:127.0.0.1'); SELECT @nip; @nip @@ -61,9 +61,9 @@ mysqld is alive CREATE USER testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1' identified by '1234'; GRANT ALL ON test.* TO testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1'; SHOW GRANTS FOR testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1'; -Grants for testuser@0000:0000:0000:0000:0000:FFFF:127.0.0.1 -GRANT USAGE ON *.* TO 'testuser'@'0000:0000:0000:0000:0000:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' -GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0000:0000:0000:0000:0000:FFFF:127.0.0.1' +Grants for testuser@0000:0000:0000:0000:0000:ffff:127.0.0.1 +GRANT USAGE ON *.* TO 'testuser'@'0000:0000:0000:0000:0000:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' +GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0000:0000:0000:0000:0000:ffff:127.0.0.1' SET @nip= inet_aton('0000:0000:0000:0000:0000:FFFF:127.0.0.1'); SELECT @nip; @nip @@ -90,9 +90,9 @@ mysqld is alive CREATE USER testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1' identified by '1234'; GRANT ALL ON test.* TO testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1'; SHOW GRANTS FOR testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1'; -Grants for testuser@0:0000:0000:0:0000:FFFF:127.0.0.1 -GRANT USAGE ON *.* TO 'testuser'@'0:0000:0000:0:0000:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' -GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0000:0000:0:0000:FFFF:127.0.0.1' +Grants for testuser@0:0000:0000:0:0000:ffff:127.0.0.1 +GRANT USAGE ON *.* TO 'testuser'@'0:0000:0000:0:0000:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' +GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0000:0000:0:0000:ffff:127.0.0.1' SET @nip= inet_aton('0:0000:0000:0:0000:FFFF:127.0.0.1'); SELECT @nip; @nip @@ -119,9 +119,9 @@ mysqld is alive CREATE USER testuser@'0::0000:FFFF:127.0.0.1' identified by '1234'; GRANT ALL ON test.* TO testuser@'0::0000:FFFF:127.0.0.1'; SHOW GRANTS FOR testuser@'0::0000:FFFF:127.0.0.1'; -Grants for testuser@0::0000:FFFF:127.0.0.1 -GRANT USAGE ON *.* TO 'testuser'@'0::0000:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' -GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0::0000:FFFF:127.0.0.1' +Grants for testuser@0::0000:ffff:127.0.0.1 +GRANT USAGE ON *.* TO 'testuser'@'0::0000:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' +GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0::0000:ffff:127.0.0.1' SET @nip= inet_aton('0::0000:FFFF:127.0.0.1'); SELECT @nip; @nip @@ -149,9 +149,9 @@ mysqld is alive CREATE USER testuser@'::FFFF:127.0.0.1' identified by '1234'; GRANT ALL ON test.* TO testuser@'::FFFF:127.0.0.1'; SHOW GRANTS FOR testuser@'::FFFF:127.0.0.1'; -Grants for testuser@::FFFF:127.0.0.1 -GRANT USAGE ON *.* TO 'testuser'@'::FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' -GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'::FFFF:127.0.0.1' +Grants for testuser@::ffff:127.0.0.1 +GRANT USAGE ON *.* TO 'testuser'@'::ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' +GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'::ffff:127.0.0.1' SET @nip= inet_aton('::FFFF:127.0.0.1'); SELECT @nip; @nip From 5aa81e380cde5bc9f9cd42787286d6db5292d631 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 18 Oct 2010 14:27:10 -0200 Subject: [PATCH 085/151] Bug#45288: pb2 returns a lot of compilation warnings on linux Enable the MySQL maintainer-specific development environment (which add various warning related options to the compiler flags) if debugging support is enabled. config/ac-macros/maintainer.m4: Enable the maintainer mode if debug support is enabled. configure.in: Move debug argument to before the maintainer mode check. --- config/ac-macros/maintainer.m4 | 3 ++- configure.in | 12 +++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/config/ac-macros/maintainer.m4 b/config/ac-macros/maintainer.m4 index 24be31395f2..5960853d7f1 100644 --- a/config/ac-macros/maintainer.m4 +++ b/config/ac-macros/maintainer.m4 @@ -8,7 +8,8 @@ AC_DEFUN([MY_MAINTAINER_MODE], [ [AS_HELP_STRING([--enable-mysql-maintainer-mode], [Enable a MySQL maintainer-specific development environment])], [USE_MYSQL_MAINTAINER_MODE=$enableval], - [USE_MYSQL_MAINTAINER_MODE=no]) + [AS_IF([test "$with_debug" != "no"], + [USE_MYSQL_MAINTAINER_MODE=yes], [USE_MYSQL_MAINTAINER_MODE=no])]) AC_MSG_RESULT([$USE_MYSQL_MAINTAINER_MODE]) ]) diff --git a/configure.in b/configure.in index c1672557bd1..09885dbbae7 100644 --- a/configure.in +++ b/configure.in @@ -103,6 +103,13 @@ AC_SUBST(SHARED_LIB_MAJOR_VERSION) AC_SUBST(SHARED_LIB_VERSION) AC_SUBST(AVAILABLE_LANGUAGES) +# Check whether a debug mode should be enabled. +AC_ARG_WITH([debug], + AS_HELP_STRING([--with-debug@<:@=full@:>@], + [Enable various amounts of debugging support (full adds a slow memory checker).]), + [with_debug=$withval], + [with_debug=no]) + # Whether the maintainer mode should be enabled. MY_MAINTAINER_MODE @@ -1674,11 +1681,6 @@ then DEBUG_OPTIMIZE_CXX="" fi -AC_ARG_WITH(debug, - [ --with-debug Add debug code - --with-debug=full Add debug code (adds memory checker, very slow)], - [with_debug=$withval], - [with_debug=no]) if test "$with_debug" = "yes" then # Medium debug. From a8f2f7af32c369e92205abeafec4cc0ff5f9f4bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 19 Oct 2010 08:58:53 +0300 Subject: [PATCH 086/151] Bug #56680 wrong InnoDB results from a case-insensitive covering index row_search_for_mysql(): When a secondary index record might not be visible in the current transaction's read view and we consult the clustered index and optionally some undo log records, return the relevant columns of the clustered index record to MySQL instead of the secondary index record. REC_INFO_DELETED_FLAG: Move the definition from rem0rec.ic to rem0rec.h. ibuf_insert_to_index_page_low(): New function, refactored from ibuf_insert_to_index_page(). ibuf_insert_to_index_page(): When we are inserting a record in place of a delete-marked record and some fields of the record differ, update that record just like row_ins_sec_index_entry_by_modify() would do. mysql_row_templ_t: Add clust_rec_field_no. row_sel_store_mysql_rec(), row_sel_push_cache_row_for_mysql(): Add the flag rec_clust, for returning data at clust_rec_field_no instead of rec_field_no. Resurrect the debug assertion that the record not be marked for deletion. (Bug #55626) buf_LRU_free_block(): Refactored from buf_LRU_search_and_free_block(). This is needed for the innodb_change_buffering_debug diagnostics. [UNIV_DEBUG || UNIV_IBUF_DEBUG] ibuf_debug, buf_page_get_gen(), buf_flush_page_try(): Implement innodb_change_buffering_debug=1 for evicting pages from the buffer pool, so that change buffering will be attempted more frequently. --- .../suite/innodb/r/innodb_bug56680.result | 102 ++++++++++ .../suite/innodb/t/innodb_bug56680.test | 130 ++++++++++++ storage/innobase/buf/buf0buf.c | 24 +++ storage/innobase/buf/buf0flu.c | 76 +++++++ storage/innobase/buf/buf0lru.c | 101 +++++---- storage/innobase/handler/ha_innodb.cc | 28 ++- storage/innobase/ibuf/ibuf0ibuf.c | 191 +++++++++++++----- storage/innobase/include/buf0flu.h | 14 ++ storage/innobase/include/buf0lru.h | 8 + storage/innobase/include/ibuf0ibuf.h | 5 + storage/innobase/include/rem0rec.h | 3 + storage/innobase/include/rem0rec.ic | 3 - storage/innobase/include/row0mysql.h | 4 + storage/innobase/include/row0upd.h | 8 +- storage/innobase/row/row0mysql.c | 2 +- storage/innobase/row/row0sel.c | 84 ++++---- storage/innobase/row/row0upd.c | 8 +- 17 files changed, 643 insertions(+), 148 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug56680.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug56680.test diff --git a/mysql-test/suite/innodb/r/innodb_bug56680.result b/mysql-test/suite/innodb/r/innodb_bug56680.result new file mode 100644 index 00000000000..c3afc3e6581 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug56680.result @@ -0,0 +1,102 @@ +SET GLOBAL tx_isolation='REPEATABLE-READ'; +CREATE TABLE bug56680( +a INT AUTO_INCREMENT PRIMARY KEY, +b CHAR(1), +c INT, +INDEX(b)) +ENGINE=InnoDB; +INSERT INTO bug56680 VALUES(0,'x',1); +BEGIN; +SELECT b FROM bug56680; +b +x +BEGIN; +UPDATE bug56680 SET b='X'; +SELECT b FROM bug56680; +b +x +SELECT * FROM bug56680; +a b c +1 x 1 +ROLLBACK; +SELECT b FROM bug56680; +b +x +SET GLOBAL tx_isolation='READ-UNCOMMITTED'; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +BEGIN; +SELECT b FROM bug56680 LIMIT 2; +b +x +x +BEGIN; +DELETE FROM bug56680 WHERE a=1; +INSERT INTO bug56680 VALUES(1,'X',1); +SELECT b FROM bug56680 LIMIT 3; +b +X +x +x +SELECT b FROM bug56680 LIMIT 2; +b +x +x +CHECK TABLE bug56680; +Table Op Msg_type Msg_text +test.bug56680 check status OK +ROLLBACK; +SELECT b FROM bug56680 LIMIT 2; +b +x +x +CHECK TABLE bug56680; +Table Op Msg_type Msg_text +test.bug56680 check status OK +SELECT b FROM bug56680 LIMIT 2; +b +x +x +CREATE TABLE bug56680_2( +a INT AUTO_INCREMENT PRIMARY KEY, +b VARCHAR(2) CHARSET latin1 COLLATE latin1_german2_ci, +c INT, +INDEX(b)) +ENGINE=InnoDB; +INSERT INTO bug56680_2 SELECT 0,_latin1 0xdf,c FROM bug56680; +BEGIN; +SELECT HEX(b) FROM bug56680_2 LIMIT 2; +HEX(b) +DF +DF +DELETE FROM bug56680_2 WHERE a=1; +INSERT INTO bug56680_2 VALUES(1,'SS',1); +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +HEX(b) +5353 +DF +DF +CHECK TABLE bug56680_2; +Table Op Msg_type Msg_text +test.bug56680_2 check status OK +DELETE FROM bug56680_2 WHERE a=1; +INSERT INTO bug56680_2 VALUES(1,_latin1 0xdf,1); +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +HEX(b) +DF +DF +DF +CHECK TABLE bug56680_2; +Table Op Msg_type Msg_text +test.bug56680_2 check status OK +DROP TABLE bug56680_2; +DROP TABLE bug56680; diff --git a/mysql-test/suite/innodb/t/innodb_bug56680.test b/mysql-test/suite/innodb/t/innodb_bug56680.test new file mode 100644 index 00000000000..ab81ca2f8e6 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug56680.test @@ -0,0 +1,130 @@ +# +# Bug #56680 InnoDB may return wrong results from a case-insensitive index +# +-- source include/have_innodb.inc + +-- disable_query_log +SET @tx_isolation_orig = @@tx_isolation; +# The flag innodb_change_buffering_debug is only available in debug builds. +# It instructs InnoDB to try to evict pages from the buffer pool when +# change buffering is possible, so that the change buffer will be used +# whenever possible. +-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET @innodb_change_buffering_debug_orig = @@innodb_change_buffering_debug; +-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_change_buffering_debug = 1; +-- enable_query_log +SET GLOBAL tx_isolation='REPEATABLE-READ'; + +CREATE TABLE bug56680( + a INT AUTO_INCREMENT PRIMARY KEY, + b CHAR(1), + c INT, + INDEX(b)) +ENGINE=InnoDB; + +INSERT INTO bug56680 VALUES(0,'x',1); +BEGIN; +SELECT b FROM bug56680; + +connect (con1,localhost,root,,); +connection con1; +BEGIN; +UPDATE bug56680 SET b='X'; + +connection default; +# This should return the last committed value 'x', but would return 'X' +# due to a bug in row_search_for_mysql(). +SELECT b FROM bug56680; +# This would always return the last committed value 'x'. +SELECT * FROM bug56680; + +connection con1; +ROLLBACK; +disconnect con1; + +connection default; + +SELECT b FROM bug56680; + +# For the rest of this test, use the READ UNCOMMITTED isolation level +# to see what exists in the secondary index. +SET GLOBAL tx_isolation='READ-UNCOMMITTED'; + +# Create enough rows for the table, so that the insert buffer will be +# used for modifying the secondary index page. There must be multiple +# index pages, because changes to the root page are never buffered. + +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; + +BEGIN; +SELECT b FROM bug56680 LIMIT 2; + +connect (con1,localhost,root,,); +connection con1; +BEGIN; +DELETE FROM bug56680 WHERE a=1; +# This should be buffered, if innodb_change_buffering_debug = 1 is in effect. +INSERT INTO bug56680 VALUES(1,'X',1); + +# This should force an insert buffer merge, and return 'X' in the first row. +SELECT b FROM bug56680 LIMIT 3; + +connection default; +SELECT b FROM bug56680 LIMIT 2; +CHECK TABLE bug56680; + +connection con1; +ROLLBACK; +SELECT b FROM bug56680 LIMIT 2; +CHECK TABLE bug56680; + +connection default; +disconnect con1; + +SELECT b FROM bug56680 LIMIT 2; + +CREATE TABLE bug56680_2( + a INT AUTO_INCREMENT PRIMARY KEY, + b VARCHAR(2) CHARSET latin1 COLLATE latin1_german2_ci, + c INT, + INDEX(b)) +ENGINE=InnoDB; + +INSERT INTO bug56680_2 SELECT 0,_latin1 0xdf,c FROM bug56680; + +BEGIN; +SELECT HEX(b) FROM bug56680_2 LIMIT 2; +DELETE FROM bug56680_2 WHERE a=1; +# This should be buffered, if innodb_change_buffering_debug = 1 is in effect. +INSERT INTO bug56680_2 VALUES(1,'SS',1); + +# This should force an insert buffer merge, and return 'SS' in the first row. +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +CHECK TABLE bug56680_2; + +DELETE FROM bug56680_2 WHERE a=1; +# This should be buffered, if innodb_change_buffering_debug = 1 is in effect. +INSERT INTO bug56680_2 VALUES(1,_latin1 0xdf,1); + +# This should force an insert buffer merge, and return 0xdf in the first row. +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +CHECK TABLE bug56680_2; + +DROP TABLE bug56680_2; +DROP TABLE bug56680; + +-- disable_query_log +SET GLOBAL tx_isolation = @tx_isolation_orig; +-- error 0, ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_change_buffering_debug = @innodb_change_buffering_debug_orig; diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 45867388a61..500088c3901 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -1270,6 +1270,30 @@ loop: buf_awe_map_page_to_frame(block, TRUE); } +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG + if (mode == BUF_GET_IF_IN_POOL && ibuf_debug) { + /* Try to evict the block from the buffer pool, to use the + insert buffer as much as possible. */ + + if (buf_LRU_free_block(block)) { + mutex_exit(&buf_pool->mutex); + mutex_exit(&block->mutex); + fprintf(stderr, + "innodb_change_buffering_debug evict %u %u\n", + (unsigned) space, (unsigned) offset); + return(NULL); + } else if (buf_flush_page_try(block)) { + fprintf(stderr, + "innodb_change_buffering_debug flush %u %u\n", + (unsigned) space, (unsigned) offset); + guess = block->frame; + goto loop; + } + + /* Failed to evict the page; change it directly */ + } +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + #ifdef UNIV_SYNC_DEBUG buf_block_buf_fix_inc_debug(block, file, line); #else diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c index 24fa306c127..7dd6bfd9198 100644 --- a/storage/innobase/buf/buf0flu.c +++ b/storage/innobase/buf/buf0flu.c @@ -723,6 +723,82 @@ buf_flush_try_page( return(0); } +# if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/********************************************************************** +Writes a flushable page asynchronously from the buffer pool to a file. +NOTE: buf_pool_mutex and block->mutex must be held upon entering this +function, and they will be released by this function after flushing. +This is loosely based on buf_flush_batch() and buf_flush_try_page(). */ + +ibool +buf_flush_page_try( +/*===============*/ + /* out: TRUE if flushed and + mutexes released */ + buf_block_t* block) /*!< in/out: buffer control block */ +{ + ut_ad(mutex_own(&buf_pool->mutex)); + ut_ad(block->state == BUF_BLOCK_FILE_PAGE); + ut_ad(mutex_own(&block->mutex)); + + if (!buf_flush_ready_for_flush(block, BUF_FLUSH_LRU)) { + return(FALSE); + } + + if (buf_pool->n_flush[BUF_FLUSH_LRU] > 0 + || buf_pool->init_flush[BUF_FLUSH_LRU]) { + /* There is already a flush batch of the same type running */ + return(FALSE); + } + + buf_pool->init_flush[BUF_FLUSH_LRU] = TRUE; + + block->io_fix = BUF_IO_WRITE; + block->flush_type = BUF_FLUSH_LRU; + + if (buf_pool->n_flush[BUF_FLUSH_LRU]++ == 0) { + + os_event_reset(buf_pool->no_flush[BUF_FLUSH_LRU]); + } + + /* VERY IMPORTANT: + Because any thread may call the LRU flush, even when owning + locks on pages, to avoid deadlocks, we must make sure that the + s-lock is acquired on the page without waiting: this is + accomplished because buf_flush_ready_for_flush() must hold, + and that requires the page not to be bufferfixed. */ + + rw_lock_s_lock_gen(&block->lock, BUF_IO_WRITE); + + /* Note that the s-latch is acquired before releasing the + buf_pool mutex: this ensures that the latch is acquired + immediately. */ + + mutex_exit(&block->mutex); + mutex_exit(&buf_pool->mutex); + + /* Even though block is not protected by any mutex at this + point, it is safe to access block, because it is io_fixed and + oldest_modification != 0. Thus, it cannot be relocated in the + buffer pool or removed from flush_list or LRU_list. */ + + buf_flush_write_block_low(block); + + mutex_enter(&buf_pool->mutex); + buf_pool->init_flush[BUF_FLUSH_LRU] = FALSE; + + if (buf_pool->n_flush[BUF_FLUSH_LRU] == 0) { + /* The running flush batch has ended */ + os_event_set(buf_pool->no_flush[BUF_FLUSH_LRU]); + } + + mutex_exit(&buf_pool->mutex); + buf_flush_buffered_writes(); + + return(TRUE); +} +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + /*************************************************************** Flushes to disk all flushable pages within the flush area. */ static diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c index d3c787d1578..1dc3efd1464 100644 --- a/storage/innobase/buf/buf0lru.c +++ b/storage/innobase/buf/buf0lru.c @@ -320,6 +320,60 @@ buf_LRU_get_recent_limit(void) return(limit); } +/********************************************************************** +Try to put a block from the LRU list to the free list. */ + +ibool +buf_LRU_free_block( +/*===============*/ + /* out: TRUE if freed */ + buf_block_t* block) /* in/out: block to be freed */ +{ + if (!buf_flush_ready_for_replace(block)) { + return(FALSE); + } + +#ifdef UNIV_DEBUG + if (buf_debug_prints) { + fprintf(stderr, + "Putting space %lu page %lu" + " to free list\n", + (ulong) block->space, + (ulong) block->offset); + } +#endif /* UNIV_DEBUG */ + + buf_LRU_block_remove_hashed_page(block); + + mutex_exit(&(buf_pool->mutex)); + mutex_exit(&block->mutex); + + /* Remove possible adaptive hash index built on the + page; in the case of AWE the block may not have a + frame at all */ + + if (block->frame) { + /* The page was declared uninitialized + by buf_LRU_block_remove_hashed_page(). + We need to flag the contents of the + page valid (which it still is) in + order to avoid bogus Valgrind + warnings. */ + UNIV_MEM_VALID(block->frame, UNIV_PAGE_SIZE); + btr_search_drop_page_hash_index(block->frame); + UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE); + } + + ut_a(block->buf_fix_count == 0); + + mutex_enter(&(buf_pool->mutex)); + mutex_enter(&block->mutex); + + buf_LRU_block_free_hashed_page(block); + + return(TRUE); +} + /********************************************************************** Look for a replaceable block from the end of the LRU list and put it to the free list if found. */ @@ -348,54 +402,13 @@ buf_LRU_search_and_free_block( ut_a(block->in_LRU_list); mutex_enter(&block->mutex); + freed = buf_LRU_free_block(block); + mutex_exit(&block->mutex); - if (buf_flush_ready_for_replace(block)) { - -#ifdef UNIV_DEBUG - if (buf_debug_prints) { - fprintf(stderr, - "Putting space %lu page %lu" - " to free list\n", - (ulong) block->space, - (ulong) block->offset); - } -#endif /* UNIV_DEBUG */ - - buf_LRU_block_remove_hashed_page(block); - - mutex_exit(&(buf_pool->mutex)); - mutex_exit(&block->mutex); - - /* Remove possible adaptive hash index built on the - page; in the case of AWE the block may not have a - frame at all */ - - if (block->frame) { - /* The page was declared uninitialized - by buf_LRU_block_remove_hashed_page(). - We need to flag the contents of the - page valid (which it still is) in - order to avoid bogus Valgrind - warnings. */ - UNIV_MEM_VALID(block->frame, UNIV_PAGE_SIZE); - btr_search_drop_page_hash_index(block->frame); - UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE); - } - - ut_a(block->buf_fix_count == 0); - - mutex_enter(&(buf_pool->mutex)); - mutex_enter(&block->mutex); - - buf_LRU_block_free_hashed_page(block); - freed = TRUE; - mutex_exit(&block->mutex); - + if (freed) { break; } - mutex_exit(&block->mutex); - block = UT_LIST_GET_PREV(LRU, block); distance++; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 5a8f5479223..4c52326a58a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -79,6 +79,7 @@ extern "C" { #include "../storage/innobase/include/dict0crea.h" #include "../storage/innobase/include/btr0cur.h" #include "../storage/innobase/include/btr0btr.h" +#include "../storage/innobase/include/ibuf0ibuf.h" #include "../storage/innobase/include/fsp0fsp.h" #include "../storage/innobase/include/sync0sync.h" #include "../storage/innobase/include/fil0fil.h" @@ -3723,17 +3724,18 @@ include_field: n_requested_fields++; templ->col_no = i; + templ->clust_rec_field_no = dict_col_get_clust_pos_noninline( + &index->table->cols[i], clust_index); + ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED); if (index == clust_index) { - templ->rec_field_no = dict_col_get_clust_pos_noninline( - &index->table->cols[i], index); + templ->rec_field_no = templ->clust_rec_field_no; } else { templ->rec_field_no = dict_index_get_nth_col_pos( index, i); - } - - if (templ->rec_field_no == ULINT_UNDEFINED) { - prebuilt->need_to_access_clustered = TRUE; + if (templ->rec_field_no == ULINT_UNDEFINED) { + prebuilt->need_to_access_clustered = TRUE; + } } if (field->null_ptr) { @@ -3785,9 +3787,7 @@ skip_field: for (i = 0; i < n_requested_fields; i++) { templ = prebuilt->mysql_template + i; - templ->rec_field_no = dict_col_get_clust_pos_noninline( - &index->table->cols[templ->col_no], - clust_index); + templ->rec_field_no = templ->clust_rec_field_no; } } } @@ -8990,6 +8990,13 @@ static MYSQL_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode, AUTOINC_OLD_STYLE_LOCKING, /* Minimum value */ AUTOINC_NO_LOCKING, 0); /* Maximum value */ +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug, + PLUGIN_VAR_RQCMDARG, + "Debug flags for InnoDB change buffering (0=none)", + NULL, NULL, 0, 0, 1, 0); +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(additional_mem_pool_size), MYSQL_SYSVAR(autoextend_increment), @@ -9031,6 +9038,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(thread_concurrency), MYSQL_SYSVAR(thread_sleep_delay), MYSQL_SYSVAR(autoinc_lock_mode), +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG + MYSQL_SYSVAR(change_buffering_debug), +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ NULL }; diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index d54a3378993..71ecc7ec49f 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -22,6 +22,7 @@ Created 7/19/1997 Heikki Tuuri #include "btr0cur.h" #include "btr0pcur.h" #include "btr0btr.h" +#include "row0upd.h" #include "sync0sync.h" #include "dict0boot.h" #include "fut0lst.h" @@ -137,6 +138,11 @@ access order rules. */ /* Buffer pool size per the maximum insert buffer size */ #define IBUF_POOL_SIZE_PER_MAX_SIZE 2 +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/* Flag to control insert buffer debugging. */ +uint ibuf_debug; +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + /* The insert buffer control structure */ ibuf_t* ibuf = NULL; @@ -2819,6 +2825,72 @@ ibuf_insert( } } +/************************************************************************ +During merge, inserts to an index page a secondary index entry extracted +from the insert buffer. */ +static +void +ibuf_insert_to_index_page_low( +/*==========================*/ + dtuple_t* entry, /* in: buffered entry to insert */ + page_t* page, /* in: index page where the buffered entry + should be placed */ + dict_index_t* index, /* in: record descriptor */ + mtr_t* mtr, /* in: mtr */ + page_cur_t* page_cur)/* in: cursor positioned on the record + after which to insert the buffered entry */ +{ + ulint space; + ulint page_no; + page_t* bitmap_page; + ulint old_bits; + + if (UNIV_LIKELY + (page_cur_tuple_insert(page_cur, entry, index, mtr) != NULL)) { + return; + } + + /* If the record did not fit, reorganize */ + + btr_page_reorganize(page, index, mtr); + + page_cur_search(page, index, entry, PAGE_CUR_LE, page_cur); + + /* This time the record must fit */ + + if (UNIV_LIKELY + (page_cur_tuple_insert(page_cur, entry, index, mtr) != NULL)) { + return; + } + + ut_print_timestamp(stderr); + + fprintf(stderr, + " InnoDB: Error: Insert buffer insert fails;" + " page free %lu, dtuple size %lu\n", + (ulong) page_get_max_insert_size(page, 1), + (ulong) rec_get_converted_size(index, entry)); + fputs("InnoDB: Cannot insert index record ", stderr); + dtuple_print(stderr, entry); + fputs("\nInnoDB: The table where this index record belongs\n" + "InnoDB: is now probably corrupt. Please run CHECK TABLE on\n" + "InnoDB: that table.\n", stderr); + + space = buf_frame_get_space_id(page); + page_no = buf_frame_get_page_no(page); + + bitmap_page = ibuf_bitmap_get_map_page(space, page_no, mtr); + old_bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no, + IBUF_BITMAP_FREE, mtr); + + fprintf(stderr, + "InnoDB: space %lu, page %lu, bitmap bits %lu\n", + (ulong) space, (ulong) page_no, (ulong) old_bits); + + fputs("InnoDB: Submit a detailed bug report" + " to http://bugs.mysql.com\n", stderr); +} + /************************************************************************ During merge, inserts to an index page a secondary index entry extracted from the insert buffer. */ @@ -2835,11 +2907,10 @@ ibuf_insert_to_index_page( page_cur_t page_cur; ulint low_match; rec_t* rec; - page_t* bitmap_page; - ulint old_bits; ut_ad(ibuf_inside()); ut_ad(dtuple_check_typed(entry)); + ut_ad(!buf_block_align(page)->is_hashed); if (UNIV_UNLIKELY(dict_table_is_comp(index->table) != (ibool)!!page_is_comp(page))) { @@ -2877,61 +2948,79 @@ dump: low_match = page_cur_search(page, index, entry, PAGE_CUR_LE, &page_cur); - if (low_match == dtuple_get_n_fields(entry)) { + if (UNIV_UNLIKELY(low_match == dtuple_get_n_fields(entry))) { + mem_heap_t* heap; + upd_t* update; + ulint* offsets; + rec = page_cur_get_rec(&page_cur); - btr_cur_del_unmark_for_ibuf(rec, mtr); - } else { - rec = page_cur_tuple_insert(&page_cur, entry, index, mtr); + /* This is based on + row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */ + ut_ad(rec_get_deleted_flag(rec, page_is_comp(page))); - if (rec == NULL) { - /* If the record did not fit, reorganize */ + heap = mem_heap_create(1024); - btr_page_reorganize(page, index, mtr); + offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, + &heap); + update = row_upd_build_sec_rec_difference_binary( + index, entry, rec, NULL, heap); - page_cur_search(page, index, entry, - PAGE_CUR_LE, &page_cur); - - /* This time the record must fit */ - if (UNIV_UNLIKELY(!page_cur_tuple_insert( - &page_cur, entry, index, - mtr))) { - - ut_print_timestamp(stderr); - - fprintf(stderr, - " InnoDB: Error: Insert buffer insert" - " fails; page free %lu," - " dtuple size %lu\n", - (ulong) page_get_max_insert_size( - page, 1), - (ulong) rec_get_converted_size( - index, entry)); - fputs("InnoDB: Cannot insert index record ", - stderr); - dtuple_print(stderr, entry); - fputs("\nInnoDB: The table where" - " this index record belongs\n" - "InnoDB: is now probably corrupt." - " Please run CHECK TABLE on\n" - "InnoDB: that table.\n", stderr); - - bitmap_page = ibuf_bitmap_get_map_page( - buf_frame_get_space_id(page), - buf_frame_get_page_no(page), - mtr); - old_bits = ibuf_bitmap_page_get_bits( - bitmap_page, - buf_frame_get_page_no(page), - IBUF_BITMAP_FREE, mtr); - - fprintf(stderr, "InnoDB: Bitmap bits %lu\n", - (ulong) old_bits); - - fputs("InnoDB: Submit a detailed bug report" - " to http://bugs.mysql.com\n", stderr); - } + if (update->n_fields == 0) { + /* The records only differ in the delete-mark. + Clear the delete-mark, like we did before + Bug #56680 was fixed. */ + btr_cur_del_unmark_for_ibuf(rec, mtr); +updated_in_place: + mem_heap_free(heap); + return; } + + /* Copy the info bits. Clear the delete-mark. */ + update->info_bits = rec_get_info_bits(rec, page_is_comp(page)); + update->info_bits &= ~REC_INFO_DELETED_FLAG; + + /* We cannot invoke btr_cur_optimistic_update() here, + because we do not have a btr_cur_t or que_thr_t, + as the insert buffer merge occurs at a very low level. */ + if (!row_upd_changes_field_size_or_external(index, offsets, + update)) { + /* This is the easy case. Do something similar + to btr_cur_update_in_place(). */ + row_upd_rec_in_place(rec, offsets, update); + goto updated_in_place; + } + + /* A collation may identify values that differ in + storage length. + Some examples (1 or 2 bytes): + utf8_turkish_ci: I = U+0131 LATIN SMALL LETTER DOTLESS I + utf8_general_ci: S = U+00DF LATIN SMALL LETTER SHARP S + utf8_general_ci: A = U+00E4 LATIN SMALL LETTER A WITH DIAERESIS + + latin1_german2_ci: SS = U+00DF LATIN SMALL LETTER SHARP S + + Examples of a character (3-byte UTF-8 sequence) + identified with 2 or 4 characters (1-byte UTF-8 sequences): + + utf8_unicode_ci: 'II' = U+2171 SMALL ROMAN NUMERAL TWO + utf8_unicode_ci: '(10)' = U+247D PARENTHESIZED NUMBER TEN + */ + + /* Delete the different-length record, and insert the + buffered one. */ + + lock_rec_store_on_page_infimum(page, rec); + page_cur_delete_rec(&page_cur, index, offsets, mtr); + page_cur_move_to_prev(&page_cur); + mem_heap_free(heap); + + ibuf_insert_to_index_page_low(entry, page, index, mtr, + &page_cur); + lock_rec_restore_from_page_infimum(rec, page); + } else { + ibuf_insert_to_index_page_low(entry, page, index, mtr, + &page_cur); } } diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index 322848509f4..e52c22b8f57 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -38,6 +38,20 @@ buf_flush_init_for_writing( dulint newest_lsn, /* in: newest modification lsn to the page */ ulint space, /* in: space id */ ulint page_no); /* in: page number */ +# if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/********************************************************************** +Writes a flushable page asynchronously from the buffer pool to a file. +NOTE: buf_pool_mutex and block->mutex must be held upon entering this +function, and they will be released by this function after flushing. +This is loosely based on buf_flush_batch() and buf_flush_try_page(). */ + +ibool +buf_flush_page_try( +/*===============*/ + /* out: TRUE if flushed and + mutexes released */ + buf_block_t* block); /*!< in/out: buffer control block */ +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ /*********************************************************************** This utility flushes dirty blocks from the end of the LRU list or flush_list. NOTE 1: in the case of an LRU flush the calling thread may own latches to diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h index 6d26fd4d3b2..777e55a350d 100644 --- a/storage/innobase/include/buf0lru.h +++ b/storage/innobase/include/buf0lru.h @@ -66,6 +66,14 @@ buf_LRU_get_recent_limit(void); /*==========================*/ /* out: the limit; zero if could not determine it */ /********************************************************************** +Try to put a block from the LRU list to the free list. */ + +ibool +buf_LRU_free_block( +/*===============*/ + /* out: TRUE if freed */ + buf_block_t* block); /* in/out: block to be freed */ +/********************************************************************** Look for a replaceable block from the end of the LRU list and put it to the free list if found. */ diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h index 77fefe2020b..d6d7a918b62 100644 --- a/storage/innobase/include/ibuf0ibuf.h +++ b/storage/innobase/include/ibuf0ibuf.h @@ -18,6 +18,11 @@ Created 7/19/1997 Heikki Tuuri #include "ibuf0types.h" #include "fsp0fsp.h" +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/* Flag to control insert buffer debugging. */ +extern uint ibuf_debug; +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + extern ibuf_t* ibuf; /********************************************************************** diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h index abc204bb583..58762fc3111 100644 --- a/storage/innobase/include/rem0rec.h +++ b/storage/innobase/include/rem0rec.h @@ -19,6 +19,9 @@ if and only if the record is the first user record on a non-leaf B-tree page that is the leftmost page on its level (PAGE_LEVEL is nonzero and FIL_PAGE_PREV is FIL_NULL). */ #define REC_INFO_MIN_REC_FLAG 0x10UL +/* The deleted flag in info bits */ +#define REC_INFO_DELETED_FLAG 0x20UL /* when bit is set to 1, it means the + record has been delete marked */ /* Number of extra bytes in an old-style record, in addition to the data and the offsets */ diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic index d91fb4c4391..df66bb13aeb 100644 --- a/storage/innobase/include/rem0rec.ic +++ b/storage/innobase/include/rem0rec.ic @@ -98,9 +98,6 @@ and the shift needed to obtain each bit-field of the record. */ #define REC_INFO_BITS_MASK 0xF0UL #define REC_INFO_BITS_SHIFT 0 -/* The deleted flag in info bits */ -#define REC_INFO_DELETED_FLAG 0x20UL /* when bit is set to 1, it means the - record has been delete marked */ /* The following masks are used to filter the SQL null bit from one-byte and two-byte offsets */ diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 488177791a4..52b13838cc7 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -485,6 +485,10 @@ struct mysql_row_templ_struct { Innobase record in the current index; not defined if template_type is ROW_MYSQL_WHOLE_ROW */ + ulint clust_rec_field_no; /* field number of the column in an + Innobase record in the clustered index; + not defined if template_type is + ROW_MYSQL_WHOLE_ROW */ ulint mysql_col_offset; /* offset of the column in the MySQL row format */ ulint mysql_col_len; /* length of the column in the MySQL diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h index efbc6d6facf..034b1dafb17 100644 --- a/storage/innobase/include/row0upd.h +++ b/storage/innobase/include/row0upd.h @@ -129,9 +129,11 @@ row_upd_changes_field_size_or_external( const ulint* offsets,/* in: rec_get_offsets(rec, index) */ upd_t* update);/* in: update vector */ /*************************************************************** -Replaces the new column values stored in the update vector to the record -given. No field size changes are allowed. This function is used only for -a clustered index */ +Replaces the new column values stored in the update vector to the +record given. No field size changes are allowed. This function is +usually invoked on a clustered index. The only use case for a +secondary index is row_ins_sec_index_entry_by_modify() or its +counterpart in ibuf_insert_to_index_page(). */ void row_upd_rec_in_place( diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index a0f54f7288e..99738115cc7 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -400,7 +400,7 @@ row_mysql_convert_row_to_innobase( row is used, as row may contain pointers to this record! */ { - mysql_row_templ_t* templ; + const mysql_row_templ_t*templ; dfield_t* dfield; ulint i; diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index ad15d0798a2..e03d3d79768 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -2601,20 +2601,21 @@ row_sel_store_mysql_rec( row_prebuilt_t* prebuilt, /* in: prebuilt struct */ rec_t* rec, /* in: Innobase record in the index which was described in prebuilt's - template */ + template, or in the clustered index; + must be protected by a page latch */ + ibool rec_clust, /* in: TRUE if rec is in the clustered + index instead of prebuilt->index */ const ulint* offsets) /* in: array returned by - rec_get_offsets() */ + rec_get_offsets(rec) */ { - mysql_row_templ_t* templ; mem_heap_t* extern_field_heap = NULL; mem_heap_t* heap; - byte* data; - ulint len; ulint i; ut_ad(prebuilt->mysql_template); ut_ad(prebuilt->default_rec); ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) { mem_heap_free(prebuilt->blob_heap); @@ -2623,10 +2624,15 @@ row_sel_store_mysql_rec( for (i = 0; i < prebuilt->n_template; i++) { - templ = prebuilt->mysql_template + i; + const mysql_row_templ_t*templ = prebuilt->mysql_template + i; + byte* data; + ulint len; + ulint field_no; - if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, - templ->rec_field_no))) { + field_no = rec_clust + ? templ->clust_rec_field_no : templ->rec_field_no; + + if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) { /* Copy an externally stored field to the temporary heap */ @@ -2652,15 +2658,13 @@ row_sel_store_mysql_rec( causes an assert */ data = btr_rec_copy_externally_stored_field( - rec, offsets, templ->rec_field_no, - &len, heap); + rec, offsets, field_no, &len, heap); ut_a(len != UNIV_SQL_NULL); } else { /* Field is stored in the row. */ - data = rec_get_nth_field(rec, offsets, - templ->rec_field_no, &len); + data = rec_get_nth_field(rec, offsets, field_no, &len); if (UNIV_UNLIKELY(templ->type == DATA_BLOB) && len != UNIV_SQL_NULL) { @@ -3019,7 +3023,7 @@ row_sel_pop_cached_row_for_mysql( row_prebuilt_t* prebuilt) /* in: prebuilt struct */ { ulint i; - mysql_row_templ_t* templ; + const mysql_row_templ_t*templ; byte* cached_rec; ut_ad(prebuilt->n_fetch_cached > 0); ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len); @@ -3075,14 +3079,19 @@ void row_sel_push_cache_row_for_mysql( /*=============================*/ row_prebuilt_t* prebuilt, /* in: prebuilt struct */ - rec_t* rec, /* in: record to push */ - const ulint* offsets) /* in: rec_get_offsets() */ + rec_t* rec, /* in: Innobase record in the index + which was described in prebuilt's + template, or in the clustered index */ + ibool rec_clust, /* in: TRUE if rec is in the clustered + index instead of prebuilt->index */ + const ulint* offsets) /* in: rec_get_offsets(rec) */ { byte* buf; ulint i; ut_ad(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE); ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); ut_a(!prebuilt->templ_contains_blob); if (prebuilt->fetch_cache[0] == NULL) { @@ -3111,7 +3120,7 @@ row_sel_push_cache_row_for_mysql( if (UNIV_UNLIKELY(!row_sel_store_mysql_rec( prebuilt->fetch_cache[ prebuilt->n_fetch_cached], - prebuilt, rec, offsets))) { + prebuilt, rec, rec_clust, offsets))) { ut_error; } @@ -3500,7 +3509,8 @@ row_search_for_mysql( rec, offsets)); #endif if (!row_sel_store_mysql_rec(buf, prebuilt, - rec, offsets)) { + rec, FALSE, + offsets)) { err = DB_TOO_BIG_RECORD; /* We let the main loop to do the @@ -4233,19 +4243,8 @@ requires_clust_rec: goto next_rec; } - if (prebuilt->need_to_access_clustered) { - - result_rec = clust_rec; - - ut_ad(rec_offs_validate(result_rec, clust_index, - offsets)); - } else { - /* We used 'offsets' for the clust rec, recalculate - them for 'rec' */ - offsets = rec_get_offsets(rec, index, offsets, - ULINT_UNDEFINED, &heap); - result_rec = rec; - } + result_rec = clust_rec; + ut_ad(rec_offs_validate(result_rec, clust_index, offsets)); } else { result_rec = rec; } @@ -4256,6 +4255,7 @@ requires_clust_rec: ut_ad(rec_offs_validate(result_rec, result_rec != rec ? clust_index : index, offsets)); + ut_ad(!rec_get_deleted_flag(result_rec, comp)); if ((match_mode == ROW_SEL_EXACT || prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD) @@ -4276,7 +4276,7 @@ requires_clust_rec: cursor. */ row_sel_push_cache_row_for_mysql(prebuilt, result_rec, - offsets); + result_rec != rec, offsets); if (prebuilt->n_fetch_cached == MYSQL_FETCH_CACHE_SIZE) { goto got_row; @@ -4284,15 +4284,31 @@ requires_clust_rec: goto next_rec; } else { - if (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE) { + if (UNIV_UNLIKELY + (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE)) { + /* CHECK TABLE: fetch the row */ + + if (result_rec != rec + && !prebuilt->need_to_access_clustered) { + /* We used 'offsets' for the clust + rec, recalculate them for 'rec' */ + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, + &heap); + result_rec = rec; + } + memcpy(buf + 4, result_rec - rec_offs_extra_size(offsets), rec_offs_size(offsets)); mach_write_to_4(buf, rec_offs_extra_size(offsets) + 4); } else { - if (!row_sel_store_mysql_rec(buf, prebuilt, - result_rec, offsets)) { + /* Returning a row to MySQL */ + + if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec, + result_rec != rec, + offsets)) { err = DB_TOO_BIG_RECORD; goto lock_wait_or_error; diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c index 034b7010410..0790cfe02e2 100644 --- a/storage/innobase/row/row0upd.c +++ b/storage/innobase/row/row0upd.c @@ -430,9 +430,11 @@ row_upd_changes_field_size_or_external( } /*************************************************************** -Replaces the new column values stored in the update vector to the record -given. No field size changes are allowed. This function is used only for -a clustered index */ +Replaces the new column values stored in the update vector to the +record given. No field size changes are allowed. This function is +usually invoked on a clustered index. The only use case for a +secondary index is row_ins_sec_index_entry_by_modify() or its +counterpart in ibuf_insert_to_index_page(). */ void row_upd_rec_in_place( From c38071ec180f6e419ac0a1f2aa03cdd9263149a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 19 Oct 2010 09:04:15 +0300 Subject: [PATCH 087/151] Bug #56680 wrong InnoDB results from a case-insensitive covering index row_search_for_mysql(): When a secondary index record might not be visible in the current transaction's read view and we consult the clustered index and optionally some undo log records, return the relevant columns of the clustered index record to MySQL instead of the secondary index record. ibuf_insert_to_index_page_low(): New function, refactored from ibuf_insert_to_index_page(). ibuf_insert_to_index_page(): When we are inserting a record in place of a delete-marked record and some fields of the record differ, update that record just like row_ins_sec_index_entry_by_modify() would do. btr_cur_update_alloc_zip(): Make the function public. mysql_row_templ_t: Add clust_rec_field_no. row_sel_store_mysql_rec(), row_sel_push_cache_row_for_mysql(): Add the flag rec_clust, for returning data at clust_rec_field_no instead of rec_field_no. Resurrect the debug assertion that the record not be marked for deletion. (Bug #55626) [UNIV_DEBUG || UNIV_IBUF_DEBUG] ibuf_debug, buf_page_get_gen(), buf_flush_page_try(): Implement innodb_change_buffering_debug=1 for evicting pages from the buffer pool, so that change buffering will be attempted more frequently. --- .../innodb_plugin/r/innodb_bug56680.result | 109 +++++++++ .../innodb_plugin/t/innodb_bug56680.test | 142 ++++++++++++ storage/innodb_plugin/ChangeLog | 10 + storage/innodb_plugin/btr/btr0cur.c | 2 +- storage/innodb_plugin/buf/buf0buf.c | 24 ++ storage/innodb_plugin/buf/buf0flu.c | 76 +++++++ storage/innodb_plugin/handler/ha_innodb.cc | 27 ++- storage/innodb_plugin/ibuf/ibuf0ibuf.c | 207 +++++++++++++----- storage/innodb_plugin/include/btr0cur.h | 16 ++ storage/innodb_plugin/include/buf0flu.h | 14 ++ storage/innodb_plugin/include/ibuf0ibuf.h | 5 + storage/innodb_plugin/include/row0mysql.h | 4 + storage/innodb_plugin/include/row0upd.h | 7 +- storage/innodb_plugin/row/row0mysql.c | 2 +- storage/innodb_plugin/row/row0sel.c | 99 +++++---- storage/innodb_plugin/row/row0upd.c | 7 +- 16 files changed, 635 insertions(+), 116 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug56680.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug56680.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug56680.result b/mysql-test/suite/innodb_plugin/r/innodb_bug56680.result new file mode 100644 index 00000000000..5e798b69167 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug56680.result @@ -0,0 +1,109 @@ +SET GLOBAL tx_isolation='REPEATABLE-READ'; +SET GLOBAL innodb_file_format=Barracuda; +SET GLOBAL innodb_file_per_table=on; +CREATE TABLE bug56680( +a INT AUTO_INCREMENT PRIMARY KEY, +b CHAR(1), +c INT, +INDEX(b)) +ENGINE=InnoDB; +INSERT INTO bug56680 VALUES(0,'x',1); +BEGIN; +SELECT b FROM bug56680; +b +x +BEGIN; +UPDATE bug56680 SET b='X'; +SELECT b FROM bug56680; +b +x +SELECT * FROM bug56680; +a b c +1 x 1 +ROLLBACK; +SELECT b FROM bug56680; +b +x +SET GLOBAL tx_isolation='READ-UNCOMMITTED'; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +BEGIN; +SELECT b FROM bug56680 LIMIT 2; +b +x +x +BEGIN; +DELETE FROM bug56680 WHERE a=1; +INSERT INTO bug56680 VALUES(1,'X',1); +SELECT b FROM bug56680 LIMIT 3; +b +X +x +x +SELECT b FROM bug56680 LIMIT 2; +b +x +x +CHECK TABLE bug56680; +Table Op Msg_type Msg_text +test.bug56680 check status OK +ROLLBACK; +SELECT b FROM bug56680 LIMIT 2; +b +x +x +CHECK TABLE bug56680; +Table Op Msg_type Msg_text +test.bug56680 check status OK +SELECT b FROM bug56680 LIMIT 2; +b +x +x +CREATE TABLE bug56680_2( +a INT AUTO_INCREMENT PRIMARY KEY, +b VARCHAR(2) CHARSET latin1 COLLATE latin1_german2_ci, +c INT, +INDEX(b)) +ENGINE=InnoDB; +INSERT INTO bug56680_2 SELECT 0,_latin1 0xdf,c FROM bug56680; +BEGIN; +SELECT HEX(b) FROM bug56680_2 LIMIT 2; +HEX(b) +DF +DF +DELETE FROM bug56680_2 WHERE a=1; +INSERT INTO bug56680_2 VALUES(1,'SS',1); +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +HEX(b) +5353 +DF +DF +CHECK TABLE bug56680_2; +Table Op Msg_type Msg_text +test.bug56680_2 check status OK +ALTER TABLE bug56680_2 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SELECT HEX(b) FROM bug56680_2 LIMIT 2; +HEX(b) +5353 +DF +DELETE FROM bug56680_2 WHERE a=1; +INSERT INTO bug56680_2 VALUES(1,_latin1 0xdf,1); +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +HEX(b) +DF +DF +DF +CHECK TABLE bug56680_2; +Table Op Msg_type Msg_text +test.bug56680_2 check status OK +DROP TABLE bug56680_2; +DROP TABLE bug56680; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug56680.test b/mysql-test/suite/innodb_plugin/t/innodb_bug56680.test new file mode 100644 index 00000000000..8d0f685c723 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug56680.test @@ -0,0 +1,142 @@ +# +# Bug #56680 InnoDB may return wrong results from a case-insensitive index +# +-- source include/have_innodb_plugin.inc + +-- disable_query_log +SET @tx_isolation_orig = @@tx_isolation; +SET @innodb_file_per_table_orig = @@innodb_file_per_table; +SET @innodb_file_format_orig = @@innodb_file_format; +SET @innodb_file_format_check_orig = @@innodb_file_format_check; +# The flag innodb_change_buffering_debug is only available in debug builds. +# It instructs InnoDB to try to evict pages from the buffer pool when +# change buffering is possible, so that the change buffer will be used +# whenever possible. +-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET @innodb_change_buffering_debug_orig = @@innodb_change_buffering_debug; +-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_change_buffering_debug = 1; +-- enable_query_log +SET GLOBAL tx_isolation='REPEATABLE-READ'; +SET GLOBAL innodb_file_format=Barracuda; +SET GLOBAL innodb_file_per_table=on; + +CREATE TABLE bug56680( + a INT AUTO_INCREMENT PRIMARY KEY, + b CHAR(1), + c INT, + INDEX(b)) +ENGINE=InnoDB; + +INSERT INTO bug56680 VALUES(0,'x',1); +BEGIN; +SELECT b FROM bug56680; + +connect (con1,localhost,root,,); +connection con1; +BEGIN; +UPDATE bug56680 SET b='X'; + +connection default; +# This should return the last committed value 'x', but would return 'X' +# due to a bug in row_search_for_mysql(). +SELECT b FROM bug56680; +# This would always return the last committed value 'x'. +SELECT * FROM bug56680; + +connection con1; +ROLLBACK; +disconnect con1; + +connection default; + +SELECT b FROM bug56680; + +# For the rest of this test, use the READ UNCOMMITTED isolation level +# to see what exists in the secondary index. +SET GLOBAL tx_isolation='READ-UNCOMMITTED'; + +# Create enough rows for the table, so that the insert buffer will be +# used for modifying the secondary index page. There must be multiple +# index pages, because changes to the root page are never buffered. + +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; + +BEGIN; +SELECT b FROM bug56680 LIMIT 2; + +connect (con1,localhost,root,,); +connection con1; +BEGIN; +DELETE FROM bug56680 WHERE a=1; +# This should be buffered, if innodb_change_buffering_debug = 1 is in effect. +INSERT INTO bug56680 VALUES(1,'X',1); + +# This should force an insert buffer merge, and return 'X' in the first row. +SELECT b FROM bug56680 LIMIT 3; + +connection default; +SELECT b FROM bug56680 LIMIT 2; +CHECK TABLE bug56680; + +connection con1; +ROLLBACK; +SELECT b FROM bug56680 LIMIT 2; +CHECK TABLE bug56680; + +connection default; +disconnect con1; + +SELECT b FROM bug56680 LIMIT 2; + +CREATE TABLE bug56680_2( + a INT AUTO_INCREMENT PRIMARY KEY, + b VARCHAR(2) CHARSET latin1 COLLATE latin1_german2_ci, + c INT, + INDEX(b)) +ENGINE=InnoDB; + +INSERT INTO bug56680_2 SELECT 0,_latin1 0xdf,c FROM bug56680; + +BEGIN; +SELECT HEX(b) FROM bug56680_2 LIMIT 2; +DELETE FROM bug56680_2 WHERE a=1; +# This should be buffered, if innodb_change_buffering_debug = 1 is in effect. +INSERT INTO bug56680_2 VALUES(1,'SS',1); + +# This should force an insert buffer merge, and return 'SS' in the first row. +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +CHECK TABLE bug56680_2; + +# Test this with compressed tables. +ALTER TABLE bug56680_2 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; + +SELECT HEX(b) FROM bug56680_2 LIMIT 2; +DELETE FROM bug56680_2 WHERE a=1; +# This should be buffered, if innodb_change_buffering_debug = 1 is in effect. +INSERT INTO bug56680_2 VALUES(1,_latin1 0xdf,1); + +# This should force an insert buffer merge, and return 0xdf in the first row. +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +CHECK TABLE bug56680_2; + +DROP TABLE bug56680_2; +DROP TABLE bug56680; + +-- disable_query_log +SET GLOBAL tx_isolation = @tx_isolation_orig; +SET GLOBAL innodb_file_per_table = @innodb_file_per_table_orig; +SET GLOBAL innodb_file_format = @innodb_file_format_orig; +SET GLOBAL innodb_file_format_check = @innodb_file_format_check_orig; +-- error 0, ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_change_buffering_debug = @innodb_change_buffering_debug_orig; diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 488669346fd..db37fa2b4bb 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,13 @@ +2010-10-19 The InnoDB Team + + * btr/btr0cur.c, buf/buf0buf.c, buf/buf0flu.c, handler/ha_innodb.cc, + ibuf/ibuf0ibuf.c, include/btr0cur.h, include/buf0flu.h, + include/ibuf0ibuf.h, include/row0mysql.h, + row/row0mysql.c, row/row0sel.c, + innodb_bug56680.test, innodb_bug56680.result: + Fix Bug #56680 InnoDB may return wrong results from a + case-insensitive covering index + 2010-10-18 The InnoDB Team * handler/ha_innodb.cc, handler/ha_innodb.h, innodb_bug57252.result, diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 9812e91e8a5..79fe328a631 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -1626,7 +1626,7 @@ func_exit: See if there is enough place in the page modification log to log an update-in-place. @return TRUE if enough place */ -static +UNIV_INTERN ibool btr_cur_update_alloc_zip( /*=====================*/ diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index 660686bac1e..65d4311b840 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -2286,6 +2286,30 @@ wait_until_unfixed: bytes. */ UNIV_MEM_ASSERT_RW(&block->page, sizeof block->page); #endif +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG + if (mode == BUF_GET_IF_IN_POOL && ibuf_debug) { + /* Try to evict the block from the buffer pool, to use the + insert buffer as much as possible. */ + + if (buf_LRU_free_block(&block->page, TRUE, NULL) + == BUF_LRU_FREED) { + buf_pool_mutex_exit(); + mutex_exit(&block->mutex); + fprintf(stderr, + "innodb_change_buffering_debug evict %u %u\n", + (unsigned) space, (unsigned) offset); + return(NULL); + } else if (buf_flush_page_try(block)) { + fprintf(stderr, + "innodb_change_buffering_debug flush %u %u\n", + (unsigned) space, (unsigned) offset); + guess = block; + goto loop; + } + + /* Failed to evict the page; change it directly */ + } +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ buf_block_buf_fix_inc(block, file, line); diff --git a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0flu.c index 747ce65879d..2123f8a060d 100644 --- a/storage/innodb_plugin/buf/buf0flu.c +++ b/storage/innodb_plugin/buf/buf0flu.c @@ -1039,6 +1039,82 @@ buf_flush_write_block_low( } } +# if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/********************************************************************//** +Writes a flushable page asynchronously from the buffer pool to a file. +NOTE: buf_pool_mutex and block->mutex must be held upon entering this +function, and they will be released by this function after flushing. +This is loosely based on buf_flush_batch() and buf_flush_page(). +@return TRUE if the page was flushed and the mutexes released */ +UNIV_INTERN +ibool +buf_flush_page_try( +/*===============*/ + buf_block_t* block) /*!< in/out: buffer control block */ +{ + ut_ad(buf_pool_mutex_own()); + ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); + ut_ad(mutex_own(&block->mutex)); + + if (!buf_flush_ready_for_flush(&block->page, BUF_FLUSH_LRU)) { + return(FALSE); + } + + if (buf_pool->n_flush[BUF_FLUSH_LRU] > 0 + || buf_pool->init_flush[BUF_FLUSH_LRU]) { + /* There is already a flush batch of the same type running */ + return(FALSE); + } + + buf_pool->init_flush[BUF_FLUSH_LRU] = TRUE; + + buf_page_set_io_fix(&block->page, BUF_IO_WRITE); + + buf_page_set_flush_type(&block->page, BUF_FLUSH_LRU); + + if (buf_pool->n_flush[BUF_FLUSH_LRU]++ == 0) { + + os_event_reset(buf_pool->no_flush[BUF_FLUSH_LRU]); + } + + /* VERY IMPORTANT: + Because any thread may call the LRU flush, even when owning + locks on pages, to avoid deadlocks, we must make sure that the + s-lock is acquired on the page without waiting: this is + accomplished because buf_flush_ready_for_flush() must hold, + and that requires the page not to be bufferfixed. */ + + rw_lock_s_lock_gen(&block->lock, BUF_IO_WRITE); + + /* Note that the s-latch is acquired before releasing the + buf_pool mutex: this ensures that the latch is acquired + immediately. */ + + mutex_exit(&block->mutex); + buf_pool_mutex_exit(); + + /* Even though block is not protected by any mutex at this + point, it is safe to access block, because it is io_fixed and + oldest_modification != 0. Thus, it cannot be relocated in the + buffer pool or removed from flush_list or LRU_list. */ + + buf_flush_write_block_low(&block->page); + + buf_pool_mutex_enter(); + buf_pool->init_flush[BUF_FLUSH_LRU] = FALSE; + + if (buf_pool->n_flush[BUF_FLUSH_LRU] == 0) { + /* The running flush batch has ended */ + os_event_set(buf_pool->no_flush[BUF_FLUSH_LRU]); + } + + buf_pool_mutex_exit(); + buf_flush_buffered_writes(); + + return(TRUE); +} +# endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + /********************************************************************//** Writes a flushable page asynchronously from the buffer pool to a file. NOTE: in simulated aio we must call diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 35f1a4974e2..99d4f294f81 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -4432,17 +4432,18 @@ include_field: n_requested_fields++; templ->col_no = i; + templ->clust_rec_field_no = dict_col_get_clust_pos( + &index->table->cols[i], clust_index); + ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED); if (index == clust_index) { - templ->rec_field_no = dict_col_get_clust_pos( - &index->table->cols[i], index); + templ->rec_field_no = templ->clust_rec_field_no; } else { templ->rec_field_no = dict_index_get_nth_col_pos( index, i); - } - - if (templ->rec_field_no == ULINT_UNDEFINED) { - prebuilt->need_to_access_clustered = TRUE; + if (templ->rec_field_no == ULINT_UNDEFINED) { + prebuilt->need_to_access_clustered = TRUE; + } } if (field->null_ptr) { @@ -4494,9 +4495,7 @@ skip_field: for (i = 0; i < n_requested_fields; i++) { templ = prebuilt->mysql_template + i; - templ->rec_field_no = dict_col_get_clust_pos( - &index->table->cols[templ->col_no], - clust_index); + templ->rec_field_no = templ->clust_rec_field_no; } } } @@ -10945,6 +10944,13 @@ static MYSQL_SYSVAR_STR(change_buffering, innobase_change_buffering, innodb_change_buffering_validate, innodb_change_buffering_update, "inserts"); +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug, + PLUGIN_VAR_RQCMDARG, + "Debug flags for InnoDB change buffering (0=none)", + NULL, NULL, 0, 0, 1, 0); +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold, PLUGIN_VAR_RQCMDARG, "Number of pages that must be accessed sequentially for InnoDB to " @@ -11005,6 +11011,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(version), MYSQL_SYSVAR(use_sys_malloc), MYSQL_SYSVAR(change_buffering), +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG + MYSQL_SYSVAR(change_buffering_debug), +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ MYSQL_SYSVAR(read_ahead_threshold), MYSQL_SYSVAR(io_capacity), NULL diff --git a/storage/innodb_plugin/ibuf/ibuf0ibuf.c b/storage/innodb_plugin/ibuf/ibuf0ibuf.c index 5e9b4b27611..701e8f0ef04 100644 --- a/storage/innodb_plugin/ibuf/ibuf0ibuf.c +++ b/storage/innodb_plugin/ibuf/ibuf0ibuf.c @@ -49,6 +49,7 @@ Created 7/19/1997 Heikki Tuuri #include "btr0cur.h" #include "btr0pcur.h" #include "btr0btr.h" +#include "row0upd.h" #include "sync0sync.h" #include "dict0boot.h" #include "fut0lst.h" @@ -170,6 +171,11 @@ access order rules. */ /** Operations that can currently be buffered. */ UNIV_INTERN ibuf_use_t ibuf_use = IBUF_USE_INSERT; +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/** Flag to control insert buffer debugging. */ +UNIV_INTERN uint ibuf_debug; +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + /** The insert buffer control structure */ UNIV_INTERN ibuf_t* ibuf = NULL; @@ -2881,9 +2887,80 @@ During merge, inserts to an index page a secondary index entry extracted from the insert buffer. */ static void +ibuf_insert_to_index_page_low( +/*==========================*/ + const dtuple_t* entry, /*!< in: buffered entry to insert */ + buf_block_t* block, /*!< in/out: index page where the buffered + entry should be placed */ + dict_index_t* index, /*!< in: record descriptor */ + mtr_t* mtr, /*!< in/out: mtr */ + page_cur_t* page_cur)/*!< in/out: cursor positioned on the record + after which to insert the buffered entry */ +{ + const page_t* page; + ulint space; + ulint page_no; + ulint zip_size; + const page_t* bitmap_page; + ulint old_bits; + + if (UNIV_LIKELY + (page_cur_tuple_insert(page_cur, entry, index, 0, mtr) != NULL)) { + return; + } + + /* If the record did not fit, reorganize */ + + btr_page_reorganize(block, index, mtr); + page_cur_search(block, index, entry, PAGE_CUR_LE, page_cur); + + /* This time the record must fit */ + + if (UNIV_LIKELY + (page_cur_tuple_insert(page_cur, entry, index, 0, mtr) != NULL)) { + return; + } + + page = buf_block_get_frame(block); + + ut_print_timestamp(stderr); + + fprintf(stderr, + " InnoDB: Error: Insert buffer insert fails;" + " page free %lu, dtuple size %lu\n", + (ulong) page_get_max_insert_size(page, 1), + (ulong) rec_get_converted_size(index, entry, 0)); + fputs("InnoDB: Cannot insert index record ", stderr); + dtuple_print(stderr, entry); + fputs("\nInnoDB: The table where this index record belongs\n" + "InnoDB: is now probably corrupt. Please run CHECK TABLE on\n" + "InnoDB: that table.\n", stderr); + + space = page_get_space_id(page); + zip_size = buf_block_get_zip_size(block); + page_no = page_get_page_no(page); + + bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr); + old_bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size, + IBUF_BITMAP_FREE, mtr); + + fprintf(stderr, + "InnoDB: space %lu, page %lu, zip_size %lu, bitmap bits %lu\n", + (ulong) space, (ulong) page_no, + (ulong) zip_size, (ulong) old_bits); + + fputs("InnoDB: Submit a detailed bug report" + " to http://bugs.mysql.com\n", stderr); +} + +/************************************************************************ +During merge, inserts to an index page a secondary index entry extracted +from the insert buffer. */ +static +void ibuf_insert_to_index_page( /*======================*/ - dtuple_t* entry, /*!< in: buffered entry to insert */ + const dtuple_t* entry, /*!< in: buffered entry to insert */ buf_block_t* block, /*!< in/out: index page where the buffered entry should be placed */ dict_index_t* index, /*!< in: record descriptor */ @@ -2893,11 +2970,10 @@ ibuf_insert_to_index_page( ulint low_match; page_t* page = buf_block_get_frame(block); rec_t* rec; - page_t* bitmap_page; - ulint old_bits; ut_ad(ibuf_inside()); ut_ad(dtuple_check_typed(entry)); + ut_ad(!buf_block_align(page)->is_hashed); if (UNIV_UNLIKELY(dict_table_is_comp(index->table) != (ibool)!!page_is_comp(page))) { @@ -2935,71 +3011,86 @@ dump: low_match = page_cur_search(block, index, entry, PAGE_CUR_LE, &page_cur); - if (low_match == dtuple_get_n_fields(entry)) { + if (UNIV_UNLIKELY(low_match == dtuple_get_n_fields(entry))) { + mem_heap_t* heap; + upd_t* update; + ulint* offsets; page_zip_des_t* page_zip; rec = page_cur_get_rec(&page_cur); + + /* This is based on + row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */ + ut_ad(rec_get_deleted_flag(rec, page_is_comp(page))); + + heap = mem_heap_create(1024); + + offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, + &heap); + update = row_upd_build_sec_rec_difference_binary( + index, entry, rec, NULL, heap); + page_zip = buf_block_get_page_zip(block); - btr_cur_del_unmark_for_ibuf(rec, page_zip, mtr); - } else { - rec = page_cur_tuple_insert(&page_cur, entry, index, 0, mtr); - - if (UNIV_LIKELY(rec != NULL)) { + if (update->n_fields == 0) { + /* The records only differ in the delete-mark. + Clear the delete-mark, like we did before + Bug #56680 was fixed. */ + btr_cur_del_unmark_for_ibuf(rec, page_zip, mtr); +updated_in_place: + mem_heap_free(heap); return; } - /* If the record did not fit, reorganize */ + /* Copy the info bits. Clear the delete-mark. */ + update->info_bits = rec_get_info_bits(rec, page_is_comp(page)); + update->info_bits &= ~REC_INFO_DELETED_FLAG; - btr_page_reorganize(block, index, mtr); - page_cur_search(block, index, entry, PAGE_CUR_LE, &page_cur); - - /* This time the record must fit */ - if (UNIV_UNLIKELY - (!page_cur_tuple_insert(&page_cur, entry, index, - 0, mtr))) { - ulint space; - ulint page_no; - ulint zip_size; - - ut_print_timestamp(stderr); - - fprintf(stderr, - " InnoDB: Error: Insert buffer insert" - " fails; page free %lu," - " dtuple size %lu\n", - (ulong) page_get_max_insert_size( - page, 1), - (ulong) rec_get_converted_size( - index, entry, 0)); - fputs("InnoDB: Cannot insert index record ", - stderr); - dtuple_print(stderr, entry); - fputs("\nInnoDB: The table where" - " this index record belongs\n" - "InnoDB: is now probably corrupt." - " Please run CHECK TABLE on\n" - "InnoDB: that table.\n", stderr); - - space = page_get_space_id(page); - zip_size = buf_block_get_zip_size(block); - page_no = page_get_page_no(page); - - bitmap_page = ibuf_bitmap_get_map_page( - space, page_no, zip_size, mtr); - old_bits = ibuf_bitmap_page_get_bits( - bitmap_page, page_no, zip_size, - IBUF_BITMAP_FREE, mtr); - - fprintf(stderr, - "InnoDB: space %lu, page %lu," - " zip_size %lu, bitmap bits %lu\n", - (ulong) space, (ulong) page_no, - (ulong) zip_size, (ulong) old_bits); - - fputs("InnoDB: Submit a detailed bug report" - " to http://bugs.mysql.com\n", stderr); + /* We cannot invoke btr_cur_optimistic_update() here, + because we do not have a btr_cur_t or que_thr_t, + as the insert buffer merge occurs at a very low level. */ + if (!row_upd_changes_field_size_or_external(index, offsets, + update) + && (!page_zip || btr_cur_update_alloc_zip( + page_zip, block, index, + rec_offs_size(offsets), FALSE, mtr))) { + /* This is the easy case. Do something similar + to btr_cur_update_in_place(). */ + row_upd_rec_in_place(rec, index, offsets, + update, page_zip); + goto updated_in_place; } + + /* A collation may identify values that differ in + storage length. + Some examples (1 or 2 bytes): + utf8_turkish_ci: I = U+0131 LATIN SMALL LETTER DOTLESS I + utf8_general_ci: S = U+00DF LATIN SMALL LETTER SHARP S + utf8_general_ci: A = U+00E4 LATIN SMALL LETTER A WITH DIAERESIS + + latin1_german2_ci: SS = U+00DF LATIN SMALL LETTER SHARP S + + Examples of a character (3-byte UTF-8 sequence) + identified with 2 or 4 characters (1-byte UTF-8 sequences): + + utf8_unicode_ci: 'II' = U+2171 SMALL ROMAN NUMERAL TWO + utf8_unicode_ci: '(10)' = U+247D PARENTHESIZED NUMBER TEN + */ + + /* Delete the different-length record, and insert the + buffered one. */ + + lock_rec_store_on_page_infimum(block, rec); + page_cur_delete_rec(&page_cur, index, offsets, mtr); + page_cur_move_to_prev(&page_cur); + mem_heap_free(heap); + + ibuf_insert_to_index_page_low(entry, block, index, mtr, + &page_cur); + lock_rec_restore_from_page_infimum(block, rec, block); + } else { + ibuf_insert_to_index_page_low(entry, block, index, mtr, + &page_cur); } } diff --git a/storage/innodb_plugin/include/btr0cur.h b/storage/innodb_plugin/include/btr0cur.h index e151fdcb563..7f6bff11f84 100644 --- a/storage/innodb_plugin/include/btr0cur.h +++ b/storage/innodb_plugin/include/btr0cur.h @@ -242,6 +242,22 @@ btr_cur_pessimistic_insert( que_thr_t* thr, /*!< in: query thread or NULL */ mtr_t* mtr); /*!< in: mtr */ /*************************************************************//** +See if there is enough place in the page modification log to log +an update-in-place. +@return TRUE if enough place */ +UNIV_INTERN +ibool +btr_cur_update_alloc_zip( +/*=====================*/ + page_zip_des_t* page_zip,/*!< in/out: compressed page */ + buf_block_t* block, /*!< in/out: buffer page */ + dict_index_t* index, /*!< in: the index corresponding to the block */ + ulint length, /*!< in: size needed */ + ibool create, /*!< in: TRUE=delete-and-insert, + FALSE=update-in-place */ + mtr_t* mtr) /*!< in: mini-transaction */ + __attribute__((nonnull, warn_unused_result)); +/*************************************************************//** Updates a record when the update causes no size changes in its fields. @return DB_SUCCESS or error number */ UNIV_INTERN diff --git a/storage/innodb_plugin/include/buf0flu.h b/storage/innodb_plugin/include/buf0flu.h index c996f6eaab4..cb8c49fde15 100644 --- a/storage/innodb_plugin/include/buf0flu.h +++ b/storage/innodb_plugin/include/buf0flu.h @@ -75,6 +75,20 @@ buf_flush_init_for_writing( ib_uint64_t newest_lsn); /*!< in: newest modification lsn to the page */ #ifndef UNIV_HOTBACKUP +# if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/********************************************************************//** +Writes a flushable page asynchronously from the buffer pool to a file. +NOTE: buf_pool_mutex and block->mutex must be held upon entering this +function, and they will be released by this function after flushing. +This is loosely based on buf_flush_batch() and buf_flush_page(). +@return TRUE if the page was flushed and the mutexes released */ +UNIV_INTERN +ibool +buf_flush_page_try( +/*===============*/ + buf_block_t* block) /*!< in/out: buffer control block */ + __attribute__((nonnull, warn_unused_result)); +# endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ /*******************************************************************//** This utility flushes dirty blocks from the end of the LRU list or flush_list. NOTE 1: in the case of an LRU flush the calling thread may own latches to diff --git a/storage/innodb_plugin/include/ibuf0ibuf.h b/storage/innodb_plugin/include/ibuf0ibuf.h index 8aa21fb9d95..f8cc4471d43 100644 --- a/storage/innodb_plugin/include/ibuf0ibuf.h +++ b/storage/innodb_plugin/include/ibuf0ibuf.h @@ -48,6 +48,11 @@ typedef enum { /** Operations that can currently be buffered. */ extern ibuf_use_t ibuf_use; +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/** Flag to control insert buffer debugging. */ +extern uint ibuf_debug; +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + /** The insert buffer control structure */ extern ibuf_t* ibuf; diff --git a/storage/innodb_plugin/include/row0mysql.h b/storage/innodb_plugin/include/row0mysql.h index b69e657361b..42182cc0044 100644 --- a/storage/innodb_plugin/include/row0mysql.h +++ b/storage/innodb_plugin/include/row0mysql.h @@ -527,6 +527,10 @@ struct mysql_row_templ_struct { Innobase record in the current index; not defined if template_type is ROW_MYSQL_WHOLE_ROW */ + ulint clust_rec_field_no; /*!< field number of the column in an + Innobase record in the clustered index; + not defined if template_type is + ROW_MYSQL_WHOLE_ROW */ ulint mysql_col_offset; /*!< offset of the column in the MySQL row format */ ulint mysql_col_len; /*!< length of the column in the MySQL diff --git a/storage/innodb_plugin/include/row0upd.h b/storage/innodb_plugin/include/row0upd.h index 635d746d5a1..4e2de9bd2ec 100644 --- a/storage/innodb_plugin/include/row0upd.h +++ b/storage/innodb_plugin/include/row0upd.h @@ -167,8 +167,11 @@ row_upd_changes_field_size_or_external( const upd_t* update);/*!< in: update vector */ #endif /* !UNIV_HOTBACKUP */ /***********************************************************//** -Replaces the new column values stored in the update vector to the record -given. No field size changes are allowed. */ +Replaces the new column values stored in the update vector to the +record given. No field size changes are allowed. This function is +usually invoked on a clustered index. The only use case for a +secondary index is row_ins_sec_index_entry_by_modify() or its +counterpart in ibuf_insert_to_index_page(). */ UNIV_INTERN void row_upd_rec_in_place( diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index 78b3b2afdbf..107af481b79 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -444,7 +444,7 @@ row_mysql_convert_row_to_innobase( row is used, as row may contain pointers to this record! */ { - mysql_row_templ_t* templ; + const mysql_row_templ_t*templ; dfield_t* dfield; ulint i; diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c index ea1a19eb82f..ac78a95839c 100644 --- a/storage/innodb_plugin/row/row0sel.c +++ b/storage/innodb_plugin/row/row0sel.c @@ -2675,21 +2675,22 @@ row_sel_store_mysql_rec( row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */ const rec_t* rec, /*!< in: Innobase record in the index which was described in prebuilt's - template; must be protected by - a page latch */ + template, or in the clustered index; + must be protected by a page latch */ + ibool rec_clust, /*!< in: TRUE if rec is in the + clustered index instead of + prebuilt->index */ const ulint* offsets) /*!< in: array returned by - rec_get_offsets() */ + rec_get_offsets(rec) */ { - mysql_row_templ_t* templ; - mem_heap_t* extern_field_heap = NULL; - mem_heap_t* heap; - const byte* data; - ulint len; - ulint i; + mem_heap_t* extern_field_heap = NULL; + mem_heap_t* heap; + ulint i; ut_ad(prebuilt->mysql_template); ut_ad(prebuilt->default_rec); ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) { mem_heap_free(prebuilt->blob_heap); @@ -2698,10 +2699,15 @@ row_sel_store_mysql_rec( for (i = 0; i < prebuilt->n_template; i++) { - templ = prebuilt->mysql_template + i; + const mysql_row_templ_t*templ = prebuilt->mysql_template + i; + const byte* data; + ulint len; + ulint field_no; - if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, - templ->rec_field_no))) { + field_no = rec_clust + ? templ->clust_rec_field_no : templ->rec_field_no; + + if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) { /* Copy an externally stored field to the temporary heap */ @@ -2729,7 +2735,7 @@ row_sel_store_mysql_rec( data = btr_rec_copy_externally_stored_field( rec, offsets, dict_table_zip_size(prebuilt->table), - templ->rec_field_no, &len, heap); + field_no, &len, heap); if (UNIV_UNLIKELY(!data)) { /* The externally stored field @@ -2750,8 +2756,7 @@ row_sel_store_mysql_rec( } else { /* Field is stored in the row. */ - data = rec_get_nth_field(rec, offsets, - templ->rec_field_no, &len); + data = rec_get_nth_field(rec, offsets, field_no, &len); if (UNIV_UNLIKELY(templ->type == DATA_BLOB) && len != UNIV_SQL_NULL) { @@ -3113,7 +3118,7 @@ row_sel_pop_cached_row_for_mysql( row_prebuilt_t* prebuilt) /*!< in: prebuilt struct */ { ulint i; - mysql_row_templ_t* templ; + const mysql_row_templ_t*templ; byte* cached_rec; ut_ad(prebuilt->n_fetch_cached > 0); ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len); @@ -3170,15 +3175,21 @@ ibool row_sel_push_cache_row_for_mysql( /*=============================*/ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */ - const rec_t* rec, /*!< in: record to push; must - be protected by a page latch */ - const ulint* offsets) /*!< in: rec_get_offsets() */ + const rec_t* rec, /*!< in: record to push, in the index + which was described in prebuilt's + template, or in the clustered index; + must be protected by a page latch */ + ibool rec_clust, /*!< in: TRUE if rec is in the + clustered index instead of + prebuilt->index */ + const ulint* offsets) /*!< in: rec_get_offsets(rec) */ { byte* buf; ulint i; ut_ad(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE); ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); ut_a(!prebuilt->templ_contains_blob); if (prebuilt->fetch_cache[0] == NULL) { @@ -3207,7 +3218,7 @@ row_sel_push_cache_row_for_mysql( if (UNIV_UNLIKELY(!row_sel_store_mysql_rec( prebuilt->fetch_cache[ prebuilt->n_fetch_cached], - prebuilt, rec, offsets))) { + prebuilt, rec, rec_clust, offsets))) { return(FALSE); } @@ -3608,7 +3619,8 @@ row_search_for_mysql( ut_ad(!rec_get_deleted_flag(rec, comp)); if (!row_sel_store_mysql_rec(buf, prebuilt, - rec, offsets)) { + rec, FALSE, + offsets)) { /* Only fresh inserts may contain incomplete externally stored columns. Pretend that such @@ -4242,7 +4254,6 @@ no_gap_lock: is necessary, because we can only get the undo information via the clustered index record. */ - ut_ad(index != clust_index); ut_ad(!dict_index_is_clust(index)); if (!lock_sec_rec_cons_read_sees( @@ -4358,26 +4369,10 @@ requires_clust_rec: goto next_rec; } - if (prebuilt->need_to_access_clustered) { - - result_rec = clust_rec; - - ut_ad(rec_offs_validate(result_rec, clust_index, - offsets)); - } else { - /* We used 'offsets' for the clust rec, recalculate - them for 'rec' */ - offsets = rec_get_offsets(rec, index, offsets, - ULINT_UNDEFINED, &heap); - result_rec = rec; - } - - /* result_rec can legitimately be delete-marked - now that it has been established that it points to a - clustered index record that exists in the read view. */ + result_rec = clust_rec; + ut_ad(rec_offs_validate(result_rec, clust_index, offsets)); } else { result_rec = rec; - ut_ad(!rec_get_deleted_flag(rec, comp)); } /* We found a qualifying record 'result_rec'. At this point, @@ -4386,6 +4381,7 @@ requires_clust_rec: ut_ad(rec_offs_validate(result_rec, result_rec != rec ? clust_index : index, offsets)); + ut_ad(!rec_get_deleted_flag(result_rec, comp)); /* At this point, the clustered index record is protected by a page latch that was acquired when pcur was positioned. @@ -4410,6 +4406,7 @@ requires_clust_rec: cursor. */ if (!row_sel_push_cache_row_for_mysql(prebuilt, result_rec, + result_rec != rec, offsets)) { /* Only fresh inserts may contain incomplete externally stored columns. Pretend that such @@ -4427,15 +4424,31 @@ requires_clust_rec: goto next_rec; } else { - if (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE) { + if (UNIV_UNLIKELY + (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE)) { + /* CHECK TABLE: fetch the row */ + + if (result_rec != rec + && !prebuilt->need_to_access_clustered) { + /* We used 'offsets' for the clust + rec, recalculate them for 'rec' */ + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, + &heap); + result_rec = rec; + } + memcpy(buf + 4, result_rec - rec_offs_extra_size(offsets), rec_offs_size(offsets)); mach_write_to_4(buf, rec_offs_extra_size(offsets) + 4); } else { - if (!row_sel_store_mysql_rec(buf, prebuilt, - result_rec, offsets)) { + /* Returning a row to MySQL */ + + if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec, + result_rec != rec, + offsets)) { /* Only fresh inserts may contain incomplete externally stored columns. Pretend that such records do diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c index 04c3139fcc7..444003ba3f0 100644 --- a/storage/innodb_plugin/row/row0upd.c +++ b/storage/innodb_plugin/row/row0upd.c @@ -466,8 +466,11 @@ row_upd_changes_field_size_or_external( #endif /* !UNIV_HOTBACKUP */ /***********************************************************//** -Replaces the new column values stored in the update vector to the record -given. No field size changes are allowed. */ +Replaces the new column values stored in the update vector to the +record given. No field size changes are allowed. This function is +usually invoked on a clustered index. The only use case for a +secondary index is row_ins_sec_index_entry_by_modify() or its +counterpart in ibuf_insert_to_index_page(). */ UNIV_INTERN void row_upd_rec_in_place( From 923003f99dfc03a173b9e683853aa73931c38352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 19 Oct 2010 09:44:38 +0300 Subject: [PATCH 088/151] ibuf_set_del_mark(): Do not complain about already delete-marked records. According to a comment in row_upd_sec_index_entry(), it is a legitimate situation that can be caused by a lock wait. --- storage/innobase/ibuf/ibuf0ibuf.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 53a11a7f2e0..7ef577e5178 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -3997,21 +3997,22 @@ ibuf_set_del_mark( rec = page_cur_get_rec(&page_cur); page_zip = page_cur_get_page_zip(&page_cur); - if (UNIV_UNLIKELY - (rec_get_deleted_flag( - rec, dict_table_is_comp(index->table)))) { - ut_print_timestamp(stderr); - fputs(" InnoDB: record is already delete-marked\n", - stderr); - goto failure; - } + /* Delete mark the old index record. According to a + comment in row_upd_sec_index_entry(), it can already + have been delete marked if a lock wait occurred in + row_ins_index_entry() in a previous invocation of + row_upd_sec_index_entry(). */ - btr_cur_set_deleted_flag_for_ibuf(rec, page_zip, TRUE, mtr); + if (UNIV_LIKELY + (!rec_get_deleted_flag( + rec, dict_table_is_comp(index->table)))) { + btr_cur_set_deleted_flag_for_ibuf(rec, page_zip, + TRUE, mtr); + } } else { ut_print_timestamp(stderr); fputs(" InnoDB: unable to find a record to delete-mark\n", stderr); -failure: fputs("InnoDB: tuple ", stderr); dtuple_print(stderr, entry); fputs("\n" From a6df37dbbf2ba51b6785576a946f664b0996c03c Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Tue, 19 Oct 2010 08:45:18 +0200 Subject: [PATCH 089/151] Bug #57203 Assertion `field_length <= 255' failed. After the fix for Bug #55077 Assertion failed: width > 0 && to != ((void *)0), file .\dtoa.c we no longer try to allocate a string of length 'field_length' so the asserts are relevant only for ZEROFILL columns. mysql-test/r/select.result: Add test case for Bug#57203 mysql-test/t/select.test: Add test case for Bug#57203 sql/field.cc: Rewrite the DBUG_ASSERTS on field_length. --- mysql-test/r/select.result | 19 +++++++++++++++++++ mysql-test/t/select.test | 19 +++++++++++++++++++ sql/field.cc | 4 ++-- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 96979d257f1..a345a2ae6aa 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4887,3 +4887,22 @@ col_int_key DROP VIEW view_t1; DROP TABLE t1; # End of test BUG#54515 +# +# Bug #57203 Assertion `field_length <= 255' failed. +# +SELECT coalesce((avg(distinct (geomfromtext("point(25379 -22010)"))))) +UNION ALL +SELECT coalesce((avg(distinct (geomfromtext("point(25379 -22010)"))))) +AS foo +; +coalesce((avg(distinct (geomfromtext("point(25379 -22010)"))))) +0.0000 +0.0000 +CREATE table t1(a text); +INSERT INTO t1 VALUES (''), (''); +SELECT avg(distinct(t1.a)) FROM t1, t1 t2 +GROUP BY t2.a ORDER BY t1.a; +avg(distinct(t1.a)) +0 +DROP TABLE t1; +# End of test BUG#57203 diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 87f36c452f2..3ed7213e8d7 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -4147,3 +4147,22 @@ DROP VIEW view_t1; DROP TABLE t1; --echo # End of test BUG#54515 + +--echo # +--echo # Bug #57203 Assertion `field_length <= 255' failed. +--echo # + +SELECT coalesce((avg(distinct (geomfromtext("point(25379 -22010)"))))) +UNION ALL +SELECT coalesce((avg(distinct (geomfromtext("point(25379 -22010)"))))) +AS foo +; + +CREATE table t1(a text); +INSERT INTO t1 VALUES (''), (''); +SELECT avg(distinct(t1.a)) FROM t1, t1 t2 +GROUP BY t2.a ORDER BY t1.a; + +DROP TABLE t1; + +--echo # End of test BUG#57203 diff --git a/sql/field.cc b/sql/field.cc index be7441f6bfd..d746de385b6 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4189,7 +4189,7 @@ String *Field_float::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { ASSERT_COLUMN_MARKED_FOR_READ; - DBUG_ASSERT(field_length <= MAX_FIELD_CHARLENGTH); + DBUG_ASSERT(!zerofill || field_length <= MAX_FIELD_CHARLENGTH); float nr; #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) @@ -4512,7 +4512,7 @@ String *Field_double::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { ASSERT_COLUMN_MARKED_FOR_READ; - DBUG_ASSERT(field_length <= MAX_FIELD_CHARLENGTH); + DBUG_ASSERT(!zerofill || field_length <= MAX_FIELD_CHARLENGTH); double nr; #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) From af665ea977698676080f0e175363dc0c83755938 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Tue, 19 Oct 2010 09:06:48 +0200 Subject: [PATCH 090/151] Bug#52172 post-push fix: init auto-variable to NULL --- dbug/dbug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbug/dbug.c b/dbug/dbug.c index 7278acca2a9..e5e11d5be00 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -2269,7 +2269,7 @@ static void dbug_flush(CODE_STATE *cs) void _db_flush_() { - CODE_STATE *cs; + CODE_STATE *cs= NULL; get_code_state_or_return; (void) fflush(cs->stack->out_file); } From 4776282bede4da8cceeee1ce450310b281e34af9 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Tue, 19 Oct 2010 10:19:57 +0200 Subject: [PATCH 091/151] Bug #57274 SET GLOBAL debug crashes on Solaris in embedded server mode (variables_debug fails) The problem was that "SET GLOBAL debug" could cause a crash on Solaris. The crash happened if the server failed to open the trace file given in the "SET GLOBAL debug" statement. This caused an error message to be printed to stderr containing the process name. However, printing to stderr crashed the server since the pointer to the process name had not been initialized. This patch fixes the problem by initializing the process name properly when doing "SET GLOBAL debug". No test case added as this bug was repeatable with existing test coverage in variables_debug.test. --- dbug/dbug.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dbug/dbug.c b/dbug/dbug.c index e5e11d5be00..fecdd4f8a6c 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -744,6 +744,7 @@ void _db_set_init_(const char *control) CODE_STATE tmp_cs; bzero((uchar*) &tmp_cs, sizeof(tmp_cs)); tmp_cs.stack= &init_settings; + tmp_cs.process= db_process ? db_process : "dbug"; DbugParse(&tmp_cs, control); } From 95d91c0f575fc490ac9e3d36a7d65980d9347489 Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Tue, 19 Oct 2010 12:27:09 +0200 Subject: [PATCH 092/151] Bug #46941 crash with lower_case_table_names=2 and foreign key data dictionary confusion On file systems with case insensitive file names, and lower_case_table_names set to '2', the server could crash due to a table definition cache inconsistency. This is the default setting on MacOSX, but may also be set and used on MS Windows. The bug is caused by using two different strategies for creating the hash key for the table definition cache, resulting in failure to look up an entry which is present in the cache, or failure to delete an existing entry. One strategy was to use the real table name (with case preserved), and the other to use a normalized table name (i.e a lower case version). This is manifested in two cases. One is during 'DROP DATABASE', where all known files are removed. The removal from the table definition cache is done via a generated list of TABLE_LIST with keys (wrongly) created using the case preserved name. The other is during CREATE TABLE, where the cache lookup is also (wrongly) based on the case preserved name. The fix was to use only the normalized table name when creating hash keys. sql/sql_db.cc: Normalize table name (i.e lower case it) sql/sql_table.cc: table_name contains the normalized name alias contains the real table name --- mysql-test/r/lowercase_table4.result | 7 +++ mysql-test/t/lowercase_table4-master.opt | 1 + mysql-test/t/lowercase_table4.test | 56 ++++++++++++++++++++++++ sql/sql_db.cc | 6 +++ sql/sql_table.cc | 2 +- 5 files changed, 71 insertions(+), 1 deletion(-) create mode 100755 mysql-test/r/lowercase_table4.result create mode 100755 mysql-test/t/lowercase_table4-master.opt create mode 100755 mysql-test/t/lowercase_table4.test diff --git a/mysql-test/r/lowercase_table4.result b/mysql-test/r/lowercase_table4.result new file mode 100755 index 00000000000..e3f861f8884 --- /dev/null +++ b/mysql-test/r/lowercase_table4.result @@ -0,0 +1,7 @@ +# +# Bug#46941 crash with lower_case_table_names=2 and +# foreign data dictionary confusion +# +CREATE DATABASE XY; +USE XY; +DROP DATABASE XY; diff --git a/mysql-test/t/lowercase_table4-master.opt b/mysql-test/t/lowercase_table4-master.opt new file mode 100755 index 00000000000..c0a1981fa7c --- /dev/null +++ b/mysql-test/t/lowercase_table4-master.opt @@ -0,0 +1 @@ +--lower-case-table-names=2 diff --git a/mysql-test/t/lowercase_table4.test b/mysql-test/t/lowercase_table4.test new file mode 100755 index 00000000000..93956047145 --- /dev/null +++ b/mysql-test/t/lowercase_table4.test @@ -0,0 +1,56 @@ +--source include/have_case_insensitive_file_system.inc +--source include/have_innodb.inc + +--echo # +--echo # Bug#46941 crash with lower_case_table_names=2 and +--echo # foreign data dictionary confusion +--echo # + +CREATE DATABASE XY; +USE XY; + +# +# Logs are disabled, since the number of creates tables +# and subsequent select statements may vary between +# versions +# +--disable_query_log +--disable_result_log + +let $tcs = `SELECT @@table_open_cache + 1`; + +let $i = $tcs; + +while ($i) +{ + eval CREATE TABLE XY.T_$i (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT, + primary key(a, b), unique(b)) ENGINE=InnoDB; + dec $i; +} + +eval ALTER TABLE XY.T_$tcs ADD INDEX I1 (c, b), + ADD CONSTRAINT C1 FOREIGN KEY (c, b) REFERENCES XY.T_1 (a, b); + +eval ALTER TABLE XY.T_$tcs ADD INDEX I2 (b), + ADD CONSTRAINT C2 FOREIGN KEY (b) REFERENCES XY.T_1(a); + +let $i = $tcs; +while ($i) +{ + eval SELECT * FROM XY.T_$i LIMIT 1; + dec $i; +} + +DROP DATABASE XY; +CREATE DATABASE XY; +USE XY; +eval CREATE TABLE XY.T_$tcs (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT, + PRIMARY KEY(a, b), UNIQUE(b)) ENGINE=InnoDB; +# +# The bug causes this SELECT to err +eval SELECT * FROM XY.T_$tcs LIMIT 1; + +--enable_query_log +--enable_result_log +DROP DATABASE XY; + diff --git a/sql/sql_db.cc b/sql/sql_db.cc index d3435b891b1..2c44c1a8449 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -1197,6 +1197,12 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, VOID(filename_to_tablename(file->name, table_list->table_name, MYSQL50_TABLE_NAME_PREFIX_LENGTH + strlen(file->name) + 1)); + + /* To be able to correctly look up the table in the table cache. */ + if (lower_case_table_names) + table_list->table_name_length= my_casedn_str(files_charset_info, + table_list->table_name); + table_list->alias= table_list->table_name; // If lower_case_table_names=2 table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix); /* Link into list */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 04cc9e42413..971e1022d63 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3896,7 +3896,7 @@ bool mysql_create_table_no_lock(THD *thd, Then she could create the table. This case is pretty obscure and therefore we don't introduce a new error message only for it. */ - if (get_cached_table_share(db, alias)) + if (get_cached_table_share(db, table_name)) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); goto unlock_and_end; From 8a67fc8c8246f5d7290b7e572fa092cf0cadb25d Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 19 Oct 2010 13:54:28 +0200 Subject: [PATCH 093/151] Test wait_timeout: do not fail by SQL syntax error, use die --- mysql-test/t/wait_timeout.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/t/wait_timeout.test b/mysql-test/t/wait_timeout.test index 6947e346675..eb86cf17ebb 100644 --- a/mysql-test/t/wait_timeout.test +++ b/mysql-test/t/wait_timeout.test @@ -53,7 +53,7 @@ while (!`select @aborted_clients`) dec $retries; if (!$retries) { - Failed to detect that client has been aborted; + die Failed to detect that client has been aborted; } } --enable_query_log @@ -108,7 +108,7 @@ while (!`select @aborted_clients`) dec $retries; if (!$retries) { - Failed to detect that client has been aborted; + die Failed to detect that client has been aborted; } } --enable_query_log From 84c57a5e278bbaa976c8d2961fd554e078c9b714 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 19 Oct 2010 13:56:30 +0200 Subject: [PATCH 094/151] Bug #52828 Tests that use perl fail when perl is not in path main.mysqltest skipped on Windows because a perl intentionally does exit(1) Use exit(2), as exit(1) on Windows is indistinguishable from failing to execute perl. --- mysql-test/t/mysqltest.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index caadce44dcf..d6bdbc2b3c1 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -331,7 +331,7 @@ eval select $mysql_errno as "after_!errno_masked_error" ; --exec illegal_command --cat_file does_not_exist --perl - exit(1); + exit(2); EOF # ---------------------------------------------------------------------------- From 05062d579a81ce9378560bee573f5769a94c579a Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 19 Oct 2010 14:01:14 +0200 Subject: [PATCH 095/151] Bug #56654 pb2 log is very hard to read Added some more info in a number of fail cases (re-commit for administrative reasons) --- mysql-test/mysql-test-run.pl | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index b83c32d3815..651dabcd408 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -586,13 +586,15 @@ sub run_test_server ($$$) { if ($test_has_failed and $retries <= $opt_retry){ # Test should be run one more time unless it has failed # too many times already + my $tname= $result->{name}; my $failures= $result->{failures}; if ($opt_retry > 1 and $failures >= $opt_retry_failure){ - mtr_report("\nTest has failed $failures times,", + mtr_report("\nTest $tname has failed $failures times,", "no more retries!\n"); } else { - mtr_report("\nRetrying test, attempt($retries/$opt_retry)...\n"); + mtr_report("\nRetrying test $tname, ". + "attempt($retries/$opt_retry)...\n"); delete($result->{result}); $result->{retries}= $retries+1; $result->write_test($sock, 'TESTCASE'); @@ -3094,7 +3096,8 @@ sub check_testcase($$) "\nMTR's internal check of the test case '$tname' failed. This means that the test case does not preserve the state that existed before the test case was executed. Most likely the test case did not -do a proper clean-up. +do a proper clean-up. It could also be caused by the previous test run +by this thread, if the server wasn't restarted. This is the diff of the states of the servers before and after the test case was executed:\n"; $tinfo->{check}.= $report; @@ -3136,6 +3139,10 @@ test case was executed:\n"; # Kill any check processes still running map($_->kill(), values(%started)); + mtr_warning("Check-testcase failed, this could also be caused by the" . + " previous test run by this worker thread") + if $result > 1 && $mode eq "before"; + return $result; } @@ -3789,7 +3796,9 @@ sub get_log_from_proc ($$) { foreach my $mysqld (mysqlds()) { if ($mysqld->{proc} eq $proc) { my @srv_lines= extract_server_log($mysqld->value('#log-error'), $name); - $srv_log= "\nServer log from this test:\n" . join ("", @srv_lines); + $srv_log= "\nServer log from this test:\n" . + "----------SERVER LOG START-----------\n". join ("", @srv_lines) . + "----------SERVER LOG END-------------\n"; last; } } From 138ede4609be43e177ecd60d3e4778647f8f35fd Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 19 Oct 2010 14:08:46 +0200 Subject: [PATCH 096/151] Bug #55135 Collect times used in test execution phases in mtr Adding option --report-times Can't collect times if test run is aborted --- mysql-test/lib/mtr_misc.pl | 84 ++++++++++++++++++++++++++++++++++++ mysql-test/mysql-test-run.pl | 33 +++++++++++++- 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index 32960d866ce..dc9928d37c5 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -33,6 +33,13 @@ sub mtr_exe_maybe_exists(@); sub mtr_milli_sleep($); sub start_timer($); sub has_expired($); +sub init_timers(); +sub mark_time_used($); +sub add_total_times($); +sub print_times_used($$); +sub print_total_times($); + +our $opt_report_times; ############################################################################## # @@ -205,4 +212,81 @@ sub start_timer ($) { return time + $_[0]; } sub has_expired ($) { return $_[0] && time gt $_[0]; } +# Below code is for time usage reporting + +use Time::HiRes qw(gettimeofday); + +my %time_used= ( + 'collect' => 0, + 'restart' => 0, + 'check' => 0, + 'ch-warn' => 0, + 'test' => 0, + 'init' => 0, +); + +my %time_text= ( + 'collect' => "Collecting test cases", + 'restart' => "Server stop/start", + 'check' => "Check-testcase", + 'ch-warn' => "Check for warnings", + 'test' => "Test execution", + 'init' => "Initialization etc.", +); + +# Counts number of reports from workers + +my $time_totals= 0; + +my $last_timer_set; + +sub init_timers() { + $last_timer_set= gettimeofday(); +} + +sub mark_time_used($) { + my ($name)= @_; + return unless $opt_report_times; + die "Unknown timer $name" unless exists $time_used{$name}; + + my $curr_time= gettimeofday(); + $time_used{$name}+= int (($curr_time - $last_timer_set) * 1000 + .5); + $last_timer_set= $curr_time; +} + +sub add_total_times($) { + my ($dummy, $num, @line)= split (" ", $_[0]); + + $time_totals++; + foreach my $elem (@line) { + my ($name, $spent)= split (":", $elem); + $time_used{$name}+= $spent; + } +} + +sub print_times_used($$) { + my ($server, $num)= @_; + return unless $opt_report_times; + + my $output= "SPENT $num"; + foreach my $name (keys %time_used) { + my $spent= $time_used{$name}; + $output.= " $name:$spent"; + } + print $server $output . "\n"; +} + +sub print_total_times($) { + # Don't print if we haven't received all worker data + return if $time_totals != $_[0]; + + foreach my $name (keys %time_used) + { + my $spent= $time_used{$name}/1000; + my $text= $time_text{$name}; + print ("Spent $spent seconds on $text\n"); + } +} + + 1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index e6d988dfba6..fe71fe69ad4 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -236,6 +236,7 @@ my $opt_skip_core; our $opt_check_testcases= 1; my $opt_mark_progress; my $opt_max_connections; +our $opt_report_times= 0; my $opt_sleep; @@ -348,8 +349,11 @@ sub main { } } + init_timers(); + mtr_report("Collecting tests..."); my $tests= collect_test_cases($opt_reorder, $opt_suites, \@opt_cases, \@opt_skip_test_list); + mark_time_used('collect'); if ( $opt_report_features ) { # Put "report features" as the first test to run @@ -418,6 +422,7 @@ sub main { $opt_tmpdir= "$opt_tmpdir/$child_num"; } + init_timers(); run_worker($server_port, $child_num); exit(1); } @@ -430,6 +435,8 @@ sub main { mtr_print_thick_line(); mtr_print_header(); + mark_time_used('init'); + my $completed= run_test_server($server, $tests, $opt_parallel); exit(0) if $opt_start_exit; @@ -475,6 +482,8 @@ sub main { $opt_gcov_msg, $opt_gcov_err); } + print_total_times($opt_parallel) if $opt_report_times; + mtr_report_stats("Completed", $completed); remove_vardir_subs() if $opt_clean_vardir; @@ -651,6 +660,9 @@ sub run_test_server ($$$) { elsif ($line eq 'START'){ ; # Send first test } + elsif ($line =~ /^SPENT/) { + add_total_times($line); + } else { mtr_error("Unknown response: '$line' from client"); } @@ -782,7 +794,9 @@ sub run_worker ($) { # Ask server for first test print $server "START\n"; - while(my $line= <$server>){ + mark_time_used('init'); + + while (my $line= <$server>){ chomp($line); if ($line eq 'TESTCASE'){ my $test= My::Test::read_test($server); @@ -800,16 +814,20 @@ sub run_worker ($) { # Send it back, now with results set #$test->print_test(); $test->write_test($server, 'TESTRESULT'); + mark_time_used('restart'); } elsif ($line eq 'BYE'){ mtr_report("Server said BYE"); stop_all_servers($opt_shutdown_timeout); + mark_time_used('restart'); if ($opt_valgrind_mysqld) { valgrind_exit_reports(); } if ( $opt_gprof ) { gprof_collect (find_mysqld($basedir), keys %gprof_dirs); } + mark_time_used('init'); + print_times_used($server, $thread_num); exit(0); } else { @@ -982,6 +1000,7 @@ sub command_line_setup { 'timediff' => \&report_option, 'max-connections=i' => \$opt_max_connections, 'default-myisam!' => \&collect_option, + 'report-times' => \$opt_report_times, 'help|h' => \$opt_usage, 'list-options' => \$opt_list_options, @@ -3169,6 +3188,7 @@ sub check_testcase($$) if ( keys(%started) == 0){ # All checks completed + mark_time_used('check'); return 0; } # Wait for next process to exit @@ -3226,6 +3246,7 @@ test case was executed:\n"; # Kill any check processes still running map($_->kill(), values(%started)); + mark_time_used('check'); return $result; } @@ -3535,6 +3556,7 @@ sub run_testcase ($) { return 1; } } + mark_time_used('restart'); # -------------------------------------------------------------------- # If --start or --start-dirty given, stop here to let user manually @@ -3587,6 +3609,8 @@ sub run_testcase ($) { do_before_run_mysqltest($tinfo); + mark_time_used('init'); + if ( $opt_check_testcases and check_testcase($tinfo, "before") ){ # Failed to record state of server or server crashed report_failure_and_restart($tinfo); @@ -3633,6 +3657,7 @@ sub run_testcase ($) { } mtr_verbose("Got $proc"); + mark_time_used('test'); # ---------------------------------------------------- # Was it the test program that exited # ---------------------------------------------------- @@ -4036,6 +4061,7 @@ sub check_warnings ($) { if ( keys(%started) == 0){ # All checks completed + mark_time_used('ch-warn'); return $result; } # Wait for next process to exit @@ -4068,6 +4094,7 @@ sub check_warnings ($) { # Kill any check processes still running map($_->kill(), values(%started)); + mark_time_used('ch-warn'); return $result; } @@ -5031,6 +5058,8 @@ sub start_mysqltest ($) { my $exe= $exe_mysqltest; my $args; + mark_time_used('init'); + mtr_init_args(\$args); mtr_add_arg($args, "--defaults-file=%s", $path_config_file); @@ -5668,6 +5697,8 @@ Misc options default-myisam Set default storage engine to MyISAM for non-innodb tests. This is needed after switching default storage engine to InnoDB. + report-times Report how much time has been spent on different + phases of test execution. HERE exit(1); From 183710558f78bb2fa55640ef1f0d2e087355240e Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 19 Oct 2010 11:49:31 -0200 Subject: [PATCH 097/151] Bug#45288: pb2 returns a lot of compilation warnings on linux Fix assorted compiler warnings on Mac OS X. BUILD/SETUP.sh: Remove -Wctor-dtor-privacy flag to workaround a GCC bug that causes it to not properly detect that implicitly generated constructors are always public. cmd-line-utils/readline/terminal.c: tgetnum and tgetflag might not take a const string argument. mysys/my_gethostbyname.c: Tag unused arguments. mysys/my_sync.c: Tag unused arguments. --- BUILD/SETUP.sh | 2 +- cmd-line-utils/readline/terminal.c | 8 +++---- mysys/my_gethostbyname.c | 6 +++-- mysys/my_sync.c | 36 +++++++++++++++++++++++------- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 08ae4de2e23..157fa7b087f 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -100,7 +100,7 @@ if [ "x$warning_mode" != "xpedantic" ]; then # C++ warnings cxx_warnings="$warnings -Wno-unused-parameter" # cxx_warnings="$cxx_warnings -Woverloaded-virtual -Wsign-promo" - cxx_warnings="$cxx_warnings -Wctor-dtor-privacy -Wnon-virtual-dtor" + cxx_warnings="$cxx_warnings -Wnon-virtual-dtor" # Added unless --with-debug=full debug_extra_cflags="-O0 -g3 -gdwarf-2" else diff --git a/cmd-line-utils/readline/terminal.c b/cmd-line-utils/readline/terminal.c index 3f92821f9dd..e2785908160 100644 --- a/cmd-line-utils/readline/terminal.c +++ b/cmd-line-utils/readline/terminal.c @@ -268,7 +268,7 @@ _rl_get_screen_size (tty, ignore_env) #if !defined (__DJGPP__) if (_rl_screenwidth <= 0 && term_string_buffer) - _rl_screenwidth = tgetnum ("co"); + _rl_screenwidth = tgetnum ((char *)"co"); #endif } @@ -284,7 +284,7 @@ _rl_get_screen_size (tty, ignore_env) #if !defined (__DJGPP__) if (_rl_screenheight <= 0 && term_string_buffer) - _rl_screenheight = tgetnum ("li"); + _rl_screenheight = tgetnum ((char *)"li"); #endif } @@ -516,7 +516,7 @@ _rl_init_terminal_io (terminal_name) if (!_rl_term_cr) _rl_term_cr = "\r"; - _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn"); + _rl_term_autowrap = tgetflag ((char *)"am") && tgetflag ((char *)"xn"); /* Allow calling application to set default height and width, using rl_set_screen_size */ @@ -531,7 +531,7 @@ _rl_init_terminal_io (terminal_name) /* Check to see if this terminal has a meta key and clear the capability variables if there is none. */ - term_has_meta = (tgetflag ("km") || tgetflag ("MT")); + term_has_meta = (tgetflag ((char *)"km") || tgetflag ((char *)"MT")); if (!term_has_meta) _rl_term_mm = _rl_term_mo = (char *)NULL; diff --git a/mysys/my_gethostbyname.c b/mysys/my_gethostbyname.c index 067fdfee9db..12cf90271dd 100644 --- a/mysys/my_gethostbyname.c +++ b/mysys/my_gethostbyname.c @@ -92,8 +92,10 @@ extern pthread_mutex_t LOCK_gethostbyname_r; */ struct hostent *my_gethostbyname_r(const char *name, - struct hostent *result, char *buffer, - int buflen, int *h_errnop) + struct hostent *res __attribute__((unused)), + char *buffer __attribute__((unused)), + int buflen __attribute__((unused)), + int *h_errnop) { struct hostent *hp; pthread_mutex_lock(&LOCK_gethostbyname_r); diff --git a/mysys/my_sync.c b/mysys/my_sync.c index 97540f5eb48..d6ca4f1c1df 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -89,6 +89,8 @@ int my_sync(File fd, myf my_flags) static const char cur_dir_name[]= {FN_CURLIB, 0}; + + /* Force directory information to disk. @@ -100,9 +102,11 @@ static const char cur_dir_name[]= {FN_CURLIB, 0}; RETURN 0 if ok, !=0 if error */ + +#ifdef NEED_EXPLICIT_SYNC_DIR + int my_sync_dir(const char *dir_name, myf my_flags) { -#ifdef NEED_EXPLICIT_SYNC_DIR File dir_fd; int res= 0; const char *correct_dir_name; @@ -124,11 +128,18 @@ int my_sync_dir(const char *dir_name, myf my_flags) else res= 1; DBUG_RETURN(res); -#else - return 0; -#endif } +#else /* NEED_EXPLICIT_SYNC_DIR */ + +int my_sync_dir(const char *dir_name __attribute__((unused)), + myf my_flags __attribute__((unused))) +{ + return 0; +} + +#endif /* NEED_EXPLICIT_SYNC_DIR */ + /* Force directory information to disk. @@ -141,15 +152,24 @@ int my_sync_dir(const char *dir_name, myf my_flags) RETURN 0 if ok, !=0 if error */ + +#ifdef NEED_EXPLICIT_SYNC_DIR + int my_sync_dir_by_file(const char *file_name, myf my_flags) { -#ifdef NEED_EXPLICIT_SYNC_DIR char dir_name[FN_REFLEN]; size_t dir_name_length; dirname_part(dir_name, file_name, &dir_name_length); return my_sync_dir(dir_name, my_flags); -#else - return 0; -#endif } +#else /* NEED_EXPLICIT_SYNC_DIR */ + +int my_sync_dir_by_file(const char *file_name __attribute__((unused)), + myf my_flags __attribute__((unused))) +{ + return 0; +} + +#endif /* NEED_EXPLICIT_SYNC_DIR */ + From 8875c2c2e05253098d44b524976619dbe1e3bfb2 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 19 Oct 2010 12:09:28 -0200 Subject: [PATCH 098/151] Bug#45288: pb2 returns a lot of compilation warnings on linux Tag unused arguments. Approved by: Marko (via IRC) --- storage/innobase/os/os0file.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index a995aee5fab..f269cd39673 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -1138,9 +1138,12 @@ Tries to disable OS caching on an opened file descriptor. */ void os_file_set_nocache( /*================*/ - int fd, /* in: file descriptor to alter */ - const char* file_name, /* in: used in the diagnostic message */ - const char* operation_name) /* in: used in the diagnostic message, + int fd /* in: file descriptor to alter */ + __attribute__((unused)), + const char* file_name /* in: used in the diagnostic message */ + __attribute__((unused)), + const char* operation_name __attribute__((unused))) + /* in: used in the diagnostic message, we call os_file_set_nocache() immediately after opening or creating a file, so this is either "open" or From be170c213fa285acfb79e06ba249a9bb30155275 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 19 Oct 2010 12:12:43 -0200 Subject: [PATCH 099/151] Bug#45288: pb2 returns a lot of compilation warnings on linux Tag unused arguments. Approved by: Marko (via IRC) --- storage/innodb_plugin/os/os0file.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c index 6a0d6ea5363..14b2fce43c3 100644 --- a/storage/innodb_plugin/os/os0file.c +++ b/storage/innodb_plugin/os/os0file.c @@ -1182,10 +1182,12 @@ UNIV_INTERN void os_file_set_nocache( /*================*/ - int fd, /*!< in: file descriptor to alter */ - const char* file_name, /*!< in: file name, used in the - diagnostic message */ - const char* operation_name) /*!< in: "open" or "create"; used in the + int fd /*!< in: file descriptor to alter */ + __attribute__((unused)), + const char* file_name /*!< in: used in the diagnostic message */ + __attribute__((unused)), + const char* operation_name __attribute__((unused))) + /*!< in: "open" or "create"; used in the diagnostic message */ { /* some versions of Solaris may not have DIRECTIO_ON */ From cb0105066157343065f85eab019660dd20609f6c Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 19 Oct 2010 17:32:26 +0300 Subject: [PATCH 100/151] Fix Bug#53916 storage/innodb_plugin does not compile on NetBSD/sparc64 Just check for all the functions that we are going to use, not a subset of them. Reviewed by: Davi (via IRC) --- storage/innodb_plugin/plug.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/storage/innodb_plugin/plug.in b/storage/innodb_plugin/plug.in index e638332d74a..2ee45389e9c 100644 --- a/storage/innodb_plugin/plug.in +++ b/storage/innodb_plugin/plug.in @@ -137,10 +137,11 @@ MYSQL_PLUGIN_ACTIONS(innodb_plugin, [ AC_MSG_CHECKING(whether Solaris libc atomic functions are available) # either define HAVE_IB_SOLARIS_ATOMICS or not - AC_CHECK_FUNCS(atomic_add_long \ + AC_CHECK_FUNCS(atomic_cas_ulong \ atomic_cas_32 \ atomic_cas_64 \ - atomic_cas_ulong, + atomic_add_long_nv \ + atomic_swap_uchar, AC_DEFINE([HAVE_IB_SOLARIS_ATOMICS], [1], [Define to 1 if Solaris libc atomic functions \ From 7406b38efa0a2eec5a245839c5ce13b85d51d125 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 19 Oct 2010 14:48:03 -0200 Subject: [PATCH 101/151] Bug#45288: pb2 returns a lot of compilation warnings Ensure that fdatasync is properly declared as on Mac OS X, the function is available but there is no prototype. Also, port a fix for a warning from the InnoDB plugin over to the builtin. configure.in: Check that fdatasync is declared. mysys/my_sync.c: Use fdatasync only if it is declared. storage/innobase/include/ut0dbg.h: Port over from the plugin a fix for a warning. --- configure.in | 7 +++++++ mysys/my_sync.c | 2 +- storage/innobase/include/ut0dbg.h | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index 09885dbbae7..4ea978c268e 100644 --- a/configure.in +++ b/configure.in @@ -2073,6 +2073,13 @@ MYSQL_TYPE_QSORT AC_FUNC_UTIME_NULL AC_FUNC_VPRINTF +AC_CHECK_DECLS([fdatasync],,, +[ +#ifdef HAVE_UNISTD_H +# include +#endif +]) + AC_CHECK_FUNCS(alarm bfill bmove bsearch bzero \ chsize cuserid fchmod fcntl \ fconvert fdatasync fesetround finite fpresetsticky fpsetmask fsync ftruncate \ diff --git a/mysys/my_sync.c b/mysys/my_sync.c index d6ca4f1c1df..7acbccec345 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -58,7 +58,7 @@ int my_sync(File fd, myf my_flags) /* Some file systems don't support F_FULLFSYNC and fail above: */ DBUG_PRINT("info",("fcntl(F_FULLFSYNC) failed, falling back")); #endif -#if defined(HAVE_FDATASYNC) +#if defined(HAVE_FDATASYNC) && HAVE_DECL_FDATASYNC res= fdatasync(fd); #elif defined(HAVE_FSYNC) res= fsync(fd); diff --git a/storage/innobase/include/ut0dbg.h b/storage/innobase/include/ut0dbg.h index a317f35f4be..06dead7fc03 100644 --- a/storage/innobase/include/ut0dbg.h +++ b/storage/innobase/include/ut0dbg.h @@ -39,7 +39,7 @@ extern ibool panic_shutdown; void ut_dbg_panic(void); # define UT_DBG_PANIC ut_dbg_panic() /* Stop threads in ut_a(). */ -# define UT_DBG_STOP while (0) /* We do not do this on NetWare */ +# define UT_DBG_STOP do {} while (0) /* We do not do this on NetWare */ #else /* __NETWARE__ */ # if defined(__WIN__) || defined(__INTEL_COMPILER) # undef UT_DBG_USE_ABORT @@ -71,7 +71,7 @@ ut_dbg_stop_thread( /* Abort the execution. */ # define UT_DBG_PANIC abort() /* Stop threads (null operation) */ -# define UT_DBG_STOP while (0) +# define UT_DBG_STOP do {} while (0) # else /* UT_DBG_USE_ABORT */ /* Abort the execution. */ # define UT_DBG_PANIC \ From 1040f98ccffccbed8d1e95fe8252e402b8ee4e3f Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 19 Oct 2010 20:36:59 -0200 Subject: [PATCH 102/151] Bug#45288: pb2 returns a lot of compilation warnings Tag or remove unused arguments and variables. regex/main.c: Use the real prototype. sql/ha_ndbcluster.cc: Make conditions less ambiguous. --- client/mysql.cc | 15 +++++++++----- client/sql_string.h | 10 ++++++--- cmd-line-utils/libedit/common.c | 5 +++-- cmd-line-utils/libedit/filecomplete.c | 3 +-- cmd-line-utils/libedit/readline.c | 23 +++++++++++++-------- cmd-line-utils/libedit/vi.c | 29 ++++++++++++++------------- regex/main.c | 8 ++++---- sql/ha_ndbcluster.cc | 10 +++++---- sql/log_event.cc | 2 +- sql/log_event.h | 4 ++-- sql/my_decimal.h | 2 +- sql/sql_string.h | 10 ++++++--- 12 files changed, 72 insertions(+), 49 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 5b90f318629..4c2c75dc79a 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -3725,7 +3725,8 @@ print_tab_data(MYSQL_RES *result) } static int -com_tee(String *buffer, char *line __attribute__((unused))) +com_tee(String *buffer __attribute__((unused)), + char *line __attribute__((unused))) { char file_name[FN_REFLEN], *end, *param; @@ -3784,7 +3785,8 @@ com_notee(String *buffer __attribute__((unused)), #ifdef USE_POPEN static int -com_pager(String *buffer, char *line __attribute__((unused))) +com_pager(String *buffer __attribute__((unused)), + char *line __attribute__((unused))) { char pager_name[FN_REFLEN], *end, *param; @@ -3911,7 +3913,8 @@ com_rehash(String *buffer __attribute__((unused)), #ifdef USE_POPEN static int -com_shell(String *buffer, char *line __attribute__((unused))) +com_shell(String *buffer __attribute__((unused)), + char *line __attribute__((unused))) { char *shell_cmd; @@ -4003,7 +4006,8 @@ com_connect(String *buffer, char *line) } -static int com_source(String *buffer, char *line) +static int com_source(String *buffer __attribute__((unused)), + char *line) { char source_name[FN_REFLEN], *end, *param; LINE_BUFFER *line_buff; @@ -4908,7 +4912,8 @@ static void init_username() } } -static int com_prompt(String *buffer, char *line) +static int com_prompt(String *buffer __attribute__((unused)), + char *line) { char *ptr=strchr(line, ' '); prompt_counter = 0; diff --git a/client/sql_string.h b/client/sql_string.h index da19c1ccfe5..84fe26a54b9 100644 --- a/client/sql_string.h +++ b/client/sql_string.h @@ -70,9 +70,13 @@ public: } static void *operator new(size_t size, MEM_ROOT *mem_root) { return (void*) alloc_root(mem_root, (uint) size); } - static void operator delete(void *ptr_arg,size_t size) - { TRASH(ptr_arg, size); } - static void operator delete(void *ptr_arg, MEM_ROOT *mem_root) + static void operator delete(void *ptr_arg, size_t size) + { + (void) ptr_arg; + (void) size; + TRASH(ptr_arg, size); + } + static void operator delete(void *, MEM_ROOT *) { /* never called */ } ~String() { free(); } diff --git a/cmd-line-utils/libedit/common.c b/cmd-line-utils/libedit/common.c index d4d024eae10..ba5890fa606 100644 --- a/cmd-line-utils/libedit/common.c +++ b/cmd-line-utils/libedit/common.c @@ -136,7 +136,7 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_delete_next_char(EditLine *el, int c) +ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) { #ifdef notdef /* XXX */ #define EL el->el_line @@ -431,7 +431,8 @@ ed_argument_digit(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -ed_unassigned(EditLine *el, int c __attribute__((__unused__))) +ed_unassigned(EditLine *el __attribute__((__unused__)), + int c __attribute__((__unused__))) { return (CC_ERROR); diff --git a/cmd-line-utils/libedit/filecomplete.c b/cmd-line-utils/libedit/filecomplete.c index 4c63f57bc45..05bd10e9f9e 100644 --- a/cmd-line-utils/libedit/filecomplete.c +++ b/cmd-line-utils/libedit/filecomplete.c @@ -95,10 +95,9 @@ static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', char * fn_tilde_expand(const char *txt) { - struct passwd pwres, *pass; + struct passwd *pass; char *temp; size_t len = 0; - char pwbuf[1024]; if (txt[0] != '~') return (strdup(txt)); diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index 1f1b18c97d8..0318ab409b3 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -202,7 +202,7 @@ _move_history(int op) */ static int /*ARGSUSED*/ -_getc_function(EditLine *el, char *c) +_getc_function(EditLine *el __attribute__((__unused__)), char *c) { int i; @@ -1613,7 +1613,8 @@ rl_insert(int count, int c) /*ARGSUSED*/ int -rl_newline(int count, int c) +rl_newline(int count __attribute__((__unused__)), + int c __attribute__((__unused__))) { /* * Readline-4.0 appears to ignore the args. @@ -1623,7 +1624,7 @@ rl_newline(int count, int c) /*ARGSUSED*/ static unsigned char -rl_bind_wrapper(EditLine *el, unsigned char c) +rl_bind_wrapper(EditLine *el __attribute__((__unused__)), unsigned char c) { if (map[c] == NULL) return CC_ERROR; @@ -1718,7 +1719,7 @@ rl_get_previous_history(int count, int key) void /*ARGSUSED*/ -rl_prep_terminal(int meta_flag) +rl_prep_terminal(int meta_flag __attribute__((__unused__))) { el_set(e, EL_PREP_TERM, 1); } @@ -1922,7 +1923,8 @@ _rl_qsort_string_compare(char **s1, char **s2) int /*ARGSUSED*/ -rl_kill_text(int from, int to) +rl_kill_text(int from __attribute__((__unused__)), + int to __attribute__((__unused__))) { return 0; } @@ -1941,20 +1943,25 @@ rl_get_keymap(void) void /*ARGSUSED*/ -rl_set_keymap(Keymap k) +rl_set_keymap(Keymap k __attribute__((__unused__))) { } int /*ARGSUSED*/ -rl_generic_bind(int type, const char * keyseq, const char * data, Keymap k) +rl_generic_bind(int type __attribute__((__unused__)), + const char * keyseq __attribute__((__unused__)), + const char * data __attribute__((__unused__)), + Keymap k __attribute__((__unused__))) { return 0; } int /*ARGSUSED*/ -rl_bind_key_in_map(int key, Function *fun, Keymap k) +rl_bind_key_in_map(int key __attribute__((__unused__)), + Function *fun __attribute__((__unused__)), + Keymap k __attribute__((__unused__))) { return 0; } diff --git a/cmd-line-utils/libedit/vi.c b/cmd-line-utils/libedit/vi.c index 00a9f493a9b..d628f076a1d 100644 --- a/cmd-line-utils/libedit/vi.c +++ b/cmd-line-utils/libedit/vi.c @@ -145,7 +145,7 @@ vi_paste_prev(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_prev_big_word(EditLine *el, int c) +vi_prev_big_word(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.buffer) @@ -195,7 +195,7 @@ vi_prev_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_next_big_word(EditLine *el, int c) +vi_next_big_word(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor >= el->el_line.lastchar - 1) @@ -462,7 +462,7 @@ vi_delete_meta(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_end_big_word(EditLine *el, int c) +vi_end_big_word(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.lastchar) @@ -797,7 +797,7 @@ vi_repeat_prev_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_match(EditLine *el, int c) +vi_match(EditLine *el, int c __attribute__((__unused__))) { const char match_chars[] = "()[]{}"; char *cp; @@ -844,7 +844,7 @@ vi_match(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_undo_line(EditLine *el, int c) +vi_undo_line(EditLine *el, int c __attribute__((__unused__))) { cv_undo(el); @@ -858,7 +858,7 @@ vi_undo_line(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_to_column(EditLine *el, int c) +vi_to_column(EditLine *el, int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; @@ -872,7 +872,7 @@ vi_to_column(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_yank_end(EditLine *el, int c) +vi_yank_end(EditLine *el, int c __attribute__((__unused__))) { cv_yank(el, el->el_line.cursor, @@ -886,7 +886,7 @@ vi_yank_end(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_yank(EditLine *el, int c) +vi_yank(EditLine *el, int c __attribute__((__unused__))) { return cv_action(el, YANK); @@ -898,7 +898,7 @@ vi_yank(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_comment_out(EditLine *el, int c) +vi_comment_out(EditLine *el, int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; @@ -919,7 +919,8 @@ extern char *get_alias_text(const char *) __weak_reference(get_alias_text); #endif protected el_action_t /*ARGSUSED*/ -vi_alias(EditLine *el, int c) +vi_alias(EditLine *el __attribute__((__unused__)), + int c __attribute__((__unused__))) { #if defined(__weak_reference) && !defined(__FreeBSD__) char alias_name[3]; @@ -949,7 +950,7 @@ vi_alias(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_to_history_line(EditLine *el, int c) +vi_to_history_line(EditLine *el, int c __attribute__((__unused__))) { int sv_event_no = el->el_history.eventno; el_action_t rval; @@ -994,7 +995,7 @@ vi_to_history_line(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_histedit(EditLine *el, int c) +vi_histedit(EditLine *el, int c __attribute__((__unused__))) { int fd; pid_t pid; @@ -1050,7 +1051,7 @@ vi_histedit(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_history_word(EditLine *el, int c) +vi_history_word(EditLine *el, int c __attribute__((__unused__))) { const char *wp = HIST_FIRST(el); const char *wep, *wsp; @@ -1099,7 +1100,7 @@ vi_history_word(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_redo(EditLine *el, int c) +vi_redo(EditLine *el, int c __attribute__((__unused__))) { c_redo_t *r = &el->el_chared.c_redo; diff --git a/regex/main.c b/regex/main.c index fa97ca89047..f5b591907cf 100644 --- a/regex/main.c +++ b/regex/main.c @@ -17,8 +17,8 @@ regoff_t startoff = 0; regoff_t endoff = 0; -extern int split(); -extern void regprint(); +extern int split(char *string, char *fields[], int nfields, char *sep); +extern void regprint(my_regex_t *r, FILE *d); /* - main - do the simple case, hand off to regress() for regression @@ -145,7 +145,7 @@ FILE *in; inbuf[strlen(inbuf)-1] = '\0'; /* get rid of stupid \n */ if (debug) fprintf(stdout, "%d:\n", line); - nf = split(inbuf, f, MAXF, "\t\t"); + nf = split(inbuf, f, MAXF, (char*) "\t\t"); if (nf < 3) { fprintf(stderr, "bad input, line %d\n", line); exit(1); @@ -288,7 +288,7 @@ int opts; /* may not match f1 */ for (i = 1; i < NSHOULD; i++) should[i] = NULL; - nshould = split(f4, should+1, NSHOULD-1, ","); + nshould = split(f4, should+1, NSHOULD-1, (char*) ","); if (nshould == 0) { nshould = 1; should[1] = (char*) ""; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 9c26105546d..4f99d354754 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1293,10 +1293,12 @@ int ha_ndbcluster::open_indexes(Ndb *ndb, TABLE *tab, bool ignore_error) for (i= 0; i < tab->s->keys; i++, key_info++, key_name++) { if ((error= add_index_handle(thd, dict, key_info, *key_name, i))) + { if (ignore_error) m_index[i].index= m_index[i].unique_index= NULL; else break; + } m_index[i].null_in_unique_index= FALSE; if (check_index_fields_not_null(key_info)) m_index[i].null_in_unique_index= TRUE; @@ -6265,8 +6267,8 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment, for (;;) { Ndb_tuple_id_range_guard g(m_share); - if (m_skip_auto_increment && - ndb->readAutoIncrementValue(m_table, g.range, auto_value) || + if ((m_skip_auto_increment && + ndb->readAutoIncrementValue(m_table, g.range, auto_value)) || ndb->getAutoIncrementValue(m_table, g.range, auto_value, cache_size, increment, offset)) { if (--retries && @@ -9916,8 +9918,8 @@ bool ha_ndbcluster::check_if_incompatible_data(HA_CREATE_INFO *create_info, { Field *field= table->field[i]; const NDBCOL *col= tab->getColumn(i); - if (col->getStorageType() == NDB_STORAGETYPE_MEMORY && create_info->storage_media != HA_SM_MEMORY || - col->getStorageType() == NDB_STORAGETYPE_DISK && create_info->storage_media != HA_SM_DISK) + if ((col->getStorageType() == NDB_STORAGETYPE_MEMORY && create_info->storage_media != HA_SM_MEMORY) || + (col->getStorageType() == NDB_STORAGETYPE_DISK && create_info->storage_media != HA_SM_DISK)) { DBUG_PRINT("info", ("Column storage media is changed")); DBUG_RETURN(COMPATIBLE_DATA_NO); diff --git a/sql/log_event.cc b/sql/log_event.cc index 91b2746ce8f..49f47edad72 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8362,7 +8362,7 @@ void Table_map_log_event::pack_info(Protocol *protocol) #ifdef MYSQL_CLIENT -void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info) +void Table_map_log_event::print(FILE *, PRINT_EVENT_INFO *print_event_info) { if (!print_event_info->short_form) { diff --git a/sql/log_event.h b/sql/log_event.h index 662fec23639..75f2015a684 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -979,9 +979,9 @@ public: return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE)); } - static void operator delete(void *ptr, size_t size) + static void operator delete(void *ptr, size_t) { - my_free((uchar*) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR)); + my_free(ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR)); } /* Placement version of the above operators */ diff --git a/sql/my_decimal.h b/sql/my_decimal.h index 21669e82c44..a5077f397e3 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -308,7 +308,7 @@ int my_decimal2int(uint mask, const my_decimal *d, my_bool unsigned_flag, inline -int my_decimal2double(uint mask, const my_decimal *d, double *result) +int my_decimal2double(uint, const my_decimal *d, double *result) { /* No need to call check_result as this will always succeed */ return decimal2double((decimal_t*) d, result); diff --git a/sql/sql_string.h b/sql/sql_string.h index bb7d69aeccc..b15179bcbe5 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -84,9 +84,13 @@ public: } static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return (void*) alloc_root(mem_root, (uint) size); } - static void operator delete(void *ptr_arg,size_t size) - { TRASH(ptr_arg, size); } - static void operator delete(void *ptr_arg, MEM_ROOT *mem_root) + static void operator delete(void *ptr_arg, size_t size) + { + (void) ptr_arg; + (void) size; + TRASH(ptr_arg, size); + } + static void operator delete(void *, MEM_ROOT *) { /* never called */ } ~String() { free(); } From 4735eafcddba5ba486e3b26211a6ab4fe25393f0 Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Wed, 20 Oct 2010 14:39:31 +1100 Subject: [PATCH 103/151] Bug #57588 - Compiler warning in InnoDB due to comparison between signed and unsigned For DATA_MBMINLEN(), cast the result of UNIV_EXPECT to ulint because in GCC it returns a long causing unsigned/signed comparison warnings. Approved by Jimmy Yang on IM. --- storage/innobase/include/data0type.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h index 850cf2e2975..f0be5ace306 100644 --- a/storage/innobase/include/data0type.h +++ b/storage/innobase/include/data0type.h @@ -174,8 +174,11 @@ store the charset-collation number; one byte is left unused, though */ /* Pack mbminlen, mbmaxlen to mbminmaxlen. */ #define DATA_MBMINMAXLEN(mbminlen, mbmaxlen) \ ((mbmaxlen) * DATA_MBMAX + (mbminlen)) -/* Get mbminlen from mbminmaxlen. */ -#define DATA_MBMINLEN(mbminmaxlen) UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), 1) +/* Get mbminlen from mbminmaxlen. Cast the result of UNIV_EXPECT to ulint +because in GCC it returns a long. */ +#define DATA_MBMINLEN(mbminmaxlen) ((ulint) \ + UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), \ + 1)) /* Get mbmaxlen from mbminmaxlen. */ #define DATA_MBMAXLEN(mbminmaxlen) ((mbminmaxlen) / DATA_MBMAX) From 6960db2dfdd90aa155bbc88cb802bdc697be4b9c Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 20 Oct 2010 11:22:08 +0200 Subject: [PATCH 104/151] Bug #52019 main.mysqltest fails on new tests for lowercase_result Limited to actual bug fix, fixing a while condition Again confirmed on Linux PPC and on AIX 5.3 --- client/mysqltest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 53c1f1bdf85..ee03b796873 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5742,7 +5742,7 @@ int read_line(char *buf, int size) { /* It was not a multiline char, push back the characters */ /* We leave first 'c', i.e. pretend it was a normal char */ - while (p > mb_start) + while (p-1 > mb_start) my_ungetc(*--p); } } From f73ada3722b9cd3624e9eac8d07f482baaa1f03b Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 20 Oct 2010 11:30:50 +0200 Subject: [PATCH 105/151] 48863 followup: move an array declaration out from within if block --- client/mysqltest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index ee03b796873..2bbb1c63724 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -9781,6 +9781,7 @@ void free_pointer_array(POINTER_ARRAY *pa) void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, int len) { + char lower[512]; #ifdef __WIN__ fix_win_paths(val, len); #endif @@ -9788,7 +9789,6 @@ void replace_dynstr_append_mem(DYNAMIC_STRING *ds, if (display_result_lower) { /* Convert to lower case, and do this first */ - char lower[512]; char *c= lower; for (const char *v= val; *v; v++) *c++= my_tolower(charset_info, *v); From e533c7cc108e5b9a00c273baa027358c4edb4dd0 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 20 Oct 2010 11:39:58 +0200 Subject: [PATCH 106/151] Fixed missing cast of arg to my_mbcharlen --- client/mysqltest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 2bbb1c63724..8523b40fc80 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5721,7 +5721,7 @@ int read_line(char *buf, int size) /* Could be a multibyte character */ /* This code is based on the code in "sql_load.cc" */ #ifdef USE_MB - int charlen = my_mbcharlen(charset_info, c); + int charlen = my_mbcharlen(charset_info, (unsigned char) c); /* We give up if multibyte character is started but not */ /* completed before we pass buf_end */ if ((charlen > 1) && (p + charlen) <= buf_end) From e4f9ead1403bff9ff07b659f0e2a2575036d39da Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 20 Oct 2010 11:41:51 +0200 Subject: [PATCH 107/151] Fixed wrong feof check in read_line, see 52019 --- client/mysqltest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 8523b40fc80..de46624bf2c 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5733,9 +5733,9 @@ int read_line(char *buf, int size) for (i= 1; i < charlen; i++) { + c= my_getc(cur_file->file); if (feof(cur_file->file)) goto found_eof; - c= my_getc(cur_file->file); *p++ = c; } if (! my_ismbchar(charset_info, mb_start, p)) From 67a0d9c0e05b1df9bd7b29878a04f50449110e10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 20 Oct 2010 14:46:28 +0300 Subject: [PATCH 108/151] Fix bit-rot left by the multiple buffer pools patch. Rename buf_pool_watch, buf_pool_mutex, buf_pool_zip_mutex to buf_pool->watch, buf_pool->mutex, buf_pool->zip_mutex in comments. Refer to buf_pool->flush_list_mutex instead of flush_list_mutex. Remove obsolete declarations of buf_pool_mutex and buf_pool_zip_mutex. --- storage/innobase/buf/buf0buddy.c | 2 +- storage/innobase/buf/buf0buf.c | 6 ++-- storage/innobase/buf/buf0flu.c | 18 +++++------ storage/innobase/buf/buf0lru.c | 10 +++--- storage/innobase/include/buf0buddy.h | 2 +- storage/innobase/include/buf0buddy.ic | 4 +-- storage/innobase/include/buf0buf.h | 45 ++++++++++++--------------- storage/innobase/include/buf0flu.h | 2 +- storage/innobase/sync/sync0sync.c | 4 +-- 9 files changed, 44 insertions(+), 49 deletions(-) diff --git a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c index 5dc0780cbdd..787b4e652a0 100644 --- a/storage/innobase/buf/buf0buddy.c +++ b/storage/innobase/buf/buf0buddy.c @@ -281,7 +281,7 @@ buf_buddy_alloc_from( /**********************************************************************//** Allocate a block. The thread calling this function must hold -buf_pool->mutex and must not hold buf_pool_zip_mutex or any block->mutex. +buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex. The buf_pool->mutex may only be released and reacquired if lru != NULL. @return allocated block, possibly NULL if lru==NULL */ UNIV_INTERN diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index af631747f48..abfde83a3bd 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -172,7 +172,7 @@ The chain of modified blocks (buf_pool->flush_list) contains the blocks holding file pages that have been modified in the memory but not written to disk yet. The block with the oldest modification which has not yet been written to disk is at the end of the chain. -The access to this list is protected by flush_list_mutex. +The access to this list is protected by buf_pool->flush_list_mutex. The chain of unmodified compressed blocks (buf_pool->zip_clean) contains the control blocks (buf_page_t) of those compressed pages @@ -1882,8 +1882,8 @@ buf_pool_watch_set( ut_ad(!bpage->in_page_hash); ut_ad(bpage->buf_fix_count == 0); - /* bpage is pointing to buf_pool_watch[], - which is protected by buf_pool_mutex. + /* bpage is pointing to buf_pool->watch[], + which is protected by buf_pool->mutex. Normally, buf_page_t objects are protected by buf_block_t::mutex or buf_pool->zip_mutex or both. */ diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c index c342b8f1901..5b0617f17b1 100644 --- a/storage/innobase/buf/buf0flu.c +++ b/storage/innobase/buf/buf0flu.c @@ -321,7 +321,7 @@ buf_flush_insert_sorted_into_flush_list( buf_flush_list_mutex_enter(buf_pool); - /* The field in_LRU_list is protected by buf_pool_mutex, which + /* The field in_LRU_list is protected by buf_pool->mutex, which we are not holding. However, while a block is in the flush list, it is dirty and cannot be discarded, not from the page_hash or from the LRU list. At most, the uncompressed @@ -1061,7 +1061,7 @@ buf_flush_write_block_low( ut_ad(buf_page_in_file(bpage)); - /* We are not holding buf_pool_mutex or block_mutex here. + /* We are not holding buf_pool->mutex or block_mutex here. Nevertheless, it is safe to access bpage, because it is io_fixed and oldest_modification != 0. Thus, it cannot be relocated in the buffer pool or removed from flush_list or @@ -1135,7 +1135,7 @@ buf_flush_write_block_low( # if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG /********************************************************************//** Writes a flushable page asynchronously from the buffer pool to a file. -NOTE: buf_pool_mutex and block->mutex must be held upon entering this +NOTE: buf_pool->mutex and block->mutex must be held upon entering this function, and they will be released by this function after flushing. This is loosely based on buf_flush_batch() and buf_flush_page(). @return TRUE if the page was flushed and the mutexes released */ @@ -2193,12 +2193,12 @@ buf_flush_validate_low( ut_ad(bpage->in_flush_list); - /* A page in flush_list can be in BUF_BLOCK_REMOVE_HASH - state. This happens when a page is in the middle of - being relocated. In that case the original descriptor - can have this state and still be in the flush list - waiting to acquire the flush_list_mutex to complete - the relocation. */ + /* A page in buf_pool->flush_list can be in + BUF_BLOCK_REMOVE_HASH state. This happens when a page + is in the middle of being relocated. In that case the + original descriptor can have this state and still be + in the flush list waiting to acquire the + buf_pool->flush_list_mutex to complete the relocation. */ ut_a(buf_page_in_file(bpage) || buf_page_get_state(bpage) == BUF_BLOCK_REMOVE_HASH); ut_a(om > 0); diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c index e1d4b5081b8..8ad5f2dad83 100644 --- a/storage/innobase/buf/buf0lru.c +++ b/storage/innobase/buf/buf0lru.c @@ -356,8 +356,8 @@ scan_again: prev_bpage = UT_LIST_GET_PREV(LRU, bpage); /* bpage->space and bpage->io_fix are protected by - buf_pool_mutex and block_mutex. It is safe to check - them while holding buf_pool_mutex only. */ + buf_pool->mutex and block_mutex. It is safe to check + them while holding buf_pool->mutex only. */ if (buf_page_get_space(bpage) != id) { /* Skip this block, as it does not belong to @@ -403,7 +403,7 @@ scan_again: /* Descriptors of uncompressed blocks will not be relocated, because we are holding the - buf_pool_mutex. */ + buf_pool->mutex. */ break; case BUF_BLOCK_ZIP_PAGE: case BUF_BLOCK_ZIP_DIRTY: @@ -1443,10 +1443,10 @@ Try to free a block. If bpage is a descriptor of a compressed-only page, the descriptor object will be freed as well. NOTE: If this function returns BUF_LRU_FREED, it will temporarily -release buf_pool_mutex. Furthermore, the page frame will no longer be +release buf_pool->mutex. Furthermore, the page frame will no longer be accessible via bpage. -The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and +The caller must hold buf_pool->mutex and buf_page_get_mutex(bpage) and release these two mutexes after the call. No other buf_page_get_mutex() may be held when calling this function. @return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or diff --git a/storage/innobase/include/buf0buddy.h b/storage/innobase/include/buf0buddy.h index 03588d18197..b255d8c9351 100644 --- a/storage/innobase/include/buf0buddy.h +++ b/storage/innobase/include/buf0buddy.h @@ -36,7 +36,7 @@ Created December 2006 by Marko Makela /**********************************************************************//** Allocate a block. The thread calling this function must hold -buf_pool->mutex and must not hold buf_pool_zip_mutex or any +buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex. The buf_pool->mutex may only be released and reacquired if lru != NULL. This function should only be used for allocating compressed page frames or control blocks (buf_page_t). Allocated diff --git a/storage/innobase/include/buf0buddy.ic b/storage/innobase/include/buf0buddy.ic index 387eacc754a..e50c33ea15a 100644 --- a/storage/innobase/include/buf0buddy.ic +++ b/storage/innobase/include/buf0buddy.ic @@ -35,7 +35,7 @@ Created December 2006 by Marko Makela /**********************************************************************//** Allocate a block. The thread calling this function must hold -buf_pool->mutex and must not hold buf_pool_zip_mutex or any block->mutex. +buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex. The buf_pool->mutex may only be released and reacquired if lru != NULL. @return allocated block, possibly NULL if lru==NULL */ UNIV_INTERN @@ -86,7 +86,7 @@ buf_buddy_get_slot( /**********************************************************************//** Allocate a block. The thread calling this function must hold -buf_pool->mutex and must not hold buf_pool_zip_mutex or any +buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex. The buf_pool->mutex may only be released and reacquired if lru != NULL. This function should only be used for allocating compressed page frames or control blocks (buf_page_t). Allocated diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index f33ef65ddf2..b0fff919918 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -96,7 +96,7 @@ enum buf_page_state { BUF_BLOCK_ZIP_FREE = 0, /*!< contains a free compressed page */ BUF_BLOCK_POOL_WATCH = 0, /*!< a sentinel for the buffer pool - watch, element of buf_pool_watch[] */ + watch, element of buf_pool->watch[] */ BUF_BLOCK_ZIP_PAGE, /*!< contains a clean compressed page */ BUF_BLOCK_ZIP_DIRTY, /*!< contains a compressed @@ -1210,10 +1210,10 @@ struct buf_page_struct{ #endif /* !UNIV_HOTBACKUP */ page_zip_des_t zip; /*!< compressed page; zip.data (but not the data it points to) is - also protected by buf_pool_mutex; + also protected by buf_pool->mutex; state == BUF_BLOCK_ZIP_PAGE and zip.data == NULL means an active - buf_pool_watch */ + buf_pool->watch */ #ifndef UNIV_HOTBACKUP buf_page_t* hash; /*!< node used in chaining to buf_pool->page_hash or @@ -1224,15 +1224,16 @@ struct buf_page_struct{ #endif /* UNIV_DEBUG */ /** @name Page flushing fields - All these are protected by buf_pool_mutex. */ + All these are protected by buf_pool->mutex. */ /* @{ */ UT_LIST_NODE_T(buf_page_t) list; /*!< based on state, this is a list node, protected either by - buf_pool_mutex or by - flush_list_mutex, in one of the - following lists in buf_pool: + buf_pool->mutex or by + buf_pool->flush_list_mutex, + in one of the following lists in + buf_pool: - BUF_BLOCK_NOT_USED: free - BUF_BLOCK_FILE_PAGE: flush_list @@ -1242,9 +1243,9 @@ struct buf_page_struct{ If bpage is part of flush_list then the node pointers are - covered by flush_list_mutex. + covered by buf_pool->flush_list_mutex. Otherwise these pointers are - protected by buf_pool_mutex. + protected by buf_pool->mutex. The contents of the list node is undefined if !in_flush_list @@ -1256,17 +1257,18 @@ struct buf_page_struct{ #ifdef UNIV_DEBUG ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list; - when flush_list_mutex is free, the - following should hold: in_flush_list + when buf_pool->flush_list_mutex is + free, the following should hold: + in_flush_list == (state == BUF_BLOCK_FILE_PAGE || state == BUF_BLOCK_ZIP_DIRTY) Writes to this field must be covered by both block->mutex - and flush_list_mutex. Hence + and buf_pool->flush_list_mutex. Hence reads can happen while holding any one of the two mutexes */ ibool in_free_list; /*!< TRUE if in buf_pool->free; when - buf_pool_mutex is free, the following + buf_pool->mutex is free, the following should hold: in_free_list == (state == BUF_BLOCK_NOT_USED) */ #endif /* UNIV_DEBUG */ @@ -1286,7 +1288,7 @@ struct buf_page_struct{ modifications are on disk. Writes to this field must be covered by both block->mutex - and flush_list_mutex. Hence + and buf_pool->flush_list_mutex. Hence reads can happen while holding any one of the two mutexes */ /* @} */ @@ -1661,20 +1663,13 @@ struct buf_pool_struct{ /* @} */ }; -/** mutex protecting the buffer pool struct and control blocks, except the -read-write lock in them */ -extern mutex_t buf_pool_mutex; -/** mutex protecting the control blocks of compressed-only pages -(of type buf_page_t, not buf_block_t) */ -extern mutex_t buf_pool_zip_mutex; - -/** @name Accessors for buf_pool_mutex. -Use these instead of accessing buf_pool_mutex directly. */ +/** @name Accessors for buf_pool->mutex. +Use these instead of accessing buf_pool->mutex directly. */ /* @{ */ -/** Test if buf_pool_mutex is owned. */ +/** Test if a buffer pool mutex is owned. */ #define buf_pool_mutex_own(b) mutex_own(&b->mutex) -/** Acquire the buffer pool mutex. */ +/** Acquire a buffer pool mutex. */ #define buf_pool_mutex_enter(b) do { \ ut_ad(!mutex_own(&b->zip_mutex)); \ mutex_enter(&b->mutex); \ diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index 976456972c1..28d9b90e755 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -87,7 +87,7 @@ buf_flush_init_for_writing( # if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG /********************************************************************//** Writes a flushable page asynchronously from the buffer pool to a file. -NOTE: buf_pool_mutex and block->mutex must be held upon entering this +NOTE: buf_pool->mutex and block->mutex must be held upon entering this function, and they will be released by this function after flushing. This is loosely based on buf_flush_batch() and buf_flush_page(). @return TRUE if the page was flushed and the mutexes released */ diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c index 8062d9e902e..761cc4c805e 100644 --- a/storage/innobase/sync/sync0sync.c +++ b/storage/innobase/sync/sync0sync.c @@ -1207,8 +1207,8 @@ sync_thread_add_level( case SYNC_BUF_BLOCK: /* Either the thread must own the buffer pool mutex - (buf_pool_mutex), or it is allowed to latch only ONE - buffer block (block->mutex or buf_pool_zip_mutex). */ + (buf_pool->mutex), or it is allowed to latch only ONE + buffer block (block->mutex or buf_pool->zip_mutex). */ if (!sync_thread_levels_g(array, level, FALSE)) { ut_a(sync_thread_levels_g(array, level - 1, TRUE)); ut_a(sync_thread_levels_contain(array, SYNC_BUF_POOL)); From 8739daeef02b1b3e3303a75f3454842eb1632514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 20 Oct 2010 15:58:47 +0300 Subject: [PATCH 109/151] Fix a compiler warning caused by fixing Bug #57588 (compiler warning). Declare DATA_MBMAXLEN with the same data type as DATA_MBMINLEN. --- storage/innobase/include/data0type.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h index f0be5ace306..d7fa0b9cd44 100644 --- a/storage/innobase/include/data0type.h +++ b/storage/innobase/include/data0type.h @@ -180,7 +180,7 @@ because in GCC it returns a long. */ UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), \ 1)) /* Get mbmaxlen from mbminmaxlen. */ -#define DATA_MBMAXLEN(mbminmaxlen) ((mbminmaxlen) / DATA_MBMAX) +#define DATA_MBMAXLEN(mbminmaxlen) ((ulint) ((mbminmaxlen) / DATA_MBMAX)) #ifndef UNIV_HOTBACKUP /*********************************************************************//** From b5bb13ec0380624c2e663a4e9b4b29fe574b3e05 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 20 Oct 2010 11:40:04 -0200 Subject: [PATCH 110/151] Bug#45288: pb2 returns a lot of compilation warnings Fix assorted compiler warnings. include/my_pthread.h: Like for pthread_cond_timedwait, the abstime is constant. mysys/my_gethwaddr.c: Instead of using a manual copy that introduce warnings due to type mismatch, copy the buffer using memcpy and use memcmp to check whether all bytes of the buffer are zeroed. mysys/thr_mutex.c: Like for pthread_cond_timedwait, the abstime is constant. unittest/mytap/tap.h: Introduce a ok() variant that does not take a format argument. Since ok() is tagged with a printf attribute, GCC complains if the fmt argument is NULL. --- include/my_pthread.h | 3 ++- mysys/my_gethwaddr.c | 32 +++++++++++++------------------- mysys/thr_mutex.c | 4 ++-- unittest/examples/skip-t.c | 8 ++++---- unittest/examples/skip_all-t.c | 8 ++++---- unittest/examples/todo-t.c | 8 ++++---- unittest/mytap/t/basic-t.c | 2 +- unittest/mytap/tap.c | 17 +++++++++++++++++ unittest/mytap/tap.h | 15 +++++++++++++-- 9 files changed, 60 insertions(+), 37 deletions(-) diff --git a/include/my_pthread.h b/include/my_pthread.h index fec7c972a7b..a7e4ea25064 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -492,7 +492,8 @@ int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line); int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file, uint line); int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, - struct timespec *abstime, const char *file, uint line); + const struct timespec *abstime, + const char *file, uint line); void safe_mutex_global_init(void); void safe_mutex_end(FILE *file); diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index 00e0e90f1e4..90908bd1c0d 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -21,18 +21,6 @@ #ifndef MAIN -#if defined(__FreeBSD__) || defined(__linux__) -static my_bool memcpy_and_test(uchar *to, uchar *from, uint len) -{ - uint i, res=1; - - for (i=0; i < len; i++) - if ((*to++= *from++)) - res=0; - return res; -} -#endif /* FreeBSD || linux */ - #ifdef __FreeBSD__ #include @@ -44,10 +32,11 @@ static my_bool memcpy_and_test(uchar *to, uchar *from, uint len) my_bool my_gethwaddr(uchar *to) { size_t len; - uchar *buf, *next, *end, *addr; + char *buf, *next, *end; struct if_msghdr *ifm; struct sockaddr_dl *sdl; int res=1, mib[6]={CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0}; + char zero_array[ETHER_ADDR_LEN] = {0}; if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) goto err; @@ -63,9 +52,9 @@ my_bool my_gethwaddr(uchar *to) ifm = (struct if_msghdr *)next; if (ifm->ifm_type == RTM_IFINFO) { - sdl = (struct sockaddr_dl *)(ifm + 1); - addr=LLADDR(sdl); - res=memcpy_and_test(to, addr, ETHER_ADDR_LEN); + sdl= (struct sockaddr_dl *)(ifm + 1); + memcpy(to, LLADDR(sdl), ETHER_ADDR_LEN); + res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1; } } @@ -81,8 +70,9 @@ err: my_bool my_gethwaddr(uchar *to) { - int fd, res=1; + int fd, res= 1; struct ifreq ifr; + char zero_array[ETHER_ADDR_LEN] = {0}; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) @@ -91,9 +81,13 @@ my_bool my_gethwaddr(uchar *to) bzero(&ifr, sizeof(ifr)); strnmov(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name) - 1); - do { + do + { if (ioctl(fd, SIOCGIFHWADDR, &ifr) >= 0) - res=memcpy_and_test(to, (uchar *)&ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); + { + memcpy(to, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); + res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1; + } } while (res && (errno == 0 || errno == ENODEV) && ifr.ifr_name[3]++ < '6'); close(fd); diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c index 8f9928026ba..c7600b58c95 100644 --- a/mysys/thr_mutex.c +++ b/mysys/thr_mutex.c @@ -259,8 +259,8 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file, int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, - struct timespec *abstime, - const char *file, uint line) + const struct timespec *abstime, + const char *file, uint line) { int error; pthread_mutex_lock(&mp->global); diff --git a/unittest/examples/skip-t.c b/unittest/examples/skip-t.c index 092353fcc48..c8c910b31ff 100644 --- a/unittest/examples/skip-t.c +++ b/unittest/examples/skip-t.c @@ -18,11 +18,11 @@ int main() { plan(4); - ok(1, NULL); - ok(1, NULL); + ok1(1); + ok1(1); SKIP_BLOCK_IF(1, 2, "Example of skipping a few test points in a test") { - ok(1, NULL); - ok(1, NULL); + ok1(1); + ok1(1); } return exit_status(); } diff --git a/unittest/examples/skip_all-t.c b/unittest/examples/skip_all-t.c index a4c8648fbe4..826fa22e82f 100644 --- a/unittest/examples/skip_all-t.c +++ b/unittest/examples/skip_all-t.c @@ -31,9 +31,9 @@ int main() { if (!has_feature()) skip_all("Example of skipping an entire test"); plan(4); - ok(1, NULL); - ok(1, NULL); - ok(1, NULL); - ok(1, NULL); + ok1(1); + ok1(1); + ok1(1); + ok1(1); return exit_status(); } diff --git a/unittest/examples/todo-t.c b/unittest/examples/todo-t.c index 2de409447ba..2751da5e010 100644 --- a/unittest/examples/todo-t.c +++ b/unittest/examples/todo-t.c @@ -21,15 +21,15 @@ int main() { plan(4); - ok(1, NULL); - ok(1, NULL); + ok1(1); + ok1(1); /* Tests in the todo region is expected to fail. If they don't, something is strange. */ todo_start("Need to fix these"); - ok(0, NULL); - ok(0, NULL); + ok1(0); + ok1(0); todo_end(); return exit_status(); } diff --git a/unittest/mytap/t/basic-t.c b/unittest/mytap/t/basic-t.c index c0ceb5bf190..b588521d192 100644 --- a/unittest/mytap/t/basic-t.c +++ b/unittest/mytap/t/basic-t.c @@ -22,7 +22,7 @@ int main() { plan(5); ok(1 == 1, "testing basic functions"); ok(2 == 2, " "); - ok(3 == 3, NULL); + ok1(3 == 3); if (1 == 1) skip(2, "Sensa fragoli"); else { diff --git a/unittest/mytap/tap.c b/unittest/mytap/tap.c index a5831f2b71d..2566d90c4b0 100644 --- a/unittest/mytap/tap.c +++ b/unittest/mytap/tap.c @@ -223,6 +223,23 @@ ok(int const pass, char const *fmt, ...) emit_endl(); } +void +ok1(int const pass) +{ + va_list ap; + + memset(&ap, 0, sizeof(ap)); + + if (!pass && *g_test.todo == '\0') + ++g_test.failed; + + vemit_tap(pass, NULL, ap); + + if (*g_test.todo != '\0') + emit_dir("todo", g_test.todo); + + emit_endl(); +} void skip(int how_many, char const *fmt, ...) diff --git a/unittest/mytap/tap.h b/unittest/mytap/tap.h index 4118207ca7a..010121507bc 100644 --- a/unittest/mytap/tap.h +++ b/unittest/mytap/tap.h @@ -98,14 +98,25 @@ void plan(int const count); @endcode @param pass Zero if the test failed, non-zero if it passed. - @param fmt Format string in printf() format. NULL is allowed, in - which case nothing is printed. + @param fmt Format string in printf() format. NULL is not allowed, + use ok1() in this case. */ void ok(int const pass, char const *fmt, ...) __attribute__((format(printf,2,3))); +/** + Report test result as a TAP line. + + Same as ok() but does not take a message to be printed. + + @param pass Zero if the test failed, non-zero if it passed. +*/ + +void ok1(int const pass); + + /** Skip a determined number of tests. From 0455ff8faf97da88c0a1cb42a615e75f43e40012 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 20 Oct 2010 16:15:32 +0200 Subject: [PATCH 111/151] Follow-up to Bug #55582 which allows chaecking strings in if Simplified cases where a select was used to compare variable against '' --- .../extra/rpl_tests/rpl_get_master_version_and_clock.test | 2 +- mysql-test/extra/rpl_tests/rpl_loaddata.test | 2 +- mysql-test/include/check_concurrent_insert.inc | 4 ++-- mysql-test/include/check_no_concurrent_insert.inc | 4 ++-- mysql-test/include/get_relay_log_pos.inc | 4 ++-- mysql-test/include/kill_query.inc | 4 ++-- mysql-test/include/kill_query_and_diff_master_slave.inc | 8 ++++---- mysql-test/include/setup_fake_relay_log.inc | 2 +- mysql-test/include/show_binlog_events.inc | 4 ++-- mysql-test/include/show_rpl_debug_info.inc | 6 +++--- mysql-test/include/wait_for_slave_io_error.inc | 2 +- mysql-test/include/wait_for_slave_param.inc | 4 ++-- mysql-test/include/wait_for_slave_sql_error.inc | 2 +- mysql-test/include/wait_for_status_var.inc | 2 +- mysql-test/suite/rpl/t/rpl_killed_ddl.test | 2 +- 15 files changed, 26 insertions(+), 26 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test b/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test index 66bd61a8ea9..40e155bc314 100644 --- a/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test +++ b/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test @@ -34,7 +34,7 @@ # connection slave; -if (`SELECT $debug_sync_action = ''`) +if (!$debug_sync_action) { --die Cannot continue. Please set value for debug_sync_action. } diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test index 1ae17398596..84419ec9cc5 100644 --- a/mysql-test/extra/rpl_tests/rpl_loaddata.test +++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test @@ -24,7 +24,7 @@ connection master; # MTR is not case-sensitive. let $lower_stmt_head= load data; let $UPPER_STMT_HEAD= LOAD DATA; -if (`SELECT '$lock_option' <> ''`) +if ($lock_option) { #if $lock_option is null, an extra blank is added into the statement, #this will change the result of rpl_loaddata test case. so $lock_option diff --git a/mysql-test/include/check_concurrent_insert.inc b/mysql-test/include/check_concurrent_insert.inc index f4bec3c9cdb..62de485d8f1 100644 --- a/mysql-test/include/check_concurrent_insert.inc +++ b/mysql-test/include/check_concurrent_insert.inc @@ -23,7 +23,7 @@ # Reset DEBUG_SYNC facility for safety. set debug_sync= "RESET"; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval create temporary table t_backup select * from $restore_table; } @@ -82,7 +82,7 @@ connection default; --eval delete from $table where i = 0; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval truncate table $restore_table; --eval insert into $restore_table select * from t_backup; diff --git a/mysql-test/include/check_no_concurrent_insert.inc b/mysql-test/include/check_no_concurrent_insert.inc index f60401bcad1..6938c53fd16 100644 --- a/mysql-test/include/check_no_concurrent_insert.inc +++ b/mysql-test/include/check_no_concurrent_insert.inc @@ -23,7 +23,7 @@ # Reset DEBUG_SYNC facility for safety. set debug_sync= "RESET"; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval create temporary table t_backup select * from $restore_table; } @@ -67,7 +67,7 @@ if (!$success) --eval delete from $table where i = 0; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval truncate table $restore_table; --eval insert into $restore_table select * from t_backup; diff --git a/mysql-test/include/get_relay_log_pos.inc b/mysql-test/include/get_relay_log_pos.inc index 7ce36fd3c50..61ee07fc655 100644 --- a/mysql-test/include/get_relay_log_pos.inc +++ b/mysql-test/include/get_relay_log_pos.inc @@ -10,12 +10,12 @@ # # at this point, get_relay_log_pos.inc sets $relay_log_pos. echo position # # in $relay_log_file: $relay_log_pos. -if (`SELECT '$relay_log_file' = ''`) +if (!$relay_log_file) { --die 'variable $relay_log_file is null' } -if (`SELECT '$master_log_pos' = ''`) +if (!$master_log_pos) { --die 'variable $master_log_pos is null' } diff --git a/mysql-test/include/kill_query.inc b/mysql-test/include/kill_query.inc index b303ed0ec39..1c949d3cbad 100644 --- a/mysql-test/include/kill_query.inc +++ b/mysql-test/include/kill_query.inc @@ -44,7 +44,7 @@ connection master; # kill the query that is waiting eval kill query $connection_id; -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { # release the lock to allow binlog continue eval SELECT RELEASE_LOCK($debug_lock); @@ -57,7 +57,7 @@ reap; connection master; -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { # get lock again to make the next query wait eval SELECT GET_LOCK($debug_lock, 10); diff --git a/mysql-test/include/kill_query_and_diff_master_slave.inc b/mysql-test/include/kill_query_and_diff_master_slave.inc index 611d6929c99..b3846d12df1 100644 --- a/mysql-test/include/kill_query_and_diff_master_slave.inc +++ b/mysql-test/include/kill_query_and_diff_master_slave.inc @@ -25,7 +25,7 @@ source include/kill_query.inc; connection master; disable_query_log; disable_result_log; -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { eval SELECT RELEASE_LOCK($debug_lock); } @@ -36,8 +36,8 @@ source include/diff_master_slave.inc; # Acquire the debug lock again if used connection master; -disable_query_log; disable_result_log; if (`SELECT '$debug_lock' != -''`) { eval SELECT GET_LOCK($debug_lock, 10); } enable_result_log; -enable_query_log; +disable_query_log; disable_result_log; +if ($debug_lock) { eval SELECT GET_LOCK($debug_lock, 10); } +enable_result_log; enable_query_log; connection $connection_name; diff --git a/mysql-test/include/setup_fake_relay_log.inc b/mysql-test/include/setup_fake_relay_log.inc index fb035941a29..f881f3bf4e8 100644 --- a/mysql-test/include/setup_fake_relay_log.inc +++ b/mysql-test/include/setup_fake_relay_log.inc @@ -56,7 +56,7 @@ if (`SELECT "$_sql_running" = "Yes" OR "$_io_running" = "Yes"`) { # Read server variables. let $MYSQLD_DATADIR= `SELECT @@datadir`; let $_fake_filename= query_get_value(SHOW VARIABLES LIKE 'relay_log', Value, 1); -if (`SELECT '$_fake_filename' = ''`) { +if (!$_fake_filename) { --echo Badly written test case: relay_log variable is empty. Please use the --echo server option --relay-log=FILE. } diff --git a/mysql-test/include/show_binlog_events.inc b/mysql-test/include/show_binlog_events.inc index 8649f31ad9f..6d8c8196102 100644 --- a/mysql-test/include/show_binlog_events.inc +++ b/mysql-test/include/show_binlog_events.inc @@ -27,14 +27,14 @@ if (!$binlog_start) } --let $_statement=show binlog events -if (`SELECT '$binlog_file' <> ''`) +if ($binlog_file) { --let $_statement= $_statement in '$binlog_file' } --let $_statement= $_statement from $binlog_start -if (`SELECT '$binlog_limit' <> ''`) +if ($binlog_limit) { --let $_statement= $_statement limit $binlog_limit } diff --git a/mysql-test/include/show_rpl_debug_info.inc b/mysql-test/include/show_rpl_debug_info.inc index 148d11f3b02..9944e6cd25f 100644 --- a/mysql-test/include/show_rpl_debug_info.inc +++ b/mysql-test/include/show_rpl_debug_info.inc @@ -48,13 +48,13 @@ let $binlog_name= query_get_value("SHOW MASTER STATUS", File, 1); eval SHOW BINLOG EVENTS IN '$binlog_name'; let $_master_con= $master_connection; -if (`SELECT '$_master_con' = ''`) +if (!$_master_con) { if (`SELECT '$_con' = 'slave'`) { let $_master_con= master; } - if (`SELECT '$_master_con' = ''`) + if (!$_master_con) { --echo Unable to determine master connection. No debug info printed for master. --echo Please fix the test case by setting $master_connection before sourcing @@ -62,7 +62,7 @@ if (`SELECT '$_master_con' = ''`) } } -if (`SELECT '$_master_con' != ''`) +if ($_master_con) { let $master_binlog_name_io= query_get_value("SHOW SLAVE STATUS", Master_Log_File, 1); diff --git a/mysql-test/include/wait_for_slave_io_error.inc b/mysql-test/include/wait_for_slave_io_error.inc index 34cbf20a73b..ffdcf752873 100644 --- a/mysql-test/include/wait_for_slave_io_error.inc +++ b/mysql-test/include/wait_for_slave_io_error.inc @@ -31,7 +31,7 @@ # $master_connection # See wait_for_slave_param.inc for description. -if (`SELECT '$slave_io_errno' = ''`) { +if (!$slave_io_errno) { --die !!!ERROR IN TEST: you must set \$slave_io_errno before sourcing wait_for_slave_io_error.inc } diff --git a/mysql-test/include/wait_for_slave_param.inc b/mysql-test/include/wait_for_slave_param.inc index ef864f9245e..98cd426fa11 100644 --- a/mysql-test/include/wait_for_slave_param.inc +++ b/mysql-test/include/wait_for_slave_param.inc @@ -51,7 +51,7 @@ if (!$_slave_timeout_counter) } let $_slave_param_comparison= $slave_param_comparison; -if (`SELECT '$_slave_param_comparison' = ''`) +if (!$_slave_param_comparison) { let $_slave_param_comparison= =; } @@ -71,7 +71,7 @@ while (`SELECT NOT('$_show_slave_status_value' $_slave_param_comparison '$slave_ if (!$_slave_timeout_counter) { --echo **** ERROR: timeout after $slave_timeout seconds while waiting for slave parameter $slave_param $_slave_param_comparison $slave_param_value **** - if (`SELECT '$slave_error_message' != ''`) + if ($slave_error_message) { --echo Message: $slave_error_message } diff --git a/mysql-test/include/wait_for_slave_sql_error.inc b/mysql-test/include/wait_for_slave_sql_error.inc index aab04036eea..80836f908c6 100644 --- a/mysql-test/include/wait_for_slave_sql_error.inc +++ b/mysql-test/include/wait_for_slave_sql_error.inc @@ -24,7 +24,7 @@ # $master_connection # See wait_for_slave_param.inc for description. -if (`SELECT '$slave_sql_errno' = ''`) { +if (!$slave_sql_errno) { --die !!!ERROR IN TEST: you must set \$slave_sql_errno before sourcing wait_for_slave_sql_error.inc } diff --git a/mysql-test/include/wait_for_status_var.inc b/mysql-test/include/wait_for_status_var.inc index 8b644c2c3c5..9f4962aeaed 100644 --- a/mysql-test/include/wait_for_status_var.inc +++ b/mysql-test/include/wait_for_status_var.inc @@ -45,7 +45,7 @@ if (!$_status_timeout_counter) } let $_status_var_comparsion= $status_var_comparsion; -if (`SELECT '$_status_var_comparsion' = ''`) +if (!$_status_var_comparsion) { let $_status_var_comparsion= =; } diff --git a/mysql-test/suite/rpl/t/rpl_killed_ddl.test b/mysql-test/suite/rpl/t/rpl_killed_ddl.test index 61b882efcf3..69648267ca4 100644 --- a/mysql-test/suite/rpl/t/rpl_killed_ddl.test +++ b/mysql-test/suite/rpl/t/rpl_killed_ddl.test @@ -119,7 +119,7 @@ echo [on master]; # This will block the execution of a statement at the DBUG_SYNC_POINT # with given lock name -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { disable_query_log; disable_result_log; From d6af9bef7a72f24b05a88b6cd4fd3a69b14cc82d Mon Sep 17 00:00:00 2001 From: "Horst.Hunger" Date: Wed, 20 Oct 2010 16:56:09 +0200 Subject: [PATCH 112/151] due to merge --- mysql-test/include/have_plugin_interface.inc | 5 + mysql-test/include/have_plugin_server.inc | 5 + mysql-test/mysql-test-run.pl | 17 +- mysql-test/r/plugin_auth_qa.result | 327 ++++++++++++++++++ mysql-test/r/plugin_auth_qa_1.result | 335 ++++++++++++++++++ mysql-test/r/plugin_auth_qa_2.result | 146 ++++++++ mysql-test/r/plugin_auth_qa_3.result | 11 + mysql-test/t/plugin_auth_qa-master.opt | 2 + mysql-test/t/plugin_auth_qa.test | 338 +++++++++++++++++++ mysql-test/t/plugin_auth_qa_1-master.opt | 2 + mysql-test/t/plugin_auth_qa_1.test | 334 ++++++++++++++++++ mysql-test/t/plugin_auth_qa_2-master.opt | 2 + mysql-test/t/plugin_auth_qa_2.test | 148 ++++++++ mysql-test/t/plugin_auth_qa_3-master.opt | 2 + mysql-test/t/plugin_auth_qa_3.test | 25 ++ plugin/auth/CMakeLists.txt | 8 + plugin/auth/Makefile.am | 6 +- plugin/auth/qa_auth_client.c | 127 +++++++ plugin/auth/qa_auth_interface.c | 262 ++++++++++++++ plugin/auth/qa_auth_server.c | 87 +++++ 20 files changed, 2187 insertions(+), 2 deletions(-) create mode 100644 mysql-test/include/have_plugin_interface.inc create mode 100644 mysql-test/include/have_plugin_server.inc create mode 100644 mysql-test/r/plugin_auth_qa.result create mode 100644 mysql-test/r/plugin_auth_qa_1.result create mode 100644 mysql-test/r/plugin_auth_qa_2.result create mode 100644 mysql-test/r/plugin_auth_qa_3.result create mode 100644 mysql-test/t/plugin_auth_qa-master.opt create mode 100644 mysql-test/t/plugin_auth_qa.test create mode 100644 mysql-test/t/plugin_auth_qa_1-master.opt create mode 100644 mysql-test/t/plugin_auth_qa_1.test create mode 100644 mysql-test/t/plugin_auth_qa_2-master.opt create mode 100644 mysql-test/t/plugin_auth_qa_2.test create mode 100644 mysql-test/t/plugin_auth_qa_3-master.opt create mode 100644 mysql-test/t/plugin_auth_qa_3.test create mode 100644 plugin/auth/qa_auth_client.c create mode 100644 plugin/auth/qa_auth_interface.c create mode 100644 plugin/auth/qa_auth_server.c diff --git a/mysql-test/include/have_plugin_interface.inc b/mysql-test/include/have_plugin_interface.inc new file mode 100644 index 00000000000..afe8ffad40d --- /dev/null +++ b/mysql-test/include/have_plugin_interface.inc @@ -0,0 +1,5 @@ +--disable_query_log +--require r/true.require +select (PLUGIN_LIBRARY LIKE 'qa_auth_interface%') as `TRUE` FROM INFORMATION_SCHEMA.PLUGINS + WHERE PLUGIN_NAME='qa_auth_interface'; +--enable_query_log diff --git a/mysql-test/include/have_plugin_server.inc b/mysql-test/include/have_plugin_server.inc new file mode 100644 index 00000000000..aad1f026b44 --- /dev/null +++ b/mysql-test/include/have_plugin_server.inc @@ -0,0 +1,5 @@ +--disable_query_log +--require r/true.require +select (PLUGIN_LIBRARY LIKE 'qa_auth_server%') as `TRUE` FROM INFORMATION_SCHEMA.PLUGINS + WHERE PLUGIN_NAME='qa_auth_server'; +--enable_query_log diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 88719ff5bb2..419fb4fdbaa 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -131,6 +131,9 @@ my $opt_start_dirty; my $opt_start_exit; my $start_only; +my $auth_interface_fn; # the name of qa_auth_interface plugin +my $auth_server_fn; # the name of qa_auth_server plugin +my $auth_client_fn; # the name of qa_auth_client plugin my $auth_filename; # the name of the authentication test plugin my $auth_plugin; # the path to the authentication test plugin @@ -1062,14 +1065,20 @@ sub command_line_setup { "$basedir/sql/share/charsets", "$basedir/share/charsets"); - # Look for client test plugin + # Look for auth test plugins if (IS_WINDOWS) { $auth_filename = "auth_test_plugin.dll"; + $auth_interface_fn = "qa_auth_interface.dll"; + $auth_server_fn = "qa_auth_server.dll"; + $auth_client_fn = "qa_auth_client.dll"; } else { $auth_filename = "auth_test_plugin.so"; + $auth_interface_fn = "qa_auth_interface.so"; + $auth_server_fn = "qa_auth_server.so"; + $auth_client_fn = "qa_auth_client.so"; } $auth_plugin= mtr_file_exists(vs_config_dirs('plugin/auth/',$auth_filename), @@ -1973,12 +1982,18 @@ sub environment_setup { $ENV{'PLUGIN_AUTH_OPT'}= "--plugin-dir=".dirname($auth_plugin); $ENV{'PLUGIN_AUTH_LOAD'}="--plugin_load=test_plugin_server=".$auth_filename; + $ENV{'PLUGIN_AUTH_INTERFACE'}="--plugin_load=qa_auth_interface=".$auth_interface_fn; + $ENV{'PLUGIN_AUTH_SERVER'}="--plugin_load=qa_auth_server=".$auth_server_fn; + $ENV{'PLUGIN_AUTH_CLIENT'}="--plugin_load=qa_auth_client=".$auth_client_fn; } else { $ENV{'PLUGIN_AUTH'}= ""; $ENV{'PLUGIN_AUTH_OPT'}="--plugin-dir="; $ENV{'PLUGIN_AUTH_LOAD'}=""; + $ENV{'PLUGIN_AUTH_INTERFACE'}=""; + $ENV{'PLUGIN_AUTH_SERVER'}=""; + $ENV{'PLUGIN_AUTH_CLIENT'}=""; } diff --git a/mysql-test/r/plugin_auth_qa.result b/mysql-test/r/plugin_auth_qa.result new file mode 100644 index 00000000000..d1ecf6a6470 --- /dev/null +++ b/mysql-test/r/plugin_auth_qa.result @@ -0,0 +1,327 @@ +CREATE DATABASE test_user_db; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +========== test 1.1 ====================================================== +CREATE USER plug IDENTIFIED WITH test_plugin_server; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server +REVOKE ALL PRIVILEGES ON test_user_db.* FROM plug; +DROP USER plug; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server +REVOKE ALL PRIVILEGES ON test_user_db.* FROM plug; +DROP USER plug; +CREATE USER plug IDENTIFIED WITH test_plugin_server AS ''; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS ''; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server +REVOKE ALL PRIVILEGES ON test_user_db.* FROM plug; +DROP USER plug; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS ; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +CREATE USER plug IDENTIFIED WITH test_plugin_server AS plug_dest; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'plug_dest' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS plug_dest; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'plug_dest' at line 1 +========== test 1.1 syntax errors ======================================== +CREATE USER plug IDENTIFIED WITH AS plug_dest; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS plug_dest' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH AS plug_dest; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS plug_dest' at line 1 +CREATE USER plug IDENTIFIED WITH; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +CREATE USER plug IDENTIFIED AS ''; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS ''' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED AS ''; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS ''' at line 1 +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' IDENTIFIED WITH 'test_plugin_server'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED WITH 'test_plugin_server'' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug +IDENTIFIED WITH 'test_plugin_server' IDENTIFIED WITH 'test_plugin_server'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED WITH 'test_plugin_server'' at line 2 +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS '' AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS 'plug_dest'' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug AS '' AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS '' AS 'plug_dest'' at line 1 +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS '' +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED WITH test_plugin_server AS 'plug_dest'' at line 2 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS '' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED WITH test_plugin_server AS 'plug_dest'' at line 2 +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd' +IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'' at line 2 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED BY 'plug_dest_passwd' + IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'' at line 2 +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' +USER plug_dest IDENTIFIED by 'plug_dest_pwd'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USER plug_dest IDENTIFIED by 'plug_dest_pwd'' at line 2 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + USER plug_dest IDENTIFIED by 'plug_dest_pwd'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USER plug_dest IDENTIFIED by 'plug_dest_pwd'' at line 2 +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' +plug_dest IDENTIFIED by 'plug_dest_pwd'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'plug_dest IDENTIFIED by 'plug_dest_pwd'' at line 2 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + plug_dest IDENTIFIED by 'plug_dest_pwd'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'plug_dest IDENTIFIED by 'plug_dest_pwd'' at line 2 +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' +IDENTIFIED by 'plug_dest_pwd'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED by 'plug_dest_pwd'' at line 2 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + IDENTIFIED by 'plug_dest_pwd'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED by 'plug_dest_pwd'' at line 2 +========== test 1.1 combinations ========================== +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +========== test 1.1.1.6/1.1.2.5 ============================ +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +plug_dest +DROP USER plug, plug_dest; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +DROP USER plug; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug_dest +DROP USER plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +plug_dest +DROP USER plug, plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +DROP USER plug; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug_dest +DROP USER plug_dest; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +plug_dest +DROP USER plug, plug_dest; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug_dest +DROP USER plug_dest; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +ERROR HY000: GRANT with IDENTIFIED WITH is illegal because the user plug already exists +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server'; +ERROR HY000: GRANT with IDENTIFIED WITH is illegal because the user plug already exists +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +ERROR HY000: Operation CREATE USER failed for 'plug'@'%' +CREATE USER plug IDENTIFIED WITH 'test_plugin_server'; +ERROR HY000: Operation CREATE USER failed for 'plug'@'%' +DROP USER plug; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +plug test_plugin_server plug_dest +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +plug test_plugin_server plug_dest *939AEE68989794C0F408277411C26055CDF41119 +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug IDENTIFIED BY 'plug_dest_passwd'; +ERROR HY000: Operation CREATE USER failed for 'plug'@'%' +DROP USER plug; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +plug test_plugin_server plug_dest +plug_dest test_plugin_server plug_dest +DROP USER plug,plug_dest; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +plug test_plugin_server plug_dest +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +plug test_plugin_server plug_dest +plug_dest test_plugin_server plug_dest +DROP USER plug,plug_dest; +========== test 1.1.1.1/1.1.2.1/1.1.1.5 ==================== +SET NAMES utf8; +CREATE USER plüg IDENTIFIED WITH 'test_plugin_server' AS 'plüg_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plüg test_plugin_server plüg_dest +DROP USER plüg; +CREATE USER plüg_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plüg_dest +DROP USER plüg_dest; +SET NAMES ascii; +CREATE USER 'plüg' IDENTIFIED WITH 'test_plugin_server' AS 'plüg_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +pl??g test_plugin_server pl??g_dest +DROP USER 'plüg'; +CREATE USER 'plüg_dest' IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +pl??g_dest +DROP USER 'plüg_dest'; +SET NAMES latin1; +========== test 1.1.1.5 ==================================== +CREATE USER 'plüg' IDENTIFIED WITH 'test_plügin_server' AS 'plüg_dest'; +ERROR HY000: Plugin 'test_plügin_server' is not loaded +CREATE USER 'plug' IDENTIFIED WITH 'test_plugin_server' AS 'plüg_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plüg_dest +DROP USER 'plug'; +CREATE USER 'plüg_dest' IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plüg_dest +DROP USER 'plüg_dest'; +SET NAMES utf8; +CREATE USER plüg IDENTIFIED WITH 'test_plügin_server' AS 'plüg_dest'; +ERROR HY000: Plugin 'test_plügin_server' is not loaded +CREATE USER 'plüg' IDENTIFIED WITH 'test_plugin_server' AS 'plüg_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plüg test_plugin_server plüg_dest +DROP USER 'plüg'; +CREATE USER 'plüg_dest' IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plüg_dest +DROP USER 'plüg_dest'; +CREATE USER plüg IDENTIFIED WITH test_plugin_server AS 'plüg_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plüg test_plugin_server plüg_dest +DROP USER plüg; +CREATE USER plüg_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plüg_dest +DROP USER plüg_dest; +========== test 1.1.1.2/1.1.2.2============================= +SET @auth_name= 'test_plugin_server'; +CREATE USER plug IDENTIFIED WITH @auth_name AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@auth_name AS 'plug_dest'' at line 1 +SET @auth_string= 'plug_dest'; +CREATE USER plug IDENTIFIED WITH test_plugin_server AS @auth_string; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@auth_string' at line 1 +========== test 1.1.1.3/1.1.2.3============================= +CREATE USER plug IDENTIFIED WITH 'hh''s_test_plugin_server' AS 'plug_dest'; +ERROR HY000: Plugin 'hh's_test_plugin_server' is not loaded +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'hh''s_plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server hh's_plug_dest +DROP USER plug; +CREATE USER 'hh''s_plug_dest' IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +hh's_plug_dest +DROP USER 'hh''s_plug_dest'; +========== test 1.1.1.4 ==================================== +CREATE USER plug IDENTIFIED WITH hh''s_test_plugin_server AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''s_test_plugin_server AS 'plug_dest'' at line 1 +========== test 1.1.3.1 ==================================== +GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +grant_user test_plugin_server plug_dest +CREATE USER plug_dest; +DROP USER plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +grant_user test_plugin_server plug_dest +plug_dest +DROP USER grant_user,plug_dest; +set @save_sql_mode= @@sql_mode; +SET @@sql_mode=no_auto_create_user; +GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +grant_user test_plugin_server plug_dest +CREATE USER plug_dest; +DROP USER plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest; +ERROR 42000: Can't find any matching row in the user table +DROP USER grant_user; +GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +grant_user test_plugin_server plug_dest +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +grant_user test_plugin_server plug_dest +plug_dest *939AEE68989794C0F408277411C26055CDF41119 +DROP USER plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_user_passwd'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +grant_user test_plugin_server plug_dest +plug_dest *560881EB651416CEF77314D07D55EDCD5FC1BD6D +DROP USER grant_user,plug_dest; +set @@sql_mode= @save_sql_mode; +DROP DATABASE test_user_db; diff --git a/mysql-test/r/plugin_auth_qa_1.result b/mysql-test/r/plugin_auth_qa_1.result new file mode 100644 index 00000000000..00ee47b56b3 --- /dev/null +++ b/mysql-test/r/plugin_auth_qa_1.result @@ -0,0 +1,335 @@ +CREATE DATABASE test_user_db; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +========== test 1.1.3.2 ==================================== +CREATE USER plug_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +current_user() +plug_dest@% +user() +plug_user@localhost +Tables_in_test_user_db +t1 +REVOKE PROXY ON plug_dest FROM plug_user; +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +DROP USER plug_user,plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug_dest +plug_user test_plugin_server plug_dest +1) +current_user() +plug_dest@% +user() +plug_user@localhost +Tables_in_test_user_db +t1 +REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +2) +current_user() +plug_dest@% +user() +plug_user@localhost +Tables_in_test_user_db +t1 +REVOKE PROXY ON plug_dest FROM plug_user; +3) +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +DROP USER plug_user,plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +1) +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +GRANT PROXY ON plug_dest TO plug_user; +2) +current_user() +plug_dest@% +user() +plug_user@localhost +Tables_in_test_user_db +t1 +REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +DROP USER plug_user,plug_dest; +========== test 1.2 ======================================== +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +current_user() +plug_dest@% +user() +plug_user@localhost +RENAME USER plug_dest TO new_dest; +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +GRANT PROXY ON new_dest TO plug_user; +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_dest +plug_user test_plugin_server plug_dest +DROP USER plug_user,new_dest; +CREATE USER plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +GRANT PROXY ON plug_dest TO plug_user; +current_user() +plug_dest@% +user() +plug_user@localhost +RENAME USER plug_dest TO new_dest; +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +GRANT PROXY ON new_dest TO plug_user; +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_dest +plug_user test_plugin_server plug_dest +DROP USER plug_user,new_dest; +CREATE USER plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +connect(plug_user,localhost,plug_user,plug_dest); +select USER(),CURRENT_USER(); +USER() CURRENT_USER() +plug_user@localhost plug_dest@% +connection default; +disconnect plug_user; +RENAME USER plug_user TO new_user; +connect(plug_user,localhost,new_user,plug_dest); +select USER(),CURRENT_USER(); +USER() CURRENT_USER() +new_user@localhost plug_dest@% +connection default; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_user test_plugin_server plug_dest +plug_dest +disconnect plug_user; +UPDATE mysql.user SET user='plug_user' WHERE user='new_user'; +FLUSH PRIVILEGES; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug_dest +plug_user test_plugin_server plug_dest +DROP USER plug_dest,plug_user; +========== test 1.3 ======================================== +CREATE USER plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +connect(plug_user,localhost,plug_user,plug_dest); +select USER(),CURRENT_USER(); +USER() CURRENT_USER() +plug_user@localhost plug_dest@% +connection default; +disconnect plug_user; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug_dest +plug_user test_plugin_server plug_dest +UPDATE mysql.user SET user='new_user' WHERE user='plug_user'; +FLUSH PRIVILEGES; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_user test_plugin_server plug_dest +plug_dest +UPDATE mysql.user SET authentication_string='new_dest' WHERE user='new_user'; +FLUSH PRIVILEGES; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_user test_plugin_server new_dest +plug_dest +UPDATE mysql.user SET plugin='new_plugin_server' WHERE user='new_user'; +FLUSH PRIVILEGES; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_user new_plugin_server new_dest +plug_dest +connect(plug_user,localhost,new_user,new_dest); +ERROR HY000: Plugin 'new_plugin_server' is not loaded +UPDATE mysql.user SET plugin='test_plugin_server' WHERE user='new_user'; +UPDATE mysql.user SET USER='new_dest' WHERE user='plug_dest'; +FLUSH PRIVILEGES; +GRANT PROXY ON new_dest TO new_user; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_dest +new_user test_plugin_server new_dest +connect(plug_user,localhost,new_user,new_dest); +select USER(),CURRENT_USER(); +USER() CURRENT_USER() +new_user@localhost new_dest@% +connection default; +disconnect plug_user; +UPDATE mysql.user SET USER='plug_dest' WHERE user='new_dest'; +FLUSH PRIVILEGES; +CREATE USER new_dest IDENTIFIED BY 'new_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_dest +new_user test_plugin_server new_dest +plug_dest +GRANT ALL PRIVILEGES ON test.* TO new_user; +connect(plug_user,localhost,new_dest,new_dest_passwd); +select USER(),CURRENT_USER(); +USER() CURRENT_USER() +new_dest@localhost new_dest@% +connection default; +disconnect plug_user; +DROP USER new_user,new_dest,plug_dest; +========== test 2, 2.1, 2.2 ================================ +CREATE USER ''@'' IDENTIFIED WITH test_plugin_server AS 'proxied_user'; +CREATE USER proxied_user IDENTIFIED BY 'proxied_user_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string + test_plugin_server proxied_user +proxied_user +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user@localhost proxied_user@% +========== test 2.2.1 ====================================== +SELECT @@proxy_user; +@@proxy_user +NULL +connection default; +disconnect proxy_con; +connect(proxy_con,localhost,proxy_user,proxied_user); +ERROR 28000: Access denied for user 'proxy_user'@'localhost' (using password: YES) +GRANT PROXY ON proxied_user TO ''@''; +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user@localhost proxied_user@% +connection default; +disconnect proxy_con; +connect(proxy_con,localhost,proxy_user,proxied_user); +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxy_user@localhost proxied_user@% +========== test 2.2.1 ====================================== +SELECT @@proxy_user; +@@proxy_user +''@'' +connection default; +disconnect proxy_con; +DROP USER ''@'',proxied_user; +GRANT ALL PRIVILEGES ON test_user_db.* TO ''@'' +IDENTIFIED WITH test_plugin_server AS 'proxied_user'; +CREATE USER proxied_user IDENTIFIED BY 'proxied_user_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string + test_plugin_server proxied_user +proxied_user +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user@localhost proxied_user@% +SELECT @@proxy_user; +@@proxy_user +NULL +connection default; +disconnect proxy_con; +connect(proxy_con,localhost,proxy_user,proxied_user); +ERROR 28000: Access denied for user 'proxy_user'@'localhost' (using password: YES) +GRANT PROXY ON proxied_user TO ''@''; +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user@localhost proxied_user@% +connection default; +disconnect proxy_con; +connect(proxy_con,localhost,proxy_user,proxied_user); +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxy_user@localhost proxied_user@% +SELECT @@proxy_user; +@@proxy_user +''@'' +connection default; +disconnect proxy_con; +DROP USER ''@'',proxied_user; +CREATE USER ''@'' IDENTIFIED WITH test_plugin_server AS 'proxied_user'; +CREATE USER proxied_user_1 IDENTIFIED BY 'proxied_user_1_pwd'; +CREATE USER proxied_user_2 IDENTIFIED BY 'proxied_user_2_pwd'; +CREATE USER proxied_user_3 IDENTIFIED BY 'proxied_user_3_pwd'; +CREATE USER proxied_user_4 IDENTIFIED BY 'proxied_user_4_pwd'; +CREATE USER proxied_user_5 IDENTIFIED BY 'proxied_user_5_pwd'; +GRANT PROXY ON proxied_user_1 TO ''@''; +GRANT PROXY ON proxied_user_2 TO ''@''; +GRANT PROXY ON proxied_user_3 TO ''@''; +GRANT PROXY ON proxied_user_4 TO ''@''; +GRANT PROXY ON proxied_user_5 TO ''@''; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string + test_plugin_server proxied_user +proxied_user_1 +proxied_user_2 +proxied_user_3 +proxied_user_4 +proxied_user_5 +connect(proxy_con_1,localhost,proxied_user_1,'proxied_user_1_pwd'); +connect(proxy_con_2,localhost,proxied_user_2,proxied_user_2_pwd); +connect(proxy_con_3,localhost,proxied_user_3,proxied_user_3_pwd); +connect(proxy_con_4,localhost,proxied_user_4,proxied_user_4_pwd); +connect(proxy_con_5,localhost,proxied_user_5,proxied_user_5_pwd); +connection proxy_con_1; +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user_1@localhost proxied_user_1@% +SELECT @@proxy_user; +@@proxy_user +NULL +connection proxy_con_2; +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user_2@localhost proxied_user_2@% +SELECT @@proxy_user; +@@proxy_user +NULL +connection proxy_con_3; +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user_3@localhost proxied_user_3@% +SELECT @@proxy_user; +@@proxy_user +NULL +connection proxy_con_4; +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user_4@localhost proxied_user_4@% +SELECT @@proxy_user; +@@proxy_user +NULL +connection proxy_con_5; +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user_5@localhost proxied_user_5@% +SELECT @@proxy_user; +@@proxy_user +NULL +connection default; +disconnect proxy_con_1; +disconnect proxy_con_2; +disconnect proxy_con_3; +disconnect proxy_con_4; +disconnect proxy_con_5; +DROP USER ''@'',proxied_user_1,proxied_user_2,proxied_user_3,proxied_user_4,proxied_user_5; +========== test 3 ========================================== +GRANT ALL PRIVILEGES ON *.* TO plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +FLUSH PRIVILEGES; +DROP USER plug_user, plug_dest; +DROP DATABASE test_user_db; diff --git a/mysql-test/r/plugin_auth_qa_2.result b/mysql-test/r/plugin_auth_qa_2.result new file mode 100644 index 00000000000..a73cc25418c --- /dev/null +++ b/mysql-test/r/plugin_auth_qa_2.result @@ -0,0 +1,146 @@ +CREATE DATABASE test_user_db; +========== test 1.1.3.2 ==================================== +=== check contens of components of info ==================== +CREATE USER qa_test_1_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_1_dest'; +CREATE USER qa_test_1_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_1_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_1_dest TO qa_test_1_user; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +qa_test_1_dest +qa_test_1_user qa_auth_interface qa_test_1_dest +SELECT @@proxy_user; +@@proxy_user +NULL +SELECT @@external_user; +@@external_user +NULL +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +current_user() user() @@local.proxy_user @@local.external_user +qa_test_1_user@% qa_test_1_user@localhost NULL NULL +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +qa_test_1_dest +qa_test_1_user qa_auth_interface qa_test_1_dest +DROP USER qa_test_1_user; +DROP USER qa_test_1_dest; +=== Assign values to components of info ==================== +CREATE USER qa_test_2_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_2_dest'; +CREATE USER qa_test_2_dest IDENTIFIED BY 'dest_passwd'; +CREATE USER authenticated_as IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_2_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_2_dest TO qa_test_2_user; +GRANT PROXY ON authenticated_as TO qa_test_2_user; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +authenticated_as +qa_test_2_dest +qa_test_2_user qa_auth_interface qa_test_2_dest +SELECT @@proxy_user; +@@proxy_user +NULL +SELECT @@external_user; +@@external_user +NULL +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +current_user() user() @@local.proxy_user @@local.external_user +authenticated_as@% user_name@localhost 'qa_test_2_user'@'%' 'qa_test_2_user'@'%' +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +authenticated_as +qa_test_2_dest +qa_test_2_user qa_auth_interface qa_test_2_dest +DROP USER qa_test_2_user; +DROP USER qa_test_2_dest; +DROP USER authenticated_as; +=== Assign too high values for *length, which should have no effect ==== +CREATE USER qa_test_3_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_3_dest'; +CREATE USER qa_test_3_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_3_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_3_dest TO qa_test_3_user; +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +current_user() user() @@local.proxy_user @@local.external_user +qa_test_3_dest@% qa_test_3_user@localhost 'qa_test_3_user'@'%' 'qa_test_3_user'@'%' +DROP USER qa_test_3_user; +DROP USER qa_test_3_dest; +=== Assign too low values for *length, which should have no effect ==== +CREATE USER qa_test_4_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_4_dest'; +CREATE USER qa_test_4_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_4_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_4_dest TO qa_test_4_user; +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +current_user() user() @@local.proxy_user @@local.external_user +qa_test_4_dest@% qa_test_4_user@localhost 'qa_test_4_user'@'%' 'qa_test_4_user'@'%' +DROP USER qa_test_4_user; +DROP USER qa_test_4_dest; +=== Assign empty string especially to authenticated_as (in plugin) ==== +CREATE USER qa_test_5_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_5_dest'; +CREATE USER qa_test_5_dest IDENTIFIED BY 'dest_passwd'; +CREATE USER ''@'localhost' IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_5_dest identified by 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO ''@'localhost' identified by 'dest_passwd'; +GRANT PROXY ON qa_test_5_dest TO qa_test_5_user; +GRANT PROXY ON qa_test_5_dest TO ''@'localhost'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password + *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +qa_test_5_user qa_auth_interface qa_test_5_dest +qa_test_5_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +ERROR 1045 (28000): Access denied for user 'qa_test_5_user'@'localhost' (using password: YES) +DROP USER qa_test_5_user; +DROP USER qa_test_5_dest; +DROP USER ''@'localhost'; +=== Assign 'root' especially to authenticated_as (in plugin) ==== +CREATE USER qa_test_6_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; +CREATE USER qa_test_6_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_6_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_6_dest TO qa_test_6_user; +SELECT user,plugin,authentication_string,password FROM mysql.user; +user plugin authentication_string password +root +root +root +qa_test_6_user qa_auth_interface qa_test_6_dest +qa_test_6_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +ERROR 1045 (28000): Access denied for user 'qa_test_6_user'@'localhost' (using password: YES) +GRANT PROXY ON qa_test_6_dest TO root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; +SELECT user,plugin,authentication_string,password FROM mysql.user; +user plugin authentication_string password +root +root +root +qa_test_6_user qa_auth_interface qa_test_6_dest +qa_test_6_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +root qa_auth_interface qa_test_6_dest +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) +REVOKE PROXY ON qa_test_6_dest FROM root; +SELECT user,plugin,authentication_string FROM mysql.user; +user plugin authentication_string +root +root +root +qa_test_6_user qa_auth_interface qa_test_6_dest +qa_test_6_dest +root qa_auth_interface qa_test_6_dest +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) +DROP USER qa_test_6_user; +DROP USER qa_test_6_dest; +DELETE FROM mysql.user WHERE user='root' AND plugin='qa_auth_interface'; +SELECT user,plugin,authentication_string,password FROM mysql.user; +user plugin authentication_string password +root +root +root +=== Test of the --default_auth option for clients ==== +CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_11_dest'; +CREATE USER qa_test_11_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; +exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P 13000 -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +ERROR 1045 (28000): Access denied for user 'qa_test_11_user'@'localhost' (using password: YES) +DROP USER qa_test_11_user, qa_test_11_dest; +DROP DATABASE test_user_db; diff --git a/mysql-test/r/plugin_auth_qa_3.result b/mysql-test/r/plugin_auth_qa_3.result new file mode 100644 index 00000000000..92d47bcf580 --- /dev/null +++ b/mysql-test/r/plugin_auth_qa_3.result @@ -0,0 +1,11 @@ +CREATE DATABASE test_user_db; +CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_server AS 'qa_test_11_dest'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; +exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P 13000 -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +current_user() user() @@local.proxy_user @@local.external_user +qa_test_11_dest@% qa_test_11_user@localhost 'qa_test_11_user'@'%' 'qa_test_11_user'@'%' +exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P 13000 -u qa_test_2_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +ERROR 1045 (28000): Access denied for user 'qa_test_2_user'@'localhost' (using password: NO) +DROP USER qa_test_11_user, qa_test_11_dest; +DROP DATABASE test_user_db; diff --git a/mysql-test/t/plugin_auth_qa-master.opt b/mysql-test/t/plugin_auth_qa-master.opt new file mode 100644 index 00000000000..3536d102387 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa-master.opt @@ -0,0 +1,2 @@ +$PLUGIN_AUTH_OPT +$PLUGIN_AUTH_LOAD diff --git a/mysql-test/t/plugin_auth_qa.test b/mysql-test/t/plugin_auth_qa.test new file mode 100644 index 00000000000..0961c1dfef5 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa.test @@ -0,0 +1,338 @@ +# The numbers represent test cases of the test plan. + +--source include/have_plugin_auth.inc +--source include/not_embedded.inc + +CREATE DATABASE test_user_db; + +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo ========== test 1.1 ====================================================== +# without '', without AS part +CREATE USER plug IDENTIFIED WITH test_plugin_server; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +REVOKE ALL PRIVILEGES ON test_user_db.* FROM plug; +DROP USER plug; +# with '', without AS part +CREATE USER plug IDENTIFIED WITH 'test_plugin_server'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +REVOKE ALL PRIVILEGES ON test_user_db.* FROM plug; +DROP USER plug; +# without '', AS part empty +CREATE USER plug IDENTIFIED WITH test_plugin_server AS ''; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS ''; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +REVOKE ALL PRIVILEGES ON test_user_db.* FROM plug; +DROP USER plug; +# with '', AS part empty without '' +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS ; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS; +# without '', AS part without '' +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH test_plugin_server AS plug_dest; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS plug_dest; +--echo ========== test 1.1 syntax errors ======================================== +# without auth_name +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH AS plug_dest; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH AS plug_dest; +# without auth_name and AS part +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH; +# without auth_name but AS part +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED AS ''; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED AS ''; +# with 2 auth_name parts +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' IDENTIFIED WITH 'test_plugin_server'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug + IDENTIFIED WITH 'test_plugin_server' IDENTIFIED WITH 'test_plugin_server'; +# with 2 AS parts +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS '' AS 'plug_dest'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug AS '' AS 'plug_dest'; +# with 2 complete WITH parts +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS '' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS '' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +# with BY and WITH part +--error ER_PARSE_ERROR +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd' + IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED BY 'plug_dest_passwd' + IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +# with WITH part and BY part +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + USER plug_dest IDENTIFIED by 'plug_dest_pwd'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + USER plug_dest IDENTIFIED by 'plug_dest_pwd'; +# with WITH part and BY part +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + plug_dest IDENTIFIED by 'plug_dest_pwd'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + plug_dest IDENTIFIED by 'plug_dest_pwd'; +# with WITH part and BY part +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + IDENTIFIED by 'plug_dest_pwd'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + IDENTIFIED by 'plug_dest_pwd'; + +--echo ========== test 1.1 combinations ========================== +# CREATE...WITH/CREATE...BY +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--echo ========== test 1.1.1.6/1.1.2.5 ============================ +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug, plug_dest; +# +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug_dest; +# GRANT...WITH/CREATE...BY +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug, plug_dest; +# +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug_dest; +# CREATE...WITH/GRANT...BY +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug, plug_dest; +# +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug_dest; +# +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--error 1700 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--error 1700 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server'; +DROP USER plug; +# +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--error ER_CANNOT_USER +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--error ER_CANNOT_USER +CREATE USER plug IDENTIFIED WITH 'test_plugin_server'; +DROP USER plug; +# +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +DROP USER plug; +# +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--error ER_CANNOT_USER +CREATE USER plug IDENTIFIED BY 'plug_dest_passwd'; +DROP USER plug; +# +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +DROP USER plug,plug_dest; +# +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +DROP USER plug,plug_dest; +# + +--echo ========== test 1.1.1.1/1.1.2.1/1.1.1.5 ==================== + +SET NAMES utf8; +# +CREATE USER plüg IDENTIFIED WITH 'test_plugin_server' AS 'plüg_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plüg; +CREATE USER plüg_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plüg_dest; + +SET NAMES ascii; +# +CREATE USER 'plüg' IDENTIFIED WITH 'test_plugin_server' AS 'plüg_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'plüg'; +CREATE USER 'plüg_dest' IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'plüg_dest'; + +SET NAMES latin1; +# +--echo ========== test 1.1.1.5 ==================================== +--error ER_PLUGIN_IS_NOT_LOADED +CREATE USER 'plüg' IDENTIFIED WITH 'test_plügin_server' AS 'plüg_dest'; +CREATE USER 'plug' IDENTIFIED WITH 'test_plugin_server' AS 'plüg_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'plug'; +CREATE USER 'plüg_dest' IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'plüg_dest'; + +SET NAMES utf8; +# +--error ER_PLUGIN_IS_NOT_LOADED +CREATE USER plüg IDENTIFIED WITH 'test_plügin_server' AS 'plüg_dest'; +CREATE USER 'plüg' IDENTIFIED WITH 'test_plugin_server' AS 'plüg_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'plüg'; +CREATE USER 'plüg_dest' IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'plüg_dest'; + +CREATE USER plüg IDENTIFIED WITH test_plugin_server AS 'plüg_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plüg; +CREATE USER plüg_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plüg_dest; + +--echo ========== test 1.1.1.2/1.1.2.2============================= + +SET @auth_name= 'test_plugin_server'; +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH @auth_name AS 'plug_dest'; + +SET @auth_string= 'plug_dest'; +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH test_plugin_server AS @auth_string; + +--echo ========== test 1.1.1.3/1.1.2.3============================= + +--error ER_PLUGIN_IS_NOT_LOADED +CREATE USER plug IDENTIFIED WITH 'hh''s_test_plugin_server' AS 'plug_dest'; + +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'hh''s_plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +CREATE USER 'hh''s_plug_dest' IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'hh''s_plug_dest'; + +--echo ========== test 1.1.1.4 ==================================== + +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH hh''s_test_plugin_server AS 'plug_dest'; + +--echo ========== test 1.1.3.1 ==================================== + +GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +CREATE USER plug_dest; +DROP USER plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER grant_user,plug_dest; +# +set @save_sql_mode= @@sql_mode; +SET @@sql_mode=no_auto_create_user; +GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +CREATE USER plug_dest; +DROP USER plug_dest; +--error ER_PASSWORD_NO_MATCH +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest; +DROP USER grant_user; +# +GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +DROP USER plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_user_passwd'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +DROP USER grant_user,plug_dest; +set @@sql_mode= @save_sql_mode; +# +DROP DATABASE test_user_db; +--exit + diff --git a/mysql-test/t/plugin_auth_qa_1-master.opt b/mysql-test/t/plugin_auth_qa_1-master.opt new file mode 100644 index 00000000000..3536d102387 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa_1-master.opt @@ -0,0 +1,2 @@ +$PLUGIN_AUTH_OPT +$PLUGIN_AUTH_LOAD diff --git a/mysql-test/t/plugin_auth_qa_1.test b/mysql-test/t/plugin_auth_qa_1.test new file mode 100644 index 00000000000..d7a7afe9407 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa_1.test @@ -0,0 +1,334 @@ +# The numbers represent test cases of the test plan. + +--source include/have_plugin_auth.inc +--source include/not_embedded.inc + +CREATE DATABASE test_user_db; + +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; + +--echo ========== test 1.1.3.2 ==================================== + +# CREATE...WITH/CREATE...BY/GRANT +CREATE USER plug_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +REVOKE PROXY ON plug_dest FROM plug_user; +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +DROP USER plug_user,plug_dest; +# +# GRANT...WITH +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; + +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo 1) +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--echo 2) +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +REVOKE PROXY ON plug_dest FROM plug_user; +--echo 3) +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +DROP USER plug_user,plug_dest; +# +# GRANT...WITH/CREATE...BY +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--echo 1) +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +GRANT PROXY ON plug_dest TO plug_user; +--echo 2) +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +#REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_dest' +# IDENTIFIED BY 'plug_dest_passwd'; +DROP USER plug_user,plug_dest; + +--echo ========== test 1.2 ======================================== + +# GRANT...WITH/CREATE...BY +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +RENAME USER plug_dest TO new_dest; +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +GRANT PROXY ON new_dest TO plug_user; +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=new_dest -e "SELECT current_user();SELECT user();" 2>&1 +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug_user,new_dest; + +# CREATE...WITH/CREATE...BY +CREATE USER plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +GRANT PROXY ON plug_dest TO plug_user; +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +RENAME USER plug_dest TO new_dest; +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +GRANT PROXY ON new_dest TO plug_user; +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=new_dest -e "SELECT current_user();SELECT user();" 2>&1 +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug_user,new_dest; +# CREATE...WITH +CREATE USER plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +--echo connect(plug_user,localhost,plug_user,plug_dest); +connect(plug_user,localhost,plug_user,plug_dest); +select USER(),CURRENT_USER(); +--echo connection default; +connection default; +--echo disconnect plug_user; +disconnect plug_user; +RENAME USER plug_user TO new_user; +--echo connect(plug_user,localhost,new_user,plug_dest); +connect(plug_user,localhost,new_user,plug_dest); +select USER(),CURRENT_USER(); +--echo connection default; +connection default; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo disconnect plug_user; +disconnect plug_user; +UPDATE mysql.user SET user='plug_user' WHERE user='new_user'; +FLUSH PRIVILEGES; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug_dest,plug_user; +--echo ========== test 1.3 ======================================== + +# +CREATE USER plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +--echo connect(plug_user,localhost,plug_user,plug_dest); +connect(plug_user,localhost,plug_user,plug_dest); +select USER(),CURRENT_USER(); +--echo connection default; +connection default; +--echo disconnect plug_user; +disconnect plug_user; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +UPDATE mysql.user SET user='new_user' WHERE user='plug_user'; +FLUSH PRIVILEGES; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +UPDATE mysql.user SET authentication_string='new_dest' WHERE user='new_user'; +FLUSH PRIVILEGES; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +UPDATE mysql.user SET plugin='new_plugin_server' WHERE user='new_user'; +FLUSH PRIVILEGES; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo connect(plug_user,localhost,new_user,new_dest); +--disable_query_log +--error ER_PLUGIN_IS_NOT_LOADED +connect(plug_user,localhost,new_user,new_dest); +--enable_query_log +UPDATE mysql.user SET plugin='test_plugin_server' WHERE user='new_user'; +UPDATE mysql.user SET USER='new_dest' WHERE user='plug_dest'; +FLUSH PRIVILEGES; +GRANT PROXY ON new_dest TO new_user; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo connect(plug_user,localhost,new_user,new_dest); +connect(plug_user,localhost,new_user,new_dest); +select USER(),CURRENT_USER(); +--echo connection default; +connection default; +--echo disconnect plug_user; +disconnect plug_user; +UPDATE mysql.user SET USER='plug_dest' WHERE user='new_dest'; +FLUSH PRIVILEGES; +CREATE USER new_dest IDENTIFIED BY 'new_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +GRANT ALL PRIVILEGES ON test.* TO new_user; +--echo connect(plug_user,localhost,new_dest,new_dest_passwd); +connect(plug_user,localhost,new_dest,new_dest_passwd); +select USER(),CURRENT_USER(); +--echo connection default; +connection default; +--echo disconnect plug_user; +disconnect plug_user; +DROP USER new_user,new_dest,plug_dest; + +--echo ========== test 2, 2.1, 2.2 ================================ + +CREATE USER ''@'' IDENTIFIED WITH test_plugin_server AS 'proxied_user'; +CREATE USER proxied_user IDENTIFIED BY 'proxied_user_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +--echo ========== test 2.2.1 ====================================== +SELECT @@proxy_user; +--echo connection default; +connection default; +--echo disconnect proxy_con; +disconnect proxy_con; +--echo connect(proxy_con,localhost,proxy_user,proxied_user); +--disable_query_log +--error ER_ACCESS_DENIED_ERROR : this should fail : no grant +connect(proxy_con,localhost,proxy_user,proxied_user); +--enable_query_log +GRANT PROXY ON proxied_user TO ''@''; +--echo connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +--echo connection default; +connection default; +--echo disconnect proxy_con; +disconnect proxy_con; +--echo connect(proxy_con,localhost,proxy_user,proxied_user); +connect(proxy_con,localhost,proxy_user,proxied_user); +SELECT USER(),CURRENT_USER(); +--echo ========== test 2.2.1 ====================================== +SELECT @@proxy_user; +--echo connection default; +connection default; +--echo disconnect proxy_con; +disconnect proxy_con; +DROP USER ''@'',proxied_user; +# +GRANT ALL PRIVILEGES ON test_user_db.* TO ''@'' + IDENTIFIED WITH test_plugin_server AS 'proxied_user'; +CREATE USER proxied_user IDENTIFIED BY 'proxied_user_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection default; +connection default; +--echo disconnect proxy_con; +disconnect proxy_con; +--echo connect(proxy_con,localhost,proxy_user,proxied_user); +--disable_query_log +--error ER_ACCESS_DENIED_ERROR : this should fail : no grant +connect(proxy_con,localhost,proxy_user,proxied_user); +--enable_query_log +GRANT PROXY ON proxied_user TO ''@''; +--echo connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +--echo connection default; +connection default; +--echo disconnect proxy_con; +disconnect proxy_con; +--echo connect(proxy_con,localhost,proxy_user,proxied_user); +connect(proxy_con,localhost,proxy_user,proxied_user); +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection default; +connection default; +--echo disconnect proxy_con; +disconnect proxy_con; +DROP USER ''@'',proxied_user; +# +CREATE USER ''@'' IDENTIFIED WITH test_plugin_server AS 'proxied_user'; +CREATE USER proxied_user_1 IDENTIFIED BY 'proxied_user_1_pwd'; +CREATE USER proxied_user_2 IDENTIFIED BY 'proxied_user_2_pwd'; +CREATE USER proxied_user_3 IDENTIFIED BY 'proxied_user_3_pwd'; +CREATE USER proxied_user_4 IDENTIFIED BY 'proxied_user_4_pwd'; +CREATE USER proxied_user_5 IDENTIFIED BY 'proxied_user_5_pwd'; +GRANT PROXY ON proxied_user_1 TO ''@''; +GRANT PROXY ON proxied_user_2 TO ''@''; +GRANT PROXY ON proxied_user_3 TO ''@''; +GRANT PROXY ON proxied_user_4 TO ''@''; +GRANT PROXY ON proxied_user_5 TO ''@''; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo connect(proxy_con_1,localhost,proxied_user_1,'proxied_user_1_pwd'); +connect(proxy_con_1,localhost,proxied_user_1,'proxied_user_1_pwd'); +--echo connect(proxy_con_2,localhost,proxied_user_2,proxied_user_2_pwd); +connect(proxy_con_2,localhost,proxied_user_2,proxied_user_2_pwd); +--echo connect(proxy_con_3,localhost,proxied_user_3,proxied_user_3_pwd); +connect(proxy_con_3,localhost,proxied_user_3,proxied_user_3_pwd); +--echo connect(proxy_con_4,localhost,proxied_user_4,proxied_user_4_pwd); +connect(proxy_con_4,localhost,proxied_user_4,proxied_user_4_pwd); +--echo connect(proxy_con_5,localhost,proxied_user_5,proxied_user_5_pwd); +connect(proxy_con_5,localhost,proxied_user_5,proxied_user_5_pwd); +--echo connection proxy_con_1; +connection proxy_con_1; +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection proxy_con_2; +connection proxy_con_2; +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection proxy_con_3; +connection proxy_con_3; +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection proxy_con_4; +connection proxy_con_4; +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection proxy_con_5; +connection proxy_con_5; +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection default; +connection default; +--echo disconnect proxy_con_1; +disconnect proxy_con_1; +--echo disconnect proxy_con_2; +disconnect proxy_con_2; +--echo disconnect proxy_con_3; +disconnect proxy_con_3; +--echo disconnect proxy_con_4; +disconnect proxy_con_4; +--echo disconnect proxy_con_5; +disconnect proxy_con_5; +DROP USER ''@'',proxied_user_1,proxied_user_2,proxied_user_3,proxied_user_4,proxied_user_5; + +--echo ========== test 3 ========================================== + +GRANT ALL PRIVILEGES ON *.* TO plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +FLUSH PRIVILEGES; + +# Not working with the patch. + +#--replace_result $MYSQLADMIN MYSQLADMIN $MASTER_MYPORT MYPORT $MASTER_MYSOCK MYSOCK +#--exec $MYSQLADMIN $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -S $MASTER_MYSOCK -u plug_user --password=plug_dest ping 2>&1 +#--replace_result $MYSQL_CHECK MYSQL_CHECK $MASTER_MYPORT MYPORT +#--exec $MYSQL_CHECK $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u plug_user --password=plug_dest test +#--replace_result $MYSQL_DUMP MYSQL_DUMP $MASTER_MYPORT MYPORT +#--exec $MYSQL_DUMP -h localhost -P $MASTER_MYPORT $PLUGIN_AUTH_OPT -u plug_user --password=plug_dest test +#--replace_result $MYSQL_SHOW MYSQL_SHOW $MASTER_MYPORT MYPORT +#--exec $MYSQL_SHOW $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --plugin_dir=../plugin/auth -u plug_user --password=plug_dest 2>&1 +DROP USER plug_user, plug_dest; +DROP DATABASE test_user_db; +--exit diff --git a/mysql-test/t/plugin_auth_qa_2-master.opt b/mysql-test/t/plugin_auth_qa_2-master.opt new file mode 100644 index 00000000000..c29153ac95b --- /dev/null +++ b/mysql-test/t/plugin_auth_qa_2-master.opt @@ -0,0 +1,2 @@ +$PLUGIN_AUTH_OPT +$PLUGIN_AUTH_INTERFACE diff --git a/mysql-test/t/plugin_auth_qa_2.test b/mysql-test/t/plugin_auth_qa_2.test new file mode 100644 index 00000000000..053e89166b7 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa_2.test @@ -0,0 +1,148 @@ +# Horst Hunger +# Created: 2010-10-06 +# +# Test of the authentification interface. The plugin checks the expected values set +# by this application and the application checks the values set the the plugin. +--source include/have_plugin_interface.inc +--source include/not_embedded.inc + +CREATE DATABASE test_user_db; + +--echo ========== test 1.1.3.2 ==================================== +--echo === check contens of components of info ==================== + +CREATE USER qa_test_1_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_1_dest'; +CREATE USER qa_test_1_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_1_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_1_dest TO qa_test_1_user; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +SELECT @@proxy_user; +SELECT @@external_user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; + +DROP USER qa_test_1_user; +DROP USER qa_test_1_dest; + +--echo === Assign values to components of info ==================== + +CREATE USER qa_test_2_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_2_dest'; +CREATE USER qa_test_2_dest IDENTIFIED BY 'dest_passwd'; +CREATE USER authenticated_as IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_2_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_2_dest TO qa_test_2_user; +GRANT PROXY ON authenticated_as TO qa_test_2_user; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +SELECT @@proxy_user; +SELECT @@external_user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; + +DROP USER qa_test_2_user; +DROP USER qa_test_2_dest; +DROP USER authenticated_as; + +--echo === Assign too high values for *length, which should have no effect ==== + +CREATE USER qa_test_3_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_3_dest'; +CREATE USER qa_test_3_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_3_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_3_dest TO qa_test_3_user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +DROP USER qa_test_3_user; +DROP USER qa_test_3_dest; + +--echo === Assign too low values for *length, which should have no effect ==== + +CREATE USER qa_test_4_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_4_dest'; +CREATE USER qa_test_4_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_4_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_4_dest TO qa_test_4_user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +DROP USER qa_test_4_user; +DROP USER qa_test_4_dest; + +--echo === Assign empty string especially to authenticated_as (in plugin) ==== + +CREATE USER qa_test_5_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_5_dest'; +CREATE USER qa_test_5_dest IDENTIFIED BY 'dest_passwd'; +CREATE USER ''@'localhost' IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_5_dest identified by 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO ''@'localhost' identified by 'dest_passwd'; +GRANT PROXY ON qa_test_5_dest TO qa_test_5_user; +GRANT PROXY ON qa_test_5_dest TO ''@'localhost'; + +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--error 1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +DROP USER qa_test_5_user; +DROP USER qa_test_5_dest; +DROP USER ''@'localhost'; + +--echo === Assign 'root' especially to authenticated_as (in plugin) ==== + +CREATE USER qa_test_6_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; +CREATE USER qa_test_6_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_6_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_6_dest TO qa_test_6_user; + +SELECT user,plugin,authentication_string,password FROM mysql.user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--error 1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +GRANT PROXY ON qa_test_6_dest TO root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; +SELECT user,plugin,authentication_string,password FROM mysql.user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--error 1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +REVOKE PROXY ON qa_test_6_dest FROM root; +SELECT user,plugin,authentication_string FROM mysql.user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--error 1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +DROP USER qa_test_6_user; +DROP USER qa_test_6_dest; +DELETE FROM mysql.user WHERE user='root' AND plugin='qa_auth_interface'; +SELECT user,plugin,authentication_string,password FROM mysql.user; + + +--echo === Test of the --default_auth option for clients ==== + +CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_11_dest'; +CREATE USER qa_test_11_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; + +--echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--error 1 +--exec $MYSQL $PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +DROP USER qa_test_11_user, qa_test_11_dest; +DROP DATABASE test_user_db; + +--exit diff --git a/mysql-test/t/plugin_auth_qa_3-master.opt b/mysql-test/t/plugin_auth_qa_3-master.opt new file mode 100644 index 00000000000..5cc2af0a358 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa_3-master.opt @@ -0,0 +1,2 @@ +$PLUGIN_AUTH_OPT +$PLUGIN_AUTH_SERVER diff --git a/mysql-test/t/plugin_auth_qa_3.test b/mysql-test/t/plugin_auth_qa_3.test new file mode 100644 index 00000000000..4fe02f10ba6 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa_3.test @@ -0,0 +1,25 @@ +# Horst Hunger +# Created: 2010-10-06 +# +# Test of the authentification interface. The plugin checks the expected values set +# by this application and the application checks the values set the the plugin. +--source include/have_plugin_server.inc +--source include/not_embedded.inc + +CREATE DATABASE test_user_db; + +CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_server AS 'qa_test_11_dest'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; + +--echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--exec $MYSQL $PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +--echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--error 1 +--exec $MYSQL $PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +DROP USER qa_test_11_user, qa_test_11_dest; +DROP DATABASE test_user_db; + +--exit diff --git a/plugin/auth/CMakeLists.txt b/plugin/auth/CMakeLists.txt index 7d87e151143..6a9c31f82ce 100644 --- a/plugin/auth/CMakeLists.txt +++ b/plugin/auth/CMakeLists.txt @@ -18,6 +18,14 @@ MYSQL_ADD_PLUGIN(auth dialog.c MODULE_ONLY) MYSQL_ADD_PLUGIN(auth_test_plugin test_plugin.c MODULE_ONLY) +MYSQL_ADD_PLUGIN(qa_auth_interface qa_auth_interface.c + MODULE_ONLY) + +MYSQL_ADD_PLUGIN(qa_auth_server qa_auth_server.c + MODULE_ONLY) + +MYSQL_ADD_PLUGIN(qa_auth_client qa_auth_client.c + MODULE_ONLY) CHECK_CXX_SOURCE_COMPILES( "#define _GNU_SOURCE diff --git a/plugin/auth/Makefile.am b/plugin/auth/Makefile.am index ed459b7b2b1..30e185f36f7 100644 --- a/plugin/auth/Makefile.am +++ b/plugin/auth/Makefile.am @@ -3,10 +3,14 @@ pkgplugindir=$(pkglibdir)/plugin AM_LDFLAGS=-module -rpath $(pkgplugindir) AM_CPPFLAGS=-DMYSQL_DYNAMIC_PLUGIN -Wno-pointer-sign -I$(top_srcdir)/include -pkgplugin_LTLIBRARIES= auth.la auth_test_plugin.la +pkgplugin_LTLIBRARIES= auth.la auth_test_plugin.la qa_auth_interface.la qa_auth_server.la qa_auth_client.la auth_la_SOURCES= dialog.c auth_test_plugin_la_SOURCES= test_plugin.c +qa_auth_interface_la_SOURCES= qa_auth_interface.c +qa_auth_server_la_SOURCES= qa_auth_server.c +qa_auth_client_la_SOURCES= qa_auth_client.c + if HAVE_PEERCRED pkgplugin_LTLIBRARIES+= auth_socket.la auth_socket_la_SOURCES= auth_socket.c diff --git a/plugin/auth/qa_auth_client.c b/plugin/auth/qa_auth_client.c new file mode 100644 index 00000000000..da7bfc14a73 --- /dev/null +++ b/plugin/auth/qa_auth_client.c @@ -0,0 +1,127 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; version 2 of the + License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include +#include +#include +#include +#include +#include + +/** + first byte of the question string is the question "type". + It can be a "ordinary" or a "password" question. + The last bit set marks a last question in the authentication exchange. +*/ +#define ORDINARY_QUESTION "\2" +#define LAST_QUESTION "\3" +#define LAST_PASSWORD "\4" +#define PASSWORD_QUESTION "\5" + +/********************* CLIENT SIDE ***************************************/ +/* + client plugin used for testing the plugin API +*/ +#include + +/** + The main function of the test plugin. + + Reads the prompt, check if the handshake is done and if the prompt is a + password request and returns the password. Otherwise return error. + + @note + 1. this plugin shows how a client authentication plugin + may read a MySQL protocol OK packet internally - which is important + where a number of packets is not known in advance. + 2. the first byte of the prompt is special. it is not + shown to the user, but signals whether it is the last question + (prompt[0] & 1 == 1) or not last (prompt[0] & 1 == 0), + and whether the input is a password (not echoed). + 3. the prompt is expected to be sent zero-terminated +*/ +static int test_plugin_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) +{ + unsigned char *pkt, cmd= 0; + int pkt_len, res; + char *reply; + + do + { + /* read the prompt */ + pkt_len= vio->read_packet(vio, &pkt); + if (pkt_len < 0) + return CR_ERROR; + + if (pkt == 0) + { + /* + in mysql_change_user() the client sends the first packet, so + the first vio->read_packet() does nothing (pkt == 0). + + We send the "password", assuming the client knows what its doing. + (in other words, the dialog plugin should be only set as a default + authentication plugin on the client if the first question + asks for a password - which will be sent in cleat text, by the way) + */ + reply= mysql->passwd; + } + else + { + cmd= *pkt++; + + /* is it MySQL protocol (0=OK or 254=need old password) packet ? */ + if (cmd == 0 || cmd == 254) + return CR_OK_HANDSHAKE_COMPLETE; /* yes. we're done */ + + /* + asking for a password with an empty prompt means mysql->password + otherwise return an error + */ + if ((cmd == LAST_PASSWORD[0] || cmd == PASSWORD_QUESTION[0]) && *pkt == 0) + reply= mysql->passwd; + else + return CR_ERROR; + } + if (!reply) + return CR_ERROR; + /* send the reply to the server */ + res= vio->write_packet(vio, (const unsigned char *) reply, + strlen(reply) + 1); + + if (res) + return CR_ERROR; + + /* repeat unless it was the last question */ + } while (cmd != LAST_QUESTION[0] && cmd != PASSWORD_QUESTION[0]); + + /* the job of reading the ok/error packet is left to the server */ + return CR_OK; +} + + +mysql_declare_client_plugin(AUTHENTICATION) + "qa_auth_client", + "Horst Hunger", + "Dialog Client Authentication Plugin", + {0,1,0}, + "GPL", + NULL, + NULL, + NULL, + NULL, + test_plugin_client +mysql_end_client_plugin; diff --git a/plugin/auth/qa_auth_interface.c b/plugin/auth/qa_auth_interface.c new file mode 100644 index 00000000000..0aa6c9ce20c --- /dev/null +++ b/plugin/auth/qa_auth_interface.c @@ -0,0 +1,262 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; version 2 of the + License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include +#include +#include +#include +#include +#include + +/** + first byte of the question string is the question "type". + It can be a "ordinary" or a "password" question. + The last bit set marks a last question in the authentication exchange. +*/ +#define ORDINARY_QUESTION "\2" +#define LAST_QUESTION "\3" +#define LAST_PASSWORD "\4" +#define PASSWORD_QUESTION "\5" + +/********************* SERVER SIDE ****************************************/ + +static int qa_auth_interface (MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) +{ + unsigned char *pkt; + int pkt_len, err= CR_OK; + + /* send a password question */ + if (vio->write_packet(vio, (const unsigned char *) PASSWORD_QUESTION, 1)) + return CR_ERROR; + + /* read the answer */ + if ((pkt_len= vio->read_packet(vio, &pkt)) < 0) + return CR_ERROR; + + info->password_used= PASSWORD_USED_YES; + + /* fail if the password is wrong */ + if (strcmp((const char *) pkt, info->auth_string)) + return CR_ERROR; + +/* Check the contens of components of info */ + if (strcmp(info->user_name, "qa_test_1_user")== 0) + { + if (info->user_name_length != 14) + err= CR_ERROR; + if (strcmp(info->auth_string, "qa_test_1_dest")) + err= CR_ERROR; + if (info->auth_string_length != 14) + err= CR_ERROR; +/* To be set by the plugin */ +// if (strcmp(info->authenticated_as, "qa_test_1_user")) +// err= CR_ERROR; +/* To be set by the plugin */ +// if (strcmp(info->external_user, "")) +// err= CR_ERROR; + if (info->password_used != PASSWORD_USED_YES) + err= CR_ERROR; + if (strcmp(info->host_or_ip, "localhost")) + err= CR_ERROR; + if (info->host_or_ip_length != 9) + err= CR_ERROR; + } +/* Assign values to the components of info even if not intended and watch the effect */ + else if (strcmp(info->user_name, "qa_test_2_user")== 0) + { + /* Overwriting not intended, but with effect on USER() */ + strcpy(info->user_name, "user_name"); + info->user_name_length= 9; + /* Overwriting not intended, effect not visible */ + strcpy((char *)info->auth_string, "auth_string"); + info->auth_string_length= 11; + /* Assign with account for authorization, effect on CURRENT_USER() */ + strcpy(info->authenticated_as, "authenticated_as"); + /* Assign with an external account, effect on @@local.EXTERNAL_USER */ + strcpy(info->external_user, "externaluser"); + /* Overwriting will cause a core dump */ +// strcpy(info->host_or_ip, "host_or_ip"); +// info->host_or_ip_length= 10; + } +/* Invalid, means too high values for length */ + else if (strcmp(info->user_name, "qa_test_3_user")== 0) + { +/* Original value is 14. Test runs also with higher value. Changes have no effect.*/ + info->user_name_length= 28; + strcpy((char *)info->auth_string, "qa_test_3_dest"); +/* Original value is 14. Test runs also with higher value. Changes have no effect.*/ + info->auth_string_length= 28; + strcpy(info->authenticated_as, info->auth_string); + strcpy(info->external_user, info->auth_string); + } +/* Invalid, means too low values for length */ + else if (strcmp(info->user_name, "qa_test_4_user")== 0) + { +/* Original value is 14. Test runs also with lower value. Changes have no effect.*/ + info->user_name_length= 8; + strcpy((char *)info->auth_string, "qa_test_4_dest"); +/* Original value is 14. Test runs also with lower value. Changes have no effect.*/ + info->auth_string_length= 8; + strcpy(info->authenticated_as, info->auth_string); + strcpy(info->external_user, info->auth_string); + } +/* Overwrite with empty values */ + else if (strcmp(info->user_name, "qa_test_5_user")== 0) + { +/* This assignment has no effect.*/ + strcpy(info->user_name, ""); + info->user_name_length= 0; +/* This assignment has no effect.*/ + strcpy((char *)info->auth_string, ""); + info->auth_string_length= 0; +/* This assignment caused an error or an "empty" user */ + strcpy(info->authenticated_as, ""); +/* This assignment has no effect.*/ + strcpy(info->external_user, ""); + /* Overwriting will cause a core dump */ +// strcpy(info->host_or_ip, ""); +// info->host_or_ip_length= 0; + } +/* Set to 'root' */ + else if (strcmp(info->user_name, "qa_test_6_user")== 0) + { + strcpy(info->authenticated_as, "root"); + } + else + { + err= CR_ERROR; + } + return err; +} + +static struct st_mysql_auth qa_auth_test_handler= +{ + MYSQL_AUTHENTICATION_INTERFACE_VERSION, + "qa_auth_interface", /* requires test_plugin client's plugin */ + qa_auth_interface +}; + +mysql_declare_plugin(test_plugin) +{ + MYSQL_AUTHENTICATION_PLUGIN, + &qa_auth_test_handler, + "qa_auth_interface", + "Horst Hunger", + "plugin API test plugin", + PLUGIN_LICENSE_GPL, + NULL, + NULL, + 0x0100, + NULL, + NULL, + NULL +} +mysql_declare_plugin_end; + +/********************* CLIENT SIDE ***************************************/ +/* + client plugin used for testing the plugin API +*/ +#include + +/** + The main function of the test plugin. + + Reads the prompt, check if the handshake is done and if the prompt is a + password request and returns the password. Otherwise return error. + + @note + 1. this plugin shows how a client authentication plugin + may read a MySQL protocol OK packet internally - which is important + where a number of packets is not known in advance. + 2. the first byte of the prompt is special. it is not + shown to the user, but signals whether it is the last question + (prompt[0] & 1 == 1) or not last (prompt[0] & 1 == 0), + and whether the input is a password (not echoed). + 3. the prompt is expected to be sent zero-terminated +*/ +static int test_plugin_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) +{ + unsigned char *pkt, cmd= 0; + int pkt_len, res; + char *reply; + + do + { + /* read the prompt */ + pkt_len= vio->read_packet(vio, &pkt); + if (pkt_len < 0) + return CR_ERROR; + + if (pkt == 0) + { + /* + in mysql_change_user() the client sends the first packet, so + the first vio->read_packet() does nothing (pkt == 0). + + We send the "password", assuming the client knows what its doing. + (in other words, the dialog plugin should be only set as a default + authentication plugin on the client if the first question + asks for a password - which will be sent in cleat text, by the way) + */ + reply= mysql->passwd; + } + else + { + cmd= *pkt++; + + /* is it MySQL protocol (0=OK or 254=need old password) packet ? */ + if (cmd == 0 || cmd == 254) + return CR_OK_HANDSHAKE_COMPLETE; /* yes. we're done */ + + /* + asking for a password with an empty prompt means mysql->password + otherwise return an error + */ + if ((cmd == LAST_PASSWORD[0] || cmd == PASSWORD_QUESTION[0]) && *pkt == 0) + reply= mysql->passwd; + else + return CR_ERROR; + } + if (!reply) + return CR_ERROR; + /* send the reply to the server */ + res= vio->write_packet(vio, (const unsigned char *) reply, + strlen(reply) + 1); + + if (res) + return CR_ERROR; + + /* repeat unless it was the last question */ + } while (cmd != LAST_QUESTION[0] && cmd != PASSWORD_QUESTION[0]); + + /* the job of reading the ok/error packet is left to the server */ + return CR_OK; +} + + +mysql_declare_client_plugin(AUTHENTICATION) + "qa_auth_interface", + "Horst Hunger", + "Dialog Client Authentication Plugin", + {0,1,0}, + "GPL", + NULL, + NULL, + NULL, + NULL, + test_plugin_client +mysql_end_client_plugin; diff --git a/plugin/auth/qa_auth_server.c b/plugin/auth/qa_auth_server.c new file mode 100644 index 00000000000..17171610200 --- /dev/null +++ b/plugin/auth/qa_auth_server.c @@ -0,0 +1,87 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; version 2 of the + License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include +#include +#include +#include +#include +#include + +/** + first byte of the question string is the question "type". + It can be a "ordinary" or a "password" question. + The last bit set marks a last question in the authentication exchange. +*/ +#define ORDINARY_QUESTION "\2" +#define LAST_QUESTION "\3" +#define LAST_PASSWORD "\4" +#define PASSWORD_QUESTION "\5" + +/********************* SERVER SIDE ****************************************/ + +static int qa_auth_interface (MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) +{ + unsigned char *pkt; + int pkt_len, err= CR_OK; + + /* send a password question */ + if (vio->write_packet(vio, (const unsigned char *) PASSWORD_QUESTION, 1)) + return CR_ERROR; + + /* read the answer */ + if ((pkt_len= vio->read_packet(vio, &pkt)) < 0) + return CR_ERROR; + + info->password_used= PASSWORD_USED_YES; + + /* fail if the password is wrong */ + if (strcmp((const char *) pkt, info->auth_string)) + return CR_ERROR; + +/* Test of default_auth */ + if (strcmp(info->user_name, "qa_test_11_user")== 0) + { + strcpy(info->authenticated_as, "qa_test_11_dest"); + } + else + err= CR_ERROR; + return err; +} + +static struct st_mysql_auth qa_auth_test_handler= +{ + MYSQL_AUTHENTICATION_INTERFACE_VERSION, + "qa_auth_interface", /* requires test_plugin client's plugin */ + qa_auth_interface +}; + +mysql_declare_plugin(test_plugin) +{ + MYSQL_AUTHENTICATION_PLUGIN, + &qa_auth_test_handler, + "qa_auth_server", + "Horst Hunger", + "plugin API test plugin", + PLUGIN_LICENSE_GPL, + NULL, + NULL, + 0x0100, + NULL, + NULL, + NULL +} +mysql_declare_plugin_end; From 3e9c52250a3ab6664c53ea6b3923acfbe8e09e4e Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 20 Oct 2010 16:21:40 -0200 Subject: [PATCH 113/151] Bug#45288: pb2 returns a lot of compilation warnings Fix assorted warnings that are generated in optimized builds. Most of it is silencing variables that are set but unused. This patch also introduces the MY_ASSERT_UNREACHABLE macro which helps the compiler to deduce that a certain piece of code is unreachable. include/my_compiler.h: Use GCC's __builtin_unreachable if available. It allows GCC to deduce the unreachability of certain code paths, thus avoiding warnings that, for example, accused that a variable could be used without being initialized (due to unreachable code paths). --- client/mysqltest.cc | 22 ++++++++++++++-------- cmd-line-utils/readline/complete.c | 7 ++++++- cmd-line-utils/readline/histexpand.c | 3 +-- cmd-line-utils/readline/histfile.c | 1 + cmd-line-utils/readline/isearch.c | 8 ++++---- cmd-line-utils/readline/parens.c | 4 ++-- cmd-line-utils/readline/readline.c | 3 +-- cmd-line-utils/readline/text.c | 3 +-- include/my_compiler.h | 13 ++++++++++++- sql/lock.cc | 8 +++----- sql/log.cc | 2 +- sql/set_var.cc | 2 +- sql/sql_acl.cc | 2 +- sql/sql_help.cc | 2 +- sql/sql_partition.cc | 4 ++-- sql/sql_union.cc | 9 --------- storage/myisam/myisamchk.c | 3 +-- storage/myisammrg/ha_myisammrg.cc | 2 +- 18 files changed, 53 insertions(+), 45 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 38862210cba..d790b3f0ee7 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5258,8 +5258,13 @@ void do_connect(struct st_command *command) opt_charsets_dir); #ifdef HAVE_OPENSSL - if (opt_use_ssl || con_ssl) + if (opt_use_ssl) + con_ssl= 1; +#endif + + if (con_ssl) { +#ifdef HAVE_OPENSSL mysql_ssl_set(&con_slot->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); #if MYSQL_VERSION_ID >= 50000 @@ -5268,36 +5273,37 @@ void do_connect(struct st_command *command) mysql_options(&con_slot->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &opt_ssl_verify_server_cert); #endif - } #endif + } -#ifdef __WIN__ if (con_pipe) { +#ifdef __WIN__ opt_protocol= MYSQL_PROTOCOL_PIPE; - } #endif + } if (opt_protocol) mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol); -#ifdef HAVE_SMEM if (con_shm) { +#ifdef HAVE_SMEM uint protocol= MYSQL_PROTOCOL_MEMORY; if (!ds_shm.length) die("Missing shared memory base name"); mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, ds_shm.str); mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol); +#endif } - else if(shared_memory_base_name) +#ifdef HAVE_SMEM + else if (shared_memory_base_name) { mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, - shared_memory_base_name); + shared_memory_base_name); } #endif - /* Use default db name */ if (ds_database.length == 0) dynstr_set(&ds_database, opt_db); diff --git a/cmd-line-utils/readline/complete.c b/cmd-line-utils/readline/complete.c index 2745e4e4801..d11ea2493a6 100644 --- a/cmd-line-utils/readline/complete.c +++ b/cmd-line-utils/readline/complete.c @@ -1839,8 +1839,11 @@ rl_username_completion_function (text, state) #else /* !__WIN32__ && !__OPENNT) */ static char *username = (char *)NULL; static struct passwd *entry; - static int namelen, first_char, first_char_loc; + static int first_char, first_char_loc; char *value; +#if defined (HAVE_GETPWENT) + static int namelen; +#endif if (state == 0) { @@ -1850,7 +1853,9 @@ rl_username_completion_function (text, state) first_char_loc = first_char == '~'; username = savestring (&text[first_char_loc]); +#if defined (HAVE_GETPWENT) namelen = strlen (username); +#endif setpwent (); } diff --git a/cmd-line-utils/readline/histexpand.c b/cmd-line-utils/readline/histexpand.c index ab8d8ecc866..7b51c369827 100644 --- a/cmd-line-utils/readline/histexpand.c +++ b/cmd-line-utils/readline/histexpand.c @@ -693,7 +693,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) case 's': { char *new_event; - int delimiter, failed, si, l_temp, ws, we; + int delimiter, failed, si, l_temp, we; if (c == 's') { @@ -792,7 +792,6 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) { for (; temp[si] && whitespace (temp[si]); si++) ; - ws = si; we = history_tokenize_word (temp, si); } diff --git a/cmd-line-utils/readline/histfile.c b/cmd-line-utils/readline/histfile.c index cbd367542ce..1a6d69b6684 100644 --- a/cmd-line-utils/readline/histfile.c +++ b/cmd-line-utils/readline/histfile.c @@ -402,6 +402,7 @@ history_truncate_file (fname, lines) if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1)) { bytes_written= write (file, bp, chars_read - (bp - buffer)); + (void) bytes_written; #if defined (__BEOS__) /* BeOS ignores O_TRUNC. */ diff --git a/cmd-line-utils/readline/isearch.c b/cmd-line-utils/readline/isearch.c index 305c847d8da..977e08eb9ba 100644 --- a/cmd-line-utils/readline/isearch.c +++ b/cmd-line-utils/readline/isearch.c @@ -617,7 +617,7 @@ rl_search_history (direction, invoking_key) int direction, invoking_key __attribute__((unused)); { _rl_search_cxt *cxt; /* local for now, but saved globally */ - int c, r; + int r; RL_SETSTATE(RL_STATE_ISEARCH); cxt = _rl_isearch_init (direction); @@ -632,7 +632,7 @@ rl_search_history (direction, invoking_key) r = -1; for (;;) { - c = _rl_search_getchar (cxt); + _rl_search_getchar (cxt); /* We might want to handle EOF here (c == 0) */ r = _rl_isearch_dispatch (cxt, cxt->lastc); if (r <= 0) @@ -655,9 +655,9 @@ int _rl_isearch_callback (cxt) _rl_search_cxt *cxt; { - int c, r; + int r; - c = _rl_search_getchar (cxt); + _rl_search_getchar (cxt); /* We might want to handle EOF here */ r = _rl_isearch_dispatch (cxt, cxt->lastc); diff --git a/cmd-line-utils/readline/parens.c b/cmd-line-utils/readline/parens.c index fe1578ed3e2..58f22291172 100644 --- a/cmd-line-utils/readline/parens.c +++ b/cmd-line-utils/readline/parens.c @@ -115,7 +115,7 @@ rl_insert_close (count, invoking_key) else { #if defined (HAVE_SELECT) - int orig_point, match_point, ready; + int orig_point, match_point; struct timeval timer; fd_set readfds; @@ -136,7 +136,7 @@ rl_insert_close (count, invoking_key) orig_point = rl_point; rl_point = match_point; (*rl_redisplay_function) (); - ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer); + select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer); rl_point = orig_point; #else /* !HAVE_SELECT */ _rl_insert_char (count, invoking_key); diff --git a/cmd-line-utils/readline/readline.c b/cmd-line-utils/readline/readline.c index fb92becdbf9..95947551823 100644 --- a/cmd-line-utils/readline/readline.c +++ b/cmd-line-utils/readline/readline.c @@ -447,11 +447,10 @@ readline_internal_char () readline_internal_charloop () #endif { - static int lastc, eof_found; + static int lastc; int c, code, lk; lastc = -1; - eof_found = 0; #if !defined (READLINE_CALLBACKS) while (rl_done == 0) diff --git a/cmd-line-utils/readline/text.c b/cmd-line-utils/readline/text.c index bb0f5d97160..02b28750c86 100644 --- a/cmd-line-utils/readline/text.c +++ b/cmd-line-utils/readline/text.c @@ -811,11 +811,10 @@ _rl_overwrite_char (count, c) int i; #if defined (HANDLE_MULTIBYTE) char mbkey[MB_LEN_MAX]; - int k; /* Read an entire multibyte character sequence to insert COUNT times. */ if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0) - k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX); + _rl_read_mbstring (c, mbkey, MB_LEN_MAX); #endif rl_begin_undo_group (); diff --git a/include/my_compiler.h b/include/my_compiler.h index 1cd46ff4260..c7d334999d0 100644 --- a/include/my_compiler.h +++ b/include/my_compiler.h @@ -32,8 +32,15 @@ /* GNU C/C++ */ #if defined __GNUC__ +/* Convenience macro to test the minimum required GCC version. */ +# define MY_GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) /* Any after 2.95... */ # define MY_ALIGN_EXT +/* Comunicate to the compiler the unreachability of the code. */ +# if MY_GNUC_PREREQ(4,5) +# define MY_ASSERT_UNREACHABLE() __builtin_unreachable() +# endif /* Microsoft Visual C++ */ #elif defined _MSC_VER @@ -67,7 +74,7 @@ #endif /** - Generic compiler-dependent features. + Generic (compiler-independent) features. */ #ifndef MY_ALIGNOF # ifdef __cplusplus @@ -79,6 +86,10 @@ # endif #endif +#ifndef MY_ASSERT_UNREACHABLE +# define MY_ASSERT_UNREACHABLE() do { assert(0); } while (0) +#endif + /** C++ Type Traits */ diff --git a/sql/lock.cc b/sql/lock.cc index 93d8b868688..e2216876635 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -693,7 +693,6 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle, TABLE_LIST *haystack) { MYSQL_LOCK *mylock; - TABLE **lock_tables; TABLE *table; TABLE *table2; THR_LOCK_DATA **lock_locks; @@ -722,12 +721,11 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle, if (mylock->table_count < 2) goto end; - lock_locks= mylock->locks; - lock_tables= mylock->table; + lock_locks= mylock->locks; /* Prepare table related variables that don't change in loop. */ DBUG_ASSERT((table->lock_position < mylock->table_count) && - (table == lock_tables[table->lock_position])); + (table == mylock->table[table->lock_position])); table_lock_data= lock_locks + table->lock_data_start; end_data= table_lock_data + table->lock_count; @@ -741,7 +739,7 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle, /* All tables in list must be in lock. */ DBUG_ASSERT((table2->lock_position < mylock->table_count) && - (table2 == lock_tables[table2->lock_position])); + (table2 == mylock->table[table2->lock_position])); for (lock_data2= lock_locks + table2->lock_data_start, end_data2= lock_data2 + table2->lock_count; diff --git a/sql/log.cc b/sql/log.cc index 2d5b62a5b2b..38f4677f06f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1217,7 +1217,7 @@ void LOGGER::deactivate_log_handler(THD *thd, uint log_type) file_log= file_log_handler->get_mysql_log(); break; default: - assert(0); // Impossible + MY_ASSERT_UNREACHABLE(); } if (!(*tmp_opt)) diff --git a/sql/set_var.cc b/sql/set_var.cc index c5517da92f8..9fbce870dc4 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2559,7 +2559,7 @@ bool update_sys_var_str_path(THD *thd, sys_var_str *var_str, file_log= logger.get_log_file_handler(); break; default: - assert(0); // Impossible + MY_ASSERT_UNREACHABLE(); } if (!old_value) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index ea002f59fe3..1733a0f74b4 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5479,7 +5479,7 @@ static int handle_grant_struct(uint struct_no, bool drop, host= grant_name->host.hostname; break; default: - assert(0); + MY_ASSERT_UNREACHABLE(); } if (! user) user= ""; diff --git a/sql/sql_help.cc b/sql/sql_help.cc index 2818aa5082c..c21968cb86e 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -686,7 +686,7 @@ bool mysqld_help(THD *thd, const char *mask) if (count_topics == 0) { - int key_id; + int UNINIT_VAR(key_id); if (!(select= prepare_select_for_name(thd,mask,mlen,tables,tables[3].table, used_fields[help_keyword_name].field, diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 76caa2b0c8d..702c3d99fda 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -6786,8 +6786,8 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info, } } else - assert(0); - + MY_ASSERT_UNREACHABLE(); + can_match_multiple_values= (flags || !min_value || !max_value || memcmp(min_value, max_value, field_len)); if (can_match_multiple_values && diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 948ba1d9d9c..70598fbfcd4 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -173,7 +173,6 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, SELECT_LEX *sl, *first_sl= first_select(); select_result *tmp_result; bool is_union_select; - TABLE *empty_table= 0; DBUG_ENTER("st_select_lex_unit::prepare"); describe= test(additional_options & SELECT_DESCRIBE); @@ -275,14 +274,6 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, types= first_sl->item_list; else if (sl == first_sl) { - /* - We need to create an empty table object. It is used - to create tmp_table fields in Item_type_holder. - The main reason of this is that we can't create - field object without table. - */ - DBUG_ASSERT(!empty_table); - empty_table= (TABLE*) thd->calloc(sizeof(TABLE)); types.empty(); List_iterator_fast it(sl->item_list); Item *item_tmp; diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index 96ceb35b3d5..7f9776ca8d0 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -697,8 +697,7 @@ get_one_option(int optid, case OPT_STATS_METHOD: { int method; - enum_mi_stats_method method_conv; - LINT_INIT(method_conv); + enum_mi_stats_method UNINIT_VAR(method_conv); myisam_stats_method_str= argument; if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0) { diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 8e18924c5b8..4c8d45d1fe1 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -415,7 +415,7 @@ static MI_INFO *myisammrg_attach_children_callback(void *callback_param) my_errno= HA_ERR_WRONG_MRG_TABLE_DEF; } DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d", - my_errno ? NULL : (long) myisam, my_errno)); + my_errno ? 0L : (long) myisam, my_errno)); err: DBUG_RETURN(my_errno ? NULL : myisam); From 9129cb184b5b443f0c863720c44e22875438235e Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 20 Oct 2010 19:25:28 -0200 Subject: [PATCH 114/151] GCC's link option only take a single hyphen. --- cmake/os/Linux.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/os/Linux.cmake b/cmake/os/Linux.cmake index 946e020d6f4..10d3a719609 100644 --- a/cmake/os/Linux.cmake +++ b/cmake/os/Linux.cmake @@ -33,7 +33,7 @@ ENDFOREACH() # Ensure we have clean build for shared libraries # without unresolved symbols -SET(LINK_FLAG_NO_UNDEFINED "--Wl,--no-undefined") +SET(LINK_FLAG_NO_UNDEFINED "-Wl,--no-undefined") # 64 bit file offset support flag SET(_FILE_OFFSET_BITS 64) From e8f228e7eb4f054bd7c272ba4c33fb7ea071ac2a Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 20 Oct 2010 19:56:42 -0700 Subject: [PATCH 115/151] Fix Bug #57616 Sig 11 in dict_load_table() when failed to load index or foreign key Approved by Sunny Bains --- storage/innobase/dict/dict0load.c | 4 ++-- storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/dict/dict0load.c | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index 625956600c0..c505bfbd6c4 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -878,13 +878,13 @@ err_exit: if (err != DB_SUCCESS) { dict_table_remove_from_cache(table); table = NULL; + } else { + table->fk_max_recusive_level = 0; } } else if (!srv_force_recovery) { dict_table_remove_from_cache(table); table = NULL; } - - table->fk_max_recusive_level = 0; #if 0 if (err != DB_SUCCESS && table != NULL) { diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index db37fa2b4bb..cccd5c0550a 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-10-20 The InnoDB Team + + * dict/dict0load.c + Fix Bug #57616 Sig 11 in dict_load_table() when failed to load + index or foreign key + 2010-10-19 The InnoDB Team * btr/btr0cur.c, buf/buf0buf.c, buf/buf0flu.c, handler/ha_innodb.cc, diff --git a/storage/innodb_plugin/dict/dict0load.c b/storage/innodb_plugin/dict/dict0load.c index b046fb32b0b..3dcee46b92c 100644 --- a/storage/innodb_plugin/dict/dict0load.c +++ b/storage/innodb_plugin/dict/dict0load.c @@ -1023,13 +1023,13 @@ err_exit: if (err != DB_SUCCESS) { dict_table_remove_from_cache(table); table = NULL; + } else { + table->fk_max_recusive_level = 0; } } else if (!srv_force_recovery) { dict_table_remove_from_cache(table); table = NULL; } - - table->fk_max_recusive_level = 0; #if 0 if (err != DB_SUCCESS && table != NULL) { From 6646fecc1420fce3b2d2425aa07170370a7671bf Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Oct 2010 13:43:19 +0800 Subject: [PATCH 116/151] Bug#55478 Row events wrongly apply on the temporary table of the same name Rows events were applied wrongly on the temporary table with the same name. But rows events are generated only for base tables. As temporary table's data never be binlogged on row mode. Normally, base table of the same name cannot be updated if a temporary table has the same name. But there are two cases which can generate rows events on the base table of same name. Case1: 'CREATE TABLE ... SELECT' statement. In mixed format, it will generate rows events if it is unsafe. Case2: Drop a transactional temporary table in a transaction (happens only on 5.5+). BEGIN; DROP TEMPORARY TABLE t1; # t1 is a InnoDB table INSERT INTO t1 VALUES(rand()); # t1 is a MyISAM table COMMIT; 'DROP TEMPORARY TABLE' will be put in the transaction cache and binlogged after the rows events generated by the 'INSERT' statement. After this patch, slave opens only base table when applying a rows event. --- .../suite/rpl/r/rpl_temp_table_mix_row.result | 44 +++++++++++++++ .../suite/rpl/t/rpl_temp_table_mix_row.test | 53 +++++++++++++++++++ sql/log_event.cc | 1 + 3 files changed, 98 insertions(+) diff --git a/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result b/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result index 3a31a206b1e..00cf238c712 100644 --- a/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result +++ b/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result @@ -69,3 +69,47 @@ slave-bin.000001 # Query # # COMMIT slave-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `t2_tmp` /* generated by server */ slave-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (2) slave-bin.000001 # Query # # use `test`; DROP TABLE t3, t1 + +# Bug#55478 Row events wrongly apply on the temporary table of the same name +# ========================================================================== +# The statement should be binlogged +CREATE TEMPORARY TABLE t1(c1 INT) ENGINE=InnoDB; + +# Case 1: CREATE TABLE t1 ... SELECT +# ---------------------------------- + +# The statement generates row events on t1. And the rows events should +# be inserted into the base table on slave. +CREATE TABLE t1 ENGINE=MyISAM SELECT rand(); +show binlog events in 'master-bin.000001' from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE `t1` ( + `rand()` double NOT NULL DEFAULT '0' +) ENGINE=MyISAM +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT + +# Case 2: DROP TEMPORARY TABLE in a transacation(happens only on 5.5+) +# -------------------------------------------------------------------- + +BEGIN; +DROP TEMPORARY TABLE t1; +# The statement will binlogged after 'DROP TEMPORARY TABLE t1' +INSERT INTO t1 VALUES(1); +# The rows event will binlogged after 'INSERT INTO t1 VALUES(1)' +INSERT INTO t1 VALUES(Rand()); +COMMIT; +show binlog events in 'master-bin.000001' from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `t1` /* generated by server */ +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES(1) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +# Compare the base table. +Comparing tables master:test.t1 and slave:test.t1 + +DROP TABLE t1; diff --git a/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test b/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test index e19c3019aa1..fa3f7929c1c 100644 --- a/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test +++ b/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test @@ -11,6 +11,7 @@ source include/master-slave.inc; source include/have_binlog_format_mixed.inc; +source include/have_innodb.inc; --echo ==== Initialize ==== @@ -146,3 +147,55 @@ DROP TABLE t3, t1; -- sync_slave_with_master -- source include/show_binlog_events.inc + +--echo +--echo # Bug#55478 Row events wrongly apply on the temporary table of the same name +--echo # ========================================================================== +connection master; + +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo # The statement should be binlogged +CREATE TEMPORARY TABLE t1(c1 INT) ENGINE=InnoDB; + +--echo +--echo # Case 1: CREATE TABLE t1 ... SELECT +--echo # ---------------------------------- +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # The statement generates row events on t1. And the rows events should +--echo # be inserted into the base table on slave. +CREATE TABLE t1 ENGINE=MyISAM SELECT rand(); + +source include/show_binlog_events.inc; +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # Case 2: DROP TEMPORARY TABLE in a transacation(happens only on 5.5+) +--echo # -------------------------------------------------------------------- +--echo + +BEGIN; +DROP TEMPORARY TABLE t1; + +--echo # The statement will binlogged after 'DROP TEMPORARY TABLE t1' +INSERT INTO t1 VALUES(1); + +--echo # The rows event will binlogged after 'INSERT INTO t1 VALUES(1)' +INSERT INTO t1 VALUES(Rand()); +COMMIT; + +source include/show_binlog_events.inc; + +--echo # Compare the base table. +let diff_table= test.t1; +source include/rpl_diff_tables.inc; + +--echo +connection master; +DROP TABLE t1; +source include/master-slave-end.inc; diff --git a/sql/log_event.cc b/sql/log_event.cc index 49f47edad72..041f90a057f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8258,6 +8258,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) m_field_metadata, m_field_metadata_size, m_null_bits, m_flags); table_list->m_tabledef_valid= TRUE; + table_list->skip_temporary= 1; /* We record in the slave's information that the table should be From ea6b469df39c1f177cd47f0d26406f95da4d7d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 21 Oct 2010 10:32:41 +0300 Subject: [PATCH 117/151] lock_rec_validate_page(): Disable the debug printout. It is filling the error log when testing the debug version of the server. The printout only seems to be useful when debugging a crash, not when testing an instrumented version of the server. --- storage/innobase/lock/lock0lock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index dcfca1b6315..f38ef48df4e 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -4859,11 +4859,11 @@ loop: ut_a(rec); offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); - +#if 0 fprintf(stderr, "Validating %lu %lu\n", (ulong) space, (ulong) page_no); - +#endif lock_mutex_exit_kernel(); /* If this thread is holding the file space From ed55f540ee16b94c4211c58830194895e4cbbdde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 21 Oct 2010 10:45:44 +0300 Subject: [PATCH 118/151] Remove files that are no longer needed. These files were needed when InnoDB Plugin was maintained and distributed separately from the MySQL 5.1 source tree. They have never been needed in MySQL 5.5. storage/innobase/mysql-test: Patches to the test suite. storage/innobase/handler/mysql_addons.cc: Wrappers for private MySQL functions. --- storage/innobase/CMakeLists.txt | 2 +- storage/innobase/Makefile.am | 2 - storage/innobase/handler/mysql_addons.cc | 42 ------ storage/innobase/include/mysql_addons.h | 33 ----- storage/innobase/mysql-test/patches/README | 30 ----- .../patches/index_merge_innodb-explain.diff | 31 ----- .../patches/information_schema.diff | 124 ------------------ .../innodb_change_buffering_basic.diff | 60 --------- .../patches/innodb_file_per_table.diff | 47 ------- .../patches/innodb_lock_wait_timeout.diff | 55 -------- .../innodb_thread_concurrency_basic.diff | 31 ----- .../mysql-test/patches/partition_innodb.diff | 59 --------- storage/innobase/trx/trx0i_s.c | 2 - 13 files changed, 1 insertion(+), 517 deletions(-) delete mode 100644 storage/innobase/handler/mysql_addons.cc delete mode 100644 storage/innobase/include/mysql_addons.h delete mode 100644 storage/innobase/mysql-test/patches/README delete mode 100644 storage/innobase/mysql-test/patches/index_merge_innodb-explain.diff delete mode 100644 storage/innobase/mysql-test/patches/information_schema.diff delete mode 100644 storage/innobase/mysql-test/patches/innodb_change_buffering_basic.diff delete mode 100644 storage/innobase/mysql-test/patches/innodb_file_per_table.diff delete mode 100644 storage/innobase/mysql-test/patches/innodb_lock_wait_timeout.diff delete mode 100644 storage/innobase/mysql-test/patches/innodb_thread_concurrency_basic.diff delete mode 100644 storage/innobase/mysql-test/patches/partition_innodb.diff diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 34639d61903..6cfd3d754f6 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -235,7 +235,7 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c os/os0file.c os/os0proc.c os/os0sync.c os/os0thread.c page/page0cur.c page/page0page.c page/page0zip.c que/que0que.c - handler/ha_innodb.cc handler/handler0alter.cc handler/i_s.cc handler/mysql_addons.cc + handler/ha_innodb.cc handler/handler0alter.cc handler/i_s.cc read/read0read.c rem/rem0cmp.c rem/rem0rec.c row/row0ext.c row/row0ins.c row/row0merge.c row/row0mysql.c row/row0purge.c row/row0row.c diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am index 460abddb11e..8e8e3300d35 100644 --- a/storage/innobase/Makefile.am +++ b/storage/innobase/Makefile.am @@ -115,7 +115,6 @@ noinst_HEADERS= \ include/mtr0mtr.h \ include/mtr0mtr.ic \ include/mtr0types.h \ - include/mysql_addons.h \ include/os0file.h \ include/os0file.ic \ include/os0proc.h \ @@ -258,7 +257,6 @@ libinnobase_a_SOURCES= \ handler/ha_innodb.cc \ handler/handler0alter.cc \ handler/i_s.cc \ - handler/mysql_addons.cc \ ibuf/ibuf0ibuf.c \ lock/lock0iter.c \ lock/lock0lock.c \ diff --git a/storage/innobase/handler/mysql_addons.cc b/storage/innobase/handler/mysql_addons.cc deleted file mode 100644 index ae6306e5db9..00000000000 --- a/storage/innobase/handler/mysql_addons.cc +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2007, 2009, Innobase Oy. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -/**************************************************//** -@file handler/mysql_addons.cc -This file contains functions that need to be added to -MySQL code but have not been added yet. - -Whenever you add a function here submit a MySQL bug -report (feature request) with the implementation. Then -write the bug number in the comment before the -function in this file. - -When MySQL commits the function it can be deleted from -here. In a perfect world this file exists but is empty. - -Created November 07, 2007 Vasil Dimov -*******************************************************/ - -#ifndef MYSQL_SERVER -#define MYSQL_SERVER -#endif /* MYSQL_SERVER */ - -#include - -#include "mysql_addons.h" -#include "univ.i" diff --git a/storage/innobase/include/mysql_addons.h b/storage/innobase/include/mysql_addons.h deleted file mode 100644 index 17660c18710..00000000000 --- a/storage/innobase/include/mysql_addons.h +++ /dev/null @@ -1,33 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2007, 2009, Innobase Oy. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -/**************************************************//** -@file include/mysql_addons.h -This file contains functions that need to be added to -MySQL code but have not been added yet. - -Whenever you add a function here submit a MySQL bug -report (feature request) with the implementation. Then -write the bug number in the comment before the -function in this file. - -When MySQL commits the function it can be deleted from -here. In a perfect world this file exists but is empty. - -Created November 07, 2007 Vasil Dimov -*******************************************************/ diff --git a/storage/innobase/mysql-test/patches/README b/storage/innobase/mysql-test/patches/README deleted file mode 100644 index 122d756e9e3..00000000000 --- a/storage/innobase/mysql-test/patches/README +++ /dev/null @@ -1,30 +0,0 @@ -This directory contains patches that need to be applied to the MySQL -source tree in order to get the mysql-test suite to succeed (when -storage/innobase is replaced with this InnoDB branch). Things to keep -in mind when adding new patches here: - -* The patch must be appliable from the mysql top-level source directory. - -* The patch filename must end in ".diff". - -* All patches here are expected to apply cleanly to the latest MySQL 5.1 - tree when storage/innobase is replaced with this InnoDB branch. If - changes to either of those cause the patch to fail, then please check - whether the patch is still needed and, if yes, adjust it so it applies - cleanly. - -* If applicable, always submit the patch at http://bugs.mysql.com and - name the file here like bug%d.diff. Once the patch is committed to - MySQL remove the file from here. - -* If the patch cannot be proposed for inclusion in the MySQL source tree - (via http://bugs.mysql.com) then add a comment at the beginning of the - patch, explaining the problem it is solving, how it does solve it and - why it is not applicable for inclusion in the MySQL source tree. - Obviously this is a very bad situation and should be avoided at all - costs, especially for files that are in the MySQL source repository - (not in storage/innobase). - -* If you ever need to add a patch here that is not related to mysql-test - suite, then please move this directory from ./mysql-test/patches to - ./patches and remove this text. diff --git a/storage/innobase/mysql-test/patches/index_merge_innodb-explain.diff b/storage/innobase/mysql-test/patches/index_merge_innodb-explain.diff deleted file mode 100644 index d1ed8afc778..00000000000 --- a/storage/innobase/mysql-test/patches/index_merge_innodb-explain.diff +++ /dev/null @@ -1,31 +0,0 @@ -InnoDB's estimate for the index cardinality depends on a pseudo random -number generator (it picks up random pages to sample). After an -optimization that was made in r2625 the following EXPLAINs started -returning a different number of rows (3 instead of 4). - -This patch adjusts the result file. - -This patch cannot be proposed to MySQL because the failures occur only -in this tree and do not occur in the standard InnoDB 5.1. Furthermore, -the file index_merge2.inc is used by other engines too. - ---- mysql-test/r/index_merge_innodb.result.orig 2008-09-30 18:32:13.000000000 +0300 -+++ mysql-test/r/index_merge_innodb.result 2008-09-30 18:33:01.000000000 +0300 -@@ -111,7 +111,7 @@ - explain select count(*) from t1 where - key1a = 2 and key1b is null and key2a = 2 and key2b is null; - id select_type table type possible_keys key key_len ref rows Extra --1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL 4 Using intersect(i1,i2); Using where; Using index -+1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL 3 Using intersect(i1,i2); Using where; Using index - select count(*) from t1 where - key1a = 2 and key1b is null and key2a = 2 and key2b is null; - count(*) -@@ -119,7 +119,7 @@ - explain select count(*) from t1 where - key1a = 2 and key1b is null and key3a = 2 and key3b is null; - id select_type table type possible_keys key key_len ref rows Extra --1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL 4 Using intersect(i1,i3); Using where; Using index -+1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL 3 Using intersect(i1,i3); Using where; Using index - select count(*) from t1 where - key1a = 2 and key1b is null and key3a = 2 and key3b is null; - count(*) diff --git a/storage/innobase/mysql-test/patches/information_schema.diff b/storage/innobase/mysql-test/patches/information_schema.diff deleted file mode 100644 index a3a21f7a08d..00000000000 --- a/storage/innobase/mysql-test/patches/information_schema.diff +++ /dev/null @@ -1,124 +0,0 @@ ---- mysql-test/r/information_schema.result.orig 2009-01-31 03:38:50.000000000 +0200 -+++ mysql-test/r/information_schema.result 2009-01-31 07:51:58.000000000 +0200 -@@ -71,6 +71,13 @@ - TRIGGERS - USER_PRIVILEGES - VIEWS -+INNODB_CMP_RESET -+INNODB_TRX -+INNODB_CMPMEM_RESET -+INNODB_LOCK_WAITS -+INNODB_CMPMEM -+INNODB_CMP -+INNODB_LOCKS - columns_priv - db - event -@@ -799,6 +806,8 @@ - TABLES UPDATE_TIME datetime - TABLES CHECK_TIME datetime - TRIGGERS CREATED datetime -+INNODB_TRX trx_started datetime -+INNODB_TRX trx_wait_started datetime - event execute_at datetime - event last_executed datetime - event starts datetime -@@ -852,7 +861,7 @@ - flush privileges; - SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA; - table_schema count(*) --information_schema 28 -+information_schema 35 - mysql 22 - create table t1 (i int, j int); - create trigger trg1 before insert on t1 for each row -@@ -1267,6 +1276,13 @@ - TRIGGERS TRIGGER_SCHEMA - USER_PRIVILEGES GRANTEE - VIEWS TABLE_SCHEMA -+INNODB_CMP_RESET page_size -+INNODB_TRX trx_id -+INNODB_CMPMEM_RESET page_size -+INNODB_LOCK_WAITS requesting_trx_id -+INNODB_CMPMEM page_size -+INNODB_CMP page_size -+INNODB_LOCKS lock_id - SELECT t.table_name, c1.column_name - FROM information_schema.tables t - INNER JOIN -@@ -1310,6 +1326,13 @@ - TRIGGERS TRIGGER_SCHEMA - USER_PRIVILEGES GRANTEE - VIEWS TABLE_SCHEMA -+INNODB_CMP_RESET page_size -+INNODB_TRX trx_id -+INNODB_CMPMEM_RESET page_size -+INNODB_LOCK_WAITS requesting_trx_id -+INNODB_CMPMEM page_size -+INNODB_CMP page_size -+INNODB_LOCKS lock_id - SELECT MAX(table_name) FROM information_schema.tables WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test'); - MAX(table_name) - VIEWS -@@ -1386,6 +1409,13 @@ - FILES information_schema.FILES 1 - GLOBAL_STATUS information_schema.GLOBAL_STATUS 1 - GLOBAL_VARIABLES information_schema.GLOBAL_VARIABLES 1 -+INNODB_CMP information_schema.INNODB_CMP 1 -+INNODB_CMPMEM information_schema.INNODB_CMPMEM 1 -+INNODB_CMPMEM_RESET information_schema.INNODB_CMPMEM_RESET 1 -+INNODB_CMP_RESET information_schema.INNODB_CMP_RESET 1 -+INNODB_LOCKS information_schema.INNODB_LOCKS 1 -+INNODB_LOCK_WAITS information_schema.INNODB_LOCK_WAITS 1 -+INNODB_TRX information_schema.INNODB_TRX 1 - KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1 - PARTITIONS information_schema.PARTITIONS 1 - PLUGINS information_schema.PLUGINS 1 -diff mysql-test/r/information_schema_db.result.orig mysql-test/r/information_schema_db.result ---- mysql-test/r/information_schema_db.result.orig 2008-08-04 09:27:49.000000000 +0300 -+++ mysql-test/r/information_schema_db.result 2008-10-07 12:26:31.000000000 +0300 -@@ -33,6 +33,13 @@ - TRIGGERS - USER_PRIVILEGES - VIEWS -+INNODB_CMP_RESET -+INNODB_TRX -+INNODB_CMPMEM_RESET -+INNODB_LOCK_WAITS -+INNODB_CMPMEM -+INNODB_CMP -+INNODB_LOCKS - show tables from INFORMATION_SCHEMA like 'T%'; - Tables_in_information_schema (T%) - TABLES -diff mysql-test/r/mysqlshow.result.orig mysql-test/r/mysqlshow.result ---- mysql-test/r/mysqlshow.result.orig 2008-08-04 09:27:51.000000000 +0300 -+++ mysql-test/r/mysqlshow.result 2008-10-07 12:35:39.000000000 +0300 -@@ -107,6 +107,13 @@ - | TRIGGERS | - | USER_PRIVILEGES | - | VIEWS | -+| INNODB_CMP_RESET | -+| INNODB_TRX | -+| INNODB_CMPMEM_RESET | -+| INNODB_LOCK_WAITS | -+| INNODB_CMPMEM | -+| INNODB_CMP | -+| INNODB_LOCKS | - +---------------------------------------+ - Database: INFORMATION_SCHEMA - +---------------------------------------+ -@@ -140,6 +147,13 @@ - | TRIGGERS | - | USER_PRIVILEGES | - | VIEWS | -+| INNODB_CMP_RESET | -+| INNODB_TRX | -+| INNODB_CMPMEM_RESET | -+| INNODB_LOCK_WAITS | -+| INNODB_CMPMEM | -+| INNODB_CMP | -+| INNODB_LOCKS | - +---------------------------------------+ - Wildcard: inf_rmation_schema - +--------------------+ diff --git a/storage/innobase/mysql-test/patches/innodb_change_buffering_basic.diff b/storage/innobase/mysql-test/patches/innodb_change_buffering_basic.diff deleted file mode 100644 index bfa1609a97c..00000000000 --- a/storage/innobase/mysql-test/patches/innodb_change_buffering_basic.diff +++ /dev/null @@ -1,60 +0,0 @@ ---- mysql-test/suite/sys_vars/t/innodb_change_buffering_basic.test.orig Mon Mar 15 16:15:22 2010 -+++ mysql-test/suite/sys_vars/t/innodb_change_buffering_basic.test Fri Mar 19 01:19:09 2010 -@@ -11,8 +11,8 @@ - # - # exists as global only - # ----echo Valid values are 'inserts' and 'none' --select @@global.innodb_change_buffering in ('inserts', 'none'); -+--echo Valid values are 'inserts', 'deletes', 'changes', 'purges', 'all', and 'none' -+select @@global.innodb_change_buffering in ('inserts', 'deletes', 'changes', 'purges', 'all', 'none'); - select @@global.innodb_change_buffering; - --error ER_INCORRECT_GLOBAL_LOCAL_VAR - select @@session.innodb_change_buffering; - ---- mysql-test/suite/sys_vars/r/innodb_change_buffering_basic.result.orig Mon Mar 15 16:15:22 2010 -+++ mysql-test/suite/sys_vars/r/innodb_change_buffering_basic.result Fri Mar 19 01:23:58 2010 -@@ -1,28 +1,28 @@ - SET @start_global_value = @@global.innodb_change_buffering; - SELECT @start_global_value; - @start_global_value --inserts --Valid values are 'inserts' and 'none' --select @@global.innodb_change_buffering in ('inserts', 'none'); --@@global.innodb_change_buffering in ('inserts', 'none') -+all -+Valid values are 'inserts', 'deletes', 'changes', 'purges', 'all', and 'none' -+select @@global.innodb_change_buffering in ('inserts', 'deletes', 'changes', 'purges', 'all', 'none'); -+@@global.innodb_change_buffering in ('inserts', 'deletes', 'changes', 'purges', 'all', 'none') - 1 - select @@global.innodb_change_buffering; - @@global.innodb_change_buffering --inserts -+all - select @@session.innodb_change_buffering; - ERROR HY000: Variable 'innodb_change_buffering' is a GLOBAL variable - show global variables like 'innodb_change_buffering'; - Variable_name Value --innodb_change_buffering inserts -+innodb_change_buffering all - show session variables like 'innodb_change_buffering'; - Variable_name Value --innodb_change_buffering inserts -+innodb_change_buffering all - select * from information_schema.global_variables where variable_name='innodb_change_buffering'; - VARIABLE_NAME VARIABLE_VALUE --INNODB_CHANGE_BUFFERING inserts -+INNODB_CHANGE_BUFFERING all - select * from information_schema.session_variables where variable_name='innodb_change_buffering'; - VARIABLE_NAME VARIABLE_VALUE --INNODB_CHANGE_BUFFERING inserts -+INNODB_CHANGE_BUFFERING all - set global innodb_change_buffering='none'; - select @@global.innodb_change_buffering; - @@global.innodb_change_buffering -@@ -60,4 +60,4 @@ - SET @@global.innodb_change_buffering = @start_global_value; - SELECT @@global.innodb_change_buffering; - @@global.innodb_change_buffering --inserts -+all diff --git a/storage/innobase/mysql-test/patches/innodb_file_per_table.diff b/storage/innobase/mysql-test/patches/innodb_file_per_table.diff deleted file mode 100644 index 8b7ae2036c9..00000000000 --- a/storage/innobase/mysql-test/patches/innodb_file_per_table.diff +++ /dev/null @@ -1,47 +0,0 @@ -diff mysql-test/suite/sys_vars/t/innodb_file_per_table_basic.test.orig mysql-test/suite/sys_vars/t/innodb_file_per_table_basic.test ---- mysql-test/suite/sys_vars/t/innodb_file_per_table_basic.test.orig 2008-10-07 11:32:30.000000000 +0300 -+++ mysql-test/suite/sys_vars/t/innodb_file_per_table_basic.test 2008-10-07 11:52:14.000000000 +0300 -@@ -37,10 +37,6 @@ - # Check if Value can set # - #################################################################### - ----error ER_INCORRECT_GLOBAL_LOCAL_VAR --SET @@GLOBAL.innodb_file_per_table=1; ----echo Expected error 'Read only variable' -- - SELECT COUNT(@@GLOBAL.innodb_file_per_table); - --echo 1 Expected - -@@ -52,7 +48,7 @@ - # Check if the value in GLOBAL Table matches value in variable # - ################################################################# - --SELECT @@GLOBAL.innodb_file_per_table = VARIABLE_VALUE -+SELECT IF(@@GLOBAL.innodb_file_per_table,'ON','OFF') = VARIABLE_VALUE - FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES - WHERE VARIABLE_NAME='innodb_file_per_table'; - --echo 1 Expected -diff mysql-test/suite/sys_vars/r/innodb_file_per_table_basic.result.orig mysql-test/suite/sys_vars/r/innodb_file_per_table_basic.result ---- mysql-test/suite/sys_vars/r/innodb_file_per_table_basic.result.orig 2008-10-07 11:32:02.000000000 +0300 -+++ mysql-test/suite/sys_vars/r/innodb_file_per_table_basic.result 2008-10-07 11:52:47.000000000 +0300 -@@ -4,18 +4,15 @@ - 1 - 1 Expected - '#---------------------BS_STVARS_028_02----------------------#' --SET @@GLOBAL.innodb_file_per_table=1; --ERROR HY000: Variable 'innodb_file_per_table' is a read only variable --Expected error 'Read only variable' - SELECT COUNT(@@GLOBAL.innodb_file_per_table); - COUNT(@@GLOBAL.innodb_file_per_table) - 1 - 1 Expected - '#---------------------BS_STVARS_028_03----------------------#' --SELECT @@GLOBAL.innodb_file_per_table = VARIABLE_VALUE -+SELECT IF(@@GLOBAL.innodb_file_per_table,'ON','OFF') = VARIABLE_VALUE - FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES - WHERE VARIABLE_NAME='innodb_file_per_table'; --@@GLOBAL.innodb_file_per_table = VARIABLE_VALUE -+IF(@@GLOBAL.innodb_file_per_table,'ON','OFF') = VARIABLE_VALUE - 1 - 1 Expected - SELECT COUNT(@@GLOBAL.innodb_file_per_table); diff --git a/storage/innobase/mysql-test/patches/innodb_lock_wait_timeout.diff b/storage/innobase/mysql-test/patches/innodb_lock_wait_timeout.diff deleted file mode 100644 index bc61a0f5841..00000000000 --- a/storage/innobase/mysql-test/patches/innodb_lock_wait_timeout.diff +++ /dev/null @@ -1,55 +0,0 @@ ---- mysql-test/suite/sys_vars/t/innodb_lock_wait_timeout_basic.test.orig 2008-08-04 09:28:16.000000000 +0300 -+++ mysql-test/suite/sys_vars/t/innodb_lock_wait_timeout_basic.test 2008-10-07 11:14:15.000000000 +0300 -@@ -37,10 +37,6 @@ - # Check if Value can set # - #################################################################### - ----error ER_INCORRECT_GLOBAL_LOCAL_VAR --SET @@GLOBAL.innodb_lock_wait_timeout=1; ----echo Expected error 'Read only variable' -- - SELECT COUNT(@@GLOBAL.innodb_lock_wait_timeout); - --echo 1 Expected - -@@ -84,13 +80,9 @@ - SELECT COUNT(@@innodb_lock_wait_timeout); - --echo 1 Expected - ----Error ER_INCORRECT_GLOBAL_LOCAL_VAR - SELECT COUNT(@@local.innodb_lock_wait_timeout); ----echo Expected error 'Variable is a GLOBAL variable' - ----Error ER_INCORRECT_GLOBAL_LOCAL_VAR - SELECT COUNT(@@SESSION.innodb_lock_wait_timeout); ----echo Expected error 'Variable is a GLOBAL variable' - - SELECT COUNT(@@GLOBAL.innodb_lock_wait_timeout); - --echo 1 Expected ---- mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result.orig 2008-08-04 09:27:50.000000000 +0300 -+++ mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result 2008-10-07 11:15:14.000000000 +0300 -@@ -4,9 +4,6 @@ - 1 - 1 Expected - '#---------------------BS_STVARS_032_02----------------------#' --SET @@GLOBAL.innodb_lock_wait_timeout=1; --ERROR HY000: Variable 'innodb_lock_wait_timeout' is a read only variable --Expected error 'Read only variable' - SELECT COUNT(@@GLOBAL.innodb_lock_wait_timeout); - COUNT(@@GLOBAL.innodb_lock_wait_timeout) - 1 -@@ -39,11 +36,11 @@ - 1 - 1 Expected - SELECT COUNT(@@local.innodb_lock_wait_timeout); --ERROR HY000: Variable 'innodb_lock_wait_timeout' is a GLOBAL variable --Expected error 'Variable is a GLOBAL variable' -+COUNT(@@local.innodb_lock_wait_timeout) -+1 - SELECT COUNT(@@SESSION.innodb_lock_wait_timeout); --ERROR HY000: Variable 'innodb_lock_wait_timeout' is a GLOBAL variable --Expected error 'Variable is a GLOBAL variable' -+COUNT(@@SESSION.innodb_lock_wait_timeout) -+1 - SELECT COUNT(@@GLOBAL.innodb_lock_wait_timeout); - COUNT(@@GLOBAL.innodb_lock_wait_timeout) - 1 diff --git a/storage/innobase/mysql-test/patches/innodb_thread_concurrency_basic.diff b/storage/innobase/mysql-test/patches/innodb_thread_concurrency_basic.diff deleted file mode 100644 index 72e5457905f..00000000000 --- a/storage/innobase/mysql-test/patches/innodb_thread_concurrency_basic.diff +++ /dev/null @@ -1,31 +0,0 @@ ---- mysql-test/suite/sys_vars/r/innodb_thread_concurrency_basic.result.orig 2008-12-04 18:45:52 -06:00 -+++ mysql-test/suite/sys_vars/r/innodb_thread_concurrency_basic.result 2009-02-12 02:05:48 -06:00 -@@ -1,19 +1,19 @@ - SET @global_start_value = @@global.innodb_thread_concurrency; - SELECT @global_start_value; - @global_start_value --8 -+0 - '#--------------------FN_DYNVARS_046_01------------------------#' - SET @@global.innodb_thread_concurrency = 0; - SET @@global.innodb_thread_concurrency = DEFAULT; - SELECT @@global.innodb_thread_concurrency; - @@global.innodb_thread_concurrency --8 -+0 - '#---------------------FN_DYNVARS_046_02-------------------------#' - SET innodb_thread_concurrency = 1; - ERROR HY000: Variable 'innodb_thread_concurrency' is a GLOBAL variable and should be set with SET GLOBAL - SELECT @@innodb_thread_concurrency; - @@innodb_thread_concurrency --8 -+0 - SELECT local.innodb_thread_concurrency; - ERROR 42S02: Unknown table 'local' in field list - SET global innodb_thread_concurrency = 0; -@@ -93,4 +93,4 @@ - SET @@global.innodb_thread_concurrency = @global_start_value; - SELECT @@global.innodb_thread_concurrency; - @@global.innodb_thread_concurrency --8 -+0 diff --git a/storage/innobase/mysql-test/patches/partition_innodb.diff b/storage/innobase/mysql-test/patches/partition_innodb.diff deleted file mode 100644 index 01bc073008e..00000000000 --- a/storage/innobase/mysql-test/patches/partition_innodb.diff +++ /dev/null @@ -1,59 +0,0 @@ -The partition_innodb test only fails if run immediately after innodb_trx_weight. -The reason for this failure is that innodb_trx_weight creates deadlocks and -leaves something like this in the SHOW ENGINE INNODB STATUS output: - - ------------------------ - LATEST DETECTED DEADLOCK - ------------------------ - 090213 10:26:25 - *** (1) TRANSACTION: - TRANSACTION 313, ACTIVE 0 sec, OS thread id 13644672 inserting - mysql tables in use 1, locked 1 - LOCK WAIT 4 lock struct(s), heap size 488, 3 row lock(s) - MySQL thread id 3, query id 36 localhost root update - -The regular expressions that partition_innodb is using are intended to extract -the lock structs and row locks numbers from another part of the output: - - ------------ - TRANSACTIONS - ------------ - Trx id counter 31D - Purge done for trx's n:o < 0 undo n:o < 0 - History list length 4 - LIST OF TRANSACTIONS FOR EACH SESSION: - ---TRANSACTION 0, not started, OS thread id 13645056 - 0 lock struct(s), heap size 488, 0 row lock(s) - MySQL thread id 8, query id 81 localhost root - -In the InnoDB Plugin a transaction id is not printed as 2 consecutive -decimal integers (as it is in InnoDB 5.1) but rather as a single -hexadecimal integer. Thus the regular expressions somehow pick the wrong -part of the SHOW ENGINE INNODB STATUS output. - -So after the regular expressions are adjusted to the InnoDB Plugin's variant -of trx_id prinout, then they pick the expected part of the output. - -This patch cannot be proposed to MySQL because the failures occur only -in this tree and do not occur in the standard InnoDB 5.1. - ---- mysql-test/t/partition_innodb.test 2008-11-14 22:51:17 +0000 -+++ mysql-test/t/partition_innodb.test 2009-02-13 07:36:07 +0000 -@@ -27,14 +27,14 @@ - - # grouping/referencing in replace_regex is very slow on long strings, - # removing all before/after the interesting row before grouping/referencing ----replace_regex /.*---TRANSACTION [0-9]+ [0-9]+, .*, OS thread id [0-9]+// /MySQL thread id [0-9]+, query id [0-9]+ .*// /.*([0-9]+ lock struct\(s\)), heap size [0-9]+, ([0-9]+ row lock\(s\)).*/\1 \2/ -+--replace_regex /.*---TRANSACTION [0-9A-F]+, .*, OS thread id [0-9]+// /MySQL thread id [0-9]+, query id [0-9]+ .*// /.*([0-9]+ lock struct\(s\)), heap size [0-9]+, ([0-9]+ row lock\(s\)).*/\1 \2/ - SHOW ENGINE InnoDB STATUS; - - UPDATE t1 SET data = data*2 WHERE data = 2; - - # grouping/referencing in replace_regex is very slow on long strings, - # removing all before/after the interesting row before grouping/referencing ----replace_regex /.*---TRANSACTION [0-9]+ [0-9]+, .*, OS thread id [0-9]+// /MySQL thread id [0-9]+, query id [0-9]+ .*// /.*([0-9]+ lock struct\(s\)), heap size [0-9]+, ([0-9]+ row lock\(s\)).*/\1 \2/ -+--replace_regex /.*---TRANSACTION [0-9A-F]+, .*, OS thread id [0-9]+// /MySQL thread id [0-9]+, query id [0-9]+ .*// /.*([0-9]+ lock struct\(s\)), heap size [0-9]+, ([0-9]+ row lock\(s\)).*/\1 \2/ - SHOW ENGINE InnoDB STATUS; - - SET @@session.tx_isolation = @old_tx_isolation; - diff --git a/storage/innobase/trx/trx0i_s.c b/storage/innobase/trx/trx0i_s.c index 1ad074769c7..ab10135c6c4 100644 --- a/storage/innobase/trx/trx0i_s.c +++ b/storage/innobase/trx/trx0i_s.c @@ -38,8 +38,6 @@ Created July 17, 2007 Vasil Dimov #include -#include "mysql_addons.h" - #include "buf0buf.h" #include "dict0dict.h" #include "ha0storage.h" From d1a349325c42fd633f3f55054f47685f2087453d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 21 Oct 2010 11:30:43 +0300 Subject: [PATCH 119/151] Fix a sys_vars.all_vars failure caused by Bug #56680 instrumentation. The variable innodb_change_buffering_debug is only present in debug builds. Hide it from the test, so that the test passes in both debug and non-debug. --- mysql-test/suite/sys_vars/r/all_vars.result | 1 + mysql-test/suite/sys_vars/t/all_vars.test | 3 +++ 2 files changed, 4 insertions(+) diff --git a/mysql-test/suite/sys_vars/r/all_vars.result b/mysql-test/suite/sys_vars/r/all_vars.result index 7f6dca3eb7b..e635f1201a3 100644 --- a/mysql-test/suite/sys_vars/r/all_vars.result +++ b/mysql-test/suite/sys_vars/r/all_vars.result @@ -3,6 +3,7 @@ create table t2 (variable_name text); load data infile "MYSQLTEST_VARDIR/tmp/sys_vars.all_vars.txt" into table t1; insert into t2 select variable_name from information_schema.global_variables; insert into t2 select variable_name from information_schema.session_variables; +delete from t2 where variable_name='innodb_change_buffering_debug'; update t2 set variable_name= replace(variable_name, "PERFORMANCE_SCHEMA_", "PFS_"); select variable_name as `There should be *no* long test name listed below:` from t2 where length(variable_name) > 50; diff --git a/mysql-test/suite/sys_vars/t/all_vars.test b/mysql-test/suite/sys_vars/t/all_vars.test index e9e7e16687a..a00b7d5fbb9 100644 --- a/mysql-test/suite/sys_vars/t/all_vars.test +++ b/mysql-test/suite/sys_vars/t/all_vars.test @@ -61,6 +61,9 @@ eval load data infile "$MYSQLTEST_VARDIR/tmp/sys_vars.all_vars.txt" into table t insert into t2 select variable_name from information_schema.global_variables; insert into t2 select variable_name from information_schema.session_variables; +# This is only present in debug builds. +delete from t2 where variable_name='innodb_change_buffering_debug'; + # Performance schema variables are too long for files named # 'mysql-test/suite/sys_vars/t/' ... # ... 'performance_schema_events_waits_history_long_size_basic-master.opt' From 89e43c84943da707d72f168c48b86c41f8a05aff Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Thu, 21 Oct 2010 15:41:13 +0700 Subject: [PATCH 120/151] Fixed bug#45445 - cannot execute procedures with thread_stack set to 128k. sql/sp.cc: Added checking for stack overrun at functions db_load_routine/sp_find_routine. sql/sp_head.cc: sp_head::execute() modified: pass constant value STACK_MIN_SIZE instead of 8 * STACK_MIN_SIZE as second argument value in call to check_stack_overrun. Added checking for stack overrun at functions sp_lex_keeper::reset_lex_and_exec_core/sp_instr_stmt::execute. sql/sql_parse.cc: check_stack_overrun modified: allocate buffer for error message at heap instead of stack. parse_sql modified: added call to check_stack_overrun() before parsing of sql statement. --- sql/sp.cc | 6 ++++++ sql/sp_head.cc | 11 +++++++---- sql/sql_parse.cc | 18 ++++++++++++++---- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index 87eb40c29ac..7385a6ffcae 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -779,6 +779,9 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, int ret= 0; + if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&ret)) + return TRUE; + thd->lex= &newlex; newlex.current_select= NULL; @@ -1505,6 +1508,9 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, (int) name->m_name.length, name->m_name.str, type, cache_only)); + if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&depth)) + return NULL; + if ((sp= sp_cache_lookup(cp, name))) { ulong level; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 1fd4e9302c4..379e81d406e 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1233,11 +1233,8 @@ sp_head::execute(THD *thd) The same with db_load_routine() required circa 7k bytes and 14k bytes accordingly. Hence, here we book the stack with some reasonable margin. - - Reverting back to 8 * STACK_MIN_SIZE until further fix. - 8 * STACK_MIN_SIZE is required on some exotic platforms. */ - if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet)) + if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&old_packet)) DBUG_RETURN(TRUE); /* init per-instruction memroot */ @@ -2902,6 +2899,9 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, It's merged with the saved parent's value at the exit of this func. */ bool parent_modified_non_trans_table= thd->transaction.stmt.modified_non_trans_table; + if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&parent_modified_non_trans_table)) + DBUG_RETURN(TRUE); + thd->transaction.stmt.modified_non_trans_table= FALSE; DBUG_ASSERT(!thd->derived_tables); DBUG_ASSERT(thd->change_list.is_empty()); @@ -3057,6 +3057,9 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) DBUG_ENTER("sp_instr_stmt::execute"); DBUG_PRINT("info", ("command: %d", m_lex_keeper.sql_command())); + if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res)) + DBUG_RETURN(TRUE); + query= thd->query(); query_length= thd->query_length(); #if defined(ENABLED_PROFILING) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b322c74cb40..4ed22e3a355 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5118,10 +5118,17 @@ bool check_stack_overrun(THD *thd, long margin, if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >= (long) (my_thread_stack_size - margin)) { - char ebuff[MYSQL_ERRMSG_SIZE]; - my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE), - stack_used, my_thread_stack_size, margin); - my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR)); + /* + Do not use stack for the message buffer to ensure correct + behaviour in cases we have close to no stack left. + */ + char* ebuff= new char[MYSQL_ERRMSG_SIZE]; + if (ebuff) { + my_snprintf(ebuff, MYSQL_ERRMSG_SIZE, ER(ER_STACK_OVERRUN_NEED_MORE), + stack_used, my_thread_stack_size, margin); + my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR)); + delete [] ebuff; + } return 1; } #ifndef DBUG_OFF @@ -7210,6 +7217,9 @@ bool parse_sql(THD *thd, Object_creation_ctx *backup_ctx= NULL; + if (check_stack_overrun(thd, 2 * STACK_MIN_SIZE, (uchar*)&backup_ctx)) + return TRUE; + if (creation_ctx) backup_ctx= creation_ctx->set_n_backup(thd); From 38f54271922aaec6e47a589fdf6d0388197c8928 Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Thu, 21 Oct 2010 22:22:27 +1100 Subject: [PATCH 121/151] Bug #57243 Inconsistent use of trans_register_ha() API in InnoDB Remove trx_t::active_trans. Split into two separate fields with distinct responsibilities. trx_t::is_registered and trx_t::owns_prepare_mutex. There are wrapper functions for using this fields in ha_innodb.cc. The wrapper functions check for invariants. Fix some formatting to conform to InnoDB guidelines. Remove innobase_register_stmt() and innobase_register_trx_and_stmt(). Add: trx_is_started() trx_deregister_from_2pc() trx_register_for_2pc() trx_is_registered_for_2pc() trx_owns_prepare_commit_mutex_set() trx_has_prepare_commit_mutex() rb://479, Approved by Jimmy Yang. --- storage/innobase/handler/ha_innodb.cc | 329 +++++++++++++------------- storage/innobase/include/trx0trx.h | 17 +- storage/innobase/trx/trx0trx.c | 7 +- 3 files changed, 186 insertions(+), 167 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index f31d92f3200..97ddbfc8199 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -32,7 +32,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA *****************************************************************************/ /* TODO list for the InnoDB handler in 5.0: - - Remove the flag trx->active_trans and look at trx->conc_state - fix savepoint functions to use savepoint storage area - Find out what kind of problems the OS X case-insensitivity causes to table and database names; should we 'normalize' the names like we do @@ -1500,7 +1499,7 @@ Gets the InnoDB transaction handle for a MySQL handler object, creates an InnoDB transaction struct if the corresponding MySQL thread struct still lacks one. @return InnoDB transaction handle */ -static +static inline trx_t* check_trx_exists( /*=============*/ @@ -1522,6 +1521,77 @@ check_trx_exists( return(trx); } +/*********************************************************************//** +Note that a transaction has been registered with MySQL. +@return true if transaction is registered with MySQL 2PC coordinator */ +static inline +bool +trx_is_registered_for_2pc( +/*=========================*/ + const trx_t* trx) /* in: transaction */ +{ + return(trx->is_registered == 1); +} + +/*********************************************************************//** +Note that a transaction owns the prepare_commit_mutex. */ +static inline +void +trx_owns_prepare_commit_mutex_set( +/*==============================*/ + trx_t* trx) /* in: transaction */ +{ + ut_a(trx_is_registered_for_2pc(trx)); + trx->owns_prepare_mutex = 1; +} + +/*********************************************************************//** +Note that a transaction has been registered with MySQL 2PC coordinator. */ +static inline +void +trx_register_for_2pc( +/*==================*/ + trx_t* trx) /* in: transaction */ +{ + trx->is_registered = 1; + ut_ad(trx->owns_prepare_mutex == 0); +} + +/*********************************************************************//** +Note that a transaction has been deregistered. */ +static inline +void +trx_deregister_from_2pc( +/*====================*/ + trx_t* trx) /* in: transaction */ +{ + trx->is_registered = 0; + trx->owns_prepare_mutex = 0; +} + +/*********************************************************************//** +Check whether atransaction owns the prepare_commit_mutex. +@return true if transaction owns the prepare commit mutex */ +static inline +bool +trx_has_prepare_commit_mutex( +/*=========================*/ + const trx_t* trx) /* in: transaction */ +{ + return(trx->owns_prepare_mutex == 1); +} + +/*********************************************************************//** +Check if transaction is started. +@reutrn true if transaction is in state started */ +static +bool +trx_is_started( +/*===========*/ + trx_t* trx) /* in: transaction */ +{ + return(trx->conc_state != TRX_NOT_STARTED); +} /*********************************************************************//** Construct ha_innobase handler. */ @@ -1585,48 +1655,31 @@ ha_innobase::update_thd() } /*********************************************************************//** -Registers that InnoDB takes part in an SQL statement, so that MySQL knows to -roll back the statement if the statement results in an error. This MUST be -called for every SQL statement that may be rolled back by MySQL. Calling this -several times to register the same statement is allowed, too. */ +Registers an InnoDB transaction with the MySQL 2PC coordinator, so that +the MySQL XA code knows to call the InnoDB prepare and commit, or rollback +for the transaction. This MUST be called for every transaction for which +the user may call commit or rollback. Calling this several times to register +the same transaction is allowed, too. This function also registers the +current SQL statement. */ static inline void -innobase_register_stmt( -/*===================*/ - handlerton* hton, /*!< in: Innobase hton */ - THD* thd) /*!< in: MySQL thd (connection) object */ +innobase_register_trx( +/*==================*/ + handlerton* hton, /* in: Innobase handlerton */ + THD* thd, /* in: MySQL thd (connection) object */ + trx_t* trx) /* in: transaction to register */ { - DBUG_ASSERT(hton == innodb_hton_ptr); - /* Register the statement */ trans_register_ha(thd, FALSE, hton); -} -/*********************************************************************//** -Registers an InnoDB transaction in MySQL, so that the MySQL XA code knows -to call the InnoDB prepare and commit, or rollback for the transaction. This -MUST be called for every transaction for which the user may call commit or -rollback. Calling this several times to register the same transaction is -allowed, too. -This function also registers the current SQL statement. */ -static inline -void -innobase_register_trx_and_stmt( -/*===========================*/ - handlerton *hton, /*!< in: Innobase handlerton */ - THD* thd) /*!< in: MySQL thd (connection) object */ -{ - /* NOTE that actually innobase_register_stmt() registers also - the transaction in the AUTOCOMMIT=1 mode. */ + if (!trx_is_registered_for_2pc(trx) + && thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { - innobase_register_stmt(hton, thd); - - if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { - - /* No autocommit mode, register for a transaction */ trans_register_ha(thd, TRUE, hton); } -} + trx_register_for_2pc(trx); +} + /* BACKGROUND INFO: HOW THE MYSQL QUERY CACHE WORKS WITH INNODB ------------------------------------------------------------ @@ -1772,14 +1825,8 @@ innobase_query_caching_of_table_permitted( #ifdef __WIN__ innobase_casedn_str(norm_name); #endif - /* The call of row_search_.. will start a new transaction if it is - not yet started */ - if (trx->active_trans == 0) { - - innobase_register_trx_and_stmt(innodb_hton_ptr, thd); - trx->active_trans = 1; - } + innobase_register_trx(innodb_hton_ptr, thd, trx); if (row_search_check_if_query_cache_permitted(trx, norm_name)) { @@ -2046,14 +2093,7 @@ ha_innobase::init_table_handle_for_HANDLER(void) trx_assign_read_view(prebuilt->trx); - /* Set the MySQL flag to mark that there is an active transaction */ - - if (prebuilt->trx->active_trans == 0) { - - innobase_register_trx_and_stmt(ht, user_thd); - - prebuilt->trx->active_trans = 1; - } + innobase_register_trx(ht, user_thd, prebuilt->trx); /* We did the necessary inits in this function, no need to repeat them in row_search_for_mysql */ @@ -2548,12 +2588,10 @@ innobase_commit_low( /*================*/ trx_t* trx) /*!< in: transaction handle */ { - if (trx->conc_state == TRX_NOT_STARTED) { + if (trx_is_started(trx)) { - return; + trx_commit_for_mysql(trx); } - - trx_commit_for_mysql(trx); } /*****************************************************************//** @@ -2595,10 +2633,7 @@ innobase_start_trx_and_assign_read_view( /* Set the MySQL flag to mark that there is an active transaction */ - if (trx->active_trans == 0) { - innobase_register_trx_and_stmt(hton, thd); - trx->active_trans = 1; - } + innobase_register_trx(hton, current_thd, trx); DBUG_RETURN(0); } @@ -2632,29 +2667,19 @@ innobase_commit( trx_search_latch_release_if_reserved(trx); } - /* The flag trx->active_trans is set to 1 in + /* Transaction is deregistered only in a commit or a rollback. If + it is deregistered we know there cannot be resources to be freed + and we could return immediately. For the time being, we play safe + and do the cleanup though there should be nothing to clean up. */ - 1. ::external_lock(), - 2. ::start_stmt(), - 3. innobase_query_caching_of_table_permitted(), - 4. innobase_savepoint(), - 5. ::init_table_handle_for_HANDLER(), - 6. innobase_start_trx_and_assign_read_view(), - 7. ::transactional_table_lock() + if (!trx_is_registered_for_2pc(trx) && trx_is_started(trx)) { - and it is only set to 0 in a commit or a rollback. If it is 0 we know - there cannot be resources to be freed and we could return immediately. - For the time being, we play safe and do the cleanup though there should - be nothing to clean up. */ - - if (trx->active_trans == 0 - && trx->conc_state != TRX_NOT_STARTED) { - - sql_print_error("trx->active_trans == 0, but" - " trx->conc_state != TRX_NOT_STARTED"); + sql_print_error("Transaction not registered for MySQL 2PC, " + "but transaction is active"); } + if (all - || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { + || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { /* We were instructed to commit the whole transaction, or this is an SQL statement end and autocommit is on */ @@ -2709,15 +2734,15 @@ retry: mysql_mutex_unlock(&commit_cond_m); } - if (trx->active_trans == 2) { - + if (trx_has_prepare_commit_mutex(trx)) { + mysql_mutex_unlock(&prepare_commit_mutex); - } + } + + trx_deregister_from_2pc(trx); /* Now do a write + flush of logs. */ trx_commit_complete_for_mysql(trx); - trx->active_trans = 0; - } else { /* We just mark the SQL statement ended and do not do a transaction commit */ @@ -2786,10 +2811,10 @@ innobase_rollback( row_unlock_table_autoinc_for_mysql(trx); if (all - || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { + || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { error = trx_rollback_for_mysql(trx); - trx->active_trans = 0; + trx_deregister_from_2pc(trx); } else { error = trx_rollback_last_sql_stat_for_mysql(trx); } @@ -2932,8 +2957,8 @@ innobase_savepoint( innobase_release_stat_resources(trx); - /* cannot happen outside of transaction */ - DBUG_ASSERT(trx->active_trans); + /* Cannot happen outside of transaction */ + DBUG_ASSERT(trx_is_registered_for_2pc(trx)); /* TODO: use provided savepoint data area to store savepoint data */ char name[64]; @@ -2963,16 +2988,15 @@ innobase_close_connection( ut_a(trx); - if (trx->active_trans == 0 - && trx->conc_state != TRX_NOT_STARTED) { + if (!trx_is_registered_for_2pc(trx) && trx_is_started(trx)) { - sql_print_error("trx->active_trans == 0, but" - " trx->conc_state != TRX_NOT_STARTED"); + sql_print_error("Transaction not registered for MySQL 2PC, " + "but transaction is active"); } - if (trx->conc_state != TRX_NOT_STARTED && - global_system_variables.log_warnings) { + if (trx_is_started(trx) && global_system_variables.log_warnings) { + sql_print_warning( "MySQL is closing a connection that has an active " "InnoDB transaction. %llu row modifications will " @@ -4872,7 +4896,7 @@ no_commit: /* Altering to InnoDB format */ innobase_commit(ht, user_thd, 1); /* Note that this transaction is still active. */ - prebuilt->trx->active_trans = 1; + trx_register_for_2pc(prebuilt->trx); /* We will need an IX lock on the destination table. */ prebuilt->sql_stat_start = TRUE; } else { @@ -4888,7 +4912,7 @@ no_commit: locks, so they have to be acquired again. */ innobase_commit(ht, user_thd, 1); /* Note that this transaction is still active. */ - prebuilt->trx->active_trans = 1; + trx_register_for_2pc(prebuilt->trx); /* Re-acquire the table lock on the source table. */ row_lock_table_for_mysql(prebuilt, src_table, mode); /* We will need an IX lock on the destination table. */ @@ -8700,39 +8724,30 @@ ha_innobase::start_stmt( prepared for an update of a row */ prebuilt->select_lock_type = LOCK_X; + + } else if (trx->isolation_level != TRX_ISO_SERIALIZABLE + && thd_sql_command(thd) == SQLCOM_SELECT + && lock_type == TL_READ) { + + /* For other than temporary tables, we obtain + no lock for consistent read (plain SELECT). */ + + prebuilt->select_lock_type = LOCK_NONE; } else { - if (trx->isolation_level != TRX_ISO_SERIALIZABLE - && thd_sql_command(thd) == SQLCOM_SELECT - && lock_type == TL_READ) { + /* Not a consistent read: restore the + select_lock_type value. The value of + stored_select_lock_type was decided in: + 1) ::store_lock(), + 2) ::external_lock(), + 3) ::init_table_handle_for_HANDLER(), and + 4) ::transactional_table_lock(). */ - /* For other than temporary tables, we obtain - no lock for consistent read (plain SELECT). */ - - prebuilt->select_lock_type = LOCK_NONE; - } else { - /* Not a consistent read: restore the - select_lock_type value. The value of - stored_select_lock_type was decided in: - 1) ::store_lock(), - 2) ::external_lock(), - 3) ::init_table_handle_for_HANDLER(), and - 4) ::transactional_table_lock(). */ - - prebuilt->select_lock_type = - prebuilt->stored_select_lock_type; - } + prebuilt->select_lock_type = prebuilt->stored_select_lock_type; } - trx->detailed_error[0] = '\0'; + *trx->detailed_error = 0; - /* Set the MySQL flag to mark that there is an active transaction */ - if (trx->active_trans == 0) { - - innobase_register_trx_and_stmt(ht, thd); - trx->active_trans = 1; - } else { - innobase_register_stmt(ht, thd); - } + innobase_register_trx(ht, thd, trx); return(0); } @@ -8821,22 +8836,14 @@ ha_innobase::external_lock( if (lock_type != F_UNLCK) { /* MySQL is setting a new table lock */ - trx->detailed_error[0] = '\0'; + *trx->detailed_error = 0; - /* Set the MySQL flag to mark that there is an active - transaction */ - if (trx->active_trans == 0) { - - innobase_register_trx_and_stmt(ht, thd); - trx->active_trans = 1; - } else if (trx->n_mysql_tables_in_use == 0) { - innobase_register_stmt(ht, thd); - } + innobase_register_trx(ht, thd, trx); if (trx->isolation_level == TRX_ISO_SERIALIZABLE - && prebuilt->select_lock_type == LOCK_NONE - && thd_test_options(thd, - OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { + && prebuilt->select_lock_type == LOCK_NONE + && thd_test_options( + thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { /* To get serializable execution, we let InnoDB conceptually add 'LOCK IN SHARE MODE' to all SELECTs @@ -8906,19 +8913,20 @@ ha_innobase::external_lock( trx->mysql_n_tables_locked = 0; prebuilt->used_in_HANDLER = FALSE; - if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { - if (trx->active_trans != 0) { + if (!thd_test_options( + thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { + + if (trx_is_started(trx)) { innobase_commit(ht, thd, TRUE); } - } else { - if (trx->isolation_level <= TRX_ISO_READ_COMMITTED - && trx->global_read_view) { - /* At low transaction isolation levels we let - each consistent read set its own snapshot */ + } else if (trx->isolation_level <= TRX_ISO_READ_COMMITTED + && trx->global_read_view) { - read_view_close_for_mysql(trx); - } + /* At low transaction isolation levels we let + each consistent read set its own snapshot */ + + read_view_close_for_mysql(trx); } } @@ -8987,12 +8995,7 @@ ha_innobase::transactional_table_lock( /* MySQL is setting a new transactional table lock */ - /* Set the MySQL flag to mark that there is an active transaction */ - if (trx->active_trans == 0) { - - innobase_register_trx_and_stmt(ht, thd); - trx->active_trans = 1; - } + innobase_register_trx(ht, thd, trx); if (THDVAR(thd, table_locks) && thd_in_lock_tables(thd)) { ulint error = DB_SUCCESS; @@ -9005,7 +9008,8 @@ ha_innobase::transactional_table_lock( DBUG_RETURN((int) error); } - if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { + if (thd_test_options( + thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { /* Store the current undo_no of the transaction so that we know where to roll back if we have @@ -10046,19 +10050,19 @@ innobase_xa_prepare( innobase_release_stat_resources(trx); - if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) { + if (!trx_is_registered_for_2pc(trx) && trx_is_started(trx)) { - sql_print_error("trx->active_trans == 0, but trx->conc_state != " - "TRX_NOT_STARTED"); + sql_print_error("Transaction not registered for MySQL 2PC, " + "but transaction is active"); } if (all - || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { + || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { /* We were instructed to prepare the whole transaction, or this is an SQL statement end and autocommit is on */ - ut_ad(trx->active_trans); + ut_ad(trx_is_registered_for_2pc(trx)); error = (int) trx_prepare_for_mysql(trx); } else { @@ -10082,9 +10086,10 @@ innobase_xa_prepare( srv_active_wake_master_thread(); - if (thd_sql_command(thd) != SQLCOM_XA_PREPARE && - (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) - { + if (thd_sql_command(thd) != SQLCOM_XA_PREPARE + && (all + || !thd_test_options( + thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { /* For ibbackup to work the order of transactions in binlog and InnoDB must be the same. Consider the situation @@ -10105,7 +10110,7 @@ innobase_xa_prepare( will be between XA PREPARE and XA COMMIT, and we don't want to block for undefined period of time. */ mysql_mutex_lock(&prepare_commit_mutex); - trx->active_trans = 2; + trx_owns_prepare_commit_mutex_set(trx); } return(error); @@ -10140,8 +10145,8 @@ static int innobase_commit_by_xid( /*===================*/ - handlerton *hton, - XID* xid) /*!< in: X/Open XA transaction identification */ + handlerton* hton, + XID* xid) /*!< in: X/Open XA transaction identification */ { trx_t* trx; diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 6a817ccdc8e..b4a4aa0ca44 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -470,6 +470,20 @@ struct trx_struct{ of view of concurrency control: TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY, ... */ + /*------------------------------*/ + /* MySQL has a transaction coordinator to coordinate two phase + commit between multiple storage engines and the binary log. When + an engine participates in a transaction, it's responsible for + registering itself using the trans_register_ha() API. */ + unsigned is_registered:1;/* This flag is set to 1 after the + transaction has been registered with + the coordinator using the XA API, and + is set to 0 after commit or rollback. */ + unsigned owns_prepare_mutex:1;/* 1 if owns prepare mutex, if + this is set to 1 then registered should + also be set to 1. This is used in the + XA code */ + /*------------------------------*/ ulint isolation_level;/* TRX_ISO_REPEATABLE_READ, ... */ ulint check_foreigns; /* normally TRUE, but if the user wants to suppress foreign key checks, @@ -500,9 +514,6 @@ struct trx_struct{ in that case we must flush the log in trx_commit_complete_for_mysql() */ ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */ - ulint active_trans; /*!< 1 - if a transaction in MySQL - is active. 2 - if prepare_commit_mutex - was taken */ ulint has_search_latch; /* TRUE if this trx has latched the search system latch in S-mode */ diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index 6ef47a8dc16..6bae0527b53 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -105,7 +105,11 @@ trx_create( trx->is_purge = 0; trx->is_recovered = 0; trx->conc_state = TRX_NOT_STARTED; - trx->start_time = time(NULL); + + trx->is_registered = 0; + trx->owns_prepare_mutex = 0; + + trx->start_time = ut_time(); trx->isolation_level = TRX_ISO_REPEATABLE_READ; @@ -124,7 +128,6 @@ trx_create( trx->table_id = 0; trx->mysql_thd = NULL; - trx->active_trans = 0; trx->duplicates = 0; trx->n_mysql_tables_in_use = 0; From 909f0bf94a5bd5879fc9cf2be11b5c0cf20caed3 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 21 Oct 2010 15:20:50 +0200 Subject: [PATCH 122/151] Follow-up to Bug #55582 which allows checking strings in if Simplified cases where a select was used to compare variable against '' --- .../extra/rpl_tests/rpl_get_master_version_and_clock.test | 2 +- mysql-test/extra/rpl_tests/rpl_loaddata.test | 2 +- mysql-test/include/check_concurrent_insert.inc | 4 ++-- mysql-test/include/check_no_concurrent_insert.inc | 4 ++-- mysql-test/include/get_relay_log_pos.inc | 4 ++-- mysql-test/include/kill_query.inc | 4 ++-- mysql-test/include/kill_query_and_diff_master_slave.inc | 8 ++++---- mysql-test/include/setup_fake_relay_log.inc | 2 +- mysql-test/include/show_binlog_events.inc | 4 ++-- mysql-test/include/show_rpl_debug_info.inc | 6 +++--- mysql-test/include/wait_for_slave_io_error.inc | 2 +- mysql-test/include/wait_for_slave_param.inc | 4 ++-- mysql-test/include/wait_for_slave_sql_error.inc | 2 +- mysql-test/include/wait_for_status_var.inc | 2 +- mysql-test/suite/rpl/t/rpl_killed_ddl.test | 2 +- 15 files changed, 26 insertions(+), 26 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test b/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test index 66bd61a8ea9..40e155bc314 100644 --- a/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test +++ b/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test @@ -34,7 +34,7 @@ # connection slave; -if (`SELECT $debug_sync_action = ''`) +if (!$debug_sync_action) { --die Cannot continue. Please set value for debug_sync_action. } diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test index 1ae17398596..84419ec9cc5 100644 --- a/mysql-test/extra/rpl_tests/rpl_loaddata.test +++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test @@ -24,7 +24,7 @@ connection master; # MTR is not case-sensitive. let $lower_stmt_head= load data; let $UPPER_STMT_HEAD= LOAD DATA; -if (`SELECT '$lock_option' <> ''`) +if ($lock_option) { #if $lock_option is null, an extra blank is added into the statement, #this will change the result of rpl_loaddata test case. so $lock_option diff --git a/mysql-test/include/check_concurrent_insert.inc b/mysql-test/include/check_concurrent_insert.inc index f4bec3c9cdb..62de485d8f1 100644 --- a/mysql-test/include/check_concurrent_insert.inc +++ b/mysql-test/include/check_concurrent_insert.inc @@ -23,7 +23,7 @@ # Reset DEBUG_SYNC facility for safety. set debug_sync= "RESET"; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval create temporary table t_backup select * from $restore_table; } @@ -82,7 +82,7 @@ connection default; --eval delete from $table where i = 0; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval truncate table $restore_table; --eval insert into $restore_table select * from t_backup; diff --git a/mysql-test/include/check_no_concurrent_insert.inc b/mysql-test/include/check_no_concurrent_insert.inc index f60401bcad1..6938c53fd16 100644 --- a/mysql-test/include/check_no_concurrent_insert.inc +++ b/mysql-test/include/check_no_concurrent_insert.inc @@ -23,7 +23,7 @@ # Reset DEBUG_SYNC facility for safety. set debug_sync= "RESET"; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval create temporary table t_backup select * from $restore_table; } @@ -67,7 +67,7 @@ if (!$success) --eval delete from $table where i = 0; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval truncate table $restore_table; --eval insert into $restore_table select * from t_backup; diff --git a/mysql-test/include/get_relay_log_pos.inc b/mysql-test/include/get_relay_log_pos.inc index 7ce36fd3c50..61ee07fc655 100644 --- a/mysql-test/include/get_relay_log_pos.inc +++ b/mysql-test/include/get_relay_log_pos.inc @@ -10,12 +10,12 @@ # # at this point, get_relay_log_pos.inc sets $relay_log_pos. echo position # # in $relay_log_file: $relay_log_pos. -if (`SELECT '$relay_log_file' = ''`) +if (!$relay_log_file) { --die 'variable $relay_log_file is null' } -if (`SELECT '$master_log_pos' = ''`) +if (!$master_log_pos) { --die 'variable $master_log_pos is null' } diff --git a/mysql-test/include/kill_query.inc b/mysql-test/include/kill_query.inc index b303ed0ec39..1c949d3cbad 100644 --- a/mysql-test/include/kill_query.inc +++ b/mysql-test/include/kill_query.inc @@ -44,7 +44,7 @@ connection master; # kill the query that is waiting eval kill query $connection_id; -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { # release the lock to allow binlog continue eval SELECT RELEASE_LOCK($debug_lock); @@ -57,7 +57,7 @@ reap; connection master; -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { # get lock again to make the next query wait eval SELECT GET_LOCK($debug_lock, 10); diff --git a/mysql-test/include/kill_query_and_diff_master_slave.inc b/mysql-test/include/kill_query_and_diff_master_slave.inc index 611d6929c99..b3846d12df1 100644 --- a/mysql-test/include/kill_query_and_diff_master_slave.inc +++ b/mysql-test/include/kill_query_and_diff_master_slave.inc @@ -25,7 +25,7 @@ source include/kill_query.inc; connection master; disable_query_log; disable_result_log; -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { eval SELECT RELEASE_LOCK($debug_lock); } @@ -36,8 +36,8 @@ source include/diff_master_slave.inc; # Acquire the debug lock again if used connection master; -disable_query_log; disable_result_log; if (`SELECT '$debug_lock' != -''`) { eval SELECT GET_LOCK($debug_lock, 10); } enable_result_log; -enable_query_log; +disable_query_log; disable_result_log; +if ($debug_lock) { eval SELECT GET_LOCK($debug_lock, 10); } +enable_result_log; enable_query_log; connection $connection_name; diff --git a/mysql-test/include/setup_fake_relay_log.inc b/mysql-test/include/setup_fake_relay_log.inc index fb035941a29..f881f3bf4e8 100644 --- a/mysql-test/include/setup_fake_relay_log.inc +++ b/mysql-test/include/setup_fake_relay_log.inc @@ -56,7 +56,7 @@ if (`SELECT "$_sql_running" = "Yes" OR "$_io_running" = "Yes"`) { # Read server variables. let $MYSQLD_DATADIR= `SELECT @@datadir`; let $_fake_filename= query_get_value(SHOW VARIABLES LIKE 'relay_log', Value, 1); -if (`SELECT '$_fake_filename' = ''`) { +if (!$_fake_filename) { --echo Badly written test case: relay_log variable is empty. Please use the --echo server option --relay-log=FILE. } diff --git a/mysql-test/include/show_binlog_events.inc b/mysql-test/include/show_binlog_events.inc index 8649f31ad9f..6d8c8196102 100644 --- a/mysql-test/include/show_binlog_events.inc +++ b/mysql-test/include/show_binlog_events.inc @@ -27,14 +27,14 @@ if (!$binlog_start) } --let $_statement=show binlog events -if (`SELECT '$binlog_file' <> ''`) +if ($binlog_file) { --let $_statement= $_statement in '$binlog_file' } --let $_statement= $_statement from $binlog_start -if (`SELECT '$binlog_limit' <> ''`) +if ($binlog_limit) { --let $_statement= $_statement limit $binlog_limit } diff --git a/mysql-test/include/show_rpl_debug_info.inc b/mysql-test/include/show_rpl_debug_info.inc index 148d11f3b02..9944e6cd25f 100644 --- a/mysql-test/include/show_rpl_debug_info.inc +++ b/mysql-test/include/show_rpl_debug_info.inc @@ -48,13 +48,13 @@ let $binlog_name= query_get_value("SHOW MASTER STATUS", File, 1); eval SHOW BINLOG EVENTS IN '$binlog_name'; let $_master_con= $master_connection; -if (`SELECT '$_master_con' = ''`) +if (!$_master_con) { if (`SELECT '$_con' = 'slave'`) { let $_master_con= master; } - if (`SELECT '$_master_con' = ''`) + if (!$_master_con) { --echo Unable to determine master connection. No debug info printed for master. --echo Please fix the test case by setting $master_connection before sourcing @@ -62,7 +62,7 @@ if (`SELECT '$_master_con' = ''`) } } -if (`SELECT '$_master_con' != ''`) +if ($_master_con) { let $master_binlog_name_io= query_get_value("SHOW SLAVE STATUS", Master_Log_File, 1); diff --git a/mysql-test/include/wait_for_slave_io_error.inc b/mysql-test/include/wait_for_slave_io_error.inc index 34cbf20a73b..ffdcf752873 100644 --- a/mysql-test/include/wait_for_slave_io_error.inc +++ b/mysql-test/include/wait_for_slave_io_error.inc @@ -31,7 +31,7 @@ # $master_connection # See wait_for_slave_param.inc for description. -if (`SELECT '$slave_io_errno' = ''`) { +if (!$slave_io_errno) { --die !!!ERROR IN TEST: you must set \$slave_io_errno before sourcing wait_for_slave_io_error.inc } diff --git a/mysql-test/include/wait_for_slave_param.inc b/mysql-test/include/wait_for_slave_param.inc index ef864f9245e..98cd426fa11 100644 --- a/mysql-test/include/wait_for_slave_param.inc +++ b/mysql-test/include/wait_for_slave_param.inc @@ -51,7 +51,7 @@ if (!$_slave_timeout_counter) } let $_slave_param_comparison= $slave_param_comparison; -if (`SELECT '$_slave_param_comparison' = ''`) +if (!$_slave_param_comparison) { let $_slave_param_comparison= =; } @@ -71,7 +71,7 @@ while (`SELECT NOT('$_show_slave_status_value' $_slave_param_comparison '$slave_ if (!$_slave_timeout_counter) { --echo **** ERROR: timeout after $slave_timeout seconds while waiting for slave parameter $slave_param $_slave_param_comparison $slave_param_value **** - if (`SELECT '$slave_error_message' != ''`) + if ($slave_error_message) { --echo Message: $slave_error_message } diff --git a/mysql-test/include/wait_for_slave_sql_error.inc b/mysql-test/include/wait_for_slave_sql_error.inc index aab04036eea..80836f908c6 100644 --- a/mysql-test/include/wait_for_slave_sql_error.inc +++ b/mysql-test/include/wait_for_slave_sql_error.inc @@ -24,7 +24,7 @@ # $master_connection # See wait_for_slave_param.inc for description. -if (`SELECT '$slave_sql_errno' = ''`) { +if (!$slave_sql_errno) { --die !!!ERROR IN TEST: you must set \$slave_sql_errno before sourcing wait_for_slave_sql_error.inc } diff --git a/mysql-test/include/wait_for_status_var.inc b/mysql-test/include/wait_for_status_var.inc index 8b644c2c3c5..9f4962aeaed 100644 --- a/mysql-test/include/wait_for_status_var.inc +++ b/mysql-test/include/wait_for_status_var.inc @@ -45,7 +45,7 @@ if (!$_status_timeout_counter) } let $_status_var_comparsion= $status_var_comparsion; -if (`SELECT '$_status_var_comparsion' = ''`) +if (!$_status_var_comparsion) { let $_status_var_comparsion= =; } diff --git a/mysql-test/suite/rpl/t/rpl_killed_ddl.test b/mysql-test/suite/rpl/t/rpl_killed_ddl.test index 61b882efcf3..69648267ca4 100644 --- a/mysql-test/suite/rpl/t/rpl_killed_ddl.test +++ b/mysql-test/suite/rpl/t/rpl_killed_ddl.test @@ -119,7 +119,7 @@ echo [on master]; # This will block the execution of a statement at the DBUG_SYNC_POINT # with given lock name -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { disable_query_log; disable_result_log; From 6c1d9fd9a90117a1f8e605ec881d890618b51ac9 Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Thu, 21 Oct 2010 12:29:00 -0500 Subject: [PATCH 123/151] Fix an error introduced in a follow-up fix of Bug#57232 by Sunny Bains revno: 3185 revid: sunny.bains@oracle.com-20101018060544-wo81q6kbl3la1uq0 --- storage/innobase/os/os0sync.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 5c400ae31c5..65fdd49f839 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -136,7 +136,7 @@ os_cond_wait_timed( #ifndef __WIN__ const struct timespec* abstime /*!< in: timeout */ #else - ulint time_in_ms /*!< in: timeout in + DWORD time_in_ms /*!< in: timeout in milliseconds*/ #endif /* !__WIN__ */ ) @@ -655,7 +655,7 @@ os_event_wait_time_low( ut_a(event); if (time_in_usec != OS_SYNC_INFINITE_TIME) { - time_in_ms = time_in_ms / 1000; + time_in_ms = time_in_usec / 1000; err = WaitForSingleObject(event->handle, time_in_ms); } else { err = WaitForSingleObject(event->handle, INFINITE); From 1291c004775458f2f35e24730c9694f99b5b54d7 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 21 Oct 2010 23:34:57 -0700 Subject: [PATCH 124/151] Fix Bug #56791 Remove ios_mutex from InnoDB code rb://495 approved by Inaam --- storage/innobase/handler/ha_innodb.cc | 1 - storage/innobase/include/sync0sync.h | 1 - storage/innobase/srv/srv0start.c | 18 ------------------ 3 files changed, 20 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 97ddbfc8199..74c83e8d44b 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -240,7 +240,6 @@ static PSI_mutex_info all_innodb_mutexes[] = { {&ibuf_mutex_key, "ibuf_mutex", 0}, {&ibuf_pessimistic_insert_mutex_key, "ibuf_pessimistic_insert_mutex", 0}, - {&ios_mutex_key, "ios_mutex", 0}, {&kernel_mutex_key, "kernel_mutex", 0}, {&log_sys_mutex_key, "log_sys_mutex", 0}, # ifdef UNIV_MEM_DEBUG diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h index 940e583350a..fb3a24c5ee5 100644 --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h @@ -85,7 +85,6 @@ extern mysql_pfs_key_t hash_table_mutex_key; extern mysql_pfs_key_t ibuf_bitmap_mutex_key; extern mysql_pfs_key_t ibuf_mutex_key; extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key; -extern mysql_pfs_key_t ios_mutex_key; extern mysql_pfs_key_t log_sys_mutex_key; extern mysql_pfs_key_t log_flush_order_mutex_key; extern mysql_pfs_key_t kernel_mutex_key; diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index 67586de736c..d7ea3d5d3da 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -120,11 +120,6 @@ UNIV_INTERN enum srv_shutdown_state srv_shutdown_state = SRV_SHUTDOWN_NONE; /** Files comprising the system tablespace */ static os_file_t files[1000]; -/** Mutex protecting the ios count */ -static mutex_t ios_mutex; -/** Count of I/O operations in io_handler_thread() */ -static ulint ios; - /** io_handler_thread parameters for thread identification */ static ulint n[SRV_MAX_N_IO_THREADS + 6]; /** io_handler_thread identifiers */ @@ -152,11 +147,6 @@ UNIV_INTERN mysql_pfs_key_t srv_master_thread_key; UNIV_INTERN mysql_pfs_key_t srv_purge_thread_key; #endif /* UNIV_PFS_THREAD */ -#ifdef UNIV_PFS_MUTEX -/* Key to register ios_mutex_key with performance schema */ -UNIV_INTERN mysql_pfs_key_t ios_mutex_key; -#endif /* UNIV_PFS_MUTEX */ - /*********************************************************************//** Convert a numeric string that optionally ends in G or M, to a number containing megabytes. @@ -491,10 +481,6 @@ io_handler_thread( while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) { fil_aio_wait(segment); - - mutex_enter(&ios_mutex); - ios++; - mutex_exit(&ios_mutex); } /* We count the number of threads in os_thread_exit(). A created @@ -998,10 +984,6 @@ skip_size_check: srv_data_file_is_raw_partition[i] != 0); } - ios = 0; - - mutex_create(ios_mutex_key, &ios_mutex, SYNC_NO_ORDER_CHECK); - return(DB_SUCCESS); } From d63cbdde8e55399c1a5e677aab1cc22a35519a42 Mon Sep 17 00:00:00 2001 From: "Horst.Hunger" Date: Fri, 22 Oct 2010 10:20:17 +0200 Subject: [PATCH 125/151] Due to issues with merge. --- mysql-test/r/plugin_auth_qa_2.result | 18 +++++++++--------- mysql-test/r/plugin_auth_qa_3.result | 4 ++-- mysql-test/t/plugin_auth_qa_1.test | 18 ++++++++++++------ mysql-test/t/plugin_auth_qa_2.test | 18 +++++++++--------- mysql-test/t/plugin_auth_qa_3.test | 4 ++-- 5 files changed, 34 insertions(+), 28 deletions(-) diff --git a/mysql-test/r/plugin_auth_qa_2.result b/mysql-test/r/plugin_auth_qa_2.result index a73cc25418c..daefdaafabc 100644 --- a/mysql-test/r/plugin_auth_qa_2.result +++ b/mysql-test/r/plugin_auth_qa_2.result @@ -15,7 +15,7 @@ NULL SELECT @@external_user; @@external_user NULL -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 current_user() user() @@local.proxy_user @@local.external_user qa_test_1_user@% qa_test_1_user@localhost NULL NULL SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; @@ -42,7 +42,7 @@ NULL SELECT @@external_user; @@external_user NULL -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 current_user() user() @@local.proxy_user @@local.external_user authenticated_as@% user_name@localhost 'qa_test_2_user'@'%' 'qa_test_2_user'@'%' SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; @@ -58,7 +58,7 @@ CREATE USER qa_test_3_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_3_dest' CREATE USER qa_test_3_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_3_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_3_dest TO qa_test_3_user; -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 current_user() user() @@local.proxy_user @@local.external_user qa_test_3_dest@% qa_test_3_user@localhost 'qa_test_3_user'@'%' 'qa_test_3_user'@'%' DROP USER qa_test_3_user; @@ -68,7 +68,7 @@ CREATE USER qa_test_4_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_4_dest' CREATE USER qa_test_4_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_4_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_4_dest TO qa_test_4_user; -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 current_user() user() @@local.proxy_user @@local.external_user qa_test_4_dest@% qa_test_4_user@localhost 'qa_test_4_user'@'%' 'qa_test_4_user'@'%' DROP USER qa_test_4_user; @@ -86,7 +86,7 @@ user plugin authentication_string password *DFCACE76914AD7BD801FC1A1ECF6562272621A22 qa_test_5_user qa_auth_interface qa_test_5_dest qa_test_5_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'qa_test_5_user'@'localhost' (using password: YES) DROP USER qa_test_5_user; DROP USER qa_test_5_dest; @@ -103,7 +103,7 @@ root root qa_test_6_user qa_auth_interface qa_test_6_dest qa_test_6_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'qa_test_6_user'@'localhost' (using password: YES) GRANT PROXY ON qa_test_6_dest TO root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; SELECT user,plugin,authentication_string,password FROM mysql.user; @@ -114,7 +114,7 @@ root qa_test_6_user qa_auth_interface qa_test_6_dest qa_test_6_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 root qa_auth_interface qa_test_6_dest -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) REVOKE PROXY ON qa_test_6_dest FROM root; SELECT user,plugin,authentication_string FROM mysql.user; @@ -125,7 +125,7 @@ root qa_test_6_user qa_auth_interface qa_test_6_dest qa_test_6_dest root qa_auth_interface qa_test_6_dest -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) DROP USER qa_test_6_user; DROP USER qa_test_6_dest; @@ -140,7 +140,7 @@ CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_11_des CREATE USER qa_test_11_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; -exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P 13000 -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'qa_test_11_user'@'localhost' (using password: YES) DROP USER qa_test_11_user, qa_test_11_dest; DROP DATABASE test_user_db; diff --git a/mysql-test/r/plugin_auth_qa_3.result b/mysql-test/r/plugin_auth_qa_3.result index 92d47bcf580..d94d8879e7d 100644 --- a/mysql-test/r/plugin_auth_qa_3.result +++ b/mysql-test/r/plugin_auth_qa_3.result @@ -2,10 +2,10 @@ CREATE DATABASE test_user_db; CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_server AS 'qa_test_11_dest'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; -exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P 13000 -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 current_user() user() @@local.proxy_user @@local.external_user qa_test_11_dest@% qa_test_11_user@localhost 'qa_test_11_user'@'%' 'qa_test_11_user'@'%' -exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P 13000 -u qa_test_2_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P MASTER_MYPORT -u qa_test_2_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'qa_test_2_user'@'localhost' (using password: NO) DROP USER qa_test_11_user, qa_test_11_dest; DROP DATABASE test_user_db; diff --git a/mysql-test/t/plugin_auth_qa_1.test b/mysql-test/t/plugin_auth_qa_1.test index d7a7afe9407..c33c4c22893 100644 --- a/mysql-test/t/plugin_auth_qa_1.test +++ b/mysql-test/t/plugin_auth_qa_1.test @@ -14,7 +14,8 @@ SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; CREATE USER plug_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; GRANT PROXY ON plug_dest TO plug_user; ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 REVOKE PROXY ON plug_dest FROM plug_user; --error 1 --exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 @@ -29,11 +30,13 @@ GRANT PROXY ON plug_dest TO plug_user; --sorted_result SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; --echo 1) ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' IDENTIFIED WITH test_plugin_server AS 'plug_dest'; --echo 2) ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 REVOKE PROXY ON plug_dest FROM plug_user; --echo 3) --error 1 @@ -49,7 +52,8 @@ CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; --exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 GRANT PROXY ON plug_dest TO plug_user; --echo 2) ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' IDENTIFIED WITH test_plugin_server AS 'plug_dest'; #REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_dest' @@ -63,7 +67,8 @@ GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; GRANT PROXY ON plug_dest TO plug_user; ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +--replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 RENAME USER plug_dest TO new_dest; --error 1 --exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 @@ -81,7 +86,8 @@ CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; --error 1 --exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 GRANT PROXY ON plug_dest TO plug_user; ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +--replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 RENAME USER plug_dest TO new_dest; --error 1 --exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 diff --git a/mysql-test/t/plugin_auth_qa_2.test b/mysql-test/t/plugin_auth_qa_2.test index 053e89166b7..135b187f6ee 100644 --- a/mysql-test/t/plugin_auth_qa_2.test +++ b/mysql-test/t/plugin_auth_qa_2.test @@ -20,7 +20,7 @@ SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; SELECT @@proxy_user; SELECT @@external_user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --sorted_result @@ -42,7 +42,7 @@ SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; SELECT @@proxy_user; SELECT @@external_user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --sorted_result @@ -59,7 +59,7 @@ CREATE USER qa_test_3_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_3_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_3_dest TO qa_test_3_user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 DROP USER qa_test_3_user; @@ -72,7 +72,7 @@ CREATE USER qa_test_4_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_4_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_4_dest TO qa_test_4_user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 DROP USER qa_test_4_user; @@ -90,7 +90,7 @@ GRANT PROXY ON qa_test_5_dest TO ''@'localhost'; SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --error 1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 @@ -107,21 +107,21 @@ GRANT PROXY ON qa_test_6_dest TO qa_test_6_user; SELECT user,plugin,authentication_string,password FROM mysql.user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --error 1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 GRANT PROXY ON qa_test_6_dest TO root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; SELECT user,plugin,authentication_string,password FROM mysql.user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --error 1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 REVOKE PROXY ON qa_test_6_dest FROM root; SELECT user,plugin,authentication_string FROM mysql.user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --error 1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 @@ -138,7 +138,7 @@ CREATE USER qa_test_11_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; ---echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --error 1 --exec $MYSQL $PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 diff --git a/mysql-test/t/plugin_auth_qa_3.test b/mysql-test/t/plugin_auth_qa_3.test index 4fe02f10ba6..f7d90226332 100644 --- a/mysql-test/t/plugin_auth_qa_3.test +++ b/mysql-test/t/plugin_auth_qa_3.test @@ -12,10 +12,10 @@ CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_server AS 'qa_test_11_dest'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; ---echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --exec $MYSQL $PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ---echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P MASTER_MYPORT -u qa_test_2_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --error 1 --exec $MYSQL $PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 From 06c49d571be82ca927b9c37d96ab8353bd87359d Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 23 Oct 2010 20:55:44 +0800 Subject: [PATCH 126/151] Bug#27606 GRANT statement should be replicated with DEFINER information "Grantor" columns' data is lost when replicating mysql.tables_priv. Slave SQL thread used its default user ''@'' as the grantor of GRANT|REVOKE statements executing on it. In this patch, current user is put in query log event for all GRANT and REVOKE statement, SQL thread uses the user in query log event as grantor. mysql-test/suite/rpl/r/rpl_do_grant.result: Add test for this bug. mysql-test/suite/rpl/t/rpl_do_grant.test: Add test for this bug. sql/log_event.cc: Refactoring THD::current_user_used and related functions. current_user_used is used to judge if current user should be binlogged in query log event. So it is better to call it m_binlog_invoker. The related functions are renamed too. sql/sql_class.cc: Refactoring THD::current_user_used and related functions. current_user_used is used to judge if current user should be binlogged in query log event. So it is better to call it m_binlog_invoker. The related functions are renamed too. sql/sql_class.h: Refactoring THD::current_user_used and related functions. current_user_used is used to judge if current user should be binlogged in query log event. So it is better to call it m_binlog_invoker. The related functions are renamed too. sql/sql_parse.cc: Call binlog_invoker() for GRANT and REVOKE statements. --- mysql-test/suite/rpl/r/rpl_do_grant.result | 23 ++++++++++++++++++++++ mysql-test/suite/rpl/t/rpl_do_grant.test | 21 ++++++++++++++++++++ sql/log_event.cc | 2 +- sql/sql_class.cc | 6 +++--- sql/sql_class.h | 7 +++---- sql/sql_parse.cc | 7 +++++++ 6 files changed, 58 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_do_grant.result b/mysql-test/suite/rpl/r/rpl_do_grant.result index 1cea2cfa9ad..6472294fe9d 100644 --- a/mysql-test/suite/rpl/r/rpl_do_grant.result +++ b/mysql-test/suite/rpl/r/rpl_do_grant.result @@ -260,4 +260,27 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; grant all on *.* to foo@"1.2.3.4" master-bin.000001 # Query # # use `test`; revoke all privileges, grant option from "foo" DROP USER foo@"1.2.3.4"; + +# Bug#27606 GRANT statement should be replicated with DEFINER information +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +GRANT SELECT, INSERT ON mysql.user TO user_bug27606@localhost; +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +Grantor +root@localhost +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +Grantor +root@localhost +REVOKE SELECT ON mysql.user FROM user_bug27606@localhost; +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +Grantor +root@localhost +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +Grantor +root@localhost +DROP USER user_bug27606@localhost; "End of test" diff --git a/mysql-test/suite/rpl/t/rpl_do_grant.test b/mysql-test/suite/rpl/t/rpl_do_grant.test index fb8ea35e869..c65eef6e939 100644 --- a/mysql-test/suite/rpl/t/rpl_do_grant.test +++ b/mysql-test/suite/rpl/t/rpl_do_grant.test @@ -355,4 +355,25 @@ revoke all privileges, grant option from "foo"; DROP USER foo@"1.2.3.4"; -- sync_slave_with_master +--echo +--echo # Bug#27606 GRANT statement should be replicated with DEFINER information +--connection master +--source include/master-slave-reset.inc +--connection master +GRANT SELECT, INSERT ON mysql.user TO user_bug27606@localhost; + +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +sync_slave_with_master; +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; + +--connection master +REVOKE SELECT ON mysql.user FROM user_bug27606@localhost; +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +sync_slave_with_master; +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; + +--connection master +DROP USER user_bug27606@localhost; + +--source include/master-slave-end.inc --echo "End of test" diff --git a/sql/log_event.cc b/sql/log_event.cc index 041f90a057f..d0635ddac1a 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2314,7 +2314,7 @@ bool Query_log_event::write(IO_CACHE* file) start+= 4; } - if (thd && thd->is_current_user_used()) + if (thd && thd->need_binlog_invoker()) { LEX_STRING user; LEX_STRING host; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 44bb6d51c6c..a61ce7bfd14 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -738,7 +738,7 @@ THD::THD() thr_lock_owner_init(&main_lock_id, &lock_info); m_internal_handler= NULL; - current_user_used= FALSE; + m_binlog_invoker= FALSE; memset(&invoker_user, 0, sizeof(invoker_user)); memset(&invoker_host, 0, sizeof(invoker_host)); } @@ -1247,7 +1247,7 @@ void THD::cleanup_after_query() where= THD::DEFAULT_WHERE; /* reset table map for multi-table update */ table_map_for_update= 0; - clean_current_user_used(); + m_binlog_invoker= FALSE; } @@ -3281,7 +3281,7 @@ void THD::set_query(char *query_arg, uint32 query_length_arg) void THD::get_definer(LEX_USER *definer) { - set_current_user_used(); + binlog_invoker(); #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) if (slave_thread && has_invoker()) { diff --git a/sql/sql_class.h b/sql/sql_class.h index 42c873e9fc3..774ae4abac4 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2344,9 +2344,8 @@ public: Protected with LOCK_thd_data mutex. */ void set_query(char *query_arg, uint32 query_length_arg); - void set_current_user_used() { current_user_used= TRUE; } - bool is_current_user_used() { return current_user_used; } - void clean_current_user_used() { current_user_used= FALSE; } + void binlog_invoker() { m_binlog_invoker= TRUE; } + bool need_binlog_invoker() { return m_binlog_invoker; } void get_definer(LEX_USER *definer); void set_invoker(const LEX_STRING *user, const LEX_STRING *host) { @@ -2384,7 +2383,7 @@ private: Current user will be binlogged into Query_log_event if current_user_used is TRUE; It will be stored into invoker_host and invoker_user by SQL thread. */ - bool current_user_used; + bool m_binlog_invoker; /** It points to the invoker in the Query_log_event. diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b38cdf4a983..7cf64134d70 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3923,6 +3923,10 @@ end_with_restore_list: if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) && check_global_access(thd,CREATE_USER_ACL)) break; + + /* Replicate current user as grantor */ + thd->binlog_invoker(); + /* Conditionally writes to binlog */ if (!(res = mysql_revoke_all(thd, lex->users_list))) my_ok(thd); @@ -3943,6 +3947,9 @@ end_with_restore_list: is_schema_db(select_lex->db) : 0)) goto error; + /* Replicate current user as grantor */ + thd->binlog_invoker(); + if (thd->security_ctx->user) // If not replication { LEX_USER *user, *tmp_user; From 112684b0ba31dbdc3f3b914a7f738793d28431fd Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Sun, 24 Oct 2010 22:51:21 -0700 Subject: [PATCH 127/151] Fix bug #57700 Latching order violation in row_truncate_table_for_mysql(). Approved by Sunny Bains --- storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/row/row0mysql.c | 23 ++++++++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index cccd5c0550a..9033e5557f3 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-10-24 The InnoDB Team + + * row/row0mysql.c + Fix Bug #57700 Latching order violation in + row_truncate_table_for_mysql() + 2010-10-20 The InnoDB Team * dict/dict0load.c diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index 107af481b79..827be32bdf7 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -2771,15 +2771,6 @@ row_truncate_table_for_mysql( trx->table_id = table->id; - /* Lock all index trees for this table, as we will - truncate the table/index and possibly change their metadata. - All DML/DDL are blocked by table level lock, with - a few exceptions such as queries into information schema - about the table, MySQL could try to access index stats - for this kind of query, we need to use index locks to - sync up */ - dict_table_x_lock_indexes(table); - if (table->space && !table->dir_path_of_temp_table) { /* Discard and create the single-table tablespace. */ ulint space = table->space; @@ -2792,6 +2783,11 @@ row_truncate_table_for_mysql( dict_hdr_get_new_id(NULL, NULL, &space); + /* Lock all index trees for this table. We must + do so after dict_hdr_get_new_id() to preserve + the latch order */ + dict_table_x_lock_indexes(table); + if (space == ULINT_UNDEFINED || fil_create_new_single_table_tablespace( space, table->name, FALSE, flags, @@ -2825,6 +2821,15 @@ row_truncate_table_for_mysql( FIL_IBD_FILE_INITIAL_SIZE, &mtr); mtr_commit(&mtr); } + } else { + /* Lock all index trees for this table, as we will + truncate the table/index and possibly change their metadata. + All DML/DDL are blocked by table level lock, with + a few exceptions such as queries into information schema + about the table, MySQL could try to access index stats + for this kind of query, we need to use index locks to + sync up */ + dict_table_x_lock_indexes(table); } /* scan SYS_INDEXES for all indexes of the table */ From 06a263e2b32bd6b5440933b4cec3eff37053cef7 Mon Sep 17 00:00:00 2001 From: "Horst.Hunger" Date: Mon, 25 Oct 2010 12:24:26 +0200 Subject: [PATCH 128/151] Due to failing on Freebsd. --- mysql-test/r/plugin_auth_qa_2.result | 30 ++++++++++++++++------------ mysql-test/t/plugin_auth_qa_1.test | 16 +++++++-------- mysql-test/t/plugin_auth_qa_2.test | 5 +++++ 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/plugin_auth_qa_2.result b/mysql-test/r/plugin_auth_qa_2.result index daefdaafabc..99fe9c6f5a9 100644 --- a/mysql-test/r/plugin_auth_qa_2.result +++ b/mysql-test/r/plugin_auth_qa_2.result @@ -84,8 +84,8 @@ GRANT PROXY ON qa_test_5_dest TO ''@'localhost'; SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; user plugin authentication_string password *DFCACE76914AD7BD801FC1A1ECF6562272621A22 -qa_test_5_user qa_auth_interface qa_test_5_dest qa_test_5_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +qa_test_5_user qa_auth_interface qa_test_5_dest exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'qa_test_5_user'@'localhost' (using password: YES) DROP USER qa_test_5_user; @@ -98,32 +98,35 @@ GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_6_dest identified by 'dest_pas GRANT PROXY ON qa_test_6_dest TO qa_test_6_user; SELECT user,plugin,authentication_string,password FROM mysql.user; user plugin authentication_string password -root -root -root -qa_test_6_user qa_auth_interface qa_test_6_dest qa_test_6_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +qa_test_6_user qa_auth_interface qa_test_6_dest +root +root +root +root exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'qa_test_6_user'@'localhost' (using password: YES) GRANT PROXY ON qa_test_6_dest TO root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; SELECT user,plugin,authentication_string,password FROM mysql.user; user plugin authentication_string password -root -root -root -qa_test_6_user qa_auth_interface qa_test_6_dest qa_test_6_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +qa_test_6_user qa_auth_interface qa_test_6_dest +root +root +root +root root qa_auth_interface qa_test_6_dest exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) REVOKE PROXY ON qa_test_6_dest FROM root; SELECT user,plugin,authentication_string FROM mysql.user; user plugin authentication_string -root -root -root -qa_test_6_user qa_auth_interface qa_test_6_dest qa_test_6_dest +qa_test_6_user qa_auth_interface qa_test_6_dest +root +root +root +root root qa_auth_interface qa_test_6_dest exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) @@ -135,6 +138,7 @@ user plugin authentication_string password root root root +root === Test of the --default_auth option for clients ==== CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_11_dest'; CREATE USER qa_test_11_dest IDENTIFIED BY 'dest_passwd'; diff --git a/mysql-test/t/plugin_auth_qa_1.test b/mysql-test/t/plugin_auth_qa_1.test index c33c4c22893..06908935b01 100644 --- a/mysql-test/t/plugin_auth_qa_1.test +++ b/mysql-test/t/plugin_auth_qa_1.test @@ -18,7 +18,7 @@ GRANT PROXY ON plug_dest TO plug_user; --exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 REVOKE PROXY ON plug_dest FROM plug_user; --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 DROP USER plug_user,plug_dest; # # GRANT...WITH @@ -40,7 +40,7 @@ REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' REVOKE PROXY ON plug_dest FROM plug_user; --echo 3) --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 DROP USER plug_user,plug_dest; # # GRANT...WITH/CREATE...BY @@ -49,7 +49,7 @@ GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; --echo 1) --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 GRANT PROXY ON plug_dest TO plug_user; --echo 2) --replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT @@ -71,10 +71,10 @@ GRANT PROXY ON plug_dest TO plug_user; --exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 RENAME USER plug_dest TO new_dest; --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 GRANT PROXY ON new_dest TO plug_user; --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=new_dest -e "SELECT current_user();SELECT user();" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=new_dest -e "SELECT current_user();SELECT user();" 2>&1 --sorted_result SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; DROP USER plug_user,new_dest; @@ -84,16 +84,16 @@ CREATE USER plug_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 GRANT PROXY ON plug_dest TO plug_user; --replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT --exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 RENAME USER plug_dest TO new_dest; --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 GRANT PROXY ON new_dest TO plug_user; --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=new_dest -e "SELECT current_user();SELECT user();" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=new_dest -e "SELECT current_user();SELECT user();" 2>&1 --sorted_result SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; DROP USER plug_user,new_dest; diff --git a/mysql-test/t/plugin_auth_qa_2.test b/mysql-test/t/plugin_auth_qa_2.test index 135b187f6ee..e265690dc7d 100644 --- a/mysql-test/t/plugin_auth_qa_2.test +++ b/mysql-test/t/plugin_auth_qa_2.test @@ -88,6 +88,7 @@ GRANT ALL PRIVILEGES ON test_user_db.* TO ''@'localhost' identified by 'dest_pas GRANT PROXY ON qa_test_5_dest TO qa_test_5_user; GRANT PROXY ON qa_test_5_dest TO ''@'localhost'; +--sorted_result SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; --echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 @@ -105,6 +106,7 @@ CREATE USER qa_test_6_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_6_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_6_dest TO qa_test_6_user; +--sorted_result SELECT user,plugin,authentication_string,password FROM mysql.user; --echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 @@ -112,6 +114,7 @@ SELECT user,plugin,authentication_string,password FROM mysql.user; --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 GRANT PROXY ON qa_test_6_dest TO root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; +--sorted_result SELECT user,plugin,authentication_string,password FROM mysql.user; --echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 @@ -119,6 +122,7 @@ SELECT user,plugin,authentication_string,password FROM mysql.user; --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 REVOKE PROXY ON qa_test_6_dest FROM root; +--sorted_result SELECT user,plugin,authentication_string FROM mysql.user; --echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 @@ -128,6 +132,7 @@ SELECT user,plugin,authentication_string FROM mysql.user; DROP USER qa_test_6_user; DROP USER qa_test_6_dest; DELETE FROM mysql.user WHERE user='root' AND plugin='qa_auth_interface'; +--sorted_result SELECT user,plugin,authentication_string,password FROM mysql.user; From 56354413f86be103ce6c30aed879562894fb28e6 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 25 Oct 2010 14:07:28 +0200 Subject: [PATCH 129/151] Revert simplified if() in mysql-test/include/show_events.inc --- mysql-test/include/show_events.inc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mysql-test/include/show_events.inc b/mysql-test/include/show_events.inc index df17534eb82..ff5a7105c24 100644 --- a/mysql-test/include/show_events.inc +++ b/mysql-test/include/show_events.inc @@ -25,7 +25,9 @@ if ($binlog_file) --let $_statement= $_statement from $binlog_start -if ($binlog_limit) +# Cannot use if($binlog_limit) since the variable may begin with a 0 + +if (`SELECT '$binlog_limit' <> ''`) { --let $_statement= $_statement limit $binlog_limit } From 4b36063336775fa892a2b6b9b47d8b27ae44b4de Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Mon, 25 Oct 2010 14:30:07 +0200 Subject: [PATCH 130/151] Bug#54569 Some options are not allowed to take argument when passed with loose- prefix Boolean options cause parsing failures when they are given with prefix loose- and an argument, either in the command line or in configuration file. The reason was a faulty logic which forced the parsing to throw an error when an argument of type NO_ARG was used together with an argument which has been identified as a key-value pair. Despite the attribute NO_ARG these options actually take arguments if they are of type BOOL. include/my_getopt.h: * More comments to help future refactoring mysys/my_getopt.c: * removed if-statement which prevented logic for handling boolean types with arguments to be executed. * Added comments to aid in future refactoring. --- include/my_getopt.h | 7 +++++++ mysys/my_getopt.c | 22 +++++++++------------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/include/my_getopt.h b/include/my_getopt.h index 5eb0004e9c3..47feb21d85e 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -39,6 +39,13 @@ C_MODE_START #define GET_ASK_ADDR 128 #define GET_TYPE_MASK 127 +/** + Enumeration of the my_option::arg_type attributes. + It should be noted that for historical reasons variables with the combination + arg_type=NO_ARG, my_option::var_type=GET_BOOL still accepts + arguments. This is someone counter intuitive and care should be taken + if the code is refactored. +*/ enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG }; struct st_typelib; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 2ec2f8eb5c9..5e66d2fc189 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -360,14 +360,6 @@ int handle_options(int *argc, char ***argv, } return EXIT_OPTION_DISABLED; } - if (must_be_var && optp->arg_type == NO_ARG) - { - if (my_getopt_print_errors) - my_getopt_error_reporter(ERROR_LEVEL, - "%s: option '%s' cannot take an argument", - my_progname, optp->name); - return EXIT_NO_ARGUMENT_ALLOWED; - } error= 0; value= optp->var_type & GET_ASK_ADDR ? (*getopt_get_addr)(key_name, (uint) strlen(key_name), optp, &error) : @@ -377,6 +369,11 @@ int handle_options(int *argc, char ***argv, if (optp->arg_type == NO_ARG) { + /* + Due to historical reasons GET_BOOL var_types still accepts arguments + despite the NO_ARG arg_type attribute. This can seems a bit unintuitive + and care should be taken when refactoring this code. + */ if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL) { if (my_getopt_print_errors) @@ -391,7 +388,7 @@ int handle_options(int *argc, char ***argv, Set bool to 1 if no argument or if the user has used --enable-'option-name'. *optend was set to '0' if one used --disable-option - */ + */ (*argc)--; if (!optend || *optend == '1' || !my_strcasecmp(&my_charset_latin1, optend, "true")) @@ -418,10 +415,9 @@ int handle_options(int *argc, char ***argv, else if (optp->arg_type == REQUIRED_ARG && !optend) { /* Check if there are more arguments after this one, - - Note: options loaded from config file that requires value - should always be in the form '--option=value'. - */ + Note: options loaded from config file that requires value + should always be in the form '--option=value'. + */ if (!is_cmdline_arg || !*++pos) { if (my_getopt_print_errors) From 56f6599e7c3f3b8ea0edf223c96557e111672257 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Mon, 25 Oct 2010 17:08:27 +0200 Subject: [PATCH 131/151] Bug#45288: pb2 returns a lot of compilation warnings sql/sql_lex.h:1437: warning: control reaches end of non-void function sql/sql_lex.h: Make compiler happy, by adding a return statement. --- sql/sql_lex.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 0f93275434d..c20c2f0bca2 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1389,6 +1389,7 @@ public: STMT_ACCESS_TABLE_COUNT }; +#ifndef DBUG_OFF static inline const char *stmt_accessed_table_string(enum_stmt_accessed_table accessed_table) { switch (accessed_table) @@ -1422,7 +1423,10 @@ public: DBUG_ASSERT(0); break; } + MY_ASSERT_UNREACHABLE(); + return ""; } +#endif /* DBUG */ #define BINLOG_DIRECT_ON 0xF0 /* unsafe when --binlog-direct-non-trans-updates From e86b6c0db40116cb0dc223999e45712e1b1908ef Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Tue, 26 Oct 2010 15:48:08 +0400 Subject: [PATCH 132/151] Patch for Bug#55850 (Trigger warnings not cleared). The problem was that the warnings risen by a trigger were not cleared upon successful completion. The warnings should be cleared if the trigger completes successfully. The fix is to skip merging warnings into caller's Warning Info for triggers. --- mysql-test/r/signal.result | 7 -- mysql-test/r/sp-error.result | 91 +++++++++----- mysql-test/r/trigger.result | 23 ---- mysql-test/suite/rpl/r/rpl_row_trig003.result | 6 - mysql-test/t/sp-error.test | 114 ++++++++++++------ sql/sp_head.cc | 26 +++- sql/sp_head.h | 2 +- 7 files changed, 162 insertions(+), 107 deletions(-) diff --git a/mysql-test/r/signal.result b/mysql-test/r/signal.result index 67bf9330451..cfa056d5d13 100644 --- a/mysql-test/r/signal.result +++ b/mysql-test/r/signal.result @@ -1379,9 +1379,6 @@ MESSAGE_TEXT = msg, MYSQL_ERRNO = 1012; end $$ insert into t1 values (1), (2) $$ -Warnings: -Warning 1012 This trigger SIGNAL a warning, a=1 -Warning 1012 This trigger SIGNAL a warning, a=2 drop trigger t1_ai $$ create trigger t1_ai after insert on t1 for each row begin @@ -1416,11 +1413,7 @@ MESSAGE_TEXT = NEW.msg, MYSQL_ERRNO = NEW.errno; end $$ insert into t1 set errno=1012, msg='Warning message 1 in trigger' $$ -Warnings: -Warning 1012 Warning message 1 in trigger insert into t1 set errno=1013, msg='Warning message 2 in trigger' $$ -Warnings: -Warning 1013 Warning message 2 in trigger drop table t1 $$ drop table if exists t1 $$ drop procedure if exists p1 $$ diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 7b8364379df..4e97429c48f 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1877,9 +1877,6 @@ DROP PROCEDURE p1; # # Bug#5889: Exit handler for a warning doesn't hide the warning in trigger # - -# - Case 1 - CREATE TABLE t1(a INT, b INT); INSERT INTO t1 VALUES (1, 2); CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW @@ -1889,40 +1886,13 @@ SET NEW.a = 10; SET NEW.a = 99999999999; END| UPDATE t1 SET b = 20; -Warnings: -Warning 1264 Out of range value for column 'a' at row 1 SHOW WARNINGS; Level Code Message -Warning 1264 Out of range value for column 'a' at row 1 SELECT * FROM t1; a b 10 20 DROP TRIGGER t1_bu; DROP TABLE t1; - -# - Case 2 - -CREATE TABLE t1(a INT); -CREATE TABLE t2(b CHAR(1)); -CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW -BEGIN -INSERT INTO t2 VALUES('ab'); # Produces a warning. -INSERT INTO t2 VALUES('b'); # Does not produce a warning, -# previous warning should be cleared. -END| -INSERT INTO t1 VALUES(0); -SHOW WARNINGS; -Level Code Message -SELECT * FROM t1; -a -0 -SELECT * FROM t2; -b -a -b -DROP TRIGGER t1_bi; -DROP TABLE t1; -DROP TABLE t2; # # Bug#9857: Stored procedures: handler for sqlwarning ignored # @@ -1961,3 +1931,64 @@ Warning 1365 Division by 0 DROP PROCEDURE p1; DROP PROCEDURE p2; SET sql_mode = @sql_mode_saved; +# +# Bug#55850: Trigger warnings not cleared. +# +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP PROCEDURE IF EXISTS p1; +CREATE TABLE t1(x SMALLINT, y SMALLINT, z SMALLINT); +CREATE TABLE t2(a SMALLINT, b SMALLINT, c SMALLINT, +d SMALLINT, e SMALLINT, f SMALLINT); +CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW +INSERT INTO t2(a, b, c) VALUES(99999, 99999, 99999); +CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW +INSERT INTO t2(d, e, f) VALUES(99999, 99999, 99999); +CREATE PROCEDURE p1() +INSERT INTO t1 VALUES(99999, 99999, 99999); + +CALL p1(); +Warnings: +Warning 1264 Out of range value for column 'x' at row 1 +Warning 1264 Out of range value for column 'y' at row 1 +Warning 1264 Out of range value for column 'z' at row 1 + +SHOW WARNINGS; +Level Code Message +Warning 1264 Out of range value for column 'x' at row 1 +Warning 1264 Out of range value for column 'y' at row 1 +Warning 1264 Out of range value for column 'z' at row 1 + +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; +# ---------------------------------------------------------------------- +CREATE TABLE t1(x SMALLINT, y SMALLINT, z SMALLINT); +CREATE TABLE t2(a SMALLINT, b SMALLINT, c SMALLINT NOT NULL); +CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW +BEGIN +INSERT INTO t2 VALUES( +CAST('111111 ' AS SIGNED), +CAST('222222 ' AS SIGNED), +NULL); +END| +CREATE PROCEDURE p1() +INSERT INTO t1 VALUES(99999, 99999, 99999); + +CALL p1(); +ERROR 23000: Column 'c' cannot be null + +SHOW WARNINGS; +Level Code Message +Warning 1264 Out of range value for column 'x' at row 1 +Warning 1264 Out of range value for column 'y' at row 1 +Warning 1264 Out of range value for column 'z' at row 1 +Warning 1292 Truncated incorrect INTEGER value: '111111 ' +Warning 1264 Out of range value for column 'a' at row 1 +Warning 1292 Truncated incorrect INTEGER value: '222222 ' +Warning 1264 Out of range value for column 'b' at row 1 +Error 1048 Column 'c' cannot be null + +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index b9b1c94ce1a..b24c5b87fa0 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -1072,8 +1072,6 @@ SELECT @x; NULL SET @x=2; UPDATE t1 SET i1 = @x; -Warnings: -Warning 1365 Division by 0 SELECT @x; @x NULL @@ -1085,9 +1083,6 @@ SELECT @x; NULL SET @x=4; UPDATE t1 SET i1 = @x; -Warnings: -Warning 1365 Division by 0 -Warning 1365 Division by 0 SELECT @x; @x NULL @@ -1198,8 +1193,6 @@ Warnings: Warning 1365 Division by 0 create trigger t1_bi before insert on t1 for each row set @a:=1/0| insert into t1 values(20, 20)| -Warnings: -Warning 1365 Division by 0 drop trigger t1_bi| create trigger t1_bi before insert on t1 for each row begin @@ -1218,8 +1211,6 @@ set @a:=1/0; end| set @check=0, @t4_bi_called=0, @t4_bu_called=0| insert into t1 values(30, 30)| -Warnings: -Warning 1365 Division by 0 select @check, @t4_bi_called, @t4_bu_called| @check @t4_bi_called @t4_bu_called 2 1 1 @@ -2090,12 +2081,8 @@ SELECT 1 FROM t1 c WHERE END// SET @bug51650 = 1; INSERT IGNORE INTO t2 VALUES(); -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed INSERT IGNORE INTO t1 SET b = '777'; INSERT IGNORE INTO t2 SET a = '111'; -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed SET @bug51650 = 1; INSERT IGNORE INTO t2 SET a = '777'; DROP TRIGGER trg1; @@ -2177,8 +2164,6 @@ SELECT 'ab' INTO a; SELECT 'a' INTO a; END| INSERT INTO t1 VALUES (1); -Warnings: -Warning 1265 Data truncated for column 'a' at row 1 DROP TRIGGER trg1; DROP TABLE t1; DROP TRIGGER IF EXISTS trg1; @@ -2196,20 +2181,12 @@ DECLARE trg2 CHAR; SELECT 'ab' INTO trg2; END| INSERT INTO t1 VALUES (0); -Warnings: -Warning 1265 Data truncated for column 'trg1' at row 1 -Warning 1265 Data truncated for column 'trg2' at row 1 SELECT * FROM t1; a 0 SHOW WARNINGS; Level Code Message INSERT INTO t1 VALUES (1),(2); -Warnings: -Warning 1265 Data truncated for column 'trg1' at row 1 -Warning 1265 Data truncated for column 'trg2' at row 1 -Warning 1265 Data truncated for column 'trg1' at row 1 -Warning 1265 Data truncated for column 'trg2' at row 1 DROP TRIGGER trg1; DROP TRIGGER trg2; DROP TABLE t1; diff --git a/mysql-test/suite/rpl/r/rpl_row_trig003.result b/mysql-test/suite/rpl/r/rpl_row_trig003.result index 131af933b41..43c2ecde2b4 100644 --- a/mysql-test/suite/rpl/r/rpl_row_trig003.result +++ b/mysql-test/suite/rpl/r/rpl_row_trig003.result @@ -69,15 +69,9 @@ INSERT INTO test.t2 VALUES(NULL,0,'Testing MySQL databases is a cool ', 'MySQL C UPDATE test.t1 SET b1 = 0 WHERE b1 = 1; INSERT INTO test.t2 VALUES(NULL,1,'This is an after update test.', 'If this works, total will not be zero on the master or slave',1.4321,5.221,0,YEAR(NOW()),NOW()); UPDATE test.t2 SET b1 = 0 WHERE b1 = 1; -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed INSERT INTO test.t1 VALUES(NULL,1,'add some more test data test.', 'and hope for the best', 3.321,5.221,0,YEAR(NOW()),NOW()); DELETE FROM test.t1 WHERE id = 1; -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed DELETE FROM test.t2 WHERE id = 1; -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed DROP TRIGGER test.t1_bi; DROP TRIGGER test.t2_ai; DROP TRIGGER test.t1_bu; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 13ca55a0127..6175fc53adf 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -2719,10 +2719,6 @@ DROP PROCEDURE p1; --echo # Bug#5889: Exit handler for a warning doesn't hide the warning in trigger --echo # ---echo ---echo # - Case 1 ---echo - CREATE TABLE t1(a INT, b INT); INSERT INTO t1 VALUES (1, 2); @@ -2747,36 +2743,6 @@ SELECT * FROM t1; DROP TRIGGER t1_bu; DROP TABLE t1; ---echo ---echo # - Case 2 ---echo - -CREATE TABLE t1(a INT); -CREATE TABLE t2(b CHAR(1)); - -delimiter |; - -CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW -BEGIN - INSERT INTO t2 VALUES('ab'); # Produces a warning. - - INSERT INTO t2 VALUES('b'); # Does not produce a warning, - # previous warning should be cleared. -END| - -delimiter ;| - -INSERT INTO t1 VALUES(0); - -SHOW WARNINGS; - -SELECT * FROM t1; -SELECT * FROM t2; - -DROP TRIGGER t1_bi; -DROP TABLE t1; -DROP TABLE t2; - --echo # --echo # Bug#9857: Stored procedures: handler for sqlwarning ignored --echo # @@ -2813,3 +2779,83 @@ SHOW WARNINGS; DROP PROCEDURE p1; DROP PROCEDURE p2; SET sql_mode = @sql_mode_saved; + +--echo # +--echo # Bug#55850: Trigger warnings not cleared. +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP PROCEDURE IF EXISTS p1; +--enable_warnings + +CREATE TABLE t1(x SMALLINT, y SMALLINT, z SMALLINT); +CREATE TABLE t2(a SMALLINT, b SMALLINT, c SMALLINT, + d SMALLINT, e SMALLINT, f SMALLINT); + +CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW + INSERT INTO t2(a, b, c) VALUES(99999, 99999, 99999); + +CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW + INSERT INTO t2(d, e, f) VALUES(99999, 99999, 99999); + +CREATE PROCEDURE p1() + INSERT INTO t1 VALUES(99999, 99999, 99999); + +# What happened before the patch was: +# - INSERT INTO t1 added 3 warnings about overflow in 'x', 'y' and 'z' columns; +# - t1_bi run and added 3 warnings about overflow in 'a', 'b' and 'c' columns; +# - t1_ai run and added 3 warnings about overflow in 'd', 'e' and 'f' columns; +# => we had 9 warnings. +# +# Now what happens is: +# - INSERT INTO t1 adds 3 warnings about overflow in 'x', 'y' and 'z' columns; +# - t1_bi adds 3 warnings about overflow in 'a', 'b' and 'c' columns; +# - The warnings added by triggers are cleared; +# - t1_ai run and added 3 warnings about overflow in 'd', 'e' and 'f' columns; +# - The warnings added by triggers are cleared; +# => we have 3 warnings. + +--echo +CALL p1(); + +--echo +SHOW WARNINGS; + +--echo +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; + +--echo # ---------------------------------------------------------------------- + +CREATE TABLE t1(x SMALLINT, y SMALLINT, z SMALLINT); +CREATE TABLE t2(a SMALLINT, b SMALLINT, c SMALLINT NOT NULL); + +delimiter |; + +CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW +BEGIN + INSERT INTO t2 VALUES( + CAST('111111 ' AS SIGNED), + CAST('222222 ' AS SIGNED), + NULL); +END| + +delimiter ;| + +CREATE PROCEDURE p1() + INSERT INTO t1 VALUES(99999, 99999, 99999); + +--echo +--error ER_BAD_NULL_ERROR +CALL p1(); + +--echo +SHOW WARNINGS; + +--echo +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 379e81d406e..0d33bd5c599 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1176,10 +1176,17 @@ find_handler_after_execution(THD *thd, sp_rcontext *ctx) /** Execute the routine. The main instruction jump loop is there. Assume the parameters already set. + + @param thd Thread context. + @param merge_da_on_success Flag specifying if Warning Info should be + propagated to the caller on Completion + Condition or not. + @todo - Will write this SP statement into binlog separately (TODO: consider changing the condition to "not inside event union") + @return Error status. @retval FALSE on success @retval @@ -1187,7 +1194,7 @@ find_handler_after_execution(THD *thd, sp_rcontext *ctx) */ bool -sp_head::execute(THD *thd) +sp_head::execute(THD *thd, bool merge_da_on_success) { DBUG_ENTER("sp_head::execute"); char saved_cur_db_name_buf[NAME_LEN+1]; @@ -1481,8 +1488,15 @@ sp_head::execute(THD *thd) thd->stmt_arena= old_arena; state= EXECUTED; - /* Restore the caller's original warning information area. */ - saved_warning_info->merge_with_routine_info(thd, thd->warning_info); + /* + Restore the caller's original warning information area: + - warnings generated during trigger execution should not be + propagated to the caller on success; + - if there was an exception during execution, warning info should be + propagated to the caller in any case. + */ + if (err_status || merge_da_on_success) + saved_warning_info->merge_with_routine_info(thd, thd->warning_info); thd->warning_info= saved_warning_info; done: @@ -1704,7 +1718,7 @@ sp_head::execute_trigger(THD *thd, thd->spcont= nctx; - err_status= execute(thd); + err_status= execute(thd, FALSE); err_with_cleanup: thd->restore_active_arena(&call_arena, &backup_arena); @@ -1921,7 +1935,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, */ thd->set_n_backup_active_arena(&call_arena, &backup_arena); - err_status= execute(thd); + err_status= execute(thd, TRUE); thd->restore_active_arena(&call_arena, &backup_arena); @@ -2154,7 +2168,7 @@ sp_head::execute_procedure(THD *thd, List *args) #endif if (!err_status) - err_status= execute(thd); + err_status= execute(thd, TRUE); if (save_log_general) thd->variables.option_bits &= ~OPTION_LOG_OFF; diff --git a/sql/sp_head.h b/sql/sp_head.h index e72ce6455f6..5efd48fc7c6 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -527,7 +527,7 @@ private: HASH m_sptabs; bool - execute(THD *thd); + execute(THD *thd, bool merge_da_on_success); /** Perform a forward flow analysis in the generated code. From c039e8249717c7d299f454f3b9877382e8fe7849 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Tue, 26 Oct 2010 19:35:02 +0200 Subject: [PATCH 133/151] Fixed test result --- mysql-test/suite/perfschema/r/schema.result | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/perfschema/r/schema.result b/mysql-test/suite/perfschema/r/schema.result index a802539b7e0..1599d51a59f 100644 --- a/mysql-test/suite/perfschema/r/schema.result +++ b/mysql-test/suite/perfschema/r/schema.result @@ -195,6 +195,6 @@ show create table THREADS; Table Create Table THREADS CREATE TABLE `THREADS` ( `THREAD_ID` int(11) NOT NULL, - `ID` int(11) NOT NULL, - `NAME` varchar(64) NOT NULL + `PROCESSLIST_ID` int(11) DEFAULT NULL, + `NAME` varchar(128) NOT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 From 02ca1fe3f12052f4d8bb14d0e394af480eccce3d Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 27 Oct 2010 11:16:52 +0400 Subject: [PATCH 134/151] Follow-up for Bug#55850: update funcs_1 result files. --- mysql-test/suite/funcs_1/r/innodb_trig_08.result | 4 ---- mysql-test/suite/funcs_1/r/memory_trig_08.result | 4 ---- mysql-test/suite/funcs_1/r/myisam_trig_08.result | 4 ---- 3 files changed, 12 deletions(-) diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_08.result b/mysql-test/suite/funcs_1/r/innodb_trig_08.result index b2b38694680..a25147a1480 100644 --- a/mysql-test/suite/funcs_1/r/innodb_trig_08.result +++ b/mysql-test/suite/funcs_1/r/innodb_trig_08.result @@ -353,8 +353,6 @@ B Test 3.5.8.5-case 00191 0000000016 C=one C Test 3.5.8.5-case 00200 0000000001 C=one Insert into tb3 (f120, f122, f136) values ('d', 'Test 3.5.8.5-case', 152); -Warnings: -Warning 1265 Data truncated for column 'f120' at row 1 select f120, f122, f136, f144, @test_var from tb3 where f122 = 'Test 3.5.8.5-case' order by f120,f136; f120 f122 f136 f144 @test_var @@ -364,8 +362,6 @@ B Test 3.5.8.5-case 00191 0000000016 1*0000099999 C Test 3.5.8.5-case 00200 0000000001 1*0000099999 Insert into tb3 (f120, f122, f136, f144) values ('e', 'Test 3.5.8.5-case', 200, 8); -Warnings: -Warning 1265 Data truncated for column 'f120' at row 1 select f120, f122, f136, f144, @test_var from tb3 where f122 = 'Test 3.5.8.5-case' order by f120,f136; f120 f122 f136 f144 @test_var diff --git a/mysql-test/suite/funcs_1/r/memory_trig_08.result b/mysql-test/suite/funcs_1/r/memory_trig_08.result index 03505af95c5..3f303ef607f 100644 --- a/mysql-test/suite/funcs_1/r/memory_trig_08.result +++ b/mysql-test/suite/funcs_1/r/memory_trig_08.result @@ -354,8 +354,6 @@ B Test 3.5.8.5-case 00191 0000000016 C=one C Test 3.5.8.5-case 00200 0000000001 C=one Insert into tb3 (f120, f122, f136) values ('d', 'Test 3.5.8.5-case', 152); -Warnings: -Warning 1265 Data truncated for column 'f120' at row 1 select f120, f122, f136, f144, @test_var from tb3 where f122 = 'Test 3.5.8.5-case' order by f120,f136; f120 f122 f136 f144 @test_var @@ -365,8 +363,6 @@ B Test 3.5.8.5-case 00191 0000000016 1*0000099999 C Test 3.5.8.5-case 00200 0000000001 1*0000099999 Insert into tb3 (f120, f122, f136, f144) values ('e', 'Test 3.5.8.5-case', 200, 8); -Warnings: -Warning 1265 Data truncated for column 'f120' at row 1 select f120, f122, f136, f144, @test_var from tb3 where f122 = 'Test 3.5.8.5-case' order by f120,f136; f120 f122 f136 f144 @test_var diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_08.result b/mysql-test/suite/funcs_1/r/myisam_trig_08.result index 03505af95c5..3f303ef607f 100644 --- a/mysql-test/suite/funcs_1/r/myisam_trig_08.result +++ b/mysql-test/suite/funcs_1/r/myisam_trig_08.result @@ -354,8 +354,6 @@ B Test 3.5.8.5-case 00191 0000000016 C=one C Test 3.5.8.5-case 00200 0000000001 C=one Insert into tb3 (f120, f122, f136) values ('d', 'Test 3.5.8.5-case', 152); -Warnings: -Warning 1265 Data truncated for column 'f120' at row 1 select f120, f122, f136, f144, @test_var from tb3 where f122 = 'Test 3.5.8.5-case' order by f120,f136; f120 f122 f136 f144 @test_var @@ -365,8 +363,6 @@ B Test 3.5.8.5-case 00191 0000000016 1*0000099999 C Test 3.5.8.5-case 00200 0000000001 1*0000099999 Insert into tb3 (f120, f122, f136, f144) values ('e', 'Test 3.5.8.5-case', 200, 8); -Warnings: -Warning 1265 Data truncated for column 'f120' at row 1 select f120, f122, f136, f144, @test_var from tb3 where f122 = 'Test 3.5.8.5-case' order by f120,f136; f120 f122 f136 f144 @test_var From ef7982fd17b046d19e783ff1bea03af1602c381a Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 25 Oct 2010 18:11:58 +0300 Subject: [PATCH 135/151] Bug #57689: mysql_change_user() breaks user connection on older clients COM_CHANGE_USER was always handled like an implicit request to change the client plugin, so that the client can re-use the same code path for both normal login and COM_CHANGE_USER. However this doesn't really work well with old clients because they don't understand the request to change a client plugin. Fixed by implementing a special state in the code (and old client issuing COM_CHANGE_USER). In this state the server parses the COM_CHANGE_USER package and pushes back the password hash, the user name and the database to the input stream in the same order that the native password server side plugin expects. As a result it replies with an OK/FAIL just like the old server does thus making the new server compatible with older clients. No test case added, since it would requre an old client binary. Tested using accounts with and without passwords. Tested with a correct and incorrect password. --- sql/sql_acl.cc | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 49224444f5c..c741a50a1db 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -8091,6 +8091,24 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio, DBUG_RETURN (1); } + /* + If we're dealing with an older client we can't just send a change plugin + packet to re-initiate the authentication handshake, because the client + won't understand it. The good thing is that we don't need to : the old client + expects us to just check the user credentials here, which we can do by just reading + the cached data that are placed there by parse_com_change_user_packet() + In this case we just do nothing and behave as if normal authentication + should continue. + */ + if (!(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)) + { + DBUG_PRINT("info", ("old client sent a COM_CHANGE_USER")); + DBUG_ASSERT(mpvio->cached_client_reply.pkt); + /* get the status back so the read can process the cached result */ + mpvio->status= MPVIO_EXT::RESTART; + DBUG_RETURN(0); + } + DBUG_PRINT("info", ("requesting client to use the %s plugin", client_auth_plugin)); DBUG_RETURN(net_write_command(net, switch_plugin_request_buf[0], @@ -8574,8 +8592,16 @@ static int server_mpvio_write_packet(MYSQL_PLUGIN_VIO *param, int res; DBUG_ENTER("server_mpvio_write_packet"); - /* reset cached_client_reply */ - mpvio->cached_client_reply.pkt= 0; + /* + Reset cached_client_reply if not an old client doing mysql_change_user, + as this is where the password from COM_CHANGE_USER is stored. + */ + if (!((!(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)) && + mpvio->status == MPVIO_EXT::RESTART && + mpvio->cached_client_reply.plugin == + ((st_mysql_auth *) (plugin_decl(mpvio->plugin)->info))->client_auth_plugin + )) + mpvio->cached_client_reply.pkt= 0; /* for the 1st packet we wrap plugin data into the handshake packet */ if (mpvio->packets_written == 0) res= send_server_handshake_packet(mpvio, (char*) packet, packet_len); @@ -8641,6 +8667,15 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf) mpvio->packets_read++; DBUG_RETURN ((int) mpvio->cached_client_reply.pkt_len); } + + /* older clients don't support change of client plugin request */ + if (!(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)) + { + mpvio->status= MPVIO_EXT::FAILURE; + pkt_len= packet_error; + goto err; + } + /* But if the client has used the wrong plugin, the cached data are useless. Furthermore, we have to send a "change plugin" request From 840c602e83840c76c092c6d843eb83e7ff4aebb5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 26 Oct 2010 14:18:31 -0500 Subject: [PATCH 136/151] Bug#57720 - Windows Vista and possibly Windows 7 can return ERROR_TIMEOUT instead of WAIT_TIMEOUT from calls to SleepConditionVariableCS() which is used in os0sync.c; os_cond_wait_timeout() where it is mapped to sleep_condition_variable(). Consider ERROR_TIMEOUT to be a timeout just like WAIT_TIMEOUT. In addition, test for EINTR as a possible return value from pthread_cond_timeout() in the posix section of os_cond_wait_timeout(), even though it is not supposed to be returned, but just to be safe. --- storage/innobase/os/os0sync.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 65fdd49f839..2f481b76bda 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -142,14 +142,24 @@ os_cond_wait_timed( ) { #ifdef __WIN__ - BOOL ret; + BOOL ret; + DWORD err; ut_a(sleep_condition_variable != NULL); ret = sleep_condition_variable(cond, mutex, time_in_ms); - if (!ret && GetLastError() == WAIT_TIMEOUT) { - return(TRUE); + if (!ret) { + err = GetLastError(); + /* From http://msdn.microsoft.com/en-us/library/ms686301%28VS.85%29.aspx, + "Condition variables are subject to spurious wakeups + (those not associated with an explicit wake) and stolen wakeups + (another thread manages to run before the woken thread)." + Check for both types of timeouts. + Conditions are checked by the caller.*/ + if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) { + return(TRUE); + } } ut_a(ret); @@ -163,12 +173,15 @@ os_cond_wait_timed( switch (ret) { case 0: case ETIMEDOUT: - break; + /* We play it safe by checking for EINTR even though + according to the POSIX documentation it can't return EINTR. */ + case EINTR: + break; default: fprintf(stderr, " InnoDB: pthread_cond_timedwait() returned: " "%d: abstime={%lu,%lu}\n", - ret, abstime->tv_sec, abstime->tv_nsec); + ret, abstime->tv_sec, abstime->tv_nsec); ut_error; } @@ -663,7 +676,7 @@ os_event_wait_time_low( if (err == WAIT_OBJECT_0) { return(0); - } else if (err == WAIT_TIMEOUT) { + } else if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) { return(OS_SYNC_TIME_EXCEEDED); } From 26738c280f77962771d68c5b43becdffa8831c51 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Tue, 26 Oct 2010 16:54:18 -0400 Subject: [PATCH 137/151] Bug #57611 ibdata file and continuous growing undo logs rb://498 Fix handling of update_undo_logs at trx commit. Previously, when rseg->update_undo_list grows beyond 500 the update_undo_logs were marked with state TRX_UNDO_TO_FREE which should have been TRX_UNDO_TO_PURGE. Approved by: Sunny Bains --- storage/innobase/trx/trx0undo.c | 18 ++++-------------- storage/innodb_plugin/trx/trx0undo.c | 18 ++++-------------- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index 4547ee9ea64..329565943c8 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -1752,21 +1752,11 @@ trx_undo_set_state_at_finish( if (undo->size == 1 && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE) - < TRX_UNDO_PAGE_REUSE_LIMIT) { + < TRX_UNDO_PAGE_REUSE_LIMIT + && UT_LIST_GET_LEN(rseg->update_undo_list) < 500 + && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) { - /* This is a heuristic to avoid the problem of all UNDO - slots ending up in one of the UNDO lists. Previously if - the server crashed with all the slots in one of the lists, - transactions that required the slots of a different type - would fail for lack of slots. */ - - if (UT_LIST_GET_LEN(rseg->update_undo_list) < 500 - && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) { - - state = TRX_UNDO_CACHED; - } else { - state = TRX_UNDO_TO_FREE; - } + state = TRX_UNDO_CACHED; } else if (undo->type == TRX_UNDO_INSERT) { diff --git a/storage/innodb_plugin/trx/trx0undo.c b/storage/innodb_plugin/trx/trx0undo.c index c8a4b15e48b..76e88948e41 100644 --- a/storage/innodb_plugin/trx/trx0undo.c +++ b/storage/innodb_plugin/trx/trx0undo.c @@ -1823,21 +1823,11 @@ trx_undo_set_state_at_finish( if (undo->size == 1 && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE) - < TRX_UNDO_PAGE_REUSE_LIMIT) { + < TRX_UNDO_PAGE_REUSE_LIMIT + && UT_LIST_GET_LEN(rseg->update_undo_list) < 500 + && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) { - /* This is a heuristic to avoid the problem of all UNDO - slots ending up in one of the UNDO lists. Previously if - the server crashed with all the slots in one of the lists, - transactions that required the slots of a different type - would fail for lack of slots. */ - - if (UT_LIST_GET_LEN(rseg->update_undo_list) < 500 - && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) { - - state = TRX_UNDO_CACHED; - } else { - state = TRX_UNDO_TO_FREE; - } + state = TRX_UNDO_CACHED; } else if (undo->type == TRX_UNDO_INSERT) { From 1c3dc21f2a15e94425ded3f176fd2df5cb3eb025 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Tue, 26 Oct 2010 17:06:24 -0400 Subject: [PATCH 138/151] Bug #57611 ibdata file and continuous growing undo logs rb://498 Fix handling of update_undo_logs at trx commit. Previously, when rseg->update_undo_list grows beyond 500 the update_undo_logs were marked with state TRX_UNDO_TO_FREE which should have been TRX_UNDO_TO_PURGE. In 5.5 we don't need the heuristic as we support multiple rollback segments. Approved by: Sunny Bains --- storage/innobase/trx/trx0undo.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index 9162c82e423..ef877f4844d 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -1830,19 +1830,7 @@ trx_undo_set_state_at_finish( && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE) < TRX_UNDO_PAGE_REUSE_LIMIT) { - /* This is a heuristic to avoid the problem of all UNDO - slots ending up in one of the UNDO lists. Previously if - the server crashed with all the slots in one of the lists, - transactions that required the slots of a different type - would fail for lack of slots. */ - - if (UT_LIST_GET_LEN(rseg->update_undo_list) < 500 - && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) { - - state = TRX_UNDO_CACHED; - } else { - state = TRX_UNDO_TO_FREE; - } + state = TRX_UNDO_CACHED; } else if (undo->type == TRX_UNDO_INSERT) { From 431e3ee7c6a7b72b4dd2ba63862e13cb221e2f41 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Tue, 26 Oct 2010 21:45:58 -0400 Subject: [PATCH 139/151] Fix compiler warning introduced by previous commit. --- storage/innobase/include/trx0undo.h | 2 -- storage/innobase/trx/trx0trx.c | 5 ++--- storage/innobase/trx/trx0undo.c | 4 ---- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h index 54809f9c2d5..937e9d7ef79 100644 --- a/storage/innobase/include/trx0undo.h +++ b/storage/innobase/include/trx0undo.h @@ -262,8 +262,6 @@ UNIV_INTERN page_t* trx_undo_set_state_at_finish( /*=========================*/ - trx_rseg_t* rseg, /*!< in: rollback segment memory object */ - trx_t* trx, /*!< in: transaction */ trx_undo_t* undo, /*!< in: undo log memory copy */ mtr_t* mtr); /*!< in: mtr */ /******************************************************************//** diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index 6bae0527b53..7f2ca1f1471 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -753,8 +753,7 @@ trx_commit_off_kernel( mutex_enter(&(rseg->mutex)); if (trx->insert_undo != NULL) { - trx_undo_set_state_at_finish( - rseg, trx, trx->insert_undo, &mtr); + trx_undo_set_state_at_finish(trx->insert_undo, &mtr); } undo = trx->update_undo; @@ -769,7 +768,7 @@ trx_commit_off_kernel( transaction commit for this transaction. */ update_hdr_page = trx_undo_set_state_at_finish( - rseg, trx, undo, &mtr); + undo, &mtr); /* We have to do the cleanup for the update log while holding the rseg mutex because update log headers diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index ef877f4844d..4021a2ed573 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -1798,8 +1798,6 @@ UNIV_INTERN page_t* trx_undo_set_state_at_finish( /*=========================*/ - trx_rseg_t* rseg, /*!< in: rollback segment memory object */ - trx_t* trx __attribute__((unused)), /*!< in: transaction */ trx_undo_t* undo, /*!< in: undo log memory copy */ mtr_t* mtr) /*!< in: mtr */ { @@ -1808,10 +1806,8 @@ trx_undo_set_state_at_finish( page_t* undo_page; ulint state; - ut_ad(trx); ut_ad(undo); ut_ad(mtr); - ut_ad(mutex_own(&rseg->mutex)); if (undo->id >= TRX_RSEG_N_SLOTS) { fprintf(stderr, "InnoDB: Error: undo->id is %lu\n", From fcfda43ca3b60266429c6deb78489f82f9686e67 Mon Sep 17 00:00:00 2001 From: Anitha Gopi Date: Wed, 27 Oct 2010 09:54:04 +0530 Subject: [PATCH 140/151] Fixed bug numbers in disabled.def files --- mysql-test/collections/default.experimental | 2 -- mysql-test/suite/binlog/t/disabled.def | 3 ++- mysql-test/t/disabled.def | 5 +++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 91dada3ee05..aa2f2e9f724 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -43,8 +43,6 @@ parts.partition_mgm_lc1_ndb # joro : NDB tests marked as experiment parts.partition_mgm_lc2_ndb # joro : NDB tests marked as experimental as agreed with bochklin parts.partition_syntax_ndb # joro : NDB tests marked as experimental as agreed with bochklin parts.partition_value_ndb # joro : NDB tests marked as experimental as agreed with bochklin -main.mysqlhotcopy_myisam # horst: due to bug#54129 -main.mysqlhotcopy_archive # horst: due to bug#54129 main.gis-rtree # svoj: due to BUG#38965 main.type_float # svoj: due to BUG#38965 main.type_newdecimal # svoj: due to BUG#38965 diff --git a/mysql-test/suite/binlog/t/disabled.def b/mysql-test/suite/binlog/t/disabled.def index 0018387de94..d261364756e 100644 --- a/mysql-test/suite/binlog/t/disabled.def +++ b/mysql-test/suite/binlog/t/disabled.def @@ -9,5 +9,6 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -binlog_truncate_innodb : BUG#42643 2009-02-06 mats Changes to InnoDB requires to complete fix for BUG#36763 +binlog_truncate_innodb : BUG#57291 2010-10-20 anitha Originally disabled due to BUG#42643. Product bug fixed, but test changes needed + diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index cede26f555a..fb07cb2c7e4 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -12,5 +12,6 @@ kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild. query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically partition_innodb_plugin : Bug#53307 2010-04-30 VasilDimov valgrind warnings -main.mysqlhotcopy_myisam : bug#54129 2010-06-04 Horst -main.mysqlhotcopy_archive: bug#54129 2010-06-04 Horst +main.mysqlhotcopy_myisam : Bug#56817 2010-10-21 anitha mysqlhotcopy* fails +main.mysqlhotcopy_archive: Bug#56817 2010-10-21 anitha mysqlhotcopy* fails + From 0fbc74a451b33b10b66c4f47000ac0f2733c69f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 27 Oct 2010 09:54:20 +0300 Subject: [PATCH 141/151] Bug #57730 Clean up references to InnoDB Plugin CMakeLists.txt: Remove the checks for mysql_storage_engine.cmake and MYSQL_VERSION_ID. ha_innodb.cc, ha_innodb.h: Remove the checks for MYSQL_VERSION_ID. --- storage/innobase/CMakeLists.txt | 32 +++++---------------------- storage/innobase/handler/ha_innodb.cc | 14 ------------ storage/innobase/handler/ha_innodb.h | 3 +-- 3 files changed, 6 insertions(+), 43 deletions(-) diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 6cfd3d754f6..fa45cc96687 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -13,7 +13,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# This is the CMakeLists for InnoDB Plugin +# This is the CMakeLists for InnoDB INCLUDE(CheckFunctionExists) INCLUDE(CheckCSourceCompiles) @@ -254,29 +254,7 @@ IF(WITH_INNODB) SET(WITH_INNOBASE_STORAGE_ENGINE TRUE) ENDIF() - -#The plugin's CMakeLists.txt still needs to work with previous versions of MySQL. -IF(EXISTS ${SOURCE_DIR}/storage/mysql_storage_engine.cmake) - # Old plugin support on Windows only, - # use tricks to force ha_innodb.dll name for DLL - INCLUDE(${SOURCE_DIR}/storage/mysql_storage_engine.cmake) - MYSQL_STORAGE_ENGINE(INNOBASE) - GET_TARGET_PROPERTY(LIB_LOCATION ha_innobase LOCATION) - IF(LIB_LOCATION) - SET_TARGET_PROPERTIES(ha_innobase PROPERTIES OUTPUT_NAME ha_innodb) - ENDIF() -ELSEIF (MYSQL_VERSION_ID LESS "50137") - # Windows only, no plugin support - IF (NOT SOURCE_SUBLIBS) - ADD_DEFINITIONS(-DMYSQL_SERVER) - ADD_LIBRARY(innobase STATIC ${INNOBASE_SOURCES}) - # Require mysqld_error.h, which is built as part of the GenError - ADD_DEPENDENCIES(innobase GenError) - ENDIF() -ELSE() - # New plugin support, cross-platform , base name for shared module is "ha_innodb" - MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE - DEFAULT - MODULE_OUTPUT_NAME ha_innodb - LINK_LIBRARIES ${ZLIB_LIBRARY}) -ENDIF() +MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE + DEFAULT + MODULE_OUTPUT_NAME ha_innodb + LINK_LIBRARIES ${ZLIB_LIBRARY}) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 74c83e8d44b..ce4cba3356f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -95,10 +95,6 @@ extern "C" { # define MYSQL_PLUGIN_IMPORT /* nothing */ # endif /* MYSQL_PLUGIN_IMPORT */ -#if MYSQL_VERSION_ID < 50124 -bool check_global_access(THD *thd, ulong want_access); -#endif /* MYSQL_VERSION_ID < 50124 */ - /** to protect innobase_open_files */ static mysql_mutex_t innobase_share_mutex; /** to force correct commit order in binlog */ @@ -1885,11 +1881,7 @@ innobase_convert_identifier( FALSE=id is an UTF-8 string */ { char nz[NAME_LEN + 1]; -#if MYSQL_VERSION_ID >= 50141 char nz2[NAME_LEN + 1 + EXPLAIN_FILENAME_MAX_EXTRA_LENGTH]; -#else /* MYSQL_VERSION_ID >= 50141 */ - char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix]; -#endif /* MYSQL_VERSION_ID >= 50141 */ const char* s = id; int q; @@ -1907,13 +1899,9 @@ innobase_convert_identifier( nz[idlen] = 0; s = nz2; -#if MYSQL_VERSION_ID >= 50141 idlen = explain_filename((THD*) thd, nz, nz2, sizeof nz2, EXPLAIN_PARTITIONS_AS_COMMENT); goto no_quote; -#else /* MYSQL_VERSION_ID >= 50141 */ - idlen = filename_to_tablename(nz, nz2, sizeof nz2); -#endif /* MYSQL_VERSION_ID >= 50141 */ } /* See if the identifier needs to be quoted. */ @@ -1924,9 +1912,7 @@ innobase_convert_identifier( } if (q == EOF) { -#if MYSQL_VERSION_ID >= 50141 no_quote: -#endif /* MYSQL_VERSION_ID >= 50141 */ if (UNIV_UNLIKELY(idlen > buflen)) { idlen = buflen; } diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 9c78c60d71e..f05ea8801f0 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -276,14 +276,13 @@ int thd_binlog_format(const MYSQL_THD thd); */ void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all); -#if MYSQL_VERSION_ID > 50140 /** Check if binary logging is filtered for thread's current db. @param thd Thread handle @retval 1 the query is not filtered, 0 otherwise. */ bool thd_binlog_filter_ok(const MYSQL_THD thd); -#endif /* MYSQL_VERSION_ID > 50140 */ + /** Check if the query may generate row changes which may end up in the binary. From 26d81a2a9835bc16b59010ebd4017ac508215643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 27 Oct 2010 09:56:56 +0300 Subject: [PATCH 142/151] Bug #57707 InnoDB buf_page_t size has doubled on 32-bit systems buf_page_t: Remove the buf_pool pointer. Add buf_pool_index:6 next to buf_fix_count:19 (it was buf_fix_count:25). This will limit the number of concurrent transactions to somewhere around 524,288. buf_pool_index(buf_pool): A new function to determine the index of a buffer pool in buf_pool_ptr[]. buf_pool_ptr: Make this a dynamically allocated array instead of an array of pointers. Allocate the array in buf_pool_init() and free in buf_pool_free(). buf_pool_free_instance(): No longer free the buf_pool object, as it is allocated from a big array. buf_pool_from_bpage(), buf_pool_from_block(): Move the definitions to the beginning of the files, because some compilers have (had) problems with forward definitions of inline functions. Calculate the buffer pool from buf_pool_index. buf_pool_from_array(): Add debug assertions for input validation. --- storage/innobase/buf/buf0buf.c | 33 ++++++------- storage/innobase/include/buf0buf.h | 25 +++++++--- storage/innobase/include/buf0buf.ic | 77 ++++++++++++++++++----------- 3 files changed, 81 insertions(+), 54 deletions(-) diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index abfde83a3bd..03133e81ceb 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -246,8 +246,8 @@ static const int WAIT_FOR_READ = 5000; /** Number of attemtps made to read in a page in the buffer pool */ static const ulint BUF_PAGE_READ_MAX_RETRIES = 100; -/** The buffer buf_pool of the database */ -UNIV_INTERN buf_pool_t* buf_pool_ptr[MAX_BUFFER_POOLS]; +/** The buffer pools of the database */ +UNIV_INTERN buf_pool_t* buf_pool_ptr; #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG static ulint buf_dbg_counter = 0; /*!< This is used to insert validation @@ -858,7 +858,7 @@ buf_block_init( block->frame = frame; - block->page.buf_pool = buf_pool; + block->page.buf_pool_index = buf_pool_index(buf_pool); block->page.state = BUF_BLOCK_NOT_USED; block->page.buf_fix_count = 0; block->page.io_fix = BUF_IO_NONE; @@ -1280,8 +1280,6 @@ buf_pool_free_instance( mem_free(buf_pool->chunks); hash_table_free(buf_pool->page_hash); hash_table_free(buf_pool->zip_hash); - mem_free(buf_pool); - buf_pool = NULL; } /********************************************************************//** @@ -1294,25 +1292,22 @@ buf_pool_init( ulint total_size, /*!< in: size of the total pool in bytes */ ulint n_instances) /*!< in: number of instances */ { - ulint i; + ulint i; + const ulint size = total_size / n_instances; + + ut_ad(n_instances < MAX_BUFFER_POOLS); + ut_ad(n_instances == srv_buf_pool_instances); /* We create an extra buffer pool instance, this instance is used for flushing the flush lists, to keep track of n_flush for all the buffer pools and also used as a waiting object during flushing. */ + buf_pool_ptr = mem_zalloc(n_instances * sizeof *buf_pool_ptr); + for (i = 0; i < n_instances; i++) { - buf_pool_t* ptr; - ulint size; - - ptr = mem_zalloc(sizeof(*ptr)); - - size = total_size / n_instances; - - buf_pool_ptr[i] = ptr; + buf_pool_t* ptr = &buf_pool_ptr[i]; if (buf_pool_init_instance(ptr, size, i) != DB_SUCCESS) { - mem_free(buf_pool_ptr[i]); - /* Free all the instances created so far. */ buf_pool_free(i); @@ -1341,8 +1336,10 @@ buf_pool_free( for (i = 0; i < n_instances; i++) { buf_pool_free_instance(buf_pool_from_array(i)); - buf_pool_ptr[i] = NULL; } + + mem_free(buf_pool_ptr); + buf_pool_ptr = NULL; } /********************************************************************//** @@ -3685,7 +3682,7 @@ err_exit: bpage = buf_buddy_alloc(buf_pool, sizeof *bpage, &lru); /* Initialize the buf_pool pointer. */ - bpage->buf_pool = buf_pool; + bpage->buf_pool_index = buf_pool_index(buf_pool); /* If buf_buddy_alloc() allocated storage from the LRU list, it released and reacquired buf_pool->mutex. Thus, we must diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index b0fff919918..a42eba57fd2 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -69,7 +69,7 @@ Created 11/5/1995 Heikki Tuuri #define BUF_POOL_WATCH_SIZE 1 /*!< Maximum number of concurrent buffer pool watches */ -extern buf_pool_t* buf_pool_ptr[MAX_BUFFER_POOLS]; /*!< The buffer pools +extern buf_pool_t* buf_pool_ptr; /*!< The buffer pools of the database */ #ifdef UNIV_DEBUG extern ibool buf_debug_prints;/*!< If this is set TRUE, the program @@ -1034,6 +1034,15 @@ buf_page_address_fold( ulint space, /*!< in: space id */ ulint offset) /*!< in: offset of the page within space */ __attribute__((const)); +/********************************************************************//** +Calculates the index of a buffer pool to the buf_pool[] array. +@return the position of the buffer pool in buf_pool[] */ +UNIV_INLINE +ulint +buf_pool_index( +/*===========*/ + const buf_pool_t* buf_pool) /*!< in: buffer pool */ + __attribute__((nonnull, const)); /******************************************************************//** Returns the buffer pool instance given a page instance @return buf_pool */ @@ -1065,8 +1074,9 @@ Returns the buffer pool instance given its array index UNIV_INLINE buf_pool_t* buf_pool_from_array( -/*====================*/ - ulint index); /*!< in: array index to get buffer pool instance from */ +/*================*/ + ulint index); /*!< in: array index to get + buffer pool instance from */ /******************************************************************//** Returns the control block of a file page, NULL if not found. @return block, NULL if not found */ @@ -1204,8 +1214,13 @@ struct buf_page_struct{ unsigned io_fix:2; /*!< type of pending I/O operation; also protected by buf_pool->mutex @see enum buf_io_fix */ - unsigned buf_fix_count:25;/*!< count of how manyfold this block + unsigned buf_fix_count:19;/*!< count of how manyfold this block is currently bufferfixed */ + unsigned buf_pool_index:6;/*!< index number of the buffer pool + that this block belongs to */ +# if MAX_BUFFER_POOLS > 64 +# error "MAX_BUFFER_POOLS > 64; redefine buf_pool_index:6" +# endif /* @} */ #endif /* !UNIV_HOTBACKUP */ page_zip_des_t zip; /*!< compressed page; zip.data @@ -1324,8 +1339,6 @@ struct buf_page_struct{ frees a page in buffer pool */ # endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* !UNIV_HOTBACKUP */ - buf_pool_t* buf_pool; /*!< buffer pool instance this - page belongs to */ }; /** The buffer control block structure */ diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index 713b7cb990d..e2e83de0a78 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -46,6 +46,48 @@ buf_pool_get_curr_size(void) return(srv_buf_pool_curr_size); } +/********************************************************************//** +Calculates the index of a buffer pool to the buf_pool[] array. +@return the position of the buffer pool in buf_pool[] */ +UNIV_INLINE +ulint +buf_pool_index( +/*===========*/ + const buf_pool_t* buf_pool) /*!< in: buffer pool */ +{ + ulint i = buf_pool - buf_pool_ptr; + ut_ad(i < MAX_BUFFER_POOLS); + ut_ad(i < srv_buf_pool_instances); + return(i); +} + +/******************************************************************//** +Returns the buffer pool instance given a page instance +@return buf_pool */ +UNIV_INLINE +buf_pool_t* +buf_pool_from_bpage( +/*================*/ + const buf_page_t* bpage) /*!< in: buffer pool page */ +{ + ulint i; + i = bpage->buf_pool_index; + ut_ad(i < srv_buf_pool_instances); + return(&buf_pool_ptr[i]); +} + +/******************************************************************//** +Returns the buffer pool instance given a block instance +@return buf_pool */ +UNIV_INLINE +buf_pool_t* +buf_pool_from_block( +/*================*/ + const buf_block_t* block) /*!< in: block */ +{ + return(buf_pool_from_bpage(&block->page)); +} + /*********************************************************************//** Gets the current size of buffer buf_pool in pages. @return size in pages*/ @@ -885,33 +927,6 @@ buf_block_buf_fix_dec( #endif } -/******************************************************************//** -Returns the buffer pool instance given a page instance -@return buf_pool */ -UNIV_INLINE -buf_pool_t* -buf_pool_from_bpage( -/*================*/ - const buf_page_t* bpage) /*!< in: buffer pool page */ -{ - /* Every page must be in some buffer pool. */ - ut_ad(bpage->buf_pool != NULL); - - return(bpage->buf_pool); -} - -/******************************************************************//** -Returns the buffer pool instance given a block instance -@return buf_pool */ -UNIV_INLINE -buf_pool_t* -buf_pool_from_block( -/*================*/ - const buf_block_t* block) /*!< in: block */ -{ - return(buf_pool_from_bpage(&block->page)); -} - /******************************************************************//** Returns the buffer pool instance given space and offset of page @return buffer pool */ @@ -929,7 +944,7 @@ buf_pool_get( ignored_offset = offset >> 6; /* 2log of BUF_READ_AHEAD_AREA (64)*/ fold = buf_page_address_fold(space, ignored_offset); index = fold % srv_buf_pool_instances; - return buf_pool_ptr[index]; + return(&buf_pool_ptr[index]); } /******************************************************************//** @@ -939,10 +954,12 @@ UNIV_INLINE buf_pool_t* buf_pool_from_array( /*================*/ - ulint index) /*!< in: array index to get + ulint index) /*!< in: array index to get buffer pool instance from */ { - return buf_pool_ptr[index]; + ut_ad(index < MAX_BUFFER_POOLS); + ut_ad(index < srv_buf_pool_instances); + return(&buf_pool_ptr[index]); } /******************************************************************//** From 712beace38e9a621eb015663d4db4ce0ec0c5fea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 27 Oct 2010 21:50:45 +0300 Subject: [PATCH 143/151] Fix a bogus debug assertion in the fix of Bug #57707. buf_pool_init(): Replace ut_ad(n_instances < MAX_BUFFER_POOLS) with ut_ad(n_instances <= MAX_BUFFER_POOLS). (Spotted by Michael Izioumtchenko.) Add ut_ad(n_instances > 0). --- storage/innobase/buf/buf0buf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 03133e81ceb..b79b5634957 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -1295,7 +1295,8 @@ buf_pool_init( ulint i; const ulint size = total_size / n_instances; - ut_ad(n_instances < MAX_BUFFER_POOLS); + ut_ad(n_instances > 0); + ut_ad(n_instances <= MAX_BUFFER_POOLS); ut_ad(n_instances == srv_buf_pool_instances); /* We create an extra buffer pool instance, this instance is used From 3fb574bf03d5c4e118d29acbc192058243a21404 Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Wed, 27 Oct 2010 17:06:20 -0500 Subject: [PATCH 144/151] Fixed a C89 violation when atomic builtins are not defined, causing a compile error with MSVC. The problem was introduced in Revision: 3150 revid:marko.makela@oracle.com-20100809085837-s1nfx6gjf7l6ttab --- storage/innobase/ibuf/ibuf0ibuf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 7ef577e5178..ab42f1ad4f3 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -1363,12 +1363,12 @@ ibuf_add_ops( const ulint* ops) /*!< in: operation counts */ { + ulint i; + #ifndef HAVE_ATOMIC_BUILTINS ut_ad(mutex_own(&ibuf_mutex)); #endif /* !HAVE_ATOMIC_BUILTINS */ - ulint i; - for (i = 0; i < IBUF_OP_COUNT; i++) { #ifdef HAVE_ATOMIC_BUILTINS os_atomic_increment_ulint(&arr[i], ops[i]); From 16feea410975e17c3cf24f8af92a3f32e8c24ba1 Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Wed, 27 Oct 2010 23:18:59 -0500 Subject: [PATCH 145/151] Bug#52062: Compiler warning in os0file.c on windows 64-bit On Windows, the parameter for number of bytes passed into WriteFile() and ReadFile() is DWORD. Casting is needed to silence the warning on 64-bit Windows. Also, adding several asserts to ensure the variable for number of bytes is no more than 32 bits, even on 64-bit Windows. This is for built-in InnoDB. rb://415 Approved by: Inaam --- storage/innobase/os/os0file.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index f269cd39673..566c50381e7 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -2207,7 +2207,10 @@ os_file_read( ibool retry; ulint i; + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_reads++; os_bytes_read_since_printout += n; @@ -2324,7 +2327,10 @@ os_file_read_no_error_handling( ibool retry; ulint i; + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_reads++; os_bytes_read_since_printout += n; @@ -2447,7 +2453,10 @@ os_file_write( ulint n_retries = 0; ulint err; - ut_a((offset & 0xFFFFFFFF) == offset); + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ + ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_writes++; @@ -3245,14 +3254,16 @@ os_aio_array_reserve_slot( ulint len) /* in: length of the block to read or write */ { os_aio_slot_t* slot; + ulint i; #ifdef WIN_ASYNC_IO OVERLAPPED* control; + ut_a((len & 0xFFFFFFFFUL) == len); #elif defined(POSIX_ASYNC_IO) struct aiocb* control; #endif - ulint i; + loop: os_mutex_enter(array->mutex); @@ -3517,6 +3528,9 @@ os_aio( ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(os_aio_validate()); +#ifdef WIN_ASYNC_IO + ut_ad((n & 0xFFFFFFFFUL) == n); +#endif wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER; mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER); @@ -3765,16 +3779,18 @@ os_aio_windows_handle( /* retry failed read/write operation synchronously. No need to hold array->mutex. */ + ut_a((slot->len & 0xFFFFFFFFUL) == slot->len); + switch (slot->type) { case OS_FILE_WRITE: ret = WriteFile(slot->file, slot->buf, - slot->len, &len, + (DWORD) slot->len, &len, &(slot->control)); break; case OS_FILE_READ: ret = ReadFile(slot->file, slot->buf, - slot->len, &len, + (DWORD) slot->len, &len, &(slot->control)); break; From 460ad14e04d022ab9ccd122af7bcbc4a0030f67a Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Thu, 28 Oct 2010 00:10:28 -0500 Subject: [PATCH 146/151] Bug#52062: Compiler warning in os0file.c on windows 64-bit On Windows, the parameter for number of bytes passed into WriteFile() and ReadFile() is DWORD. Casting is needed to silence the warning on 64-bit Windows. Also, adding several asserts to ensure the variable for number of bytes is no more than 32 bits, even on 64-bit Windows. This is for InnoDB Plugin. rb://415 Approved by: Inaam --- storage/innodb_plugin/os/os0file.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c index 14b2fce43c3..ff80f7ed1b4 100644 --- a/storage/innodb_plugin/os/os0file.c +++ b/storage/innodb_plugin/os/os0file.c @@ -2280,7 +2280,10 @@ os_file_read( ulint i; #endif /* !UNIV_HOTBACKUP */ + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_reads++; os_bytes_read_since_printout += n; @@ -2404,7 +2407,10 @@ os_file_read_no_error_handling( ulint i; #endif /* !UNIV_HOTBACKUP */ + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_reads++; os_bytes_read_since_printout += n; @@ -2534,7 +2540,10 @@ os_file_write( ulint i; #endif /* !UNIV_HOTBACKUP */ - ut_a((offset & 0xFFFFFFFF) == offset); + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ + ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_writes++; @@ -3304,12 +3313,14 @@ os_aio_array_reserve_slot( ulint len) /*!< in: length of the block to read or write */ { os_aio_slot_t* slot; -#ifdef WIN_ASYNC_IO - OVERLAPPED* control; -#endif ulint i; ulint slots_per_seg; ulint local_seg; +#ifdef WIN_ASYNC_IO + OVERLAPPED* control; + + ut_a((len & 0xFFFFFFFFUL) == len); +#endif /* No need of a mutex. Only reading constant fields */ slots_per_seg = array->n_slots / array->n_segments; @@ -3589,6 +3600,9 @@ os_aio( ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(os_aio_validate()); +#ifdef WIN_ASYNC_IO + ut_ad((n & 0xFFFFFFFFUL) == n); +#endif wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER; mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER); @@ -3829,16 +3843,18 @@ os_aio_windows_handle( /* retry failed read/write operation synchronously. No need to hold array->mutex. */ + ut_a((slot->len & 0xFFFFFFFFUL) == slot->len); + switch (slot->type) { case OS_FILE_WRITE: ret = WriteFile(slot->file, slot->buf, - slot->len, &len, + (DWORD) slot->len, &len, &(slot->control)); break; case OS_FILE_READ: ret = ReadFile(slot->file, slot->buf, - slot->len, &len, + (DWORD) slot->len, &len, &(slot->control)); break; From ec51b47954455b4714efbbccdeb9f7e11c17a60a Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Thu, 28 Oct 2010 00:34:53 -0500 Subject: [PATCH 147/151] Bug#52062: Compiler warning in os0file.c on windows 64-bit On Windows, the parameter for number of bytes passed into WriteFile() and ReadFile() is DWORD. Casting is needed to silence the warning on 64-bit Windows. Also, adding several asserts to ensure the variable for number of bytes is no more than 32 bits, even on 64-bit Windows. rb://415 Approved by: Inaam --- storage/innobase/os/os0file.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index 3d1577fe3ca..93d2f72746d 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -2400,7 +2400,10 @@ os_file_read_func( ulint i; #endif /* !UNIV_HOTBACKUP */ + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_reads++; os_bytes_read_since_printout += n; @@ -2526,7 +2529,10 @@ os_file_read_no_error_handling_func( ulint i; #endif /* !UNIV_HOTBACKUP */ + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_reads++; os_bytes_read_since_printout += n; @@ -2658,7 +2664,10 @@ os_file_write_func( ulint i; #endif /* !UNIV_HOTBACKUP */ - ut_a((offset & 0xFFFFFFFF) == offset); + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ + ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_writes++; @@ -3621,6 +3630,10 @@ os_aio_array_reserve_slot( ulint slots_per_seg; ulint local_seg; +#ifdef WIN_ASYNC_IO + ut_a((len & 0xFFFFFFFFUL) == len); +#endif + /* No need of a mutex. Only reading constant fields */ slots_per_seg = array->n_slots / array->n_segments; @@ -3996,6 +4009,9 @@ os_aio_func( ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(os_aio_validate()); +#ifdef WIN_ASYNC_IO + ut_ad((n & 0xFFFFFFFFUL) == n); +#endif wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER; mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER); @@ -4271,16 +4287,18 @@ os_aio_windows_handle( __FILE__, __LINE__); #endif + ut_a((slot->len & 0xFFFFFFFFUL) == slot->len); + switch (slot->type) { case OS_FILE_WRITE: ret = WriteFile(slot->file, slot->buf, - slot->len, &len, + (DWORD) slot->len, &len, &(slot->control)); break; case OS_FILE_READ: ret = ReadFile(slot->file, slot->buf, - slot->len, &len, + (DWORD) slot->len, &len, &(slot->control)); break; From 1a9083b94ab0fef7dbf29fe6069f588f8a4acab5 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Thu, 28 Oct 2010 12:08:09 +0200 Subject: [PATCH 148/151] post merge fix --- sql/ha_partition.h | 12 ------------ sql/sql_partition_admin.cc | 2 ++ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 785d2388652..f1abc0cefe2 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -935,22 +935,16 @@ private: /* lock already taken */ if (auto_increment_safe_stmt_log_lock) return; -#ifdef WITH_PARTITION_STORAGE_ENGINE DBUG_ASSERT(table_share->ha_part_data && !auto_increment_lock); -#endif if(table_share->tmp_table == NO_TMP_TABLE) { auto_increment_lock= TRUE; -#ifdef WITH_PARTITION_STORAGE_ENGINE mysql_mutex_lock(&table_share->ha_part_data->LOCK_auto_inc); -#endif } } virtual void unlock_auto_increment() { -#ifdef WITH_PARTITION_STORAGE_ENGINE DBUG_ASSERT(table_share->ha_part_data); -#endif /* If auto_increment_safe_stmt_log_lock is true, we have to keep the lock. It will be set to false and thus unlocked at the end of the statement by @@ -958,25 +952,19 @@ private: */ if(auto_increment_lock && !auto_increment_safe_stmt_log_lock) { -#ifdef WITH_PARTITION_STORAGE_ENGINE mysql_mutex_unlock(&table_share->ha_part_data->LOCK_auto_inc); -#endif auto_increment_lock= FALSE; } } virtual void set_auto_increment_if_higher(Field *field) { -#ifdef WITH_PARTITION_STORAGE_ENGINE ulonglong nr= (((Field_num*) field)->unsigned_flag || field->val_int() > 0) ? field->val_int() : 0; -#endif lock_auto_increment(); -#ifdef WITH_PARTITION_STORAGE_ENGINE DBUG_ASSERT(table_share->ha_part_data->auto_inc_initialized == TRUE); /* must check when the mutex is taken */ if (nr >= table_share->ha_part_data->next_auto_inc_val) table_share->ha_part_data->next_auto_inc_val= nr + 1; -#endif unlock_auto_increment(); } diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index 98750314a4a..8f6ab5803d7 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -18,7 +18,9 @@ #include "sql_lex.h" // Sql_statement #include "sql_admin.h" // Analyze/Check/.._table_statement #include "sql_partition_admin.h" // Alter_table_*_partition +#ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" // ha_partition +#endif #include "sql_base.h" // open_and_lock_tables #ifndef WITH_PARTITION_STORAGE_ENGINE From e3decfa0aed2f2240eda7f0f92b14ff3a791b8d4 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 28 Oct 2010 20:12:23 +0300 Subject: [PATCH 149/151] Fix a compilation warning: /export/home/pb2/build/sb_0-2459340-1288264809.63/mysql-5.5.8-ga/storage/innobase/os/os0sync.c: In function 'os_cond_wait_timed': /export/home/pb2/build/sb_0-2459340-1288264809.63/mysql-5.5.8-ga/storage/innobase/os/os0sync.c:184: warning: format '%lu' expects type 'long unsigned int', but argument 4 has type 'time_t' gmake[2]: *** [storage/innobase/CMakeFiles/innobase.dir/os/os0sync.c.o] Error 1 --- storage/innobase/os/os0sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 2f481b76bda..24d36acecb2 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -181,7 +181,7 @@ os_cond_wait_timed( default: fprintf(stderr, " InnoDB: pthread_cond_timedwait() returned: " "%d: abstime={%lu,%lu}\n", - ret, abstime->tv_sec, abstime->tv_nsec); + ret, (ulong) abstime->tv_sec, (ulong) abstime->tv_nsec); ut_error; } From 6f03e15cf958da34b9517a1fc4ae6cf00c80b9de Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 28 Oct 2010 21:55:43 -0700 Subject: [PATCH 150/151] Merge fix for bug#57616 from mysql-5.5-security to mysql-5.5-innodb. --- storage/innobase/dict/dict0load.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index 74f108fcf8e..9c6fa086d58 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -1733,13 +1733,13 @@ err_exit: if (err != DB_SUCCESS) { dict_table_remove_from_cache(table); table = NULL; + } else { + table->fk_max_recusive_level = 0; } } else if (!srv_force_recovery) { dict_table_remove_from_cache(table); table = NULL; } - - table->fk_max_recusive_level = 0; #if 0 if (err != DB_SUCCESS && table != NULL) { From c3f923857a1cfcec4f1d037b20427931f8fe9a51 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 27 Oct 2010 18:12:17 +0300 Subject: [PATCH 151/151] Bug #57774: Typos/ambiguities in the WL1054 comments Fixed few typos and added better wording as suggested. --- include/mysql/plugin_auth.h | 6 +++--- plugin/auth/dialog.c | 6 +++--- plugin/auth/test_plugin.c | 26 ++++++++------------------ 3 files changed, 14 insertions(+), 24 deletions(-) diff --git a/include/mysql/plugin_auth.h b/include/mysql/plugin_auth.h index 5622e9cdebe..420eb3bb80f 100644 --- a/include/mysql/plugin_auth.h +++ b/include/mysql/plugin_auth.h @@ -90,8 +90,8 @@ typedef struct st_mysql_server_auth_info int password_used; /** - Set to the name of the connected client if it can be resolved, or to - the address otherwise + Set to the name of the connected client host, if it can be resolved, + or to its IP address otherwise. */ const char *host_or_ip; @@ -107,7 +107,7 @@ typedef struct st_mysql_server_auth_info */ struct st_mysql_auth { - int interface_version; /**< version plugin uses */ + int interface_version; /** version plugin uses */ /** A plugin that a client must use for authentication with this server plugin. Can be NULL to mean "any plugin". diff --git a/plugin/auth/dialog.c b/plugin/auth/dialog.c index 54f88dd9b4e..41312f95674 100644 --- a/plugin/auth/dialog.c +++ b/plugin/auth/dialog.c @@ -52,7 +52,7 @@ /** first byte of the question string is the question "type". - It can be a "ordinary" or a "password" question. + It can be an "ordinary" or a "password" question. The last bit set marks a last question in the authentication exchange. */ #define ORDINARY_QUESTION "\2" @@ -176,7 +176,7 @@ mysql_declare_plugin_end; This plugin performs a dialog with the user, asking questions and reading answers. Depending on the client it may be desirable to do it using GUI, or console, with or without curses, or read answers - from a smardcard, for example. + from a smartcard, for example. To support all this variety, the dialog plugin has a callback function "authentication_dialog_ask". If the client has a function of this name @@ -256,7 +256,7 @@ static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) in mysql_change_user() the client sends the first packet, so the first vio->read_packet() does nothing (pkt == 0). - We send the "password", assuming the client knows what its doing. + We send the "password", assuming the client knows what it's doing. (in other words, the dialog plugin should be only set as a default authentication plugin on the client if the first question asks for a password - which will be sent in clear text, by the way) diff --git a/plugin/auth/test_plugin.c b/plugin/auth/test_plugin.c index caea7795833..161062d5b6c 100644 --- a/plugin/auth/test_plugin.c +++ b/plugin/auth/test_plugin.c @@ -17,22 +17,12 @@ /** @file - dialog client authentication plugin with examples + Test driver for the mysql-test/t/plugin_auth.test - dialog is a general purpose client authentication plugin, it simply - asks the user the question, as provided by the server and reports - the answer back to the server. No encryption is involved, - the answers are sent in clear text. - - Two examples are provided: two_questions server plugin, that asks - the password and an "Are you sure?" question with a reply "yes, of course". - It demonstrates the usage of "password" (input is hidden) and "ordinary" - (input can be echoed) questions, and how to mark the last question, - to avoid an extra roundtrip. - - And three_attempts plugin that gives the user three attempts to enter - a correct password. It shows the situation when a number of questions - is not known in advance. + This is a set of test plugins used to test the external authentication + implementation. + See the above test file for more details. + This test plugin is based on the dialog plugin example. */ #include @@ -55,7 +45,7 @@ /********************* SERVER SIDE ****************************************/ /** - dialog test plugin mimicing the ordinary auth mechanism. Used to test the auth plugin API + dialog test plugin mimicking the ordinary auth mechanism. Used to test the auth plugin API */ static int auth_test_plugin(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) { @@ -150,10 +140,10 @@ static int test_plugin_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) in mysql_change_user() the client sends the first packet, so the first vio->read_packet() does nothing (pkt == 0). - We send the "password", assuming the client knows what its doing. + We send the "password", assuming the client knows what it's doing. (in other words, the dialog plugin should be only set as a default authentication plugin on the client if the first question - asks for a password - which will be sent in cleat text, by the way) + asks for a password - which will be sent in clear text, by the way) */ reply= mysql->passwd; }