diff --git a/include/keycache.h b/include/keycache.h index 9ebb7d5b992..7f4ce86cea0 100644 --- a/include/keycache.h +++ b/include/keycache.h @@ -47,7 +47,6 @@ typedef struct st_key_cache my_bool in_resize; /* true during resize operation */ 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 4c98882ac7e..44e03fdee63 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -234,7 +234,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)) @@ -399,7 +399,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)); @@ -422,7 +421,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= @@ -2558,7 +2557,7 @@ uchar *key_cache_read(KEY_CACHE *keycache, inc_counter_for_resize_op(keycache); locked_and_incremented= TRUE; /* Requested data may not always be aligned to cache blocks. */ - 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 { @@ -2756,7 +2755,7 @@ int key_cache_insert(KEY_CACHE *keycache, inc_counter_for_resize_op(keycache); locked_and_incremented= TRUE; /* Loaded data may not always be aligned to cache blocks. */ - offset= (uint) (filepos & (keycache->key_cache_block_size-1)); + offset= (uint) (filepos % keycache->key_cache_block_size); /* Load data in key_cache_block_size increments. */ do { @@ -3030,7 +3029,7 @@ int key_cache_write(KEY_CACHE *keycache, inc_counter_for_resize_op(keycache); locked_and_incremented= TRUE; /* Requested data may not always be aligned to cache blocks. */ - offset= (uint) (filepos & (keycache->key_cache_block_size-1)); + offset= (uint) (filepos % keycache->key_cache_block_size); /* Write data in key_cache_block_size increments. */ do { diff --git a/mysys/my_seek.c b/mysys/my_seek.c index 0d30ba203ae..2c661baeff7 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 diff --git a/sql/lock.cc b/sql/lock.cc index 6f1dd0669ee..08c109a17ab 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -197,6 +197,13 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, } else if (rc == 1) /* aborted */ { + /* + 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 already freed } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1fa08a1d862..29e2a01693a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5931,7 +5931,7 @@ log and this option does nothing anymore.", (uchar**) &dflt_key_cache_var.param_block_size, (uchar**) 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", (uchar**) &dflt_key_cache_var.param_division_limit, diff --git a/sql/set_var.cc b/sql/set_var.cc index 46dfbc7c7f9..6064bf605c0 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1500,6 +1500,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; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 37301751d03..c0161463550 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, (uchar*)plugin_dl)) + if (insert_dynamic(&plugin_dl_array, (uchar*)&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, (uchar*)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, (uchar*)plugin)) + if (insert_dynamic(&plugin_array, (uchar*)&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, (uchar*)plugin, + sizeof(struct st_plugin_int)); + DBUG_RETURN(tmp); } @@ -873,7 +879,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 */ @@ -1096,9 +1102,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)) @@ -1233,11 +1239,13 @@ static bool register_builtin(struct st_mysql_plugin *plugin, tmp->ref_count= 0; tmp->plugin_dl= 0; - if (insert_dynamic(&plugin_array, (uchar*)tmp)) + if (insert_dynamic(&plugin_array, (uchar*)&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, (uchar*)tmp, + sizeof(struct st_plugin_int)); if (my_hash_insert(&plugin_hash[plugin->type],(uchar*) *ptr)) DBUG_RETURN(1); @@ -1459,7 +1467,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; @@ -1491,7 +1499,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; @@ -1556,7 +1564,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); @@ -1715,7 +1723,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; } } @@ -3140,7 +3148,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))) diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c index bf4c29f5b4e..f38561a76dd 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, uchar *query, uint len, - struct st_mysql_ftparser *parser) +static int _ftb_parse_query(FTB *ftb, uchar *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, uchar *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, uchar *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, uchar *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() @@ -622,7 +622,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; } @@ -640,6 +640,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 uchar *document, uint len, @@ -668,12 +669,13 @@ static int _ftb_check_phrase(FTB *ftb, const uchar *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; @@ -705,17 +707,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 @@ -747,6 +751,7 @@ static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_ weight*= ftbe->weight; } } + return 0; } @@ -779,7 +784,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); @@ -855,7 +864,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); } @@ -927,7 +937,8 @@ float ft_boolean_find_relevance(FT_INFO *ftb, uchar *record, uint length) continue; param->doc= (uchar *)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 bcf6c46d41f..4774b819aa2 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, uchar *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);