From 52989c445f51f981e8d28842a022e82ac5faab8b Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Fri, 21 Nov 2008 17:38:42 +0400 Subject: [PATCH 001/110] Bug#25058 ignored return codes in memory allocation functions memory allocation error checks added for functions calling insert_dynamic() per-file messages: myisam/mi_delete.c Bug#25058 ignored return codes in memory allocation functions out-of-memory errors handled myisam/mi_write.c Bug#25058 ignored return codes in memory allocation functions out-of-memory errors handled server-tools/instance-manager/instance_options.cc Bug#25058 ignored return codes in memory allocation functions out-of-memory errors handled sql/slave.cc Bug#25058 ignored return codes in memory allocation functions out-of-memory errors handled sql/sp_head.cc Bug#25058 ignored return codes in memory allocation functions out-of-memory errors handled sql/sp_head.h Bug#25058 ignored return codes in memory allocation functions out-of-memory errors handled sql/sp_pcontext.cc Bug#25058 ignored return codes in memory allocation functions out-of-memory errors handled sql/sp_pcontext.h Bug#25058 ignored return codes in memory allocation functions out-of-memory errors handled sql/sql_select.cc Bug#25058 ignored return codes in memory allocation functions out-of-memory errors handled sql/sql_yacc.yy Bug#25058 ignored return codes in memory allocation functions out-of-memory errors handled --- myisam/mi_delete.c | 6 +- myisam/mi_write.c | 9 +- .../instance-manager/instance_options.cc | 3 +- sql/slave.cc | 3 +- sql/sp_head.cc | 27 +-- sql/sp_head.h | 8 +- sql/sp_pcontext.cc | 22 +-- sql/sp_pcontext.h | 4 +- sql/sql_select.cc | 46 +++-- sql/sql_yacc.yy | 172 +++++++++--------- 10 files changed, 167 insertions(+), 133 deletions(-) diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c index ca8a537b322..e08e5097e33 100644 --- a/myisam/mi_delete.c +++ b/myisam/mi_delete.c @@ -250,7 +250,11 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, if (info->ft1_to_ft2) { /* we're in ft1->ft2 conversion mode. Saving key data */ - insert_dynamic(info->ft1_to_ft2, (char*) (lastkey+off)); + if (insert_dynamic(info->ft1_to_ft2, (char*) (lastkey+off))) + { + DBUG_PRINT("error",("Out of memory")); + DBUG_RETURN(-1); + } } else { diff --git a/myisam/mi_write.c b/myisam/mi_write.c index 4f11fc78ccf..b4843a748dd 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -550,7 +550,14 @@ int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo, we cannot easily dispatch an empty page here */ b+=blen+ft2len+2; for (a=anc_buff+a_length ; b < a ; b+=ft2len+2) - insert_dynamic(info->ft1_to_ft2, (char*) b); + { + if (insert_dynamic(info->ft1_to_ft2, (char*) b)) + { + mi_print_error(info->s, HA_ERR_OUT_OF_MEM); + my_errno= HA_ERR_OUT_OF_MEM; + DBUG_RETURN(-1); + } + } /* fixing the page's length - it contains only one key now */ mi_putint(anc_buff,2+blen+ft2len+2,0); diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc index d4ca2ad570f..c01b09de2b2 100644 --- a/server-tools/instance-manager/instance_options.cc +++ b/server-tools/instance-manager/instance_options.cc @@ -522,8 +522,7 @@ int Instance_options::add_option(const char* option) switch (selected_options->type) { case SAVE_WHOLE_AND_ADD: *(selected_options->value)= tmp; - insert_dynamic(&options_array,(gptr) &tmp); - return 0; + return insert_dynamic(&options_array,(gptr) &tmp); case SAVE_VALUE: *(selected_options->value)= strchr(tmp, '=') + 1; return 0; diff --git a/sql/slave.cc b/sql/slave.cc index b4e74f8e68d..c15c395cdb8 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1053,8 +1053,7 @@ int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec) e->tbl_name = e->db + (dot - table_spec) + 1; e->key_len = len; memcpy(e->db, table_spec, len); - insert_dynamic(a, (gptr)&e); - return 0; + return insert_dynamic(a, (gptr)&e); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 3ec6dd5cf06..57502f240d9 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1924,17 +1924,16 @@ sp_head::restore_lex(THD *thd) DBUG_VOID_RETURN; } -void +int sp_head::push_backpatch(sp_instr *i, sp_label_t *lab) { bp_t *bp= (bp_t *)sql_alloc(sizeof(bp_t)); - if (bp) - { - bp->lab= lab; - bp->instr= i; - (void)m_backpatch.push_front(bp); - } + if (!bp) + return 1; + bp->lab= lab; + bp->instr= i; + return m_backpatch.push_front(bp); } void @@ -2009,7 +2008,7 @@ sp_head::fill_field_definition(THD *thd, LEX *lex, } -void +int sp_head::new_cont_backpatch(sp_instr_opt_meta *i) { m_cont_level+= 1; @@ -2017,15 +2016,17 @@ sp_head::new_cont_backpatch(sp_instr_opt_meta *i) { /* Use the cont. destination slot to store the level */ i->m_cont_dest= m_cont_level; - (void)m_cont_backpatch.push_front(i); + if (m_cont_backpatch.push_front(i)) + return 1; } + return 0; } -void +int sp_head::add_cont_backpatch(sp_instr_opt_meta *i) { i->m_cont_dest= m_cont_level; - (void)m_cont_backpatch.push_front(i); + return m_cont_backpatch.push_front(i); } void @@ -2207,7 +2208,7 @@ sp_head::show_create_procedure(THD *thd) instr Instruction */ -void sp_head::add_instr(sp_instr *instr) +int sp_head::add_instr(sp_instr *instr) { instr->free_list= m_thd->free_list; m_thd->free_list= 0; @@ -2218,7 +2219,7 @@ void sp_head::add_instr(sp_instr *instr) entire stored procedure, as their life span is equal. */ instr->mem_root= &main_mem_root; - insert_dynamic(&m_instr, (gptr)&instr); + return insert_dynamic(&m_instr, (gptr)&instr); } diff --git a/sql/sp_head.h b/sql/sp_head.h index 91f465a4e2a..c54dc7401c4 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -226,7 +226,7 @@ public: int show_create_function(THD *thd); - void + int add_instr(sp_instr *instr); inline uint @@ -254,7 +254,7 @@ public: restore_lex(THD *thd); // Put the instruction on the backpatch list, associated with the label. - void + int push_backpatch(sp_instr *, struct sp_label *); // Update all instruction with this label in the backpatch list to @@ -263,11 +263,11 @@ public: backpatch(struct sp_label *); // Start a new cont. backpatch level. If 'i' is NULL, the level is just incr. - void + int new_cont_backpatch(sp_instr_opt_meta *i); // Add an instruction to the current level - void + int add_cont_backpatch(sp_instr_opt_meta *i); // Backpatch (and pop) the current level to the current position. diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 780243cc79f..265964d3d45 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -263,7 +263,8 @@ sp_pcontext::push_variable(LEX_STRING *name, enum enum_field_types type, p->mode= mode; p->offset= current_var_count(); p->dflt= NULL; - insert_dynamic(&m_vars, (gptr)&p); + if (insert_dynamic(&m_vars, (gptr)&p)) + return NULL; return p; } @@ -308,18 +309,17 @@ sp_pcontext::find_label(char *name) return NULL; } -void +int sp_pcontext::push_cond(LEX_STRING *name, sp_cond_type_t *val) { sp_cond_t *p= (sp_cond_t *)sql_alloc(sizeof(sp_cond_t)); - if (p) - { - p->name.str= name->str; - p->name.length= name->length; - p->val= val; - insert_dynamic(&m_conds, (gptr)&p); - } + if (p == NULL) + return 1; + p->name.str= name->str; + p->name.length= name->length; + p->val= val; + return insert_dynamic(&m_conds, (gptr)&p); } /* @@ -382,7 +382,7 @@ sp_pcontext::find_handler(sp_cond_type_t *cond) return FALSE; } -void +int sp_pcontext::push_cursor(LEX_STRING *name) { LEX_STRING n; @@ -391,7 +391,7 @@ sp_pcontext::push_cursor(LEX_STRING *name) m_max_cursor_index+= 1; n.str= name->str; n.length= name->length; - insert_dynamic(&m_cursors, (gptr)&n); + return insert_dynamic(&m_cursors, (gptr)&n); } /* diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 5bffda79f98..db8bed349f2 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -323,7 +323,7 @@ public: // Conditions // - void + int push_cond(LEX_STRING *name, sp_cond_type_t *val); inline void @@ -365,7 +365,7 @@ public: // Cursors // - void + int push_cursor(LEX_STRING *name); my_bool diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 428d1709f94..4883e9e4196 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3342,10 +3342,6 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, } } -/* - Add all keys with uses 'field' for some keypart - If field->and_level != and_level then only mark key_part as const_part -*/ static uint max_part_bit(key_part_map bits) @@ -3355,7 +3351,16 @@ max_part_bit(key_part_map bits) return found; } -static void +/* + Add all keys with uses 'field' for some keypart + If field->and_level != and_level then only mark key_part as const_part + + RETURN + 0 - OK + 1 - Out of memory. +*/ + +static bool add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field) { Field *field=key_field->field; @@ -3385,24 +3390,26 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field) keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL; keyuse.null_rejecting= key_field->null_rejecting; keyuse.cond_guard= key_field->cond_guard; - VOID(insert_dynamic(keyuse_array,(gptr) &keyuse)); + if (insert_dynamic(keyuse_array,(gptr) &keyuse)) + return TRUE; } } } } + return FALSE; } #define FT_KEYPART (MAX_REF_PARTS+10) -static void +static bool add_ft_keys(DYNAMIC_ARRAY *keyuse_array, JOIN_TAB *stat,COND *cond,table_map usable_tables) { Item_func_match *cond_func=NULL; if (!cond) - return; + return FALSE; if (cond->type() == Item::FUNC_ITEM) { @@ -3436,13 +3443,16 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, { Item *item; while ((item=li++)) - add_ft_keys(keyuse_array,stat,item,usable_tables); + { + if (add_ft_keys(keyuse_array,stat,item,usable_tables)) + return TRUE; + } } } if (!cond_func || cond_func->key == NO_SUCH_KEY || !(usable_tables & cond_func->table->map)) - return; + return FALSE; KEYUSE keyuse; keyuse.table= cond_func->table; @@ -3452,7 +3462,7 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, keyuse.used_tables=cond_func->key_item()->used_tables(); keyuse.optimize= 0; keyuse.keypart_map= 0; - VOID(insert_dynamic(keyuse_array,(gptr) &keyuse)); + return insert_dynamic(keyuse_array,(gptr) &keyuse); } @@ -3602,7 +3612,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, sargables); for (; field != end ; field++) { - add_key_part(keyuse,field); + if (add_key_part(keyuse,field)) + return TRUE; /* Mark that we can optimize LEFT JOIN */ if (field->val->type() == Item::NULL_ITEM && !field->field->real_maybe_null()) @@ -3640,11 +3651,15 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, /* fill keyuse with found key parts */ for ( ; field != end ; field++) - add_key_part(keyuse,field); + { + if (add_key_part(keyuse,field)) + return TRUE; + } if (select_lex->ftfunc_list->elements) { - add_ft_keys(keyuse,join_tab,cond,normal_tables); + if (add_ft_keys(keyuse,join_tab,cond,normal_tables)) + return TRUE; } /* @@ -3665,7 +3680,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, (qsort_cmp) sort_keyuse); bzero((char*) &key_end,sizeof(key_end)); /* Add for easy testing */ - VOID(insert_dynamic(keyuse,(gptr) &key_end)); + if (insert_dynamic(keyuse,(gptr) &key_end)) + return TRUE; use=save_pos=dynamic_element(keyuse,0,KEYUSE*); prev= &key_end; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0eefe782354..c149e12d567 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -234,9 +234,7 @@ int case_stmt_action_expr(LEX *lex, Item* expr) parsing_ctx, case_expr_id, expr, lex); sp->add_cont_backpatch(i); - sp->add_instr(i); - - return 0; + return sp->add_instr(i); } /** @@ -247,7 +245,7 @@ int case_stmt_action_expr(LEX *lex, Item* expr) @param simple true for simple cases, false for searched cases */ -void case_stmt_action_when(LEX *lex, Item *when, bool simple) +int case_stmt_action_when(LEX *lex, Item *when, bool simple) { sp_head *sp= lex->sphead; sp_pcontext *ctx= lex->spcont; @@ -279,9 +277,10 @@ void case_stmt_action_when(LEX *lex, Item *when, bool simple) (jump_if_not from instruction 2 to 5, 5 to 8 ... in the example) */ - sp->push_backpatch(i, ctx->push_label((char *)"", 0)); - sp->add_cont_backpatch(i); - sp->add_instr(i); + return !test(i) || + sp->push_backpatch(i, ctx->push_label((char *)"", 0)) || + sp->add_cont_backpatch(i) || + sp->add_instr(i); } /** @@ -290,13 +289,14 @@ void case_stmt_action_when(LEX *lex, Item *when, bool simple) @param lex the parser lex context */ -void case_stmt_action_then(LEX *lex) +int case_stmt_action_then(LEX *lex) { sp_head *sp= lex->sphead; sp_pcontext *ctx= lex->spcont; uint ip= sp->instructions(); sp_instr_jump *i = new sp_instr_jump(ip, ctx); - sp->add_instr(i); + if (!test(i) || sp->add_instr(i)) + return 1; /* BACKPATCH: Resolving forward jump from @@ -312,7 +312,7 @@ void case_stmt_action_then(LEX *lex) (jump from instruction 4 to 12, 7 to 12 ... in the example) */ - sp->push_backpatch(i, ctx->last_label()); + return sp->push_backpatch(i, ctx->last_label()); } /** @@ -1905,10 +1905,9 @@ sp_decl: var_type, lex, (i == num_vars - 1)); - if (is == NULL) + if (is == NULL || + lex->sphead->add_instr(is)) MYSQL_YYABORT; - - lex->sphead->add_instr(is); } pctx->declare_var_boundary(0); @@ -1927,7 +1926,8 @@ sp_decl: my_error(ER_SP_DUP_COND, MYF(0), $2.str); MYSQL_YYABORT; } - YYTHD->lex->spcont->push_cond(&$2, $5); + if(YYTHD->lex->spcont->push_cond(&$2, $5)) + MYSQL_YYABORT; $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; } @@ -1942,10 +1942,10 @@ sp_decl: sp_instr_hpush_jump *i= new sp_instr_hpush_jump(sp->instructions(), ctx, $2, ctx->current_var_count()); - if (i == NULL) + if (i == NULL || + sp->add_instr(i)) MYSQL_YYABORT; - sp->add_instr(i); sp->push_backpatch(i, ctx->push_label((char *)"", 0)); } sp_hcond_list sp_proc_stmt @@ -1960,17 +1960,17 @@ sp_decl: { i= new sp_instr_hreturn(sp->instructions(), ctx, ctx->current_var_count()); - if (i == NULL ) + if (i == NULL || + sp->add_instr(i)) MYSQL_YYABORT; - sp->add_instr(i); } else { /* EXIT or UNDO handler, just jump to the end of the block */ i= new sp_instr_hreturn(sp->instructions(), ctx, 0); - if (i == NULL) + if (i == NULL || + sp->add_instr(i) || + sp->push_backpatch(i, lex->spcont->last_label())) /* Block end */ MYSQL_YYABORT; - sp->add_instr(i); - sp->push_backpatch(i, lex->spcont->last_label()); /* Block end */ } lex->sphead->backpatch(hlab); @@ -1996,10 +1996,10 @@ sp_decl: } i= new sp_instr_cpush(sp->instructions(), ctx, $5, ctx->current_cursor_count()); - if (i == NULL) + if (i == NULL || + sp->add_instr(i) || + ctx->push_cursor(&$2)) MYSQL_YYABORT; - sp->add_instr(i); - ctx->push_cursor(&$2); $$.vars= $$.conds= $$.hndlrs= 0; $$.curs= 1; } @@ -2223,10 +2223,11 @@ sp_proc_stmt: i->m_query.length= lip->ptr - sp->m_tmp_query; else i->m_query.length= lip->tok_end - sp->m_tmp_query; - i->m_query.str= strmake_root(thd->mem_root, - sp->m_tmp_query, - i->m_query.length); - sp->add_instr(i); + if (!(i->m_query.str= strmake_root(thd->mem_root, + sp->m_tmp_query, + i->m_query.length)) || + sp->add_instr(i)) + MYSQL_YYABORT; } sp->restore_lex(thd); } @@ -2251,9 +2252,9 @@ sp_proc_stmt: i= new sp_instr_freturn(sp->instructions(), lex->spcont, $3, sp->m_return_field_def.sql_type, lex); - if (i == NULL) + if (i == NULL || + sp->add_instr(i)) MYSQL_YYABORT; - sp->add_instr(i); sp->m_flags|= sp_head::HAS_RETURN; } sp->restore_lex(YYTHD); @@ -2311,23 +2312,23 @@ sp_proc_stmt: if (n) { sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n); - if (hpop == NULL) + if (hpop == NULL || + sp->add_instr(hpop)) MYSQL_YYABORT; - sp->add_instr(hpop); } n= ctx->diff_cursors(lab->ctx, exclusive); if (n) { sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n); - if (cpop == NULL) + if (cpop == NULL || + sp->add_instr(cpop)) MYSQL_YYABORT; - sp->add_instr(cpop); } i= new sp_instr_jump(ip, ctx); - if (i == NULL) + if (i == NULL || + sp->push_backpatch(i, lab) || /* Jumping forward */ + sp->add_instr(i)) MYSQL_YYABORT; - sp->push_backpatch(i, lab); /* Jumping forward */ - sp->add_instr(i); } } | ITERATE_SYM label_ident @@ -2352,22 +2353,22 @@ sp_proc_stmt: if (n) { sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n); - if (hpop == NULL) + if (hpop == NULL || + sp->add_instr(hpop)) MYSQL_YYABORT; - sp->add_instr(hpop); } n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */ if (n) { sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n); - if (cpop == NULL) + if (cpop == NULL || + sp->add_instr(cpop)) MYSQL_YYABORT; - sp->add_instr(cpop); } i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */ - if (i == NULL) + if (i == NULL || + sp->add_instr(i)) MYSQL_YYABORT; - sp->add_instr(i); } } | OPEN_SYM ident @@ -2383,9 +2384,9 @@ sp_proc_stmt: MYSQL_YYABORT; } i= new sp_instr_copen(sp->instructions(), lex->spcont, offset); - if (i == NULL) + if (i == NULL || + sp->add_instr(i)) MYSQL_YYABORT; - sp->add_instr(i); } | FETCH_SYM sp_opt_fetch_noise ident INTO { @@ -2400,9 +2401,9 @@ sp_proc_stmt: MYSQL_YYABORT; } i= new sp_instr_cfetch(sp->instructions(), lex->spcont, offset); - if (i == NULL) + if (i == NULL || + sp->add_instr(i)) MYSQL_YYABORT; - sp->add_instr(i); } sp_fetch_list { } @@ -2419,9 +2420,9 @@ sp_proc_stmt: MYSQL_YYABORT; } i= new sp_instr_cclose(sp->instructions(), lex->spcont, offset); - if (i == NULL) + if (i == NULL || + sp->add_instr(i)) MYSQL_YYABORT; - sp->add_instr(i); } ; @@ -2488,11 +2489,11 @@ sp_if: uint ip= sp->instructions(); sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, ctx, $2, lex); - if (i == NULL) + if (i == NULL || + sp->push_backpatch(i, ctx->push_label((char *)"", 0)) || + sp->add_cont_backpatch(i) || + sp->add_instr(i)) MYSQL_YYABORT; - sp->push_backpatch(i, ctx->push_label((char *)"", 0)); - sp->add_cont_backpatch(i); - sp->add_instr(i); sp->restore_lex(YYTHD); } sp_proc_stmts1 @@ -2501,9 +2502,9 @@ sp_if: sp_pcontext *ctx= Lex->spcont; uint ip= sp->instructions(); sp_instr_jump *i = new sp_instr_jump(ip, ctx); - if (i == NULL) + if (i == NULL || + sp->add_instr(i)) MYSQL_YYABORT; - sp->add_instr(i); sp->backpatch(ctx->pop_label()); sp->push_backpatch(i, ctx->push_label((char *)"", 0)); } @@ -2589,14 +2590,16 @@ simple_when_clause: /* Simple case: = */ LEX *lex= Lex; - case_stmt_action_when(lex, $3, true); + if (case_stmt_action_when(lex, $3, true)) + MYSQL_YYABORT; lex->sphead->restore_lex(YYTHD); /* For expr $3 */ } THEN_SYM sp_proc_stmts1 { LEX *lex= Lex; - case_stmt_action_then(lex); + if (case_stmt_action_then(lex)) + MYSQL_YYABORT; } ; @@ -2609,14 +2612,16 @@ searched_when_clause: expr { LEX *lex= Lex; - case_stmt_action_when(lex, $3, false); + if (case_stmt_action_when(lex, $3, false)) + MYSQL_YYABORT; lex->sphead->restore_lex(YYTHD); /* For expr $3 */ } THEN_SYM sp_proc_stmts1 { LEX *lex= Lex; - case_stmt_action_then(lex); + if (case_stmt_action_then(lex)) + MYSQL_YYABORT; } ; @@ -2628,9 +2633,9 @@ else_clause_opt: uint ip= sp->instructions(); sp_instr_error *i= new sp_instr_error(ip, lex->spcont, ER_SP_CASE_NOT_FOUND); - if (i == NULL) + if (i == NULL || + sp->add_instr(i)) MYSQL_YYABORT; - sp->add_instr(i); } | ELSE sp_proc_stmts1 ; @@ -2744,17 +2749,17 @@ sp_block_content: { sp_instr_hpop *hpop= new sp_instr_hpop(sp->instructions(), ctx, $3.hndlrs); - if (hpop == NULL) + if (hpop == NULL || + sp->add_instr(hpop)) MYSQL_YYABORT; - sp->add_instr(hpop); } if ($3.curs) { sp_instr_cpop *cpop= new sp_instr_cpop(sp->instructions(), ctx, $3.curs); - if (cpop == NULL) + if (cpop == NULL || + sp->add_instr(cpop)) MYSQL_YYABORT; - sp->add_instr(cpop); } lex->spcont= ctx->pop_context(); } @@ -2768,9 +2773,9 @@ sp_unlabeled_control: uint ip= lex->sphead->instructions(); sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip); - if (i == NULL) + if (i == NULL || + lex->sphead->add_instr(i)) MYSQL_YYABORT; - lex->sphead->add_instr(i); } | WHILE_SYM { @@ -2784,12 +2789,12 @@ sp_unlabeled_control: uint ip= sp->instructions(); sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont, $3, lex); - if (i == NULL) - MYSQL_YYABORT; + if (i == NULL || /* Jumping forward */ - sp->push_backpatch(i, lex->spcont->last_label()); - sp->new_cont_backpatch(i); - sp->add_instr(i); + sp->push_backpatch(i, lex->spcont->last_label()) || + sp->new_cont_backpatch(i) || + sp->add_instr(i)) + MYSQL_YYABORT; sp->restore_lex(YYTHD); } sp_proc_stmts1 END WHILE_SYM @@ -2798,9 +2803,9 @@ sp_unlabeled_control: uint ip= lex->sphead->instructions(); sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip); - if (i == NULL) + if (i == NULL || + lex->sphead->add_instr(i)) MYSQL_YYABORT; - lex->sphead->add_instr(i); lex->sphead->do_cont_backpatch(); } | REPEAT_SYM sp_proc_stmts1 UNTIL_SYM @@ -2816,9 +2821,9 @@ sp_unlabeled_control: sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont, $5, lab->ip, lex); - if (i == NULL) + if (i == NULL || + lex->sphead->add_instr(i)) MYSQL_YYABORT; - lex->sphead->add_instr(i); lex->sphead->restore_lex(YYTHD); /* We can shortcut the cont_backpatch here */ i->m_cont_dest= ip+1; @@ -9643,7 +9648,8 @@ option_type_value: qbuff.length); qbuff.length+= 4; i->m_query= qbuff; - sp->add_instr(i); + if (sp->add_instr(i)) + MYSQL_YYABORT; } lex->sphead->restore_lex(thd); } @@ -9725,7 +9731,8 @@ sys_option_value: lex->trg_table_fields.link_in_list((byte *)trg_fld, (byte **)&trg_fld->next_trg_field); - lex->sphead->add_instr(sp_fld); + if (lex->sphead->add_instr(sp_fld)) + MYSQL_YYABORT; } else if ($2.var) { /* System variable */ @@ -9755,11 +9762,12 @@ sys_option_value: it= spv->dflt; else it= new Item_null(); - if (it == NULL) + if (it == NULL || + (sp_set= new sp_instr_set(lex->sphead->instructions(), ctx, + spv->offset, it, spv->type, lex, + TRUE)) == NULL || + lex->sphead->add_instr(sp_set)) MYSQL_YYABORT; - sp_set= new sp_instr_set(lex->sphead->instructions(), ctx, - spv->offset, it, spv->type, lex, TRUE); - lex->sphead->add_instr(sp_set); } } | option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types From 87679ac97302915962f3c9c5f188f5b0c3d44b22 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Wed, 11 Feb 2009 11:56:25 +0000 Subject: [PATCH 002/110] BUG#38197 Errors in @@init_slave not visible in 'show slave status' Some errors that cause the slave SQL thread to stop are not shown in the Slave_SQL_Error column of "SHOW SLAVE STATUS". Instead, the error is only in the server's error log. That makes it difficult to analyze the error for the user. One example of an error that stops the slave but is not shown by "SHOW SLAVE STATUS" is when @@global.init_slave is set incorrectly (e.g., it contains something that is not valid SQL). Three failures were not correctly reported: 1 - Failures during slave thread initialization 2 - Failures while initializing the relay log position right after starting the slave thread. 3 - Failures while processing queries passed through the init_slave option. This patch fixes the issues by reporting the errors through relay-info->report. --- mysql-test/suite/rpl/r/rpl_bug33931.result | 10 +-- mysql-test/suite/rpl/r/rpl_bug38197.result | 18 +++++ mysql-test/suite/rpl/t/rpl_bug33931.test | 6 +- mysql-test/suite/rpl/t/rpl_bug38197.test | 86 ++++++++++++++++++++++ sql/slave.cc | 23 ++++-- 5 files changed, 129 insertions(+), 14 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_bug38197.result create mode 100644 mysql-test/suite/rpl/t/rpl_bug38197.test diff --git a/mysql-test/suite/rpl/r/rpl_bug33931.result b/mysql-test/suite/rpl/r/rpl_bug33931.result index 1b3f2cfc7dc..85c8fb0da9c 100644 --- a/mysql-test/suite/rpl/r/rpl_bug33931.result +++ b/mysql-test/suite/rpl/r/rpl_bug33931.result @@ -1,5 +1,5 @@ reset master; -call mtr.add_suppression("Failed during slave.*thread initialization"); +call mtr.add_suppression("Failed during slave thread initialization"); stop slave; reset slave; SET GLOBAL debug="d,simulate_io_slave_error_on_init,simulate_sql_slave_error_on_init"; @@ -23,8 +23,8 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 0 -Last_Error +Last_Errno # +Last_Error Failed during slave thread initialization Skip_Counter 0 Exec_Master_Log_Pos 0 Relay_Log_Space # @@ -41,6 +41,6 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 Last_IO_Error -Last_SQL_Errno 0 -Last_SQL_Error +Last_SQL_Errno # +Last_SQL_Error Failed during slave thread initialization SET GLOBAL debug=""; diff --git a/mysql-test/suite/rpl/r/rpl_bug38197.result b/mysql-test/suite/rpl/r/rpl_bug38197.result new file mode 100644 index 00000000000..ab957e6d9bc --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_bug38197.result @@ -0,0 +1,18 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +stop slave; +reset slave; +SET GLOBAL debug= "d,simulate_io_slave_error_on_init,simulate_sql_slave_error_on_init"; +start slave; +Reporting the following error: Failed during slave thread initialization +SET GLOBAL debug= ""; +stop slave; +reset slave; +SET GLOBAL init_slave= "garbage"; +start slave; +Reporting the following error: Slave SQL thread aborted. Can't execute init_slave query +SET GLOBAL init_slave= ""; diff --git a/mysql-test/suite/rpl/t/rpl_bug33931.test b/mysql-test/suite/rpl/t/rpl_bug33931.test index a439b346538..13f781c644b 100644 --- a/mysql-test/suite/rpl/t/rpl_bug33931.test +++ b/mysql-test/suite/rpl/t/rpl_bug33931.test @@ -15,7 +15,7 @@ reset master; connection slave; # Add suppression for expected warnings in slaves error log -call mtr.add_suppression("Failed during slave.*thread initialization"); +call mtr.add_suppression("Failed during slave thread initialization"); --disable_warnings stop slave; @@ -37,8 +37,8 @@ connection slave; # source include/wait_for_slave_to_stop.inc; ---replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 8 # 9 # 23 # 33 # +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 8 # 9 # 19 # 23 # 33 # 37 # query_vertical show slave status; # diff --git a/mysql-test/suite/rpl/t/rpl_bug38197.test b/mysql-test/suite/rpl/t/rpl_bug38197.test new file mode 100644 index 00000000000..4ca0de6ec66 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_bug38197.test @@ -0,0 +1,86 @@ +###################################################################### +# Some errors that cause the slave SQL thread to stop are not shown in +# the Slave_SQL_Error column of "SHOW SLAVE STATUS". Instead, the error +# is only in the server's error log. +# +# Two failures and their respective reporting are verified: +# +# 1 - Failures during slave thread initialization +# 2 - Failures while processing queries passed through the init_slave +# option. +# +# In order to check the first type of failure, we inject a fault in the +# SQL/IO Threads through SET GLOBAL debug. +# +# To check the second type, we set @@global.init_slave to an invalid +# command thus preventing the initialization of the SQL Thread. +# +# Obs: +# 1 - Note that testing failures while initializing the relay log position +# is hard as the same function is called before the code reaches the point +# that we want to test. +# +# 2 - This test does not target failures that are reported while applying +# events such as duplicate keys, errors while reading the relay-log.bin*, +# etc. Such errors are already checked on other tests. +###################################################################### + +###################################################################### +# Configuring the Environment +###################################################################### +source include/have_debug.inc; +source include/master-slave.inc; +source include/have_log_bin.inc; + +connection slave; + +--disable_warnings +stop slave; +--enable_warnings +reset slave; + +###################################################################### +# Injecting faults in the threads' initialization +###################################################################### +connection slave; + +# Set debug flags on slave to force errors to occur +SET GLOBAL debug= "d,simulate_io_slave_error_on_init,simulate_sql_slave_error_on_init"; + +start slave; + +# +# slave is going to stop because of emulated failures +# but there won't be any crashes nor asserts hit. +# +source include/wait_for_slave_to_stop.inc; + +let $error= query_get_value(SHOW SLAVE STATUS, Last_Error, 1); +echo Reporting the following error: $error; + +SET GLOBAL debug= ""; + +###################################################################### +# Injecting faults in the init_slave option +###################################################################### +connection slave; + +--disable_warnings +stop slave; +--enable_warnings +source include/wait_for_slave_to_stop.inc; + +reset slave; + +SET GLOBAL init_slave= "garbage"; + +start slave; +source include/wait_for_slave_sql_to_stop.inc; + +let $error= query_get_value(SHOW SLAVE STATUS, Last_Error, 1); +echo Reporting the following error: $error; + +###################################################################### +# Clean up +###################################################################### +SET GLOBAL init_slave= ""; diff --git a/sql/slave.cc b/sql/slave.cc index 22c61b3ec6c..71affbab6bf 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2678,7 +2678,8 @@ pthread_handler_t handle_slave_sql(void *arg) */ pthread_cond_broadcast(&rli->start_cond); pthread_mutex_unlock(&rli->run_lock); - sql_print_error("Failed during slave thread initialization"); + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + "Failed during slave thread initialization"); goto err; } thd->init_for_queries(); @@ -2722,9 +2723,9 @@ pthread_handler_t handle_slave_sql(void *arg) rli->group_relay_log_pos, 1 /*need data lock*/, &errmsg, 1 /*look for a description_event*/)) - { - sql_print_error("Error initializing relay log position: %s", - errmsg); + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + "Error initializing relay log position: %s", errmsg); goto err; } THD_CHECK_SENTRY(thd); @@ -2769,8 +2770,8 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME, execute_init_command(thd, &sys_init_slave, &LOCK_sys_init_slave); if (thd->is_slave_error) { - sql_print_error("\ -Slave SQL thread aborted. Can't execute init_slave query"); + rli->report(ERROR_LEVEL, thd->main_da.sql_errno(), + "Slave SQL thread aborted. Can't execute init_slave query"); goto err; } } @@ -2820,10 +2821,20 @@ Slave SQL thread aborted. Can't execute init_slave query"); thd->main_da.sql_errno(), last_errno)); if (last_errno == 0) { + /* + This function is reporting an error which was not reported + while executing exec_relay_log_event(). + */ rli->report(ERROR_LEVEL, thd->main_da.sql_errno(), errmsg); } else if (last_errno != thd->main_da.sql_errno()) { + /* + * An error was reported while executing exec_relay_log_event() + * however the error code differs from what is in the thread. + * This function prints out more information to help finding + * what caused the problem. + */ sql_print_error("Slave (additional info): %s Error_code: %d", errmsg, thd->main_da.sql_errno()); } From 67239e07f0e735eaf7fbcbcb1e84a0c4416c8f2c Mon Sep 17 00:00:00 2001 From: "Patrick.Crews@Sun.COM" <> Date: Mon, 9 Mar 2009 22:14:52 +0100 Subject: [PATCH 003/110] Test cases adjusted, precision changes "error Corrupt" changed to "status Operation failed" --- mysql-test/suite/funcs_1/r/innodb_func_view.result | 4 ++-- mysql-test/suite/funcs_1/r/innodb_views.result | 6 +++--- mysql-test/suite/funcs_1/r/myisam_views.result | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mysql-test/suite/funcs_1/r/innodb_func_view.result b/mysql-test/suite/funcs_1/r/innodb_func_view.result index c2689a36801..0bd83c81bcf 100644 --- a/mysql-test/suite/funcs_1/r/innodb_func_view.result +++ b/mysql-test/suite/funcs_1/r/innodb_func_view.result @@ -5245,7 +5245,7 @@ WHERE select_id = 1 OR select_id IS NULL order by id; sqrt(my_bigint) my_bigint id NULL NULL 1 NULL -9223372036854775808 2 -3037000499.976 9223372036854775807 3 +3037000499.97605 9223372036854775807 3 0 0 4 NULL -1 5 2 4 6 @@ -5259,7 +5259,7 @@ WHERE select_id = 1 OR select_id IS NULL) order by id; sqrt(my_bigint) my_bigint id NULL NULL 1 NULL -9223372036854775808 2 -3037000499.976 9223372036854775807 3 +3037000499.97605 9223372036854775807 3 0 0 4 NULL -1 5 2 4 6 diff --git a/mysql-test/suite/funcs_1/r/innodb_views.result b/mysql-test/suite/funcs_1/r/innodb_views.result index 3d5c5a1e698..30c7261d09e 100644 --- a/mysql-test/suite/funcs_1/r/innodb_views.result +++ b/mysql-test/suite/funcs_1/r/innodb_views.result @@ -22824,7 +22824,7 @@ f1 f2 ABC 3 SELECT * FROM v1 order by 2; f1 my_sqrt -ABC 1.7320508075689 +ABC 1.73205080756888 ALTER TABLE t1 CHANGE COLUMN f2 f2 VARCHAR(30); INSERT INTO t1 SET f1 = 'ABC', f2 = 'DEF'; DESCRIBE t1; @@ -22842,7 +22842,7 @@ ABC DEF SELECT * FROM v1 order by 2; f1 my_sqrt ABC 0 -ABC 1.7320508075689 +ABC 1.73205080756888 SELECT SQRT('DEF'); SQRT('DEF') 0 @@ -22862,7 +22862,7 @@ my_sqrt double YES NULL SELECT * FROM v2 order by 2; f1 my_sqrt ABC 0 -ABC 1.7320508075689 +ABC 1.73205080756888 CREATE TABLE t2 AS SELECT f1, SQRT(f2) my_sqrt FROM t1; SELECT * FROM t2 order by 2; f1 ABC diff --git a/mysql-test/suite/funcs_1/r/myisam_views.result b/mysql-test/suite/funcs_1/r/myisam_views.result index e4d6dd4cf8e..c0b12796355 100644 --- a/mysql-test/suite/funcs_1/r/myisam_views.result +++ b/mysql-test/suite/funcs_1/r/myisam_views.result @@ -23043,7 +23043,7 @@ ERROR 42S02: Table 'test.v1' doesn't exist CHECK TABLE v1; Table Op Msg_type Msg_text test.v1 check Error Table 'test.v1' doesn't exist -test.v1 check error Corrupt +test.v1 check status Operation failed DESCRIBE v1; ERROR 42S02: Table 'test.v1' doesn't exist EXPLAIN SELECT * FROM v1; From e60cecab80edd322d3c82375bfb7d7eb256a4e98 Mon Sep 17 00:00:00 2001 From: "kent.boortz@sun.com" <> Date: Mon, 9 Mar 2009 22:16:24 +0100 Subject: [PATCH 004/110] Back patched libedit portability changes from 5.1.32 --- cmd-line-utils/libedit/makelist.sh | 4 ++-- cmd-line-utils/libedit/readline.c | 5 +---- cmd-line-utils/libedit/readline/readline.h | 2 +- cmd-line-utils/libedit/vi.c | 4 ++-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/cmd-line-utils/libedit/makelist.sh b/cmd-line-utils/libedit/makelist.sh index fdd3f934e15..5d25b4776c9 100644 --- a/cmd-line-utils/libedit/makelist.sh +++ b/cmd-line-utils/libedit/makelist.sh @@ -84,7 +84,7 @@ case $FLAG in cat $FILES | $AWK ' BEGIN { printf("/* Automatically generated file, do not edit */\n"); - printf("#include \"sys.h\"\n#include \"el.h\"\n"); + printf("#include \"config.h\"\n#include \"el.h\"\n"); printf("private const struct el_bindings_t el_func_help[] = {\n"); low = "abcdefghijklmnopqrstuvwxyz_"; high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"; @@ -169,7 +169,7 @@ case $FLAG in cat $FILES | $AWK '/el_action_t/ { print $3 }' | sort | $AWK ' BEGIN { printf("/* Automatically generated file, do not edit */\n"); - printf("#include \"sys.h\"\n#include \"el.h\"\n"); + printf("#include \"config.h\"\n#include \"el.h\"\n"); printf("private const el_func_t el_func[] = {"); maxlen = 80; needn = 1; diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index ca8796fbd37..1f1b18c97d8 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -51,13 +51,10 @@ #else #include "np/vis.h" #endif -#ifdef HAVE_ALLOCA_H -#include -#endif +#include "readline/readline.h" #include "el.h" #include "fcns.h" /* for EL_NUM_FCNS */ #include "histedit.h" -#include "readline/readline.h" #include "filecomplete.h" void rl_prep_terminal(int); diff --git a/cmd-line-utils/libedit/readline/readline.h b/cmd-line-utils/libedit/readline/readline.h index c4806734bc5..c77b080c439 100644 --- a/cmd-line-utils/libedit/readline/readline.h +++ b/cmd-line-utils/libedit/readline/readline.h @@ -66,7 +66,7 @@ typedef KEYMAP_ENTRY *Keymap; #ifndef CTRL #include -#if !defined(__sun__) && !defined(__hpux__) +#if !defined(__sun) && !defined(__hpux) && !defined(_AIX) #include #endif #ifndef CTRL diff --git a/cmd-line-utils/libedit/vi.c b/cmd-line-utils/libedit/vi.c index 602383f3231..00a9f493a9b 100644 --- a/cmd-line-utils/libedit/vi.c +++ b/cmd-line-utils/libedit/vi.c @@ -914,14 +914,14 @@ vi_comment_out(EditLine *el, int c) * NB: posix implies that we should enter insert mode, however * this is against historical precedent... */ -#ifdef __weak_reference +#if defined(__weak_reference) && !defined(__FreeBSD__) extern char *get_alias_text(const char *) __weak_reference(get_alias_text); #endif protected el_action_t /*ARGSUSED*/ vi_alias(EditLine *el, int c) { -#ifdef __weak_reference +#if defined(__weak_reference) && !defined(__FreeBSD__) char alias_name[3]; char *alias_text; From 8961b82ac742c21874e2ee13ba3692ec5ea975eb Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Wed, 11 Mar 2009 11:46:21 -0400 Subject: [PATCH 005/110] Accept wide-character version of libncurses also. --- config/ac-macros/misc.m4 | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/config/ac-macros/misc.m4 b/config/ac-macros/misc.m4 index 8c3b51ebc5e..aef1eeaf935 100644 --- a/config/ac-macros/misc.m4 +++ b/config/ac-macros/misc.m4 @@ -358,16 +358,19 @@ esac AC_DEFUN([MYSQL_CHECK_LIB_TERMCAP], [ AC_CACHE_VAL(mysql_cv_termcap_lib, -[AC_CHECK_LIB(ncurses, tgetent, mysql_cv_termcap_lib=libncurses, - [AC_CHECK_LIB(curses, tgetent, mysql_cv_termcap_lib=libcurses, - [AC_CHECK_LIB(termcap, tgetent, mysql_cv_termcap_lib=libtermcap, - [AC_CHECK_LIB(tinfo, tgetent, mysql_cv_termcap_lib=libtinfo, - mysql_cv_termcap_lib=NOT_FOUND)])])])]) + [AC_CHECK_LIB(ncursesw, tgetent, mysql_cv_termcap_lib=libncursesw, + [AC_CHECK_LIB(ncurses, tgetent, mysql_cv_termcap_lib=libncurses, + [AC_CHECK_LIB(curses, tgetent, mysql_cv_termcap_lib=libcurses, + [AC_CHECK_LIB(termcap, tgetent, mysql_cv_termcap_lib=libtermcap, + [AC_CHECK_LIB(tinfo, tgetent, mysql_cv_termcap_lib=libtinfo, + mysql_cv_termcap_lib=NOT_FOUND)])])])])]) AC_MSG_CHECKING(for termcap functions library) if test "$mysql_cv_termcap_lib" = "NOT_FOUND"; then AC_MSG_ERROR([No curses/termcap library found]) elif test "$mysql_cv_termcap_lib" = "libtermcap"; then TERMCAP_LIB=-ltermcap +elif test "$mysql_cv_termcap_lib" = "libncursesw"; then +TERMCAP_LIB=-lncursesw elif test "$mysql_cv_termcap_lib" = "libncurses"; then TERMCAP_LIB=-lncurses elif test "$mysql_cv_termcap_lib" = "libtinfo"; then From 677b00faf68c9745c11d899f7538f50b10b5d4ca Mon Sep 17 00:00:00 2001 From: "kent.boortz@sun.com" <> Date: Thu, 19 Mar 2009 16:40:54 +0100 Subject: [PATCH 006/110] cmd-line-utils/libedit/readline/readline.h - Header missing or not usable on QNX and OpenServer 6 include/my_global.h - Moved down definition of function rint(), as for some platforms (in this case Netware) 'longlong' is not defined until later in "my_global.h" --- cmd-line-utils/libedit/readline/readline.h | 2 +- include/my_global.h | 69 +++++++++++----------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/cmd-line-utils/libedit/readline/readline.h b/cmd-line-utils/libedit/readline/readline.h index c77b080c439..0e300faed89 100644 --- a/cmd-line-utils/libedit/readline/readline.h +++ b/cmd-line-utils/libedit/readline/readline.h @@ -66,7 +66,7 @@ typedef KEYMAP_ENTRY *Keymap; #ifndef CTRL #include -#if !defined(__sun) && !defined(__hpux) && !defined(_AIX) +#if !defined(__sun) && !defined(__hpux) && !defined(_AIX) && !defined(__QNXNTO__) && !defined(__USLC__) #include #endif #ifndef CTRL diff --git a/include/my_global.h b/include/my_global.h index f5a3016bb1e..06d5b0f94b4 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -486,40 +486,6 @@ typedef unsigned short ushort; #define test_all_bits(a,b) (((a) & (b)) == (b)) #define set_bits(type, bit_count) (sizeof(type)*8 <= (bit_count) ? ~(type) 0 : ((((type) 1) << (bit_count)) - (type) 1)) #define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0]))) -#ifndef HAVE_RINT -/** - All integers up to this number can be represented exactly as double precision - values (DBL_MANT_DIG == 53 for IEEE 754 hardware). -*/ -#define MAX_EXACT_INTEGER ((1LL << DBL_MANT_DIG) - 1) - -/** - rint(3) implementation for platforms that do not have it. - Always rounds to the nearest integer with ties being rounded to the nearest - even integer to mimic glibc's rint() behavior in the "round-to-nearest" - FPU mode. Hardware-specific optimizations are possible (frndint on x86). - Unlike this implementation, hardware will also honor the FPU rounding mode. -*/ - -static inline double rint(double x) -{ - double f, i; - f = modf(x, &i); - /* - All doubles with absolute values > MAX_EXACT_INTEGER are even anyway, - no need to check it. - */ - if (x > 0.0) - i += (double) ((f > 0.5) || (f == 0.5 && - i <= (double) MAX_EXACT_INTEGER && - (longlong) i % 2)); - else - i -= (double) ((f < -0.5) || (f == -0.5 && - i >= (double) -MAX_EXACT_INTEGER && - (longlong) i % 2)); - return i; -} -#endif /* HAVE_RINT */ /* Define some general constants */ #ifndef TRUE @@ -1391,4 +1357,39 @@ do { doubleget_union _tmp; \ #define MY_INT64_NUM_DECIMAL_DIGITS 21 +#ifndef HAVE_RINT +/** + All integers up to this number can be represented exactly as double precision + values (DBL_MANT_DIG == 53 for IEEE 754 hardware). +*/ +#define MAX_EXACT_INTEGER ((1LL << DBL_MANT_DIG) - 1) + +/** + rint(3) implementation for platforms that do not have it. + Always rounds to the nearest integer with ties being rounded to the nearest + even integer to mimic glibc's rint() behavior in the "round-to-nearest" + FPU mode. Hardware-specific optimizations are possible (frndint on x86). + Unlike this implementation, hardware will also honor the FPU rounding mode. +*/ + +static inline double rint(double x) +{ + double f, i; + f = modf(x, &i); + /* + All doubles with absolute values > MAX_EXACT_INTEGER are even anyway, + no need to check it. + */ + if (x > 0.0) + i += (double) ((f > 0.5) || (f == 0.5 && + i <= (double) MAX_EXACT_INTEGER && + (longlong) i % 2)); + else + i -= (double) ((f < -0.5) || (f == -0.5 && + i >= (double) -MAX_EXACT_INTEGER && + (longlong) i % 2)); + return i; +} +#endif /* HAVE_RINT */ + #endif /* my_global_h */ From 0e0843d8700a791e379e8c2d41bc85eff307026f Mon Sep 17 00:00:00 2001 From: Satya B Date: Fri, 20 Mar 2009 14:48:14 +0530 Subject: [PATCH 007/110] Fix for BUG#41330 -Myisam table open count set to zero before index blocks are written. When we have a myisam table with DELAY_KEY_WRITE option, index updates are not applied until the flush tables command is issued or until the server is shutdown. If server gets killed before the index updates are written to disk, the index file is corrupted as expected but the table is not marked as crashed. So when we start server with myisam-recover, table is not repaired leaving the table unusable. The problem is when we try to write the index updates to index file, we decrement the open_count even before the flushing the keys to index file. Fixed by moving the decrement operation after flushing the keys to the index file. So we always have non zero open count if the flush table operation is killed and when the server is started with mysiam-recover option, it marks the table as crashed and repairs it. Note: No testcase for added as we need to kill the server and start the server with different set of options and other non trivial operations involved. --- myisam/mi_close.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/myisam/mi_close.c b/myisam/mi_close.c index 81d32be468a..43eebed520b 100644 --- a/myisam/mi_close.c +++ b/myisam/mi_close.c @@ -35,8 +35,6 @@ int mi_close(register MI_INFO *info) if (info->lock_type == F_EXTRA_LCK) info->lock_type=F_UNLCK; /* HA_EXTRA_NO_USER_CHANGE */ - if (share->reopen == 1 && share->kfile >= 0) - _mi_decrement_open_count(info); if (info->lock_type != F_UNLCK) { @@ -78,6 +76,8 @@ int mi_close(register MI_INFO *info) */ if (share->mode != O_RDONLY && mi_is_crashed(info)) mi_state_info_write(share->kfile, &share->state, 1); + /* Decrement open count must be last I/O on this file. */ + _mi_decrement_open_count(info); if (my_close(share->kfile,MYF(0))) error = my_errno; } From 73cb9b6e04a110c3fd71f68bcf3bc0cbfcc4f326 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Tue, 24 Mar 2009 11:26:22 +0300 Subject: [PATCH 008/110] Fix for bug #42965: isinf() on 32bit x86 with gcc 4.3 can produce incorrect results for ROUND() Added a workaround and a configure check to test whether isinf() is affected by the GCC bug #39228. Since no code in MySQL server is currently affected by that bug, the patch is actually a safeguard for possible future code modifications. No test cases or changelog entries are needed. --- configure.in | 21 +++++++++++++++++++++ include/my_global.h | 14 ++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 9591b5bbc5a..afe0cdc78ed 100644 --- a/configure.in +++ b/configure.in @@ -2094,6 +2094,27 @@ esac AC_MSG_CHECKING(for isinf in ) AC_TRY_LINK([#include ], [float f = 0.0; int r = isinf(f); return r], AC_MSG_RESULT(yes) + AC_MSG_CHECKING(whether isinf() is safe to use in C code) + AC_TRY_RUN([ +#include +int main() +{ + double a= 10.0; + double b= 1e308; + + return !isinf(a * b); +} +], + [AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no) + AC_DEFINE([HAVE_BROKEN_ISINF], [1], + [Define to 1 if isinf() uses 80-bit register for intermediate values]) + ], + [ +# Let's be optimistic when cross-compiling, since the only compiler known +# to be affected by this isinf() bug is GCC 4.3 on 32-bit x86. + AC_MSG_RESULT([[cross-compiling, assuming 'yes']]) + ]) AC_MSG_CHECKING(whether isinf() can be used in C++ code) AC_LANG_SAVE AC_LANG_CPLUSPLUS diff --git a/include/my_global.h b/include/my_global.h index 845ae042a42..7712696f633 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -797,9 +797,19 @@ typedef SOCKET_SIZE_TYPE size_socket; #endif #ifdef HAVE_ISINF -/* isinf() can be used in both C and C++ code */ -#define my_isinf(X) isinf(X) +/* Check if C compiler is affected by GCC bug #39228 */ +#if !defined(__cplusplus) && defined(HAVE_BROKEN_ISINF) +/* Force store/reload of the argument to/from a 64-bit double */ +static inline double my_isinf(double x) +{ + volatile double t= x; + return isinf(t); +} #else +/* System-provided isinf() is available and safe to use */ +#define my_isinf(X) isinf(X) +#endif +#else /* !HAVE_ISINF */ #define my_isinf(X) (!finite(X) && !isnan(X)) #endif From d0cb03b860a6b08de8deb21ba37e72cce8e1e8b2 Mon Sep 17 00:00:00 2001 From: Leonard Zhou Date: Tue, 24 Mar 2009 16:55:03 +0800 Subject: [PATCH 009/110] Bug#43440 rpl.rpl_temp_table_mix_row fails sporadicly The problem is that after disconnect, the DOPR TEMPORARY TABLE event didn't been written into binlog. So after syncing with slave, the TEMPORARY table on slave is not removed. Waiting DROP TEMPORARY TABLE event to be written into binlog before sync slave with master. --- mysql-test/suite/rpl/t/disabled.def | 1 - mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index cb714c60ba4..f3f329c4b5b 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -11,4 +11,3 @@ ############################################################################## rpl_binlog_corruption : BUG#41793 2008-12-30 sven rpl_binlog_corruption disabled in main (needs new mtr) -rpl_temp_table_mix_row : BUG#43440 2009-03-23 joro rpl.rpl_temp_table_mix_row fails sporadicly diff --git a/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test b/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test index 1fe484b7c27..0cb7f2cbf80 100644 --- a/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test +++ b/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test @@ -33,6 +33,10 @@ SHOW STATUS LIKE "Slave_open_temp_tables"; disconnect master; --connection master1 +# waiting DROP TEMPORARY TABLE event to be written into binlog +let $wait_binlog_event= DROP; +source include/wait_for_binlog_event.inc; + --echo [on slave] sync_slave_with_master; From 7b1d72a096e5ffef0cc82f7c2782cd7a6da84bb1 Mon Sep 17 00:00:00 2001 From: Satya B Date: Wed, 25 Mar 2009 14:45:53 +0530 Subject: [PATCH 010/110] Fix for BUG#41541 - Valgrind warnings on packed MyISAM table After the table is compressed by the myisampack utility, opening the table by the server produces valgrind warnings. This happens because when we try to read a record into the buffer we alway assume that the remaining buffer to read is always equal to word size(4 or 8 or 2 bytes) we read. Sometimes we have remaining buffer size less than word size and trying to read the entire word size will end up in valgrind errors. Fixed by reading byte by byte when we detect the remaining buffer size is less than the word size. --- myisam/mi_packrec.c | 26 ++++++++++++++++++++++++++ mysql-test/r/myisampack.result | 11 +++++++++++ mysql-test/t/myisampack.test | 19 +++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c index ddcf0f33e61..df9a4d18a6c 100644 --- a/myisam/mi_packrec.c +++ b/myisam/mi_packrec.c @@ -1430,6 +1430,32 @@ static void fill_buffer(MI_BIT_BUFF *bit_buff) bit_buff->current_byte=0; return; } + else + { + uint len= 0; + uint i= 0; + /* + Check if the remaining buffer/record to read is less than the word size. + If so read byte by byte + + Note: if this branch becomes a bottleneck it can be removed, assuming + that the second memory segment allocates 7 extra bytes (see + _mi_read_pack_info()). + */ + len= bit_buff->end - bit_buff->pos; + if (len < (BITS_SAVED / 8)) + { + bit_buff->current_byte= 0; + for (i=0 ; i < len ; i++) + { + bit_buff->current_byte+= (((uint) ((uchar) bit_buff->pos[len - i - 1])) + << (8 * i)); + } + bit_buff->pos= bit_buff->end; + return; + } + } + #if BITS_SAVED == 64 bit_buff->current_byte= ((((uint) ((uchar) bit_buff->pos[7]))) + (((uint) ((uchar) bit_buff->pos[6])) << 8) + diff --git a/mysql-test/r/myisampack.result b/mysql-test/r/myisampack.result index 5f39d318234..b4b200549a5 100644 --- a/mysql-test/r/myisampack.result +++ b/mysql-test/r/myisampack.result @@ -27,3 +27,14 @@ CHECK TABLE t1 EXTENDED; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; +# +# BUG#41541 - Valgrind warnings on packed MyISAM table +# +CREATE TABLE t1(f1 VARCHAR(200), f2 TEXT); +INSERT INTO t1 VALUES ('foo', 'foo1'), ('bar', 'bar1'); +FLUSH TABLE t1; +# Compress the table using MYISAMPACK tool +SELECT COUNT(*) FROM t1; +COUNT(*) +1024 +DROP TABLE t1; diff --git a/mysql-test/t/myisampack.test b/mysql-test/t/myisampack.test index 6598af6318a..ace7afce88a 100644 --- a/mysql-test/t/myisampack.test +++ b/mysql-test/t/myisampack.test @@ -31,3 +31,22 @@ FLUSH TABLES; --exec $MYISAMCHK -s --unpack $MYSQLTEST_VARDIR/master-data/test/t1 CHECK TABLE t1 EXTENDED; DROP TABLE t1; + +--echo # +--echo # BUG#41541 - Valgrind warnings on packed MyISAM table +--echo # +CREATE TABLE t1(f1 VARCHAR(200), f2 TEXT); +INSERT INTO t1 VALUES ('foo', 'foo1'), ('bar', 'bar1'); +let $i=9; +--disable_query_log +while ($i) +{ + INSERT INTO t1 SELECT * FROM t1; + dec $i; +} +--enable_query_log +FLUSH TABLE t1; +--echo # Compress the table using MYISAMPACK tool +--exec $MYISAMPACK $MYSQLTEST_VARDIR/master-data/test/t1 +SELECT COUNT(*) FROM t1; +DROP TABLE t1; From e0824fe7609c653440963921cfc1cf6f0def265b Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 25 Mar 2009 19:00:04 +0300 Subject: [PATCH 011/110] Disable query_cache_28249 due to Bug#43861. --- mysql-test/t/disabled.def | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index eab0542314a..760c29bbae6 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -11,5 +11,7 @@ ############################################################################## kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild. innodb_bug39438 : BUG#42383 2009-01-28 lsoares "This fails in embedded and on windows. Note that this test is not run on windows and on embedded in PB for main trees currently" +query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically + #concurrent_innodb_safelog: disabled for embedded server due to bug#43733 Select on processlist let the embedded server crash (concurrent_innodb_safelog). #concurrent_innodb_unsafelog: disabled for embedded server due to bug#43733. From 8fec2b0321274f12c0a264351eab1b6e77d6c1a3 Mon Sep 17 00:00:00 2001 From: Matthias Leich Date: Wed, 25 Mar 2009 19:30:43 +0100 Subject: [PATCH 012/110] Fix for Bug#43383 main.variables-big : Weak testing code and result including modifications according to code review + backport of the fix for Bug 41932 funcs_1: is_collation_character_set_applicability path too long for tar which was missing in 5.0 (just a renaming of two files) --- mysql-test/r/variables-big.result | 34 +++++------ ...ty.result => is_coll_char_set_appl.result} | 0 ...bility.test => is_coll_char_set_appl.test} | 0 mysql-test/t/variables-big.test | 57 +++++++++++++++---- 4 files changed, 61 insertions(+), 30 deletions(-) rename mysql-test/suite/funcs_1/r/{is_collation_character_set_applicability.result => is_coll_char_set_appl.result} (100%) rename mysql-test/suite/funcs_1/t/{is_collation_character_set_applicability.test => is_coll_char_set_appl.test} (100%) diff --git a/mysql-test/r/variables-big.result b/mysql-test/r/variables-big.result index c441f27d82d..960fc6d22f4 100644 --- a/mysql-test/r/variables-big.result +++ b/mysql-test/r/variables-big.result @@ -1,24 +1,20 @@ -set session transaction_prealloc_size=1024*1024*1024*1; -show processlist; +SET SESSION transaction_prealloc_size=1024*1024*1024*1; +SHOW PROCESSLIST; Id User Host db Command Time State Info -6 root localhost test Query 0 NULL show processlist -set session transaction_prealloc_size=1024*1024*1024*2; -show processlist; + root localhost test Query