From c6e0b8d18e768661a22d05e685348a0d0dec3aa1 Mon Sep 17 00:00:00 2001 From: "istruewing@chilla.local" <> Date: Wed, 16 May 2007 20:00:23 +0200 Subject: [PATCH 01/12] Bug#23068 - key_cache_block_size is not set or displayes correctly Command line and configuration file option 'key_cache_block_size' was reduced by MALLOC_OVERHEAD (8 in a production server, 36 in a debug server) from the user supplied value and restricted it to the greatest multiple of 512 less or equal to the reduced value. This patch changes option 'key_cache_block_size' to not deduce MALLOC_OVERHEAD from the input value. However, the restriction to a multiple of 512 is still done. --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e5abef25b62..c1c7dad1551 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5806,7 +5806,7 @@ log and this option does nothing anymore.", (gptr*) &dflt_key_cache_var.param_block_size, (gptr*) 0, 0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, - KEY_CACHE_BLOCK_SIZE , 512, 1024*16, MALLOC_OVERHEAD, 512, 0}, + KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0}, {"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT, "The minimum percentage of warm blocks in key cache", (gptr*) &dflt_key_cache_var.param_division_limit, From 57382213afd278a54b96b9652b8bfe0ade30e8e9 Mon Sep 17 00:00:00 2001 From: "antony@ppcg5.local" <> Date: Thu, 24 May 2007 10:39:24 -0700 Subject: [PATCH 02/12] Bug#27836 "sql_plugin.cc, dynamic_array is not dynamic" When the DYNAMIC_ARRAYs were resized, pointers became invalid. Solved by only storing pointers within the DYNAMIC_ARRAYs. --- sql/sql_plugin.cc | 56 +++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 5f8513a4a9e..5008019fb30 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -278,7 +278,7 @@ static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *dl) DBUG_ENTER("plugin_dl_find"); for (i= 0; i < plugin_dl_array.elements; i++) { - tmp= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *); + tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **); if (tmp->ref_count && ! my_strnncoll(files_charset_info, (const uchar *)dl->str, dl->length, @@ -296,17 +296,20 @@ static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl) DBUG_ENTER("plugin_dl_insert_or_reuse"); for (i= 0; i < plugin_dl_array.elements; i++) { - tmp= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *); + tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **); if (! tmp->ref_count) { memcpy(tmp, plugin_dl, sizeof(struct st_plugin_dl)); DBUG_RETURN(tmp); } } - if (insert_dynamic(&plugin_dl_array, (gptr)plugin_dl)) + if (insert_dynamic(&plugin_dl_array, (gptr)&plugin_dl)) DBUG_RETURN(0); - DBUG_RETURN(dynamic_element(&plugin_dl_array, plugin_dl_array.elements - 1, - struct st_plugin_dl *)); + tmp= *dynamic_element(&plugin_dl_array, plugin_dl_array.elements - 1, + struct st_plugin_dl **)= + (struct st_plugin_dl *) memdup_root(&plugin_mem_root, (gptr)plugin_dl, + sizeof(struct st_plugin_dl)); + DBUG_RETURN(tmp); } #endif /* HAVE_DLOPEN */ @@ -516,8 +519,8 @@ static void plugin_dl_del(const LEX_STRING *dl) for (i= 0; i < plugin_dl_array.elements; i++) { - struct st_plugin_dl *tmp= dynamic_element(&plugin_dl_array, i, - struct st_plugin_dl *); + struct st_plugin_dl *tmp= *dynamic_element(&plugin_dl_array, i, + struct st_plugin_dl **); if (tmp->ref_count && ! my_strnncoll(files_charset_info, (const uchar *)dl->str, dl->length, @@ -665,21 +668,24 @@ plugin_ref plugin_lock_by_name(THD *thd, const LEX_STRING *name, int type static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin) { uint i; + struct st_plugin_int *tmp; DBUG_ENTER("plugin_insert_or_reuse"); for (i= 0; i < plugin_array.elements; i++) { - struct st_plugin_int *tmp= dynamic_element(&plugin_array, i, - struct st_plugin_int *); + tmp= *dynamic_element(&plugin_array, i, struct st_plugin_int **); if (tmp->state == PLUGIN_IS_FREED) { memcpy(tmp, plugin, sizeof(struct st_plugin_int)); DBUG_RETURN(tmp); } } - if (insert_dynamic(&plugin_array, (gptr)plugin)) + if (insert_dynamic(&plugin_array, (gptr)&plugin)) DBUG_RETURN(0); - DBUG_RETURN(dynamic_element(&plugin_array, plugin_array.elements - 1, - struct st_plugin_int *)); + tmp= *dynamic_element(&plugin_array, plugin_array.elements - 1, + struct st_plugin_int **)= + (struct st_plugin_int *) memdup_root(&plugin_mem_root, (gptr)plugin, + sizeof(struct st_plugin_int)); + DBUG_RETURN(tmp); } @@ -874,7 +880,7 @@ static void reap_plugins(void) for (idx= 0; idx < count; idx++) { - plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *); + plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **); if (plugin->state == PLUGIN_IS_DELETED && !plugin->ref_count) { /* change the status flag to prevent reaping by another thread */ @@ -1097,9 +1103,9 @@ int plugin_init(int *argc, char **argv, int flags) pthread_mutex_init(&LOCK_plugin, MY_MUTEX_INIT_FAST); if (my_init_dynamic_array(&plugin_dl_array, - sizeof(struct st_plugin_dl),16,16) || + sizeof(struct st_plugin_dl *),16,16) || my_init_dynamic_array(&plugin_array, - sizeof(struct st_plugin_int),16,16)) + sizeof(struct st_plugin_int *),16,16)) goto err; for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++) @@ -1185,7 +1191,7 @@ int plugin_init(int *argc, char **argv, int flags) for (i= 0; i < plugin_array.elements; i++) { - plugin_ptr= dynamic_element(&plugin_array, i, struct st_plugin_int *); + plugin_ptr= *dynamic_element(&plugin_array, i, struct st_plugin_int **); if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED) { if (plugin_initialize(plugin_ptr)) @@ -1232,11 +1238,13 @@ static bool register_builtin(struct st_mysql_plugin *plugin, tmp->ref_count= 0; tmp->plugin_dl= 0; - if (insert_dynamic(&plugin_array, (gptr)tmp)) + if (insert_dynamic(&plugin_array, (gptr)&tmp)) DBUG_RETURN(1); - *ptr= dynamic_element(&plugin_array, plugin_array.elements - 1, - struct st_plugin_int *); + *ptr= *dynamic_element(&plugin_array, plugin_array.elements - 1, + struct st_plugin_int **)= + (struct st_plugin_int *) memdup_root(&plugin_mem_root, (gptr)tmp, + sizeof(struct st_plugin_int)); if (my_hash_insert(&plugin_hash[plugin->type],(byte*) *ptr)) DBUG_RETURN(1); @@ -1458,7 +1466,7 @@ void plugin_shutdown(void) reap_plugins(); for (i= free_slots= 0; i < count; i++) { - plugin= dynamic_element(&plugin_array, i, struct st_plugin_int *); + plugin= *dynamic_element(&plugin_array, i, struct st_plugin_int **); switch (plugin->state) { case PLUGIN_IS_READY: plugin->state= PLUGIN_IS_DELETED; @@ -1490,7 +1498,7 @@ void plugin_shutdown(void) */ for (i= 0; i < count; i++) { - plugins[i]= dynamic_element(&plugin_array, i, struct st_plugin_int *); + plugins[i]= *dynamic_element(&plugin_array, i, struct st_plugin_int **); /* change the state to ensure no reaping races */ if (plugins[i]->state == PLUGIN_IS_DELETED) plugins[i]->state= PLUGIN_IS_DYING; @@ -1555,7 +1563,7 @@ void plugin_shutdown(void) count= plugin_dl_array.elements; dl= (struct st_plugin_dl **)my_alloca(sizeof(void*) * count); for (i= 0; i < count; i++) - dl[i]= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *); + dl[i]= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **); for (i= 0; i < plugin_dl_array.elements; i++) free_plugin_mem(dl[i]); my_afree(dl); @@ -1714,7 +1722,7 @@ bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func, { for (idx= 0; idx < total; idx++) { - plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *); + plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **); plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL; } } @@ -3139,7 +3147,7 @@ void my_print_help_inc_plugins(my_option *main_options, uint size) if (initialized) for (uint idx= 0; idx < plugin_array.elements; idx++) { - p= dynamic_element(&plugin_array, idx, struct st_plugin_int *); + p= *dynamic_element(&plugin_array, idx, struct st_plugin_int **); if (!p->plugin->system_vars || !(opt= construct_help_options(&mem_root, p))) From 8e06a2b0dd6fdc7e3c7b9c62f4dde58a997677b7 Mon Sep 17 00:00:00 2001 From: "acurtis/antony@xiphis.org/ltamd64.xiphis.org" <> Date: Fri, 25 May 2007 16:40:24 -0700 Subject: [PATCH 03/12] Missing functionality in WL#2936: String variables not readable by using @@name. Required for WL1722. --- sql/set_var.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sql/set_var.cc b/sql/set_var.cc index 3dc8cddcb26..bd9b31468f7 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1489,6 +1489,25 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) pthread_mutex_unlock(&LOCK_global_system_variables); return new Item_int(value,1); } + case SHOW_CHAR_PTR: + { + Item *tmp; + pthread_mutex_lock(&LOCK_global_system_variables); + char *str= *(char**) value_ptr(thd, var_type, base); + if (str) + { + uint length= strlen(str); + tmp= new Item_string(thd->strmake(str, length), length, + system_charset_info, DERIVATION_SYSCONST); + } + else + { + tmp= new Item_null(); + tmp->collation.set(system_charset_info, DERIVATION_SYSCONST); + } + pthread_mutex_unlock(&LOCK_global_system_variables); + return tmp; + } case SHOW_CHAR: { Item *tmp; From 5d71c2f885eb20bfb2e1e484a494acda0025e0d7 Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/june.mysql.com" <> Date: Mon, 28 May 2007 13:27:26 +0500 Subject: [PATCH 04/12] BUG#18839 - return value of parser->parse() is ignored Check value returned by parser->parse(). Better handle situations when it fails. --- storage/myisam/ft_boolean_search.c | 51 ++++++++++++++++++------------ storage/myisam/ft_nlq_search.c | 8 +++-- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c index 68076d7e401..f5866011f04 100644 --- a/storage/myisam/ft_boolean_search.c +++ b/storage/myisam/ft_boolean_search.c @@ -286,8 +286,8 @@ static int ftb_parse_query_internal(MYSQL_FTPARSER_PARAM *param, } -static void _ftb_parse_query(FTB *ftb, byte *query, uint len, - struct st_mysql_ftparser *parser) +static int _ftb_parse_query(FTB *ftb, byte *query, uint len, + struct st_mysql_ftparser *parser) { MYSQL_FTPARSER_PARAM *param; MY_FTB_PARAM ftb_param; @@ -295,9 +295,9 @@ static void _ftb_parse_query(FTB *ftb, byte *query, uint len, DBUG_ASSERT(parser); if (ftb->state != UNINITIALIZED) - DBUG_VOID_RETURN; + DBUG_RETURN(0); if (! (param= ftparser_call_initializer(ftb->info, ftb->keynr, 0))) - DBUG_VOID_RETURN; + DBUG_RETURN(1); ftb_param.ftb= ftb; ftb_param.depth= 0; @@ -312,8 +312,7 @@ static void _ftb_parse_query(FTB *ftb, byte *query, uint len, param->length= len; param->flags= 0; param->mode= MYSQL_FTPARSER_FULL_BOOLEAN_INFO; - parser->parse(param); - DBUG_VOID_RETURN; + DBUG_RETURN(parser->parse(param)); } @@ -538,9 +537,10 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, ftbe->phrase= NULL; ftbe->document= 0; ftb->root=ftbe; - _ftb_parse_query(ftb, query, query_len, keynr == NO_SUCH_KEY ? - &ft_default_parser : - info->s->keyinfo[keynr].parser); + if (unlikely(_ftb_parse_query(ftb, query, query_len, + keynr == NO_SUCH_KEY ? &ft_default_parser : + info->s->keyinfo[keynr].parser))) + goto err; /* Hack: instead of init_queue, we'll use reinit queue to be able to alloc queue with alloc_root() @@ -621,7 +621,7 @@ static int ftb_check_phrase_internal(MYSQL_FTPARSER_PARAM *param, { param->mysql_add_word(param, word.pos, word.len, 0); if (phrase_param->match) - return 1; + break; } return 0; } @@ -639,6 +639,7 @@ static int ftb_check_phrase_internal(MYSQL_FTPARSER_PARAM *param, RETURN VALUE 1 is returned if phrase found, 0 else. + -1 is returned if error occurs. */ static int _ftb_check_phrase(FTB *ftb, const byte *document, uint len, @@ -667,12 +668,13 @@ static int _ftb_check_phrase(FTB *ftb, const byte *document, uint len, param->length= len; param->flags= 0; param->mode= MYSQL_FTPARSER_WITH_STOPWORDS; - parser->parse(param); + if (unlikely(parser->parse(param))) + return -1; DBUG_RETURN(ftb_param.match ? 1 : 0); } -static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig) +static int _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig) { FT_SEG_ITERATOR ftsi; FTB_EXPR *ftbe; @@ -704,17 +706,19 @@ static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_ weight=ftbe->cur_weight*ftbe->weight; if (mode && ftbe->phrase) { - int not_found=1; + int found= 0; memcpy(&ftsi, ftsi_orig, sizeof(ftsi)); - while (_mi_ft_segiterator(&ftsi) && not_found) + while (_mi_ft_segiterator(&ftsi) && !found) { if (!ftsi.pos) continue; - not_found = ! _ftb_check_phrase(ftb, ftsi.pos, ftsi.len, - ftbe, parser); + found= _ftb_check_phrase(ftb, ftsi.pos, ftsi.len, ftbe, parser); + if (unlikely(found < 0)) + return 1; } - if (not_found) break; + if (!found) + break; } /* ftbe->quot */ } else @@ -746,6 +750,7 @@ static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_ weight*= ftbe->weight; } } + return 0; } @@ -778,7 +783,11 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record) { while (curdoc == (ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0]) { - _ftb_climb_the_tree(ftb, ftbw, 0); + if (unlikely(_ftb_climb_the_tree(ftb, ftbw, 0))) + { + my_errno= HA_ERR_OUT_OF_MEM; + goto err; + } /* update queue */ _ft2_search(ftb, ftbw, 0); @@ -854,7 +863,8 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param, if (ftbw->docid[1] == ftb->info->lastpos) continue; ftbw->docid[1]= ftb->info->lastpos; - _ftb_climb_the_tree(ftb, ftbw, ftb_param->ftsi); + if (unlikely(_ftb_climb_the_tree(ftb, ftbw, ftb_param->ftsi))) + return 1; } return(0); } @@ -926,7 +936,8 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) continue; param->doc= (byte *)ftsi.pos; param->length= ftsi.len; - parser->parse(param); + if (unlikely(parser->parse(param))) + return 0; } ftbe=ftb->root; if (ftbe->docid[1]==docid && ftbe->cur_weight>0 && diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c index 5c6f66897ee..2bef5238501 100644 --- a/storage/myisam/ft_nlq_search.c +++ b/storage/myisam/ft_nlq_search.c @@ -257,8 +257,12 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query, { info->update|= HA_STATE_AKTIV; ftparser_param->flags= MYSQL_FTFLAGS_NEED_COPY; - _mi_ft_parse(&wtree, info, keynr, record, ftparser_param, - &wtree.mem_root); + if (unlikely(_mi_ft_parse(&wtree, info, keynr, record, ftparser_param, + &wtree.mem_root))) + { + delete_queue(&best); + goto err; + } } } delete_queue(&best); From 59a05422097a9f902f29c0aa749f65f321e23460 Mon Sep 17 00:00:00 2001 From: "istruewing@chilla.local" <> Date: Thu, 31 May 2007 20:04:54 +0200 Subject: [PATCH 05/12] Bug#28478 - Improper key_cache_block_size corrupts MyISAM tables Setting a key_cache_block_size which is not a power of 2 could corrupt MyISAM tables. A couple of computations in the key cache code use bit operations which do only work if key_cache_block_size is a power of 2. Replaced bit operations by arithmetic operations to make key cache able to handle block sizes that are not a power of 2. --- include/keycache.h | 1 - mysql-test/r/key_cache.result | 27 +++++++++++++++++++++++++++ mysql-test/t/key_cache.test | 27 +++++++++++++++++++++++++++ mysys/mf_keycache.c | 11 +++++------ 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/include/keycache.h b/include/keycache.h index dc763b8cc08..54c099fc474 100644 --- a/include/keycache.h +++ b/include/keycache.h @@ -46,7 +46,6 @@ typedef struct st_key_cache my_bool key_cache_inited; my_bool resize_in_flush; /* true during flush of resize operation */ my_bool can_be_used; /* usage of cache for read/write is allowed */ - uint key_cache_shift; ulong key_cache_mem_size; /* specified size of the cache memory */ uint key_cache_block_size; /* size of the page buffer of a cache block */ ulong min_warm_blocks; /* min number of warm blocks; */ diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result index a1bf3d0e128..1ab58c1ad6c 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -341,3 +341,30 @@ Warning 1438 Cannot drop default keycache select @@global.key_buffer_size; @@global.key_buffer_size 2097152 +SET @bug28478_key_cache_block_size= @@global.key_cache_block_size; +SET GLOBAL key_cache_block_size= 1536; +CREATE TABLE t1 ( +id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c1 CHAR(150), +c2 CHAR(150), +c3 CHAR(150), +KEY(c1, c2, c3) +) ENGINE= MyISAM; +INSERT INTO t1 (c1, c2, c3) VALUES +('a', 'b', 'c'), ('b', 'c', 'd'), ('c', 'd', 'e'), ('d', 'e', 'f'), +('e', 'f', 'g'), ('f', 'g', 'h'), ('g', 'h', 'i'), ('h', 'i', 'j'), +('i', 'j', 'k'), ('j', 'k', 'l'), ('k', 'l', 'm'), ('l', 'm', 'n'), +('m', 'n', 'o'), ('n', 'o', 'p'), ('o', 'p', 'q'), ('p', 'q', 'r'), +('q', 'r', 's'), ('r', 's', 't'), ('s', 't', 'u'), ('t', 'u', 'v'), +('u', 'v', 'w'), ('v', 'w', 'x'), ('w', 'x', 'y'), ('x', 'y', 'z'); +INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1; +INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1; +INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SHOW VARIABLES LIKE 'key_cache_block_size'; +Variable_name Value +key_cache_block_size 1536 +SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size; +DROP TABLE t1; diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test index 3044964ebc3..4c14dc96aaa 100644 --- a/mysql-test/t/key_cache.test +++ b/mysql-test/t/key_cache.test @@ -219,4 +219,31 @@ set global key_cache_block_size= @my_key_cache_block_size; set @@global.key_buffer_size=0; select @@global.key_buffer_size; +# +# Bug#28478 - Improper key_cache_block_size corrupts MyISAM tables +# +SET @bug28478_key_cache_block_size= @@global.key_cache_block_size; +SET GLOBAL key_cache_block_size= 1536; +CREATE TABLE t1 ( + id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c1 CHAR(150), + c2 CHAR(150), + c3 CHAR(150), + KEY(c1, c2, c3) + ) ENGINE= MyISAM; +INSERT INTO t1 (c1, c2, c3) VALUES + ('a', 'b', 'c'), ('b', 'c', 'd'), ('c', 'd', 'e'), ('d', 'e', 'f'), + ('e', 'f', 'g'), ('f', 'g', 'h'), ('g', 'h', 'i'), ('h', 'i', 'j'), + ('i', 'j', 'k'), ('j', 'k', 'l'), ('k', 'l', 'm'), ('l', 'm', 'n'), + ('m', 'n', 'o'), ('n', 'o', 'p'), ('o', 'p', 'q'), ('p', 'q', 'r'), + ('q', 'r', 's'), ('r', 's', 't'), ('s', 't', 'u'), ('t', 'u', 'v'), + ('u', 'v', 'w'), ('v', 'w', 'x'), ('w', 'x', 'y'), ('x', 'y', 'z'); +INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1; +INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1; +INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1; +CHECK TABLE t1; +SHOW VARIABLES LIKE 'key_cache_block_size'; +SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size; +DROP TABLE t1; + # End of 4.1 tests diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 87f136dbf81..af910678a1f 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -173,7 +173,7 @@ static void test_key_cache(KEY_CACHE *keycache, #endif #define KEYCACHE_HASH(f, pos) \ -(((ulong) ((pos) >> keycache->key_cache_shift)+ \ +(((ulong) ((pos) / keycache->key_cache_block_size) + \ (ulong) (f)) & (keycache->hash_entries-1)) #define FILE_HASH(f) ((uint) (f) & (CHANGED_BLOCKS_HASH-1)) @@ -329,7 +329,6 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, keycache->key_cache_mem_size= use_mem; keycache->key_cache_block_size= key_cache_block_size; - keycache->key_cache_shift= my_bit_log2(key_cache_block_size); DBUG_PRINT("info", ("key_cache_block_size: %u", key_cache_block_size)); @@ -352,7 +351,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, ALIGN_SIZE(hash_links * sizeof(HASH_LINK)) + ALIGN_SIZE(sizeof(HASH_LINK*) * keycache->hash_entries))) + - ((ulong) blocks << keycache->key_cache_shift) > use_mem) + ((ulong) blocks * keycache->key_cache_block_size) > use_mem) blocks--; /* Allocate memory for cache page buffers */ if ((keycache->block_mem= @@ -1807,7 +1806,7 @@ byte *key_cache_read(KEY_CACHE *keycache, uint status; int page_st; - offset= (uint) (filepos & (keycache->key_cache_block_size-1)); + offset= (uint) (filepos % keycache->key_cache_block_size); /* Read data in key_cache_block_size increments */ do { @@ -1946,7 +1945,7 @@ int key_cache_insert(KEY_CACHE *keycache, int error; uint offset; - offset= (uint) (filepos & (keycache->key_cache_block_size-1)); + offset= (uint) (filepos % keycache->key_cache_block_size); do { keycache_pthread_mutex_lock(&keycache->cache_lock); @@ -2081,7 +2080,7 @@ int key_cache_write(KEY_CACHE *keycache, int page_st; uint offset; - offset= (uint) (filepos & (keycache->key_cache_block_size-1)); + offset= (uint) (filepos % keycache->key_cache_block_size); do { keycache_pthread_mutex_lock(&keycache->cache_lock); From 316f09d444bbdd1903165ad1b4a59b0a9e176212 Mon Sep 17 00:00:00 2001 From: "istruewing@chilla.local" <> Date: Thu, 31 May 2007 22:07:44 +0200 Subject: [PATCH 06/12] post-merge fix --- sql/sql_plugin.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 2c5fb75e575..c0161463550 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -307,7 +307,7 @@ static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl) DBUG_RETURN(0); tmp= *dynamic_element(&plugin_dl_array, plugin_dl_array.elements - 1, struct st_plugin_dl **)= - (struct st_plugin_dl *) memdup_root(&plugin_mem_root, (gptr)plugin_dl, + (struct st_plugin_dl *) memdup_root(&plugin_mem_root, (uchar*)plugin_dl, sizeof(struct st_plugin_dl)); DBUG_RETURN(tmp); } @@ -683,7 +683,7 @@ static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin) DBUG_RETURN(0); tmp= *dynamic_element(&plugin_array, plugin_array.elements - 1, struct st_plugin_int **)= - (struct st_plugin_int *) memdup_root(&plugin_mem_root, (gptr)plugin, + (struct st_plugin_int *) memdup_root(&plugin_mem_root, (uchar*)plugin, sizeof(struct st_plugin_int)); DBUG_RETURN(tmp); } @@ -1244,7 +1244,7 @@ static bool register_builtin(struct st_mysql_plugin *plugin, *ptr= *dynamic_element(&plugin_array, plugin_array.elements - 1, struct st_plugin_int **)= - (struct st_plugin_int *) memdup_root(&plugin_mem_root, (gptr)tmp, + (struct st_plugin_int *) memdup_root(&plugin_mem_root, (uchar*)tmp, sizeof(struct st_plugin_int)); if (my_hash_insert(&plugin_hash[plugin->type],(uchar*) *ptr)) From 0478ef18ec595973410b76a483078bc61bc9a52f Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/june.mysql.com" <> Date: Fri, 1 Jun 2007 13:50:13 +0500 Subject: [PATCH 07/12] BUG#28574 - repair table causes queries to fail with various corruption errors: 126,134,145 When one thread attempts to lock two (or more) tables and another thread executes statement that aborts these locks (e.g. REPAIR TABLE) we may get a table object with wrong lock type in a table cache. For example if SELECT FROM t1,t2 was aborted, subsequent INSERT INTO t1 may be executed under read lock. As a result we may get various table corruptions and even a server crash. This is fixed by resetting lock type in case lock was aborted by another thread. I failed to create reasonable test case for this bug. --- sql/lock.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sql/lock.cc b/sql/lock.cc index 3b2b2857f65..92c34f84b97 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -155,6 +155,13 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags) if (thr_multi_lock(sql_lock->locks + sql_lock->lock_count, sql_lock->lock_count)) { + /* + reset_lock_data is required here. If thr_multi_lock fails it + resets lock type for tables, which were locked before (and + including) one that caused error. Lock type for other tables + preserved. + */ + reset_lock_data(sql_lock); thd->some_tables_deleted=1; // Try again sql_lock->lock_count=0; // Locks are alread freed } From bb437f82051670959ed022039e9d20de94087129 Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/april.(none)" <> Date: Tue, 5 Jun 2007 03:16:02 +0500 Subject: [PATCH 08/12] BUG#27141 - Calling tell(-1) under Windows causes assertion failure in Debug mode Original problem was fixed by Magnus (see BUG25807). Currently only windows debug build causes assertion failure. This patch assures that my_tell gets correct file descriptor on any platform by DBUG_ASSERT macro. --- mysys/my_seek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mysys/my_seek.c b/mysys/my_seek.c index 3d415400aa2..5c1a6c44b6f 100644 --- a/mysys/my_seek.c +++ b/mysys/my_seek.c @@ -88,6 +88,7 @@ my_off_t my_tell(File fd, myf MyFlags __attribute__((unused))) os_off_t pos; DBUG_ENTER("my_tell"); DBUG_PRINT("my",("Fd: %d MyFlags: %d",fd, MyFlags)); + DBUG_ASSERT(fd >= 0); #ifdef HAVE_TELL pos=tell(fd); #else From bd8f81f470d285b27fb52924aa2c3de57ce25592 Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/april.(none)" <> Date: Wed, 6 Jun 2007 04:42:41 +0500 Subject: [PATCH 09/12] BUG#26976 - Missing table in merge not noted in related error msg + SHOW CREATE TABLE fails Underlying table names, that merge engine fails to open were not reported. With this fix CHECK TABLE issued against merge table reports all underlying table names that it fails to open. Other statements are unaffected, that is underlying table names are not included into error message. This fix doesn't solve SHOW CREATE TABLE issue. --- myisammrg/myrg_def.h | 5 ++- myisammrg/myrg_open.c | 12 +++++ mysql-test/r/backup.result | 6 +-- mysql-test/r/key_cache.result | 4 +- mysql-test/r/lock.result | 3 +- mysql-test/r/merge.result | 32 ++++++++++++++ mysql-test/r/preload.result | 13 +++--- mysql-test/r/ps.result | 30 +++++-------- mysql-test/r/repair.result | 10 ++--- mysql-test/r/rpl_failed_optimize.result | 5 +-- mysql-test/r/sp.result | 33 +++++++------- mysql-test/r/view.result | 58 ++++++++++++++----------- mysql-test/t/merge.test | 21 +++++++++ sql/ha_myisam.cc | 21 +++++---- sql/ha_myisammrg.cc | 26 ++++++++++- sql/ha_myisammrg.h | 1 + sql/share/errmsg.txt | 3 +- sql/sql_error.cc | 4 +- sql/sql_error.h | 2 + sql/sql_table.cc | 49 ++++++++++----------- 20 files changed, 213 insertions(+), 125 deletions(-) diff --git a/myisammrg/myrg_def.h b/myisammrg/myrg_def.h index 344bd4edd3c..bc114523a80 100644 --- a/myisammrg/myrg_def.h +++ b/myisammrg/myrg_def.h @@ -29,4 +29,7 @@ extern pthread_mutex_t THR_LOCK_open; int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag); int _myrg_mi_read_record(MI_INFO *info, byte *buf); - +#ifdef __cplusplus +extern "C" +#endif +void myrg_print_wrong_table(const char *table_name); diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c index afab21dfa3d..0e82e429afd 100644 --- a/myisammrg/myrg_open.c +++ b/myisammrg/myrg_open.c @@ -90,6 +90,11 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0)))) { my_errno= HA_ERR_WRONG_MRG_TABLE_DEF; + if (handle_locking & HA_OPEN_FOR_REPAIR) + { + myrg_print_wrong_table(buff); + continue; + } goto err; } if (!m_info) /* First file */ @@ -118,6 +123,11 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) if (m_info->reclength != isam->s->base.reclength) { my_errno=HA_ERR_WRONG_MRG_TABLE_DEF; + if (handle_locking & HA_OPEN_FOR_REPAIR) + { + myrg_print_wrong_table(buff); + continue; + } goto err; } m_info->options|= isam->s->options; @@ -131,6 +141,8 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) m_info->tables); } + if (my_errno == HA_ERR_WRONG_MRG_TABLE_DEF) + goto err; if (!m_info && !(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO), MYF(MY_WME | MY_ZEROFILL)))) goto err; diff --git a/mysql-test/r/backup.result b/mysql-test/r/backup.result index 29702e583cc..14313ba490f 100644 --- a/mysql-test/r/backup.result +++ b/mysql-test/r/backup.result @@ -4,18 +4,16 @@ create table t4(n int); backup table t4 to '../bogus'; Table Op Msg_type Msg_text test.t4 backup error Failed copying .frm file (errno: X) +test.t4 backup Error Can't create/write to file 'MYSQLTEST_VARDIR/bogus/t4.frm' (Errcode: X) test.t4 backup status Operation failed -Warnings: -Error 1 Can't create/write to file 'MYSQLTEST_VARDIR/bogus/t4.frm' (Errcode: X) backup table t4 to '../tmp'; Table Op Msg_type Msg_text test.t4 backup status OK backup table t4 to '../tmp'; Table Op Msg_type Msg_text test.t4 backup error Failed copying .frm file (errno: X) +test.t4 backup Error Can't create/write to file 'MYSQLTEST_VARDIR/tmp/t4.frm' (Errcode: X) test.t4 backup status Operation failed -Warnings: -Error 1 Can't create/write to file 'MYSQLTEST_VARDIR/tmp/t4.frm' (Errcode: X) drop table t4; restore table t4 from '../tmp'; Table Op Msg_type Msg_text diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result index 1ab58c1ad6c..08d8059f61b 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -191,10 +191,8 @@ cache index t1 in unknown_key_cache; ERROR HY000: Unknown key cache 'unknown_key_cache' cache index t1 key (unknown_key) in keycache1; Table Op Msg_type Msg_text -test.t1 assign_to_keycache error Key 'unknown_key' doesn't exist in table 't1' +test.t1 assign_to_keycache Error Key 'unknown_key' doesn't exist in table 't1' test.t1 assign_to_keycache status Operation failed -Warnings: -Error 1176 Key 'unknown_key' doesn't exist in table 't1' select @@keycache2.key_buffer_size; @@keycache2.key_buffer_size 4194304 diff --git a/mysql-test/r/lock.result b/mysql-test/r/lock.result index 079b0253ff6..a5a78ecc986 100644 --- a/mysql-test/r/lock.result +++ b/mysql-test/r/lock.result @@ -40,7 +40,8 @@ test.t1 check status OK lock tables t1 write; check table t2; Table Op Msg_type Msg_text -test.t2 check error Table 't2' was not locked with LOCK TABLES +test.t2 check Error Table 't2' was not locked with LOCK TABLES +test.t2 check error Corrupt insert into t1 select index1,nr from t1; ERROR HY000: Table 't1' was not locked with LOCK TABLES unlock tables; diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 27465dd96f6..9f7d5f54d0e 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -844,4 +844,36 @@ insert into t1 values (1); ERROR HY000: Table 't1' is read only drop table t2; drop table t1; +CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1, t2); +SELECT * FROM tm1; +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +CHECK TABLE tm1; +Table Op Msg_type Msg_text +test.tm1 check Error Table './test/t1' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Table './test/t2' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check error Corrupt +CREATE TABLE t1(a INT); +SELECT * FROM tm1; +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +CHECK TABLE tm1; +Table Op Msg_type Msg_text +test.tm1 check Error Table './test/t2' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check error Corrupt +CREATE TABLE t2(a BLOB); +SELECT * FROM tm1; +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +CHECK TABLE tm1; +Table Op Msg_type Msg_text +test.tm1 check Error Table './test/t2' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check error Corrupt +ALTER TABLE t2 MODIFY a INT; +SELECT * FROM tm1; +a +CHECK TABLE tm1; +Table Op Msg_type Msg_text +test.tm1 check status OK +DROP TABLE tm1, t1, t2; End of 5.0 tests diff --git a/mysql-test/r/preload.result b/mysql-test/r/preload.result index 145fd22ffb6..24a6e594a14 100644 --- a/mysql-test/r/preload.result +++ b/mysql-test/r/preload.result @@ -143,10 +143,9 @@ Key_read_requests 0 Key_reads 0 load index into cache t3, t2 key (primary,b) ; Table Op Msg_type Msg_text -test.t3 preload_keys error Table 'test.t3' doesn't exist +test.t3 preload_keys Error Table 'test.t3' doesn't exist +test.t3 preload_keys error Corrupt test.t2 preload_keys status OK -Warnings: -Error 1146 Table 'test.t3' doesn't exist show status like "key_read%"; Variable_name Value Key_read_requests 478 @@ -159,12 +158,10 @@ Key_read_requests 0 Key_reads 0 load index into cache t3 key (b), t2 key (c) ; Table Op Msg_type Msg_text -test.t3 preload_keys error Table 'test.t3' doesn't exist -test.t2 preload_keys error Key 'c' doesn't exist in table 't2' +test.t3 preload_keys Error Table 'test.t3' doesn't exist +test.t3 preload_keys error Corrupt +test.t2 preload_keys Error Key 'c' doesn't exist in table 't2' test.t2 preload_keys status Operation failed -Warnings: -Error 1146 Table 'test.t3' doesn't exist -Error 1176 Key 'c' doesn't exist in table 't2' show status like "key_read%"; Variable_name Value Key_read_requests 0 diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 8a10a52ee65..fcf532320e0 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1378,45 +1378,39 @@ prepare stmt from "repair table t1, t4, t3"; execute stmt; Table Op Msg_type Msg_text test.t1 repair status OK -test.t4 repair error Table 'test.t4' doesn't exist +test.t4 repair Error Table 'test.t4' doesn't exist +test.t4 repair error Corrupt test.t3 repair status OK -Warnings: -Error 1146 Table 'test.t4' doesn't exist execute stmt; Table Op Msg_type Msg_text test.t1 repair status OK -test.t4 repair error Table 'test.t4' doesn't exist +test.t4 repair Error Table 'test.t4' doesn't exist +test.t4 repair error Corrupt test.t3 repair status OK -Warnings: -Error 1146 Table 'test.t4' doesn't exist prepare stmt from "optimize table t1, t3, t4"; execute stmt; Table Op Msg_type Msg_text test.t1 optimize status OK test.t3 optimize status OK -test.t4 optimize error Table 'test.t4' doesn't exist -Warnings: -Error 1146 Table 'test.t4' doesn't exist +test.t4 optimize Error Table 'test.t4' doesn't exist +test.t4 optimize error Corrupt execute stmt; Table Op Msg_type Msg_text test.t1 optimize status Table is already up to date test.t3 optimize status Table is already up to date -test.t4 optimize error Table 'test.t4' doesn't exist -Warnings: -Error 1146 Table 'test.t4' doesn't exist +test.t4 optimize Error Table 'test.t4' doesn't exist +test.t4 optimize error Corrupt prepare stmt from "analyze table t4, t1"; execute stmt; Table Op Msg_type Msg_text -test.t4 analyze error Table 'test.t4' doesn't exist +test.t4 analyze Error Table 'test.t4' doesn't exist +test.t4 analyze error Corrupt test.t1 analyze status Table is already up to date -Warnings: -Error 1146 Table 'test.t4' doesn't exist execute stmt; Table Op Msg_type Msg_text -test.t4 analyze error Table 'test.t4' doesn't exist +test.t4 analyze Error Table 'test.t4' doesn't exist +test.t4 analyze error Corrupt test.t1 analyze status Table is already up to date -Warnings: -Error 1146 Table 'test.t4' doesn't exist deallocate prepare stmt; drop table t1, t2, t3; create database mysqltest_long_database_name_to_thrash_heap; diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result index 417a5e0c990..bd746711f1f 100644 --- a/mysql-test/r/repair.result +++ b/mysql-test/r/repair.result @@ -26,16 +26,14 @@ t1 1 st_key 1 st A NULL NULL NULL YES BTREE disabled drop table t1; repair table t1 use_frm; Table Op Msg_type Msg_text -test.t1 repair error Table 'test.t1' doesn't exist -Warnings: -Error 1146 Table 'test.t1' doesn't exist +test.t1 repair Error Table 'test.t1' doesn't exist +test.t1 repair error Corrupt create table t1 engine=myisam SELECT 1,"table 1"; flush tables; repair table t1; Table Op Msg_type Msg_text -test.t1 repair error Incorrect file format 't1' -Warnings: -Error 130 Incorrect file format 't1' +test.t1 repair Error Incorrect file format 't1' +test.t1 repair error Corrupt repair table t1 use_frm; Table Op Msg_type Msg_text test.t1 repair warning Number of rows changed from 0 to 1 diff --git a/mysql-test/r/rpl_failed_optimize.result b/mysql-test/r/rpl_failed_optimize.result index c2c07dc6343..33a8cdc4a2f 100644 --- a/mysql-test/r/rpl_failed_optimize.result +++ b/mysql-test/r/rpl_failed_optimize.result @@ -15,7 +15,6 @@ Warnings: Error 1205 Lock wait timeout exceeded; try restarting transaction OPTIMIZE TABLE non_existing; Table Op Msg_type Msg_text -test.non_existing optimize error Table 'test.non_existing' doesn't exist -Warnings: -Error 1146 Table 'test.non_existing' doesn't exist +test.non_existing optimize Error Table 'test.non_existing' doesn't exist +test.non_existing optimize error Corrupt drop table t1; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index b5b79af031e..558a34e5ab6 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -4409,55 +4409,58 @@ Table Op Msg_type Msg_text test.t1 repair status OK test.t2 repair status OK test.t3 repair status OK -test.v1 repair error 'test.v1' is not BASE TABLE +test.v1 repair Error 'test.v1' is not BASE TABLE +test.v1 repair error Corrupt Table Op Msg_type Msg_text test.t1 optimize status OK test.t2 optimize status OK test.t3 optimize status OK -test.v1 optimize error 'test.v1' is not BASE TABLE +test.v1 optimize Error 'test.v1' is not BASE TABLE +test.v1 optimize error Corrupt Table Op Msg_type Msg_text test.t1 analyze status Table is already up to date test.t2 analyze status Table is already up to date test.t3 analyze status Table is already up to date -test.v1 analyze error 'test.v1' is not BASE TABLE -Warnings: -Error 1347 'test.v1' is not BASE TABLE +test.v1 analyze Error 'test.v1' is not BASE TABLE +test.v1 analyze error Corrupt call bug13012()| Table Op Msg_type Msg_text test.t1 repair status OK test.t2 repair status OK test.t3 repair status OK -test.v1 repair error 'test.v1' is not BASE TABLE +test.v1 repair Error 'test.v1' is not BASE TABLE +test.v1 repair error Corrupt Table Op Msg_type Msg_text test.t1 optimize status OK test.t2 optimize status OK test.t3 optimize status OK -test.v1 optimize error 'test.v1' is not BASE TABLE +test.v1 optimize Error 'test.v1' is not BASE TABLE +test.v1 optimize error Corrupt Table Op Msg_type Msg_text test.t1 analyze status Table is already up to date test.t2 analyze status Table is already up to date test.t3 analyze status Table is already up to date -test.v1 analyze error 'test.v1' is not BASE TABLE -Warnings: -Error 1347 'test.v1' is not BASE TABLE +test.v1 analyze Error 'test.v1' is not BASE TABLE +test.v1 analyze error Corrupt call bug13012()| Table Op Msg_type Msg_text test.t1 repair status OK test.t2 repair status OK test.t3 repair status OK -test.v1 repair error 'test.v1' is not BASE TABLE +test.v1 repair Error 'test.v1' is not BASE TABLE +test.v1 repair error Corrupt Table Op Msg_type Msg_text test.t1 optimize status OK test.t2 optimize status OK test.t3 optimize status OK -test.v1 optimize error 'test.v1' is not BASE TABLE +test.v1 optimize Error 'test.v1' is not BASE TABLE +test.v1 optimize error Corrupt Table Op Msg_type Msg_text test.t1 analyze status Table is already up to date test.t2 analyze status Table is already up to date test.t3 analyze status Table is already up to date -test.v1 analyze error 'test.v1' is not BASE TABLE -Warnings: -Error 1347 'test.v1' is not BASE TABLE +test.v1 analyze Error 'test.v1' is not BASE TABLE +test.v1 analyze error Corrupt drop procedure bug13012| drop view v1; select * from t1| diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 8d9d802949d..f1aa4e64179 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1377,7 +1377,9 @@ test.t1 check status OK drop table t1; check table v1; Table Op Msg_type Msg_text -test.v1 check error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v1 check Error Table 'test.t1' doesn't exist +test.v1 check Error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v1 check error Corrupt drop view v1; create table t1 (a int); create table t2 (a int); @@ -1901,11 +1903,17 @@ CREATE VIEW v6 AS SELECT CONVERT_TZ(col1,'GMT','MET') FROM t2; DROP TABLE t1; CHECK TABLE v1, v2, v3, v4, v5, v6; Table Op Msg_type Msg_text -test.v1 check error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v1 check Error Table 'test.t1' doesn't exist +test.v1 check Error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v1 check error Corrupt test.v2 check status OK -test.v3 check error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v3 check Error Table 'test.t1' doesn't exist +test.v3 check Error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v3 check error Corrupt test.v4 check status OK -test.v5 check error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v5 check Error Table 'test.t1' doesn't exist +test.v5 check Error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v5 check error Corrupt test.v6 check status OK drop view v1, v2, v3, v4, v5, v6; drop table t2; @@ -1925,11 +1933,17 @@ CREATE VIEW v6 AS SELECT f2() FROM t3; drop function f1; CHECK TABLE v1, v2, v3, v4, v5, v6; Table Op Msg_type Msg_text -test.v1 check error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v1 check Error FUNCTION test.f1 does not exist +test.v1 check Error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v1 check error Corrupt test.v2 check status OK -test.v3 check error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v3 check Error FUNCTION test.f1 does not exist +test.v3 check Error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v3 check error Corrupt test.v4 check status OK -test.v5 check error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v5 check Error FUNCTION test.f1 does not exist +test.v5 check Error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +test.v5 check error Corrupt test.v6 check status OK create function f1 () returns int return (select max(col1) from t1); DROP TABLE t1; @@ -2376,35 +2390,29 @@ CREATE TABLE t1(id INT); CREATE VIEW v1 AS SELECT id FROM t1; OPTIMIZE TABLE v1; Table Op Msg_type Msg_text -test.v1 optimize error 'test.v1' is not BASE TABLE -Warnings: -Error 1347 'test.v1' is not BASE TABLE +test.v1 optimize Error 'test.v1' is not BASE TABLE +test.v1 optimize error Corrupt ANALYZE TABLE v1; Table Op Msg_type Msg_text -test.v1 analyze error 'test.v1' is not BASE TABLE -Warnings: -Error 1347 'test.v1' is not BASE TABLE +test.v1 analyze Error 'test.v1' is not BASE TABLE +test.v1 analyze error Corrupt REPAIR TABLE v1; Table Op Msg_type Msg_text -test.v1 repair error 'test.v1' is not BASE TABLE -Warnings: -Error 1347 'test.v1' is not BASE TABLE +test.v1 repair Error 'test.v1' is not BASE TABLE +test.v1 repair error Corrupt DROP TABLE t1; OPTIMIZE TABLE v1; Table Op Msg_type Msg_text -test.v1 optimize error 'test.v1' is not BASE TABLE -Warnings: -Error 1347 'test.v1' is not BASE TABLE +test.v1 optimize Error 'test.v1' is not BASE TABLE +test.v1 optimize error Corrupt ANALYZE TABLE v1; Table Op Msg_type Msg_text -test.v1 analyze error 'test.v1' is not BASE TABLE -Warnings: -Error 1347 'test.v1' is not BASE TABLE +test.v1 analyze Error 'test.v1' is not BASE TABLE +test.v1 analyze error Corrupt REPAIR TABLE v1; Table Op Msg_type Msg_text -test.v1 repair error 'test.v1' is not BASE TABLE -Warnings: -Error 1347 'test.v1' is not BASE TABLE +test.v1 repair Error 'test.v1' is not BASE TABLE +test.v1 repair error Corrupt DROP VIEW v1; create definer = current_user() sql security invoker view v1 as select 1; show create view v1; diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index b3944416adc..c3e5cef5e63 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -486,4 +486,25 @@ insert into t1 values (1); drop table t2; drop table t1; +# +# BUG#26976 - Missing table in merge not noted in related error msg + SHOW +# CREATE TABLE fails +# +CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1, t2); +--error 1168 +SELECT * FROM tm1; +CHECK TABLE tm1; +CREATE TABLE t1(a INT); +--error 1168 +SELECT * FROM tm1; +CHECK TABLE tm1; +CREATE TABLE t2(a BLOB); +--error 1168 +SELECT * FROM tm1; +CHECK TABLE tm1; +ALTER TABLE t2 MODIFY a INT; +SELECT * FROM tm1; +CHECK TABLE tm1; +DROP TABLE tm1, t1, t2; + --echo End of 5.0 tests diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 9a397ffbbac..5e953092436 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -109,6 +109,14 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, } length=(uint) (strxmov(name, param->db_name,".",param->table_name,NullS) - name); + /* + TODO: switch from protocol to push_warning here. The main reason we didn't + it yet is parallel repair. Due to following trace: + mi_check_print_msg/push_warning/sql_alloc/my_pthread_getspecific_ptr. + + Also we likely need to lock mutex here (in both cases with protocol and + push_warning). + */ protocol->prepare_for_resend(); protocol->store(name, length, system_charset_info); protocol->store(param->op_name, system_charset_info); @@ -1138,11 +1146,7 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt) /* We only come here when the user did specify an index map */ key_map kmap; if (get_key_map_from_key_list(&kmap, table, table_list->use_index)) - { - errmsg= thd->net.last_error; - error= HA_ADMIN_FAILED; - goto err; - } + DBUG_RETURN(HA_ADMIN_FAILED); map= kmap.to_ulonglong(); } @@ -1155,7 +1159,6 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt) error= HA_ADMIN_CORRUPT; } - err: if (error != HA_ADMIN_OK) { /* Send error to user */ @@ -1192,11 +1195,7 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt) key_map kmap; get_key_map_from_key_list(&kmap, table, table_list->use_index); if (kmap.is_set_all()) - { - errmsg= thd->net.last_error; - error= HA_ADMIN_FAILED; - goto err; - } + DBUG_RETURN(HA_ADMIN_FAILED); if (!kmap.is_clear_all()) map= kmap.to_ulonglong(); } diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 1202a733a16..e7baa6705ee 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -72,6 +72,13 @@ extern int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo, uint t1_keys, uint t1_recs, MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo, uint t2_keys, uint t2_recs, bool strict); +extern "C" void myrg_print_wrong_table(const char *table_name) +{ + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_ADMIN_WRONG_MRG_TABLE, ER(ER_ADMIN_WRONG_MRG_TABLE), + table_name); +} + const char **ha_myisammrg::bas_ext() const { @@ -121,6 +128,8 @@ int ha_myisammrg::open(const char *name, int mode, uint test_if_locked) { DBUG_PRINT("error",("reclength: %lu mean_rec_length: %lu", table->s->reclength, mean_rec_length)); + if (test_if_locked & HA_OPEN_FOR_REPAIR) + myrg_print_wrong_table(file->open_tables->table->filename); error= HA_ERR_WRONG_MRG_TABLE_DEF; goto err; } @@ -139,12 +148,19 @@ int ha_myisammrg::open(const char *name, int mode, uint test_if_locked) u_table->table->s->base.keys, u_table->table->s->base.fields, false)) { - my_free((gptr) recinfo, MYF(0)); error= HA_ERR_WRONG_MRG_TABLE_DEF; - goto err; + if (test_if_locked & HA_OPEN_FOR_REPAIR) + myrg_print_wrong_table(u_table->table->filename); + else + { + my_free((gptr) recinfo, MYF(0)); + goto err; + } } } my_free((gptr) recinfo, MYF(0)); + if (error == HA_ERR_WRONG_MRG_TABLE_DEF) + goto err; #if !defined(BIG_TABLES) || SIZEOF_OFF_T == 4 /* Merge table has more than 2G rows */ if (table->s->crashed) @@ -597,3 +613,9 @@ void ha_myisammrg::append_create_info(String *packet) } packet->append(')'); } + + +int ha_myisammrg::check(THD* thd, HA_CHECK_OPT* check_opt) +{ + return HA_ADMIN_OK; +} diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h index 16c734e2682..2ba5b6b551e 100644 --- a/sql/ha_myisammrg.h +++ b/sql/ha_myisammrg.h @@ -81,4 +81,5 @@ class ha_myisammrg: public handler void update_create_info(HA_CREATE_INFO *create_info); void append_create_info(String *packet); MYRG_INFO *myrg_info() { return file; } + int check(THD* thd, HA_CHECK_OPT* check_opt); }; diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 1230287656e..a52ffa8216c 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5633,4 +5633,5 @@ ER_WRONG_STRING_LENGTH eng "String '%-.70s' is too long for %s (should be no longer than %d)" ER_NON_INSERTABLE_TABLE eng "The target table %-.100s of the %s is not insertable-into" - +ER_ADMIN_WRONG_MRG_TABLE + eng "Table '%-.64s' is differently defined or of non-MyISAM type or doesn't exist" diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 61a7581908c..a25c82c7721 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -205,8 +205,8 @@ void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level, TRUE Error sending data to client */ -static const char *warning_level_names[]= {"Note", "Warning", "Error", "?"}; -static int warning_level_length[]= { 4, 7, 5, 1 }; +const char *warning_level_names[]= {"Note", "Warning", "Error", "?"}; +int warning_level_length[]= { 4, 7, 5, 1 }; bool mysqld_show_warnings(THD *thd, ulong levels_to_show) { diff --git a/sql/sql_error.h b/sql/sql_error.h index 28d946f14f8..4dbf3ada8f0 100644 --- a/sql/sql_error.h +++ b/sql/sql_error.h @@ -39,3 +39,5 @@ void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code, const char *format, ...); void mysql_reset_errors(THD *thd, bool force); bool mysqld_show_warnings(THD *thd, ulong levels_to_show); +extern const char *warning_level_names[]; +extern int warning_level_length[]; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 079cc0d6456..2456c3818a2 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2283,33 +2283,16 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, */ if (!table->table) { - char buf[ERRMSGSIZE+ERRMSGSIZE+2]; - const char *err_msg; - protocol->prepare_for_resend(); - protocol->store(table_name, system_charset_info); - protocol->store(operator_name, system_charset_info); - protocol->store(STRING_WITH_LEN("error"), system_charset_info); - if (!(err_msg=thd->net.last_error)) - err_msg=ER(ER_CHECK_NO_SUCH_TABLE); + if (!thd->warn_list.elements) + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE)); /* if it was a view will check md5 sum */ if (table->view && view_checksum(thd, table) == HA_ADMIN_WRONG_CHECKSUM) - { - strxmov(buf, err_msg, "; ", ER(ER_VIEW_CHECKSUM), NullS); - err_msg= (const char *)buf; - } - protocol->store(err_msg, system_charset_info); - lex->cleanup_after_one_table_open(); - thd->clear_error(); - /* - View opening can be interrupted in the middle of process so some - tables can be left opening - */ - close_thread_tables(thd); - lex->reset_query_tables_list(FALSE); - if (protocol->write()) - goto err; - continue; + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_VIEW_CHECKSUM, ER(ER_VIEW_CHECKSUM)); + result_code= HA_ADMIN_CORRUPT; + goto send_result; } if (table->view) @@ -2391,6 +2374,22 @@ send_result: lex->cleanup_after_one_table_open(); thd->clear_error(); // these errors shouldn't get client + { + List_iterator_fast it(thd->warn_list); + MYSQL_ERROR *err; + while ((err= it++)) + { + protocol->prepare_for_resend(); + protocol->store(table_name, system_charset_info); + protocol->store((char*) operator_name, system_charset_info); + protocol->store(warning_level_names[err->level], + warning_level_length[err->level], system_charset_info); + protocol->store(err->msg, system_charset_info); + if (protocol->write()) + goto err; + } + mysql_reset_errors(thd, true); + } protocol->prepare_for_resend(); protocol->store(table_name, system_charset_info); protocol->store(operator_name, system_charset_info); @@ -2924,7 +2923,7 @@ bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt) DBUG_ENTER("mysql_check_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, "check", lock_type, - 0, HA_OPEN_FOR_REPAIR, 0, 0, + 0, 0, HA_OPEN_FOR_REPAIR, 0, &handler::ha_check, &view_checksum)); } From a1529d92d1a4f71a6f04eae958c3b0be2869b8ba Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/june.mysql.com" <> Date: Fri, 8 Jun 2007 11:20:50 +0500 Subject: [PATCH 10/12] BUG#26976 - Missing table in merge not noted in related error msg + SHOW CREATE TABLE fails After merge fixes. --- mysql-test/r/backup.result | 40 +++++++++++------------------- mysql-test/r/sp.result | 41 +++++++++++++++---------------- sql/sql_table.cc | 8 +++++- sql/sql_yacc.yy | 4 --- storage/myisam/ha_myisam.cc | 13 ++-------- storage/myisammrg/ha_myisammrg.cc | 1 - 6 files changed, 43 insertions(+), 64 deletions(-) diff --git a/mysql-test/r/backup.result b/mysql-test/r/backup.result index be1a3efc5c6..154b577e61f 100644 --- a/mysql-test/r/backup.result +++ b/mysql-test/r/backup.result @@ -4,28 +4,24 @@ create table t4(n int); backup table t4 to '../bogus'; Table Op Msg_type Msg_text test.t4 backup error Failed copying .frm file (errno: X) +test.t4 backup Warning The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead +test.t4 backup Error Can't create/write to file 'MYSQLTEST_VARDIR/bogus/t4.frm' (Errcode: X) test.t4 backup status Operation failed -Warnings: -Warning 1543 The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead -Error 1 Can't create/write to file 'MYSQLTEST_VARDIR/bogus/t4.frm' (Errcode: X) backup table t4 to '../tmp'; Table Op Msg_type Msg_text +test.t4 backup Warning The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead test.t4 backup status OK -Warnings: -Warning 1543 The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead backup table t4 to '../tmp'; Table Op Msg_type Msg_text test.t4 backup error Failed copying .frm file (errno: X) +test.t4 backup Warning The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead +test.t4 backup Error Can't create/write to file 'MYSQLTEST_VARDIR/tmp/t4.frm' (Errcode: X) test.t4 backup status Operation failed -Warnings: -Warning 1543 The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead -Error 1 Can't create/write to file 'MYSQLTEST_VARDIR/tmp/t4.frm' (Errcode: X) drop table t4; restore table t4 from '../tmp'; Table Op Msg_type Msg_text +test.t4 restore Warning The syntax 'RESTORE TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead test.t4 restore status OK -Warnings: -Warning 1543 The syntax 'RESTORE TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead select count(*) from t4; count(*) 0 @@ -33,9 +29,8 @@ create table t1(n int); insert into t1 values (23),(45),(67); backup table t1 to '../tmp'; Table Op Msg_type Msg_text +test.t1 backup Warning The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead test.t1 backup status OK -Warnings: -Warning 1543 The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead drop table t1; restore table t1 from '../bogus'; Table Op Msg_type Msg_text @@ -45,9 +40,8 @@ Warning 1543 The syntax 'RESTORE TABLE' is deprecated and will be removed in MyS Error 29 File 'MYSQLTEST_VARDIR/bogus/t1.frm' not found (Errcode: X) restore table t1 from '../tmp'; Table Op Msg_type Msg_text +test.t1 restore Warning The syntax 'RESTORE TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead test.t1 restore status OK -Warnings: -Warning 1543 The syntax 'RESTORE TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead select n from t1; n 23 @@ -59,18 +53,16 @@ insert into t2 values (123),(145),(167); insert into t3 values (223),(245),(267); backup table t2,t3 to '../tmp'; Table Op Msg_type Msg_text +test.t2 backup Warning The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead test.t2 backup status OK test.t3 backup status OK -Warnings: -Warning 1543 The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead drop table t1,t2,t3; restore table t1,t2,t3 from '../tmp'; Table Op Msg_type Msg_text +test.t1 restore Warning The syntax 'RESTORE TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead test.t1 restore status OK test.t2 restore status OK test.t3 restore status OK -Warnings: -Warning 1543 The syntax 'RESTORE TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead select n from t1; n 23 @@ -89,32 +81,28 @@ k drop table t1,t2,t3,t4; restore table t1 from '../tmp'; Table Op Msg_type Msg_text +test.t1 restore Warning The syntax 'RESTORE TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead test.t1 restore status OK -Warnings: -Warning 1543 The syntax 'RESTORE TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead rename table t1 to t5; lock tables t5 write; backup table t5 to '../tmp'; unlock tables; Table Op Msg_type Msg_text +test.t5 backup Warning The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead test.t5 backup status OK -Warnings: -Warning 1543 The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead drop table t5; DROP TABLE IF EXISTS `t+1`; CREATE TABLE `t+1` (c1 INT); INSERT INTO `t+1` VALUES (1), (2), (3); BACKUP TABLE `t+1` TO '../tmp'; Table Op Msg_type Msg_text +test.t+1 backup Warning The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead test.t+1 backup status OK -Warnings: -Warning 1543 The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead DROP TABLE `t+1`; RESTORE TABLE `t+1` FROM '../tmp'; Table Op Msg_type Msg_text +test.t+1 restore Warning The syntax 'RESTORE TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead test.t+1 restore status OK -Warnings: -Warning 1543 The syntax 'RESTORE TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead SELECT * FROM `t+1`; c1 1 diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 86ede7a8f00..7c64715fc80 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -4404,8 +4404,10 @@ call bug13012()| Table Op Msg_type Msg_text test.t1 repair status OK Table Op Msg_type Msg_text +test.t1 backup Warning The syntax 'BACKUP TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead test.t1 backup status OK Table Op Msg_type Msg_text +test.t1 restore Warning The syntax 'RESTORE TABLE' is deprecated and will be removed in MySQL 5.2. Please use MySQL Administrator (mysqldump, mysql) instead test.t1 restore status OK drop procedure bug13012| create view v1 as select * from t1| @@ -4420,61 +4422,58 @@ Table Op Msg_type Msg_text test.t1 repair status OK test.t2 repair status OK test.t3 repair status OK -test.v1 repair error 'test.v1' is not BASE TABLE +test.v1 repair Error 'test.v1' is not BASE TABLE +test.v1 repair error Corrupt Table Op Msg_type Msg_text test.t1 optimize status OK test.t2 optimize status OK test.t3 optimize status OK -test.v1 optimize error 'test.v1' is not BASE TABLE +test.v1 optimize Error 'test.v1' is not BASE TABLE +test.v1 optimize error Corrupt Table Op Msg_type Msg_text test.t1 analyze status Table is already up to date test.t2 analyze status Table is already up to date test.t3 analyze status Table is already up to date -test.v1 analyze error 'test.v1' is not BASE TABLE -Warnings: -Error 1347 'test.v1' is not BASE TABLE -Error 1347 'test.v1' is not BASE TABLE -Error 1347 'test.v1' is not BASE TABLE +test.v1 analyze Error 'test.v1' is not BASE TABLE +test.v1 analyze error Corrupt call bug13012()| Table Op Msg_type Msg_text test.t1 repair status OK test.t2 repair status OK test.t3 repair status OK -test.v1 repair error 'test.v1' is not BASE TABLE +test.v1 repair Error 'test.v1' is not BASE TABLE +test.v1 repair error Corrupt Table Op Msg_type Msg_text test.t1 optimize status OK test.t2 optimize status OK test.t3 optimize status OK -test.v1 optimize error 'test.v1' is not BASE TABLE +test.v1 optimize Error 'test.v1' is not BASE TABLE +test.v1 optimize error Corrupt Table Op Msg_type Msg_text test.t1 analyze status Table is already up to date test.t2 analyze status Table is already up to date test.t3 analyze status Table is already up to date -test.v1 analyze error 'test.v1' is not BASE TABLE -Warnings: -Error 1347 'test.v1' is not BASE TABLE -Error 1347 'test.v1' is not BASE TABLE -Error 1347 'test.v1' is not BASE TABLE +test.v1 analyze Error 'test.v1' is not BASE TABLE +test.v1 analyze error Corrupt call bug13012()| Table Op Msg_type Msg_text test.t1 repair status OK test.t2 repair status OK test.t3 repair status OK -test.v1 repair error 'test.v1' is not BASE TABLE +test.v1 repair Error 'test.v1' is not BASE TABLE +test.v1 repair error Corrupt Table Op Msg_type Msg_text test.t1 optimize status OK test.t2 optimize status OK test.t3 optimize status OK -test.v1 optimize error 'test.v1' is not BASE TABLE +test.v1 optimize Error 'test.v1' is not BASE TABLE +test.v1 optimize error Corrupt Table Op Msg_type Msg_text test.t1 analyze status Table is already up to date test.t2 analyze status Table is already up to date test.t3 analyze status Table is already up to date -test.v1 analyze error 'test.v1' is not BASE TABLE -Warnings: -Error 1347 'test.v1' is not BASE TABLE -Error 1347 'test.v1' is not BASE TABLE -Error 1347 'test.v1' is not BASE TABLE +test.v1 analyze Error 'test.v1' is not BASE TABLE +test.v1 analyze error Corrupt drop procedure bug13012| drop view v1| select * from t1 order by data| diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ce292a9da60..7c13f9f2c54 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4175,7 +4175,9 @@ send_result: protocol->prepare_for_resend(); protocol->store(table_name, system_charset_info); protocol->store((char*) operator_name, system_charset_info); - protocol->store(warning_level_names[err->level], system_charset_info); + protocol->store(warning_level_names[err->level].str, + warning_level_names[err->level].length, + system_charset_info); protocol->store(err->msg, system_charset_info); if (protocol->write()) goto err; @@ -4387,6 +4389,8 @@ send_result_message: bool mysql_backup_table(THD* thd, TABLE_LIST* table_list) { DBUG_ENTER("mysql_backup_table"); + WARN_DEPRECATED(thd, "5.2", "BACKUP TABLE", + "MySQL Administrator (mysqldump, mysql)"); DBUG_RETURN(mysql_admin_table(thd, table_list, 0, "backup", TL_READ, 0, 0, 0, 0, &handler::backup, 0)); @@ -4396,6 +4400,8 @@ bool mysql_backup_table(THD* thd, TABLE_LIST* table_list) bool mysql_restore_table(THD* thd, TABLE_LIST* table_list) { DBUG_ENTER("mysql_restore_table"); + WARN_DEPRECATED(thd, "5.2", "RESTORE TABLE", + "MySQL Administrator (mysqldump, mysql)"); DBUG_RETURN(mysql_admin_table(thd, table_list, 0, "restore", TL_WRITE, 1, 1, 0, &prepare_for_restore, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1073c8141df..ec9fdc2c60a 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5751,8 +5751,6 @@ restore: RESTORE_SYM table_or_tables { Lex->sql_command = SQLCOM_RESTORE_TABLE; - WARN_DEPRECATED(yythd, "5.2", "RESTORE TABLE", - "MySQL Administrator (mysqldump, mysql)"); } table_list FROM TEXT_STRING_sys { @@ -5763,8 +5761,6 @@ backup: BACKUP_SYM table_or_tables { Lex->sql_command = SQLCOM_BACKUP_TABLE; - WARN_DEPRECATED(yythd, "5.2", "BACKUP TABLE", - "MySQL Administrator (mysqldump, mysql)"); } table_list TO_SYM TEXT_STRING_sys { diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 351ec87fb51..12c722e8f80 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1224,11 +1224,7 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt) table->keys_in_use_for_query.clear_all(); if (table_list->process_index_hints(table)) - { - errmsg= thd->net.last_error; - error= HA_ADMIN_FAILED; - goto err; - } + DBUG_RETURN(HA_ADMIN_FAILED); map= ~(ulonglong) 0; if (!table->keys_in_use_for_query.is_clear_all()) /* use all keys if there's no list specified by the user through hints */ @@ -1243,7 +1239,6 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt) error= HA_ADMIN_CORRUPT; } - err: if (error != HA_ADMIN_OK) { /* Send error to user */ @@ -1278,11 +1273,7 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt) table->keys_in_use_for_query.clear_all(); if (table_list->process_index_hints(table)) - { - errmsg= thd->net.last_error; - error= HA_ADMIN_FAILED; - goto err; - } + DBUG_RETURN(HA_ADMIN_FAILED); map= ~(ulonglong) 0; /* Check validity of the index references */ diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index c7907c53582..04a9938f315 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -129,7 +129,6 @@ int ha_myisammrg::open(const char *name, int mode, uint test_if_locked) u_table->table->s->base.keys, u_table->table->s->base.fields, false)) { - my_free((uchar*) recinfo, MYF(0)); error= HA_ERR_WRONG_MRG_TABLE_DEF; if (test_if_locked & HA_OPEN_FOR_REPAIR) myrg_print_wrong_table(u_table->table->filename); From 01c9419cec2bd91fe1b7b970614949e6111b131f Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/june.mysql.com" <> Date: Thu, 14 Jun 2007 16:18:01 +0500 Subject: [PATCH 11/12] BUG#26976 - Missing table in merge not noted in related error msg + SHOW CREATE TABLE fails Addition to the fix: report db name + table name instead of table path. This solves embedded merge test failure. --- mysql-test/r/merge.result | 8 ++++---- sql/ha_myisammrg.cc | 13 ++++++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 9f7d5f54d0e..42669eeb66f 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -849,8 +849,8 @@ SELECT * FROM tm1; ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist CHECK TABLE tm1; Table Op Msg_type Msg_text -test.tm1 check Error Table './test/t1' is differently defined or of non-MyISAM type or doesn't exist -test.tm1 check Error Table './test/t2' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Table 'test.t1' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist test.tm1 check error Corrupt CREATE TABLE t1(a INT); @@ -858,7 +858,7 @@ SELECT * FROM tm1; ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist CHECK TABLE tm1; Table Op Msg_type Msg_text -test.tm1 check Error Table './test/t2' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist test.tm1 check error Corrupt CREATE TABLE t2(a BLOB); @@ -866,7 +866,7 @@ SELECT * FROM tm1; ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist CHECK TABLE tm1; Table Op Msg_type Msg_text -test.tm1 check Error Table './test/t2' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist test.tm1 check error Corrupt ALTER TABLE t2 MODIFY a INT; diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index e7baa6705ee..60aa4bd6adc 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -72,11 +72,22 @@ extern int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo, uint t1_keys, uint t1_recs, MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo, uint t2_keys, uint t2_recs, bool strict); +static void split_file_name(const char *file_name, + LEX_STRING *db, LEX_STRING *name); + + extern "C" void myrg_print_wrong_table(const char *table_name) { + LEX_STRING db, name; + char buf[FN_REFLEN]; + split_file_name(table_name, &db, &name); + memcpy(buf, db.str, db.length); + buf[db.length]= '.'; + memcpy(buf + db.length + 1, name.str, name.length); + buf[db.length + name.length + 1]= 0; push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, ER_ADMIN_WRONG_MRG_TABLE, ER(ER_ADMIN_WRONG_MRG_TABLE), - table_name); + buf); } From 6d2ffe7b8e1eff9ca7ade9bdb26da1a5e7947537 Mon Sep 17 00:00:00 2001 From: "bar@mysql.com/bar.myoffice.izhnet.ru" <> Date: Thu, 14 Jun 2007 16:28:33 +0500 Subject: [PATCH 12/12] Bug#26402 Server crashes with old-style named table Problem: crash on attempt to open a table having "#mysql50#" prefix in db or table name. Fix: This prefix is reserved for "mysql_upgrade" to access 5.0 tables whose file names are not encoded according to "5.1 tablename to filename encoded". Don't try open tables whose db name or table name has this prefix. --- mysql-test/r/show_check.result | 2 ++ mysql-test/t/show_check.test | 6 ++++++ sql/mysql_priv.h | 4 ++++ sql/sql_table.cc | 4 ---- sql/table.cc | 19 +++++++++++++++++-- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index acab2f17910..dbb1f063513 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -752,4 +752,6 @@ Tables_in_test Table_type été BASE TABLE drop table `été`; set names latin1; +show columns from `#mysql50#????????`; +ERROR 42S02: Table 'test.#mysql50#????????' doesn't exist End of 5.1 tests diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 60e680c63f3..3aeb92ac203 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -593,4 +593,10 @@ show full tables; drop table `été`; set names latin1; +# +# Bug#26402 Server crashes with old-style named table +# +--error ER_NO_SUCH_TABLE +show columns from `#mysql50#????????`; + --echo End of 5.1 tests diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 7fb4d95f1f6..921a940834f 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1920,6 +1920,10 @@ uint filename_to_tablename(const char *from, char *to, uint to_length); uint tablename_to_filename(const char *from, char *to, uint to_length); uint build_table_filename(char *buff, size_t bufflen, const char *db, const char *table, const char *ext, uint flags); + +#define MYSQL50_TABLE_NAME_PREFIX "#mysql50#" +#define MYSQL50_TABLE_NAME_PREFIX_LENGTH 9 + /* Flags for conversion functions. */ #define FN_FROM_IS_TMP (1 << 0) #define FN_TO_IS_TMP (1 << 1) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7c13f9f2c54..4378d69dd9f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -54,10 +54,6 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, HA_CREATE_INFO *create_info, Alter_info *alter_info); -#define MYSQL50_TABLE_NAME_PREFIX "#mysql50#" -#define MYSQL50_TABLE_NAME_PREFIX_LENGTH 9 - - /* Translate a file name to a table name (WL #1324). diff --git a/sql/table.cc b/sql/table.cc index 745f3a2a34e..7076dc2d8f8 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -343,10 +343,25 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) strxmov(path, share->normalized_path.str, reg_ext, NullS); if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0) { - if (strchr(share->table_name.str, '@')) + /* + We don't try to open 5.0 unencoded name, if + - non-encoded name contains '@' signs, + because '@' can be misinterpreted. + It is not clear if '@' is escape character in 5.1, + or a normal character in 5.0. + + - non-encoded db or table name contain "#mysql50#" prefix. + This kind of tables must have been opened only by the + my_open() above. + */ + if (strchr(share->table_name.str, '@') || + !strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX, + MYSQL50_TABLE_NAME_PREFIX_LENGTH) || + !strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX, + MYSQL50_TABLE_NAME_PREFIX_LENGTH)) goto err_not_open; - /* Try unecoded 5.0 name */ + /* Try unencoded 5.0 name */ uint length; strxnmov(path, sizeof(path)-1, mysql_data_home, "/", share->db.str, "/",