From 52989c445f51f981e8d28842a022e82ac5faab8b Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Fri, 21 Nov 2008 17:38:42 +0400 Subject: [PATCH 01/85] 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 02/85] 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 0e0843d8700a791e379e8c2d41bc85eff307026f Mon Sep 17 00:00:00 2001 From: Satya B Date: Fri, 20 Mar 2009 14:48:14 +0530 Subject: [PATCH 03/85] 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 badc6a127dde53abf722b0a8a1fa2ca7c57c6fca Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Thu, 26 Mar 2009 10:25:06 +0200 Subject: [PATCH 04/85] Bug#38205 Row-based Replication (RBR) causes inconsistencies: HA_ERR_FOUND_DUP Bug#319 if while a non-transactional slave is replicating a transaction possible problem It is impossible to roll back a mixed engines transaction when one of the engine is non-transaction. In replication that fact is crucial because the slave can not safely re-apply a transction that was interrupted with STOP SLAVE. Fixed with making STOP SLAVE not be effective immediately in the case the current group of replication events has modified a non-transaction table. In order for slave to leave either the group needs finishing or the user issues KILL QUERY|CONNECTION slave_thread_id. --- mysql-test/suite/bugs/r/rpl_bug38205.result | 56 ++++++ mysql-test/suite/bugs/t/rpl_bug38205.test | 165 ++++++++++++++++++ .../suite/rpl/r/rpl_start_stop_slave.result | 28 +++ .../rpl/t/rpl_start_stop_slave-slave.opt | 1 + .../suite/rpl/t/rpl_start_stop_slave.test | 87 ++++++++- sql/log_event.cc | 11 +- sql/slave.cc | 3 + 7 files changed, 349 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/bugs/r/rpl_bug38205.result create mode 100644 mysql-test/suite/bugs/t/rpl_bug38205.test create mode 100644 mysql-test/suite/rpl/t/rpl_start_stop_slave-slave.opt diff --git a/mysql-test/suite/bugs/r/rpl_bug38205.result b/mysql-test/suite/bugs/r/rpl_bug38205.result new file mode 100644 index 00000000000..195c0ca1135 --- /dev/null +++ b/mysql-test/suite/bugs/r/rpl_bug38205.result @@ -0,0 +1,56 @@ +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; +create table t1i(n int primary key) engine=innodb; +create table t2m(n int primary key) engine=myisam; +begin; +insert into t1i values (1); +insert into t1i values (2); +insert into t1i values (3); +commit; +begin; +insert into t1i values (5); +begin; +insert into t1i values (4); +insert into t2m values (1); +update t1i set n = 5 where n = 4; +commit; +zero +0 +*** kill sql thread *** +rollback; +*** sql thread is *not* running: No *** +*** the prove: the killed slave has not finished the current transaction *** +three +3 +one +1 +zero +0 +delete from t2m; +start slave sql_thread; +delete from t1i; +delete from t2m; +begin; +insert into t1i values (5); +begin; +insert into t1i values (4); +update t1i set n = 5 where n = 4; +commit; +zero +0 +stop slave sql_thread; +rollback; +*** sql thread is running: No *** +*** the prove: the stopped slave has rolled back the current transaction *** +zero +0 +zero +0 +one +1 +start slave sql_thread; +drop table t1i, t2m; diff --git a/mysql-test/suite/bugs/t/rpl_bug38205.test b/mysql-test/suite/bugs/t/rpl_bug38205.test new file mode 100644 index 00000000000..f754d7481c7 --- /dev/null +++ b/mysql-test/suite/bugs/t/rpl_bug38205.test @@ -0,0 +1,165 @@ +# +# Bug #38205 Row-based Replication (RBR) causes inconsistencies: HA_ERR_FOUND_DUPP_KEY +# +# Verifying the fact that STOP SLAVE in the middle of a group execution waits +# for the end of the group before the slave sql thread will stop. +# The patch refines STOP SLAVE to not interrupt a transaction or other type of +# the replication events group (the part I). +# Killing the sql thread continues to provide a "hard" stop (the part II). +# +# Non-deterministic tests +# + +source include/master-slave.inc; +source include/have_innodb.inc; + + +# +# Part II, killed sql slave leaves instantly +# + +# A. multi-statement transaction as the replication group + +connection master; + +create table t1i(n int primary key) engine=innodb; +create table t2m(n int primary key) engine=myisam; + +sync_slave_with_master; + +connection master; + +begin; +insert into t1i values (1); +insert into t1i values (2); +insert into t1i values (3); +commit; + +sync_slave_with_master; + +# +# todo: first challenge is to find out the SQL thread id +# the following is not fully reliable +# + +let $id=`SELECT id from information_schema.processlist where user like 'system user' and state like '%Has read all relay log%' or user like 'system user' and state like '%Reading event from the relay log%'`; +connection slave; +begin; +insert into t1i values (5); + +connection master; +let $pos0_master= query_get_value(SHOW MASTER STATUS, Position, 1); +begin; +insert into t1i values (4); +insert into t2m values (1); # non-ta update +update t1i set n = 5 where n = 4; # to block at. can't be played with killed +commit; +let $pos1_master= query_get_value(SHOW MASTER STATUS, Position, 1); + +connection slave; +# slave sql thread must be locked out by the conn `slave' explicit lock +let $pos0_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +--disable_query_log +eval select $pos0_master - $pos0_slave as zero; +--enable_query_log + +connection slave1; + +let $count= 1; +let $table= t2m; +source include/wait_until_rows_count.inc; +# +# todo: may fail as said above +# +--echo *** kill sql thread *** +--disable_query_log +eval kill connection $id; +--enable_query_log + +connection slave; +rollback; # release the sql thread + +connection slave1; + +source include/wait_for_slave_sql_to_stop.inc; +let $sql_status= query_get_value(SHOW SLAVE STATUS, Slave_SQL_Running, 1); +--echo *** sql thread is *not* running: $sql_status *** +let $pos1_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); + +connection slave; +--echo *** the prove: the killed slave has not finished the current transaction *** + +--disable_query_log +select count(*) as three from t1i; +eval select $pos1_master > $pos1_slave as one; +eval select $pos1_slave - $pos0_slave as zero; +--enable_query_log + +delete from t2m; # remove the row to be able to replay +start slave sql_thread; + +# +# Part I: B The homogenous transaction remains interuptable in between +# + +connection master; +delete from t1i; +delete from t2m; + +sync_slave_with_master; +begin; +insert into t1i values (5); + +connection master; +let $pos0_master= query_get_value(SHOW MASTER STATUS, Position, 1); +begin; +insert into t1i values (4); +update t1i set n = 5 where n = 4; # to block at. not to be played +commit; +let $pos1_master= query_get_value(SHOW MASTER STATUS, Position, 1); + + +connection slave1; +# slave sql can't advance as must be locked by the conn `slave' trans +let $pos0_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +--disable_query_log +eval select $pos0_master - $pos0_slave as zero; +--enable_query_log + +# +# the replicated trans is blocked by the slave's local. +# However, it's not easy to catch the exact moment when it happens. +# The test issues sleep which makes the test either non-deterministic or +# wasting too much time. +# +--sleep 3 + +send stop slave sql_thread; + +connection slave; +rollback; # release the sql thread + +connection slave1; +reap; +source include/wait_for_slave_sql_to_stop.inc; +let $sql_status= query_get_value(SHOW SLAVE STATUS, Slave_SQL_Running, 1); +--echo *** sql thread is running: $sql_status *** + +let $pos1_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); + +--echo *** the prove: the stopped slave has rolled back the current transaction *** + +--disable_query_log +select count(*) as zero from t1i; +eval select $pos0_master - $pos0_slave as zero; +eval select $pos1_master > $pos0_slave as one; +--enable_query_log + +start slave sql_thread; + +# clean-up + +connection master; +drop table t1i, t2m; + +sync_slave_with_master; diff --git a/mysql-test/suite/rpl/r/rpl_start_stop_slave.result b/mysql-test/suite/rpl/r/rpl_start_stop_slave.result index 04ece812f35..130b65c704c 100644 --- a/mysql-test/suite/rpl/r/rpl_start_stop_slave.result +++ b/mysql-test/suite/rpl/r/rpl_start_stop_slave.result @@ -10,3 +10,31 @@ start slave; stop slave io_thread; start slave io_thread; drop table t1; +create table t1i(n int primary key) engine=innodb; +create table t2m(n int primary key) engine=myisam; +begin; +insert into t1i values (1); +insert into t1i values (2); +insert into t1i values (3); +commit; +begin; +insert into t1i values (5); +begin; +insert into t1i values (4); +insert into t2m values (1); +insert into t1i values (5); +commit; +zero +0 +stop slave; +rollback; +*** sql thread is running: No *** +*** the prove: the stopped slave has finished the current transaction *** +five +5 +zero +0 +one +1 +start slave; +drop table t1i, t2m; diff --git a/mysql-test/suite/rpl/t/rpl_start_stop_slave-slave.opt b/mysql-test/suite/rpl/t/rpl_start_stop_slave-slave.opt new file mode 100644 index 00000000000..00ea161cd6e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_start_stop_slave-slave.opt @@ -0,0 +1 @@ +--innodb_lock_wait_timeout=60 diff --git a/mysql-test/suite/rpl/t/rpl_start_stop_slave.test b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test index dbf0775c978..529ed7acb32 100644 --- a/mysql-test/suite/rpl/t/rpl_start_stop_slave.test +++ b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test @@ -1,4 +1,5 @@ source include/master-slave.inc; +source include/have_innodb.inc; # # Bug#6148 () @@ -35,4 +36,88 @@ save_master_pos; connection slave; sync_with_master; -# End of 4.1 tests + +# +# Bug #38205 Row-based Replication (RBR) causes inconsistencies... +# +# Verifying that STOP SLAVE does not interrupt excution of a group +# execution of events if the group can not roll back. +# Killing the sql thread continues to provide a "hard" stop (the +# part II, moved to the bugs suite as it's hard to make it +# deterministic with KILL). +# + +# +# Part I. The being stopped sql thread finishes first the current group of +# events if the group contains an event on a non-transaction table. + +connection master; +create table t1i(n int primary key) engine=innodb; +create table t2m(n int primary key) engine=myisam; +begin; +insert into t1i values (1); +insert into t1i values (2); +insert into t1i values (3); +commit; + +sync_slave_with_master; +connection slave; +begin; +insert into t1i values (5); + +connection master; +let $pos0_master= query_get_value(SHOW MASTER STATUS, Position, 1); +begin; +insert into t1i values (4); +insert into t2m values (1); # non-ta update to process +insert into t1i values (5); # to block at. to be played with stopped +commit; + +connection slave; +# slave sql thread must be locked out by the conn `slave' explicit lock +let $pos0_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +--disable_query_log +eval select $pos0_master - $pos0_slave as zero; +--enable_query_log + +connection slave1; +let $count= 1; +let $table= t2m; +source include/wait_until_rows_count.inc; +send stop slave; + +connection slave; +rollback; # release the sql thread + +connection slave1; +reap; +source include/wait_for_slave_to_stop.inc; +let $sql_status= query_get_value(SHOW SLAVE STATUS, Slave_SQL_Running, 1); +--echo *** sql thread is running: $sql_status *** + + +connection master; +let $pos1_master= query_get_value(SHOW MASTER STATUS, Position, 1); + +connection slave; +source include/wait_for_slave_sql_to_stop.inc; + +let $pos1_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); + +--echo *** the prove: the stopped slave has finished the current transaction *** + +--disable_query_log +select count(*) as five from t1i; +eval select $pos1_master - $pos1_slave as zero; +eval select $pos1_slave > $pos0_slave as one; +--enable_query_log + +start slave; + +# clean-up +connection master; +drop table t1i, t2m; + +sync_slave_with_master; + +# End of tests diff --git a/sql/log_event.cc b/sql/log_event.cc index 1941a304e8e..9dfc7ed3198 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -7114,7 +7114,12 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) */ lex_start(thd); mysql_reset_thd_for_next_command(thd); - + /* + The current statement is just about to begin and + has not yet modified anything. Note, all.modified is reset + by mysql_reset_thd_for_next_command. + */ + thd->transaction.stmt.modified_non_trans_table= FALSE; /* Check if the slave is set to use SBR. If so, it should switch to using RBR until the end of the "statement", i.e., next @@ -7217,6 +7222,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) if (table) { + bool transactional_table= table->file->has_transactions(); /* table == NULL means that this table should not be replicated (this was set up by Table_map_log_event::do_apply_event() @@ -7348,6 +7354,9 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) m_curr_row= m_curr_row_end; + if (error == 0 && !transactional_table) + thd->transaction.all.modified_non_trans_table= + thd->transaction.stmt.modified_non_trans_table= TRUE; } // row processing loop DBUG_EXECUTE_IF("STOP_SLAVE_after_first_Rows_event", diff --git a/sql/slave.cc b/sql/slave.cc index 22c61b3ec6c..5a797328bc4 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -687,6 +687,9 @@ static bool sql_slave_killed(THD* thd, Relay_log_info* rli) DBUG_ASSERT(rli->slave_running == 1);// tracking buffer overrun if (abort_loop || thd->killed || rli->abort_slave) { + if (rli->abort_slave && rli->is_in_group() && + thd->transaction.all.modified_non_trans_table) + DBUG_RETURN(0); /* If we are in an unsafe situation (stopping could corrupt replication), we give one minute to the slave SQL thread of grace before really From 95301268221bfcf72baaa9f34f234ff6231235c8 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Fri, 27 Mar 2009 13:19:50 +0800 Subject: [PATCH 05/85] BUG#37145 Killing a statement doing DDL may log binlog event with error code 1053 When the thread executing a DDL was killed after finished its execution but before writing the binlog event, the error code in the binlog event could be set wrongly to ER_SERVER_SHUTDOWN or ER_QUERY_INTERRUPTED. This patch fixed the problem by ignoring the kill status when constructing the event for DDL statements. This patch also included the following changes in order to provide the test case. 1) modified mysqltest to support variable for connection command 2) modified mysql-test-run.pl, add new variable MYSQL_SLAVE to run mysql client against the slave mysqld. --- client/mysqltest.c | 21 +- mysql-test/include/diff_master_slave.inc | 21 ++ mysql-test/include/kill_query.inc | 68 +++++ .../kill_query_and_diff_master_slave.inc | 43 +++ mysql-test/mysql-test-run.pl | 14 +- mysql-test/r/rpl_killed_ddl.result | 146 ++++++++++ mysql-test/t/rpl_killed_ddl-master.opt | 1 + mysql-test/t/rpl_killed_ddl.test | 271 ++++++++++++++++++ sql/item_func.cc | 4 + sql/log.cc | 15 +- sql/log_event.cc | 3 + sql/log_event.h | 6 +- sql/mysql_priv.h | 7 + sql/sp.cc | 8 +- sql/sp_head.cc | 3 +- sql/sql_acl.cc | 24 +- sql/sql_base.cc | 16 +- sql/sql_db.cc | 8 +- sql/sql_delete.cc | 4 +- sql/sql_insert.cc | 5 +- sql/sql_parse.cc | 12 +- sql/sql_rename.cc | 3 +- sql/sql_table.cc | 24 +- sql/sql_trigger.cc | 2 +- sql/sql_update.cc | 2 +- sql/sql_view.cc | 6 +- 26 files changed, 674 insertions(+), 63 deletions(-) create mode 100644 mysql-test/include/diff_master_slave.inc create mode 100644 mysql-test/include/kill_query.inc create mode 100644 mysql-test/include/kill_query_and_diff_master_slave.inc create mode 100644 mysql-test/r/rpl_killed_ddl.result create mode 100644 mysql-test/t/rpl_killed_ddl-master.opt create mode 100644 mysql-test/t/rpl_killed_ddl.test diff --git a/client/mysqltest.c b/client/mysqltest.c index 312012d7b8d..865c1d9a717 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -4093,13 +4093,20 @@ int select_connection(struct st_command *command) if (!*p) die("Missing connection name in connect"); - name= p; - while (*p && !my_isspace(charset_info,*p)) - p++; - if (*p) - *p++= 0; - command->last_argument= p; - return select_connection_name(name); + + static DYNAMIC_STRING ds_connection; + const struct command_arg connection_args[] = { + { "connection_name", ARG_STRING, TRUE, &ds_connection, "Name of the connection that we switch to." } + }; + check_command_args(command, command->first_argument, connection_args, + sizeof(connection_args)/sizeof(struct command_arg), + ','); + + DBUG_PRINT("info", ("changing connection: %s", ds_connection.str)); + + int ret= select_connection_name(ds_connection.str); + dynstr_free(&ds_connection); + return ret; } diff --git a/mysql-test/include/diff_master_slave.inc b/mysql-test/include/diff_master_slave.inc new file mode 100644 index 00000000000..b6d79190671 --- /dev/null +++ b/mysql-test/include/diff_master_slave.inc @@ -0,0 +1,21 @@ +# ==== Purpose ==== +# +# Diff the output of a statement on master and slave +# +# ==== Usage ===== +# +# let $diff_statement= SELECT * FROM t1 WHERE a < 100; +# source include/diff_master_slave.inc; + +--echo source include/diff_master_slave.inc; +disable_query_log; +disable_result_log; + +exec $MYSQL test -e "$diff_statement" > $MYSQLTEST_VARDIR/tmp/diff_master.out; +sync_slave_with_master; +exec $MYSQL_SLAVE test -e "$diff_statement" > $MYSQLTEST_VARDIR/tmp/diff_slave.out; + +diff_files $MYSQLTEST_VARDIR/tmp/diff_master.out $MYSQLTEST_VARDIR/tmp/diff_slave.out; + +enable_result_log; +enable_query_log; diff --git a/mysql-test/include/kill_query.inc b/mysql-test/include/kill_query.inc new file mode 100644 index 00000000000..341c3b93535 --- /dev/null +++ b/mysql-test/include/kill_query.inc @@ -0,0 +1,68 @@ +# ==== Purpose ==== +# +# Kill a query in the master connection, and then try to reap the +# result of the killed query. +# +# ==== Usage ==== +# +# The following variables should be set before sourcing this file. +# +# $debug_lock: name of the debug user lock, if set, will release/lock +# the specified debug lock accordingly, and before +# sourcing this, connection 'master' should get the user +# lock and run a query in another thread, which will +# block before creating statement event. +# +# $connection_name: name of the connection that is waiting for the +# lock, this can not be 'master' +# +# $connection_id: id of the connection that is waiting for the lock +# +# Example: +# let $debug_lock=; +# connection master1; +# let $connection_name= master1; +# let $connection_id= `SELECT CONNECTION_ID()`; +# send CREATE TABLE t1; +# source kill_query.inc; +# +# let $debug_lock= "debug_lock.before_query_log_event"; +# connection master; +# eval SELECT GET_LOCK($debug_lock, 10); +# connection master1; +# let $connection_name= master1; +# let $connection_id= `SELECT CONNECTION_ID()`; +# send CREATE TABLE t1; +# source kill_query.inc; + + +--echo source include/kill_query.inc; +disable_query_log; +disable_result_log; +connection master; + +# kill the query that is waiting +eval kill query $connection_id; + +if (`SELECT '$debug_lock' != ''`) +{ + # release the lock to allow binlog continue + eval SELECT RELEASE_LOCK($debug_lock); +} + +# reap the result of the waiting query +connection $connection_name; +error 0, 1317, 1307, 1306, 1334, 1305; +reap; + +connection master; + +if (`SELECT '$debug_lock' != ''`) +{ + # get lock again to make the next query wait + eval SELECT GET_LOCK($debug_lock, 10); +} + +connection $connection_name; +enable_query_log; +enable_result_log; diff --git a/mysql-test/include/kill_query_and_diff_master_slave.inc b/mysql-test/include/kill_query_and_diff_master_slave.inc new file mode 100644 index 00000000000..611d6929c99 --- /dev/null +++ b/mysql-test/include/kill_query_and_diff_master_slave.inc @@ -0,0 +1,43 @@ +# ==== Purpose ==== +# +# Kill a query, sync master with slave, and diff the output of a +# statement on master and slave to check if statement is correctly +# replicated. +# +# ==== Usage ==== +# +# connection ; +# let $connection_name= +# let $connection_id=`SELECT CONNECTION_ID()`; +# let $diff_statement=; +# send ; +# source include/kill_query_and_diff_master_slave.inc; +# +# Note: must not be 'master'. +# +# See also kill_query.inc and diff_master_slave.inc for more +# information + +source include/kill_query.inc; + +# Release the debug lock if used, so that the statements in +# diff_master_slave.inc will not be blocked. +connection master; +disable_query_log; +disable_result_log; +if (`SELECT '$debug_lock' != ''`) +{ + eval SELECT RELEASE_LOCK($debug_lock); +} +enable_result_log; +enable_query_log; + +source include/diff_master_slave.inc; + +# Acquire the debug lock again if used +connection master; +disable_query_log; disable_result_log; if (`SELECT '$debug_lock' != +''`) { eval SELECT GET_LOCK($debug_lock, 10); } enable_result_log; +enable_query_log; + +connection $connection_name; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 0948c973e9b..ffa9b4cb1d3 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2063,7 +2063,7 @@ sub environment_setup () { $ENV{'MYSQL_BINLOG'}= $cmdline_mysqlbinlog; # ---------------------------------------------------- - # Setup env so childs can execute mysql + # Setup env so childs can execute mysql against master # ---------------------------------------------------- my $cmdline_mysql= mtr_native_path($exe_mysql) . @@ -2074,6 +2074,18 @@ sub environment_setup () { $ENV{'MYSQL'}= $cmdline_mysql; + # ---------------------------------------------------- + # Setup env so childs can execute mysql against slave + # ---------------------------------------------------- + my $cmdline_mysql_slave= + mtr_native_path($exe_mysql) . + " --no-defaults --host=localhost --user=root --password= " . + "--port=$slave->[0]->{'port'} " . + "--socket=$slave->[0]->{'path_sock'} ". + "--character-sets-dir=$path_charsetsdir"; + + $ENV{'MYSQL_SLAVE'}= $cmdline_mysql_slave; + # ---------------------------------------------------- # Setup env so childs can execute bug25714 # ---------------------------------------------------- diff --git a/mysql-test/r/rpl_killed_ddl.result b/mysql-test/r/rpl_killed_ddl.result new file mode 100644 index 00000000000..aa419a8556e --- /dev/null +++ b/mysql-test/r/rpl_killed_ddl.result @@ -0,0 +1,146 @@ +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; +DROP DATABASE IF EXISTS d1; +DROP DATABASE IF EXISTS d2; +DROP DATABASE IF EXISTS d3; +DROP DATABASE IF EXISTS d4; +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP FUNCTION IF EXISTS f3; +DROP FUNCTION IF EXISTS f4; +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; +DROP TABLE IF EXISTS t4; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +DROP PROCEDURE IF EXISTS p3; +DROP PROCEDURE IF EXISTS p4; +DROP TRIGGER IF EXISTS tr1; +DROP TRIGGER IF EXISTS tr2; +DROP TRIGGER IF EXISTS tr3; +DROP TRIGGER IF EXISTS tr4; +CREATE DATABASE d1; +CREATE FUNCTION f1 () RETURNS INT DETERMINISTIC +RETURN 1; +CREATE PROCEDURE p1 (OUT rows INT) +BEGIN +SELECT COUNT(*) INTO rows FROM t1; +END; +// +CREATE TABLE t1 (a int); +CREATE TABLE t3 (a int); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 +FOR EACH ROW BEGIN +DELETE FROM t4 WHERE a=NEW.a; +END; +// +CREATE INDEX i1 ON t1 (a); +CREATE VIEW v1 AS SELECT a FROM t1 WHERE a < 100; +[on master] +[on master1] +CREATE DATABASE d2; +source include/kill_query.inc; +source include/diff_master_slave.inc; +ALTER DATABASE d1 +DEFAULT CHARACTER SET = 'utf8'; +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP DATABASE d1; +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP DATABASE d2; +source include/kill_query.inc; +source include/diff_master_slave.inc; +CREATE FUNCTION f2 () RETURNS INT DETERMINISTIC +RETURN 1; +source include/kill_query.inc; +source include/diff_master_slave.inc; +ALTER FUNCTION f1 SQL SECURITY INVOKER; +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP FUNCTION IF EXISTS f1; +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP FUNCTION IF EXISTS f2; +source include/kill_query.inc; +source include/diff_master_slave.inc; +CREATE PROCEDURE p2 (OUT rows INT) +BEGIN +SELECT COUNT(*) INTO rows FROM t2; +END; +// +source include/kill_query.inc; +source include/diff_master_slave.inc; +ALTER PROCEDURE p1 SQL SECURITY INVOKER COMMENT 'return rows of table t1'; +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP PROCEDURE IF EXISTS p1; +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP PROCEDURE IF EXISTS p2; +source include/kill_query.inc; +source include/diff_master_slave.inc; +CREATE TABLE t2 (b int); +source include/kill_query.inc; +source include/diff_master_slave.inc; +ALTER TABLE t1 ADD (d int); +source include/kill_query.inc; +source include/diff_master_slave.inc; +RENAME TABLE t3 TO t4; +source include/kill_query.inc; +source include/diff_master_slave.inc; +CREATE INDEX i2 on t1 (a); +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP INDEX i1 on t1; +source include/kill_query.inc; +source include/diff_master_slave.inc; +CREATE TRIGGER tr2 BEFORE INSERT ON t4 +FOR EACH ROW BEGIN +DELETE FROM t1 WHERE a=NEW.a; +END; +// +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP TRIGGER tr1; +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP TRIGGER IF EXISTS tr2; +source include/kill_query.inc; +source include/diff_master_slave.inc; +CREATE VIEW v2 AS SELECT a FROM t1 WHERE a > 100; +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP VIEW v1; +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP VIEW IF EXISTS v2; +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP TABLE t1; +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP TABLE IF EXISTS t2; +source include/kill_query.inc; +source include/diff_master_slave.inc; +DROP DATABASE IF EXISTS d1; +DROP DATABASE IF EXISTS d2; +DROP DATABASE IF EXISTS d3; +DROP DATABASE IF EXISTS d4; +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP FUNCTION IF EXISTS f3; +DROP FUNCTION IF EXISTS f4; +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; +DROP TABLE IF EXISTS t4; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +DROP PROCEDURE IF EXISTS p3; +DROP PROCEDURE IF EXISTS p4; diff --git a/mysql-test/t/rpl_killed_ddl-master.opt b/mysql-test/t/rpl_killed_ddl-master.opt new file mode 100644 index 00000000000..aaf2d8a4251 --- /dev/null +++ b/mysql-test/t/rpl_killed_ddl-master.opt @@ -0,0 +1 @@ +--debug=d,debug_lock_before_query_log_event diff --git a/mysql-test/t/rpl_killed_ddl.test b/mysql-test/t/rpl_killed_ddl.test new file mode 100644 index 00000000000..f4f2f6ac320 --- /dev/null +++ b/mysql-test/t/rpl_killed_ddl.test @@ -0,0 +1,271 @@ +# ==== Purpose ==== +# +# This test check if DDL statements are correctly binlogged when the +# thread is killed +# +# ==== Method ==== +# +# Start a DDL query and kill it, check if the error code of the binlog +# event is correct. +# +# DDL statements tested: +# CREATE/ALTER/RENAME/DROP DATABASE +# CREATE/ALTER/DROP FUNCTION +# CREATE/ALTER/DROP PROCEDURE +# CREATE/ALTER/RENAME/DROP TABLE +# CREATE/DROP TRIGGER +# CREATE/ALTER/DROP VIEW +# +# ==== Bugs ===== +# + +source include/have_debug.inc; +source include/master-slave.inc; + +# Use the DBUG_SYNC_POINT to make sure the thread running the DDL is +# waiting before creating the query log event + +let $debug_lock= "debug_lock.before_query_log_event"; + +######## INITIALIZATION ######## + +disable_warnings; +DROP DATABASE IF EXISTS d1; +DROP DATABASE IF EXISTS d2; +DROP DATABASE IF EXISTS d3; +DROP DATABASE IF EXISTS d4; +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP FUNCTION IF EXISTS f3; +DROP FUNCTION IF EXISTS f4; +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; +DROP TABLE IF EXISTS t4; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +DROP PROCEDURE IF EXISTS p3; +DROP PROCEDURE IF EXISTS p4; +DROP TRIGGER IF EXISTS tr1; +DROP TRIGGER IF EXISTS tr2; +DROP TRIGGER IF EXISTS tr3; +DROP TRIGGER IF EXISTS tr4; +enable_warnings; + +CREATE DATABASE d1; + +CREATE FUNCTION f1 () RETURNS INT DETERMINISTIC + RETURN 1; + +DELIMITER //; +CREATE PROCEDURE p1 (OUT rows INT) + BEGIN + SELECT COUNT(*) INTO rows FROM t1; + END; + // +DELIMITER ;// + +CREATE TABLE t1 (a int); +CREATE TABLE t3 (a int); + +DELIMITER //; +CREATE TRIGGER tr1 BEFORE INSERT ON t1 + FOR EACH ROW BEGIN + DELETE FROM t4 WHERE a=NEW.a; + END; + // +DELIMITER ;// + +CREATE INDEX i1 ON t1 (a); + +CREATE VIEW v1 AS SELECT a FROM t1 WHERE a < 100; + +sync_slave_with_master; + +connection master1; +let $connection_name= master1; +let $connection_id= `SELECT CONNECTION_ID()`; + +connection master; +echo [on master]; + +# This will block the execution of a statement at the DBUG_SYNC_POINT +# with given lock name +if (`SELECT '$debug_lock' != ''`) +{ + disable_query_log; + disable_result_log; + eval SELECT IS_FREE_LOCK($debug_lock); + eval SELECT GET_LOCK($debug_lock, 10); + eval SELECT IS_FREE_LOCK($debug_lock); + enable_query_log; + enable_result_log; +} + +######## START TEST ######## + +connection master1; +echo [on master1]; + +disable_warnings; + +######## DATABASE ######## + +let $diff_statement= SHOW DATABASES LIKE 'd%'; + +send CREATE DATABASE d2; +source include/kill_query_and_diff_master_slave.inc; + +send ALTER DATABASE d1 + DEFAULT CHARACTER SET = 'utf8'; +source include/kill_query_and_diff_master_slave.inc; + +send DROP DATABASE d1; +source include/kill_query_and_diff_master_slave.inc; + +send DROP DATABASE d2; +source include/kill_query_and_diff_master_slave.inc; + +######## FUNCTION ######## + +let $diff_statement= SHOW FUNCTION STATUS LIKE 'f%'; + +send CREATE FUNCTION f2 () RETURNS INT DETERMINISTIC + RETURN 1; +source include/kill_query_and_diff_master_slave.inc; + +send ALTER FUNCTION f1 SQL SECURITY INVOKER; +source include/kill_query_and_diff_master_slave.inc; + +# function f1 probably does not exist because the ALTER query was +# killed +send DROP FUNCTION IF EXISTS f1; +source include/kill_query_and_diff_master_slave.inc; + +# function f2 probably does not exist because the CREATE query was +# killed +send DROP FUNCTION IF EXISTS f2; +source include/kill_query_and_diff_master_slave.inc; + +######## PROCEDURE ######## + +let $diff_statement= SHOW PROCEDURE STATUS LIKE 'p%'; + +DELIMITER //; +send CREATE PROCEDURE p2 (OUT rows INT) + BEGIN + SELECT COUNT(*) INTO rows FROM t2; + END; + // +DELIMITER ;// +source include/kill_query_and_diff_master_slave.inc; + +send ALTER PROCEDURE p1 SQL SECURITY INVOKER COMMENT 'return rows of table t1'; +source include/kill_query_and_diff_master_slave.inc; + +send DROP PROCEDURE IF EXISTS p1; +source include/kill_query_and_diff_master_slave.inc; + +send DROP PROCEDURE IF EXISTS p2; +source include/kill_query_and_diff_master_slave.inc; + +######## TABLE ######## + +let $diff_statement= SHOW TABLES LIKE 't%'; + +send CREATE TABLE t2 (b int); +source include/kill_query_and_diff_master_slave.inc; + +send ALTER TABLE t1 ADD (d int); +source include/kill_query_and_diff_master_slave.inc; + +send RENAME TABLE t3 TO t4; +source include/kill_query_and_diff_master_slave.inc; + +######## INDEX ######## + +let $diff_statement= SHOW INDEX FROM t1; + +send CREATE INDEX i2 on t1 (a); +source include/kill_query_and_diff_master_slave.inc; + +send DROP INDEX i1 on t1; +source include/kill_query_and_diff_master_slave.inc; + +######## TRIGGER ######## + +let $diff_statement= SHOW TRIGGERS LIKE 'v%'; + +DELIMITER //; +send CREATE TRIGGER tr2 BEFORE INSERT ON t4 + FOR EACH ROW BEGIN + DELETE FROM t1 WHERE a=NEW.a; + END; + // +DELIMITER ;// +source include/kill_query_and_diff_master_slave.inc; + +send DROP TRIGGER tr1; +source include/kill_query_and_diff_master_slave.inc; + +send DROP TRIGGER IF EXISTS tr2; +source include/kill_query_and_diff_master_slave.inc; + +######## VIEW ######## + +let $diff_statement= SHOW TABLES LIKE 'v%'; + +send CREATE VIEW v2 AS SELECT a FROM t1 WHERE a > 100; +source include/kill_query_and_diff_master_slave.inc; + +send DROP VIEW v1; +source include/kill_query_and_diff_master_slave.inc; + +send DROP VIEW IF EXISTS v2; +source include/kill_query_and_diff_master_slave.inc; + +######## DROP TABLE ######## + +# Because of BUG#43529, we cannot use the DBUG_SYNC_POINT for DROP +# TABLE statements on 5.0 +connection master; +disable_query_log; +disable_result_log; +eval SELECT RELEASE_LOCK($debug_lock); +enable_result_log; +enable_query_log; +let $debug_lock=; + +connection master1; + +let $diff_statement= SHOW TABLES LIKE 't%'; + +send DROP TABLE t1; +source include/kill_query_and_diff_master_slave.inc; + +send DROP TABLE IF EXISTS t2; +source include/kill_query_and_diff_master_slave.inc; + +######## CLEAN UP ######## + +# The DROP statements above are killed during the process, so they +# does not make sure the objects are dropped. + +disable_warnings; +DROP DATABASE IF EXISTS d1; +DROP DATABASE IF EXISTS d2; +DROP DATABASE IF EXISTS d3; +DROP DATABASE IF EXISTS d4; +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP FUNCTION IF EXISTS f3; +DROP FUNCTION IF EXISTS f4; +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; +DROP TABLE IF EXISTS t4; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +DROP PROCEDURE IF EXISTS p3; +DROP PROCEDURE IF EXISTS p4; +enable_warnings; diff --git a/sql/item_func.cc b/sql/item_func.cc index 47e16a1bcc3..e7e75ecd020 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3377,6 +3377,10 @@ longlong Item_master_pos_wait::val_int() } #ifdef EXTRA_DEBUG +/** + This will release the user lock that the thread currently locked, + please see also the comment of DEBUG_SYNC_POINT. +*/ void debug_sync_point(const char* lock_name, uint lock_timeout) { THD* thd=current_thd; diff --git a/sql/log.cc b/sql/log.cc index d979dd101e0..b16303ee232 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -158,7 +158,8 @@ static int binlog_commit(THD *thd, bool all) */ if (all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { - Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE); + Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), + TRUE, FALSE, THD::KILLED_NO_VALUE); qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE) DBUG_RETURN(binlog_end_trans(thd, trans_log, &qev)); } @@ -202,7 +203,8 @@ static int binlog_rollback(THD *thd, bool all) */ if (unlikely(thd->transaction.all.modified_non_trans_table)) { - Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE); + Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), + TRUE, FALSE, THD::KILLED_NO_VALUE); qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE) error= binlog_end_trans(thd, trans_log, &qev); } @@ -240,7 +242,8 @@ static int binlog_savepoint_set(THD *thd, void *sv) *(my_off_t *)sv= my_b_tell(trans_log); /* Write it to the binary log */ - Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + TRUE, FALSE, THD::KILLED_NO_VALUE); DBUG_RETURN(mysql_bin_log.write(&qinfo)); } @@ -257,7 +260,8 @@ static int binlog_savepoint_rollback(THD *thd, void *sv) */ if (unlikely(thd->transaction.all.modified_non_trans_table)) { - Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + TRUE, FALSE, THD::KILLED_NO_VALUE); DBUG_RETURN(mysql_bin_log.write(&qinfo)); } reinit_io_cache(trans_log, WRITE_CACHE, *(my_off_t *)sv, 0, 0); @@ -2089,7 +2093,8 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) transaction is either a BEGIN..COMMIT block or a single statement in autocommit mode. */ - Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE); + Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), + TRUE, FALSE, THD::KILLED_NO_VALUE); /* Imagine this is rollback due to net timeout, after all statements of the transaction succeeded. Then we want a diff --git a/sql/log_event.cc b/sql/log_event.cc index c4cdfc27fa0..7856e1458ef 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1358,6 +1358,9 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, { time_t end_time; + DBUG_EXECUTE_IF("debug_lock_before_query_log_event", + DBUG_SYNC_POINT("debug_lock.before_query_log_event", 10);); + if (killed_status_arg == THD::KILLED_NO_VALUE) killed_status_arg= thd_arg->killed; error_code= diff --git a/sql/log_event.h b/sql/log_event.h index 6ccbf8e4d5c..45e3d11b48c 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -813,9 +813,13 @@ public: #ifndef MYSQL_CLIENT + /* + for argument killed_err_arg, use ` THD::NOT_KILLED ' if the killed + status should be ignored, otherwise use `THD::KILLED_NO_VALUE' + */ Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, bool using_trans, bool suppress_use, - THD::killed_state killed_err_arg= THD::KILLED_NO_VALUE); + THD::killed_state killed_err_arg); const char* get_db() { return db; } #ifdef HAVE_REPLICATION void pack_info(Protocol* protocol); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b855af9a8d3..37ba0611ee0 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -451,6 +451,13 @@ MY_LOCALE *my_locale_by_number(uint number); The client tells the server to block with SELECT GET_LOCK() and unblocks it with SELECT RELEASE_LOCK(). Used for debugging difficult concurrency problems + + NOTE: This will release the user lock that the thread currently + locked, which can cause problem if users want to use user locks for + other purposes. In order to overcome this problem, it's adviced to + wrap the call to DBUG_SYNC_POINT() within the DBUG_EXECUTE_IF(), so + that it will only be activated if the given keyword is included in + the 'debug' option, and will not fiddle user locks otherwise. */ #define DBUG_SYNC_POINT(lock_name,lock_timeout) \ debug_sync_point(lock_name,lock_timeout) diff --git a/sql/sp.cc b/sql/sp.cc index 3af51b82521..2450e9564d0 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -646,7 +646,7 @@ db_create_routine(THD *thd, int type, sp_head *sp) /* Such a statement can always go directly to binlog, no trans cache */ Query_log_event qinfo(thd, log_query.c_ptr(), log_query.length(), 0, - FALSE); + FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } @@ -680,7 +680,8 @@ db_drop_routine(THD *thd, int type, sp_name *name) if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } } @@ -725,7 +726,8 @@ db_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index b51d97e66c5..7da52458f26 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1601,7 +1601,8 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, if (need_binlog_call && thd->binlog_evt_union.unioned_events) { Query_log_event qinfo(thd, binlog_buf.ptr(), binlog_buf.length(), - thd->binlog_evt_union.unioned_events_trans, FALSE); + thd->binlog_evt_union.unioned_events_trans, + FALSE, THD::KILLED_NO_VALUE); if (mysql_bin_log.write(&qinfo) && thd->binlog_evt_union.unioned_events_trans) { diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index b2d0304f007..f61304a1e26 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1506,7 +1506,8 @@ bool change_password(THD *thd, const char *host, const char *user, acl_user->host.hostname ? acl_user->host.hostname : "", new_password)); thd->clear_error(); - Query_log_event qinfo(thd, buff, query_length, 0, FALSE); + Query_log_event qinfo(thd, buff, query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } end: @@ -3014,7 +3015,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } } @@ -3181,7 +3183,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } } @@ -3294,7 +3297,8 @@ bool mysql_grant(THD *thd, const char *db, List &list, if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } } @@ -5404,7 +5408,8 @@ bool mysql_create_user(THD *thd, List &list) if (some_users_created && mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } @@ -5473,7 +5478,8 @@ bool mysql_drop_user(THD *thd, List &list) if (some_users_deleted && mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } @@ -5553,7 +5559,8 @@ bool mysql_rename_user(THD *thd, List &list) if (some_users_renamed && mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } @@ -5731,7 +5738,8 @@ bool mysql_revoke_all(THD *thd, List &list) if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0cf3e023be9..8f60c02a08c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -793,18 +793,9 @@ void close_temporary_tables(THD *thd) thd->variables.character_set_client= system_charset_info; Query_log_event qinfo(thd, s_query.ptr(), s_query.length() - 1 /* to remove trailing ',' */, - 0, FALSE); + 0, FALSE, THD::NOT_KILLED); thd->variables.character_set_client= cs_save; - /* - Imagine the thread had created a temp table, then was doing a SELECT, and - the SELECT was killed. Then it's not clever to mark the statement above as - "killed", because it's not really a statement updating data, and there - are 99.99% chances it will succeed on slave. - If a real update (one updating a persistent table) was killed on the - master, then this real update will be logged with error_code=killed, - rightfully causing the slave to stop. - */ - qinfo.error_code= 0; + DBUG_ASSERT(qinfo.error_code == 0); mysql_bin_log.write(&qinfo); } else @@ -2578,7 +2569,8 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, { end = strxmov(strmov(query, "DELETE FROM `"), db,"`.`",name,"`", NullS); - Query_log_event qinfo(thd, query, (ulong)(end-query), 0, FALSE); + Query_log_event qinfo(thd, query, (ulong)(end-query), + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); my_free(query, MYF(0)); } diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 80fea3ef1b1..be538783458 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -70,7 +70,7 @@ static byte* dboptions_get_key(my_dbopt_t *opt, uint *length, static inline void write_to_binlog(THD *thd, char *query, uint q_len, char *db, uint db_len) { - Query_log_event qinfo(thd, query, q_len, 0, 0); + Query_log_event qinfo(thd, query, q_len, 0, 0, THD::NOT_KILLED); qinfo.error_code= 0; qinfo.db= db; qinfo.db_len= db_len; @@ -562,7 +562,7 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, query, query_length, 0, - /* suppress_use */ TRUE); + /* suppress_use */ TRUE, THD::NOT_KILLED); /* Write should use the database being created as the "current @@ -645,7 +645,7 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0, - /* suppress_use */ TRUE); + /* suppress_use */ TRUE, THD::NOT_KILLED); /* Write should use the database being created as the "current @@ -770,7 +770,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, query, query_length, 0, - /* suppress_use */ TRUE); + /* suppress_use */ TRUE, THD::NOT_KILLED); /* Write should use the database being created as the "current database" and not the threads current database, which is the diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 38f89683065..a757b7c28a5 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -730,7 +730,7 @@ void multi_delete::send_error(uint errcode,const char *err) if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, - transactional_tables, FALSE); + transactional_tables, FALSE, THD::KILLED_NO_VALUE); mysql_bin_log.write(&qinfo); } thd->transaction.all.modified_non_trans_table= true; @@ -958,7 +958,7 @@ end: { thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - 0, FALSE); + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } send_ok(thd); // This should return record count diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index b79f979df05..dcee47f6518 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2537,7 +2537,8 @@ bool Delayed_insert::handle_inserts(void) thd.variables.time_zone = row->time_zone; } - Query_log_event qinfo(&thd, row->query, row->query_length, 0, FALSE); + Query_log_event qinfo(&thd, row->query, row->query_length, + 0, FALSE, THD::KILLED_NO_VALUE); mysql_bin_log.write(&qinfo); thd.time_zone_used = backup_time_zone_used; @@ -3099,7 +3100,7 @@ void select_insert::abort() if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, - transactional_table, FALSE); + transactional_table, FALSE, THD::KILLED_NO_VALUE); mysql_bin_log.write(&qinfo); } if (thd->transaction.stmt.modified_non_trans_table) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2297283c92d..a946a6afb35 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3551,7 +3551,8 @@ end_with_restore_list: if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } } @@ -3586,7 +3587,8 @@ end_with_restore_list: if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } } @@ -3612,7 +3614,8 @@ end_with_restore_list: if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } } @@ -4394,7 +4397,8 @@ end_with_restore_list: { if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } } diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index f6766aec285..cec9e4c39de 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -84,7 +84,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } send_ok(thd); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 963a98cfb59..eec6ad626f0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -333,7 +333,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, { if (!error) thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + FALSE, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } } @@ -1814,7 +1815,8 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, if (!internal_tmp_table && mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + FALSE, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } error= FALSE; @@ -2903,7 +2905,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST *src_table, if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + FALSE, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } res= FALSE; @@ -3012,7 +3015,8 @@ mysql_discard_or_import_tablespace(THD *thd, goto err; if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + FALSE, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } err: @@ -3168,7 +3172,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } send_ok(thd); @@ -3360,7 +3365,8 @@ view_err: if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + FALSE, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } send_ok(thd); @@ -3872,7 +3878,8 @@ view_err: if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + FALSE, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } goto end_temporary; @@ -4007,7 +4014,8 @@ view_err: if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + FALSE, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } broadcast_refresh(); diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 930e3601699..d2ae494d4eb 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -304,7 +304,7 @@ end: /* Such a statement can always go directly to binlog, no trans cache. */ Query_log_event qinfo(thd, stmt_query.ptr(), stmt_query.length(), 0, - FALSE); + FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 8a3f5bcdc26..0da0b6e6635 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1575,7 +1575,7 @@ void multi_update::send_error(uint errcode,const char *err) into repl event. */ Query_log_event qinfo(thd, thd->query, thd->query_length, - transactional_tables, FALSE); + transactional_tables, FALSE, THD::KILLED_NO_VALUE); mysql_bin_log.write(&qinfo); } thd->transaction.all.modified_non_trans_table= TRUE; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 9e0fa87d5f5..9e1e2a20dc6 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -655,7 +655,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, else if (views->with_check == VIEW_CHECK_CASCADED) buff.append(STRING_WITH_LEN(" WITH CASCADED CHECK OPTION")); - Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE); + Query_log_event qinfo(thd, buff.ptr(), buff.length(), + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } @@ -1544,7 +1545,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) { if (!something_wrong) thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + Query_log_event qinfo(thd, thd->query, thd->query_length, + 0, FALSE, THD::NOT_KILLED); mysql_bin_log.write(&qinfo); } From 9b09ac249ca41000505395d57f3f03e0ead64fa2 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 31 Mar 2009 16:04:02 +0200 Subject: [PATCH 06/85] Apply 64-bit fix from Azundris. --- mysys/safemalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 36d07b475e9..c484f1d4c54 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -174,7 +174,7 @@ void *_mymalloc(size_t size, const char *filename, uint lineno, myf MyFlags) data[size + 3]= MAGICEND3; irem->filename= (char *) filename; irem->linenum= lineno; - irem->datasize= (uint32) size; + irem->datasize= size; irem->prev= NULL; /* Add this remember structure to the linked list */ From 5c2ba04cba0091e46aba5bb8a47f0cd3dcf73341 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 1 Apr 2009 22:18:49 +0200 Subject: [PATCH 07/85] Add new headers to noinst_HEADERS (ibmdb2i storage engine) --- storage/ibmdb2i/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/ibmdb2i/Makefile.am b/storage/ibmdb2i/Makefile.am index 2436a764429..768ca15f4cf 100644 --- a/storage/ibmdb2i/Makefile.am +++ b/storage/ibmdb2i/Makefile.am @@ -27,6 +27,7 @@ DEFS = @DEFS@ noinst_HEADERS = ha_ibmdb2i.h db2i_collationSupport.h db2i_file.h \ db2i_ioBuffers.h db2i_blobCollection.h \ db2i_global.h db2i_misc.h db2i_charsetSupport.h db2i_errors.h \ + db2i_iconv.h db2i_myconv.h db2i_safeString.h db2i_sqlStatementStream.h \ db2i_ileBridge.h db2i_validatedPointer.h EXTRA_LTLIBRARIES = ha_ibmdb2i.la From 79650ae64133a3eba5f2e10575de56aa4b555226 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 2 Apr 2009 13:17:38 +0200 Subject: [PATCH 08/85] Apply http://lists.mysql.com/commits/70427 to fix Win32 builds with VS 2005. --- include/config-win.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/config-win.h b/include/config-win.h index 26b08a5e4fb..3a21551ebbb 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -63,9 +63,6 @@ functions */ #endif #ifndef __WIN32__ #define __WIN32__ -#define _INTEGRAL_MAX_BITS 32 -#else -#define _INTEGRAL_MAX_BITS 64 #endif #endif /* _WIN64 */ #ifndef __WIN__ From 668d988c71a7980b3f131feb51c24427cfd78082 Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Thu, 2 Apr 2009 11:29:28 -0400 Subject: [PATCH 09/85] Bug#43876: mysqld_multi introduces --no-defaults which screws up my system Bug#32136: mysqld_multi --defaults-file not respected while using \ --mysqld=mysqld_safe Revert change that adds "--no-defaults" to mysqld_multi. This closes Bug#43508 and re-opens Bug#32136. --- scripts/mysqld_multi.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index 631e1e38cc7..3cb4665eb1c 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -293,12 +293,7 @@ sub start_mysqlds() @groups = &find_groups($groupids); for ($i = 0; defined($groups[$i]); $i++) { - # Defaults are made explicit parameters to server execution... @options = defaults_for_group($groups[$i]); - # ...so server MUST NOT try to read again from some config file, especially - # as the "right" file may be unknown to the server if we are using - # --defaults-file=... params in here. - unshift(@options,"--no-defaults"); $mysqld_found= 1; # The default $mysqld_found= 0 if (!length($mysqld)); From 4fda8858b16ebb41262e8e4944e204ece83aaec9 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Thu, 2 Apr 2009 18:34:18 -0400 Subject: [PATCH 10/85] Bug#43716: Test mysqlbinlog_row_big is failing, needs to be updated Altered the test to accommodate the new behavior of max_allowed_packet. Had to disconnect / reconnect the default connection for the new value to register. Re-enabled certain parts of the test that were commented out and added some setup / cleanup code to ensure proper reset of max_allowed_packet at the end of the test. Re-recorded the .result file to account for changes to the test. --- mysql-test/r/mysqlbinlog_row_big.result | 48 ++++++++++++++++----- mysql-test/t/mysqlbinlog_row_big.test | 56 +++++++++++++++++-------- 2 files changed, 77 insertions(+), 27 deletions(-) diff --git a/mysql-test/r/mysqlbinlog_row_big.result b/mysql-test/r/mysqlbinlog_row_big.result index f2ca72f9936..46fa0dc79cd 100644 --- a/mysql-test/r/mysqlbinlog_row_big.result +++ b/mysql-test/r/mysqlbinlog_row_big.result @@ -9,7 +9,17 @@ SET timestamp=1000000000; # # We need big packets. # +# Capture initial value to reset at the end of the test +# Now adjust max_allowed_packet SET @@global.max_allowed_packet= 1024*1024*1024; +max_allowed_packet is a global variable. +In order for the preceding change in max_allowed_packets' value +to be seen and used, we must start a new connection. +The change does not take effect with the current one. +For simplicity, we just disconnect / reconnect connection default here. +Disconnecting default connection... +Reconnecting default connection... +default connection established, continuing with the test # # Delete all existing binary logs. # @@ -21,40 +31,56 @@ CREATE TABLE t1 ( c1 LONGTEXT ) ENGINE=MyISAM DEFAULT CHARSET latin1; # -# Show how much rows are affected by each statement. +# Show how many rows are affected by each statement. # # -# Insert a big row. +# Insert some big rows. # +256MB +INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 16777216)); +affected rows: 1 +32MB INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 2097152)); affected rows: 1 +4MB +INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 262144)); +affected rows: 1 +512KB +INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 32768)); +affected rows: 1 # # Show what we have in the table. # Do not display the column value itself, just its length. # SELECT LENGTH(c1) FROM t1; +LENGTH(c1) 268435456 LENGTH(c1) 33554432 -affected rows: 1 +LENGTH(c1) 4194304 +LENGTH(c1) 524288 +affected rows: 4 # -# Grow the row by updating. +# Grow the rows by updating. # UPDATE t1 SET c1 = CONCAT(c1, c1); -affected rows: 1 -info: Rows matched: 1 Changed: 1 Warnings: 0 +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 # # Show what we have in the table. # Do not display the column value itself, just its length. # SELECT LENGTH(c1) FROM t1; +LENGTH(c1) 536870912 +LENGTH(c1) 1048576 LENGTH(c1) 67108864 -affected rows: 1 +LENGTH(c1) 8388608 +affected rows: 4 # -# Delete the row. +# Delete the rows. # DELETE FROM t1 WHERE c1 >= 'ManyMegaByteBlck'; -affected rows: 1 +affected rows: 4 # -# Hide how much rows are affected by each statement. +# Hide how many rows are affected by each statement. # # # Flush all log buffers to the log file. @@ -70,5 +96,7 @@ FLUSH LOGS; # # Cleanup. # +# reset variable value to pass testcase checks +SET @@global.max_allowed_packet = 1048576; DROP TABLE t1; remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_big_1.out diff --git a/mysql-test/t/mysqlbinlog_row_big.test b/mysql-test/t/mysqlbinlog_row_big.test index 14e818e7214..75f3b90269f 100644 --- a/mysql-test/t/mysqlbinlog_row_big.test +++ b/mysql-test/t/mysqlbinlog_row_big.test @@ -38,8 +38,26 @@ SET timestamp=1000000000; --echo # --echo # We need big packets. --echo # +--echo # Capture initial value to reset at the end of the test +# use let $ = query_get_value as FLUSH statements +# in the test will set @ values to NULL +let $orig_max_allowed_packet = +query_get_value(SELECT @@global.max_allowed_packet, @@global.max_allowed_packet, 1); + +--echo # Now adjust max_allowed_packet SET @@global.max_allowed_packet= 1024*1024*1024; +--echo max_allowed_packet is a global variable. +--echo In order for the preceding change in max_allowed_packets' value +--echo to be seen and used, we must start a new connection. +--echo The change does not take effect with the current one. +--echo For simplicity, we just disconnect / reconnect connection default here. +--echo Disconnecting default connection... +disconnect default; +--echo Reconnecting default connection... +connect (default, localhost,root,,); +--echo default connection established, continuing with the test + --echo # --echo # Delete all existing binary logs. --echo # @@ -53,34 +71,35 @@ eval CREATE TABLE t1 ( ) ENGINE=$engine_type DEFAULT CHARSET latin1; --echo # ---echo # Show how much rows are affected by each statement. +--echo # Show how many rows are affected by each statement. --echo # --enable_info --echo # ---echo # Insert a big row. +--echo # Insert some big rows. --echo # -# -# 256MB -#INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 16777216)); -# -# 32MB + +--echo 256MB +INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 16777216)); + +--echo 32MB INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 2097152)); -# -# 4MB -#INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 262144)); -# -# 512KB -#INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 32768)); + +--echo 4MB +INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 262144)); + +--echo 512KB +INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 32768)); --echo # --echo # Show what we have in the table. --echo # Do not display the column value itself, just its length. --echo # +--sorted_result query_vertical SELECT LENGTH(c1) FROM t1; --echo # ---echo # Grow the row by updating. +--echo # Grow the rows by updating. --echo # UPDATE t1 SET c1 = CONCAT(c1, c1); @@ -88,15 +107,16 @@ UPDATE t1 SET c1 = CONCAT(c1, c1); --echo # Show what we have in the table. --echo # Do not display the column value itself, just its length. --echo # +--sorted_result query_vertical SELECT LENGTH(c1) FROM t1; --echo # ---echo # Delete the row. +--echo # Delete the rows. --echo # DELETE FROM t1 WHERE c1 >= 'ManyMegaByteBlck'; --echo # ---echo # Hide how much rows are affected by each statement. +--echo # Hide how many rows are affected by each statement. --echo # --disable_info @@ -113,13 +133,15 @@ FLUSH LOGS; --echo # at the bottom of the test script. --echo # let $MYSQLD_DATADIR= `select @@datadir`; ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_result $MYSQLTEST_VARDIR --replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /Xid = [0-9]*/Xid = #/ --exec $MYSQL_BINLOG -v -v $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/$mysqlbinlog_output --echo # --echo # Cleanup. --echo # +--echo # reset variable value to pass testcase checks +eval SET @@global.max_allowed_packet = $orig_max_allowed_packet; DROP TABLE t1; --echo remove_file \$MYSQLTEST_VARDIR/$mysqlbinlog_output From 33364242bb6f27b87af495ca14c5cd7a22952b00 Mon Sep 17 00:00:00 2001 From: Horst Hunger Date: Fri, 3 Apr 2009 11:37:48 +0200 Subject: [PATCH 11/85] Fix belonging to bug#42838: Though this bug is only for 6.0 I put in some updated result files for 6.0 and this are the corrsponding resul files for 5.1, so that sys_vars should then run successfully also in 5.1. --- .../r/binlog_cache_size_basic_64.result | 2 +- .../r/bulk_insert_buffer_size_basic_64.result | 4 +++ .../r/delayed_insert_limit_basic_64.result | 2 +- .../r/delayed_queue_size_basic_64.result | 2 +- .../r/join_buffer_size_basic_64.result | 4 +-- .../r/key_buffer_size_basic_64.result | 2 -- .../sys_vars/r/log_warnings_basic_64.result | 4 +++ .../r/max_binlog_cache_size_basic_64.result | 6 ++-- .../r/max_connect_errors_basic_64.result | 4 +-- .../r/max_heap_table_size_basic_64.result | 6 ++-- .../r/max_seeks_for_key_basic_64.result | 4 +-- .../sys_vars/r/max_tmp_tables_basic_64.result | 8 ++--- .../r/max_write_lock_count_basic_64.result | 4 +-- .../r/min_examined_row_limit_basic_64.result | 4 +++ .../r/multi_range_count_basic_64.result | 4 +-- .../myisam_max_sort_file_size_basic_64.result | 8 ++++- .../r/myisam_repair_threads_basic_64.result | 4 +-- .../r/myisam_sort_buffer_size_basic_64.result | 4 +-- .../r/net_retry_count_basic_64.result | 4 +-- .../r/query_alloc_block_size_basic_64.result | 4 +-- .../r/query_cache_limit_basic_64.result | 4 +++ .../query_cache_min_res_unit_basic_64.result | 4 +++ .../r/query_cache_size_basic_64.result | 4 +++ .../r/query_prealloc_size_basic_64.result | 34 +++---------------- .../r/range_alloc_block_size_basic_64.result | 4 +-- .../r/rpl_recovery_rank_basic_64.result | 6 ++++ .../slave_transaction_retries_basic_64.result | 2 ++ .../sys_vars/r/sync_binlog_basic_64.result | 4 +++ ...ansaction_alloc_block_size_basic_64.result | 2 +- .../transaction_prealloc_size_basic_64.result | 2 +- .../sys_vars/r/wait_timeout_basic_64.result | 2 +- 31 files changed, 84 insertions(+), 68 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/binlog_cache_size_basic_64.result b/mysql-test/suite/sys_vars/r/binlog_cache_size_basic_64.result index 45ed43589a3..3858df0f4d6 100644 --- a/mysql-test/suite/sys_vars/r/binlog_cache_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/binlog_cache_size_basic_64.result @@ -44,7 +44,7 @@ SET @@global.binlog_cache_size = 10000.01; ERROR 42000: Incorrect argument type to variable 'binlog_cache_size' SET @@global.binlog_cache_size = -1024; Warnings: -Warning 1292 Truncated incorrect binlog_cache_size value: '0' +Warning 1292 Truncated incorrect binlog_cache_size value: '-1024' SELECT @@global.binlog_cache_size; @@global.binlog_cache_size 4096 diff --git a/mysql-test/suite/sys_vars/r/bulk_insert_buffer_size_basic_64.result b/mysql-test/suite/sys_vars/r/bulk_insert_buffer_size_basic_64.result index 9e0e8e07470..320290fbca1 100644 --- a/mysql-test/suite/sys_vars/r/bulk_insert_buffer_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/bulk_insert_buffer_size_basic_64.result @@ -66,6 +66,8 @@ SELECT @@global.bulk_insert_buffer_size; @@global.bulk_insert_buffer_size 42949672950 SET @@global.bulk_insert_buffer_size = -1024; +Warnings: +Warning 1292 Truncated incorrect bulk_insert_buffer_size value: '-1024' SELECT @@global.bulk_insert_buffer_size; @@global.bulk_insert_buffer_size 0 @@ -80,6 +82,8 @@ SELECT @@session.bulk_insert_buffer_size; @@session.bulk_insert_buffer_size 42949672950 SET @@session.bulk_insert_buffer_size = -2; +Warnings: +Warning 1292 Truncated incorrect bulk_insert_buffer_size value: '-2' SELECT @@session.bulk_insert_buffer_size; @@session.bulk_insert_buffer_size 0 diff --git a/mysql-test/suite/sys_vars/r/delayed_insert_limit_basic_64.result b/mysql-test/suite/sys_vars/r/delayed_insert_limit_basic_64.result index 246bf0e8734..1f7d0a52e72 100644 --- a/mysql-test/suite/sys_vars/r/delayed_insert_limit_basic_64.result +++ b/mysql-test/suite/sys_vars/r/delayed_insert_limit_basic_64.result @@ -35,7 +35,7 @@ SELECT @@global.delayed_insert_limit; 1 SET @@global.delayed_insert_limit = -1024; Warnings: -Warning 1292 Truncated incorrect delayed_insert_limit value: '0' +Warning 1292 Truncated incorrect delayed_insert_limit value: '-1024' SELECT @@global.delayed_insert_limit; @@global.delayed_insert_limit 1 diff --git a/mysql-test/suite/sys_vars/r/delayed_queue_size_basic_64.result b/mysql-test/suite/sys_vars/r/delayed_queue_size_basic_64.result index d575626b0a1..ed866b7e0b4 100644 --- a/mysql-test/suite/sys_vars/r/delayed_queue_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/delayed_queue_size_basic_64.result @@ -35,7 +35,7 @@ SELECT @@global.delayed_queue_size; 1 SET @@global.delayed_queue_size = -1024; Warnings: -Warning 1292 Truncated incorrect delayed_queue_size value: '0' +Warning 1292 Truncated incorrect delayed_queue_size value: '-1024' SELECT @@global.delayed_queue_size; @@global.delayed_queue_size 1 diff --git a/mysql-test/suite/sys_vars/r/join_buffer_size_basic_64.result b/mysql-test/suite/sys_vars/r/join_buffer_size_basic_64.result index ed652af67d2..4811d4732df 100644 --- a/mysql-test/suite/sys_vars/r/join_buffer_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/join_buffer_size_basic_64.result @@ -71,7 +71,7 @@ SELECT @@global.join_buffer_size=8200 OR @@global.join_buffer_size= 8228; 1 SET @@global.join_buffer_size = -1024; Warnings: -Warning 1292 Truncated incorrect join_buffer_size value: '0' +Warning 1292 Truncated incorrect join_buffer_size value: '-1024' SELECT @@global.join_buffer_size=8200 OR @@global.join_buffer_size= 8228; @@global.join_buffer_size=8200 OR @@global.join_buffer_size= 8228 1 @@ -103,7 +103,7 @@ SELECT @@session.join_buffer_size=8200 OR @@session.join_buffer_size= 8228; 1 SET @@session.join_buffer_size = -2; Warnings: -Warning 1292 Truncated incorrect join_buffer_size value: '0' +Warning 1292 Truncated incorrect join_buffer_size value: '-2' SELECT @@session.join_buffer_size=8200 OR @@session.join_buffer_size= 8228; @@session.join_buffer_size=8200 OR @@session.join_buffer_size= 8228 1 diff --git a/mysql-test/suite/sys_vars/r/key_buffer_size_basic_64.result b/mysql-test/suite/sys_vars/r/key_buffer_size_basic_64.result index 9ce1ab20993..eea782701bb 100644 --- a/mysql-test/suite/sys_vars/r/key_buffer_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/key_buffer_size_basic_64.result @@ -17,8 +17,6 @@ SELECT @@global.key_buffer_size BETWEEN 8 AND 36; @@global.key_buffer_size BETWEEN 8 AND 36 1 SET @@global.key_buffer_size = 1800; -Warnings: -Warning 1292 Truncated incorrect key_buffer_size value: '1800' SELECT @@global.key_buffer_size BETWEEN 8 AND 36; @@global.key_buffer_size BETWEEN 8 AND 36 1 diff --git a/mysql-test/suite/sys_vars/r/log_warnings_basic_64.result b/mysql-test/suite/sys_vars/r/log_warnings_basic_64.result index ba6671c87a4..6a94881dad0 100644 --- a/mysql-test/suite/sys_vars/r/log_warnings_basic_64.result +++ b/mysql-test/suite/sys_vars/r/log_warnings_basic_64.result @@ -74,6 +74,8 @@ SELECT @@global.log_warnings; @@global.log_warnings 100000000000 SET @@global.log_warnings = -1024; +Warnings: +Warning 1292 Truncated incorrect log_warnings value: '-1024' SELECT @@global.log_warnings; @@global.log_warnings 0 @@ -92,6 +94,8 @@ SELECT @@session.log_warnings; @@session.log_warnings 100000000000 SET @@session.log_warnings = -2; +Warnings: +Warning 1292 Truncated incorrect log_warnings value: '-2' SELECT @@session.log_warnings; @@session.log_warnings 0 diff --git a/mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic_64.result b/mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic_64.result index 30db3f14dd4..10a42f6ab0e 100644 --- a/mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic_64.result @@ -1,7 +1,7 @@ SET @start_value = @@global.max_binlog_cache_size; SELECT @start_value; @start_value -18446744073709551615 +18446744073709547520 '#--------------------FN_DYNVARS_072_01------------------------#' SET @@global.max_binlog_cache_size = 5000; SET @@global.max_binlog_cache_size = DEFAULT; @@ -39,7 +39,7 @@ SELECT @@global.max_binlog_cache_size; '#--------------------FN_DYNVARS_072_04-------------------------#' SET @@global.max_binlog_cache_size = -1; Warnings: -Warning 1292 Truncated incorrect max_binlog_cache_size value: '0' +Warning 1292 Truncated incorrect max_binlog_cache_size value: '-1' SELECT @@global.max_binlog_cache_size; @@global.max_binlog_cache_size 4096 @@ -54,7 +54,7 @@ SELECT @@global.max_binlog_cache_size; 99999997952 SET @@global.max_binlog_cache_size = -1024; Warnings: -Warning 1292 Truncated incorrect max_binlog_cache_size value: '0' +Warning 1292 Truncated incorrect max_binlog_cache_size value: '-1024' SELECT @@global.max_binlog_cache_size; @@global.max_binlog_cache_size 4096 diff --git a/mysql-test/suite/sys_vars/r/max_connect_errors_basic_64.result b/mysql-test/suite/sys_vars/r/max_connect_errors_basic_64.result index 8117b650651..762cfd14a3a 100644 --- a/mysql-test/suite/sys_vars/r/max_connect_errors_basic_64.result +++ b/mysql-test/suite/sys_vars/r/max_connect_errors_basic_64.result @@ -39,7 +39,7 @@ SELECT @@global.max_connect_errors; '#--------------------FN_DYNVARS_073_04-------------------------#' SET @@global.max_connect_errors = -1; Warnings: -Warning 1292 Truncated incorrect max_connect_errors value: '0' +Warning 1292 Truncated incorrect max_connect_errors value: '-1' SELECT @@global.max_connect_errors; @@global.max_connect_errors 1 @@ -54,7 +54,7 @@ SELECT @@global.max_connect_errors; 100000000000 SET @@global.max_connect_errors = -1024; Warnings: -Warning 1292 Truncated incorrect max_connect_errors value: '0' +Warning 1292 Truncated incorrect max_connect_errors value: '-1024' SELECT @@global.max_connect_errors; @@global.max_connect_errors 1 diff --git a/mysql-test/suite/sys_vars/r/max_heap_table_size_basic_64.result b/mysql-test/suite/sys_vars/r/max_heap_table_size_basic_64.result index ebab80f376b..6642b6024b5 100644 --- a/mysql-test/suite/sys_vars/r/max_heap_table_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/max_heap_table_size_basic_64.result @@ -73,13 +73,13 @@ SELECT @@session.max_heap_table_size; '#------------------FN_DYNVARS_077_05-----------------------#' SET @@global.max_heap_table_size = -1; Warnings: -Warning 1292 Truncated incorrect max_heap_table_size value: '0' +Warning 1292 Truncated incorrect max_heap_table_size value: '-1' SELECT @@global.max_heap_table_size; @@global.max_heap_table_size 16384 SET @@global.max_heap_table_size = -1024; Warnings: -Warning 1292 Truncated incorrect max_heap_table_size value: '0' +Warning 1292 Truncated incorrect max_heap_table_size value: '-1024' SELECT @@global.max_heap_table_size; @@global.max_heap_table_size 16384 @@ -111,7 +111,7 @@ SELECT @@global.max_heap_table_size; 4294967296 SET @@session.max_heap_table_size = -1; Warnings: -Warning 1292 Truncated incorrect max_heap_table_size value: '0' +Warning 1292 Truncated incorrect max_heap_table_size value: '-1' SELECT @@session.max_heap_table_size; @@session.max_heap_table_size 16384 diff --git a/mysql-test/suite/sys_vars/r/max_seeks_for_key_basic_64.result b/mysql-test/suite/sys_vars/r/max_seeks_for_key_basic_64.result index eefb829cdae..5b1e076c188 100644 --- a/mysql-test/suite/sys_vars/r/max_seeks_for_key_basic_64.result +++ b/mysql-test/suite/sys_vars/r/max_seeks_for_key_basic_64.result @@ -77,7 +77,7 @@ SELECT @@global.max_seeks_for_key; 1 SET @@global.max_seeks_for_key = -1024; Warnings: -Warning 1292 Truncated incorrect max_seeks_for_key value: '0' +Warning 1292 Truncated incorrect max_seeks_for_key value: '-1024' SELECT @@global.max_seeks_for_key; @@global.max_seeks_for_key 1 @@ -103,7 +103,7 @@ SELECT @@session.max_seeks_for_key; 1 SET @@session.max_seeks_for_key = -2; Warnings: -Warning 1292 Truncated incorrect max_seeks_for_key value: '0' +Warning 1292 Truncated incorrect max_seeks_for_key value: '-2' SELECT @@session.max_seeks_for_key; @@session.max_seeks_for_key 1 diff --git a/mysql-test/suite/sys_vars/r/max_tmp_tables_basic_64.result b/mysql-test/suite/sys_vars/r/max_tmp_tables_basic_64.result index 4b9f68c509e..808e99b739d 100644 --- a/mysql-test/suite/sys_vars/r/max_tmp_tables_basic_64.result +++ b/mysql-test/suite/sys_vars/r/max_tmp_tables_basic_64.result @@ -71,7 +71,7 @@ SELECT @@session.max_tmp_tables; '#------------------FN_DYNVARS_086_05-----------------------#' SET @@global.max_tmp_tables = -1024; Warnings: -Warning 1292 Truncated incorrect max_tmp_tables value: '0' +Warning 1292 Truncated incorrect max_tmp_tables value: '-1024' SELECT @@global.max_tmp_tables; @@global.max_tmp_tables 1 @@ -81,7 +81,7 @@ SELECT @@global.max_tmp_tables; 4294967296 SET @@global.max_tmp_tables = -1; Warnings: -Warning 1292 Truncated incorrect max_tmp_tables value: '0' +Warning 1292 Truncated incorrect max_tmp_tables value: '-1' SELECT @@global.max_tmp_tables; @@global.max_tmp_tables 1 @@ -105,7 +105,7 @@ SELECT @@session.max_tmp_tables; 4294967296 SET @@session.max_tmp_tables = -1; Warnings: -Warning 1292 Truncated incorrect max_tmp_tables value: '0' +Warning 1292 Truncated incorrect max_tmp_tables value: '-1' SELECT @@session.max_tmp_tables; @@session.max_tmp_tables 1 @@ -115,7 +115,7 @@ SELECT @@session.max_tmp_tables; 429496729500 SET @@session.max_tmp_tables = -001; Warnings: -Warning 1292 Truncated incorrect max_tmp_tables value: '0' +Warning 1292 Truncated incorrect max_tmp_tables value: '-1' SELECT @@session.max_tmp_tables; @@session.max_tmp_tables 1 diff --git a/mysql-test/suite/sys_vars/r/max_write_lock_count_basic_64.result b/mysql-test/suite/sys_vars/r/max_write_lock_count_basic_64.result index d74586841dd..934777e38d3 100644 --- a/mysql-test/suite/sys_vars/r/max_write_lock_count_basic_64.result +++ b/mysql-test/suite/sys_vars/r/max_write_lock_count_basic_64.result @@ -37,7 +37,7 @@ SELECT @@global.max_write_lock_count; '#------------------FN_DYNVARS_088_04-----------------------#' SET @@global.max_write_lock_count = -1024; Warnings: -Warning 1292 Truncated incorrect max_write_lock_count value: '0' +Warning 1292 Truncated incorrect max_write_lock_count value: '-1024' SELECT @@global.max_write_lock_count; @@global.max_write_lock_count 1 @@ -47,7 +47,7 @@ SELECT @@global.max_write_lock_count; 4294967296 SET @@global.max_write_lock_count = -1; Warnings: -Warning 1292 Truncated incorrect max_write_lock_count value: '0' +Warning 1292 Truncated incorrect max_write_lock_count value: '-1' SELECT @@global.max_write_lock_count; @@global.max_write_lock_count 1 diff --git a/mysql-test/suite/sys_vars/r/min_examined_row_limit_basic_64.result b/mysql-test/suite/sys_vars/r/min_examined_row_limit_basic_64.result index fa11659c6c5..5cf77ed6dc8 100644 --- a/mysql-test/suite/sys_vars/r/min_examined_row_limit_basic_64.result +++ b/mysql-test/suite/sys_vars/r/min_examined_row_limit_basic_64.result @@ -82,6 +82,8 @@ SELECT @@global.min_examined_row_limit; @@global.min_examined_row_limit 429496726 SET @@global.min_examined_row_limit = -1024; +Warnings: +Warning 1292 Truncated incorrect min_examined_row_limit value: '-1024' SELECT @@global.min_examined_row_limit; @@global.min_examined_row_limit 0 @@ -104,6 +106,8 @@ SELECT @@session.min_examined_row_limit; @@session.min_examined_row_limit 4294967296 SET @@session.min_examined_row_limit = -1; +Warnings: +Warning 1292 Truncated incorrect min_examined_row_limit value: '-1' SELECT @@session.min_examined_row_limit; @@session.min_examined_row_limit 0 diff --git a/mysql-test/suite/sys_vars/r/multi_range_count_basic_64.result b/mysql-test/suite/sys_vars/r/multi_range_count_basic_64.result index f2115aec2e2..29019ca5971 100644 --- a/mysql-test/suite/sys_vars/r/multi_range_count_basic_64.result +++ b/mysql-test/suite/sys_vars/r/multi_range_count_basic_64.result @@ -81,7 +81,7 @@ SELECT @@global.multi_range_count; 4294967296 SET @@global.multi_range_count = -1024; Warnings: -Warning 1292 Truncated incorrect multi_range_count value: '0' +Warning 1292 Truncated incorrect multi_range_count value: '-1024' SELECT @@global.multi_range_count; @@global.multi_range_count 1 @@ -111,7 +111,7 @@ SELECT @@session.multi_range_count; 4294967296 SET @@session.multi_range_count = -1; Warnings: -Warning 1292 Truncated incorrect multi_range_count value: '0' +Warning 1292 Truncated incorrect multi_range_count value: '-1' SELECT @@session.multi_range_count; @@session.multi_range_count 1 diff --git a/mysql-test/suite/sys_vars/r/myisam_max_sort_file_size_basic_64.result b/mysql-test/suite/sys_vars/r/myisam_max_sort_file_size_basic_64.result index 00ff1dfc1ab..df2a49e4dd5 100644 --- a/mysql-test/suite/sys_vars/r/myisam_max_sort_file_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/myisam_max_sort_file_size_basic_64.result @@ -1,7 +1,7 @@ SET @start_global_value = @@global.myisam_max_sort_file_size; SELECT @start_global_value; @start_global_value -9223372036854775807 +9223372036853727232 '#--------------------FN_DYNVARS_094_01-------------------------#' SET @@global.myisam_max_sort_file_size = 500000; SET @@global.myisam_max_sort_file_size = DEFAULT; @@ -48,14 +48,20 @@ SET @@local.myisam_max_sort_file_size = 4; ERROR HY000: Variable 'myisam_max_sort_file_size' is a GLOBAL variable and should be set with SET GLOBAL '#------------------FN_DYNVARS_094_05-----------------------#' SET @@global.myisam_max_sort_file_size = -1; +Warnings: +Warning 1292 Truncated incorrect myisam_max_sort_file_size value: '-1' SELECT @@global.myisam_max_sort_file_size; @@global.myisam_max_sort_file_size 0 SET @@global.myisam_max_sort_file_size = -2147483648; +Warnings: +Warning 1292 Truncated incorrect myisam_max_sort_file_size value: '-2147483648' SELECT @@global.myisam_max_sort_file_size; @@global.myisam_max_sort_file_size 0 SET @@global.myisam_max_sort_file_size = -2147483649; +Warnings: +Warning 1292 Truncated incorrect myisam_max_sort_file_size value: '-2147483649' SELECT @@global.myisam_max_sort_file_size; @@global.myisam_max_sort_file_size 0 diff --git a/mysql-test/suite/sys_vars/r/myisam_repair_threads_basic_64.result b/mysql-test/suite/sys_vars/r/myisam_repair_threads_basic_64.result index 8271451cc9e..0a317d28b11 100644 --- a/mysql-test/suite/sys_vars/r/myisam_repair_threads_basic_64.result +++ b/mysql-test/suite/sys_vars/r/myisam_repair_threads_basic_64.result @@ -61,7 +61,7 @@ SELECT @@global.myisam_repair_threads ; 1 SET @@global.myisam_repair_threads = -1024; Warnings: -Warning 1292 Truncated incorrect myisam_repair_threads value: '0' +Warning 1292 Truncated incorrect myisam_repair_threads value: '-1024' SELECT @@global.myisam_repair_threads ; @@global.myisam_repair_threads 1 @@ -102,7 +102,7 @@ SELECT @@session.myisam_repair_threads ; 1 SET @@session.myisam_repair_threads = -2; Warnings: -Warning 1292 Truncated incorrect myisam_repair_threads value: '0' +Warning 1292 Truncated incorrect myisam_repair_threads value: '-2' SELECT @@session.myisam_repair_threads ; @@session.myisam_repair_threads 1 diff --git a/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_64.result b/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_64.result index bfcada76a46..be9e415d830 100644 --- a/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_64.result @@ -61,7 +61,7 @@ SELECT @@global.myisam_sort_buffer_size ; 4 SET @@global.myisam_sort_buffer_size = -1024; Warnings: -Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '0' +Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '-1024' SELECT @@global.myisam_sort_buffer_size ; @@global.myisam_sort_buffer_size 4 @@ -102,7 +102,7 @@ SELECT @@session.myisam_sort_buffer_size ; 4 SET @@session.myisam_sort_buffer_size = -2; Warnings: -Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '0' +Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '-2' SELECT @@session.myisam_sort_buffer_size ; @@session.myisam_sort_buffer_size 4 diff --git a/mysql-test/suite/sys_vars/r/net_retry_count_basic_64.result b/mysql-test/suite/sys_vars/r/net_retry_count_basic_64.result index db133d23f79..67dae3d1291 100644 --- a/mysql-test/suite/sys_vars/r/net_retry_count_basic_64.result +++ b/mysql-test/suite/sys_vars/r/net_retry_count_basic_64.result @@ -77,7 +77,7 @@ SELECT @@global.net_retry_count; 1 SET @@global.net_retry_count = -1024; Warnings: -Warning 1292 Truncated incorrect net_retry_count value: '0' +Warning 1292 Truncated incorrect net_retry_count value: '-1024' SELECT @@global.net_retry_count; @@global.net_retry_count 1 @@ -107,7 +107,7 @@ SELECT @@session.net_retry_count; 1 SET @@session.net_retry_count = -2; Warnings: -Warning 1292 Truncated incorrect net_retry_count value: '0' +Warning 1292 Truncated incorrect net_retry_count value: '-2' SELECT @@session.net_retry_count; @@session.net_retry_count 1 diff --git a/mysql-test/suite/sys_vars/r/query_alloc_block_size_basic_64.result b/mysql-test/suite/sys_vars/r/query_alloc_block_size_basic_64.result index 57c96a8168a..7c573bdb7cb 100644 --- a/mysql-test/suite/sys_vars/r/query_alloc_block_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/query_alloc_block_size_basic_64.result @@ -78,7 +78,7 @@ SELECT @@global.query_alloc_block_size; 1024 SET @@global.query_alloc_block_size = -1; Warnings: -Warning 1292 Truncated incorrect query_alloc_block_size value: '0' +Warning 1292 Truncated incorrect query_alloc_block_size value: '-1' SELECT @@global.query_alloc_block_size; @@global.query_alloc_block_size 1024 @@ -110,7 +110,7 @@ SELECT @@session.query_alloc_block_size; 1024 SET @@session.query_alloc_block_size = -2; Warnings: -Warning 1292 Truncated incorrect query_alloc_block_size value: '0' +Warning 1292 Truncated incorrect query_alloc_block_size value: '-2' SELECT @@session.query_alloc_block_size; @@session.query_alloc_block_size 1024 diff --git a/mysql-test/suite/sys_vars/r/query_cache_limit_basic_64.result b/mysql-test/suite/sys_vars/r/query_cache_limit_basic_64.result index a592883ef91..7b3e759deb4 100644 --- a/mysql-test/suite/sys_vars/r/query_cache_limit_basic_64.result +++ b/mysql-test/suite/sys_vars/r/query_cache_limit_basic_64.result @@ -32,6 +32,8 @@ SELECT @@global.query_cache_limit; 1048575 '#--------------------FN_DYNVARS_131_04-------------------------#' SET @@global.query_cache_limit = -1; +Warnings: +Warning 1292 Truncated incorrect query_cache_limit value: '-1' SELECT @@global.query_cache_limit; @@global.query_cache_limit 0 @@ -49,6 +51,8 @@ SELECT @@global.query_cache_limit; @@global.query_cache_limit 10240022115 SET @@global.query_cache_limit = -1024; +Warnings: +Warning 1292 Truncated incorrect query_cache_limit value: '-1024' SELECT @@global.query_cache_limit; @@global.query_cache_limit 0 diff --git a/mysql-test/suite/sys_vars/r/query_cache_min_res_unit_basic_64.result b/mysql-test/suite/sys_vars/r/query_cache_min_res_unit_basic_64.result index e1c74d2bbc1..fdbbc71f108 100644 --- a/mysql-test/suite/sys_vars/r/query_cache_min_res_unit_basic_64.result +++ b/mysql-test/suite/sys_vars/r/query_cache_min_res_unit_basic_64.result @@ -42,6 +42,8 @@ SELECT @@global.query_cache_min_res_unit; 1048576 '#--------------------FN_DYNVARS_132_04-------------------------#' SET @@global.query_cache_min_res_unit = -1; +Warnings: +Warning 1292 Truncated incorrect query_cache_min_res_unit value: '-1' SELECT @@global.query_cache_min_res_unit; @@global.query_cache_min_res_unit 512 @@ -59,6 +61,8 @@ SELECT @@global.query_cache_min_res_unit; @@global.query_cache_min_res_unit 512 SET @@global.query_cache_min_res_unit = -1024; +Warnings: +Warning 1292 Truncated incorrect query_cache_min_res_unit value: '-1024' SELECT @@global.query_cache_min_res_unit; @@global.query_cache_min_res_unit 512 diff --git a/mysql-test/suite/sys_vars/r/query_cache_size_basic_64.result b/mysql-test/suite/sys_vars/r/query_cache_size_basic_64.result index 0cc508b169e..c6d7999677f 100644 --- a/mysql-test/suite/sys_vars/r/query_cache_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/query_cache_size_basic_64.result @@ -41,6 +41,8 @@ SELECT @@global.query_cache_size; 1047552 '#--------------------FN_DYNVARS_133_04-------------------------#' SET @@global.query_cache_size = -1; +Warnings: +Warning 1292 Truncated incorrect query_cache_size value: '-1' SELECT @@global.query_cache_size; @@global.query_cache_size 0 @@ -58,6 +60,8 @@ SELECT @@global.query_cache_size; @@global.query_cache_size 0 SET @@global.query_cache_size = -1024; +Warnings: +Warning 1292 Truncated incorrect query_cache_size value: '-1024' SELECT @@global.query_cache_size; @@global.query_cache_size 0 diff --git a/mysql-test/suite/sys_vars/r/query_prealloc_size_basic_64.result b/mysql-test/suite/sys_vars/r/query_prealloc_size_basic_64.result index 0e61fbcd4b5..a16c56f95c5 100644 --- a/mysql-test/suite/sys_vars/r/query_prealloc_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/query_prealloc_size_basic_64.result @@ -35,10 +35,6 @@ SET @@global.query_prealloc_size = 8192; SELECT @@global.query_prealloc_size ; @@global.query_prealloc_size 8192 -SET @@global.query_prealloc_size = 4294967295; -SELECT @@global.query_prealloc_size ; -@@global.query_prealloc_size -4294966272 SET @@global.query_prealloc_size = 655354; SELECT @@global.query_prealloc_size ; @@global.query_prealloc_size @@ -48,10 +44,6 @@ SET @@session.query_prealloc_size = 8192; SELECT @@session.query_prealloc_size ; @@session.query_prealloc_size 8192 -SET @@session.query_prealloc_size = 4294967295; -SELECT @@session.query_prealloc_size ; -@@session.query_prealloc_size -4294966272 SET @@session.query_prealloc_size = 655345; SELECT @@session.query_prealloc_size ; @@session.query_prealloc_size @@ -63,48 +55,32 @@ Warning 1292 Truncated incorrect query_prealloc_size value: '0' SELECT @@global.query_prealloc_size ; @@global.query_prealloc_size 8192 -SET @@global.query_prealloc_size = -1024; -Warnings: -Warning 1292 Truncated incorrect query_prealloc_size value: '0' -SELECT @@global.query_prealloc_size ; -@@global.query_prealloc_size -8192 -SET @@global.query_prealloc_size = 429496729533; -SELECT @@global.query_prealloc_size ; -@@global.query_prealloc_size -429496728576 SET @@global.query_prealloc_size = 65530.34.; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.' at line 1 SELECT @@global.query_prealloc_size ; @@global.query_prealloc_size -429496728576 +8192 SET @@global.query_prealloc_size = test; ERROR 42000: Incorrect argument type to variable 'query_prealloc_size' SELECT @@global.query_prealloc_size ; @@global.query_prealloc_size -429496728576 +8192 SET @@global.query_prealloc_size = "test"; ERROR 42000: Incorrect argument type to variable 'query_prealloc_size' SELECT @@global.query_prealloc_size ; @@global.query_prealloc_size -429496728576 +8192 SET @@global.query_prealloc_size = 'test'; ERROR 42000: Incorrect argument type to variable 'query_prealloc_size' SELECT @@global.query_prealloc_size ; @@global.query_prealloc_size -429496728576 +8192 SET @@global.query_prealloc_size = ON; ERROR 42000: Incorrect argument type to variable 'query_prealloc_size' SELECT @@global.query_prealloc_size ; @@global.query_prealloc_size -429496728576 -SET @@session.query_prealloc_size = 0; -Warnings: -Warning 1292 Truncated incorrect query_prealloc_size value: '0' -SELECT @@session.query_prealloc_size ; -@@session.query_prealloc_size 8192 -SET @@session.query_prealloc_size = -2; +SET @@session.query_prealloc_size = 0; Warnings: Warning 1292 Truncated incorrect query_prealloc_size value: '0' SELECT @@session.query_prealloc_size ; diff --git a/mysql-test/suite/sys_vars/r/range_alloc_block_size_basic_64.result b/mysql-test/suite/sys_vars/r/range_alloc_block_size_basic_64.result index 26ddfdd2bae..29bf939edac 100644 --- a/mysql-test/suite/sys_vars/r/range_alloc_block_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/range_alloc_block_size_basic_64.result @@ -71,7 +71,7 @@ SELECT @@global.range_alloc_block_size; 4096 SET @@global.range_alloc_block_size = -1024; Warnings: -Warning 1292 Truncated incorrect range_alloc_block_size value: '0' +Warning 1292 Truncated incorrect range_alloc_block_size value: '-1024' SELECT @@global.range_alloc_block_size; @@global.range_alloc_block_size 4096 @@ -97,7 +97,7 @@ SELECT @@session.range_alloc_block_size; 4096 SET @@session.range_alloc_block_size = -2; Warnings: -Warning 1292 Truncated incorrect range_alloc_block_size value: '0' +Warning 1292 Truncated incorrect range_alloc_block_size value: '-2' SELECT @@session.range_alloc_block_size; @@session.range_alloc_block_size 4096 diff --git a/mysql-test/suite/sys_vars/r/rpl_recovery_rank_basic_64.result b/mysql-test/suite/sys_vars/r/rpl_recovery_rank_basic_64.result index 74a47fa0f08..9ec34c677e1 100644 --- a/mysql-test/suite/sys_vars/r/rpl_recovery_rank_basic_64.result +++ b/mysql-test/suite/sys_vars/r/rpl_recovery_rank_basic_64.result @@ -45,14 +45,20 @@ SET @@local.rpl_recovery_rank = 4; ERROR HY000: Variable 'rpl_recovery_rank' is a GLOBAL variable and should be set with SET GLOBAL '#------------------FN_DYNVARS_142_04-----------------------#' SET @@global.rpl_recovery_rank = -1; +Warnings: +Warning 1292 Truncated incorrect rpl_recovery_rank value: '-1' SELECT @@global.rpl_recovery_rank; @@global.rpl_recovery_rank 0 SET @@global.rpl_recovery_rank = -2147483648; +Warnings: +Warning 1292 Truncated incorrect rpl_recovery_rank value: '-2147483648' SELECT @@global.rpl_recovery_rank; @@global.rpl_recovery_rank 0 SET @@global.rpl_recovery_rank = -2147483649; +Warnings: +Warning 1292 Truncated incorrect rpl_recovery_rank value: '-2147483649' SELECT @@global.rpl_recovery_rank; @@global.rpl_recovery_rank 0 diff --git a/mysql-test/suite/sys_vars/r/slave_transaction_retries_basic_64.result b/mysql-test/suite/sys_vars/r/slave_transaction_retries_basic_64.result index 9434b14b238..6e0bc659f9e 100644 --- a/mysql-test/suite/sys_vars/r/slave_transaction_retries_basic_64.result +++ b/mysql-test/suite/sys_vars/r/slave_transaction_retries_basic_64.result @@ -55,6 +55,8 @@ SET @@local.slave_transaction_retries = 4; ERROR HY000: Variable 'slave_transaction_retries' is a GLOBAL variable and should be set with SET GLOBAL '#------------------FN_DYNVARS_149_05-----------------------#' SET @@global.slave_transaction_retries = -1; +Warnings: +Warning 1292 Truncated incorrect slave_transaction_retries value: '-1' SELECT @@global.slave_transaction_retries; @@global.slave_transaction_retries 0 diff --git a/mysql-test/suite/sys_vars/r/sync_binlog_basic_64.result b/mysql-test/suite/sys_vars/r/sync_binlog_basic_64.result index ffd1b3fc4f1..d3cc4e2a9c2 100644 --- a/mysql-test/suite/sys_vars/r/sync_binlog_basic_64.result +++ b/mysql-test/suite/sys_vars/r/sync_binlog_basic_64.result @@ -36,6 +36,8 @@ SELECT @@global.sync_binlog; 65536 '#--------------------FN_DYNVARS_168_04-------------------------#' SET @@global.sync_binlog = -1; +Warnings: +Warning 1292 Truncated incorrect sync_binlog value: '-1' SELECT @@global.sync_binlog; @@global.sync_binlog 0 @@ -53,6 +55,8 @@ SELECT @@global.sync_binlog; @@global.sync_binlog 10240022115 SET @@global.sync_binlog = -1024; +Warnings: +Warning 1292 Truncated incorrect sync_binlog value: '-1024' SELECT @@global.sync_binlog; @@global.sync_binlog 0 diff --git a/mysql-test/suite/sys_vars/r/transaction_alloc_block_size_basic_64.result b/mysql-test/suite/sys_vars/r/transaction_alloc_block_size_basic_64.result index c968d6f108c..749df56c60b 100644 --- a/mysql-test/suite/sys_vars/r/transaction_alloc_block_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/transaction_alloc_block_size_basic_64.result @@ -67,7 +67,7 @@ SELECT @@global.transaction_alloc_block_size; 1024 SET @@global.transaction_alloc_block_size = -1024; Warnings: -Warning 1292 Truncated incorrect transaction_alloc_block_size value: '0' +Warning 1292 Truncated incorrect transaction_alloc_block_size value: '-1024' SELECT @@global.transaction_alloc_block_size; @@global.transaction_alloc_block_size 1024 diff --git a/mysql-test/suite/sys_vars/r/transaction_prealloc_size_basic_64.result b/mysql-test/suite/sys_vars/r/transaction_prealloc_size_basic_64.result index 2fb6451372f..3455b9479c0 100644 --- a/mysql-test/suite/sys_vars/r/transaction_prealloc_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/transaction_prealloc_size_basic_64.result @@ -66,7 +66,7 @@ SELECT @@global.transaction_prealloc_size; 1024 SET @@global.transaction_prealloc_size = -1024; Warnings: -Warning 1292 Truncated incorrect transaction_prealloc_size value: '0' +Warning 1292 Truncated incorrect transaction_prealloc_size value: '-1024' SELECT @@global.transaction_prealloc_size; @@global.transaction_prealloc_size 1024 diff --git a/mysql-test/suite/sys_vars/r/wait_timeout_basic_64.result b/mysql-test/suite/sys_vars/r/wait_timeout_basic_64.result index ae03e677e56..c9bffc61b6f 100644 --- a/mysql-test/suite/sys_vars/r/wait_timeout_basic_64.result +++ b/mysql-test/suite/sys_vars/r/wait_timeout_basic_64.result @@ -44,7 +44,7 @@ Warnings: Warning 1292 Truncated incorrect wait_timeout value: '0' SET @@global.wait_timeout = -1024; Warnings: -Warning 1292 Truncated incorrect wait_timeout value: '0' +Warning 1292 Truncated incorrect wait_timeout value: '-1024' 'Bug # 34837: Errors are not coming on assigning invalid values to variable'; SET @@global.wait_timeout = ON; ERROR 42000: Incorrect argument type to variable 'wait_timeout' From 61ce70924c56b2f4b597338344575a8236cf7189 Mon Sep 17 00:00:00 2001 From: Guangbao Ni Date: Fri, 3 Apr 2009 18:21:57 +0000 Subject: [PATCH 12/85] BUG#42640 mysqld crashes when unsafe statements are executed (STRICT_TRANS_TABLESmode) Mysql server crashes because unsafe statements warning is wrongly elevated to error, which is set the error status of Diagnostics_area of the thread in THD::binlog_query(). Yet the caller believes that binary logging shouldn't touch the status, so it will set the status also later by my_ok(), my_error() or my_message() seperately according to the execution result of the statement or transaction. But the status of Diagnostics_area of the thread is allowed to set only once. Fixed to clear the error wrongly set by binary logging, but keep the warning message. --- .../suite/binlog/r/binlog_stm_ps.result | 2 +- .../suite/binlog/r/binlog_unsafe.result | 128 ++++++++++-------- mysql-test/suite/binlog/t/binlog_unsafe.test | 19 +++ mysql-test/suite/rpl/r/rpl_skip_error.result | 2 +- .../suite/rpl/r/rpl_stm_loadfile.result | 4 +- mysql-test/suite/rpl/r/rpl_udf.result | 8 +- sql/sql_class.cc | 6 +- 7 files changed, 105 insertions(+), 64 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_stm_ps.result b/mysql-test/suite/binlog/r/binlog_stm_ps.result index 1cf7429987e..ea7cc6f16df 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_ps.result +++ b/mysql-test/suite/binlog/r/binlog_stm_ps.result @@ -11,7 +11,7 @@ prepare s from "insert into t1 select 100 limit ?"; set @a=100; execute s using @a; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; create table t1 (a int) diff --git a/mysql-test/suite/binlog/r/binlog_unsafe.result b/mysql-test/suite/binlog/r/binlog_unsafe.result index a0809c79fa2..675c327e9e7 100644 --- a/mysql-test/suite/binlog/r/binlog_unsafe.result +++ b/mysql-test/suite/binlog/r/binlog_unsafe.result @@ -10,25 +10,25 @@ INSERT DELAYED INTO t1 VALUES (5); ---- Insert directly ---- INSERT INTO t1 VALUES (@@global.sync_binlog); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. INSERT INTO t1 VALUES (@@session.insert_id); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. INSERT INTO t1 VALUES (@@global.auto_increment_increment); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. INSERT INTO t2 SELECT UUID(); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. INSERT INTO t2 VALUES (@@session.sql_mode); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. INSERT INTO t2 VALUES (@@global.init_slave); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. INSERT INTO t2 VALUES (@@hostname); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. ---- Insert from stored procedure ---- CREATE PROCEDURE proc() BEGIN @@ -42,13 +42,13 @@ INSERT INTO t2 VALUES (@@hostname); END| CALL proc(); Warnings: -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. ---- Insert from stored function ---- CREATE FUNCTION func() RETURNS INT @@ -66,13 +66,13 @@ SELECT func(); func() 0 Warnings: -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. ---- Insert from trigger ---- CREATE TRIGGER trig BEFORE INSERT ON trigger_table @@ -88,14 +88,14 @@ INSERT INTO t2 VALUES (@@hostname); END| INSERT INTO trigger_table VALUES ('bye.'); Warnings: -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. ---- Insert from prepared statement ---- PREPARE p1 FROM 'INSERT INTO t1 VALUES (@@global.sync_binlog)'; PREPARE p2 FROM 'INSERT INTO t1 VALUES (@@session.insert_id)'; @@ -106,25 +106,25 @@ PREPARE p6 FROM 'INSERT INTO t2 VALUES (@@global.init_slave)'; PREPARE p7 FROM 'INSERT INTO t2 VALUES (@@hostname)'; EXECUTE p1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. EXECUTE p2; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. EXECUTE p3; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. EXECUTE p4; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. EXECUTE p5; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. EXECUTE p6; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. EXECUTE p7; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. ---- Insert from nested call of triggers / functions / procedures ---- CREATE PROCEDURE proc1() INSERT INTO trigger_table VALUES ('ha!')| @@ -154,13 +154,13 @@ EXECUTE prep6; func5() 0 Warnings: -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. ==== Variables that should *not* be unsafe ==== INSERT INTO t1 VALUES (@@session.pseudo_thread_id); INSERT INTO t1 VALUES (@@session.pseudo_thread_id); @@ -195,16 +195,16 @@ DROP TABLE t1, t2, t3, trigger_table, trigger_table2; CREATE TABLE t1(a INT, b INT, KEY(a), PRIMARY KEY(b)); INSERT INTO t1 SELECT * FROM t1 LIMIT 1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. REPLACE INTO t1 SELECT * FROM t1 LIMIT 1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. UPDATE t1 SET a=1 LIMIT 1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. DELETE FROM t1 LIMIT 1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. CREATE PROCEDURE p1() BEGIN INSERT INTO t1 SELECT * FROM t1 LIMIT 1; @@ -214,10 +214,10 @@ DELETE FROM t1 LIMIT 1; END| CALL p1(); Warnings: -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. DROP PROCEDURE p1; DROP TABLE t1; DROP TABLE IF EXISTS t1; @@ -225,7 +225,7 @@ CREATE TABLE t1 (a VARCHAR(100), b VARCHAR(100)); INSERT INTO t1 VALUES ('a','b'); UPDATE t1 SET b = '%s%s%s%s%s%s%s%s%s%s%s%s%s%s' WHERE a = 'a' LIMIT 1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. DROP TABLE t1; DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1(i INT PRIMARY KEY); @@ -234,7 +234,7 @@ CREATE TABLE t3(i INT, ch CHAR(50)); "Should issue message Statement is not safe to log in statement format." INSERT INTO t1 SELECT * FROM t2 LIMIT 1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. CREATE FUNCTION func6() RETURNS INT BEGIN @@ -246,7 +246,7 @@ END| "Should issue message Statement is not safe to log in statement format only once" INSERT INTO t3 VALUES(func6(), UUID()); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. "Check whether SET @@SQL_LOG_BIN = 0/1 doesn't work in substatements" CREATE FUNCTION fun_check_log_bin() RETURNS INT BEGIN @@ -259,7 +259,7 @@ SELECT fun_check_log_bin(); fun_check_log_bin() 100 Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. "SQL_LOG_BIN should be ON still" SHOW VARIABLES LIKE "SQL_LOG_BIN"; Variable_name Value @@ -309,4 +309,22 @@ DROP FUNCTION func7; DROP TRIGGER trig; DROP TABLE t1, t2, t3, trigger_table; set @@SESSION.SQL_LOG_BIN = @save_log_bin; +SET @save_sql_mode = @@SESSION.SQL_MODE; +SET @@SESSION.SQL_MODE = STRICT_ALL_TABLES; +CREATE TABLE t1(i INT PRIMARY KEY); +CREATE TABLE t2(i INT PRIMARY KEY); +INSERT INTO t1 SELECT * FROM t2 LIMIT 1; +Warnings: +Note 1592 Statement is not safe to log in statement format. +INSERT INTO t1 VALUES(@@global.sync_binlog); +Warnings: +Note 1592 Statement is not safe to log in statement format. +UPDATE t1 SET i = 999 LIMIT 1; +Warnings: +Note 1592 Statement is not safe to log in statement format. +DELETE FROM t1 LIMIT 1; +Warnings: +Note 1592 Statement is not safe to log in statement format. +DROP TABLE t1, t2; +SET @@SESSION.SQL_MODE = @save_sql_mode; "End of tests" diff --git a/mysql-test/suite/binlog/t/binlog_unsafe.test b/mysql-test/suite/binlog/t/binlog_unsafe.test index 642dc3a46f7..1b0f0a6c30a 100644 --- a/mysql-test/suite/binlog/t/binlog_unsafe.test +++ b/mysql-test/suite/binlog/t/binlog_unsafe.test @@ -46,6 +46,7 @@ # BUG#34732: mysqlbinlog does not print default values for auto_increment variables # BUG#34768: nondeterministic INSERT using LIMIT logged in stmt mode if binlog_format=mixed # BUG#41980, SBL, INSERT .. SELECT .. LIMIT = ERROR, even when @@SQL_LOG_BIN is 0 +# BUG#42640: mysqld crashes when unsafe statements are executed (STRICT_TRANS_TABLES mode) # # ==== Related test cases ==== # @@ -369,4 +370,22 @@ DROP FUNCTION func7; DROP TRIGGER trig; DROP TABLE t1, t2, t3, trigger_table; set @@SESSION.SQL_LOG_BIN = @save_log_bin; + +# +# For BUG#42640: mysqld crashes when unsafe statements are executed (STRICT_TRANS_TABLES mode) +# +SET @save_sql_mode = @@SESSION.SQL_MODE; +SET @@SESSION.SQL_MODE = STRICT_ALL_TABLES; + +CREATE TABLE t1(i INT PRIMARY KEY); +CREATE TABLE t2(i INT PRIMARY KEY); + +INSERT INTO t1 SELECT * FROM t2 LIMIT 1; +INSERT INTO t1 VALUES(@@global.sync_binlog); + +UPDATE t1 SET i = 999 LIMIT 1; +DELETE FROM t1 LIMIT 1; + +DROP TABLE t1, t2; +SET @@SESSION.SQL_MODE = @save_sql_mode; --echo "End of tests" diff --git a/mysql-test/suite/rpl/r/rpl_skip_error.result b/mysql-test/suite/rpl/r/rpl_skip_error.result index b90d8113e8e..205c7785349 100644 --- a/mysql-test/suite/rpl/r/rpl_skip_error.result +++ b/mysql-test/suite/rpl/r/rpl_skip_error.result @@ -76,7 +76,7 @@ create table t1(a int primary key); insert into t1 values (1),(2); delete from t1 where @@server_id=1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. set sql_mode=strict_trans_tables; insert into t1 values (7), (8), (9); [on slave] diff --git a/mysql-test/suite/rpl/r/rpl_stm_loadfile.result b/mysql-test/suite/rpl/r/rpl_stm_loadfile.result index d18befe6e4c..72f58268d5f 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_loadfile.result +++ b/mysql-test/suite/rpl/r/rpl_stm_loadfile.result @@ -10,7 +10,7 @@ CREATE TABLE test.t1 (a INT, blob_column LONGBLOB, PRIMARY KEY(a)); INSERT INTO test.t1 VALUES(1,'test'); UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. create procedure test.p1() begin INSERT INTO test.t1 VALUES(2,'test'); @@ -18,7 +18,7 @@ UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=2; end| CALL test.p1(); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. SELECT * FROM test.t1 ORDER BY blob_column; a blob_column 1 abase diff --git a/mysql-test/suite/rpl/r/rpl_udf.result b/mysql-test/suite/rpl/r/rpl_udf.result index 79a82b5fbc7..56df5b30d93 100644 --- a/mysql-test/suite/rpl/r/rpl_udf.result +++ b/mysql-test/suite/rpl/r/rpl_udf.result @@ -182,19 +182,19 @@ CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=MyISAM; affected rows: 0 INSERT INTO t1 VALUES(myfunc_int(100), myfunc_double(50.00)); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. affected rows: 1 INSERT INTO t1 VALUES(myfunc_int(10), myfunc_double(5.00)); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. affected rows: 1 INSERT INTO t1 VALUES(myfunc_int(200), myfunc_double(25.00)); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. affected rows: 1 INSERT INTO t1 VALUES(myfunc_int(1), myfunc_double(500.00)); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. affected rows: 1 SELECT * FROM t1 ORDER BY sum; sum price diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7f15508caa1..b73822f5a48 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3676,7 +3676,11 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, if (sql_log_bin_toplevel && lex->is_stmt_unsafe() && variables.binlog_format == BINLOG_FORMAT_STMT) { - push_warning(this, MYSQL_ERROR::WARN_LEVEL_WARN, + /* + A warning can be elevated a error when STRICT sql mode. + But we don't want to elevate binlog warning to error here. + */ + push_warning(this, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_BINLOG_UNSAFE_STATEMENT, ER(ER_BINLOG_UNSAFE_STATEMENT)); if (!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED)) From aebaf079d1611532767dd0c9b183ca73a07b6ac9 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 3 Apr 2009 16:11:54 -0300 Subject: [PATCH 13/85] Bug#43230: SELECT ... FOR UPDATE can hang with FLUSH TABLES WITH READ LOCK indefinitely The problem is that a SELECT .. FOR UPDATE statement might open a table and later wait for a impeding global read lock without noticing whether it is holding a table that is being waited upon the the flush phase of the process that took the global read lock. The same problem also affected the following statements: LOCK TABLES .. WRITE UPDATE .. SET (update and multi-table update) TRUNCATE TABLE .. LOAD DATA .. The solution is to make the above statements wait for a impending global read lock before opening the tables. If there is no impending global read lock, the statement raises a temporary protection against global read locks and progresses smoothly towards completion. Important notice: the patch does not try to address all possible cases, only those which are common and can be fixed unintrusively enough for 5.0. --- mysql-test/r/lock_multi.result | 55 ++++++++++++++ mysql-test/t/lock_multi.test | 128 +++++++++++++++++++++++++++++++++ sql/sql_lex.cc | 1 + sql/sql_lex.h | 16 +++++ sql/sql_parse.cc | 26 ++++++- sql/sql_yacc.yy | 7 +- 6 files changed, 231 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index d1b50a0080c..037b375fe0b 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -133,3 +133,58 @@ ALTER TABLE t1 ADD COLUMN a INT; # 2.2.1. normal mode # 2.2.2. PS mode DROP TABLE t1; +create table t1 (a int); +create table t2 like t1; +# con1 +lock tables t1 write; +# con2 +flush tables with read lock; +# con5 +# global read lock is taken +# con3 +select * from t2 for update; +# waiting for release of read lock +# con4 +# would hang and later cause a deadlock +flush tables t2; +# clean up +unlock tables; +unlock tables; +a +drop table t1,t2; +# +# Lightweight version: +# Ensure that the wait for a GRL is done before opening tables. +# +create table t1 (a int); +create table t2 like t1; +# +# UPDATE +# +# default +flush tables with read lock; +# con1 +update t2 set a = 1; +# default +# statement is waiting for release of read lock +# con2 +flush table t2; +# default +unlock tables; +# con1 +# +# LOCK TABLES .. WRITE +# +# default +flush tables with read lock; +# con1 +lock tables t2 write; +# default +# statement is waiting for release of read lock +# con2 +flush table t2; +# default +unlock tables; +# con1 +unlock tables; +drop table t1,t2; diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index 6c3c942b046..fa6af85f29c 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -683,6 +683,134 @@ DROP TABLE t1; --disconnect locker --disconnect writer +# +# Bug#43230: SELECT ... FOR UPDATE can hang with FLUSH TABLES WITH READ LOCK indefinitely +# + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); +connect (con3,localhost,root,,); +connect (con4,localhost,root,,); +connect (con5,localhost,root,,); + +create table t1 (a int); +create table t2 like t1; + +connection con1; +--echo # con1 +lock tables t1 write; +connection con2; +--echo # con2 +send flush tables with read lock; +connection con5; +--echo # con5 +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Flushing tables'; +--source include/wait_show_condition.inc +--echo # global read lock is taken +connection con3; +--echo # con3 +send select * from t2 for update; +connection con5; +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Waiting for release of readlock'; +--source include/wait_show_condition.inc +--echo # waiting for release of read lock +connection con4; +--echo # con4 +--echo # would hang and later cause a deadlock +flush tables t2; +connection con1; +--echo # clean up +unlock tables; +connection con2; +--reap +unlock tables; +connection con3; +--reap +connection default; +disconnect con5; +disconnect con4; +disconnect con3; +disconnect con2; +disconnect con1; + +drop table t1,t2; + +--echo # +--echo # Lightweight version: +--echo # Ensure that the wait for a GRL is done before opening tables. +--echo # + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +create table t1 (a int); +create table t2 like t1; + +--echo # +--echo # UPDATE +--echo # + +connection default; +--echo # default +flush tables with read lock; +connection con1; +--echo # con1 +send update t2 set a = 1; +connection default; +--echo # default +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Waiting for release of readlock'; +--source include/wait_show_condition.inc +--echo # statement is waiting for release of read lock +connection con2; +--echo # con2 +flush table t2; +connection default; +--echo # default +unlock tables; +connection con1; +--echo # con1 +--reap + +--echo # +--echo # LOCK TABLES .. WRITE +--echo # + +connection default; +--echo # default +flush tables with read lock; +connection con1; +--echo # con1 +send lock tables t2 write; +connection default; +--echo # default +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Waiting for release of readlock'; +--source include/wait_show_condition.inc +--echo # statement is waiting for release of read lock +connection con2; +--echo # con2 +flush table t2; +connection default; +--echo # default +unlock tables; +connection con1; +--echo # con1 +--reap +unlock tables; + +connection default; +disconnect con2; +disconnect con1; + +drop table t1,t2; + # End of 5.0 tests # Wait till all disconnects are completed diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 4c53772bc25..da31106648a 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -204,6 +204,7 @@ void lex_start(THD *thd) lex->nest_level=0 ; lex->allow_sum_func= 0; lex->in_sum_func= NULL; + lex->protect_against_global_read_lock= FALSE; DBUG_VOID_RETURN; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 9f020f4adc5..3e762581e04 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1176,6 +1176,22 @@ typedef struct st_lex : public Query_tables_list bool escape_used; + /* + Special case for SELECT .. FOR UPDATE and LOCK TABLES .. WRITE. + + Protect from a impending GRL as otherwise the thread might deadlock + if it starts waiting for the GRL in mysql_lock_tables. + + The protection is needed because there is a race between setting + the global read lock and waiting for all open tables to be closed. + The problem is a circular wait where a thread holding "old" open + tables will wait for the global read lock to be released while the + thread holding the global read lock will wait for all "old" open + tables to be closed -- the flush part of flush tables with read + lock. + */ + bool protect_against_global_read_lock; + st_lex(); virtual ~st_lex() diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ba887486aa1..02030ac2e19 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2800,6 +2800,10 @@ mysql_execute_command(THD *thd) if (res) goto error; + if (!thd->locked_tables && lex->protect_against_global_read_lock && + !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) + goto error; + if (!(res= open_and_lock_tables(thd, all_tables))) { if (lex->describe) @@ -3660,6 +3664,9 @@ end_with_restore_list: DBUG_ASSERT(first_table == all_tables && first_table != 0); if (update_precheck(thd, all_tables)) break; + if (!thd->locked_tables && + !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) + goto error; DBUG_ASSERT(select_lex->offset_limit == 0); unit->set_limit(select_lex); res= (up_result= mysql_update(thd, all_tables, @@ -3686,6 +3693,15 @@ end_with_restore_list: else res= 0; + /* + Protection might have already been risen if its a fall through + from the SQLCOM_UPDATE case above. + */ + if (!thd->locked_tables && + lex->sql_command == SQLCOM_UPDATE_MULTI && + !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) + goto error; + res= mysql_multi_update_prepare(thd); #ifdef HAVE_REPLICATION @@ -3853,7 +3869,8 @@ end_with_restore_list: ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); goto error; } - + if (!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) + goto error; res= mysql_truncate(thd, first_table, 0); break; case SQLCOM_DELETE: @@ -4027,6 +4044,10 @@ end_with_restore_list: if (check_one_table_access(thd, privilege, all_tables)) goto error; + if (!thd->locked_tables && + !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) + goto error; + res= mysql_load(thd, lex->exchange, first_table, lex->field_list, lex->update_list, lex->value_list, lex->duplicates, lex->ignore, (bool) lex->local_file); @@ -4082,6 +4103,9 @@ end_with_restore_list: goto error; if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, 0)) goto error; + if (lex->protect_against_global_read_lock && + !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) + goto error; thd->in_lock_tables=1; thd->options|= OPTION_TABLE_LOCK; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 51fb5dbdfe4..b36c65854d7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4522,6 +4522,7 @@ select_lock_type: LEX *lex=Lex; lex->current_select->set_lock_for_tables(TL_WRITE); lex->safe_to_cache_query=0; + lex->protect_against_global_read_lock= TRUE; } | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM { @@ -10058,8 +10059,12 @@ table_lock_list: table_lock: table_ident opt_table_alias lock_option { - if (!Select->add_table_to_list(YYTHD, $1, $2, 0, (thr_lock_type) $3)) + thr_lock_type lock_type= (thr_lock_type) $3; + if (!Select->add_table_to_list(YYTHD, $1, $2, 0, lock_type)) MYSQL_YYABORT; + /* If table is to be write locked, protect from a impending GRL. */ + if (lock_type >= TL_WRITE_ALLOW_WRITE) + Lex->protect_against_global_read_lock= TRUE; } ; From 2ee7a7cff1a18b68d895a9aaf29993ea81d5a48e Mon Sep 17 00:00:00 2001 From: Serge Kozlov Date: Sat, 4 Apr 2009 01:33:13 +0400 Subject: [PATCH 14/85] Bug#37716. 1. Test case was rewritten completely. 2. Test covers 3 cases: a) do deadlock on slave, wait retries of transaction, unlock slave before lock timeout; b) do deadlock on slave and wait error 'lock timeout exceed' on slave; c) same as b) but if of max relay log size = 0; 3. Added comments inline. 4. Updated result file. --- mysql-test/extra/rpl_tests/rpl_deadlock.test | 199 +++++++-------- mysql-test/include/wait_for_status_var.inc | 68 ++++++ .../suite/rpl/r/rpl_deadlock_innodb.result | 230 ++++++++++-------- 3 files changed, 290 insertions(+), 207 deletions(-) create mode 100644 mysql-test/include/wait_for_status_var.inc diff --git a/mysql-test/extra/rpl_tests/rpl_deadlock.test b/mysql-test/extra/rpl_tests/rpl_deadlock.test index 62fe9b2223a..1b331cc948b 100644 --- a/mysql-test/extra/rpl_tests/rpl_deadlock.test +++ b/mysql-test/extra/rpl_tests/rpl_deadlock.test @@ -7,125 +7,126 @@ # (Guilhem) have seen the test manage to provoke lock wait timeout # error but not deadlock error; that is ok as code deals with the two # errors in exactly the same way. -# We don't 'show status like 'slave_retried_transactions'' because this -# is not repeatable (depends on sleeps). --- source include/master-slave.inc +--source include/master-slave.inc + +# 0) Prepare tables and data +--echo *** Prepare tables and data *** connection master; eval CREATE TABLE t1 (a INT NOT NULL, KEY(a)) ENGINE=$engine_type; -eval CREATE TABLE t2 (a INT NOT NULL, KEY(a)) ENGINE=$engine_type; -# requiring 'unique' for the timeout part of the test -eval CREATE TABLE t3 (a INT UNIQUE) ENGINE=$engine_type; -eval CREATE TABLE t4 (a INT) ENGINE=$engine_type; -show variables like 'slave_transaction_retries'; +eval CREATE TABLE t2 (a INT) ENGINE=$engine_type; +eval CREATE TABLE t3 (a INT NOT NULL, KEY(a)) ENGINE=$engine_type; sync_slave_with_master; -show create table t1; -show create table t2; -show variables like 'slave_transaction_retries'; -stop slave; +SHOW CREATE TABLE t1; +SHOW CREATE TABLE t2; +SHOW CREATE TABLE t3; +SHOW VARIABLES LIKE 'slave_transaction_retries'; +--source include/stop_slave.inc + +connection master; +BEGIN; +INSERT INTO t1 VALUES (1); +# We make a long transaction here +INSERT INTO t2 VALUES (2), (2), (2), (2), (2), (2), (2), (2), (2), (2); +INSERT INTO t3 VALUES (3); +COMMIT; +save_master_pos; +# Save BEGIN event into variable +let $master_pos_begin= query_get_value(SHOW BINLOG EVENTS, Pos, 5); +--echo # 1) Test deadlock - -connection master; -begin; -# Let's keep BEGIN and the locked statement in two different relay logs. -insert into t2 values (0); # t2,t1 actors of deadlock in repl-ed ta -#insert into t3 select * from t2 for update; -let $1=10; -disable_query_log; -while ($1) -{ - eval insert into t3 values( $1 ); - dec $1; -} -enable_query_log; -insert into t1 values(1); -commit; -save_master_pos; +# Block slave SQL thread, wait retries of transaction, unlock slave before lock timeout +--echo *** Test deadlock *** connection slave; -begin; -# Let's make our transaction large so that it's repl-ed msta that's victim -let $1=100; -disable_query_log; -while ($1) -{ - eval insert into t4 values( $1 ); - dec $1; -} -enable_query_log; -select * from t1 for update; # t1,t2 on local slave's -start slave; - -# bad option, todo: replicate a non-transactional t_sync with the transaction -# and use wait_until_rows_count macro below ---real_sleep 3 # hope that slave is blocked now -#let $count=11; -#let $table=t_sync; -#--include wait_until_rows_count.inc - -select * from t2 for update /* dl */; # provoke deadlock, repl-ed should be victim -commit; +BEGIN; +SELECT * FROM t1 FOR UPDATE; +# Save variable 'Slave_retried_transactions' before deadlock +let $slave_retried_transactions= query_get_value(SHOW GLOBAL STATUS LIKE 'Slave_retried_transactions', Value, 1); +START SLAVE; +# Wait until SQL thread blocked: variable 'Slave_retried_transactions' will incremented +let $status_var= Slave_retried_transactions; +let $status_var_value= $slave_retried_transactions; +let $status_type= GLOBAL; +let $status_var_comparsion= >; +--source include/wait_for_status_var.inc +SELECT COUNT(*) FROM t2; +COMMIT; sync_with_master; -select * from t1; # check that repl-ed succeeded finally -select * from t2 /* must be 1 */; -# check that no error is reported ---replace_column 1 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 # ---replace_result $MASTER_MYPORT MASTER_MYPORT ---vertical_results -show slave status; ---horizontal_results + +# Check the data +SELECT * FROM t1; +SELECT * FROM t3; +# Check that no error is reported +--source include/show_slave_status2.inc +--echo # 2) Test lock wait timeout +# Block slave and wait lock timeout error +--echo *** Test lock wait timeout *** -stop slave; -delete from t3; -change master to master_log_pos=548; # the BEGIN log event -begin; -select * from t2 for update; # hold lock -start slave; ---real_sleep 10 # repl-ed should have blocked, and be retrying -select count(*) from t3 /* must be zero */; # replaying begins after rollback -commit; +connection slave; +--source include/stop_slave.inc +DELETE FROM t2; +# Set slave position to the BEGIN log event +--replace_result $master_pos_begin MASTER_POS_BEGIN +eval CHANGE MASTER TO MASTER_LOG_POS=$master_pos_begin; +BEGIN; +# Hold lock +SELECT * FROM t1 FOR UPDATE; +# Wait until slave stopped with error 'Lock wait timeout exceeded' +START SLAVE; +let $slave_sql_errno= 1205; +--source include/wait_for_slave_sql_error.inc +SELECT COUNT(*) FROM t2; +COMMIT; +--source include/start_slave.inc sync_with_master; -select * from t1; # check that repl-ed succeeded finally -select * from t2; -# check that no error is reported ---replace_column 1 # 7 # 8 # 9 # 11 # 16 # 22 # 23 # 33 # ---replace_result $MASTER_MYPORT MASTER_MYPORT ---vertical_results -show slave status; ---horizontal_results +# Check data from tables +SELECT * FROM t1; +SELECT * FROM t3; +# Check that no error is reported +--source include/show_slave_status2.inc +--echo -# Now we repeat 2), but with BEGIN in the same relay log as -# COMMIT (to see if seeking into hot log is ok). -set @my_max_relay_log_size= @@global.max_relay_log_size; -set global max_relay_log_size=0; +# 3) Test lock wait timeout and purged relay log +# Set max_relay_log_size=0, block slave and wait lock timeout error. +# Restart slave and check that no erros appear +--echo *** Test lock wait timeout and purged relay logs *** -# This is really copy-paste of 2) of above -stop slave; -delete from t3; -change master to master_log_pos=548; -begin; -select * from t2 for update; -start slave; ---real_sleep 10 -select count(*) from t3 /* must be zero */; # replaying begins after rollback -commit; +connection slave; +SET @my_max_relay_log_size= @@global.max_relay_log_size; +SET global max_relay_log_size=0; +--source include/stop_slave.inc +DELETE FROM t2; +# Set slave position to the BEGIN log event +eval CHANGE MASTER TO MASTER_LOG_POS=$master_pos_begin; +BEGIN; +# Hold lock +SELECT * FROM t1 FOR UPDATE; +# Wait until slave stopped with error 'Lock wait timeout exceeded' +START SLAVE; +let $slave_sql_errno= 1205; +--source include/wait_for_slave_sql_error.inc +SELECT COUNT(*) FROM t2; +COMMIT; +--source include/start_slave.inc sync_with_master; -select * from t1; -select * from t2; ---replace_column 1 # 7 # 8 # 9 # 11 # 16 # 22 # 23 # 33 # 35 # 36 # ---replace_result $MASTER_MYPORT MASTER_MYPORT ---vertical_results -show slave status; ---horizontal_results +# Check data from tables +SELECT * FROM t1; +SELECT * FROM t3; +# Check that no error is reported +--source include/show_slave_status2.inc +--echo +# Clean up +--echo *** Clean up *** connection master; -drop table t1,t2,t3,t4; +DROP TABLE t1,t2,t3; sync_slave_with_master; -set global max_relay_log_size= @my_max_relay_log_size; +SET global max_relay_log_size= @my_max_relay_log_size; --echo End of 5.1 tests diff --git a/mysql-test/include/wait_for_status_var.inc b/mysql-test/include/wait_for_status_var.inc new file mode 100644 index 00000000000..4c168da7f1a --- /dev/null +++ b/mysql-test/include/wait_for_status_var.inc @@ -0,0 +1,68 @@ +# ==== Purpose ==== +# +# Waits until a variable from SHOW STATUS has returned a specified +# value, or until a timeout is reached. +# +# ==== Usage ==== +# +# let $status_var= Threads_connected; +# let $status_var_value= 1; +# --source include/wait_for_status_var.inc +# +# Parameters: +# +# $status_var, $status_var_value +# This macro will wait until the variable of SHOW STATUS +# named $status_var gets the value $status_var_value. See +# the example above. +# +# $status_type= GLOBAL|SESSION +# To specify the type (attribute) of status variable and +# run either SHOW GLOBAL STATUS or SHOW SESSION STATUS. +# +# $status_var_comparsion +# By default, this file waits until $status_var becomes equal to +# $status_var_value. If you want to wait until $status_var +# becomes *unequal* to $status_var_value, set this parameter to the +# string '!=', like this: +# let $status_var_comparsion= !=; +# +# $status_timeout +# The default timeout is 1 minute. You can change the timeout by +# setting $status_timeout. The unit is tenths of seconds. +# + +if (`SELECT STRCMP('$status_type', '') * STRCMP(UPPER('$status_type'), 'SESSION') * STRCMP(UPPER('$status_type'), 'GLOBAL')`) +{ + --echo **** ERROR: Unknown type of variable status_type: allowed values are: SESSION or GLOBAL **** + exit; +} + +let $_status_timeout_counter= $status_timeout; +if (!$_status_timeout_counter) +{ + let $_status_timeout_counter= 600; +} + +let $_status_var_comparsion= $status_var_comparsion; +if (`SELECT '$_status_var_comparsion' = ''`) +{ + let $_status_var_comparsion= =; +} + +let $_show_status_value= query_get_value("SHOW $status_type STATUS LIKE '$status_var'", Value, 1); +while (`SELECT NOT('$_show_status_value' $_status_var_comparsion '$status_var_value')`) +{ + if (!$_status_timeout_counter) + { + --echo **** ERROR: failed while waiting for $status_type $status_var $_status_var_comparison $status_var_value **** + --echo Note: the following output may have changed since the failure was detected + --echo **** Showing STATUS, PROCESSLIST **** + eval SHOW $status_type STATUS LIKE '$status_var'; + SHOW PROCESSLIST; + exit; + } + dec $_status_timeout_counter; + sleep 0.1; + let $_show_status_value= query_get_value("SHOW $status_type STATUS LIKE '$status_var'", Value, 1); +} diff --git a/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result b/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result index 1753fc0cb2d..6c8d35619e5 100644 --- a/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result @@ -4,51 +4,57 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +*** Prepare tables and data *** CREATE TABLE t1 (a INT NOT NULL, KEY(a)) ENGINE=innodb; -CREATE TABLE t2 (a INT NOT NULL, KEY(a)) ENGINE=innodb; -CREATE TABLE t3 (a INT UNIQUE) ENGINE=innodb; -CREATE TABLE t4 (a INT) ENGINE=innodb; -show variables like 'slave_transaction_retries'; -Variable_name Value -slave_transaction_retries 10 -show create table t1; +CREATE TABLE t2 (a INT) ENGINE=innodb; +CREATE TABLE t3 (a INT NOT NULL, KEY(a)) ENGINE=innodb; +SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL, KEY `a` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 -show create table t2; +SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( `a` int(11) NOT NULL, KEY `a` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 -show variables like 'slave_transaction_retries'; +SHOW VARIABLES LIKE 'slave_transaction_retries'; Variable_name Value slave_transaction_retries 2 -stop slave; -begin; -insert into t2 values (0); -insert into t1 values(1); -commit; -begin; -select * from t1 for update; +include/stop_slave.inc +BEGIN; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (2), (2), (2), (2), (2), (2), (2), (2), (2), (2); +INSERT INTO t3 VALUES (3); +COMMIT; + +*** Test deadlock *** +BEGIN; +SELECT * FROM t1 FOR UPDATE; a -start slave; -select * from t2 for update /* dl */; -a -commit; -select * from t1; +START SLAVE; +SELECT COUNT(*) FROM t2; +COUNT(*) +0 +COMMIT; +SELECT * FROM t1; a 1 -select * from t2 /* must be 1 */; +SELECT * FROM t3; a -0 -show slave status; +3 +SHOW SLAVE STATUS; Slave_IO_State # Master_Host 127.0.0.1 Master_User root -Master_Port MASTER_MYPORT +Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 Read_Master_Log_Pos # @@ -83,102 +89,41 @@ Last_IO_Errno # Last_IO_Error # Last_SQL_Errno 0 Last_SQL_Error -stop slave; -delete from t3; -change master to master_log_pos=548; -begin; -select * from t2 for update; + +*** Test lock wait timeout *** +include/stop_slave.inc +DELETE FROM t2; +CHANGE MASTER TO MASTER_LOG_POS=MASTER_POS_BEGIN; +BEGIN; +SELECT * FROM t1 FOR UPDATE; a +1 +START SLAVE; +SELECT COUNT(*) FROM t2; +COUNT(*) 0 -start slave; -select count(*) from t3 /* must be zero */; -count(*) -0 -commit; -select * from t1; +COMMIT; +include/start_slave.inc +SELECT * FROM t1; a 1 1 -select * from t2; +SELECT * FROM t3; a -0 -0 -show slave status; +3 +3 +SHOW SLAVE STATUS; Slave_IO_State # Master_Host 127.0.0.1 Master_User root -Master_Port MASTER_MYPORT +Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 -Slave_IO_Running # -Slave_SQL_Running Yes -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table # -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 0 -Last_Error -Skip_Counter 0 -Exec_Master_Log_Pos # -Relay_Log_Space # -Until_Condition None -Until_Log_File -Until_Log_Pos 0 -Master_SSL_Allowed No -Master_SSL_CA_File -Master_SSL_CA_Path -Master_SSL_Cert -Master_SSL_Cipher -Master_SSL_Key -Seconds_Behind_Master # -Master_SSL_Verify_Server_Cert No -Last_IO_Errno 0 -Last_IO_Error -Last_SQL_Errno 0 -Last_SQL_Error -set @my_max_relay_log_size= @@global.max_relay_log_size; -set global max_relay_log_size=0; -stop slave; -delete from t3; -change master to master_log_pos=548; -begin; -select * from t2 for update; -a -0 -0 -start slave; -select count(*) from t3 /* must be zero */; -count(*) -0 -commit; -select * from t1; -a -1 -1 -1 -select * from t2; -a -0 -0 -0 -show slave status; -Slave_IO_State # -Master_Host 127.0.0.1 -Master_User root -Master_Port MASTER_MYPORT -Connect_Retry 1 -Master_Log_File master-bin.000001 -Read_Master_Log_Pos # -Relay_Log_File # -Relay_Log_Pos # -Relay_Master_Log_File master-bin.000001 -Slave_IO_Running # +Slave_IO_Running Yes Slave_SQL_Running Yes Replicate_Do_DB Replicate_Ignore_DB @@ -206,6 +151,75 @@ Last_IO_Errno # Last_IO_Error # Last_SQL_Errno 0 Last_SQL_Error -drop table t1,t2,t3,t4; -set global max_relay_log_size= @my_max_relay_log_size; + +*** Test lock wait timeout and purged relay logs *** +SET @my_max_relay_log_size= @@global.max_relay_log_size; +SET global max_relay_log_size=0; +include/stop_slave.inc +DELETE FROM t2; +CHANGE MASTER TO MASTER_LOG_POS=440; +BEGIN; +SELECT * FROM t1 FOR UPDATE; +a +1 +1 +START SLAVE; +SELECT COUNT(*) FROM t2; +COUNT(*) +0 +COMMIT; +include/start_slave.inc +SELECT * FROM t1; +a +1 +1 +1 +SELECT * FROM t3; +a +3 +3 +3 +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table # +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno # +Last_IO_Error # +Last_SQL_Errno 0 +Last_SQL_Error + +*** Clean up *** +DROP TABLE t1,t2,t3; +SET global max_relay_log_size= @my_max_relay_log_size; End of 5.1 tests From 1287d8c53a71c583508802a0fb98e92983fea9ed Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Sun, 5 Apr 2009 13:03:04 +0100 Subject: [PATCH 15/85] BUG#39393 slave-skip-errors does not work when using ROW based replication RBR was not considering the option --slave-skip-errors. To fix the problem, we are reporting the ignored ERROR(s) as warnings thus avoiding stopping the SQL Thread. Besides, it fixes the output of "SHOW VARIABLES LIKE 'slave_skip_errors'" which was showing nothing when the value "all" was assigned to --slave-skip-errors. @sql/log_event.cc skipped rbr errors when the option skip-slave-errors is set. @sql/slave.cc fixed the output of for SHOW VARIABLES LIKE 'slave_skip_errors'" @test-cases fixed the output of rpl.rpl_idempotency updated the test case rpl_skip_error --- mysql-test/suite/rpl/r/rpl_idempotency.result | 20 +-- mysql-test/suite/rpl/r/rpl_skip_error.result | 92 +++++++++- mysql-test/suite/rpl/t/rpl_idempotency.test | 16 +- mysql-test/suite/rpl/t/rpl_skip_error.test | 115 +++++++++++- sql/log_event.cc | 165 +++++++++++------- sql/slave.cc | 1 + 6 files changed, 315 insertions(+), 94 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_idempotency.result b/mysql-test/suite/rpl/r/rpl_idempotency.result index f39d0f1f37f..3341c03db0f 100644 --- a/mysql-test/suite/rpl/r/rpl_idempotency.result +++ b/mysql-test/suite/rpl/r/rpl_idempotency.result @@ -141,9 +141,9 @@ select * from ti1 order by b /* must be (2),(3) */; b 2 3 -*** slave must stop +*** slave must stop (Trying to delete a referenced foreing key) Last_SQL_Error -0 +1451 select * from ti1 order by b /* must be (1),(2),(3) - not deleted */; b 1 @@ -159,7 +159,7 @@ set global slave_exec_mode='STRICT'; *** conspire future problem delete from ti1 where b=3; insert into ti2 set a=3, b=3 /* offending write event */; -*** slave must stop +*** slave must stop (Trying to insert an invalid foreign key) Last_SQL_Error 1452 select * from ti2 order by b /* must be (2,2) */; @@ -179,7 +179,7 @@ a b *** conspiring query insert into ti1 set b=1; insert into ti1 set b=1 /* offending write event */; -*** slave must stop +*** slave must stop (Trying to insert a dupliacte key) Last_SQL_Error 1062 set foreign_key_checks= 0; @@ -195,32 +195,32 @@ INSERT INTO t2 VALUES (-1),(-2),(-3); DELETE FROM t1 WHERE a = -2; DELETE FROM t2 WHERE a = -2; DELETE FROM t1 WHERE a = -2; -*** slave must stop +*** slave must stop (Key was not found) Last_SQL_Error 1032 set global slave_exec_mode='IDEMPOTENT'; start slave sql_thread; set global slave_exec_mode='STRICT'; DELETE FROM t2 WHERE a = -2; -*** slave must stop +*** slave must stop (Key was not found) Last_SQL_Error -0 +1032 set global slave_exec_mode='IDEMPOTENT'; start slave sql_thread; set global slave_exec_mode='STRICT'; UPDATE t1 SET a = 1 WHERE a = -1; UPDATE t2 SET a = 1 WHERE a = -1; UPDATE t1 SET a = 1 WHERE a = -1; -*** slave must stop +*** slave must stop (Key was not found) Last_SQL_Error 1032 set global slave_exec_mode='IDEMPOTENT'; start slave sql_thread; set global slave_exec_mode='STRICT'; UPDATE t2 SET a = 1 WHERE a = -1; -*** slave must stop +*** slave must stop (Key was not found) Last_SQL_Error -0 +1032 set global slave_exec_mode='IDEMPOTENT'; start slave sql_thread; SET @@global.slave_exec_mode= @old_slave_exec_mode; diff --git a/mysql-test/suite/rpl/r/rpl_skip_error.result b/mysql-test/suite/rpl/r/rpl_skip_error.result index b90d8113e8e..dc02bb783ae 100644 --- a/mysql-test/suite/rpl/r/rpl_skip_error.result +++ b/mysql-test/suite/rpl/r/rpl_skip_error.result @@ -74,19 +74,16 @@ Last_SQL_Error drop table t1; create table t1(a int primary key); insert into t1 values (1),(2); -delete from t1 where @@server_id=1; -Warnings: -Warning 1592 Statement is not safe to log in statement format. +SET SQL_LOG_BIN=0; +delete from t1; +SET SQL_LOG_BIN=1; set sql_mode=strict_trans_tables; -insert into t1 values (7), (8), (9); +insert into t1 values (1), (2), (3); [on slave] select * from t1; a 1 2 -7 -8 -9 SHOW SLAVE STATUS; Slave_IO_State # Master_Host 127.0.0.1 @@ -128,3 +125,84 @@ Last_SQL_Errno 0 Last_SQL_Error ==== Clean Up ==== drop table t1; +==== Using Innodb ==== +SET SQL_LOG_BIN=0; +CREATE TABLE t1(id INT NOT NULL PRIMARY KEY, data INT) Engine=InnoDB; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `data` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SET SQL_LOG_BIN=1; +CREATE TABLE t1(id INT NOT NULL PRIMARY KEY, data INT) Engine=InnoDB; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `data` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES(1, 1); +INSERT INTO t1 VALUES(2, 1); +INSERT INTO t1 VALUES(3, 1); +INSERT INTO t1 VALUES(4, 1); +SET SQL_LOG_BIN=0; +DELETE FROM t1 WHERE id = 4; +SET SQL_LOG_BIN=1; +UPDATE t1 SET id= id + 3, data = 2; + +SELECT *, "INNODB SET SLAVE DATA" FROM t1 ORDER BY id; +id data INNODB SET SLAVE DATA +1 1 INNODB SET SLAVE DATA +2 1 INNODB SET SLAVE DATA +3 1 INNODB SET SLAVE DATA +4 1 INNODB SET SLAVE DATA +SELECT *, "INNODB SET MASTER DATA" FROM t1 ORDER BY id; +id data INNODB SET MASTER DATA +4 2 INNODB SET MASTER DATA +5 2 INNODB SET MASTER DATA +6 2 INNODB SET MASTER DATA +==== Using MyIsam ==== +SET SQL_LOG_BIN=0; +CREATE TABLE t2(id INT NOT NULL PRIMARY KEY, data INT) Engine=MyIsam; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL, + `data` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SET SQL_LOG_BIN=1; +CREATE TABLE t2(id INT NOT NULL PRIMARY KEY, data INT) Engine=MyIsam; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL, + `data` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t2 VALUES(1, 1); +INSERT INTO t2 VALUES(2, 1); +INSERT INTO t2 VALUES(3, 1); +INSERT INTO t2 VALUES(5, 1); +SET SQL_LOG_BIN=0; +DELETE FROM t2 WHERE id = 5; +SET SQL_LOG_BIN=1; +UPDATE t2 SET id= id + 3, data = 2; + +SELECT *, "MYISAM SET SLAVE DATA" FROM t2 ORDER BY id; +id data MYISAM SET SLAVE DATA +2 1 MYISAM SET SLAVE DATA +3 1 MYISAM SET SLAVE DATA +4 2 MYISAM SET SLAVE DATA +5 1 MYISAM SET SLAVE DATA +SELECT *, "MYISAM SET MASTER DATA" FROM t2 ORDER BY id; +id data MYISAM SET MASTER DATA +4 2 MYISAM SET MASTER DATA +5 2 MYISAM SET MASTER DATA +6 2 MYISAM SET MASTER DATA +==== Clean Up ==== +DROP TABLE t1; +DROP TABLE t2; diff --git a/mysql-test/suite/rpl/t/rpl_idempotency.test b/mysql-test/suite/rpl/t/rpl_idempotency.test index 1946aa100ab..bfd1860759e 100644 --- a/mysql-test/suite/rpl/t/rpl_idempotency.test +++ b/mysql-test/suite/rpl/t/rpl_idempotency.test @@ -208,7 +208,7 @@ select * from ti1 order by b /* must be (2),(3) */; # foreign key: row is referenced ---echo *** slave must stop +--echo *** slave must stop (Trying to delete a referenced foreing key) connection slave; source include/wait_for_slave_sql_to_stop.inc; @@ -242,7 +242,7 @@ delete from ti1 where b=3; connection master; insert into ti2 set a=3, b=3 /* offending write event */; ---echo *** slave must stop +--echo *** slave must stop (Trying to insert an invalid foreign key) connection slave; source include/wait_for_slave_sql_to_stop.inc; @@ -281,7 +281,7 @@ insert into ti1 set b=1; connection master; insert into ti1 set b=1 /* offending write event */; ---echo *** slave must stop +--echo *** slave must stop (Trying to insert a dupliacte key) connection slave; source include/wait_for_slave_sql_to_stop.inc; @@ -316,7 +316,7 @@ DELETE FROM t2 WHERE a = -2; connection master; DELETE FROM t1 WHERE a = -2; ---echo *** slave must stop +--echo *** slave must stop (Key was not found) connection slave; source include/wait_for_slave_sql_to_stop.inc; @@ -333,8 +333,8 @@ sync_slave_with_master; set global slave_exec_mode='STRICT'; connection master; -DELETE FROM t2 WHERE a = -2; ---echo *** slave must stop +DELETE FROM t2 WHERE a = -2; +--echo *** slave must stop (Key was not found) connection slave; source include/wait_for_slave_sql_to_stop.inc; @@ -356,7 +356,7 @@ UPDATE t2 SET a = 1 WHERE a = -1; connection master; UPDATE t1 SET a = 1 WHERE a = -1; ---echo *** slave must stop +--echo *** slave must stop (Key was not found) connection slave; source include/wait_for_slave_sql_to_stop.inc; @@ -376,7 +376,7 @@ set global slave_exec_mode='STRICT'; connection master; UPDATE t2 SET a = 1 WHERE a = -1; ---echo *** slave must stop +--echo *** slave must stop (Key was not found) connection slave; source include/wait_for_slave_sql_to_stop.inc; diff --git a/mysql-test/suite/rpl/t/rpl_skip_error.test b/mysql-test/suite/rpl/t/rpl_skip_error.test index cac797d3797..c15d24be9e5 100644 --- a/mysql-test/suite/rpl/t/rpl_skip_error.test +++ b/mysql-test/suite/rpl/t/rpl_skip_error.test @@ -8,18 +8,23 @@ # ==== Method ==== # # We run the slave with --slave-skip-errors=1062 (the code for -# duplicate key). On slave, we insert value 1 in a table, and then, -# on master, we insert value 1 in the table. The error should be -# ignored on slave. -# +# duplicate key). Then we have two set of tests. In the first +# set, we insert value 1 in a table on the slave, and then, on +# master, we insert value 1 in the table. In the second set, we +# insert several values on the master, disable the binlog and +# delete one of the values and re-enable the binlog. Right after, +# we perform an update on the set of values in order to generate +# a duplicate key on the slave. The errors should be ignored on +# the slave. +# # ==== Related bugs ==== # # BUG#28839: Errors in strict mode silently stop SQL thread if --slave-skip-errors exists -# bug in this test: BUG#30594: rpl.rpl_skip_error is nondeterministic +# bug in this test: BUG#30594: rpl.rpl_skip_error is nondeterministic: +# BUG#39393: slave-skip-errors does not work when using ROW based replication source include/master-slave.inc; -source include/have_binlog_format_statement.inc; - +source include/have_innodb.inc; --echo ==== Test Without sql_mode=strict_trans_tables ==== @@ -64,9 +69,11 @@ sync_slave_with_master; connection master; create table t1(a int primary key); insert into t1 values (1),(2); -delete from t1 where @@server_id=1; +SET SQL_LOG_BIN=0; +delete from t1; +SET SQL_LOG_BIN=1; set sql_mode=strict_trans_tables; -insert into t1 values (7), (8), (9); +insert into t1 values (1), (2), (3); --echo [on slave] sync_slave_with_master; @@ -80,3 +87,93 @@ connection master; drop table t1; sync_slave_with_master; # End of 5.0 tests + +# +# BUG#39393: slave-skip-errors does not work when using ROW based replication +# +--echo ==== Using Innodb ==== + +connection master; + +SET SQL_LOG_BIN=0; +CREATE TABLE t1(id INT NOT NULL PRIMARY KEY, data INT) Engine=InnoDB; +SHOW CREATE TABLE t1; +SET SQL_LOG_BIN=1; + +connection slave; + +CREATE TABLE t1(id INT NOT NULL PRIMARY KEY, data INT) Engine=InnoDB; +SHOW CREATE TABLE t1; + +connection master; + +INSERT INTO t1 VALUES(1, 1); +INSERT INTO t1 VALUES(2, 1); +INSERT INTO t1 VALUES(3, 1); +INSERT INTO t1 VALUES(4, 1); + +SET SQL_LOG_BIN=0; +DELETE FROM t1 WHERE id = 4; +SET SQL_LOG_BIN=1; +UPDATE t1 SET id= id + 3, data = 2; + +sync_slave_with_master; + +let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); +echo $error; + +connection slave; + +SELECT *, "INNODB SET SLAVE DATA" FROM t1 ORDER BY id; + +connection master; + +SELECT *, "INNODB SET MASTER DATA" FROM t1 ORDER BY id; + +--echo ==== Using MyIsam ==== + +connection master; + +SET SQL_LOG_BIN=0; +CREATE TABLE t2(id INT NOT NULL PRIMARY KEY, data INT) Engine=MyIsam; +SHOW CREATE TABLE t2; +SET SQL_LOG_BIN=1; + +connection slave; + +CREATE TABLE t2(id INT NOT NULL PRIMARY KEY, data INT) Engine=MyIsam; +SHOW CREATE TABLE t2; + +connection master; + +INSERT INTO t2 VALUES(1, 1); +INSERT INTO t2 VALUES(2, 1); +INSERT INTO t2 VALUES(3, 1); +INSERT INTO t2 VALUES(5, 1); + +SET SQL_LOG_BIN=0; +DELETE FROM t2 WHERE id = 5; +SET SQL_LOG_BIN=1; +UPDATE t2 SET id= id + 3, data = 2; + +sync_slave_with_master; + +let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); +echo $error; + +connection slave; + +SELECT *, "MYISAM SET SLAVE DATA" FROM t2 ORDER BY id; + +connection master; + +SELECT *, "MYISAM SET MASTER DATA" FROM t2 ORDER BY id; + +--echo ==== Clean Up ==== + +connection master; + +DROP TABLE t1; +DROP TABLE t2; + +sync_slave_with_master; diff --git a/sql/log_event.cc b/sql/log_event.cc index aa7e8c84a0f..423174f77d5 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -277,6 +277,47 @@ static void clear_all_errors(THD *thd, Relay_log_info *rli) rli->clear_error(); } +inline int idempotent_error_code(int err_code) +{ + int ret= 0; + + switch (err_code) + { + case 0: + ret= 1; + break; + /* + The following list of "idempotent" errors + means that an error from the list might happen + because of idempotent (more than once) + applying of a binlog file. + Notice, that binlog has a ddl operation its + second applying may cause + + case HA_ERR_TABLE_DEF_CHANGED: + case HA_ERR_CANNOT_ADD_FOREIGN: + + which are not included into to the list. + + Note that HA_ERR_RECORD_DELETED is not in the list since + do_exec_row() should not return that error code. + */ + case HA_ERR_RECORD_CHANGED: + case HA_ERR_KEY_NOT_FOUND: + case HA_ERR_END_OF_FILE: + case HA_ERR_FOUND_DUPP_KEY: + case HA_ERR_FOUND_DUPP_UNIQUE: + case HA_ERR_FOREIGN_DUPLICATE_KEY: + case HA_ERR_NO_REFERENCED_ROW: + case HA_ERR_ROW_IS_REFERENCED: + ret= 1; + break; + default: + ret= 0; + break; + } + return (ret); +} /** Ignore error code specified on command line. @@ -301,14 +342,37 @@ inline int ignored_error_code(int err_code) return ((err_code == ER_SLAVE_IGNORED_TABLE) || (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code))); } -#endif +/* + This function converts an engine's error to a server error. + + If the thread does not have an error already reported, it tries to + define it by calling the engine's method print_error. However, if a + mapping is not found, it uses the ER_UNKNOWN_ERROR and prints out a + warning message. +*/ +int convert_handler_error(int error, THD* thd, TABLE *table) +{ + uint actual_error= (thd->is_error() ? thd->main_da.sql_errno() : + 0); + + if (actual_error == 0) + { + table->file->print_error(error, MYF(0)); + actual_error= (thd->is_error() ? thd->main_da.sql_errno() : + ER_UNKNOWN_ERROR); + if (actual_error == ER_UNKNOWN_ERROR) + if (global_system_variables.log_warnings) + sql_print_warning("Unknown error detected %d in handler", error); + } + + return (actual_error); +} /* pretty_print_str() */ -#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) static char *pretty_print_str(char *packet, const char *str, int len) { const char *end= str + len; @@ -7158,7 +7222,9 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) { /* Error reporting borrowed from Query_log_event with many excessive - simplifications (we don't honour --slave-skip-errors) + simplifications. + We should not honour --slave-skip-errors at this point as we are + having severe errors which should not be skiped. */ rli->report(ERROR_LEVEL, actual_error, "Error '%s' on opening tables", @@ -7184,6 +7250,10 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) { if (ptr->m_tabledef.compatible_with(rli, ptr->table)) { + /* + We should not honour --slave-skip-errors at this point as we are + having severe errors which should not be skiped. + */ mysql_unlock_tables(thd, thd->lock); thd->lock= 0; thd->is_slave_error= 1; @@ -7275,7 +7345,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) // Do event specific preparations error= do_before_row_operations(rli); - // row processing loop while (error == 0 && m_curr_row < m_rows_end) @@ -7291,48 +7360,27 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) DBUG_ASSERT(error != HA_ERR_RECORD_DELETED); table->in_use = old_thd; - switch (error) + + if (error) { - case 0: - break; - /* - The following list of "idempotent" errors - means that an error from the list might happen - because of idempotent (more than once) - applying of a binlog file. - Notice, that binlog has a ddl operation its - second applying may cause + int actual_error= convert_handler_error(error, thd, table); + bool idempotent_error= (idempotent_error_code(error) && + ((bit_is_set(slave_exec_mode, + SLAVE_EXEC_MODE_IDEMPOTENT)) == 1)); + bool ignored_error= (idempotent_error == 0 ? + ignored_error_code(actual_error) : 0); - case HA_ERR_TABLE_DEF_CHANGED: - case HA_ERR_CANNOT_ADD_FOREIGN: - - which are not included into to the list. - - Note that HA_ERR_RECORD_DELETED is not in the list since - do_exec_row() should not return that error code. - */ - case HA_ERR_RECORD_CHANGED: - case HA_ERR_KEY_NOT_FOUND: - case HA_ERR_END_OF_FILE: - case HA_ERR_FOUND_DUPP_KEY: - case HA_ERR_FOUND_DUPP_UNIQUE: - case HA_ERR_FOREIGN_DUPLICATE_KEY: - case HA_ERR_NO_REFERENCED_ROW: - case HA_ERR_ROW_IS_REFERENCED: - - if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1) + if (idempotent_error || ignored_error) { if (global_system_variables.log_warnings) slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table, get_type_str(), RPL_LOG_NAME, (ulong) log_pos); + clear_all_errors(thd, const_cast(rli)); error= 0; + if (idempotent_error == 0) + break; } - break; - - default: - thd->is_slave_error= 1; - break; } /* @@ -7346,7 +7394,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end)); if (!m_curr_row_end && !error) - unpack_current_row(rli); + error= unpack_current_row(rli); // at this moment m_curr_row_end should be set DBUG_ASSERT(error || m_curr_row_end != NULL); @@ -7359,7 +7407,19 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) DBUG_EXECUTE_IF("STOP_SLAVE_after_first_Rows_event", const_cast(rli)->abort_slave= 1;); - error= do_after_row_operations(rli, error); + + if ((error= do_after_row_operations(rli, error)) && + ignored_error_code(convert_handler_error(error, thd, table))) + { + + if (global_system_variables.log_warnings) + slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table, + get_type_str(), + RPL_LOG_NAME, (ulong) log_pos); + clear_all_errors(thd, const_cast(rli)); + error= 0; + } + if (!cache_stmt) { DBUG_PRINT("info", ("Marked that we need to keep log")); @@ -7374,37 +7434,22 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) if (rli->tables_to_lock && get_flags(STMT_END_F)) const_cast(rli)->clear_tables_to_lock(); - if (error) - { /* error has occured during the transaction */ - slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table, - get_type_str(), RPL_LOG_NAME, (ulong) log_pos); - } if (error) { - /* - If one day we honour --skip-slave-errors in row-based replication, and - the error should be skipped, then we would clear mappings, rollback, - close tables, but the slave SQL thread would not stop and then may - assume the mapping is still available, the tables are still open... - So then we should clear mappings/rollback/close here only if this is a - STMT_END_F. - For now we code, knowing that error is not skippable and so slave SQL - thread is certainly going to stop. - rollback at the caller along with sbr. - */ + slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table, + get_type_str(), + RPL_LOG_NAME, (ulong) log_pos); thd->reset_current_stmt_binlog_row_based(); const_cast(rli)->cleanup_context(thd, error); thd->is_slave_error= 1; - DBUG_RETURN(error); } - /* This code would ideally be placed in do_update_pos() instead, but since we have no access to table there, we do the setting of last_event_start_time here instead. */ - if (table && (table->s->primary_key == MAX_KEY) && - !cache_stmt && get_flags(STMT_END_F) == RLE_NO_FLAGS) + else if (table && (table->s->primary_key == MAX_KEY) && + !cache_stmt && get_flags(STMT_END_F) == RLE_NO_FLAGS) { /* ------------ Temporary fix until WL#2975 is implemented --------- @@ -7425,7 +7470,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) const_cast(rli)->last_event_start_time= my_time(0); } - DBUG_RETURN(0); + DBUG_RETURN(error); } Log_event::enum_skip_reason diff --git a/sql/slave.cc b/sql/slave.cc index 8c29cb8a72f..fed53cf605e 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -361,6 +361,7 @@ void init_slave_skip_errors(const char* arg) if (!my_strnncoll(system_charset_info,(uchar*)arg,4,(const uchar*)"all",4)) { bitmap_set_all(&slave_error_mask); + print_slave_skip_errors(); DBUG_VOID_RETURN; } for (p= arg ; *p; ) From 11f44544fcb9c8508c95b75dd4d3ef7ee254588a Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Mon, 6 Apr 2009 13:42:33 +0200 Subject: [PATCH 16/85] Bug#43835: SHOW VARIABLES does not include 0 for slave_skip_errors We didn't expect "error: no error", although this is in fact a legitimate state (if something is erroneous on the master, but not on the slave, e.g. INSERT fails on master due to UNIQUE constraint which does not exist on slave). We now list the ignore for "0: no error" the same way as any other ignore; moreover, if no or an empty --slave-skip-errors is passed at start-up, we show "OFF" instead of empty list, as intended. (The code for that was there, but was only run for the empty- argument case, even if it subsequently tested for both conditions.) --- mysql-test/r/not_embedded_server.result | 3 +++ mysql-test/r/variables-notembedded.result | 6 +++--- mysql-test/t/not_embedded_server.test | 6 ++++++ mysql-test/t/variables-notembedded-master.opt | 2 +- sql/slave.cc | 12 +++++++++++- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/not_embedded_server.result b/mysql-test/r/not_embedded_server.result index 8f7c125196a..60c92bd0196 100644 --- a/mysql-test/r/not_embedded_server.result +++ b/mysql-test/r/not_embedded_server.result @@ -1,3 +1,6 @@ select 1; 1 1 +SHOW VARIABLES like 'slave_skip_errors'; +Variable_name Value +slave_skip_errors OFF diff --git a/mysql-test/r/variables-notembedded.result b/mysql-test/r/variables-notembedded.result index c9125bcee90..8c6d54757ed 100644 --- a/mysql-test/r/variables-notembedded.result +++ b/mysql-test/r/variables-notembedded.result @@ -11,7 +11,7 @@ Variable_name Value slave_load_tmpdir SLAVE_LOAD_TMPDIR show variables like 'slave_skip_errors'; Variable_name Value -slave_skip_errors 3,100,137,643,1752 +slave_skip_errors 0,3,100,137,643,1752 ---- Clean Up ---- set global slave_net_timeout=default; set global sql_slave_skip_counter= 0; @@ -98,12 +98,12 @@ ERROR HY000: Variable 'slave_load_tmpdir' is a read only variable # SHOW VARIABLES like 'slave_skip_errors'; Variable_name Value -slave_skip_errors 3,100,137,643,1752 +slave_skip_errors 0,3,100,137,643,1752 SELECT @@session.slave_skip_errors; ERROR HY000: Variable 'slave_skip_errors' is a GLOBAL variable SELECT @@global.slave_skip_errors; @@global.slave_skip_errors -3,100,137,643,1752 +0,3,100,137,643,1752 SET @@session.slave_skip_errors= 7; ERROR HY000: Variable 'slave_skip_errors' is a read only variable SET @@global.slave_skip_errors= 7; diff --git a/mysql-test/t/not_embedded_server.test b/mysql-test/t/not_embedded_server.test index 233ac3edfbb..fa2b659ec57 100644 --- a/mysql-test/t/not_embedded_server.test +++ b/mysql-test/t/not_embedded_server.test @@ -36,4 +36,10 @@ select 1; #execute stmt1; #deallocate prepare stmt1; +# +# Bug#43835: SHOW VARIABLES does not include 0 for slave_skip_errors +# + +SHOW VARIABLES like 'slave_skip_errors'; + # End of 5.1 tests diff --git a/mysql-test/t/variables-notembedded-master.opt b/mysql-test/t/variables-notembedded-master.opt index a684e591d10..8a173a043ac 100644 --- a/mysql-test/t/variables-notembedded-master.opt +++ b/mysql-test/t/variables-notembedded-master.opt @@ -1 +1 @@ ---loose-slave-skip-errors=3,100,137,643,1752 +--loose-slave-skip-errors=3,100,137,0,643,1752 diff --git a/sql/slave.cc b/sql/slave.cc index 8c29cb8a72f..b862c5eff20 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -128,6 +128,7 @@ static bool wait_for_relay_log_space(Relay_log_info* rli); static inline bool io_slave_killed(THD* thd,Master_info* mi); static inline bool sql_slave_killed(THD* thd,Relay_log_info* rli); static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type); +static void print_slave_skip_errors(void); static int safe_connect(THD* thd, MYSQL* mysql, Master_info* mi); static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi, bool suppress_warnings); @@ -231,6 +232,15 @@ int init_slave() */ active_mi= new Master_info; + /* + If --slave-skip-errors=... was not used, the string value for the + system variable has not been set up yet. Do it now. + */ + if (!use_slave_mask) + { + print_slave_skip_errors(); + } + /* If master_host is not specified, try to read it from the master_info file. If master_host is specified, create the master_info file if it doesn't @@ -311,7 +321,7 @@ static void print_slave_skip_errors(void) char *bend= buff + sizeof(slave_skip_error_names); int errnum; - for (errnum= 1; errnum < MAX_SLAVE_ERROR; errnum++) + for (errnum= 0; errnum < MAX_SLAVE_ERROR; errnum++) { if (bitmap_is_set(&slave_error_mask, errnum)) { From 83a78142641e243b39dba198e06de749f0d2db09 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 7 Apr 2009 11:48:38 +0500 Subject: [PATCH 17/85] Bug#42649 THR_LOCK_charset global mutex abused by InnoDB The patch was originally proposed by Mikael and reviewed by Bar. --- mysys/charset.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/mysys/charset.c b/mysys/charset.c index e61995de1d8..7a7ef0ad3ea 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -494,29 +494,40 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags) { char buf[FN_REFLEN]; CHARSET_INFO *cs; - /* - To make things thread safe we are not allowing other threads to interfere - while we may changing the cs_info_table - */ - pthread_mutex_lock(&THR_LOCK_charset); + if ((cs= all_charsets[cs_number])) { - if (!(cs->state & MY_CS_COMPILED) && !(cs->state & MY_CS_LOADED)) + if (cs->state & MY_CS_READY) /* if CS is already initialized */ + return cs; + + /* + To make things thread safe we are not allowing other threads to interfere + while we may changing the cs_info_table + */ + pthread_mutex_lock(&THR_LOCK_charset); + + if (!(cs->state & (MY_CS_COMPILED|MY_CS_LOADED))) /* if CS is not in memory */ { strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS); my_read_charset_file(buf,flags); } - cs= (cs->state & MY_CS_AVAILABLE) ? cs : NULL; - } - if (cs && !(cs->state & MY_CS_READY)) - { - if ((cs->cset->init && cs->cset->init(cs, cs_alloc)) || - (cs->coll->init && cs->coll->init(cs, cs_alloc))) - cs= NULL; + + if (cs->state & MY_CS_AVAILABLE) + { + if (!(cs->state & MY_CS_READY)) + { + if ((cs->cset->init && cs->cset->init(cs, cs_alloc)) || + (cs->coll->init && cs->coll->init(cs, cs_alloc))) + cs= NULL; + else + cs->state|= MY_CS_READY; + } + } else - cs->state|= MY_CS_READY; + cs= NULL; + + pthread_mutex_unlock(&THR_LOCK_charset); } - pthread_mutex_unlock(&THR_LOCK_charset); return cs; } From c045d1dcea0b2582b38ee5476b090097182c7144 Mon Sep 17 00:00:00 2001 From: Satya B Date: Tue, 7 Apr 2009 16:54:32 +0530 Subject: [PATCH 18/85] Fix for Bug #43973 - backup_myisam.test fails on 6.0-bugteam The test started failing following the push for BUG#41541. Some of the algorithms access bytes beyond the input data and this can affect up to one byte less than "word size" which is BITS_SAVED / 8. Fixed by adding (BITS_SAVED / 8) -1 bytes to buffer size (i.e. Memory Segment #2) to avoid accessing un-allocated data. --- myisam/mi_packrec.c | 36 +++++++++------------------------- mysql-test/r/myisampack.result | 22 +++++++++++++++++++++ mysql-test/t/myisampack.test | 25 +++++++++++++++++++++++ 3 files changed, 56 insertions(+), 27 deletions(-) diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c index df9a4d18a6c..68911d7f129 100644 --- a/myisam/mi_packrec.c +++ b/myisam/mi_packrec.c @@ -208,10 +208,17 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys) This segment will be reallocated after construction of the tables. */ length=(uint) (elements*2+trees*(1 << myisam_quick_table_bits)); + /* + To keep some algorithms simpler, we accept that they access + bytes beyond the end of the input data. This can affect up to + one byte less than the "word size" size used in this file, + which is BITS_SAVED / 8. To avoid accessing non-allocated + data, we add (BITS_SAVED / 8) - 1 bytes to the buffer size. + */ if (!(share->decode_tables=(uint16*) my_malloc((length + OFFSET_TABLE_SIZE) * sizeof(uint16) + - (uint) (share->pack.header_length - sizeof(header)), - MYF(MY_WME | MY_ZEROFILL)))) + (uint) (share->pack.header_length - sizeof(header) + + (BITS_SAVED / 8) - 1), MYF(MY_WME | MY_ZEROFILL)))) goto err1; tmp_buff=share->decode_tables+length; disk_cache=(byte*) (tmp_buff+OFFSET_TABLE_SIZE); @@ -1430,31 +1437,6 @@ 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]))) + diff --git a/mysql-test/r/myisampack.result b/mysql-test/r/myisampack.result index b4b200549a5..736a550e32b 100644 --- a/mysql-test/r/myisampack.result +++ b/mysql-test/r/myisampack.result @@ -38,3 +38,25 @@ SELECT COUNT(*) FROM t1; COUNT(*) 1024 DROP TABLE t1; +# +# Bug #43973 - backup_myisam.test fails on 6.0-bugteam +# +CREATE DATABASE mysql_db1; +CREATE TABLE mysql_db1.t1 (c1 VARCHAR(5), c2 int); +CREATE INDEX i1 ON mysql_db1.t1 (c1, c2); +INSERT INTO mysql_db1.t1 VALUES ('A',1); +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +FLUSH TABLE mysql_db1.t1; +# Compress the table using MYISAMPACK tool +# Run MYISAMCHK tool on the compressed table +SELECT COUNT(*) FROM mysql_db1.t1 WHERE c2 < 5; +COUNT(*) +128 +DROP TABLE mysql_db1.t1; +DROP DATABASE mysql_db1; diff --git a/mysql-test/t/myisampack.test b/mysql-test/t/myisampack.test index ace7afce88a..ce27071bcf8 100644 --- a/mysql-test/t/myisampack.test +++ b/mysql-test/t/myisampack.test @@ -50,3 +50,28 @@ FLUSH TABLE t1; --exec $MYISAMPACK $MYSQLTEST_VARDIR/master-data/test/t1 SELECT COUNT(*) FROM t1; DROP TABLE t1; + +--echo # +--echo # Bug #43973 - backup_myisam.test fails on 6.0-bugteam +--echo # +CREATE DATABASE mysql_db1; +CREATE TABLE mysql_db1.t1 (c1 VARCHAR(5), c2 int); +CREATE INDEX i1 ON mysql_db1.t1 (c1, c2); +INSERT INTO mysql_db1.t1 VALUES ('A',1); +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1; +FLUSH TABLE mysql_db1.t1; +# +--echo # Compress the table using MYISAMPACK tool +--exec $MYISAMPACK -s $MYSQLTEST_VARDIR/master-data/mysql_db1/t1 +--echo # Run MYISAMCHK tool on the compressed table +--exec $MYISAMCHK -srq $MYSQLTEST_VARDIR/master-data/mysql_db1/t1 +SELECT COUNT(*) FROM mysql_db1.t1 WHERE c2 < 5; +# +DROP TABLE mysql_db1.t1; +DROP DATABASE mysql_db1; From 998697fd4cb1594b39b969a67992e5197408e9e5 Mon Sep 17 00:00:00 2001 From: Narayanan V Date: Wed, 8 Apr 2009 12:25:19 +0530 Subject: [PATCH 19/85] Bug#37631 Incorrect key file for table after upgrading from 5.0 to 5.1 The conformance checker was not taking into account, and, making concessions for acceptable incompatibilites in tables created by versions earlier than 4.1. The current patch relaxes the conformance checker to ignore differences in key_alg and language for tables created by versions earlier than 4.1. --- storage/myisam/ha_myisam.cc | 21 +++++++++++++++------ storage/myisammrg/ha_myisammrg.cc | 5 +++-- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 72e202e6132..dd66c255475 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -315,6 +315,7 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, t2_keys in Number of keys in second table t2_recs in Number of records in second table strict in Strict check switch + table in handle to the table object DESCRIPTION This function compares two MyISAM definitions. By intention it was done @@ -330,6 +331,10 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, Otherwise 'strict' flag must be set to 1 and it is not required to pass converted dot-frm definition as t1_*. + For compatibility reasons we relax some checks, specifically: + - 4.0 (and earlier versions) always set key_alg to 0. + - 4.0 (and earlier versions) have the same language for all keysegs. + RETURN VALUE 0 - Equal definitions. 1 - Different definitions. @@ -344,10 +349,11 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, 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) + uint t2_keys, uint t2_recs, bool strict, TABLE *table_arg) { uint i, j; DBUG_ENTER("check_definition"); + my_bool mysql_40_compat= table_arg && table_arg->s->frm_version < FRM_VER_TRUE_VARCHAR; if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys)) { DBUG_PRINT("error", ("Number of keys differs: t1_keys=%u, t2_keys=%u", @@ -386,8 +392,9 @@ int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo, test(t2_keyinfo[i].flag & HA_SPATIAL))); DBUG_RETURN(1); } - if (t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs || - t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg) + if ((mysql_40_compat && + t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg) || + t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs) { DBUG_PRINT("error", ("Key %d has different definition", i)); DBUG_PRINT("error", ("t1_keysegs=%d, t1_key_alg=%d", @@ -417,8 +424,9 @@ int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo, t1_keysegs_j__type= HA_KEYTYPE_VARBINARY1; /* purecov: inspected */ } - if (t1_keysegs_j__type != t2_keysegs[j].type || - t1_keysegs[j].language != t2_keysegs[j].language || + if ((mysql_40_compat && + t1_keysegs[j].language != t2_keysegs[j].language) || + t1_keysegs_j__type != t2_keysegs[j].type || t1_keysegs[j].null_bit != t2_keysegs[j].null_bit || t1_keysegs[j].length != t2_keysegs[j].length) { @@ -671,7 +679,8 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) } if (check_definition(keyinfo, recinfo, table->s->keys, recs, file->s->keyinfo, file->s->rec, - file->s->base.keys, file->s->base.fields, true)) + file->s->base.keys, file->s->base.fields, + true, table)) { /* purecov: begin inspected */ my_errno= HA_ERR_CRASHED; diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 061af97d0fb..7e25309ae70 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -137,7 +137,8 @@ extern int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, 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); + uint t2_keys, uint t2_recs, bool strict, + TABLE *table_arg); static void split_file_name(const char *file_name, LEX_STRING *db, LEX_STRING *name); @@ -595,7 +596,7 @@ int ha_myisammrg::attach_children(void) if (check_definition(keyinfo, recinfo, keys, recs, u_table->table->s->keyinfo, u_table->table->s->rec, u_table->table->s->base.keys, - u_table->table->s->base.fields, false)) + u_table->table->s->base.fields, false, NULL)) { DBUG_PRINT("error", ("table definition mismatch: '%s'", u_table->table->filename)); From 40b00f174ce67b895e6defbfb8f9efd67454eed1 Mon Sep 17 00:00:00 2001 From: Anurag Shekhar Date: Wed, 8 Apr 2009 16:45:43 +0530 Subject: [PATCH 20/85] Bug #43950 myisamchk shows negative value for 'Max keyfile length' While printing the Max keyfile length 'llstr' call was used which was treating the max_key_file_length as negative. Changing this to ullstr fixes the problem. myisamchk output will differ in 32 bit and 64 bit Operating systems so its not possible to have test case for this bug. --- myisam/myisamchk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 29fb2ea1a60..b1a61f2f373 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -1311,7 +1311,7 @@ static void descript(MI_CHECK *param, register MI_INFO *info, my_string name) share->base.max_key_file_length != HA_OFFSET_ERROR) printf("Max datafile length: %13s Max keyfile length: %13s\n", llstr(share->base.max_data_file_length-1,llbuff), - llstr(share->base.max_key_file_length-1,llbuff2)); + ullstr(share->base.max_key_file_length - 1, llbuff2)); } } From 65ff9e1b0b70d81c1d404fd388c3cd8090c07589 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Wed, 8 Apr 2009 22:02:19 +0100 Subject: [PATCH 21/85] BUG#39393. Post-fix for test rpl_skip_error. The result set for multi-row statements is not the same between STMT and RBR and among different versions. Thus to avoid test failures, we are not printing out such result sets. Note, however, that this does not have impact on coverage and accuracy since the execution is able to continue without further issues when an error is found on the master and such error is set to be skipped. --- mysql-test/suite/rpl/r/rpl_skip_error.result | 26 +++----------------- mysql-test/suite/rpl/t/rpl_skip_error.test | 18 +++----------- 2 files changed, 8 insertions(+), 36 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_skip_error.result b/mysql-test/suite/rpl/r/rpl_skip_error.result index dc02bb783ae..d955859f030 100644 --- a/mysql-test/suite/rpl/r/rpl_skip_error.result +++ b/mysql-test/suite/rpl/r/rpl_skip_error.result @@ -153,17 +153,8 @@ DELETE FROM t1 WHERE id = 4; SET SQL_LOG_BIN=1; UPDATE t1 SET id= id + 3, data = 2; -SELECT *, "INNODB SET SLAVE DATA" FROM t1 ORDER BY id; -id data INNODB SET SLAVE DATA -1 1 INNODB SET SLAVE DATA -2 1 INNODB SET SLAVE DATA -3 1 INNODB SET SLAVE DATA -4 1 INNODB SET SLAVE DATA -SELECT *, "INNODB SET MASTER DATA" FROM t1 ORDER BY id; -id data INNODB SET MASTER DATA -4 2 INNODB SET MASTER DATA -5 2 INNODB SET MASTER DATA -6 2 INNODB SET MASTER DATA +**** We cannot execute a select as there are differences in the +**** behavior between STMT and RBR. ==== Using MyIsam ==== SET SQL_LOG_BIN=0; CREATE TABLE t2(id INT NOT NULL PRIMARY KEY, data INT) Engine=MyIsam; @@ -192,17 +183,8 @@ DELETE FROM t2 WHERE id = 5; SET SQL_LOG_BIN=1; UPDATE t2 SET id= id + 3, data = 2; -SELECT *, "MYISAM SET SLAVE DATA" FROM t2 ORDER BY id; -id data MYISAM SET SLAVE DATA -2 1 MYISAM SET SLAVE DATA -3 1 MYISAM SET SLAVE DATA -4 2 MYISAM SET SLAVE DATA -5 1 MYISAM SET SLAVE DATA -SELECT *, "MYISAM SET MASTER DATA" FROM t2 ORDER BY id; -id data MYISAM SET MASTER DATA -4 2 MYISAM SET MASTER DATA -5 2 MYISAM SET MASTER DATA -6 2 MYISAM SET MASTER DATA +**** We cannot execute a select as there are differences in the +**** behavior between STMT and RBR. ==== Clean Up ==== DROP TABLE t1; DROP TABLE t2; diff --git a/mysql-test/suite/rpl/t/rpl_skip_error.test b/mysql-test/suite/rpl/t/rpl_skip_error.test index c15d24be9e5..9c6aa3dcb57 100644 --- a/mysql-test/suite/rpl/t/rpl_skip_error.test +++ b/mysql-test/suite/rpl/t/rpl_skip_error.test @@ -122,13 +122,8 @@ sync_slave_with_master; let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); echo $error; -connection slave; - -SELECT *, "INNODB SET SLAVE DATA" FROM t1 ORDER BY id; - -connection master; - -SELECT *, "INNODB SET MASTER DATA" FROM t1 ORDER BY id; +--echo **** We cannot execute a select as there are differences in the +--echo **** behavior between STMT and RBR. --echo ==== Using MyIsam ==== @@ -161,13 +156,8 @@ sync_slave_with_master; let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); echo $error; -connection slave; - -SELECT *, "MYISAM SET SLAVE DATA" FROM t2 ORDER BY id; - -connection master; - -SELECT *, "MYISAM SET MASTER DATA" FROM t2 ORDER BY id; +--echo **** We cannot execute a select as there are differences in the +--echo **** behavior between STMT and RBR. --echo ==== Clean Up ==== From 41361d89467cc59fa1fee8f3eb66c356b4826fe8 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Thu, 9 Apr 2009 14:22:06 +0800 Subject: [PATCH 22/85] Post fix of BUG#37145 Binlog the CREATE EVENT unless the created event been successfully dropped Modified Query_log_event constructor to make sure that error_code is not set to ER_SERVER_SHUTDOWN or ER_QUERY_INTERRUPTED errors when NOT_KILLED --- sql/events.cc | 12 ++++++++++-- sql/log_event.cc | 11 ++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/sql/events.cc b/sql/events.cc index 4203ca06d7f..ea935e67bd3 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -412,6 +412,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, if (!(ret= db_repository->create_event(thd, parse_data, if_not_exists))) { Event_queue_element *new_element; + bool dropped= 0; if (!(new_element= new Event_queue_element())) ret= TRUE; // OOM @@ -419,8 +420,9 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, parse_data->name, new_element))) { - db_repository->drop_event(thd, parse_data->dbname, parse_data->name, - TRUE); + if (!db_repository->drop_event(thd, parse_data->dbname, parse_data->name, + TRUE)) + dropped= 1; delete new_element; } else @@ -429,6 +431,12 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, bool created; if (event_queue) event_queue->create_event(thd, new_element, &created); + } + /* + binlog the create event unless it's been successfully dropped + */ + if (!dropped) + { /* Binlog the create event. */ DBUG_ASSERT(thd->query && thd->query_length); write_bin_log(thd, TRUE, thd->query, thd->query_length); diff --git a/sql/log_event.cc b/sql/log_event.cc index 89094da3e94..10ff6555e9b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2292,7 +2292,16 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, (thd_arg->is_error() ? thd_arg->main_da.sql_errno() : 0) : ((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ? 0 : thd_arg->killed_errno()); - + + /* thd_arg->main_da.sql_errno() might be ER_SERVER_SHUTDOWN or + ER_QUERY_INTERRUPTED, So here we need to make sure that + error_code is not set to these errors when specified NOT_KILLED + by the caller + */ + if ((killed_status_arg == THD::NOT_KILLED) && + (error_code == ER_SERVER_SHUTDOWN || error_code == ER_QUERY_INTERRUPTED)) + error_code= 0; + time(&end_time); exec_time = (ulong) (end_time - thd_arg->start_time); /** From 74a332d50468456a303920597a8031dda10d5baf Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Thu, 9 Apr 2009 15:42:59 +0800 Subject: [PATCH 23/85] post fix compiling problem after push BUG#37145 to 5.0-bugteam --- client/mysqltest.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 865c1d9a717..799609a7d27 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -4087,17 +4087,16 @@ int select_connection_name(const char *name) int select_connection(struct st_command *command) { - char *name; char *p= command->first_argument; + static DYNAMIC_STRING ds_connection; + const struct command_arg connection_args[] = { + { "connection_name", ARG_STRING, TRUE, &ds_connection, "Name of the connection that we switch to." } + }; DBUG_ENTER("select_connection"); if (!*p) die("Missing connection name in connect"); - static DYNAMIC_STRING ds_connection; - const struct command_arg connection_args[] = { - { "connection_name", ARG_STRING, TRUE, &ds_connection, "Name of the connection that we switch to." } - }; check_command_args(command, command->first_argument, connection_args, sizeof(connection_args)/sizeof(struct command_arg), ','); From 9b1076b4717e470c6b9391441a1016b402053541 Mon Sep 17 00:00:00 2001 From: Narayanan V Date: Thu, 9 Apr 2009 13:48:23 +0530 Subject: [PATCH 24/85] Bug#38848 myisam_use_mmap causes widespread myisam corruption on windows Currently the memory map is being created with a size that is greater than the size of the underlying datafile. This can cause varying behaviour, e.g. In windows the size of the datafile is increased, while on linux it remains the same. This fix removes the increment margin to the size that is used while creating the memory map. --- storage/myisam/mi_dynrec.c | 6 +++--- storage/myisam/mi_packrec.c | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c index 3433c26f98b..d1cbd6955dd 100644 --- a/storage/myisam/mi_dynrec.c +++ b/storage/myisam/mi_dynrec.c @@ -66,7 +66,7 @@ static int _mi_cmp_buffer(File file, const uchar *buff, my_off_t filepos, my_bool mi_dynmap_file(MI_INFO *info, my_off_t size) { DBUG_ENTER("mi_dynmap_file"); - if (size > (my_off_t) (~((size_t) 0)) - MEMMAP_EXTRA_MARGIN) + if (size > (my_off_t) (~((size_t) 0))) { DBUG_PRINT("warning", ("File is too large for mmap")); DBUG_RETURN(1); @@ -80,7 +80,7 @@ my_bool mi_dynmap_file(MI_INFO *info, my_off_t size) upon a write if no physical memory is available. */ info->s->file_map= (uchar*) - my_mmap(0, (size_t)(size + MEMMAP_EXTRA_MARGIN), + my_mmap(0, (size_t) size, info->s->mode==O_RDONLY ? PROT_READ : PROT_READ | PROT_WRITE, MAP_SHARED | MAP_NORESERVE, @@ -113,7 +113,7 @@ void mi_remap_file(MI_INFO *info, my_off_t size) if (info->s->file_map) { VOID(my_munmap((char*) info->s->file_map, - (size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN)); + (size_t) info->s->mmaped_length)); mi_dynmap_file(info, size); } } diff --git a/storage/myisam/mi_packrec.c b/storage/myisam/mi_packrec.c index be9ce9a0c24..d9abcbce050 100644 --- a/storage/myisam/mi_packrec.c +++ b/storage/myisam/mi_packrec.c @@ -1502,7 +1502,9 @@ my_bool _mi_memmap_file(MI_INFO *info) DBUG_PRINT("warning",("File isn't extended for memmap")); DBUG_RETURN(0); } - if (mi_dynmap_file(info, share->state.state.data_file_length)) + if (mi_dynmap_file(info, + share->state.state.data_file_length + + MEMMAP_EXTRA_MARGIN)) DBUG_RETURN(0); } info->opt_flag|= MEMMAP_USED; From b6e8991cd1984927649b89fa70650de6111a69ad Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Thu, 9 Apr 2009 16:58:18 +0800 Subject: [PATCH 25/85] Fix compile error on windows for BUG#37145 on 5.0-bugteam --- client/mysqltest.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 799609a7d27..2f19fad9ea9 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -4087,6 +4087,7 @@ int select_connection_name(const char *name) int select_connection(struct st_command *command) { + int ret; char *p= command->first_argument; static DYNAMIC_STRING ds_connection; const struct command_arg connection_args[] = { @@ -4103,7 +4104,7 @@ int select_connection(struct st_command *command) DBUG_PRINT("info", ("changing connection: %s", ds_connection.str)); - int ret= select_connection_name(ds_connection.str); + ret= select_connection_name(ds_connection.str); dynstr_free(&ds_connection); return ret; } From db992986fe94ff7c5224786e0cccd1d4b846239d Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 9 Apr 2009 14:19:31 +0500 Subject: [PATCH 26/85] Bug#43833 Simple INSERT crashes the server The crash happens due to wrong 'digits' variable value(0), 'digits' can not be 0, so the fix is use 1 as min allowed value. --- mysql-test/r/insert.result | 5 +++++ mysql-test/t/insert.test | 9 +++++++++ sql/field.cc | 6 +++--- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index 2e49bd373d6..c98ed104a69 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -595,4 +595,9 @@ SELECT * FROM t2; c1 15449237462 DROP TABLE t1, t2; +CREATE TABLE t1(f1 FLOAT); +INSERT INTO t1 VALUES (1.23); +CREATE TABLE t2(f1 CHAR(1)); +INSERT INTO t2 SELECT f1 FROM t1; +DROP TABLE t1, t2; End of 5.0 tests. diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test index 0b5a12fa523..a1735c1a91f 100644 --- a/mysql-test/t/insert.test +++ b/mysql-test/t/insert.test @@ -454,5 +454,14 @@ SELECT * FROM t2; DROP TABLE t1, t2; +# +# Bug#43833 Simple INSERT crashes the server +# +CREATE TABLE t1(f1 FLOAT); +INSERT INTO t1 VALUES (1.23); +CREATE TABLE t2(f1 CHAR(1)); +INSERT INTO t2 SELECT f1 FROM t1; +DROP TABLE t1, t2; + --echo End of 5.0 tests. diff --git a/sql/field.cc b/sql/field.cc index 36cc4681dec..99e9d7803e1 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5987,13 +5987,13 @@ int Field_str::store(double nr) calculate the maximum number of significant digits if the 'f'-format would be used (+1 for decimal point if the number has a fractional part). */ - digits= max(0, (int) max_length - fractional); + digits= max(1, (int) max_length - fractional); /* If the exponent is negative, decrease digits by the number of leading zeros after the decimal point that do not count as significant digits. */ if (exp < 0) - digits= max(0, (int) digits + exp); + digits= max(1, (int) digits + exp); /* 'e'-format is used only if the exponent is less than -4 or greater than or equal to the precision. In this case we need to adjust the number of @@ -6001,7 +6001,7 @@ int Field_str::store(double nr) We also have to reserve one additional character if abs(exp) >= 100. */ if (exp >= (int) digits || exp < -4) - digits= max(0, (int) (max_length - 5 - (exp >= 100 || exp <= -100))); + digits= max(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100))); /* Limit precision to DBL_DIG to avoid garbage past significant digits */ set_if_smaller(digits, DBL_DIG); From dc3fad94b478813e17f03cb43a3b837f3aafdc81 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 9 Apr 2009 11:40:22 +0100 Subject: [PATCH 27/85] BUG#13684: SP: DROP PROCEDURE|FUNCTION IF EXISTS not binlogged if routine does not exist There is an inconsistency with DROP DATABASE IF EXISTS, DROP TABLE IF EXISTS and DROP VIEW IF EXISTS: those are binlogged even if the DB or TABLE does not exist, whereas DROP PROCEDURE IF EXISTS does not. It would be nice or at least consistent if DROP PROCEDURE/STATEMENT worked the same too. Fixed DROP PROCEDURE|FUNCTION IF EXISTS by adding a call to mysql_bin_log.write in mysql_execute_command. Checked also if all documented "DROP (...) IF EXISTS" get binlogged. NOTE: This is a 5.0 backport patch as requested by support. --- mysql-test/r/rpl_drop_if_exists.result | 80 ++++++++++++++++++++++++++ mysql-test/r/rpl_sp.result | 16 ++++++ mysql-test/t/rpl_drop_if_exists.test | 77 +++++++++++++++++++++++++ sql/sql_parse.cc | 8 +++ 4 files changed, 181 insertions(+) create mode 100644 mysql-test/r/rpl_drop_if_exists.result create mode 100644 mysql-test/t/rpl_drop_if_exists.test diff --git a/mysql-test/r/rpl_drop_if_exists.result b/mysql-test/r/rpl_drop_if_exists.result new file mode 100644 index 00000000000..f711a873122 --- /dev/null +++ b/mysql-test/r/rpl_drop_if_exists.result @@ -0,0 +1,80 @@ +RESET MASTER; +DROP PROCEDURE IF EXISTS db_bug_13684.p; +DROP FUNCTION IF EXISTS db_bug_13684.f; +DROP TRIGGER IF EXISTS db_bug_13684.tr; +DROP VIEW IF EXISTS db_bug_13684.v; +DROP TABLE IF EXISTS db_bug_13684.t; +DROP DATABASE IF EXISTS db_bug_13684; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS db_bug_13684.p +master-bin.000001 # Query # # use `test`; DROP FUNCTION IF EXISTS db_bug_13684.f +master-bin.000001 # Query # # use `test`; DROP TRIGGER IF EXISTS db_bug_13684.tr +master-bin.000001 # Query # # use `test`; DROP VIEW IF EXISTS db_bug_13684.v +master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t +master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684 +CREATE DATABASE db_bug_13684; +CREATE TABLE db_bug_13684.t (a int); +CREATE VIEW db_bug_13684.v +AS SELECT * FROM db_bug_13684.t; +CREATE TRIGGER db_bug_13684.tr BEFORE INSERT ON db_bug_13684.t +FOR EACH ROW BEGIN +END; +CREATE PROCEDURE db_bug_13684.p (OUT p1 INT) +BEGIN +END; +CREATE FUNCTION db_bug_13684.f (s CHAR(20)) +RETURNS CHAR(50) DETERMINISTIC +RETURN s; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS db_bug_13684.p +master-bin.000001 # Query # # use `test`; DROP FUNCTION IF EXISTS db_bug_13684.f +master-bin.000001 # Query # # use `test`; DROP TRIGGER IF EXISTS db_bug_13684.tr +master-bin.000001 # Query # # use `test`; DROP VIEW IF EXISTS db_bug_13684.v +master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t +master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684 +master-bin.000001 # Query # # CREATE DATABASE db_bug_13684 +master-bin.000001 # Query # # use `test`; CREATE TABLE db_bug_13684.t (a int) +master-bin.000001 # Query # # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `db_bug_13684`.`v` AS select `db_bug_13684`.`t`.`a` AS `a` from `db_bug_13684`.`t` +master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER db_bug_13684.tr BEFORE INSERT ON db_bug_13684.t +FOR EACH ROW BEGIN +END +master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `db_bug_13684`.`p`(OUT p1 INT) +BEGIN +END +master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `db_bug_13684`.`f`(s CHAR(20)) RETURNS char(50) CHARSET latin1 + DETERMINISTIC +RETURN s +DROP PROCEDURE IF EXISTS db_bug_13684.p; +DROP FUNCTION IF EXISTS db_bug_13684.f; +DROP TRIGGER IF EXISTS db_bug_13684.tr; +DROP VIEW IF EXISTS db_bug_13684.v; +DROP TABLE IF EXISTS db_bug_13684.t; +DROP DATABASE IF EXISTS db_bug_13684; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS db_bug_13684.p +master-bin.000001 # Query # # use `test`; DROP FUNCTION IF EXISTS db_bug_13684.f +master-bin.000001 # Query # # use `test`; DROP TRIGGER IF EXISTS db_bug_13684.tr +master-bin.000001 # Query # # use `test`; DROP VIEW IF EXISTS db_bug_13684.v +master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t +master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684 +master-bin.000001 # Query # # CREATE DATABASE db_bug_13684 +master-bin.000001 # Query # # use `test`; CREATE TABLE db_bug_13684.t (a int) +master-bin.000001 # Query # # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `db_bug_13684`.`v` AS select `db_bug_13684`.`t`.`a` AS `a` from `db_bug_13684`.`t` +master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER db_bug_13684.tr BEFORE INSERT ON db_bug_13684.t +FOR EACH ROW BEGIN +END +master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `db_bug_13684`.`p`(OUT p1 INT) +BEGIN +END +master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `db_bug_13684`.`f`(s CHAR(20)) RETURNS char(50) CHARSET latin1 + DETERMINISTIC +RETURN s +master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS db_bug_13684.p +master-bin.000001 # Query # # use `test`; DROP FUNCTION IF EXISTS db_bug_13684.f +master-bin.000001 # Query # # use `test`; DROP TRIGGER IF EXISTS db_bug_13684.tr +master-bin.000001 # Query # # use `test`; DROP VIEW IF EXISTS db_bug_13684.v +master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t +master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684 diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_sp.result index ebe5f8b0be9..0f4d0fa8dad 100644 --- a/mysql-test/r/rpl_sp.result +++ b/mysql-test/r/rpl_sp.result @@ -483,6 +483,7 @@ master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1 master-bin.000001 # Query 1 # drop database mysqltest1 master-bin.000001 # Query 1 # drop user "zedjzlcsjhd"@127.0.0.1 +master-bin.000001 # Query 1 # use `test`; drop function if exists f1 master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) READS SQL DATA begin @@ -498,12 +499,15 @@ master-bin.000001 # Query 1 # use `test`; create table t1 (a int) master-bin.000001 # Query 1 # use `test`; insert into t1 (a) values (f1()) master-bin.000001 # Query 1 # use `test`; drop view v1 master-bin.000001 # Query 1 # use `test`; drop function f1 +master-bin.000001 # Query 1 # use `test`; DROP PROCEDURE IF EXISTS p1 master-bin.000001 # Query 1 # use `test`; DROP TABLE IF EXISTS t1 master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1(col VARCHAR(10)) master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(arg VARCHAR(10)) INSERT INTO t1 VALUES(arg) master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES( NAME_CONST('arg',_latin1'test' COLLATE 'latin1_swedish_ci')) master-bin.000001 # Query 1 # use `test`; DROP PROCEDURE p1 +master-bin.000001 # Query 1 # use `test`; DROP PROCEDURE IF EXISTS p1 +master-bin.000001 # Query 1 # use `test`; DROP FUNCTION IF EXISTS f1 master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`() SET @a = 1 master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) @@ -804,6 +808,9 @@ drop user "zedjzlcsjhd"@127.0.0.1 /*!*/; use test/*!*/; SET TIMESTAMP=t/*!*/; +drop function if exists f1 +/*!*/; +SET TIMESTAMP=t/*!*/; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) READS SQL DATA begin @@ -831,6 +838,9 @@ SET TIMESTAMP=t/*!*/; drop function f1 /*!*/; SET TIMESTAMP=t/*!*/; +DROP PROCEDURE IF EXISTS p1 +/*!*/; +SET TIMESTAMP=t/*!*/; DROP TABLE IF EXISTS t1 /*!*/; SET TIMESTAMP=t/*!*/; @@ -847,6 +857,12 @@ SET TIMESTAMP=t/*!*/; DROP PROCEDURE p1 /*!*/; SET TIMESTAMP=t/*!*/; +DROP PROCEDURE IF EXISTS p1 +/*!*/; +SET TIMESTAMP=t/*!*/; +DROP FUNCTION IF EXISTS f1 +/*!*/; +SET TIMESTAMP=t/*!*/; CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`() SET @a = 1 /*!*/; diff --git a/mysql-test/t/rpl_drop_if_exists.test b/mysql-test/t/rpl_drop_if_exists.test new file mode 100644 index 00000000000..a042fa8caff --- /dev/null +++ b/mysql-test/t/rpl_drop_if_exists.test @@ -0,0 +1,77 @@ +# BUG#13684: +# SP: DROP PROCEDURE|FUNCTION IF EXISTS not binlogged if routine +# does not exist +# +# There is an inconsistency with DROP DATABASE IF EXISTS, DROP +# TABLE IF EXISTS and DROP VIEW IF EXISTS: those are binlogged even +# if the DB or TABLE does not exist, whereas DROP PROCEDURE IF +# EXISTS does not. It would be nice or at least consistent if DROP +# PROCEDURE/STATEMENT worked the same too. +# +# Description: +# DROP PROCEDURE|FUNCTION IF EXISTS does not get binlogged whereas DROP +# DATABASE|TABLE|TRIGGER|... IF EXISTS do. +# +# Fixed DROP PROCEDURE|FUNCTION IF EXISTS by adding a call to +# mysql_bin_log.write in mysql_execute_command. Checked also if all +# documented "DROP (...) IF EXISTS" get binlogged. +# +# Test is implemented as follows: +# +# i) test each "drop if exists" (DDL) +# ii) show binlog events; +# iii) create an object for each drop if exists statement; +# iv) issue "drop if exists" in existent objects. +# v) show binlog events; +# + +--source include/have_log_bin.inc +RESET MASTER; + +disable_warnings; + +# test all "drop if exists" in manual with inexistent objects +DROP PROCEDURE IF EXISTS db_bug_13684.p; +DROP FUNCTION IF EXISTS db_bug_13684.f; +DROP TRIGGER IF EXISTS db_bug_13684.tr; +DROP VIEW IF EXISTS db_bug_13684.v; +DROP TABLE IF EXISTS db_bug_13684.t; +DROP DATABASE IF EXISTS db_bug_13684; + +--source include/show_binlog_events.inc + +# test drop with existing values + +# create +CREATE DATABASE db_bug_13684; + +CREATE TABLE db_bug_13684.t (a int); + +CREATE VIEW db_bug_13684.v + AS SELECT * FROM db_bug_13684.t; + +CREATE TRIGGER db_bug_13684.tr BEFORE INSERT ON db_bug_13684.t + FOR EACH ROW BEGIN + END; + +CREATE PROCEDURE db_bug_13684.p (OUT p1 INT) + BEGIN + END; + +CREATE FUNCTION db_bug_13684.f (s CHAR(20)) + RETURNS CHAR(50) DETERMINISTIC + RETURN s; + +--source include/show_binlog_events.inc + +# drop existing +DROP PROCEDURE IF EXISTS db_bug_13684.p; +DROP FUNCTION IF EXISTS db_bug_13684.f; +DROP TRIGGER IF EXISTS db_bug_13684.tr; +DROP VIEW IF EXISTS db_bug_13684.v; +DROP TABLE IF EXISTS db_bug_13684.t; +DROP DATABASE IF EXISTS db_bug_13684; + +--source include/show_binlog_events.inc + +enable_warnings; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e4618874fb9..7fbe6b86fbd 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5067,6 +5067,14 @@ create_sp_error: case SP_KEY_NOT_FOUND: if (lex->drop_if_exists) { + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, + /* using_trans */ 0, + /* suppress use */ FALSE, + THD::NOT_KILLED); + mysql_bin_log.write(&qinfo); + } push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), SP_COM_STRING(lex), lex->spname->m_name.str); From ae758cbd52e44e3d22e5c61834910ebe3c6404b9 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Thu, 9 Apr 2009 16:05:41 +0300 Subject: [PATCH 28/85] Bug #38205 Row-based Replication (RBR) causes inconsistencies: HA_ERR_FOUND_DUPP_KEY Bug#319 if while a non-transactional slave is replicating a transaction possible problem only testing related: addressing reviewers' comments. --- mysql-test/suite/bugs/r/rpl_bug38205.result | 2 +- mysql-test/suite/bugs/t/rpl_bug38205.test | 3 ++- mysql-test/suite/rpl/r/rpl_start_stop_slave.result | 4 ++-- mysql-test/suite/rpl/t/rpl_start_stop_slave.test | 8 ++++---- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/bugs/r/rpl_bug38205.result b/mysql-test/suite/bugs/r/rpl_bug38205.result index 195c0ca1135..8f1dee344fa 100644 --- a/mysql-test/suite/bugs/r/rpl_bug38205.result +++ b/mysql-test/suite/bugs/r/rpl_bug38205.result @@ -44,7 +44,7 @@ zero 0 stop slave sql_thread; rollback; -*** sql thread is running: No *** +*** sql thread is *not* running: No *** *** the prove: the stopped slave has rolled back the current transaction *** zero 0 diff --git a/mysql-test/suite/bugs/t/rpl_bug38205.test b/mysql-test/suite/bugs/t/rpl_bug38205.test index f754d7481c7..52b36636e79 100644 --- a/mysql-test/suite/bugs/t/rpl_bug38205.test +++ b/mysql-test/suite/bugs/t/rpl_bug38205.test @@ -1,5 +1,6 @@ # # Bug #38205 Row-based Replication (RBR) causes inconsistencies: HA_ERR_FOUND_DUPP_KEY +# Bug#319 if while a non-transactional slave is replicating a transaction possible problem # # Verifying the fact that STOP SLAVE in the middle of a group execution waits # for the end of the group before the slave sql thread will stop. @@ -143,7 +144,7 @@ connection slave1; reap; source include/wait_for_slave_sql_to_stop.inc; let $sql_status= query_get_value(SHOW SLAVE STATUS, Slave_SQL_Running, 1); ---echo *** sql thread is running: $sql_status *** +--echo *** sql thread is *not* running: $sql_status *** let $pos1_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); diff --git a/mysql-test/suite/rpl/r/rpl_start_stop_slave.result b/mysql-test/suite/rpl/r/rpl_start_stop_slave.result index 130b65c704c..e2b1935c268 100644 --- a/mysql-test/suite/rpl/r/rpl_start_stop_slave.result +++ b/mysql-test/suite/rpl/r/rpl_start_stop_slave.result @@ -28,7 +28,7 @@ zero 0 stop slave; rollback; -*** sql thread is running: No *** +*** sql thread is *not* running: No *** *** the prove: the stopped slave has finished the current transaction *** five 5 @@ -36,5 +36,5 @@ zero 0 one 1 -start slave; +include/start_slave.inc drop table t1i, t2m; diff --git a/mysql-test/suite/rpl/t/rpl_start_stop_slave.test b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test index 529ed7acb32..d9b87427321 100644 --- a/mysql-test/suite/rpl/t/rpl_start_stop_slave.test +++ b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test @@ -38,7 +38,8 @@ sync_with_master; # -# Bug #38205 Row-based Replication (RBR) causes inconsistencies... +# Bug#38205 Row-based Replication (RBR) causes inconsistencies... +# Bug#319 if while a non-transactional slave is replicating a transaction... # # Verifying that STOP SLAVE does not interrupt excution of a group # execution of events if the group can not roll back. @@ -93,14 +94,13 @@ connection slave1; reap; source include/wait_for_slave_to_stop.inc; let $sql_status= query_get_value(SHOW SLAVE STATUS, Slave_SQL_Running, 1); ---echo *** sql thread is running: $sql_status *** +--echo *** sql thread is *not* running: $sql_status *** connection master; let $pos1_master= query_get_value(SHOW MASTER STATUS, Position, 1); connection slave; -source include/wait_for_slave_sql_to_stop.inc; let $pos1_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); @@ -112,7 +112,7 @@ eval select $pos1_master - $pos1_slave as zero; eval select $pos1_slave > $pos0_slave as one; --enable_query_log -start slave; +source include/start_slave.inc; # clean-up connection master; From 064c1b2cac3ee742d0384edcc4b1988a8c8eba60 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 9 Apr 2009 12:25:25 -0300 Subject: [PATCH 29/85] Bug#43706: libmysqld segfaults when re-intialised Bug#44091: libmysqld gets stuck waiting on mutex on initialization The problem was that libmysqld wasn't enforcing a certain initialization and deinitialization order for the mysys library. Another problem was that the global object used for management of log event handlers (aka LOGGER) wasn't being prepared for a possible reutilization. What leads to the hang/crash reported is that a failure to load the language file triggers a double call of the cleanup functions, causing an already destroyed mutex to be used. The solution is enforce a order on the initialization and deinitialization of the mysys library within the libmysqld library and to ensure that the global LOGGER object reset it's internal state during cleanup. --- mysys/my_init.c | 4 ++++ sql/log.cc | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/mysys/my_init.c b/mysys/my_init.c index b330ffac65a..a60927be693 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -136,6 +136,10 @@ void my_end(int infoflag) */ FILE *info_file= DBUG_FILE; my_bool print_info= (info_file != stderr); + + if (!my_init_done) + return; + /* We do not use DBUG_ENTER here, as after cleanup DBUG is no longer operational, so we cannot use DBUG_RETURN. diff --git a/sql/log.cc b/sql/log.cc index 44296daa939..ed2eff6625d 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -845,6 +845,7 @@ void LOGGER::cleanup_base() { table_log_handler->cleanup(); delete table_log_handler; + table_log_handler= NULL; } if (file_log_handler) file_log_handler->cleanup(); @@ -855,7 +856,11 @@ void LOGGER::cleanup_end() { DBUG_ASSERT(inited == 1); if (file_log_handler) + { delete file_log_handler; + file_log_handler=NULL; + } + inited= 0; } From aa449c10535df749e263f15d144d23b51e1c8cb0 Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Thu, 9 Apr 2009 22:18:18 -0400 Subject: [PATCH 30/85] Bug#39559: dump of stored procedures / functions with C-style \ comment can't be read back A change to the lexer in 5.1 caused slash-asterisk-bang-version sections to be terminated early if there exists a slash-asterisk- style comment inside it. Nesting comments is usually illegal, but we rely on versioned comment blocks in mysqldump, and the contents of those sections must be allowed to have comments. The problem was that when encountering open-comment tokens and consuming -or- passing through the contents, the "in_comment" state at the end was clobbered with the not-in-a-comment value, regardless of whether we were in a comment before this or not. So, """/*!VER one /* two */ three */""" would lose its in-comment state between "two" and "three". Save the echo and in-comment state, and restore it at the end of the comment if we consume a comment. --- mysql-test/r/parser.result | 52 ++++++++++++++++++++++ mysql-test/t/parser.test | 28 ++++++++++++ sql/sql_lex.cc | 91 +++++++++++++++++++++++++++++--------- sql/sql_lex.h | 14 ++++++ 4 files changed, 163 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index 002fbd02c2a..097f6dc69ff 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -615,3 +615,55 @@ UPDATE t3 SET a4={d '1789-07-14'} WHERE a1=0; SELECT a1, a4 FROM t2 WHERE a4 LIKE {fn UCASE('1789-07-14')}; a1 a4 DROP TABLE t1, t2, t3; +# +# Bug#39559: dump of stored procedures / functions with C-style +# comment can't be read back +# ++----------+--------+ +| expected | result | ++----------+--------+ +| 2 | 2 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 1 | 1 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 3 | 3 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 2 | 2 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 7 | 7 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 8 | 8 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 7 | 7 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 4 | 4 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 4 | 4 | ++----------+--------+ +# +# End of 5.1 tests +# diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test index 7efc519e441..e44fc85bc5e 100644 --- a/mysql-test/t/parser.test +++ b/mysql-test/t/parser.test @@ -724,3 +724,31 @@ SELECT {fn CONCAT(a1,a2)} FROM t1; UPDATE t3 SET a4={d '1789-07-14'} WHERE a1=0; SELECT a1, a4 FROM t2 WHERE a4 LIKE {fn UCASE('1789-07-14')}; DROP TABLE t1, t2, t3; + +########################################################################### +--echo # +--echo # Bug#39559: dump of stored procedures / functions with C-style +--echo # comment can't be read back +--echo # + +--write_file $MYSQLTEST_VARDIR/tmp/bug39559.sql +select 2 as expected, /*!01000/**/*/ 2 as result; +select 1 as expected, /*!99998/**/*/ 1 as result; +select 3 as expected, /*!01000 1 + */ 2 as result; +select 2 as expected, /*!99990 1 + */ 2 as result; +select 7 as expected, /*!01000 1 + /* 8 + */ 2 + */ 4 as result; +select 8 as expected, /*!99998 1 + /* 2 + */ 4 + */ 8 as result; +select 7 as expected, /*!01000 1 + /*!01000 8 + */ 2 + */ 4 as result; +select 7 as expected, /*!01000 1 + /*!99998 8 + */ 2 + */ 4 as result; +select 4 as expected, /*!99998 1 + /*!99998 8 + */ 2 + */ 4 as result; +select 4 as expected, /*!99998 1 + /*!01000 8 + */ 2 + */ 4 as result; +select 7 as expected, /*!01000 1 + /*!01000 8 + /*!01000 error */ 16 + */ 2 + */ 4 as result; +select 4 as expected, /* 1 + /*!01000 8 + */ 2 + */ 4; +EOF + +--exec $MYSQL --comment --force --table test <$MYSQLTEST_VARDIR/tmp/bug39559.sql +--remove_file $MYSQLTEST_VARDIR/tmp/bug39559.sql + +--echo # +--echo # End of 5.1 tests +--echo # diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 19a19f2b6fb..5e24a18bea3 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -712,6 +712,53 @@ static inline uint int_token(const char *str,uint length) return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger; } + +/** + Given a stream that is advanced to the first contained character in + an open comment, consume the comment. Optionally, if we are allowed, + recurse so that we understand comments within this current comment. + + At this level, we do not support version-condition comments. We might + have been called with having just passed one in the stream, though. In + that case, we probably want to tolerate mundane comments inside. Thus, + the case for recursion. + + @retval Whether EOF reached before comment is closed. +*/ +bool consume_comment(Lex_input_stream *lip, int remaining_recursions_permitted) +{ + reg1 uchar c; + while (! lip->eof()) + { + c= lip->yyGet(); + + if (remaining_recursions_permitted > 0) + { + if ((c == '/') && (lip->yyPeek() == '*')) + { + lip->yySkip(); /* Eat asterisk */ + consume_comment(lip, remaining_recursions_permitted-1); + continue; + } + } + + if (c == '*') + { + if (lip->yyPeek() == '/') + { + lip->yySkip(); /* Eat slash */ + return FALSE; + } + } + + if (c == '\n') + lip->yylineno++; + } + + return TRUE; +} + + /* MYSQLlex remember the following states from the following MYSQLlex() @@ -1204,6 +1251,8 @@ int MYSQLlex(void *arg, void *yythd) /* Reject '/' '*', since we might need to turn off the echo */ lip->yyUnget(); + lip->save_in_comment_state(); + if (lip->yyPeekn(2) == '!') { lip->in_comment= DISCARD_COMMENT; @@ -1246,11 +1295,17 @@ int MYSQLlex(void *arg, void *yythd) /* Expand the content of the special comment as real code */ lip->set_echo(TRUE); state=MY_LEX_START; - break; + break; /* Do not treat contents as a comment. */ + } + else + { + comment_closed= ! consume_comment(lip, 1); + /* version allowed to have one level of comment inside. */ } } else { + /* Not a version comment. */ state=MY_LEX_START; lip->set_echo(TRUE); break; @@ -1261,38 +1316,30 @@ int MYSQLlex(void *arg, void *yythd) lip->in_comment= PRESERVE_COMMENT; lip->yySkip(); // Accept / lip->yySkip(); // Accept * + comment_closed= ! consume_comment(lip, 0); + /* regular comments can have zero comments inside. */ } /* Discard: - regular '/' '*' comments, - special comments '/' '*' '!' for a future version, by scanning until we find a closing '*' '/' marker. - Note: There is no such thing as nesting comments, - the first '*' '/' sequence seen will mark the end. + + Nesting regular comments isn't allowed. The first + '*' '/' returns the parser to the previous state. + + /#!VERSI oned containing /# regular #/ is allowed #/ + + Inside one versioned comment, another versioned comment + is treated as a regular discardable comment. It gets + no special parsing. */ - comment_closed= FALSE; - while (! lip->eof()) - { - c= lip->yyGet(); - if (c == '*') - { - if (lip->yyPeek() == '/') - { - lip->yySkip(); - comment_closed= TRUE; - state = MY_LEX_START; - break; - } - } - else if (c == '\n') - lip->yylineno++; - } + /* Unbalanced comments with a missing '*' '/' are a syntax error */ if (! comment_closed) return (ABORT_SYM); state = MY_LEX_START; // Try again - lip->in_comment= NO_COMMENT; - lip->set_echo(TRUE); + lip->restore_in_comment_state(); break; case MY_LEX_END_LONG_COMMENT: if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/') diff --git a/sql/sql_lex.h b/sql/sql_lex.h index a48b99d07c7..cf825a57fd5 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1160,6 +1160,18 @@ public: m_echo= echo; } + void save_in_comment_state() + { + m_echo_saved= m_echo; + in_comment_saved= in_comment; + } + + void restore_in_comment_state() + { + m_echo= m_echo_saved; + in_comment= in_comment_saved; + } + /** Skip binary from the input stream. @param n number of bytes to accept. @@ -1417,6 +1429,7 @@ private: /** Echo the parsed stream to the pre-processed buffer. */ bool m_echo; + bool m_echo_saved; /** Pre-processed buffer. */ char *m_cpp_buf; @@ -1479,6 +1492,7 @@ public: /** State of the lexical analyser for comments. */ enum_comment_state in_comment; + enum_comment_state in_comment_saved; /** Starting position of the TEXT_STRING or IDENT in the pre-processed From 39d9d106bf7ba62b0e33bfe3bd2028dbd54c55a7 Mon Sep 17 00:00:00 2001 From: Narayanan V Date: Fri, 10 Apr 2009 11:56:54 +0530 Subject: [PATCH 31/85] Bug#44020 Unicode Swedish collations not working with IBMDB2I The utf8_swedish_ci and ucs2_swedish_ci collations do not work with indexes on IBMDB2I tables. The current patch adds the mapping for ucs2_swedish collation and removes the ucs2_spanish2 mapping which is not supported by any version of the operating system. --- storage/ibmdb2i/db2i_collationSupport.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/storage/ibmdb2i/db2i_collationSupport.cc b/storage/ibmdb2i/db2i_collationSupport.cc index 26ad0c9dee6..a41f211a689 100644 --- a/storage/ibmdb2i/db2i_collationSupport.cc +++ b/storage/ibmdb2i/db2i_collationSupport.cc @@ -111,7 +111,7 @@ static const char* mySQLCollation[MAX_COLLATION] = {"ucs2_slovak"}, {"ucs2_slovenian"}, {"ucs2_spanish"}, - {"ucs2_spanish2"}, + {"ucs2_swedish"}, {"ucs2_turkish"}, {"ucs2_unicode"}, {"ucs2"}, @@ -132,7 +132,7 @@ static const char* mySQLCollation[MAX_COLLATION] = {"utf8_slovak"}, {"utf8_slovenian"}, {"utf8_spanish"}, - {"utf8_spanish2"}, + {"utf8_swedish"}, {"utf8_turkish"}, {"utf8_unicode"}, {"utf8"} @@ -205,7 +205,7 @@ static const char* mySqlSortSequence[MAX_COLLATION] = {"ASK"}, {"ASL"}, {"AES"}, - {"AES__TRADIT"}, + {"ASW"}, {"ATR"}, {"AEN"}, {"*HEX"}, @@ -226,7 +226,7 @@ static const char* mySqlSortSequence[MAX_COLLATION] = {"ASK"}, {"ASL"}, {"AES"}, - {"AES__TRADIT"}, + {"ASW"}, {"ATR"}, {"AEN"}, {"*HEX"} From 9887dd7a669ad15fdada650f276dfb5d699faa5f Mon Sep 17 00:00:00 2001 From: Narayanan V Date: Fri, 10 Apr 2009 13:01:15 +0530 Subject: [PATCH 32/85] Bug#44022 CREATE TABLE sometimes fails silently for IBMDB2I engine In some circumstances, when a table is created with the IBMDB2I engine, the CREATE TABLE statement will return successfully but the table will not exist. The current patch addresses the above issue and causes CREATE to fail and report and error to the user. --- storage/ibmdb2i/ha_ibmdb2i.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/ibmdb2i/ha_ibmdb2i.cc b/storage/ibmdb2i/ha_ibmdb2i.cc index 6c7ce12ded1..11eceb68cb7 100644 --- a/storage/ibmdb2i/ha_ibmdb2i.cc +++ b/storage/ibmdb2i/ha_ibmdb2i.cc @@ -2323,7 +2323,7 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg, if (!rc && !isTemporary) { db2i_table* temp = new db2i_table(table_arg->s, name); - int32 rc = temp->fastInitForCreate(name); + rc = temp->fastInitForCreate(name); delete temp; if (rc) delete_table(name); From 4a12ecf7d9b6476d4062dd54ad6d6d30b4f43f56 Mon Sep 17 00:00:00 2001 From: Narayanan V Date: Fri, 10 Apr 2009 13:18:07 +0530 Subject: [PATCH 33/85] Bug#44025 Some schema names longer than 8 characters not supported by IBMDB2I On IBM i 5.4, schemas with names that are longer than 8 characters and contain digits or an underscore cannot contain IBMDB2I tables, even though this should theoritically be possible if all alpha characters are uppercase. THe current patch fixes the IBMDB2I engine to allow digits and the underscore(_) to be used in schema names longer than 8 characters on IBM i 5.4. --- storage/ibmdb2i/db2i_misc.h | 10 ++++++++-- storage/ibmdb2i/ha_ibmdb2i.cc | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/storage/ibmdb2i/db2i_misc.h b/storage/ibmdb2i/db2i_misc.h index 1cc3f962cfc..9e20f01208b 100644 --- a/storage/ibmdb2i/db2i_misc.h +++ b/storage/ibmdb2i/db2i_misc.h @@ -92,11 +92,17 @@ bool convertMySQLNameToDB2Name(const char* input, return (o <= outlen-1); } -bool isUpperOrQuote(const CHARSET_INFO* cs, const char* s) +bool isOrdinaryIdentifier(const char* s) { while (*s) { - if (my_isupper(cs, *s) || (*s == '"')) + if (my_isupper(system_charset_info, *s) || + my_isdigit(system_charset_info, *s) || + (*s == '_') || + (*s == '@') || + (*s == '$') || + (*s == '#') || + (*s == '"')) ++s; else return false; diff --git a/storage/ibmdb2i/ha_ibmdb2i.cc b/storage/ibmdb2i/ha_ibmdb2i.cc index 6c7ce12ded1..fee4a993b00 100644 --- a/storage/ibmdb2i/ha_ibmdb2i.cc +++ b/storage/ibmdb2i/ha_ibmdb2i.cc @@ -2122,7 +2122,7 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg, if (osVersion.v < 6) { if (strlen(libName) > - MAX_DB2_V5R4_LIBNAME_LENGTH + (isUpperOrQuote(system_charset_info, libName) ? 2 : 0)) + MAX_DB2_V5R4_LIBNAME_LENGTH + (isOrdinaryIdentifier(libName) ? 2 : 0)) { getErrTxt(DB2I_ERR_TOO_LONG_SCHEMA,libName, MAX_DB2_V5R4_LIBNAME_LENGTH); DBUG_RETURN(DB2I_ERR_TOO_LONG_SCHEMA); From 5c5691e8ec0a4c7ffe7990b03008838ae7571d19 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 10 Apr 2009 14:25:48 +0500 Subject: [PATCH 34/85] Bug#43385 Cannot ALTER DATABASE ... UPGRADE DATA DIRECTORY NAME when Views exist allow 'rename view' for ALTER ...UPGRADE DATA DIRECTORY NAME command. it's safe because a view has valid internal db&table names in this case. --- mysql-test/r/upgrade.result | 20 ++++++++++++++++++++ mysql-test/t/upgrade.test | 30 ++++++++++++++++++++++++++++++ sql/sql_rename.cc | 9 +++++++-- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/upgrade.result b/mysql-test/r/upgrade.result index adf81efe8e3..711e69094f7 100644 --- a/mysql-test/r/upgrade.result +++ b/mysql-test/r/upgrade.result @@ -84,3 +84,23 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin2 drop database `a-b-c`; drop database `tabc`; +use `#mysql50#a-b-c`; +create table t1(f1 char(10)); +show databases like '%a-b-c%'; +Database (%a-b-c%) +#mysql50#a-b-c +ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME; +show databases like '%a-b-c%'; +Database (%a-b-c%) +a-b-c +show create view `a-b-c`.v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `a`.`f1` AS `f1` from (`a-b-c`.`t1` `a` join `information_schema`.`tables` `b`) where (convert(`a`.`f1` using utf8) = `b`.`TABLE_NAME`) utf8 utf8_general_ci +Warnings: +Note 1600 Creation context of view `a-b-c`.`v1' is invalid +select * from `a-b-c`.v1; +f1 +Warnings: +Note 1600 Creation context of view `a-b-c`.`v1' is invalid +drop database `a-b-c`; +use test; diff --git a/mysql-test/t/upgrade.test b/mysql-test/t/upgrade.test index 437b0f47cc0..5c4abc7559d 100644 --- a/mysql-test/t/upgrade.test +++ b/mysql-test/t/upgrade.test @@ -89,3 +89,33 @@ show create table `a-b-c`.`t1`; drop database `a-b-c`; drop database `tabc`; +# +# Bug#43385 Cannot ALTER DATABASE ... UPGRADE DATA DIRECTORY NAME when Views exist +# +let $MYSQLD_DATADIR= `select @@datadir`; +--mkdir $MYSQLD_DATADIR/a-b-c +use `#mysql50#a-b-c`; +create table t1(f1 char(10)); + +--write_file $MYSQLD_DATADIR/a-b-c/v1.frm +TYPE=VIEW +query=select `a`.`f1` AS `f1` from `a-b-c`.`t1` `a` join `information_schema`.`tables` `b` where (convert(`a`.`f1` using utf8) = `b`.`TABLE_NAME`) +md5=068271f1c657fe115e497856ca0fa493 +updatable=0 +algorithm=0 +definer_user=root +definer_host=localhost +suid=2 +with_check_option=0 +timestamp=2009-04-10 11:53:37 +create-version=1 +source=select f1 from `a-b-c`.t1 a, information_schema.tables b\nwhere a.f1 = b.table_name +EOF + +show databases like '%a-b-c%'; +ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME; +show databases like '%a-b-c%'; +show create view `a-b-c`.v1; +select * from `a-b-c`.v1; +drop database `a-b-c`; +use test; diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index fc87356e452..ced69388009 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -301,8 +301,13 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, } break; case FRMTYPE_VIEW: - /* change of schema is not allowed */ - if (strcmp(ren_table->db, new_db)) + /* + change of schema is not allowed + except of ALTER ...UPGRADE DATA DIRECTORY NAME command + because a view has valid internal db&table names in this case. + */ + if (thd->lex->sql_command != SQLCOM_ALTER_DB_UPGRADE && + strcmp(ren_table->db, new_db)) my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db, new_db); else From 7ff5b7a9369e97a66d5773df5092553f5e976888 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Mon, 13 Apr 2009 18:09:10 +0500 Subject: [PATCH 35/85] Bug#43385 Cannot ALTER DATABASE ... UPGRADE DATA DIRECTORY NAME when Views exist(addon) mysql_rename_view can not rename view if database is not the same. The fix is to add new argument 'new_db' to mysql_rename_view() and allow rename with different databases (only for ALTER DATABASE ... UPGRADE DATA DIRECTORY NAME). --- mysql-test/t/upgrade.test | 2 ++ sql/parse_file.cc | 5 +++-- sql/parse_file.h | 2 +- sql/sql_rename.cc | 2 +- sql/sql_view.cc | 10 ++++++---- sql/sql_view.h | 3 ++- 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/mysql-test/t/upgrade.test b/mysql-test/t/upgrade.test index 5c4abc7559d..e096b6520a1 100644 --- a/mysql-test/t/upgrade.test +++ b/mysql-test/t/upgrade.test @@ -116,6 +116,8 @@ show databases like '%a-b-c%'; ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME; show databases like '%a-b-c%'; show create view `a-b-c`.v1; +--disable_ps_protocol select * from `a-b-c`.v1; +--enable_ps_protocol drop database `a-b-c`; use test; diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 07ea434e8e0..f2dbeba1bbf 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -302,6 +302,7 @@ err_w_file: @thd thread handler @param schema name of given schema @param old_name original file name + @param new_db new schema @param new_name new file name @retval @@ -311,14 +312,14 @@ err_w_file: */ my_bool rename_in_schema_file(THD *thd, const char *schema, const char *old_name, - const char *new_name) + const char *new_db, const char *new_name) { char old_path[FN_REFLEN], new_path[FN_REFLEN], arc_path[FN_REFLEN]; build_table_filename(old_path, sizeof(old_path) - 1, schema, old_name, reg_ext, 0); build_table_filename(new_path, sizeof(new_path) - 1, - schema, new_name, reg_ext, 0); + new_db, new_name, reg_ext, 0); if (my_rename(old_path, new_path, MYF(MY_WME))) return 1; diff --git a/sql/parse_file.h b/sql/parse_file.h index cfac69cc471..84647e45927 100644 --- a/sql/parse_file.h +++ b/sql/parse_file.h @@ -83,7 +83,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, uchar* base, File_option *parameters); my_bool rename_in_schema_file(THD *thd, const char *schema, const char *old_name, - const char *new_name); + const char *new_db, const char *new_name); class File_parser: public Sql_alloc { diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index ced69388009..d4331b12cd4 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -311,7 +311,7 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db, new_db); else - rc= mysql_rename_view(thd, new_alias, ren_table); + rc= mysql_rename_view(thd, new_db, new_alias, ren_table); break; default: DBUG_ASSERT(0); // should never happen diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 4d523ddf9ac..4f207f78688 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1912,6 +1912,7 @@ int view_checksum(THD *thd, TABLE_LIST *view) Parameters: thd thread handler + new_db new name of database new_name new name of view view view @@ -1921,6 +1922,7 @@ int view_checksum(THD *thd, TABLE_LIST *view) */ bool mysql_rename_view(THD *thd, + const char *new_db, const char *new_name, TABLE_LIST *view) { @@ -1959,16 +1961,16 @@ mysql_rename_view(THD *thd, goto err; /* rename view and it's backups */ - if (rename_in_schema_file(thd, view->db, view->table_name, new_name)) + if (rename_in_schema_file(thd, view->db, view->table_name, new_db, new_name)) goto err; dir.str= dir_buff; dir.length= build_table_filename(dir_buff, sizeof(dir_buff) - 1, - view->db, "", "", 0); + new_db, "", "", 0); pathstr.str= path_buff; pathstr.length= build_table_filename(path_buff, sizeof(path_buff) - 1, - view->db, new_name, reg_ext, 0); + new_db, new_name, reg_ext, 0); file.str= pathstr.str + dir.length; file.length= pathstr.length - dir.length; @@ -1977,7 +1979,7 @@ mysql_rename_view(THD *thd, (uchar*)&view_def, view_parameters)) { /* restore renamed view in case of error */ - rename_in_schema_file(thd, view->db, new_name, view->table_name); + rename_in_schema_file(thd, new_db, new_name, view->db, view->table_name); goto err; } } else diff --git a/sql/sql_view.h b/sql/sql_view.h index b8138663489..e08c2168e14 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -37,7 +37,8 @@ int view_checksum(THD *thd, TABLE_LIST *view); extern TYPELIB updatable_views_with_limit_typelib; bool check_duplicate_names(List& item_list, bool gen_unique_view_names); -bool mysql_rename_view(THD *thd, const char *new_name, TABLE_LIST *view); +bool mysql_rename_view(THD *thd, const char *new_db, const char *new_name, + TABLE_LIST *view); #define VIEW_ANY_ACL (SELECT_ACL | UPDATE_ACL | INSERT_ACL | DELETE_ACL) From 5592d206f854ee0a772d158e6f1617cbd7730132 Mon Sep 17 00:00:00 2001 From: Narayanan V Date: Tue, 14 Apr 2009 16:32:55 +0530 Subject: [PATCH 36/85] Importing test cases for IBMDB2I The current patch -- Adds the ibmdb2i suite -- related include(.inc) files -- tests for Bug#44020 and Bug#44025 --- mysql-test/suite/ibmdb2i/include/have_i61.inc | 20 +++++++++++++++++++ .../suite/ibmdb2i/include/have_ibmdb2i.inc | 6 ++++++ .../suite/ibmdb2i/r/ibmdb2i_bug_44020.result | 11 ++++++++++ .../suite/ibmdb2i/r/ibmdb2i_bug_44025.result | 4 ++++ .../suite/ibmdb2i/t/ibmdb2i_bug_44020.test | 9 +++++++++ .../suite/ibmdb2i/t/ibmdb2i_bug_44025.test | 9 +++++++++ 6 files changed, 59 insertions(+) create mode 100644 mysql-test/suite/ibmdb2i/include/have_i61.inc create mode 100644 mysql-test/suite/ibmdb2i/include/have_ibmdb2i.inc create mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44020.result create mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44025.result create mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44020.test create mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44025.test diff --git a/mysql-test/suite/ibmdb2i/include/have_i61.inc b/mysql-test/suite/ibmdb2i/include/have_i61.inc new file mode 100644 index 00000000000..84b9a17c1d8 --- /dev/null +++ b/mysql-test/suite/ibmdb2i/include/have_i61.inc @@ -0,0 +1,20 @@ +# Check for IBM i 6.1 or later +--disable_query_log +system uname -rv > $MYSQLTEST_VARDIR/tmp/version; +--disable_warnings +drop table if exists uname_vr; +--enable_warnings +create temporary table uname_vr (r int, v int); +--disable_warnings +eval LOAD DATA INFILE "$MYSQLTEST_VARDIR/tmp/version" into table uname_vr fields terminated by ' '; +--enable_warnings +let $ok = `select count(*) from uname_vr where v > 5`; +drop table uname_vr; +remove_file $MYSQLTEST_VARDIR/tmp/version; +--enable_query_log +if (!$ok) +{ + skip "Need IBM i 6.1 or later"; +} + + diff --git a/mysql-test/suite/ibmdb2i/include/have_ibmdb2i.inc b/mysql-test/suite/ibmdb2i/include/have_ibmdb2i.inc new file mode 100644 index 00000000000..f3ef0b4f1ac --- /dev/null +++ b/mysql-test/suite/ibmdb2i/include/have_ibmdb2i.inc @@ -0,0 +1,6 @@ +if (!`SELECT count(*) FROM information_schema.engines WHERE + (support = 'YES' OR support = 'DEFAULT') AND + engine = 'ibmdb2i'`) +{ + skip Need ibmdb2i engine; +} diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44020.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44020.result new file mode 100644 index 00000000000..ddf92db6bca --- /dev/null +++ b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44020.result @@ -0,0 +1,11 @@ +create schema `A12345_@$#`; +create table `A12345_@$#`.t1 (i int) engine=ibmdb2i; +show create table `A12345_@$#`.t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL +) ENGINE=IBMDB2I DEFAULT CHARSET=latin1 +select * from `A12345_@$#`.t1; +i +drop table `A12345_@$#`.t1; +drop schema `A12345_@$#`; diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44025.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44025.result new file mode 100644 index 00000000000..10a3070fcc4 --- /dev/null +++ b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44025.result @@ -0,0 +1,4 @@ +create table t1 (c char(10) collate utf8_swedish_ci, index(c)) engine=ibmdb2i; +drop table t1; +create table t1 (c char(10) collate ucs2_swedish_ci, index(c)) engine=ibmdb2i; +drop table t1; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44020.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44020.test new file mode 100644 index 00000000000..09a7c75cfc0 --- /dev/null +++ b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44020.test @@ -0,0 +1,9 @@ +source suite/ibmdb2i/include/have_ibmdb2i.inc; +source include/have_case_sensitive_file_system.inc; + +create schema `A12345_@$#`; +create table `A12345_@$#`.t1 (i int) engine=ibmdb2i; +show create table `A12345_@$#`.t1; +select * from `A12345_@$#`.t1; +drop table `A12345_@$#`.t1; +drop schema `A12345_@$#`; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44025.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44025.test new file mode 100644 index 00000000000..9b033a2298f --- /dev/null +++ b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44025.test @@ -0,0 +1,9 @@ +source suite/ibmdb2i/include/have_ibmdb2i.inc; +source suite/ibmdb2i/include/have_i61.inc; + + +create table t1 (c char(10) collate utf8_swedish_ci, index(c)) engine=ibmdb2i; +drop table t1; + +create table t1 (c char(10) collate ucs2_swedish_ci, index(c)) engine=ibmdb2i; +drop table t1; From 9952fa7a36dc78cf8d5bcf7e46642092b5e9770c Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Tue, 14 Apr 2009 19:19:15 +0500 Subject: [PATCH 37/85] Bug #42563: Message tells me to repair table though Storage Engine doesn't allow me to. In case of incompatible changes between old and new table versions, the mysqlcheck program prints error messages like this: error: Table upgrade required. Please do "REPAIR TABLE `table_name`" to fix it! However, InnoDB doesn't support REPAIR TABLE query, so the message is confusing. Error message text has been changed to: Table upgrade required. Please do "REPAIR TABLE `table_name`" or dump/reload to fix it!" --- mysql-test/r/repair.result | 2 +- mysql-test/r/varbinary.result | 2 +- sql/share/errmsg.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result index 0cb2dff6f64..5bb3dd76fed 100644 --- a/mysql-test/r/repair.result +++ b/mysql-test/r/repair.result @@ -126,7 +126,7 @@ id # Run CHECK TABLE, it should indicate table need a REPAIR TABLE CHECK TABLE t1 FOR UPGRADE; Table Op Msg_type Msg_text -test.t1 check error Table upgrade required. Please do "REPAIR TABLE `t1`" to fix it! +test.t1 check error Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! # REPAIR old table USE_FRM should fail REPAIR TABLE t1 USE_FRM; Table Op Msg_type Msg_text diff --git a/mysql-test/r/varbinary.result b/mysql-test/r/varbinary.result index 271d7a0fe8d..b623ea1d86e 100644 --- a/mysql-test/r/varbinary.result +++ b/mysql-test/r/varbinary.result @@ -38,7 +38,7 @@ length(a) length(b) 255 3 CHECK TABLE t1 FOR UPGRADE; Table Op Msg_type Msg_text -test.t1 check error Table upgrade required. Please do "REPAIR TABLE `t1`" to fix it! +test.t1 check error Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! REPAIR TABLE t1; Table Op Msg_type Msg_text test.t1 repair status OK diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index aa1521acab6..f9b66990e93 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5614,7 +5614,7 @@ ER_SP_WRONG_NAME 42000 eng "Incorrect routine name '%-.192s'" ger "Ungültiger Routinenname '%-.192s'" ER_TABLE_NEEDS_UPGRADE - eng "Table upgrade required. Please do \"REPAIR TABLE `%-.32s`\" to fix it!" + eng "Table upgrade required. Please do \"REPAIR TABLE `%-.32s`\" or dump/reload to fix it!" ger "Tabellenaktualisierung erforderlich. Bitte zum Reparieren \"REPAIR TABLE `%-.32s`\" eingeben!" ER_SP_NO_AGGREGATE 42000 eng "AGGREGATE is not supported for stored functions" From 09d4c1da0febf90504ba883c3fd721dac5ed4f34 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 14 Apr 2009 14:05:32 +0200 Subject: [PATCH 38/85] Bug#44164: TL_WRITE has no description in lock_descriptions[] The problem was that new lock types were being added without a corresponding description. Since the lock types (enum values) are used as indices to the description array, the descriptions could be shifted depending on the lock type. The solution is to ensure that every lock type has a correspondent description. --- include/thr_lock.h | 4 ++++ sql/sql_test.cc | 28 ++++++++++++++++------------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/include/thr_lock.h b/include/thr_lock.h index e409df30972..fb70c57c0e7 100644 --- a/include/thr_lock.h +++ b/include/thr_lock.h @@ -27,6 +27,10 @@ extern "C" { struct st_thr_lock; extern ulong locks_immediate,locks_waited ; +/* + Important: if a new lock type is added, a matching lock description + must be added to sql_test.cc's lock_descriptions array. +*/ enum thr_lock_type { TL_IGNORE=-1, TL_UNLOCK, /* UNLOCK ANY LOCK */ /* diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 78932396efe..eeb9a21b6f5 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -33,18 +33,20 @@ static const char *lock_descriptions[] = { - "No lock", - "Low priority read lock", - "Shared Read lock", - "High priority read lock", - "Read lock without concurrent inserts", - "Write lock that allows other writers", - "Write lock, but allow reading", - "Concurrent insert lock", - "Lock Used by delayed insert", - "Low priority write lock", - "High priority write lock", - "Highest priority write lock" + /* TL_UNLOCK */ "No lock", + /* TL_READ_DEFAULT */ NULL, + /* TL_READ */ "Low priority read lock", + /* TL_READ_WITH_SHARED_LOCKS */ "Shared read lock", + /* TL_READ_HIGH_PRIORITY */ "High priority read lock", + /* TL_READ_NO_INSERT */ "Read lock without concurrent inserts", + /* TL_WRITE_ALLOW_WRITE */ "Write lock that allows other writers", + /* TL_WRITE_ALLOW_READ */ "Write lock, but allow reading", + /* TL_WRITE_CONCURRENT_INSERT */ "Concurrent insert lock", + /* TL_WRITE_DELAYED */ "Lock used by delayed insert", + /* TL_WRITE_DEFAULT */ NULL, + /* TL_WRITE_LOW_PRIORITY */ "Low priority write lock", + /* TL_WRITE */ "High priority write lock", + /* TL_WRITE_ONLY */ "Highest priority write lock" }; @@ -75,6 +77,8 @@ void print_cached_tables(void) uint idx,count,unused; TABLE *start_link,*lnk; + compile_time_assert(TL_WRITE_ONLY+1 == array_elements(lock_descriptions)); + /* purecov: begin tested */ VOID(pthread_mutex_lock(&LOCK_open)); puts("DB Table Version Thread Open Lock"); From 04ee3f2ffac9936999b4c1d2bcd1050c4da0d1cf Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 14 Apr 2009 19:16:30 +0500 Subject: [PATCH 39/85] Bug#41268 Help Text for \c is misleading in client command line interface(addon) fixed message for 'help' command --- client/mysql.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysql.cc b/client/mysql.cc index 983d7719c3c..93aab390e5a 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -241,7 +241,7 @@ typedef struct { static COMMANDS commands[] = { { "?", '?', com_help, 1, "Synonym for `help'." }, - { "clear", 'c', com_clear, 0, "Clear command."}, + { "clear", 'c', com_clear, 0, "Clear the current input statement."}, { "connect",'r', com_connect,1, "Reconnect to the server. Optional arguments are db and host." }, { "delimiter", 'd', com_delimiter, 1, From a8f7d47e6a8a29ceff2e9b7073318ac69ab8da32 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Wed, 15 Apr 2009 12:43:17 +0100 Subject: [PATCH 40/85] BUG#41793 rpl_binlog_corruption disabled in main (needs new mtr) The test case was missing "let $slave_sql_errno= 1594;". --- mysql-test/suite/rpl/t/disabled.def | 1 - mysql-test/suite/rpl/t/rpl_binlog_corruption.test | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index e7691776027..b7cb6da8127 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -10,5 +10,4 @@ # ############################################################################## -rpl_binlog_corruption : BUG#41793 2008-12-30 sven rpl_binlog_corruption disabled in main (needs new mtr) rpl_cross_version : BUG#42311 2009-03-27 joro rpl_cross_version fails on macosx diff --git a/mysql-test/suite/rpl/t/rpl_binlog_corruption.test b/mysql-test/suite/rpl/t/rpl_binlog_corruption.test index 39799180f8b..dfab035a7a8 100644 --- a/mysql-test/suite/rpl/t/rpl_binlog_corruption.test +++ b/mysql-test/suite/rpl/t/rpl_binlog_corruption.test @@ -34,6 +34,7 @@ source include/setup_fake_relay_log.inc; --echo ==== Test ==== START SLAVE SQL_THREAD; +let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE source include/wait_for_slave_sql_error.inc; let $error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1); --echo Last_SQL_Error = $error From df7f5472c9e153460c6fbdc46842b6b6b5995bcd Mon Sep 17 00:00:00 2001 From: Satya B Date: Wed, 15 Apr 2009 17:16:08 +0530 Subject: [PATCH 41/85] Applying InnoDB snashot 5.1-ss4699, part 1. Fixes BUG#39320 and other problems 1) BUG#39320 - innodb crash in file btr/btr0pcur.c line 217 with innodb_locks_unsafe_for_binlog 2) Fixes bug in multi-table semi consistent reads. 3) Fixes email address from dev@innodb.com to innodb_dev_ww@oracle.com 4) Fixes warning message generated by main.innodb test Detailed revision comments: r4399 | marko | 2009-03-12 09:38:05 +0200 (Thu, 12 Mar 2009) | 5 lines branches/5.1: row_sel_get_clust_rec_for_mysql(): Store the cursor position also for unlock_row(). (Bug #39320) rb://96 approved by Heikki Tuuri. r4400 | marko | 2009-03-12 10:06:44 +0200 (Thu, 12 Mar 2009) | 8 lines branches/5.1: Fix a bug in multi-table semi-consistent reads. Remember the acquired record locks per table handle (row_prebuilt_t) rather than per transaction (trx_t), so that unlock_row should successfully unlock all non-matching rows in multi-table operations. This deficiency was found while investigating Bug #39320. rb://94 approved by Heikki Tuuri. r4481 | marko | 2009-03-19 15:01:48 +0200 (Thu, 19 Mar 2009) | 6 lines branches/5.1: row_unlock_for_mysql(): Do not unlock records that were modified by the current transaction. This bug was introduced or unmasked in r4400. rb://97 approved by Heikki Tuuri r4573 | vasil | 2009-03-30 14:17:13 +0300 (Mon, 30 Mar 2009) | 4 lines branches/5.1: Fix email address from dev@innodb.com to innodb_dev_ww@oracle.com r4574 | vasil | 2009-03-30 14:27:08 +0300 (Mon, 30 Mar 2009) | 38 lines branches/5.1: Restore the state of INNODB_THREAD_CONCURRENCY to silence this warning: TEST RESULT TIME (ms) ------------------------------------------------------------ worker[1] Using MTR_BUILD_THREAD 250, with reserved ports 12500..12509 main.innodb [ pass ] 8803 MTR's internal check of the test case 'main.innodb' failed. This means that the test case does not preserve the state that existed before the test case was executed. Most likely the test case did not do a proper clean-up. This is the diff of the states of the servers before and after the test case was executed: mysqltest: Logging to '/tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.log'. mysqltest: Results saved in '/tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.result'. mysqltest: Connecting to server localhost:12500 (socket /tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/mysqld.1.sock) as 'root', connection 'default', attempt 0 ... mysqltest: ... Connected. mysqltest: Start processing test commands from './include/check-testcase.test' ... mysqltest: ... Done processing test commands. --- /tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.result 2009-03-30 14:12:31.000000000 +0300 +++ /tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.reject 2009-03-30 14:12:41.000000000 +0300 @@ -99,7 +99,7 @@ INNODB_SUPPORT_XA ON INNODB_SYNC_SPIN_LOOPS 20 INNODB_TABLE_LOCKS ON -INNODB_THREAD_CONCURRENCY 8 +INNODB_THREAD_CONCURRENCY 16 INNODB_THREAD_SLEEP_DELAY 10000 INSERT_ID 0 INTERACTIVE_TIMEOUT 28800 mysqltest: Result content mismatch not ok r4576 | vasil | 2009-03-30 16:25:10 +0300 (Mon, 30 Mar 2009) | 4 lines branches/5.1: Revert a change to Makefile.am that I committed accidentally in c4574. --- mysql-test/r/innodb-semi-consistent.result | 7 ++ mysql-test/t/innodb-semi-consistent.test | 13 ++++ mysql-test/t/innodb.test | 14 +++- storage/innobase/include/row0mysql.h | 15 ++++ storage/innobase/include/trx0trx.h | 42 ----------- storage/innobase/include/trx0trx.ic | 58 --------------- storage/innobase/lock/lock0lock.c | 21 ------ storage/innobase/row/row0mysql.c | 85 ++++++++++++++-------- storage/innobase/row/row0sel.c | 43 ++++++----- storage/innobase/trx/trx0trx.c | 2 - 10 files changed, 125 insertions(+), 175 deletions(-) diff --git a/mysql-test/r/innodb-semi-consistent.result b/mysql-test/r/innodb-semi-consistent.result index 55e3cb5c7b4..ca0e362ef80 100644 --- a/mysql-test/r/innodb-semi-consistent.result +++ b/mysql-test/r/innodb-semi-consistent.result @@ -38,3 +38,10 @@ a 11 7 drop table t1; +create table t1 (a int, b int) engine=myisam; +create table t2 (c int, d int, key (c)) engine=innodb; +insert into t1 values (1,1); +insert into t2 values (1,2); +set session transaction isolation level read committed; +delete from t1 using t1 join t2 on t1.a = t2.c where t2.d in (1); +drop table t1, t2; diff --git a/mysql-test/t/innodb-semi-consistent.test b/mysql-test/t/innodb-semi-consistent.test index 6d3020bb560..61ad7815ca9 100644 --- a/mysql-test/t/innodb-semi-consistent.test +++ b/mysql-test/t/innodb-semi-consistent.test @@ -53,3 +53,16 @@ drop table t1; connection default; disconnect a; disconnect b; + +# Bug 39320 +create table t1 (a int, b int) engine=myisam; +create table t2 (c int, d int, key (c)) engine=innodb; +insert into t1 values (1,1); +insert into t2 values (1,2); +connect (a,localhost,root,,); +connection a; +set session transaction isolation level read committed; +delete from t1 using t1 join t2 on t1.a = t2.c where t2.d in (1); +connection default; +disconnect a; +drop table t1, t2; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index b0353ed5268..9221e389f97 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -6,7 +6,9 @@ # Use innodb_mysql.[test|result] files instead. # # # # If nevertheless you need to make some changes here, please, forward # -# your commit message To: dev@innodb.com Cc: dev-innodb@mysql.com # +# your commit message # +# To: innodb_dev_ww@oracle.com # +# Cc: dev-innodb@mysql.com # # (otherwise your changes may be erased). # # # ####################################################################### @@ -17,6 +19,10 @@ # Small basic test with ignore # +-- disable_query_log +SET @innodb_thread_concurrency_orig = @@innodb_thread_concurrency; +-- enable_query_log + --disable_warnings drop table if exists t1,t2,t3,t4; drop database if exists mysqltest; @@ -2524,6 +2530,8 @@ DROP TABLE bug35537; DISCONNECT c1; CONNECTION default; +SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig; + ####################################################################### # # # Please, DO NOT TOUCH this file as well as the innodb.result file. # @@ -2532,7 +2540,9 @@ CONNECTION default; # Use innodb_mysql.[test|result] files instead. # # # # If nevertheless you need to make some changes here, please, forward # -# your commit message To: dev@innodb.com Cc: dev-innodb@mysql.com # +# your commit message # +# To: innodb_dev_ww@oracle.com # +# Cc: dev-innodb@mysql.com # # (otherwise your changes may be erased). # # # ####################################################################### diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 9b2f3250486..5430190fa51 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -656,6 +656,21 @@ struct row_prebuilt_struct { This eliminates lock waits in some cases; note that this breaks serializability. */ + ulint new_rec_locks; /* normally 0; if + srv_locks_unsafe_for_binlog is + TRUE or session is using READ + COMMITTED isolation level, in a + cursor search, if we set a new + record lock on an index, this is + incremented; this is used in + releasing the locks under the + cursors if we are performing an + UPDATE and we determine after + retrieving the row that it does + not need to be locked; thus, + these can be used to implement a + 'mini-rollback' that releases + the latest record locks */ ulint mysql_prefix_len;/* byte offset of the end of the last requested column */ ulint mysql_row_len; /* length in bytes of a row in the diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 5017c15aaf0..f0833bc6f21 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -21,34 +21,6 @@ Created 3/26/1996 Heikki Tuuri extern ulint trx_n_mysql_transactions; -/***************************************************************** -Resets the new record lock info in a transaction struct. */ -UNIV_INLINE -void -trx_reset_new_rec_lock_info( -/*========================*/ - trx_t* trx); /* in: transaction struct */ -/***************************************************************** -Registers that we have set a new record lock on an index. We only have space -to store 2 indexes! If this is called to store more than 2 indexes after -trx_reset_new_rec_lock_info(), then this function does nothing. */ -UNIV_INLINE -void -trx_register_new_rec_lock( -/*======================*/ - trx_t* trx, /* in: transaction struct */ - dict_index_t* index); /* in: trx sets a new record lock on this - index */ -/***************************************************************** -Checks if trx has set a new record lock on an index. */ -UNIV_INLINE -ibool -trx_new_rec_locks_contain( -/*======================*/ - /* out: TRUE if trx has set a new record lock - on index */ - trx_t* trx, /* in: transaction struct */ - dict_index_t* index); /* in: index */ /************************************************************************ Releases the search latch if trx has reserved it. */ @@ -527,20 +499,6 @@ struct trx_struct{ lock_t* auto_inc_lock; /* possible auto-inc lock reserved by the transaction; note that it is also in the lock list trx_locks */ - dict_index_t* new_rec_locks[2];/* these are normally NULL; if - srv_locks_unsafe_for_binlog is TRUE - or session is using READ COMMITTED - isolation level, - in a cursor search, if we set a new - record lock on an index, this is set - to point to the index; this is - used in releasing the locks under the - cursors if we are performing an UPDATE - and we determine after retrieving - the row that it does not need to be - locked; thus, these can be used to - implement a 'mini-rollback' that - releases the latest record locks */ UT_LIST_NODE_T(trx_t) trx_list; /* list of transactions */ UT_LIST_NODE_T(trx_t) diff --git a/storage/innobase/include/trx0trx.ic b/storage/innobase/include/trx0trx.ic index d562db233e9..09b2f822ff7 100644 --- a/storage/innobase/include/trx0trx.ic +++ b/storage/innobase/include/trx0trx.ic @@ -38,61 +38,3 @@ trx_start_if_not_started_low( trx_start_low(trx, ULINT_UNDEFINED); } } - -/***************************************************************** -Resets the new record lock info in a transaction struct. */ -UNIV_INLINE -void -trx_reset_new_rec_lock_info( -/*========================*/ - trx_t* trx) /* in: transaction struct */ -{ - trx->new_rec_locks[0] = NULL; - trx->new_rec_locks[1] = NULL; -} - -/***************************************************************** -Registers that we have set a new record lock on an index. We only have space -to store 2 indexes! If this is called to store more than 2 indexes after -trx_reset_new_rec_lock_info(), then this function does nothing. */ -UNIV_INLINE -void -trx_register_new_rec_lock( -/*======================*/ - trx_t* trx, /* in: transaction struct */ - dict_index_t* index) /* in: trx sets a new record lock on this - index */ -{ - if (trx->new_rec_locks[0] == NULL) { - trx->new_rec_locks[0] = index; - - return; - } - - if (trx->new_rec_locks[0] == index) { - - return; - } - - if (trx->new_rec_locks[1] != NULL) { - - return; - } - - trx->new_rec_locks[1] = index; -} - -/***************************************************************** -Checks if trx has set a new record lock on an index. */ -UNIV_INLINE -ibool -trx_new_rec_locks_contain( -/*======================*/ - /* out: TRUE if trx has set a new record lock - on index */ - trx_t* trx, /* in: transaction struct */ - dict_index_t* index) /* in: index */ -{ - return(trx->new_rec_locks[0] == index - || trx->new_rec_locks[1] == index); -} diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index d9bc8ba09e4..5afd19aa7e7 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -1970,12 +1970,6 @@ lock_rec_lock_fast( if (lock == NULL) { if (!impl) { lock_rec_create(mode, rec, index, trx); - - if (srv_locks_unsafe_for_binlog - || trx->isolation_level - == TRX_ISO_READ_COMMITTED) { - trx_register_new_rec_lock(trx, index); - } } return(TRUE); @@ -1999,11 +1993,6 @@ lock_rec_lock_fast( if (!lock_rec_get_nth_bit(lock, heap_no)) { lock_rec_set_nth_bit(lock, heap_no); - if (srv_locks_unsafe_for_binlog - || trx->isolation_level - == TRX_ISO_READ_COMMITTED) { - trx_register_new_rec_lock(trx, index); - } } } @@ -2058,22 +2047,12 @@ lock_rec_lock_slow( enough already granted on the record, we have to wait. */ err = lock_rec_enqueue_waiting(mode, rec, index, thr); - - if (srv_locks_unsafe_for_binlog - || trx->isolation_level == TRX_ISO_READ_COMMITTED) { - trx_register_new_rec_lock(trx, index); - } } else { if (!impl) { /* Set the requested lock on the record */ lock_rec_add_to_queue(LOCK_REC | mode, rec, index, trx); - if (srv_locks_unsafe_for_binlog - || trx->isolation_level - == TRX_ISO_READ_COMMITTED) { - trx_register_new_rec_lock(trx, index); - } } err = DB_SUCCESS; diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 088d944cb91..2d9ed4fc944 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1476,12 +1476,9 @@ row_unlock_for_mysql( and clust_pcur, and we do not need to reposition the cursors. */ { - dict_index_t* index; btr_pcur_t* pcur = prebuilt->pcur; btr_pcur_t* clust_pcur = prebuilt->clust_pcur; trx_t* trx = prebuilt->trx; - rec_t* rec; - mtr_t mtr; ut_ad(prebuilt && trx); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); @@ -1501,9 +1498,12 @@ row_unlock_for_mysql( trx->op_info = "unlock_row"; - index = btr_pcur_get_btr_cur(pcur)->index; + if (prebuilt->new_rec_locks >= 1) { - if (index != NULL && trx_new_rec_locks_contain(trx, index)) { + rec_t* rec; + dict_index_t* index; + dulint rec_trx_id; + mtr_t mtr; mtr_start(&mtr); @@ -1514,43 +1514,64 @@ row_unlock_for_mysql( } rec = btr_pcur_get_rec(pcur); + index = btr_pcur_get_btr_cur(pcur)->index; - lock_rec_unlock(trx, rec, prebuilt->select_lock_type); + if (prebuilt->new_rec_locks >= 2) { + /* Restore the cursor position and find the record + in the clustered index. */ - mtr_commit(&mtr); + if (!has_latches_on_recs) { + btr_pcur_restore_position(BTR_SEARCH_LEAF, + clust_pcur, &mtr); + } - /* If the search was done through the clustered index, then - we have not used clust_pcur at all, and we must NOT try to - reset locks on clust_pcur. The values in clust_pcur may be - garbage! */ - - if (index->type & DICT_CLUSTERED) { - - goto func_exit; - } - } - - index = btr_pcur_get_btr_cur(clust_pcur)->index; - - if (index != NULL && trx_new_rec_locks_contain(trx, index)) { - - mtr_start(&mtr); - - /* Restore the cursor position and find the record */ - - if (!has_latches_on_recs) { - btr_pcur_restore_position(BTR_SEARCH_LEAF, clust_pcur, - &mtr); + rec = btr_pcur_get_rec(clust_pcur); + index = btr_pcur_get_btr_cur(clust_pcur)->index; } - rec = btr_pcur_get_rec(clust_pcur); + /* If the record has been modified by this + transaction, do not unlock it. */ + ut_a(index->type & DICT_CLUSTERED); - lock_rec_unlock(trx, rec, prebuilt->select_lock_type); + if (index->trx_id_offset) { + rec_trx_id = trx_read_trx_id(rec + + index->trx_id_offset); + } else { + mem_heap_t* heap = NULL; + ulint offsets_[REC_OFFS_NORMAL_SIZE]; + ulint* offsets = offsets_; + + *offsets_ = (sizeof offsets_) / sizeof *offsets_; + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); + + rec_trx_id = row_get_rec_trx_id(rec, index, offsets); + + if (UNIV_LIKELY_NULL(heap)) { + mem_heap_free(heap); + } + } + + if (ut_dulint_cmp(rec_trx_id, trx->id) != 0) { + /* We did not update the record: unlock it */ + + rec = btr_pcur_get_rec(pcur); + index = btr_pcur_get_btr_cur(pcur)->index; + + lock_rec_unlock(trx, rec, prebuilt->select_lock_type); + + if (prebuilt->new_rec_locks >= 2) { + rec = btr_pcur_get_rec(clust_pcur); + index = btr_pcur_get_btr_cur(clust_pcur)->index; + + lock_rec_unlock(trx, rec, + prebuilt->select_lock_type); + } + } mtr_commit(&mtr); } -func_exit: trx->op_info = ""; return(DB_SUCCESS); diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index f53dfe8a686..1746fb39f43 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -2901,8 +2901,9 @@ row_sel_get_clust_rec_for_mysql( func_exit: *out_rec = clust_rec; - if (prebuilt->select_lock_type == LOCK_X) { - /* We may use the cursor in update: store its position */ + if (prebuilt->select_lock_type != LOCK_NONE) { + /* We may use the cursor in update or in unlock_row(): + store its position */ btr_pcur_store_position(prebuilt->clust_pcur, mtr); } @@ -3303,13 +3304,7 @@ row_search_for_mysql( is set or session is using a READ COMMITED isolation level. Then we are able to remove the record locks set here on an individual row. */ - - if ((srv_locks_unsafe_for_binlog - || trx->isolation_level == TRX_ISO_READ_COMMITTED) - && prebuilt->select_lock_type != LOCK_NONE) { - - trx_reset_new_rec_lock_info(trx); - } + prebuilt->new_rec_locks = 0; /*-------------------------------------------------------------*/ /* PHASE 1: Try to pop the row from the prefetch cache */ @@ -3951,6 +3946,12 @@ no_gap_lock: switch (err) { rec_t* old_vers; case DB_SUCCESS: + if (srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) { + /* Note that a record of + prebuilt->index was locked. */ + prebuilt->new_rec_locks = 1; + } break; case DB_LOCK_WAIT: if (UNIV_LIKELY(prebuilt->row_read_type @@ -3981,7 +3982,7 @@ no_gap_lock: if (UNIV_LIKELY(trx->wait_lock != NULL)) { lock_cancel_waiting_and_release( trx->wait_lock); - trx_reset_new_rec_lock_info(trx); + prebuilt->new_rec_locks = 0; } else { mutex_exit(&kernel_mutex); @@ -3993,6 +3994,9 @@ no_gap_lock: ULINT_UNDEFINED, &heap); err = DB_SUCCESS; + /* Note that a record of + prebuilt->index was locked. */ + prebuilt->new_rec_locks = 1; break; } mutex_exit(&kernel_mutex); @@ -4142,6 +4146,15 @@ requires_clust_rec: goto next_rec; } + if ((srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) + && prebuilt->select_lock_type != LOCK_NONE) { + /* Note that both the secondary index record + and the clustered index record were locked. */ + ut_ad(prebuilt->new_rec_locks == 1); + prebuilt->new_rec_locks = 2; + } + if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec, comp))) { /* The record is delete marked: we can skip it */ @@ -4267,13 +4280,7 @@ next_rec: prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT; } did_semi_consistent_read = FALSE; - - if (UNIV_UNLIKELY(srv_locks_unsafe_for_binlog - || trx->isolation_level == TRX_ISO_READ_COMMITTED) - && prebuilt->select_lock_type != LOCK_NONE) { - - trx_reset_new_rec_lock_info(trx); - } + prebuilt->new_rec_locks = 0; /*-------------------------------------------------------------*/ /* PHASE 5: Move the cursor to the next index record */ @@ -4379,7 +4386,7 @@ lock_wait_or_error: rec_loop we will again try to set a lock, and new_rec_lock_info in trx will be right at the end. */ - trx_reset_new_rec_lock_info(trx); + prebuilt->new_rec_locks = 0; } mode = pcur->search_mode; diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index 43456865903..8ada38845c5 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -192,8 +192,6 @@ trx_create( trx->n_autoinc_rows = 0; - trx_reset_new_rec_lock_info(trx); - return(trx); } From d629c4ecca014a95d4b8110f0dcb5a32a7e737bd Mon Sep 17 00:00:00 2001 From: Satya B Date: Wed, 15 Apr 2009 17:58:07 +0530 Subject: [PATCH 42/85] Applying InnoDB snashot 5.1-ss4699, part 2. Fixes BUG#43309 1) BUG#43309 - Test main.innodb can't be run twice 2) Follow up fix for BUG#43309, adds explanatory comments. Detailed revision comments: r4575 | vasil | 2009-03-30 15:55:31 +0300 (Mon, 30 Mar 2009) | 8 lines branches/5.1: Fix Bug#43309 Test main.innodb can't be run twice Make the innodb mysql-test more flexible by inspecting how much a variable of interest has changed since the start of the test. Do not assume the variables have zero values at the start of the test. r4659 | vasil | 2009-04-06 15:34:51 +0300 (Mon, 06 Apr 2009) | 6 lines branches/5.1: Followup to r4575 and the fix of Bug#43309 Test main.innodb can't be run twice: Add an explanatory comment, as suggested by Patrick Crews in the bug report. --- mysql-test/r/innodb.result | 60 +++++++++++++++++++------------------- mysql-test/t/innodb.test | 45 +++++++++++++++++++--------- 2 files changed, 61 insertions(+), 44 deletions(-) diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 2ce9587ef1a..b6602c9cfaf 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1736,36 +1736,36 @@ select count(*) from t1 where x = 18446744073709551601; count(*) 1 drop table t1; -show status like "Innodb_buffer_pool_pages_total"; -Variable_name Value -Innodb_buffer_pool_pages_total 512 -show status like "Innodb_page_size"; -Variable_name Value -Innodb_page_size 16384 -show status like "Innodb_rows_deleted"; -Variable_name Value -Innodb_rows_deleted 71 -show status like "Innodb_rows_inserted"; -Variable_name Value -Innodb_rows_inserted 1084 -show status like "Innodb_rows_updated"; -Variable_name Value -Innodb_rows_updated 885 -show status like "Innodb_row_lock_waits"; -Variable_name Value -Innodb_row_lock_waits 0 -show status like "Innodb_row_lock_current_waits"; -Variable_name Value -Innodb_row_lock_current_waits 0 -show status like "Innodb_row_lock_time"; -Variable_name Value -Innodb_row_lock_time 0 -show status like "Innodb_row_lock_time_max"; -Variable_name Value -Innodb_row_lock_time_max 0 -show status like "Innodb_row_lock_time_avg"; -Variable_name Value -Innodb_row_lock_time_avg 0 +SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_buffer_pool_pages_total'; +variable_value +512 +SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; +variable_value +16384 +SELECT variable_value - @innodb_rows_deleted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_deleted'; +variable_value - @innodb_rows_deleted_orig +71 +SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted'; +variable_value - @innodb_rows_inserted_orig +1084 +SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated'; +variable_value - @innodb_rows_updated_orig +885 +SELECT variable_value - @innodb_row_lock_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_waits'; +variable_value - @innodb_row_lock_waits_orig +0 +SELECT variable_value - @innodb_row_lock_current_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_current_waits'; +variable_value - @innodb_row_lock_current_waits_orig +0 +SELECT variable_value - @innodb_row_lock_time_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time'; +variable_value - @innodb_row_lock_time_orig +0 +SELECT variable_value - @innodb_row_lock_time_max_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_max'; +variable_value - @innodb_row_lock_time_max_orig +0 +SELECT variable_value - @innodb_row_lock_time_avg_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg'; +variable_value - @innodb_row_lock_time_avg_orig +0 show variables like "innodb_sync_spin_loops"; Variable_name Value innodb_sync_spin_loops 20 diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 9221e389f97..42c24324ebc 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -15,12 +15,25 @@ -- source include/have_innodb.inc -# -# Small basic test with ignore -# - +# Save the original values of some variables in order to be able to +# estimate how much they have changed during the tests. Previously this +# test assumed that e.g. rows_deleted is 0 here and after deleting 23 +# rows it expected that rows_deleted will be 23. Now we do not make +# assumptions about the values of the variables at the beginning, e.g. +# rows_deleted should be 23 + "rows_deleted before the test". This allows +# the test to be run multiple times without restarting the mysqld server. +# See Bug#43309 Test main.innodb can't be run twice -- disable_query_log SET @innodb_thread_concurrency_orig = @@innodb_thread_concurrency; + +SET @innodb_rows_deleted_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_deleted'); +SET @innodb_rows_inserted_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted'); +SET @innodb_rows_updated_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated'); +SET @innodb_row_lock_waits_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_waits'); +SET @innodb_row_lock_current_waits_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_current_waits'); +SET @innodb_row_lock_time_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time'); +SET @innodb_row_lock_time_max_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_max'); +SET @innodb_row_lock_time_avg_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg'); -- enable_query_log --disable_warnings @@ -28,6 +41,10 @@ drop table if exists t1,t2,t3,t4; drop database if exists mysqltest; --enable_warnings +# +# Small basic test with ignore +# + create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) engine=innodb; insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt'); @@ -1300,18 +1317,18 @@ drop table t1; # Test for testable InnoDB status variables. This test # uses previous ones(pages_created, rows_deleted, ...). -show status like "Innodb_buffer_pool_pages_total"; -show status like "Innodb_page_size"; -show status like "Innodb_rows_deleted"; -show status like "Innodb_rows_inserted"; -show status like "Innodb_rows_updated"; +SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_buffer_pool_pages_total'; +SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; +SELECT variable_value - @innodb_rows_deleted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_deleted'; +SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted'; +SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated'; # Test for row locks InnoDB status variables. -show status like "Innodb_row_lock_waits"; -show status like "Innodb_row_lock_current_waits"; -show status like "Innodb_row_lock_time"; -show status like "Innodb_row_lock_time_max"; -show status like "Innodb_row_lock_time_avg"; +SELECT variable_value - @innodb_row_lock_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_waits'; +SELECT variable_value - @innodb_row_lock_current_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_current_waits'; +SELECT variable_value - @innodb_row_lock_time_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time'; +SELECT variable_value - @innodb_row_lock_time_max_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_max'; +SELECT variable_value - @innodb_row_lock_time_avg_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg'; # Test for innodb_sync_spin_loops variable show variables like "innodb_sync_spin_loops"; From 3e90469f9523813820ae03736b51228a8a93407a Mon Sep 17 00:00:00 2001 From: Satya B Date: Wed, 15 Apr 2009 18:11:54 +0530 Subject: [PATCH 43/85] Applying InnoDB snashot 5.1-ss4699, part 3. Fixes BUG#43660 1) BUG#43660 - SHOW INDEXES/ANALYZE does NOT update cardinality for indexes of InnoDB table Detailed revision comments: r4699 | vasil | 2009-04-09 14:01:52 +0300 (Thu, 09 Apr 2009) | 15 lines branches/5.1: Fix Bug#43660 SHOW INDEXES/ANALYZE does NOT update cardinality for indexes of InnoDB table by replacing the PRNG that is used to pick random pages with a better one. This is based on r4670 but also adds a new configuration option and enables the fix only if this option is changed. Please skip the present revision when merging. Approved by: Heikki (via email) --- storage/innobase/handler/ha_innodb.cc | 9 ++++ storage/innobase/include/srv0srv.h | 6 +++ storage/innobase/page/page0cur.c | 75 ++++++++++++++++++++++++++- storage/innobase/srv/srv0srv.c | 6 +++ 4 files changed, 94 insertions(+), 2 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index d3a60b46dd8..e9c3f62c9dc 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8260,6 +8260,14 @@ static MYSQL_SYSVAR_BOOL(stats_on_metadata, innobase_stats_on_metadata, "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)", NULL, NULL, TRUE); +static MYSQL_SYSVAR_BOOL(use_legacy_cardinality_algorithm, + srv_use_legacy_cardinality_algorithm, + PLUGIN_VAR_OPCMDARG, + "Use legacy algorithm for picking random pages during index cardinality " + "estimation. Disable this to use a better algorithm, but note that your " + "query plans may change (enabled by default).", + NULL, NULL, TRUE); + static MYSQL_SYSVAR_BOOL(adaptive_hash_index, innobase_adaptive_hash_index, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, "Enable InnoDB adaptive hash index (enabled by default). " @@ -8395,6 +8403,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(open_files), MYSQL_SYSVAR(rollback_on_timeout), MYSQL_SYSVAR(stats_on_metadata), + MYSQL_SYSVAR(use_legacy_cardinality_algorithm), MYSQL_SYSVAR(adaptive_hash_index), MYSQL_SYSVAR(status_file), MYSQL_SYSVAR(support_xa), diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 2516937565d..9ff3c225eb0 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -235,6 +235,12 @@ extern ulint srv_read_ahead_seq; /* variable to count the number of random read-aheads were done */ extern ulint srv_read_ahead_rnd; +/* An option to enable the fix for "Bug#43660 SHOW INDEXES/ANALYZE does +NOT update cardinality for indexes of InnoDB table". By default we are +running with the fix disabled because MySQL 5.1 is frozen for such +behavioral changes. */ +extern char srv_use_legacy_cardinality_algorithm; + /* In this structure we store status variables to be passed to MySQL */ typedef struct export_var_struct export_struc; diff --git a/storage/innobase/page/page0cur.c b/storage/innobase/page/page0cur.c index a297eb545a0..70b7de194fd 100644 --- a/storage/innobase/page/page0cur.c +++ b/storage/innobase/page/page0cur.c @@ -15,6 +15,8 @@ Created 10/4/1994 Heikki Tuuri #include "mtr0log.h" #include "log0recv.h" #include "rem0cmp.h" +#include "srv0srv.h" +#include "ut0ut.h" static ulint page_rnd = 976722341; @@ -23,6 +25,44 @@ static ulint page_rnd = 976722341; ulint page_cur_short_succ = 0; # endif /* UNIV_SEARCH_PERF_STAT */ +/*********************************************************************** +This is a linear congruential generator PRNG. Returns a pseudo random +number between 0 and 2^64-1 inclusive. The formula and the constants +being used are: +X[n+1] = (a * X[n] + c) mod m +where: +X[0] = ut_usectime() +a = 1103515245 (3^5 * 5 * 7 * 129749) +c = 12345 (3 * 5 * 823) +m = 18446744073709551616 (2^64) +*/ +#define LCG_a 1103515245 +#define LCG_c 12345 +static +unsigned long long +page_cur_lcg_prng() +/*===============*/ + /* out: number between 0 and 2^64-1 */ +{ + static unsigned long long lcg_current = 0; + static ibool initialized = FALSE; + ulint time_sec; + ulint time_ms; + + if (!initialized) { + ut_usectime(&time_sec, &time_ms); + lcg_current = (unsigned long long) (time_sec * 1000000 + + time_ms); + initialized = TRUE; + } + + /* no need to "% 2^64" explicitly because lcg_current is + 64 bit and this will be done anyway */ + lcg_current = LCG_a * lcg_current + LCG_c; + + return(lcg_current); +} + /******************************************************************** Tries a search shortcut based on the last insert. */ UNIV_INLINE @@ -493,9 +533,13 @@ page_cur_open_on_rnd_user_rec( return; } - page_rnd += 87584577; + if (srv_use_legacy_cardinality_algorithm) { + page_rnd += 87584577; - rnd = page_rnd % page_get_n_recs(page); + rnd = page_rnd % page_get_n_recs(page); + } else { + rnd = (ulint) page_cur_lcg_prng() % page_get_n_recs(page); + } rec = page_get_infimum_rec(page); @@ -1437,3 +1481,30 @@ page_cur_delete_rec( page_dir_balance_slot(page, cur_slot_no); } } + +#ifdef UNIV_COMPILE_TEST_FUNCS + +/*********************************************************************** +Print the first n numbers, generated by page_cur_lcg_prng() to make sure +(visually) that it works properly. */ +void +test_page_cur_lcg_prng( +/*===================*/ + int n) /* in: print first n numbers */ +{ + int i; + unsigned long long rnd; + + for (i = 0; i < n; i++) { + rnd = page_cur_lcg_prng(); + printf("%llu\t%%2=%llu %%3=%llu %%5=%llu %%7=%llu %%11=%llu\n", + rnd, + rnd % 2, + rnd % 3, + rnd % 5, + rnd % 7, + rnd % 11); + } +} + +#endif /* UNIV_COMPILE_TEST_FUNCS */ diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index e2d8bd4c600..b8b63052394 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -256,6 +256,12 @@ ulint srv_read_ahead_seq = 0; /* variable to count the number of random read-aheads */ ulint srv_read_ahead_rnd = 0; +/* An option to enable the fix for "Bug#43660 SHOW INDEXES/ANALYZE does +NOT update cardinality for indexes of InnoDB table". By default we are +running with the fix disabled because MySQL 5.1 is frozen for such +behavioral changes. */ +char srv_use_legacy_cardinality_algorithm = TRUE; + /* structure to pass status variables to MySQL */ export_struc export_vars; From 4387f01efd08e6a7475d49c89b20a34f1f39dc24 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Thu, 16 Apr 2009 11:40:51 +0200 Subject: [PATCH 44/85] Bug#42430 Final commit to 5.0-bugteam --- cmd-line-utils/libedit/term.c | 2 +- ndb/tools/restore/consumer_restore.cpp | 4 ++-- ndb/tools/restore/consumer_restorem.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd-line-utils/libedit/term.c b/cmd-line-utils/libedit/term.c index 488c760da14..2f1aefa7117 100644 --- a/cmd-line-utils/libedit/term.c +++ b/cmd-line-utils/libedit/term.c @@ -61,7 +61,7 @@ static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; #ifdef HAVE_NCURSES_H #include #endif -/* Solaris's term.h does horrid things. */ +/* Don't use Solaris's term.h. */ #if (defined(HAVE_TERM_H) && !defined(__SunOS)) #include #endif diff --git a/ndb/tools/restore/consumer_restore.cpp b/ndb/tools/restore/consumer_restore.cpp index 811868f3e77..869dd0e9d8b 100644 --- a/ndb/tools/restore/consumer_restore.cpp +++ b/ndb/tools/restore/consumer_restore.cpp @@ -556,7 +556,7 @@ BackupRestore::logEntry(const LogEntry & tup) NdbTransaction * trans = m_ndb->startTransaction(); if (trans == NULL) { - // Deep shit, TODO: handle the error + // TODO: handle the error err << "Cannot start transaction" << endl; exitHandler(); } // if @@ -693,7 +693,7 @@ BackupRestore::tuple(const TupleS & tup) NdbTransaction * trans = m_ndb->startTransaction(); if (trans == NULL) { - // Deep shit, TODO: handle the error + // TODO: handle the error ndbout << "Cannot start transaction" << endl; exitHandler(); } // if diff --git a/ndb/tools/restore/consumer_restorem.cpp b/ndb/tools/restore/consumer_restorem.cpp index 2dc0476b5a6..642c9e4acb4 100644 --- a/ndb/tools/restore/consumer_restorem.cpp +++ b/ndb/tools/restore/consumer_restorem.cpp @@ -373,7 +373,7 @@ BackupRestore::tuple(const TupleS & tup) NdbTransaction * trans = m_ndb->startTransaction(); if (trans == NULL) { - // Deep shit, TODO: handle the error + // TODO: handle the error ndbout << "Cannot start transaction" << endl; exit(-1); } // if @@ -462,7 +462,7 @@ BackupRestore::logEntry(const LogEntry & tup) NdbTransaction * trans = m_ndb->startTransaction(); if (trans == NULL) { - // Deep shit, TODO: handle the error + // TODO: handle the error ndbout << "Cannot start transaction" << endl; exit(-1); } // if From f6c28cd948a99dbb1cd32eb3b90d8095c957b18c Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 16 Apr 2009 17:02:56 +0530 Subject: [PATCH 45/85] BUG#40827 - Killing insert-select to MyISAM can cause table corruption Killing insert-select statement on MyISAM corrupts the table. Killing the insert-select statement corrupts the MyISAM table only when the destination table is empty and when it has indexes. When we bulk insert huge data and if the destination table is empty we disable the indexes for fast inserts, data is then inserted and indexes are re-enabled after bulk_insert operation Killing the query, aborts the repair table operation during enable indexes phase leading to table corruption. We now truncate the table when we detect that enable indexes is killed for bulk insert query.As we have an empty table before the operation, we can fix by truncating the table. --- mysql-test/r/myisam.result | 39 +++++++++++++++++++++++++++ mysql-test/t/myisam.test | 52 ++++++++++++++++++++++++++++++++++++ storage/myisam/ha_myisam.cc | 53 ++++++++++++++++++++++++++++++++++--- 3 files changed, 140 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 6f26135ce45..68895257088 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -2226,4 +2226,43 @@ Key Start Len Index Type 1 2 30 multip. varchar 2 33 30 multip. char NULL DROP TABLE t1; +# +# BUG#40827 - Killing insert-select to MyISAM can cause table corruption +# +CREATE TABLE `t1` ( +`id` BIGINT(20) , +`id1` BIGINT(20) AUTO_INCREMENT, +KEY(id1), KEY(id) +) ENGINE=MyISAM; +CREATE TABLE `t2` ( +`id` BIGINT(20) , +`id1` BIGINT(20) AUTO_INCREMENT, +KEY (id1), KEY(id) +) ENGINE=MyISAM; +INSERT INTO t2 (id) VALUES (123); +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +# Switch to insert Connection +SET SESSION debug='+d,wait_in_enable_indexes'; +# Send insert data +INSERT INTO t1(id) SELECT id FROM t2; +# Switch to default Connection +# Wait for insert data to reach the debug point +SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST +WHERE STATE = 'wait_in_enable_indexes' AND +INFO = "INSERT INTO t1(id) SELECT id FROM t2" +INTO @thread_id; +KILL QUERY @thread_id; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1,t2; End of 5.1 tests diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 6d7e03b1c28..14282a366c7 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1478,5 +1478,57 @@ let $MYSQLD_DATADIR= `select @@datadir`; --exec $MYISAMCHK -d $MYSQLD_DATADIR/test/t1 DROP TABLE t1; +--echo # +--echo # BUG#40827 - Killing insert-select to MyISAM can cause table corruption +--echo # + +CONNECT (insertConn, localhost, root,,); + +CREATE TABLE `t1` ( +`id` BIGINT(20) , +`id1` BIGINT(20) AUTO_INCREMENT, + KEY(id1), KEY(id) +) ENGINE=MyISAM; + +CREATE TABLE `t2` ( +`id` BIGINT(20) , +`id1` BIGINT(20) AUTO_INCREMENT, + KEY (id1), KEY(id) +) ENGINE=MyISAM; + +INSERT INTO t2 (id) VALUES (123); + +let $i = 10; +while ($i) +{ + INSERT INTO t2 (id) SELECT id FROM t2; + dec $i; +} + +--echo # Switch to insert Connection +CONNECTION insertConn; +SET SESSION debug='+d,wait_in_enable_indexes'; +--echo # Send insert data +SEND INSERT INTO t1(id) SELECT id FROM t2; + +--echo # Switch to default Connection +CONNECTION default; +--echo # Wait for insert data to reach the debug point + +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST + WHERE STATE = "wait_in_enable_indexes" AND + INFO = "INSERT INTO t1(id) SELECT id FROM t2"; +--source include/wait_condition.inc + +SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST +WHERE STATE = 'wait_in_enable_indexes' AND +INFO = "INSERT INTO t1(id) SELECT id FROM t2" +INTO @thread_id; + +KILL QUERY @thread_id; +CHECK TABLE t1; +DROP TABLE t1,t2; +DISCONNECT insertConn; --echo End of 5.1 tests diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index dd66c255475..b98b090d021 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -43,6 +43,28 @@ TYPELIB myisam_stats_method_typelib= { array_elements(myisam_stats_method_names) - 1, "", myisam_stats_method_names, NULL}; +#ifndef DBUG_OFF +/** + Causes the thread to wait in a spin lock for a query kill signal. + This function is used by the test frame work to identify race conditions. + + The signal is caught and ignored and the thread is not killed. +*/ + +static void debug_wait_for_kill(const char *info) +{ + DBUG_ENTER("debug_wait_for_kill"); + const char *prev_info; + THD *thd; + thd= current_thd; + prev_info= thd_proc_info(thd, info); + while(!thd->killed) + my_sleep(1000); + DBUG_PRINT("info", ("Exit debug_wait_for_kill")); + thd_proc_info(thd, prev_info); + DBUG_VOID_RETURN; +} +#endif /***************************************************************************** ** MyISAM tables @@ -1395,6 +1417,9 @@ int ha_myisam::enable_indexes(uint mode) { int error; + DBUG_EXECUTE_IF("wait_in_enable_indexes", + debug_wait_for_kill("wait_in_enable_indexes"); ); + if (mi_is_all_keys_active(file->s->state.key_map, file->s->base.keys)) { /* All indexes are enabled already. */ @@ -1508,8 +1533,9 @@ void ha_myisam::start_bulk_insert(ha_rows rows) /* Only disable old index if the table was empty and we are inserting a lot of rows. - We should not do this for only a few rows as this is slower and - we don't want to update the key statistics based of only a few rows. + Note that in end_bulk_insert() we may truncate the table if + enable_indexes() failed, thus it's essential that indexes are + disabled ONLY for an empty table. */ if (file->state->records == 0 && can_enable_indexes && (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES)) @@ -1541,8 +1567,27 @@ int ha_myisam::end_bulk_insert() { mi_end_bulk_insert(file); int err=mi_extra(file, HA_EXTRA_NO_CACHE, 0); - return err ? err : can_enable_indexes ? - enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE) : 0; + if (!err) + { + if (can_enable_indexes) + { + /* + Truncate the table when enable index operation is killed. + After truncating the table we don't need to enable the + indexes, because the last repair operation is aborted after + setting the indexes as active and trying to recreate them. + */ + + if (((err= enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE)) != 0) && + current_thd->killed) + { + delete_all_rows(); + /* not crashed, despite being killed during repair */ + file->s->state.changed&= ~(STATE_CRASHED|STATE_CRASHED_ON_REPAIR); + } + } + } + return err; } From 361bd1a7c374aac4d33082460d812747229c4b19 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 16 Apr 2009 16:47:02 +0300 Subject: [PATCH 46/85] bumped the version to 5.0.82 (5.0.81-community to be released) --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 1fbb5bf9b7a..9267e5d3189 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.81) +AM_INIT_AUTOMAKE(mysql, 5.0.82) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 @@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=81 +NDB_VERSION_BUILD=82 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? From 2c1add4b4599b70e2f512d704a5a18cf1fbfc446 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Thu, 16 Apr 2009 13:47:44 -0400 Subject: [PATCH 47/85] Bug#26887 - main.count_distinct3 fails randomly Streamlined how we increase the size of our test table. The new method shows run time decreased by ~60%. This is not a guarantee that we will not see test timeouts (the random failures noted in the bug), but it should significantly reduce the chances of this occurring. --- mysql-test/r/count_distinct3.result | 5 ++-- mysql-test/t/count_distinct3.test | 39 +++++++++++------------------ 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/mysql-test/r/count_distinct3.result b/mysql-test/r/count_distinct3.result index 086e1360b0c..840c26669a1 100644 --- a/mysql-test/r/count_distinct3.result +++ b/mysql-test/r/count_distinct3.result @@ -2,7 +2,8 @@ DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 (id INTEGER, grp TINYINT, id_rev INTEGER); SELECT COUNT(*) FROM t1; COUNT(*) -4181000 +4201000 SELECT COUNT(DISTINCT id) FROM t1 GROUP BY grp; +# Begin cleanup +SET session myisam_sort_buffer_size = @orig_myisam_sort_buffer_size; DROP TABLE t1; -set @@read_buffer_size=default; diff --git a/mysql-test/t/count_distinct3.test b/mysql-test/t/count_distinct3.test index f817b2c635d..2f7cf7e5260 100644 --- a/mysql-test/t/count_distinct3.test +++ b/mysql-test/t/count_distinct3.test @@ -1,4 +1,4 @@ -# +# Bug #958 a big table without indices and select with group by doesnt work # this is a test for error 1032 in count(distinct) + group by, introduced in # mysql-4.1 # @@ -21,27 +21,16 @@ while ($1) INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev); dec $1; } -set @@read_buffer_size=2*1024*1024; -CREATE TABLE t2 SELECT * FROM t1; -INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2; -INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1; -INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2; -INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1; -INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2; -INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1; -INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2; -INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1; -INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2; -INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1; -INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2; -INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1; -INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2; -INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1; -INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2; -INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1; -INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2; -INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1; -DROP TABLE t2; + +# We increase the size of t1 here. +SET @orig_myisam_sort_buffer_size = @@session.myisam_sort_buffer_size; +SET session myisam_sort_buffer_size=20000000; +INSERT INTO t1 +SELECT A.id, A.grp, A.id_rev +FROM + t1 A, + (SELECT * FROM t1 B LIMIT 100) B, + (SELECT * FROM t1 Z LIMIT 42) Z; --enable_query_log SELECT COUNT(*) FROM t1; @@ -49,12 +38,12 @@ SELECT COUNT(*) FROM t1; # As t1 contains random numbers, results are different from test to test. # That's okay, because we test only that select doesn't yield an # error. Note, that --disable_result_log doesn't suppress error output. - --disable_result_log SELECT COUNT(DISTINCT id) FROM t1 GROUP BY grp; --enable_result_log + +--echo # Begin cleanup +SET session myisam_sort_buffer_size = @orig_myisam_sort_buffer_size; DROP TABLE t1; -set @@read_buffer_size=default; - # End of 4.1 tests From e0e8ec4b28f27f8f2e82ef5f241d67471a45cd0f Mon Sep 17 00:00:00 2001 From: Anurag Shekhar Date: Fri, 17 Apr 2009 11:21:51 +0530 Subject: [PATCH 48/85] Bug#44040 MySQL allows creating a MERGE table upon VIEWs but crashes when using it. The crash was due to a null pointer present for select_lex while processing the view. Adding a check while opening the view to see if its a child of a merge table fixed this problem. --- mysql-test/r/merge.result | 12 ++++++++++++ mysql-test/t/merge.test | 21 +++++++++++++++++++++ sql/sql_base.cc | 10 ++++++++++ 3 files changed, 43 insertions(+) diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index d844abc1847..f53b328d14e 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -2115,4 +2115,16 @@ insert into m1 (col1) values (1); insert into m1 (col1) values (1); ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' drop table m1, t1; +CREATE TABLE t1 ( +col1 INT(10) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +CREATE VIEW v1 as SELECT * FROM t1; +CREATE TABLE m1 ( +col1 INT(10) +)ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(v1); +#Select should detect that the child table is a view and fail. +SELECT * FROM m1; +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +DROP VIEW v1; +DROP TABLE m1, t1; End of 5.1 tests diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index f12187ea143..5315c91daa6 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -1514,4 +1514,25 @@ insert into m1 (col1) values (1); insert into m1 (col1) values (1); drop table m1, t1; + +# +#Bug #44040 MySQL allows creating a MERGE table upon VIEWs but crashes +#when using it +# + +CREATE TABLE t1 ( + col1 INT(10) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +CREATE VIEW v1 as SELECT * FROM t1; +CREATE TABLE m1 ( + col1 INT(10) +)ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(v1); + +--echo #Select should detect that the child table is a view and fail. +--error ER_WRONG_MRG_TABLE +SELECT * FROM m1; + +DROP VIEW v1; +DROP TABLE m1, t1; --echo End of 5.1 tests diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0f0ee7c529e..0dc29f7e3c2 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3843,6 +3843,16 @@ retry: if (share->is_view) { + /* + If parent_l of the table_list is non null then a merge table + has this view as child table, which is not supported. + */ + if (table_list->parent_l) + { + my_error(ER_WRONG_MRG_TABLE, MYF(0)); + goto err; + } + /* This table is a view. Validate its metadata version: in particular, that it was a view when the statement was prepared. From 4fbfa8db451b10b409eb4dd4ba985552c4a86a95 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 17 Apr 2009 12:41:15 +0500 Subject: [PATCH 49/85] Bug#44151 using handler commands on information_schema tables crashes server information schema tables are based on internal tmp tables which are removed after each statement execution. So HANDLER comands can not be used with information schema. --- mysql-test/r/handler.result | 4 ++++ mysql-test/t/handler.test | 8 ++++++++ sql/sql_handler.cc | 8 ++++++++ 3 files changed, 20 insertions(+) diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result index dc3750e16ea..4906111982f 100644 --- a/mysql-test/r/handler.result +++ b/mysql-test/r/handler.result @@ -502,3 +502,7 @@ handler t1_alias READ a next where inexistent > 0; ERROR 42S22: Unknown column 'inexistent' in 'field list' handler t1_alias close; drop table t1; +USE information_schema; +HANDLER COLUMNS OPEN; +ERROR HY000: Incorrect usage of HANDLER OPEN and information_schema +USE test; diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test index 6ef216f6ed2..70d4157a272 100644 --- a/mysql-test/t/handler.test +++ b/mysql-test/t/handler.test @@ -460,3 +460,11 @@ handler t1_alias read a next; handler t1_alias READ a next where inexistent > 0; handler t1_alias close; drop table t1; + +# +# Bug#44151 using handler commands on information_schema tables crashes server +# +USE information_schema; +--error ER_WRONG_USAGE +HANDLER COLUMNS OPEN; +USE test; diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index c376f1b3d1d..721b365a7b9 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -190,6 +190,14 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) tables->db, tables->table_name, tables->alias, (int) reopen)); + if (tables->schema_table) + { + my_error(ER_WRONG_USAGE, MYF(0), "HANDLER OPEN", + INFORMATION_SCHEMA_NAME.str); + DBUG_PRINT("exit",("ERROR")); + DBUG_RETURN(TRUE); + } + if (! hash_inited(&thd->handler_tables_hash)) { /* From 4783b2e196e4ed4c037194d74b99922e92deecd0 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 17 Apr 2009 18:52:57 +0300 Subject: [PATCH 50/85] Bug #35087: Inserting duplicate values at one time with DES_ENCRYPT leads to wrong results 3 problems found with DES_ENCRYPT/DES_DECRYPT : 1. The max length was not calculated properly. Fixed in fix_length_and_dec() 2. DES_ENCRYPT had a side effect of sometimes reallocating and changing the value of its argument. Fixed by explicitly pre-allocating the necessary space to pad the argument with trailing '*' (stars) when calculating the DES digest. 3. in DES_ENCRYPT the string buffer for the result value was not reallocated to the correct size and only string length was assigned to it. Fixed by making sure there's enough space to hold the result. --- mysql-test/r/func_des_encrypt.result | 34 ++++++++++++++++++++++++++++ mysql-test/t/func_des_encrypt.test | 28 +++++++++++++++++++++++ sql/item_strfunc.cc | 12 ++++++---- sql/item_strfunc.h | 15 +++++++++--- 4 files changed, 82 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/func_des_encrypt.result b/mysql-test/r/func_des_encrypt.result index 46b30bdab58..b81f96f6ef7 100644 --- a/mysql-test/r/func_des_encrypt.result +++ b/mysql-test/r/func_des_encrypt.result @@ -1,3 +1,37 @@ select des_encrypt('hello'); des_encrypt('hello') €Ö2nV“Ø} +# +# Bug #11643: des_encrypt() causes server to die +# +CREATE TABLE t1 (des VARBINARY(200) NOT NULL DEFAULT '') ENGINE=MyISAM; +INSERT INTO t1 VALUES ('1234'), ('12345'), ('123456'), ('1234567'); +UPDATE t1 SET des=DES_ENCRYPT('1234'); +SELECT LENGTH(des) FROM t1; +LENGTH(des) +9 +9 +9 +9 +SELECT DES_DECRYPT(des) FROM t1; +DES_DECRYPT(des) +1234 +1234 +1234 +1234 +SELECT +LENGTH(DES_ENCRYPT('1234')), +LENGTH(DES_ENCRYPT('12345')), +LENGTH(DES_ENCRYPT('123456')), +LENGTH(DES_ENCRYPT('1234567')); +LENGTH(DES_ENCRYPT('1234')) LENGTH(DES_ENCRYPT('12345')) LENGTH(DES_ENCRYPT('123456')) LENGTH(DES_ENCRYPT('1234567')) +9 9 9 9 +SELECT +DES_DECRYPT(DES_ENCRYPT('1234')), +DES_DECRYPT(DES_ENCRYPT('12345')), +DES_DECRYPT(DES_ENCRYPT('123456')), +DES_DECRYPT(DES_ENCRYPT('1234567')); +DES_DECRYPT(DES_ENCRYPT('1234')) DES_DECRYPT(DES_ENCRYPT('12345')) DES_DECRYPT(DES_ENCRYPT('123456')) DES_DECRYPT(DES_ENCRYPT('1234567')) +1234 12345 123456 1234567 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/t/func_des_encrypt.test b/mysql-test/t/func_des_encrypt.test index b757a632adf..2c364a40090 100644 --- a/mysql-test/t/func_des_encrypt.test +++ b/mysql-test/t/func_des_encrypt.test @@ -9,3 +9,31 @@ select des_encrypt('hello'); # End of 4.1 tests + +--echo # +--echo # Bug #11643: des_encrypt() causes server to die +--echo # + +CREATE TABLE t1 (des VARBINARY(200) NOT NULL DEFAULT '') ENGINE=MyISAM; + +INSERT INTO t1 VALUES ('1234'), ('12345'), ('123456'), ('1234567'); + +UPDATE t1 SET des=DES_ENCRYPT('1234'); + +SELECT LENGTH(des) FROM t1; +SELECT DES_DECRYPT(des) FROM t1; + +SELECT + LENGTH(DES_ENCRYPT('1234')), + LENGTH(DES_ENCRYPT('12345')), + LENGTH(DES_ENCRYPT('123456')), + LENGTH(DES_ENCRYPT('1234567')); +SELECT + DES_DECRYPT(DES_ENCRYPT('1234')), + DES_DECRYPT(DES_ENCRYPT('12345')), + DES_DECRYPT(DES_ENCRYPT('123456')), + DES_DECRYPT(DES_ENCRYPT('1234567')); + +DROP TABLE t1; + +--Echo End of 5.0 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 7edc1a62307..4640929b2bf 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -473,17 +473,21 @@ String *Item_func_des_encrypt::val_str(String *str) string marking change of string length. */ - tail= (8-(res_length) % 8); // 1..8 marking extra length + tail= 8 - (res_length % 8); // 1..8 marking extra length res_length+=tail; + tmp_arg.realloc(res_length); + tmp_arg.length(0); + tmp_arg.append(res->ptr(), res->length()); code= ER_OUT_OF_RESOURCES; - if (tail && res->append(append_str, tail) || tmp_value.alloc(res_length+1)) + if (tmp_arg.append(append_str, tail) || tmp_value.alloc(res_length+1)) goto error; - (*res)[res_length-1]=tail; // save extra length + tmp_arg[res_length-1]=tail; // save extra length + tmp_value.realloc(res_length+1); tmp_value.length(res_length+1); tmp_value[0]=(char) (128 | key_number); // Real encryption bzero((char*) &ivec,sizeof(ivec)); - DES_ede3_cbc_encrypt((const uchar*) (res->ptr()), + DES_ede3_cbc_encrypt((const uchar*) (tmp_arg.ptr()), (uchar*) (tmp_value.ptr()+1), res_length, &keyschedule.ks1, diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 9794a092648..1c5346ab074 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -306,13 +306,17 @@ public: class Item_func_des_encrypt :public Item_str_func { - String tmp_value; + String tmp_value,tmp_arg; public: Item_func_des_encrypt(Item *a) :Item_str_func(a) {} Item_func_des_encrypt(Item *a, Item *b): Item_str_func(a,b) {} String *val_str(String *); void fix_length_and_dec() - { maybe_null=1; max_length = args[0]->max_length+8; } + { + maybe_null=1; + /* 9 = MAX ((8- (arg_len % 8)) + 1) */ + max_length = args[0]->max_length + 9; + } const char *func_name() const { return "des_encrypt"; } }; @@ -323,7 +327,12 @@ public: Item_func_des_decrypt(Item *a) :Item_str_func(a) {} Item_func_des_decrypt(Item *a, Item *b): Item_str_func(a,b) {} String *val_str(String *); - void fix_length_and_dec() { maybe_null=1; max_length = args[0]->max_length; } + void fix_length_and_dec() + { + maybe_null=1; + /* 9 = MAX ((8- (arg_len % 8)) + 1) */ + max_length = args[0]->max_length - 9; + } const char *func_name() const { return "des_decrypt"; } }; From a3bddbe4657dfc90c34d95f3b9c3dabc54da34a0 Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Fri, 17 Apr 2009 16:00:53 -0400 Subject: [PATCH 51/85] Move test for bug 39559, which uses command-line mysql client to separate test file that doesn't permit mysqld embedded in mysqltest. Also, fix different comment handling in a incorrect new-to-5.1 test. --- mysql-test/r/parser.result | 49 ------------------------- mysql-test/r/parser_not_embedded.result | 49 +++++++++++++++++++++++++ mysql-test/r/partition_mgm.result | 9 ++++- mysql-test/t/parser.test | 24 ------------ mysql-test/t/parser_not_embedded.test | 26 +++++++++++++ mysql-test/t/partition_mgm.test | 3 +- 6 files changed, 85 insertions(+), 75 deletions(-) create mode 100644 mysql-test/r/parser_not_embedded.result create mode 100644 mysql-test/t/parser_not_embedded.test diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index 097f6dc69ff..7e703de0876 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -616,54 +616,5 @@ SELECT a1, a4 FROM t2 WHERE a4 LIKE {fn UCASE('1789-07-14')}; a1 a4 DROP TABLE t1, t2, t3; # -# Bug#39559: dump of stored procedures / functions with C-style -# comment can't be read back -# -+----------+--------+ -| expected | result | -+----------+--------+ -| 2 | 2 | -+----------+--------+ -+----------+--------+ -| expected | result | -+----------+--------+ -| 1 | 1 | -+----------+--------+ -+----------+--------+ -| expected | result | -+----------+--------+ -| 3 | 3 | -+----------+--------+ -+----------+--------+ -| expected | result | -+----------+--------+ -| 2 | 2 | -+----------+--------+ -+----------+--------+ -| expected | result | -+----------+--------+ -| 7 | 7 | -+----------+--------+ -+----------+--------+ -| expected | result | -+----------+--------+ -| 8 | 8 | -+----------+--------+ -+----------+--------+ -| expected | result | -+----------+--------+ -| 7 | 7 | -+----------+--------+ -+----------+--------+ -| expected | result | -+----------+--------+ -| 4 | 4 | -+----------+--------+ -+----------+--------+ -| expected | result | -+----------+--------+ -| 4 | 4 | -+----------+--------+ -# # End of 5.1 tests # diff --git a/mysql-test/r/parser_not_embedded.result b/mysql-test/r/parser_not_embedded.result new file mode 100644 index 00000000000..871eb226cc4 --- /dev/null +++ b/mysql-test/r/parser_not_embedded.result @@ -0,0 +1,49 @@ +# +# Bug#39559: dump of stored procedures / functions with C-style +# comment can't be read back +# ++----------+--------+ +| expected | result | ++----------+--------+ +| 2 | 2 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 1 | 1 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 3 | 3 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 2 | 2 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 7 | 7 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 8 | 8 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 7 | 7 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 4 | 4 | ++----------+--------+ ++----------+--------+ +| expected | result | ++----------+--------+ +| 4 | 4 | ++----------+--------+ diff --git a/mysql-test/r/partition_mgm.result b/mysql-test/r/partition_mgm.result index a1f35756e21..2ff6e3f1923 100644 --- a/mysql-test/r/partition_mgm.result +++ b/mysql-test/r/partition_mgm.result @@ -53,7 +53,14 @@ CREATE TABLE t1 (a INT) of multi-line comment */ PARTITIONS 5 */; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '*/' at line 6 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY HASH (a) +PARTITIONS 5 */ +DROP TABLE t1; CREATE TABLE t1 (a INT) /*!50100 PARTITION BY HASH (a) -- with a single line comment embedded diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test index e44fc85bc5e..e579e371184 100644 --- a/mysql-test/t/parser.test +++ b/mysql-test/t/parser.test @@ -725,30 +725,6 @@ UPDATE t3 SET a4={d '1789-07-14'} WHERE a1=0; SELECT a1, a4 FROM t2 WHERE a4 LIKE {fn UCASE('1789-07-14')}; DROP TABLE t1, t2, t3; -########################################################################### ---echo # ---echo # Bug#39559: dump of stored procedures / functions with C-style ---echo # comment can't be read back ---echo # - ---write_file $MYSQLTEST_VARDIR/tmp/bug39559.sql -select 2 as expected, /*!01000/**/*/ 2 as result; -select 1 as expected, /*!99998/**/*/ 1 as result; -select 3 as expected, /*!01000 1 + */ 2 as result; -select 2 as expected, /*!99990 1 + */ 2 as result; -select 7 as expected, /*!01000 1 + /* 8 + */ 2 + */ 4 as result; -select 8 as expected, /*!99998 1 + /* 2 + */ 4 + */ 8 as result; -select 7 as expected, /*!01000 1 + /*!01000 8 + */ 2 + */ 4 as result; -select 7 as expected, /*!01000 1 + /*!99998 8 + */ 2 + */ 4 as result; -select 4 as expected, /*!99998 1 + /*!99998 8 + */ 2 + */ 4 as result; -select 4 as expected, /*!99998 1 + /*!01000 8 + */ 2 + */ 4 as result; -select 7 as expected, /*!01000 1 + /*!01000 8 + /*!01000 error */ 16 + */ 2 + */ 4 as result; -select 4 as expected, /* 1 + /*!01000 8 + */ 2 + */ 4; -EOF - ---exec $MYSQL --comment --force --table test <$MYSQLTEST_VARDIR/tmp/bug39559.sql ---remove_file $MYSQLTEST_VARDIR/tmp/bug39559.sql - --echo # --echo # End of 5.1 tests --echo # diff --git a/mysql-test/t/parser_not_embedded.test b/mysql-test/t/parser_not_embedded.test new file mode 100644 index 00000000000..8ebeb9a8301 --- /dev/null +++ b/mysql-test/t/parser_not_embedded.test @@ -0,0 +1,26 @@ +--source include/not_embedded.inc + +########################################################################### +--echo # +--echo # Bug#39559: dump of stored procedures / functions with C-style +--echo # comment can't be read back +--echo # + +--write_file $MYSQLTEST_VARDIR/tmp/bug39559.sql +select 2 as expected, /*!01000/**/*/ 2 as result; +select 1 as expected, /*!99998/**/*/ 1 as result; +select 3 as expected, /*!01000 1 + */ 2 as result; +select 2 as expected, /*!99990 1 + */ 2 as result; +select 7 as expected, /*!01000 1 + /* 8 + */ 2 + */ 4 as result; +select 8 as expected, /*!99998 1 + /* 2 + */ 4 + */ 8 as result; +select 7 as expected, /*!01000 1 + /*!01000 8 + */ 2 + */ 4 as result; +select 7 as expected, /*!01000 1 + /*!99998 8 + */ 2 + */ 4 as result; +select 4 as expected, /*!99998 1 + /*!99998 8 + */ 2 + */ 4 as result; +select 4 as expected, /*!99998 1 + /*!01000 8 + */ 2 + */ 4 as result; +select 7 as expected, /*!01000 1 + /*!01000 8 + /*!01000 error */ 16 + */ 2 + */ 4 as result; +select 4 as expected, /* 1 + /*!01000 8 + */ 2 + */ 4; +EOF + +--exec $MYSQL --comment --force --table test <$MYSQLTEST_VARDIR/tmp/bug39559.sql +--remove_file $MYSQLTEST_VARDIR/tmp/bug39559.sql + diff --git a/mysql-test/t/partition_mgm.test b/mysql-test/t/partition_mgm.test index e17edf0a4e5..bf9b5ed174e 100644 --- a/mysql-test/t/partition_mgm.test +++ b/mysql-test/t/partition_mgm.test @@ -67,13 +67,14 @@ drop table t1; # # Verification tests for bug#14326 # ---error ER_PARSE_ERROR CREATE TABLE t1 (a INT) /*!50100 PARTITION BY HASH (a) /* Test of multi-line comment */ PARTITIONS 5 */; +SHOW CREATE TABLE t1; +DROP TABLE t1; CREATE TABLE t1 (a INT) /*!50100 PARTITION BY HASH (a) -- with a single line comment embedded From 669060712f83a31107367c1a2ce0726a4c30ecc2 Mon Sep 17 00:00:00 2001 From: Satya B Date: Mon, 20 Apr 2009 12:57:41 +0530 Subject: [PATCH 52/85] Applying InnoDB snashot 5.1-ss3603. Fixes BUG#27276 1) BUG#27276 - InnoDB Error: ibuf cursor restoration fails 2) Follow up fix for BUG#27276 which fixes the bug introduced in the previous revision r2924 Detailed revision comments: r2924 | marko | 2008-10-29 10:07:48 +0200 (Wed, 29 Oct 2008) | 7 lines branches/5.1: Merge revision 2866 from branches/zip: ibuf_delete_rec(): When the cursor to the insert buffer record cannot be restored, do not complain if the tablespace does not exist. (Bug #27276) Approved by Sunny Bains (rb://34) r3598 | marko | 2008-12-22 15:28:03 +0200 (Mon, 22 Dec 2008) | 6 lines branches/5.1: ibuf_delete_rec(): When the record cannot be found and the tablespace has been dropped, commit the mini-transaction, so that InnoDB will not hold the insert buffer tree latch in exclusive mode, causing a potential deadlock. This bug was introduced in the fix of Bug #27276 in r2924. --- storage/innobase/ibuf/ibuf0ibuf.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 126fd9fdd33..d54a3378993 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -2992,6 +2992,13 @@ ibuf_delete_rec( success = btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr); if (!success) { + if (fil_space_get_version(space) == -1) { + /* The tablespace has been dropped. It is possible + that another thread has deleted the insert buffer + entry. Do not complain. */ + goto commit_and_exit; + } + fprintf(stderr, "InnoDB: ERROR: Submit the output to" " http://bugs.mysql.com\n" @@ -3018,11 +3025,7 @@ ibuf_delete_rec( fprintf(stderr, "InnoDB: ibuf tree ok\n"); fflush(stderr); - btr_pcur_close(pcur); - - mutex_exit(&ibuf_mutex); - - return(TRUE); + goto func_exit; } root = ibuf_tree_root_get(ibuf_data, 0, mtr); @@ -3033,15 +3036,15 @@ ibuf_delete_rec( #ifdef UNIV_IBUF_DEBUG ibuf_count_set(space, page_no, ibuf_count_get(space, page_no) - 1); -#else - UT_NOT_USED(space); #endif ibuf_data_sizes_update(ibuf_data, root, mtr); ut_ad(ibuf_validate_low()); +commit_and_exit: btr_pcur_commit_specify_mtr(pcur, mtr); +func_exit: btr_pcur_close(pcur); mutex_exit(&ibuf_mutex); From 904498295fc10d213e75f0b59ababcc938ee580d Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 21 Apr 2009 14:01:13 +0500 Subject: [PATCH 53/85] BUG#36966 - mysqldump.test fails in pushbuild mysqldump.test is designed to run with concurrent inserts disabled. It is disabling concurrent inserts at the very beginning of the test case, and re-enables them at the bottom of the test. But for some reason (likely incorrect merge) we enable concurrent inserts in the middle of the test. The problem is fixed by enabling concurrent inserts only at the bottom of the test case. --- mysql-test/r/mysqldump.result | 2 +- mysql-test/t/mysqldump.test | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 1897a7df799..ce24922db28 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -3557,7 +3557,6 @@ DROP TABLE t1,t2; -- Dump completed on DATE -SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT; # # Bug #42635: mysqldump includes views that were excluded using # the --ignore-table option @@ -3693,6 +3692,7 @@ UNLOCK TABLES; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE `כדשגכחךלדגכחשךדגחכךלדגכ`; SET NAMES latin1; +SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT; # # End of 5.0 tests # diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 52eecc62931..1e9090fdd01 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1646,9 +1646,6 @@ DROP TABLE t1,t2; --replace_regex /-- [^D][^u][^m][^p].*// /\/\*!.*// / on [0-9 :-]+/ on DATE/ --exec $MYSQL_DUMP test -# We reset concurrent_inserts value to whatever it was at the start of the test -SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT; - --echo # --echo # Bug #42635: mysqldump includes views that were excluded using --echo # the --ignore-table option @@ -1681,6 +1678,9 @@ CREATE TABLE `כדשגכחךלדגכחשךדגחכךלדגכ` ( f1 INT ); DROP TABLE `כדשגכחךלדגכחשךדגחכךלדגכ`; SET NAMES latin1; +# We reset concurrent_inserts value to whatever it was at the start of the test +# This line must be executed _after_ all test cases. +SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT; --echo # --echo # End of 5.0 tests From c27566aec5529beacd7ee27be4433827d8fa1755 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Tue, 21 Apr 2009 15:31:21 +0100 Subject: [PATCH 54/85] BUG#44378 rpl_binlog_corruption fails with warning messages in Valgrind The rpl_binlog_corruption test case was inject failures, specifically, incidents with invalid numbers to see if the replication was failing gracefully. However, this test was causing the following warning message in Valgrind: "Conditional jump or move depends on uninitialised value(s)" The patch fixes the problem by correctly initializing the m_inicident number. --- sql/log_event.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 917e79b86f2..a10a36f3b43 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -9250,7 +9250,7 @@ Incident_log_event::Incident_log_event(const char *buf, uint event_len, // If the incident is not recognized, this binlog event is // invalid. If we set incident_number to INCIDENT_NONE, the // invalidity will be detected by is_valid(). - incident_number= INCIDENT_NONE; + m_incident= INCIDENT_NONE; DBUG_VOID_RETURN; } m_incident= static_cast(incident_number); From 3b3fc01425a89fd2c60890fb6019eb58dc121e03 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 23 Apr 2009 12:43:42 +0500 Subject: [PATCH 55/85] Bug#44358 valgrind errors with decode() function The warning happens because string argument is not zero ended. The fix is to add new parameter 'length' to SQL_CRYPT() and use ptr() instead of c_ptr(). --- mysql-test/r/func_str.result | 14 ++++++++++++++ mysql-test/t/func_str.test | 12 ++++++++++++ sql/item_strfunc.cc | 4 ++-- sql/sql_crypt.cc | 4 ++-- sql/sql_crypt.h | 2 +- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 00c98ad136c..25cbf2470ed 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -2526,3 +2526,17 @@ h i 31.12.2008 AAAAAA, aaaaaa DROP TABLE t1; End of 5.0 tests +drop table if exists t1; +create table t1(f1 tinyint default null)engine=myisam; +insert into t1 values (-1),(null); +explain select 1 as a from t1,(select decode(f1,f1) as b from t1) a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY ALL NULL NULL NULL NULL 2 Using join buffer +2 DERIVED t1 ALL NULL NULL NULL NULL 2 +explain select 1 as a from t1,(select encode(f1,f1) as b from t1) a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY ALL NULL NULL NULL NULL 2 Using join buffer +2 DERIVED t1 ALL NULL NULL NULL NULL 2 +drop table t1; diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index b71dbe91467..ef406d2aeca 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1283,3 +1283,15 @@ SELECT DATE_FORMAT(c, GET_FORMAT(DATE, 'eur')) h, CONCAT(UPPER(aa),', ', aa) i F DROP TABLE t1; --echo End of 5.0 tests + +# +# Bug#44358 valgrind errors with decode() function +# +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1(f1 tinyint default null)engine=myisam; +insert into t1 values (-1),(null); +explain select 1 as a from t1,(select decode(f1,f1) as b from t1) a; +explain select 1 as a from t1,(select encode(f1,f1) as b from t1) a; +drop table t1; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 5a8b1c6493c..5bb561fc1a9 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1742,7 +1742,7 @@ String *Item_func_encode::val_str(String *str) null_value=0; res=copy_if_not_alloced(str,res,res->length()); - SQL_CRYPT sql_crypt(password->ptr()); + SQL_CRYPT sql_crypt(password->ptr(), password->length()); sql_crypt.init(); sql_crypt.encode((char*) res->ptr(),res->length()); res->set_charset(&my_charset_bin); @@ -1771,7 +1771,7 @@ String *Item_func_decode::val_str(String *str) null_value=0; res=copy_if_not_alloced(str,res,res->length()); - SQL_CRYPT sql_crypt(password->ptr()); + SQL_CRYPT sql_crypt(password->ptr(), password->length()); sql_crypt.init(); sql_crypt.decode((char*) res->ptr(),res->length()); return res; diff --git a/sql/sql_crypt.cc b/sql/sql_crypt.cc index aa21d429d90..c4f93cc2a33 100644 --- a/sql/sql_crypt.cc +++ b/sql/sql_crypt.cc @@ -28,10 +28,10 @@ #include "mysql_priv.h" -SQL_CRYPT::SQL_CRYPT(const char *password) +SQL_CRYPT::SQL_CRYPT(const char *password, uint length) { ulong rand_nr[2]; - hash_password(rand_nr,password, (uint) strlen(password)); + hash_password(rand_nr,password, length); crypt_init(rand_nr); } diff --git a/sql/sql_crypt.h b/sql/sql_crypt.h index f3db9adde25..a5a6bee8a58 100644 --- a/sql/sql_crypt.h +++ b/sql/sql_crypt.h @@ -25,7 +25,7 @@ class SQL_CRYPT :public Sql_alloc uint shift; void crypt_init(ulong *seed); public: - SQL_CRYPT(const char *seed); + SQL_CRYPT(const char *seed, uint length); SQL_CRYPT(ulong *seed) { crypt_init(seed); From 0c65370a06e4bee800c82ff1369593a145cb4886 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 23 Apr 2009 12:47:54 +0500 Subject: [PATCH 56/85] Bug#44365 valgrind warnings with encrypt() function replaced String->c_ptr() with String->c_ptr_safe() --- mysql-test/r/func_encrypt.result | 12 ++++++++++++ mysql-test/t/func_encrypt.test | 13 +++++++++++++ sql/item_strfunc.cc | 4 ++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_encrypt.result b/mysql-test/r/func_encrypt.result index 04af76429f8..2e5812eb44f 100644 --- a/mysql-test/r/func_encrypt.result +++ b/mysql-test/r/func_encrypt.result @@ -183,3 +183,15 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: Note 1003 select des_decrypt(des_encrypt('hello',4),'password2') AS `des_decrypt(des_encrypt("hello",4),'password2')`,des_decrypt(des_encrypt('hello','hidden')) AS `des_decrypt(des_encrypt("hello","hidden"))` +drop table if exists t1; +create table t1 (f1 smallint(6) default null, f2 mediumtext character set utf8) +engine=myisam default charset=latin1; +insert into t1 values (null,'contraction\'s'); +insert into t1 values (-15818,'requirement\'s'); +select encrypt(f1,f2) as a from t1,(select encrypt(f1,f2) as b from t1) a; +a +NULL +re3VF.eOzS/lg +NULL +re3VF.eOzS/lg +drop table t1; diff --git a/mysql-test/t/func_encrypt.test b/mysql-test/t/func_encrypt.test index bcf1e5a77f4..31cfae2be1d 100644 --- a/mysql-test/t/func_encrypt.test +++ b/mysql-test/t/func_encrypt.test @@ -88,3 +88,16 @@ select hex(des_decrypt(des_encrypt("hello","hidden"))); explain extended select des_decrypt(des_encrypt("hello",4),'password2'), des_decrypt(des_encrypt("hello","hidden")); # End of 4.1 tests + +# +# Bug#44365 valgrind warnings with encrypt() function +# +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (f1 smallint(6) default null, f2 mediumtext character set utf8) +engine=myisam default charset=latin1; +insert into t1 values (null,'contraction\'s'); +insert into t1 values (-15818,'requirement\'s'); +select encrypt(f1,f2) as a from t1,(select encrypt(f1,f2) as b from t1) a; +drop table t1; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 5bb561fc1a9..267036e4a3d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1693,10 +1693,10 @@ String *Item_func_encrypt::val_str(String *str) String *salt_str=args[1]->val_str(&tmp_value); if ((null_value= (args[1]->null_value || salt_str->length() < 2))) return 0; - salt_ptr= salt_str->c_ptr(); + salt_ptr= salt_str->c_ptr_safe(); } pthread_mutex_lock(&LOCK_crypt); - char *tmp= crypt(res->c_ptr(),salt_ptr); + char *tmp= crypt(res->c_ptr_safe(),salt_ptr); if (!tmp) { pthread_mutex_unlock(&LOCK_crypt); From ed39e7634941d8910006d0751731dca787255e29 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 23 Apr 2009 12:50:34 +0500 Subject: [PATCH 57/85] Bug#44367 valgrind warnings with find_in_set() functions init 'wc' variable --- mysql-test/r/func_set.result | 43 ++++++++++++++++++++++++++++++++++++ mysql-test/t/func_set.test | 12 ++++++++++ sql/item_func.cc | 2 +- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result index 3f9f7b85731..ecdc35ac4cd 100644 --- a/mysql-test/r/func_set.result +++ b/mysql-test/r/func_set.result @@ -103,3 +103,46 @@ CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL)) 8 End of 5.0 tests +drop table if exists t1; +create table t1 (f1 set('test1','test2','test3') character set utf8 default null) +engine=myisam default charset=latin1; +insert into t1 values (''),(null),(null),(''),(''),(''); +select find_in_set(f1,f1) as a from t1,(select find_in_set(f1,f1) as b from t1) a; +a +0 +NULL +NULL +0 +0 +0 +0 +NULL +NULL +0 +0 +0 +0 +NULL +NULL +0 +0 +0 +0 +NULL +NULL +0 +0 +0 +0 +NULL +NULL +0 +0 +0 +0 +NULL +NULL +0 +0 +0 +drop table t1; diff --git a/mysql-test/t/func_set.test b/mysql-test/t/func_set.test index e4fde6e0e0e..5f37cd2a13e 100644 --- a/mysql-test/t/func_set.test +++ b/mysql-test/t/func_set.test @@ -72,3 +72,15 @@ SELECT INTERVAL(0.0, CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL)); --echo End of 5.0 tests + +# +# Bug#44367 valgrind warnings with find_in_set() functions +# +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (f1 set('test1','test2','test3') character set utf8 default null) +engine=myisam default charset=latin1; +insert into t1 values (''),(null),(null),(''),(''),(''); +select find_in_set(f1,f1) as a from t1,(select find_in_set(f1,f1) as b from t1) a; +drop table t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 8fc9fadb6bd..876aee719a3 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2716,7 +2716,7 @@ longlong Item_func_find_in_set::val_int() int diff; if ((diff=buffer->length() - find->length()) >= 0) { - my_wc_t wc; + my_wc_t wc= 0; CHARSET_INFO *cs= cmp_collation.collation; const char *str_begin= buffer->ptr(); const char *str_end= buffer->ptr(); From f3d921c08273123385c4e1db590c3e18d33f9c7a Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 23 Apr 2009 16:24:08 +0500 Subject: [PATCH 58/85] BUG#42907 - Multi-term boolean fulltext query containing a single quote fails in 5.1.x Performing fulltext prefix search (a word with truncation operator) may cause a dead-loop. The problem was in smarter index merge algorithm - it was writing record reference to an incorrect memory area. --- mysql-test/r/fulltext.result | 8 ++++++++ mysql-test/t/fulltext.test | 9 +++++++++ storage/myisam/ft_boolean_search.c | 21 +++++++++++++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index a980c7bfa01..d1edce12cce 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -535,3 +535,11 @@ CREATE TABLE t1(a TEXT); SELECT GROUP_CONCAT(a) AS st FROM t1 HAVING MATCH(st) AGAINST('test' IN BOOLEAN MODE); ERROR HY000: Incorrect arguments to AGAINST DROP TABLE t1; +CREATE TABLE t1(a VARCHAR(64), FULLTEXT(a)); +INSERT INTO t1 VALUES('awrd bwrd cwrd'),('awrd bwrd cwrd'),('awrd bwrd cwrd'); +SELECT * FROM t1 WHERE MATCH(a) AGAINST('+awrd bwrd* +cwrd*' IN BOOLEAN MODE); +a +awrd bwrd cwrd +awrd bwrd cwrd +awrd bwrd cwrd +DROP TABLE t1; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 11dbff5ce9a..b565485bab9 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -462,3 +462,12 @@ CREATE TABLE t1(a TEXT); --error ER_WRONG_ARGUMENTS SELECT GROUP_CONCAT(a) AS st FROM t1 HAVING MATCH(st) AGAINST('test' IN BOOLEAN MODE); DROP TABLE t1; + +# +# BUG#42907 - Multi-term boolean fulltext query containing a single +# quote fails in 5.1.x +# +CREATE TABLE t1(a VARCHAR(64), FULLTEXT(a)); +INSERT INTO t1 VALUES('awrd bwrd cwrd'),('awrd bwrd cwrd'),('awrd bwrd cwrd'); +SELECT * FROM t1 WHERE MATCH(a) AGAINST('+awrd bwrd* +cwrd*' IN BOOLEAN MODE); +DROP TABLE t1; diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c index 66097864622..58363894cff 100644 --- a/storage/myisam/ft_boolean_search.c +++ b/storage/myisam/ft_boolean_search.c @@ -335,7 +335,23 @@ static int _ftb_no_dupes_cmp(void* not_used __attribute__((unused)), return CMP_NUM((*((my_off_t*)a)), (*((my_off_t*)b))); } -/* returns 1 if the search was finished (must-word wasn't found) */ +/* + When performing prefix search (a word with truncation operator), we + must preserve original prefix to ensure that characters which may be + expanded/contracted do not break the prefix. This is done by storing + newly found key immediatly after the original word in ftbw->word + buffer. + + ftbw->word= LENGTH WORD [ LENGTH1 WORD1 ] WEIGHT REFERENCE + LENGTH - 1 byte, length of the WORD + WORD - LENGTH bytes, the word itself + LENGTH1 - 1 byte, length of the WORD1, present in case of prefix search + WORD1 - LENGTH bytes, the word itself, present in case of prefix search + WEIGHT - 4 bytes (HA_FT_WLEN), either weight or number of subkeys + REFERENCE - rec_reflength bytes, pointer to the record + + returns 1 if the search was finished (must-word wasn't found) +*/ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) { int r; @@ -369,7 +385,8 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) if (ftbw->docid[0] < max_docid) { sflag|= SEARCH_SAME; - _mi_dpointer(info, (uchar *)(ftbw->word + ftbw->len + HA_FT_WLEN), + _mi_dpointer(info, (uchar*) (lastkey_buf + HA_FT_WLEN + + (ftbw->off ? 0 : lastkey_buf[0] + 1)), max_docid); } r=_mi_search(info, ftbw->keyinfo, (uchar*) lastkey_buf, From 7fc1ab0b4ba99fec01ce317f27b888b9da7e3fe7 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Thu, 23 Apr 2009 19:52:39 +0200 Subject: [PATCH 59/85] Bug#33146 CHECKSUM TABLE is not interruptable by KILL QUERY statement Commit 55629 applied to 5.0-bugteam and 5.1-bugteam: Check for thd->killed in CHECKSUM loop. --- sql/sql_table.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index eec6ad626f0..08ea093f2c8 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4376,6 +4376,16 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) { for (;;) { + if (thd->killed) + { + /* + we've been killed; let handler clean up, and remove the + partial current row from the recordset (embedded lib) + */ + t->file->ha_rnd_end(); + thd->protocol->remove_last_row(); + goto err; + } ha_checksum row_crc= 0; int error= t->file->rnd_next(t->record[0]); if (unlikely(error)) From 99d1233a72f7f04cd3a75661d08671ac14067896 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Fri, 24 Apr 2009 02:02:07 +0100 Subject: [PATCH 60/85] BUG#44389 rpl_row_mysqlbinlog fails on windows due to operating system specifc command Replaced "--exec rm" by "remove_file" which is a mysqltest command to erase a file. --- mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test b/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test index 62b46eeb58e..3328d582692 100644 --- a/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test +++ b/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test @@ -244,7 +244,7 @@ connection master; # We should be gold by the time, so I will get rid of our file. ---exec rm $MYSQLTEST_VARDIR/tmp/remote.sql +--remove_file $MYSQLTEST_VARDIR/tmp/remote.sql ################### End Bug 17654 ###################### # What is the point of this test? It seems entirely pointless. It @@ -349,9 +349,9 @@ FLUSH LOGS; --diff_files $MYSQLTEST_VARDIR/tmp/local.sql $MYSQLTEST_VARDIR/tmp/remote.sql ---exec rm $MYSQLTEST_VARDIR/tmp/remote.sql +--remove_file $MYSQLTEST_VARDIR/tmp/remote.sql ---exec rm $MYSQLTEST_VARDIR/tmp/local.sql +--remove_file $MYSQLTEST_VARDIR/tmp/local.sql DROP TABLE IF EXISTS t1, t2, t3, t04, t05, t4, t5; sync_slave_with_master; From 022a326d3a1a1118f467959d244d682ae3c1ee8c Mon Sep 17 00:00:00 2001 From: Anurag Shekhar Date: Fri, 24 Apr 2009 14:49:07 +0530 Subject: [PATCH 61/85] Bug #44353 build-v9.bat is missing in source archive Entry for build-vs9.bat and build-vs9_x64.bat was missing in win/Makefile.am. Added the entries to fix the problem. --- win/Makefile.am | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/win/Makefile.am b/win/Makefile.am index 279183480d8..5dc637ae8a3 100644 --- a/win/Makefile.am +++ b/win/Makefile.am @@ -14,8 +14,9 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ## Process this file with automake to create Makefile.in -EXTRA_DIST = build-vs71.bat build-vs8.bat build-vs8_x64.bat configure.js README \ - mysql_manifest.cmake create_manifest.js +EXTRA_DIST = build-vs71.bat build-vs8.bat build-vs8_x64.bat build-vs9.bat \ + build-vs9_x64.bat configure.js README mysql_manifest.cmake \ + create_manifest.js # Don't update the files from bitkeeper %::SCCS/s.% From 97ae03bf526a0cef7c76739b9a583a0f6209aa7f Mon Sep 17 00:00:00 2001 From: Satya B Date: Fri, 24 Apr 2009 16:33:50 +0530 Subject: [PATCH 62/85] Fix for BUG#43660- SHOW INDEXES/ANALYZE does NOT update cardinality for indexes of InnoDB table Fixes by replacing the PRNG that is used to pick random pages with a better one. Also adds a configuration option "innodb_use_legacy_cardinality_algorithm" to enable the fix only when the option is set. This patch is from http://bugs.mysql.com/file.php?id=11789 --- innobase/include/srv0srv.h | 6 +++ innobase/page/page0cur.c | 75 +++++++++++++++++++++++++++++++++++++- innobase/srv/srv0srv.c | 6 +++ sql/ha_innodb.h | 5 +++ sql/mysqld.cc | 11 +++++- sql/set_var.cc | 6 +++ 6 files changed, 106 insertions(+), 3 deletions(-) diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 97e9136040d..ece6b1d763f 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -253,6 +253,12 @@ extern ulint srv_read_ahead_seq; /* variable to count the number of random read-aheads were done */ extern ulint srv_read_ahead_rnd; +/* An option to enable the fix for "Bug#43660 SHOW INDEXES/ANALYZE does +NOT update cardinality for indexes of InnoDB table". By default we are +running with the fix disabled because MySQL 5.1 is frozen for such +behavioral changes. */ +extern char srv_use_legacy_cardinality_algorithm; + /* In this structure we store status variables to be passed to MySQL */ typedef struct export_var_struct export_struc; diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c index d0b89e81787..93082560001 100644 --- a/innobase/page/page0cur.c +++ b/innobase/page/page0cur.c @@ -15,6 +15,8 @@ Created 10/4/1994 Heikki Tuuri #include "mtr0log.h" #include "log0recv.h" #include "rem0cmp.h" +#include "srv0srv.h" +#include "ut0ut.h" static ulint page_rnd = 976722341; @@ -23,6 +25,44 @@ static ulint page_rnd = 976722341; ulint page_cur_short_succ = 0; # endif /* UNIV_SEARCH_PERF_STAT */ +/*********************************************************************** +This is a linear congruential generator PRNG. Returns a pseudo random +number between 0 and 2^64-1 inclusive. The formula and the constants +being used are: +X[n+1] = (a * X[n] + c) mod m +where: +X[0] = ut_usectime() +a = 1103515245 (3^5 * 5 * 7 * 129749) +c = 12345 (3 * 5 * 823) +m = 18446744073709551616 (2^64) +*/ +#define LCG_a 1103515245 +#define LCG_c 12345 +static +unsigned long long +page_cur_lcg_prng() +/*===============*/ + /* out: number between 0 and 2^64-1 */ +{ + static unsigned long long lcg_current = 0; + static ibool initialized = FALSE; + ulint time_sec; + ulint time_ms; + + if (!initialized) { + ut_usectime(&time_sec, &time_ms); + lcg_current = (unsigned long long) (time_sec * 1000000 + + time_ms); + initialized = TRUE; + } + + /* no need to "% 2^64" explicitly because lcg_current is + 64 bit and this will be done anyway */ + lcg_current = LCG_a * lcg_current + LCG_c; + + return(lcg_current); +} + /******************************************************************** Tries a search shortcut based on the last insert. */ UNIV_INLINE @@ -489,9 +529,13 @@ page_cur_open_on_rnd_user_rec( return; } - page_rnd += 87584577; + if (srv_use_legacy_cardinality_algorithm) { + page_rnd += 87584577; - rnd = page_rnd % page_get_n_recs(page); + rnd = page_rnd % page_get_n_recs(page); + } else { + rnd = (ulint) page_cur_lcg_prng() % page_get_n_recs(page); + } rec = page_get_infimum_rec(page); @@ -1419,3 +1463,30 @@ page_cur_delete_rec( page_dir_balance_slot(page, cur_slot_no); } } + +#ifdef UNIV_COMPILE_TEST_FUNCS + +/*********************************************************************** +Print the first n numbers, generated by page_cur_lcg_prng() to make sure +(visually) that it works properly. */ +void +test_page_cur_lcg_prng( +/*===================*/ + int n) /* in: print first n numbers */ +{ + int i; + unsigned long long rnd; + + for (i = 0; i < n; i++) { + rnd = page_cur_lcg_prng(); + printf("%llu\t%%2=%llu %%3=%llu %%5=%llu %%7=%llu %%11=%llu\n", + rnd, + rnd % 2, + rnd % 3, + rnd % 5, + rnd % 7, + rnd % 11); + } +} + +#endif /* UNIV_COMPILE_TEST_FUNCS */ diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 6b755ae9816..0974c616db3 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -239,6 +239,12 @@ ulint srv_read_ahead_seq = 0; /* variable to count the number of random read-aheads */ ulint srv_read_ahead_rnd = 0; +/* An option to enable the fix for "Bug#43660 SHOW INDEXES/ANALYZE does +NOT update cardinality for indexes of InnoDB table". By default we are +running with the fix disabled because MySQL 5.1 is frozen for such +behavioral changes. */ +char srv_use_legacy_cardinality_algorithm = TRUE; + /* structure to pass status variables to MySQL */ export_struc export_vars; diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 3db983901b3..e27fb89d014 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -234,6 +234,11 @@ extern ulong srv_thread_sleep_delay; extern ulong srv_thread_concurrency; extern ulong srv_commit_concurrency; extern ulong srv_flush_log_at_trx_commit; +/* An option to enable the fix for "Bug#43660 SHOW INDEXES/ANALYZE does +NOT update cardinality for indexes of InnoDB table". By default we are +running with the fix disabled because MySQL 5.1 is frozen for such +behavioral changes. */ +extern char srv_use_legacy_cardinality_algorithm; } bool innobase_init(void); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ad3521e5dde..0583e3fa57f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5044,7 +5044,8 @@ enum options_mysqld OPT_SECURE_FILE_PRIV, OPT_KEEP_FILES_ON_CREATE, OPT_INNODB_ADAPTIVE_HASH_INDEX, - OPT_FEDERATED + OPT_FEDERATED, + OPT_INNODB_USE_LEGACY_CARDINALITY_ALGORITHM }; @@ -5351,6 +5352,14 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite, (gptr*) &global_system_variables.innodb_table_locks, (gptr*) &global_system_variables.innodb_table_locks, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, + {"innodb_use_legacy_cardinality_algorithm", + OPT_INNODB_USE_LEGACY_CARDINALITY_ALGORITHM, + "Use legacy algorithm for picking random pages during index cardinality " + "estimation. Disable this to use a better algorithm, but note that your " + "query plans may change (enabled by default).", + (gptr*) &srv_use_legacy_cardinality_algorithm, + (gptr*) &srv_use_legacy_cardinality_algorithm, + 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, #endif /* End HAVE_INNOBASE_DB */ {"isam", OPT_ISAM, "Obsolete. ISAM storage engine is no longer supported.", (gptr*) &opt_isam, (gptr*) &opt_isam, 0, GET_BOOL, NO_ARG, 0, 0, 0, diff --git a/sql/set_var.cc b/sql/set_var.cc index 735bb5279bd..14ec2e57aab 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -450,6 +450,9 @@ sys_var_thd_bool sys_innodb_table_locks("innodb_table_locks", &SV::innodb_table_locks); sys_var_thd_bool sys_innodb_support_xa("innodb_support_xa", &SV::innodb_support_xa); +sys_var_bool_ptr sys_innodb_use_legacy_cardinality_algorithm( + "innodb_use_legacy_cardinality_algorithm", + &srv_use_legacy_cardinality_algorithm); sys_var_long_ptr sys_innodb_autoextend_increment("innodb_autoextend_increment", &srv_auto_extend_increment); sys_var_long_ptr sys_innodb_sync_spin_loops("innodb_sync_spin_loops", @@ -804,6 +807,7 @@ sys_var *sys_variables[]= &sys_innodb_max_purge_lag, &sys_innodb_table_locks, &sys_innodb_support_xa, + &sys_innodb_use_legacy_cardinality_algorithm, &sys_innodb_autoextend_increment, &sys_innodb_sync_spin_loops, &sys_innodb_concurrency_tickets, @@ -946,6 +950,8 @@ struct show_var_st init_vars[]= { {sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS}, {sys_innodb_thread_concurrency.name, (char*) &sys_innodb_thread_concurrency, SHOW_SYS}, {sys_innodb_thread_sleep_delay.name, (char*) &sys_innodb_thread_sleep_delay, SHOW_SYS}, + {sys_innodb_use_legacy_cardinality_algorithm.name, + (char*) &sys_innodb_use_legacy_cardinality_algorithm, SHOW_SYS}, #endif {sys_interactive_timeout.name,(char*) &sys_interactive_timeout, SHOW_SYS}, {sys_join_buffer_size.name, (char*) &sys_join_buffer_size, SHOW_SYS}, From 8d06b4de51126f856793d00d1e3d49b80cbf87b0 Mon Sep 17 00:00:00 2001 From: Satya B Date: Fri, 24 Apr 2009 17:18:20 +0530 Subject: [PATCH 63/85] Applying InnoDB snashot 5.0-ss4900 part 1, Fixes BUG#42279 1) BUG#42279 - Race condition in btr_search_drop_page_hash_when_freed() Detailed revision comments: r4031 | marko | 2009-01-23 15:33:46 +0200 (Fri, 23 Jan 2009) | 8 lines branches/5.0: btr_search_drop_page_hash_when_freed(): Check if buf_page_get_gen() returns NULL. The page may have been evicted from the buffer pool between buf_page_peek_if_search_hashed() and buf_page_get_gen(), because the buffer pool mutex will be released between these two calls. (Bug #42279) rb://82 approved by Heikki Tuuri --- innobase/btr/btr0sea.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index 3c202c5a3bf..e8f294e9305 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -1101,12 +1101,20 @@ btr_search_drop_page_hash_when_freed( page = buf_page_get_gen(space, page_no, RW_S_LATCH, NULL, BUF_GET_IF_IN_POOL, __FILE__, __LINE__, &mtr); + /* Because the buffer pool mutex was released by + buf_page_peek_if_search_hashed(), it is possible that the + block was removed from the buffer pool by another thread + before buf_page_get_gen() got a chance to acquire the buffer + pool mutex again. Thus, we must check for a NULL return. */ + + if (UNIV_LIKELY(page != NULL)) { #ifdef UNIV_SYNC_DEBUG - buf_page_dbg_add_level(page, SYNC_TREE_NODE_FROM_HASH); + buf_page_dbg_add_level(page, SYNC_TREE_NODE_FROM_HASH); #endif /* UNIV_SYNC_DEBUG */ - btr_search_drop_page_hash_index(page); + btr_search_drop_page_hash_index(page); + } mtr_commit(&mtr); } From f05f760e660abb29bb4e48b7e22b685796174875 Mon Sep 17 00:00:00 2001 From: Satya B Date: Fri, 24 Apr 2009 17:27:53 +0530 Subject: [PATCH 64/85] Applying InnoDB snashot 5.0-ss4900, part 2. Fixes BUG#43309 1) BUG#43309 - Test main.innodb can't be run twice Detailed revision comments: r4701 | vasil | 2009-04-13 17:03:46 +0300 (Mon, 13 Apr 2009) | 6 lines branches/5.0: Fix Bug#43309 Test main.innodb can't be run twice by making the innodb.test reentrant. --- mysql-test/r/innodb.result | 15 ++++++--------- mysql-test/t/innodb.test | 29 ++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 854712fdb1d..415fbe87f53 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1803,15 +1803,12 @@ Innodb_buffer_pool_pages_total 512 show status like "Innodb_page_size"; Variable_name Value Innodb_page_size 16384 -show status like "Innodb_rows_deleted"; -Variable_name Value -Innodb_rows_deleted 73 -show status like "Innodb_rows_inserted"; -Variable_name Value -Innodb_rows_inserted 29734 -show status like "Innodb_rows_updated"; -Variable_name Value -Innodb_rows_updated 29532 +innodb_rows_deleted +73 +innodb_rows_inserted +29734 +innodb_rows_updated +29532 show status like "Innodb_row_lock_waits"; Variable_name Value Innodb_row_lock_waits 0 diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index d045bad39f7..f09901d1112 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -13,6 +13,18 @@ -- source include/have_innodb.inc +# Save the original values of some variables in order to be able to +# estimate how much they have changed during the tests. Previously this +# test assumed that e.g. rows_deleted is 0 here and after deleting 23 +# rows it expected that rows_deleted will be 23. Now we do not make +# assumptions about the values of the variables at the beginning, e.g. +# rows_deleted should be 23 + "rows_deleted before the test". This allows +# the test to be run multiple times without restarting the mysqld server. +# See Bug#43309 Test main.innodb can't be run twice +-- let $innodb_rows_deleted_orig = query_get_value(SHOW STATUS WHERE variable_name = 'innodb_rows_deleted', Value, 1) +-- let $innodb_rows_inserted_orig = query_get_value(SHOW STATUS WHERE variable_name = 'innodb_rows_inserted', Value, 1) +-- let $innodb_rows_updated_orig = query_get_value(SHOW STATUS WHERE variable_name = 'innodb_rows_updated', Value, 1) + # # Small basic test with ignore # @@ -1344,9 +1356,14 @@ drop table t1; # uses previous ones(pages_created, rows_deleted, ...). show status like "Innodb_buffer_pool_pages_total"; show status like "Innodb_page_size"; -show status like "Innodb_rows_deleted"; -show status like "Innodb_rows_inserted"; -show status like "Innodb_rows_updated"; +-- let $innodb_rows_deleted = query_get_value(SHOW STATUS WHERE variable_name = 'innodb_rows_deleted', Value, 1) +-- let $innodb_rows_inserted = query_get_value(SHOW STATUS WHERE variable_name = 'innodb_rows_inserted', Value, 1) +-- let $innodb_rows_updated = query_get_value(SHOW STATUS WHERE variable_name = 'innodb_rows_updated', Value, 1) +-- disable_query_log +-- eval SELECT $innodb_rows_deleted - $innodb_rows_deleted_orig AS innodb_rows_deleted +-- eval SELECT $innodb_rows_inserted - $innodb_rows_inserted_orig AS innodb_rows_inserted +-- eval SELECT $innodb_rows_updated - $innodb_rows_updated_orig AS innodb_rows_updated +-- enable_query_log # Test for row locks InnoDB status variables. show status like "Innodb_row_lock_waits"; @@ -1365,6 +1382,8 @@ set global innodb_sync_spin_loops=20; show variables like "innodb_sync_spin_loops"; # Test for innodb_thread_concurrency variable +# save the original value so we can restore it at the end +-- let $innodb_thread_concurrency_orig = query_get_value(SHOW VARIABLES WHERE variable_name = 'innodb_thread_concurrency', Value, 1) show variables like "innodb_thread_concurrency"; set global innodb_thread_concurrency=1001; show variables like "innodb_thread_concurrency"; @@ -1372,6 +1391,10 @@ set global innodb_thread_concurrency=0; show variables like "innodb_thread_concurrency"; set global innodb_thread_concurrency=16; show variables like "innodb_thread_concurrency"; +# restore the orginal value, this way the test can be run multiple times +-- disable_query_log +-- eval set global innodb_thread_concurrency = $innodb_thread_concurrency_orig +-- enable_query_log # Test for innodb_concurrency_tickets variable show variables like "innodb_concurrency_tickets"; From 3df4ad8a5d5452d9a62027c7fbe82ba1875a93c5 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Fri, 24 Apr 2009 12:58:23 -0400 Subject: [PATCH 65/85] Bug#32784: Timeout in test "innodb_charset": InnoDB much slower than other handlers Turned off autocommit at the start of this test per Innobase recommendation. Noted significant reduction in run time for this test w/ a minor increase in other tests' run-times. --- mysql-test/suite/funcs_2/charset/charset_master.test | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mysql-test/suite/funcs_2/charset/charset_master.test b/mysql-test/suite/funcs_2/charset/charset_master.test index 09e24e2c246..99ca4564a0b 100644 --- a/mysql-test/suite/funcs_2/charset/charset_master.test +++ b/mysql-test/suite/funcs_2/charset/charset_master.test @@ -86,6 +86,15 @@ let $check_std_csets= 1; let $check_ucs2_csets= 1; let $check_utf8_csets= 1; +# Bug#32784: Timeout in test "innodb_charset": InnoDB much slower +# than other handlers +# NOTE: We turn autocommit off to improve the performance of the innodb variant +# of this test. Per Innobase's recommendation. + +--disable_query_log +SET autocommit=0; +--enable_query_log + # # Check all charsets/collation combinations # From 8126db7c9605b9909ba08d7d0da9959970e9b7d2 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Sun, 26 Apr 2009 22:21:01 +0100 Subject: [PATCH 66/85] Fixed rpl_innodb_mixed_ddl and rpl_000015. Respectively, replaced "--exec diff" by "--diff_files" which is a mysqltest command to run a non-operating system specific diff. Removed the file rpl_000015-slave.sh as it is not necessary in the new MTR. --- mysql-test/suite/rpl/include/rpl_mixed_ddl.inc | 2 +- mysql-test/suite/rpl/t/rpl_000015-slave.sh | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100755 mysql-test/suite/rpl/t/rpl_000015-slave.sh diff --git a/mysql-test/suite/rpl/include/rpl_mixed_ddl.inc b/mysql-test/suite/rpl/include/rpl_mixed_ddl.inc index 6a00dcc6e50..70e17cef9fe 100644 --- a/mysql-test/suite/rpl/include/rpl_mixed_ddl.inc +++ b/mysql-test/suite/rpl/include/rpl_mixed_ddl.inc @@ -83,4 +83,4 @@ sync_slave_with_master; # will be created. You will need to go to the mysql-test dir and diff # the files your self to see what is not matching ---exec diff $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_slave.sql +--diff_files $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_slave.sql diff --git a/mysql-test/suite/rpl/t/rpl_000015-slave.sh b/mysql-test/suite/rpl/t/rpl_000015-slave.sh deleted file mode 100755 index 7deeca3d2d6..00000000000 --- a/mysql-test/suite/rpl/t/rpl_000015-slave.sh +++ /dev/null @@ -1 +0,0 @@ -rm -f $MYSQLTEST_VARDIR/slave-data/master.info From 00c37fdfbaa59145522304283df5cff979b6d6f7 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Mon, 27 Apr 2009 15:05:01 +0500 Subject: [PATCH 67/85] ENCRYPT function always returns NULL on windows. The fix is to disable result log as we need to test valgrind error only. --- mysql-test/r/func_encrypt.result | 5 ----- mysql-test/t/func_encrypt.test | 2 ++ 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/func_encrypt.result b/mysql-test/r/func_encrypt.result index 2e5812eb44f..8fbf36b45b9 100644 --- a/mysql-test/r/func_encrypt.result +++ b/mysql-test/r/func_encrypt.result @@ -189,9 +189,4 @@ engine=myisam default charset=latin1; insert into t1 values (null,'contraction\'s'); insert into t1 values (-15818,'requirement\'s'); select encrypt(f1,f2) as a from t1,(select encrypt(f1,f2) as b from t1) a; -a -NULL -re3VF.eOzS/lg -NULL -re3VF.eOzS/lg drop table t1; diff --git a/mysql-test/t/func_encrypt.test b/mysql-test/t/func_encrypt.test index 31cfae2be1d..879732fc81f 100644 --- a/mysql-test/t/func_encrypt.test +++ b/mysql-test/t/func_encrypt.test @@ -99,5 +99,7 @@ create table t1 (f1 smallint(6) default null, f2 mediumtext character set utf8) engine=myisam default charset=latin1; insert into t1 values (null,'contraction\'s'); insert into t1 values (-15818,'requirement\'s'); +--disable_result_log select encrypt(f1,f2) as a from t1,(select encrypt(f1,f2) as b from t1) a; +--enable_result_log drop table t1; From fa01a4ed26a0851157690ca1b422481d8e817908 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Tue, 28 Apr 2009 05:19:13 +0500 Subject: [PATCH 68/85] backport from 6.0: Bug #40925: Equality propagation takes non indexed attribute Query execution plans and execution time of queries like select a, b, c from t1 where a > '2008-11-21' and b = a limit 10 depended on the order of equality operator parameters: "b = a" and "a = b" are not same. An equality propagation algorithm has been fixed: the substitute_for_best_equal_field function should not substitute a field for an equal field if both fields belong to the same table. --- mysql-test/r/select.result | 13 +++++++++++++ mysql-test/t/select.test | 14 ++++++++++++++ sql/item.cc | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 9558b0533ad..c9dd65108da 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4388,4 +4388,17 @@ f3 f4 count 1 abc 1 1 def 2 drop table t1, t2, t3; +CREATE TABLE t1 (a INT KEY, b INT); +INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4); +EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND a = b LIMIT 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2 +EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` > 1)) limit 2 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 1e8dc7ac2f6..60f2f191e0b 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3737,4 +3737,18 @@ cr.f4 = cr2.f4 GROUP BY a.f3, cr.f4; drop table t1, t2, t3; + + +# +# Bug #40925: Equality propagation takes non indexed attribute +# + +CREATE TABLE t1 (a INT KEY, b INT); +INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4); + +EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND a = b LIMIT 2; +EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2; + +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index c284e8b3bf4..13f09914ec6 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4341,7 +4341,7 @@ Item *Item_field::replace_equal_field(byte *arg) return const_item; } Item_field *subst= item_equal->get_first(); - if (subst && !field->eq(subst->field)) + if (subst && field->table != subst->field->table && !field->eq(subst->field)) return subst; } return this; From d1968ad43f9256f0007eec6c2375a493464e745c Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Tue, 28 Apr 2009 14:47:26 +0500 Subject: [PATCH 69/85] Bug#38990 Arbitrary data input plus GIS functions causes mysql server crash the Point() and Linestring() functions create WKB representation of an object instead of an real geometry object. That produced bugs when these were inserted into tables. GIS tests fixed accordingly. per-file messages: mysql-test/r/gis-rtree.result Bug#38990 Arbitrary data input plus GIS functions causes mysql server crash test result mysql-test/r/gis.result Bug#38990 Arbitrary data input plus GIS functions causes mysql server crash test result mysql-test/t/gis-rtree.test Bug#38990 Arbitrary data input plus GIS functions causes mysql server crash test fixed - GeomFromWKB invocations removed mysql-test/t/gis.test Bug#38990 Arbitrary data input plus GIS functions causes mysql server crash test fixed - AsWKB invocations added sql/item_geofunc.cc Bug#38990 Arbitrary data input plus GIS functions causes mysql server crash Point() and similar functions to create a proper object --- mysql-test/r/gis-rtree.result | 668 +++++++++++++++++----------------- mysql-test/r/gis.result | 12 +- mysql-test/t/gis-rtree.test | 72 ++-- mysql-test/t/gis.test | 12 +- sql/item_geofunc.cc | 27 +- 5 files changed, 401 insertions(+), 390 deletions(-) diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result index 99bfede3ee0..a4fa929c32e 100644 --- a/mysql-test/r/gis-rtree.result +++ b/mysql-test/r/gis-rtree.result @@ -186,106 +186,106 @@ CREATE TABLE t2 ( fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, g GEOMETRY NOT NULL ) ENGINE=MyISAM; -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10)))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10))); ALTER TABLE t2 ADD SPATIAL KEY(g); SHOW CREATE TABLE t2; Table Create Table @@ -309,406 +309,406 @@ fid AsText(g) 56 LINESTRING(41 41,50 50) 45 LINESTRING(51 51,60 60) 55 LINESTRING(41 51,50 60) -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10))))); +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -99 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -98 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -97 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -96 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -95 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -94 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -93 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -92 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -91 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -90 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -89 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -88 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -87 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -86 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -85 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -84 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -83 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -82 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -81 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -80 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -79 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -78 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -77 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -76 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -75 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -74 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -73 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -72 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -71 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -70 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -69 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -68 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -67 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -66 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -65 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -64 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -63 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -62 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -61 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -60 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -59 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -58 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -57 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -56 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -55 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -54 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -53 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -52 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -51 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -50 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -49 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -48 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -47 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -46 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -45 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -44 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -43 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -42 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -41 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -40 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -39 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -38 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -37 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -36 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -35 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -34 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -33 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -32 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -31 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -30 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -29 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -28 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -27 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -26 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -25 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -24 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -23 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -22 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -21 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -20 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -19 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -18 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -17 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -16 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -15 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -14 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -13 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -12 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -11 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -10 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -9 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -8 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -7 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -6 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -5 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -4 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -3 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -2 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -1 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -0 +100 DROP TABLE t2; drop table if exists t1; Warnings: @@ -863,11 +863,11 @@ Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; CREATE TABLE t1 (foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) ); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,1))); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,0))); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,1))); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,0))); -SELECT 1 FROM t1 WHERE foo != PointFromWKB(POINT(0,0)); +INSERT INTO t1 (foo) VALUES (POINT(1,1)); +INSERT INTO t1 (foo) VALUES (POINT(1,0)); +INSERT INTO t1 (foo) VALUES (POINT(0,1)); +INSERT INTO t1 (foo) VALUES (POINT(0,0)); +SELECT 1 FROM t1 WHERE foo != POINT(0,0); 1 1 1 @@ -1426,35 +1426,35 @@ Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; create table t1 (a geometry not null, spatial index(a)); -insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 131072))); -insert into t1 values (PointFromWKB(POINT(9.1248812352444e+192, 2.9740338169556e+284))); -insert into t1 values (PointFromWKB(POINT(4.7783097267365e-299, -0))); -insert into t1 values (PointFromWKB(POINT(1.49166814624e-154, 2.0880974297595e-53))); -insert into t1 values (PointFromWKB(POINT(4.0917382598702e+149, 1.2024538023802e+111))); -insert into t1 values (PointFromWKB(POINT(2.0349165139404e+236, 2.9993936277913e-241))); -insert into t1 values (PointFromWKB(POINT(2.5243548967072e-29, 1.2024538023802e+111))); -insert into t1 values (PointFromWKB(POINT(0, 6.9835074892995e-251))); -insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 3.1050361846014e+231))); -insert into t1 values (PointFromWKB(POINT(2.8728483499323e-188, 2.4600631144627e+260))); -insert into t1 values (PointFromWKB(POINT(3.0517578125e-05, 2.0349165139404e+236))); -insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 1.1818212630766e-125))); -insert into t1 values (PointFromWKB(POINT(2.481040258324e-265, 5.7766220027675e-275))); -insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 2.5243548967072e-29))); -insert into t1 values (PointFromWKB(POINT(5.7766220027675e-275, 9.9464647281957e+86))); -insert into t1 values (PointFromWKB(POINT(2.2181357552967e+130, 3.7857669957337e-270))); -insert into t1 values (PointFromWKB(POINT(4.5767114681874e-246, 3.6893488147419e+19))); -insert into t1 values (PointFromWKB(POINT(4.5767114681874e-246, 3.7537584144024e+255))); -insert into t1 values (PointFromWKB(POINT(3.7857669957337e-270, 1.8033161362863e-130))); -insert into t1 values (PointFromWKB(POINT(0, 5.8774717541114e-39))); -insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 2.2761049594727e-159))); -insert into t1 values (PointFromWKB(POINT(6.243497100632e+144, 3.7857669957337e-270))); -insert into t1 values (PointFromWKB(POINT(3.7857669957337e-270, 2.6355494858076e-82))); -insert into t1 values (PointFromWKB(POINT(2.0349165139404e+236, 3.8518598887745e-34))); -insert into t1 values (PointFromWKB(POINT(4.6566128730774e-10, 2.0880974297595e-53))); -insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 1.8827498946116e-183))); -insert into t1 values (PointFromWKB(POINT(1.8033161362863e-130, 9.1248812352444e+192))); -insert into t1 values (PointFromWKB(POINT(4.7783097267365e-299, 2.2761049594727e-159))); -insert into t1 values (PointFromWKB(POINT(1.94906280228e+289, 1.2338789709327e-178))); +insert into t1 values (POINT(1.1517219314031e+164, 131072)); +insert into t1 values (POINT(9.1248812352444e+192, 2.9740338169556e+284)); +insert into t1 values (POINT(4.7783097267365e-299, -0)); +insert into t1 values (POINT(1.49166814624e-154, 2.0880974297595e-53)); +insert into t1 values (POINT(4.0917382598702e+149, 1.2024538023802e+111)); +insert into t1 values (POINT(2.0349165139404e+236, 2.9993936277913e-241)); +insert into t1 values (POINT(2.5243548967072e-29, 1.2024538023802e+111)); +insert into t1 values (POINT(0, 6.9835074892995e-251)); +insert into t1 values (POINT(2.0880974297595e-53, 3.1050361846014e+231)); +insert into t1 values (POINT(2.8728483499323e-188, 2.4600631144627e+260)); +insert into t1 values (POINT(3.0517578125e-05, 2.0349165139404e+236)); +insert into t1 values (POINT(1.1517219314031e+164, 1.1818212630766e-125)); +insert into t1 values (POINT(2.481040258324e-265, 5.7766220027675e-275)); +insert into t1 values (POINT(2.0880974297595e-53, 2.5243548967072e-29)); +insert into t1 values (POINT(5.7766220027675e-275, 9.9464647281957e+86)); +insert into t1 values (POINT(2.2181357552967e+130, 3.7857669957337e-270)); +insert into t1 values (POINT(4.5767114681874e-246, 3.6893488147419e+19)); +insert into t1 values (POINT(4.5767114681874e-246, 3.7537584144024e+255)); +insert into t1 values (POINT(3.7857669957337e-270, 1.8033161362863e-130)); +insert into t1 values (POINT(0, 5.8774717541114e-39)); +insert into t1 values (POINT(1.1517219314031e+164, 2.2761049594727e-159)); +insert into t1 values (POINT(6.243497100632e+144, 3.7857669957337e-270)); +insert into t1 values (POINT(3.7857669957337e-270, 2.6355494858076e-82)); +insert into t1 values (POINT(2.0349165139404e+236, 3.8518598887745e-34)); +insert into t1 values (POINT(4.6566128730774e-10, 2.0880974297595e-53)); +insert into t1 values (POINT(2.0880974297595e-53, 1.8827498946116e-183)); +insert into t1 values (POINT(1.8033161362863e-130, 9.1248812352444e+192)); +insert into t1 values (POINT(4.7783097267365e-299, 2.2761049594727e-159)); +insert into t1 values (POINT(1.94906280228e+289, 1.2338789709327e-178)); drop table t1; CREATE TABLE t1(foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) ); INSERT INTO t1(foo) VALUES (NULL); diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index e3b2ea751d9..5b7a58add06 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -47,26 +47,26 @@ INSERT INTO gis_point VALUES INSERT INTO gis_line VALUES (105, LineFromText('LINESTRING(0 0,0 10,10 0)')), (106, LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')), -(107, LineStringFromWKB(LineString(Point(10, 10), Point(40, 10)))); +(107, LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10))))); INSERT INTO gis_polygon VALUES (108, PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')), (109, PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')), -(110, PolyFromWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))); +(110, PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0)))))); INSERT INTO gis_multi_point VALUES (111, MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')), (112, MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')), -(113, MPointFromWKB(MultiPoint(Point(3, 6), Point(4, 10)))); +(113, MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10))))); INSERT INTO gis_multi_line VALUES (114, MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')), (115, MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')), -(116, MLineFromWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))); +(116, MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7)))))); INSERT INTO gis_multi_polygon VALUES (117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')), (118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')), -(119, MPolyFromWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))); +(119, MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3))))))); INSERT INTO gis_geometrycollection VALUES (120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')), -(121, GeometryFromWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9))))); +(121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))); INSERT into gis_geometry SELECT * FROM gis_point; INSERT into gis_geometry SELECT * FROM gis_line; INSERT into gis_geometry SELECT * FROM gis_polygon; diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test index e68e5039adf..2c1632f8d40 100644 --- a/mysql-test/t/gis-rtree.test +++ b/mysql-test/t/gis-rtree.test @@ -41,7 +41,7 @@ while ($1) let $2=10; while ($2) { - eval INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10)))); + eval INSERT INTO t2 (g) VALUES (LineString(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10))); dec $2; } dec $1; @@ -61,7 +61,7 @@ while ($1) let $2=10; while ($2) { - eval DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10))))); + eval DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10)))); SELECT count(*) FROM t2; dec $2; } @@ -235,11 +235,11 @@ DROP TABLE t1; # Bug #21888: Query on GEOMETRY field using PointFromWKB() results in lost connection # CREATE TABLE t1 (foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) ); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,1))); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,0))); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,1))); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,0))); -SELECT 1 FROM t1 WHERE foo != PointFromWKB(POINT(0,0)); +INSERT INTO t1 (foo) VALUES (POINT(1,1)); +INSERT INTO t1 (foo) VALUES (POINT(1,0)); +INSERT INTO t1 (foo) VALUES (POINT(0,1)); +INSERT INTO t1 (foo) VALUES (POINT(0,0)); +SELECT 1 FROM t1 WHERE foo != POINT(0,0); DROP TABLE t1; # @@ -802,35 +802,35 @@ DROP TABLE t1; # create table t1 (a geometry not null, spatial index(a)); -insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 131072))); -insert into t1 values (PointFromWKB(POINT(9.1248812352444e+192, 2.9740338169556e+284))); -insert into t1 values (PointFromWKB(POINT(4.7783097267365e-299, -0))); -insert into t1 values (PointFromWKB(POINT(1.49166814624e-154, 2.0880974297595e-53))); -insert into t1 values (PointFromWKB(POINT(4.0917382598702e+149, 1.2024538023802e+111))); -insert into t1 values (PointFromWKB(POINT(2.0349165139404e+236, 2.9993936277913e-241))); -insert into t1 values (PointFromWKB(POINT(2.5243548967072e-29, 1.2024538023802e+111))); -insert into t1 values (PointFromWKB(POINT(0, 6.9835074892995e-251))); -insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 3.1050361846014e+231))); -insert into t1 values (PointFromWKB(POINT(2.8728483499323e-188, 2.4600631144627e+260))); -insert into t1 values (PointFromWKB(POINT(3.0517578125e-05, 2.0349165139404e+236))); -insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 1.1818212630766e-125))); -insert into t1 values (PointFromWKB(POINT(2.481040258324e-265, 5.7766220027675e-275))); -insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 2.5243548967072e-29))); -insert into t1 values (PointFromWKB(POINT(5.7766220027675e-275, 9.9464647281957e+86))); -insert into t1 values (PointFromWKB(POINT(2.2181357552967e+130, 3.7857669957337e-270))); -insert into t1 values (PointFromWKB(POINT(4.5767114681874e-246, 3.6893488147419e+19))); -insert into t1 values (PointFromWKB(POINT(4.5767114681874e-246, 3.7537584144024e+255))); -insert into t1 values (PointFromWKB(POINT(3.7857669957337e-270, 1.8033161362863e-130))); -insert into t1 values (PointFromWKB(POINT(0, 5.8774717541114e-39))); -insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 2.2761049594727e-159))); -insert into t1 values (PointFromWKB(POINT(6.243497100632e+144, 3.7857669957337e-270))); -insert into t1 values (PointFromWKB(POINT(3.7857669957337e-270, 2.6355494858076e-82))); -insert into t1 values (PointFromWKB(POINT(2.0349165139404e+236, 3.8518598887745e-34))); -insert into t1 values (PointFromWKB(POINT(4.6566128730774e-10, 2.0880974297595e-53))); -insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 1.8827498946116e-183))); -insert into t1 values (PointFromWKB(POINT(1.8033161362863e-130, 9.1248812352444e+192))); -insert into t1 values (PointFromWKB(POINT(4.7783097267365e-299, 2.2761049594727e-159))); -insert into t1 values (PointFromWKB(POINT(1.94906280228e+289, 1.2338789709327e-178))); +insert into t1 values (POINT(1.1517219314031e+164, 131072)); +insert into t1 values (POINT(9.1248812352444e+192, 2.9740338169556e+284)); +insert into t1 values (POINT(4.7783097267365e-299, -0)); +insert into t1 values (POINT(1.49166814624e-154, 2.0880974297595e-53)); +insert into t1 values (POINT(4.0917382598702e+149, 1.2024538023802e+111)); +insert into t1 values (POINT(2.0349165139404e+236, 2.9993936277913e-241)); +insert into t1 values (POINT(2.5243548967072e-29, 1.2024538023802e+111)); +insert into t1 values (POINT(0, 6.9835074892995e-251)); +insert into t1 values (POINT(2.0880974297595e-53, 3.1050361846014e+231)); +insert into t1 values (POINT(2.8728483499323e-188, 2.4600631144627e+260)); +insert into t1 values (POINT(3.0517578125e-05, 2.0349165139404e+236)); +insert into t1 values (POINT(1.1517219314031e+164, 1.1818212630766e-125)); +insert into t1 values (POINT(2.481040258324e-265, 5.7766220027675e-275)); +insert into t1 values (POINT(2.0880974297595e-53, 2.5243548967072e-29)); +insert into t1 values (POINT(5.7766220027675e-275, 9.9464647281957e+86)); +insert into t1 values (POINT(2.2181357552967e+130, 3.7857669957337e-270)); +insert into t1 values (POINT(4.5767114681874e-246, 3.6893488147419e+19)); +insert into t1 values (POINT(4.5767114681874e-246, 3.7537584144024e+255)); +insert into t1 values (POINT(3.7857669957337e-270, 1.8033161362863e-130)); +insert into t1 values (POINT(0, 5.8774717541114e-39)); +insert into t1 values (POINT(1.1517219314031e+164, 2.2761049594727e-159)); +insert into t1 values (POINT(6.243497100632e+144, 3.7857669957337e-270)); +insert into t1 values (POINT(3.7857669957337e-270, 2.6355494858076e-82)); +insert into t1 values (POINT(2.0349165139404e+236, 3.8518598887745e-34)); +insert into t1 values (POINT(4.6566128730774e-10, 2.0880974297595e-53)); +insert into t1 values (POINT(2.0880974297595e-53, 1.8827498946116e-183)); +insert into t1 values (POINT(1.8033161362863e-130, 9.1248812352444e+192)); +insert into t1 values (POINT(4.7783097267365e-299, 2.2761049594727e-159)); +insert into t1 values (POINT(1.94906280228e+289, 1.2338789709327e-178)); drop table t1; # End of 4.1 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index cc2ac5b7392..c01fa205349 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -36,32 +36,32 @@ INSERT INTO gis_point VALUES INSERT INTO gis_line VALUES (105, LineFromText('LINESTRING(0 0,0 10,10 0)')), (106, LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')), -(107, LineStringFromWKB(LineString(Point(10, 10), Point(40, 10)))); +(107, LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10))))); INSERT INTO gis_polygon VALUES (108, PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')), (109, PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')), -(110, PolyFromWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))); +(110, PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0)))))); INSERT INTO gis_multi_point VALUES (111, MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')), (112, MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')), -(113, MPointFromWKB(MultiPoint(Point(3, 6), Point(4, 10)))); +(113, MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10))))); INSERT INTO gis_multi_line VALUES (114, MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')), (115, MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')), -(116, MLineFromWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))); +(116, MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7)))))); INSERT INTO gis_multi_polygon VALUES (117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')), (118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')), -(119, MPolyFromWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))); +(119, MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3))))))); INSERT INTO gis_geometrycollection VALUES (120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')), -(121, GeometryFromWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9))))); +(121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))); INSERT into gis_geometry SELECT * FROM gis_point; INSERT into gis_geometry SELECT * FROM gis_line; diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index d088f68fc0c..71bd1347f6e 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -70,10 +70,17 @@ String *Item_func_geometry_from_wkb::val_str(String *str) { DBUG_ASSERT(fixed == 1); String arg_val; - String *wkb= args[0]->val_str(&arg_val); + String *wkb; Geometry_buffer buffer; uint32 srid= 0; + if (args[0]->field_type() == MYSQL_TYPE_GEOMETRY) + { + return args[0]->val_str(str); + } + + wkb= args[0]->val_str(&arg_val); + if ((arg_count == 2) && !args[1]->null_value) srid= (uint32)args[1]->val_int(); @@ -83,8 +90,8 @@ String *Item_func_geometry_from_wkb::val_str(String *str) str->length(0); str->q_append(srid); if ((null_value= - (args[0]->null_value || - !Geometry::create_from_wkb(&buffer, wkb->ptr(), wkb->length(), str)))) + (args[0]->null_value || + !Geometry::create_from_wkb(&buffer, wkb->ptr(), wkb->length(), str)))) return 0; return str; } @@ -337,14 +344,16 @@ String *Item_func_point::val_str(String *str) DBUG_ASSERT(fixed == 1); double x= args[0]->val_real(); double y= args[1]->val_real(); + uint32 srid= 0; if ((null_value= (args[0]->null_value || args[1]->null_value || - str->realloc(1 + 4 + SIZEOF_STORED_DOUBLE*2)))) + str->realloc(4/*SRID*/ + 1 + 4 + SIZEOF_STORED_DOUBLE*2)))) return 0; str->set_charset(&my_charset_bin); str->length(0); + str->q_append(srid); str->q_append((char)Geometry::wkb_ndr); str->q_append((uint32)Geometry::wkb_point); str->q_append(x); @@ -368,12 +377,14 @@ String *Item_func_spatial_collection::val_str(String *str) DBUG_ASSERT(fixed == 1); String arg_value; uint i; + uint32 srid= 0; str->set_charset(&my_charset_bin); str->length(0); - if (str->reserve(1 + 4 + 4, 512)) + if (str->reserve(4/*SRID*/ + 1 + 4 + 4, 512)) goto err; + str->q_append(srid); str->q_append((char) Geometry::wkb_ndr); str->q_append((uint32) coll_type); str->q_append((uint32) arg_count); @@ -391,13 +402,13 @@ String *Item_func_spatial_collection::val_str(String *str) In the case of GeometryCollection we don't need any checkings for item types, so just copy them into target collection */ - if (str->append(res->ptr(), len, (uint32) 512)) + if (str->append(res->ptr() + 4/*SRID*/, len - 4/*SRID*/, (uint32) 512)) goto err; } else { enum Geometry::wkbType wkb_type; - const char *data= res->ptr() + 1; + const char *data= res->ptr() + 4/*SRID*/ + 1; /* In the case of named collection we must check that items @@ -406,7 +417,7 @@ String *Item_func_spatial_collection::val_str(String *str) wkb_type= (Geometry::wkbType) uint4korr(data); data+= 4; - len-= 5; + len-= 5 + 4/*SRID*/; if (wkb_type != item_type) goto err; From e02d162f792c1df93c19b584bfc5f098fbbbfb5e Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Tue, 28 Apr 2009 14:46:07 +0300 Subject: [PATCH 70/85] Bug #38694 Race condition in replication thread shutdown The issue of the current bug is unguarded access to mi->slave_running by the shutdown thread calling end_slave() that is bug#29968 (alas happened not to be cross-linked with the current bug) Fixed: with removing the unguarded read of the running status and perform reading it in terminate_slave_thread() at time run_lock is taken (mostly bug#29968 backporting, still with some improvements over that patch - see the error reporting from terminate_slave_thread()). Issue of bug#38716 is fixed here for 5.0 branch as well. Note: There has been a separate artifact identified - a race condition between init_slave() and end_slave() - reported as Bug#44467. --- mysql-test/r/rpl_bug38694.result | 6 ++ mysql-test/t/rpl_bug38694-slave.opt | 1 + mysql-test/t/rpl_bug38694.test | 10 +++ sql/slave.cc | 105 +++++++++++++++++++++------- sql/slave.h | 4 -- 5 files changed, 96 insertions(+), 30 deletions(-) create mode 100644 mysql-test/r/rpl_bug38694.result create mode 100644 mysql-test/t/rpl_bug38694-slave.opt create mode 100644 mysql-test/t/rpl_bug38694.test diff --git a/mysql-test/r/rpl_bug38694.result b/mysql-test/r/rpl_bug38694.result new file mode 100644 index 00000000000..711c4a91c03 --- /dev/null +++ b/mysql-test/r/rpl_bug38694.result @@ -0,0 +1,6 @@ +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; diff --git a/mysql-test/t/rpl_bug38694-slave.opt b/mysql-test/t/rpl_bug38694-slave.opt new file mode 100644 index 00000000000..d96e981b198 --- /dev/null +++ b/mysql-test/t/rpl_bug38694-slave.opt @@ -0,0 +1 @@ +--loose-debug=d,simulate_slave_delay_at_terminate_bug38694 diff --git a/mysql-test/t/rpl_bug38694.test b/mysql-test/t/rpl_bug38694.test new file mode 100644 index 00000000000..41b11d271b9 --- /dev/null +++ b/mysql-test/t/rpl_bug38694.test @@ -0,0 +1,10 @@ +# Testing replication threads stopping concurrency issue +# at the server shutdown +# Related bugs: bug#38694, bug#29968, bug#25306 +# The test checks if a delay at the termination phase of slave threads +# DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5);); +# could cause any issue. + +source include/master-slave.inc; + +# End of tests diff --git a/sql/slave.cc b/sql/slave.cc index cc82710dec7..f9ae7eb92b6 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -78,6 +78,11 @@ static int request_table_dump(MYSQL* mysql, const char* db, const char* table); static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, const char* table_name, bool overwrite); static int get_master_version_and_clock(MYSQL* mysql, MASTER_INFO* mi); +static int terminate_slave_thread(THD *thd, + pthread_mutex_t *term_lock, + pthread_cond_t *term_cond, + volatile uint *slave_running, + bool skip_lock); /* Find out which replications threads are running @@ -637,55 +642,96 @@ int terminate_slave_threads(MASTER_INFO* mi,int thread_mask,bool skip_lock) return 0; /* successfully do nothing */ int error,force_all = (thread_mask & SLAVE_FORCE_ALL); pthread_mutex_t *sql_lock = &mi->rli.run_lock, *io_lock = &mi->run_lock; - pthread_mutex_t *sql_cond_lock,*io_cond_lock; DBUG_ENTER("terminate_slave_threads"); - sql_cond_lock=sql_lock; - io_cond_lock=io_lock; - - if (skip_lock) - { - sql_lock = io_lock = 0; - } - if ((thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL)) && mi->slave_running) + if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL)) { DBUG_PRINT("info",("Terminating IO thread")); mi->abort_slave=1; - if ((error=terminate_slave_thread(mi->io_thd,io_lock, - io_cond_lock, + if ((error=terminate_slave_thread(mi->io_thd, io_lock, &mi->stop_cond, - &mi->slave_running)) && + &mi->slave_running, + skip_lock)) && !force_all) DBUG_RETURN(error); } - if ((thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL)) && mi->rli.slave_running) + if (thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL)) { DBUG_PRINT("info",("Terminating SQL thread")); - DBUG_ASSERT(mi->rli.sql_thd != 0) ; mi->rli.abort_slave=1; - if ((error=terminate_slave_thread(mi->rli.sql_thd,sql_lock, - sql_cond_lock, + if ((error=terminate_slave_thread(mi->rli.sql_thd, sql_lock, &mi->rli.stop_cond, - &mi->rli.slave_running)) && + &mi->rli.slave_running, + skip_lock)) && !force_all) DBUG_RETURN(error); } DBUG_RETURN(0); } +/** + Wait for a slave thread to terminate. -int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock, - pthread_mutex_t *cond_lock, - pthread_cond_t* term_cond, - volatile uint *slave_running) + This function is called after requesting the thread to terminate + (by setting abort_slave member of Relay_log_info or + Master_info structure to 1). Termination of the thread is + controlled with the the predicate *slave_running. + + Function will acquire term_lock before waiting on the condition + unless skip_lock is true in which case the mutex should be owned + by the caller of this function and will remain acquired after + return from the function. + + term_lock + Associated lock to use when waiting for term_cond + + term_cond + Condition that is signalled when the thread has terminated + + slave_running + Pointer to predicate to check for slave thread termination + + skip_lock + If true the lock will not be acquired before waiting on + the condition. In this case, it is assumed that the calling + function acquires the lock before calling this function. + + + returns zero if success, ER_SLAVE_NOT_RUNNING otherwise. + + NOTE: + If the executing thread has to acquire term_lock (skip_lock is false), + the negative running status does not represent any issue therefore no error is reported. +*/ + +int terminate_slave_thread(THD* thd, + pthread_mutex_t *term_lock, + pthread_cond_t *term_cond, + volatile uint *slave_running, + bool skip_lock) { DBUG_ENTER("terminate_slave_thread"); - if (term_lock) + if (!skip_lock) { pthread_mutex_lock(term_lock); - if (!*slave_running) + } + else + { + safe_mutex_assert_owner(term_lock); + } + if (!*slave_running) + { + if (!skip_lock) { + /* + if run_lock (term_lock) is acquired locally then either + slave_running status is fine + */ pthread_mutex_unlock(term_lock); + DBUG_RETURN(0); + } + else + { DBUG_RETURN(ER_SLAVE_NOT_RUNNING); } } @@ -698,6 +744,7 @@ int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock, while (*slave_running) // Should always be true { + int error; DBUG_PRINT("loop", ("killing slave thread")); pthread_mutex_lock(&thd->LOCK_delete); @@ -719,9 +766,13 @@ int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock, */ struct timespec abstime; set_timespec(abstime,2); - pthread_cond_timedwait(term_cond, cond_lock, &abstime); + error= pthread_cond_timedwait(term_cond, term_lock, &abstime); + DBUG_ASSERT(error == ETIMEDOUT || error == 0); } - if (term_lock) + + DBUG_ASSERT(*slave_running == 0); + + if (!skip_lock) pthread_mutex_unlock(term_lock); DBUG_RETURN(0); } @@ -834,7 +885,7 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start, &mi->rli.slave_running, &mi->rli.slave_run_id, mi, 0); if (error) - terminate_slave_threads(mi, thread_mask & SLAVE_IO, 0); + terminate_slave_threads(mi, thread_mask & SLAVE_IO, !need_slave_mutex); } DBUG_RETURN(error); } @@ -3855,6 +3906,7 @@ err: delete the mi structure leading to a crash! (see BUG#25306 for details) */ pthread_cond_broadcast(&mi->stop_cond); // tell the world we are done + DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5);); pthread_mutex_unlock(&mi->run_lock); #ifndef DBUG_OFF if (abort_slave_event_count && !events_till_abort) @@ -4103,6 +4155,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ */ const int eta= rli->events_till_abort; #endif + DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5);); pthread_mutex_unlock(&rli->run_lock); // tell the world we are done #ifndef DBUG_OFF // TODO: reconsider the code below diff --git a/sql/slave.h b/sql/slave.h index da548e145d3..5ae596f1eb5 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -504,10 +504,6 @@ bool flush_relay_log_info(RELAY_LOG_INFO* rli); int register_slave_on_master(MYSQL* mysql); int terminate_slave_threads(MASTER_INFO* mi, int thread_mask, bool skip_lock = 0); -int terminate_slave_thread(THD* thd, pthread_mutex_t* term_mutex, - pthread_mutex_t* cond_lock, - pthread_cond_t* term_cond, - volatile uint* slave_running); int start_slave_threads(bool need_slave_mutex, bool wait_for_start, MASTER_INFO* mi, const char* master_info_fname, const char* slave_info_fname, int thread_mask); From 7f119d203fca994cc8d4813d4f4f7332774e749a Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Tue, 28 Apr 2009 18:16:17 +0200 Subject: [PATCH 71/85] Bug#35769 typo in mysqlhotcopy documentation Fixed a number of typos, and made punctuation and capitalization more consistent in documentation and help. --- scripts/mysqlhotcopy.sh | 60 ++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index 4819f512a65..21fca0c0848 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -49,11 +49,11 @@ $0 Ver $VERSION Usage: $0 db_name[./table_regex/] [new_db_name | directory] - -?, --help display this helpscreen and exit + -?, --help display this help-screen and exit -u, --user=# user for database login if not current user -p, --password=# password to use when connecting to server (if not set in my.cnf, which is recommended) - -h, --host=# Hostname for local server when connecting over TCP/IP + -h, --host=# hostname for local server when connecting over TCP/IP -P, --port=# port to use when connecting to local server with TCP/IP -S, --socket=# socket to use when connecting to local server @@ -86,7 +86,7 @@ sub usage { # Do not initialize user or password options; that way, any user/password # options specified in option files will be used. If no values are specified -# all, the defaults will be used (login name, no password). +# at all, the defaults will be used (login name, no password). my %opt = ( noindices => 0, @@ -95,7 +95,7 @@ my %opt = ( method => "cp", flushlog => 0, ); -Getopt::Long::Configure(qw(no_ignore_case)); # disambuguate -p and -P +Getopt::Long::Configure(qw(no_ignore_case)); # disambiguate -p and -P GetOptions( \%opt, "help", "host|h=s", @@ -453,7 +453,7 @@ else { printf "Locked $num_tables tables in %d seconds.\n", time-$start unless $opt{quiet}; $hc_started = time; # count from time lock is granted - # flush tables to make on-disk copy uptodate + # flush tables to make on-disk copy up to date $start = time; $dbh->do("FLUSH TABLES /*!32323 $hc_tables */"); printf "Flushed tables ($hc_tables) in %d seconds.\n", time-$start unless $opt{quiet}; @@ -895,7 +895,7 @@ tables and you don't want to have all the tables locked for the whole duration. In this situation, I you are happy for groups of tables to be -backed up separately (and thus possibly not be logically consistant +backed up separately (and thus possibly not be logically consistent with one another) then you can run mysqlhotcopy several times on the same database each with different db_name./table_regex/. All but the first should use the --addtodest option so the tables @@ -920,7 +920,7 @@ server in a mutual replication setup. =item --regexp pattern -Copy all databases with names matching the pattern +Copy all databases with names matching the pattern. =item --regexp /pattern1/./pattern2/ @@ -933,7 +933,7 @@ names begin with 'bar' from all databases which names end with 'foo': =item db_name./pattern/ Copy only tables matching pattern. Shell metacharacters ( (, ), |, !, -etc.) have to be escaped (e.g. \). For example, to select all tables +etc.) have to be escaped (e.g., \). For example, to select all tables in database db1 whose names begin with 'foo' or 'bar': mysqlhotcopy --indices --method=cp db1./^\(foo\|bar\)/ @@ -947,19 +947,19 @@ that do not begin with foo nor bar: =item -?, --help -Display helpscreen and exit +Display help-screen and exit. =item -u, --user=# -user for database login if not current user +User for database login if not current user. =item -p, --password=# -password to use when connecting to the server. Note that you are strongly +Password to use when connecting to the server. Note that you are strongly encouraged *not* to use this option as every user would be able to see the password in the process list. Instead use the '[mysqlhotcopy]' section in one of the config files, normally /etc/my.cnf or your personal ~/.my.cnf. -(See the chapter 'my.cnf Option Files' in the manual) +(See the chapter 'my.cnf Option Files' in the manual.) =item -h, -h, --host=# @@ -968,12 +968,12 @@ different from 'localhost' will trigger mysqlhotcopy to use TCP/IP connection. =item -P, --port=# -port to use when connecting to MySQL server with TCP/IP. This is only used +Port to use when connecting to MySQL server with TCP/IP. This is only used when using the --host option. =item -S, --socket=# -UNIX domain socket to use when connecting to local server +UNIX domain socket to use when connecting to local server. =item --noindices @@ -983,7 +983,7 @@ on the backup. =item --method=# -method for copy (only "cp" currently supported). Alpha support for +Method for copy (only "cp" currently supported). Alpha support for "scp" was added in November 2000. Your experience with the scp method will vary with your ability to understand how scp works. 'man scp' and 'man ssh' are your friends. @@ -1000,15 +1000,15 @@ scp or rsync the files at your leisure. =item -q, --quiet -be silent except for errors +Be silent except for errors. =item --debug -Debug messages are displayed +Debug messages are displayed. =item -n, --dryrun -Display commands without actually doing them +Display commands without actually doing them. =back @@ -1030,18 +1030,18 @@ to be specified on the command line: mysqlhotcopy db newdb t1 t2 /^foo_/ : t3 /^bar_/ : + where ":" delimits the subsets, the /^foo_/ indicates all tables -with names begining with "foo_" and the "+" indicates all tables +with names beginning with "foo_" and the "+" indicates all tables not copied by the previous subsets. -newdb is either another not existing database or a full path to a directory -where we can create a directory 'db' +'newdb' is either the name of the new database, or the full path name +of the new database file. The database should not already exist. Add option to lock each table in turn for people who don\'t need cross-table integrity. Add option to FLUSH STATUS just before UNLOCK TABLES. -Add support for other copy methods (eg tar to single file?). +Add support for other copy methods (e.g., tar to single file?). Add support for forthcoming MySQL ``RAID'' table subdirectory layouts. @@ -1049,26 +1049,26 @@ Add support for forthcoming MySQL ``RAID'' table subdirectory layouts. Tim Bunce -Martin Waite - added checkpoint, flushlog, regexp and dryrun options +Martin Waite - Added checkpoint, flushlog, regexp and dryrun options. Fixed cleanup of targets when hotcopy fails. - Added --record_log_pos. + Added --record_log_pos. RAID tables are now copied (don't know if this works over scp). -Ralph Corderoy - added synonyms for commands +Ralph Corderoy - Added synonyms for commands. -Scott Wiersdorf - added table regex and scp support +Scott Wiersdorf - Added table regex and scp support. -Monty - working --noindex (copy only first 2048 bytes of index file) - Fixes for --method=scp +Monty - Working --noindex (copy only first 2048 bytes of index file). + Fixes for --method=scp. Ask Bjoern Hansen - Cleanup code to fix a few bugs and enable -w again. Emil S. Hansen - Added resetslave and resetmaster. -Jeremy D. Zawodny - Removed depricated DBI calls. Fixed bug which +Jeremy D. Zawodny - Removed deprecated DBI calls. Fixed bug which resulted in nothing being copied when a regexp was specified but no database name(s). Martin Waite - Fix to handle database name that contains space. -Paul DuBois - Remove end '/' from directory names +Paul DuBois - Remove end '/' from directory names. From 386ceb4916dac1585f6ac304e47f73ce3594dee2 Mon Sep 17 00:00:00 2001 From: Matthias Leich Date: Tue, 28 Apr 2009 20:12:18 +0200 Subject: [PATCH 72/85] Fix for Bug#43546 Several 5.0 tests do not pass MTR's --check option (moved from Bug 42308) Details: - insert_update Add DROP TABLE which was missing, error numbers -> names - varbinary Add DROP TABLE which was missing - sp_trans_log Add missing DROP function, improved formatting --- mysql-test/r/insert_update.result | 1 + mysql-test/r/sp_trans_log.result | 5 ++++- mysql-test/r/varbinary.result | 1 + mysql-test/t/insert_update.test | 19 ++++++++++--------- mysql-test/t/sp_trans_log.test | 19 ++++++++++++++----- mysql-test/t/varbinary.test | 1 + 6 files changed, 31 insertions(+), 15 deletions(-) diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result index 20cde86101e..b648531b455 100644 --- a/mysql-test/r/insert_update.result +++ b/mysql-test/r/insert_update.result @@ -393,6 +393,7 @@ id c1 cnt 1 0 3 2 2 1 DROP TABLE t1; +DROP TABLE t2; create table t1(f1 int primary key, f2 timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP); insert into t1(f1) values(1); diff --git a/mysql-test/r/sp_trans_log.result b/mysql-test/r/sp_trans_log.result index eb0770cb0a1..cce5a28fa2e 100644 --- a/mysql-test/r/sp_trans_log.result +++ b/mysql-test/r/sp_trans_log.result @@ -1,3 +1,5 @@ +drop function if exists bug23333| +drop table if exists t1,t2| CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM| CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB| insert into t2 values (1,1)| @@ -20,4 +22,5 @@ master-bin.000001 # Query 1 # # select count(*),@a from t1 /* must be 1,1 */| count(*) @a 1 1 -drop table t1, t2| +drop table t1,t2; +drop function if exists bug23333; diff --git a/mysql-test/r/varbinary.result b/mysql-test/r/varbinary.result index f584c22f98a..01af6979ca3 100644 --- a/mysql-test/r/varbinary.result +++ b/mysql-test/r/varbinary.result @@ -78,6 +78,7 @@ alter table t1 modify a varchar(255); select length(a) from t1; length(a) 6 +drop table t1; select 0b01000001; 0b01000001 A diff --git a/mysql-test/t/insert_update.test b/mysql-test/t/insert_update.test index 67108744ec6..de38ae0b0d3 100644 --- a/mysql-test/t/insert_update.test +++ b/mysql-test/t/insert_update.test @@ -12,7 +12,7 @@ INSERT t1 VALUES (8,4,50) ON DUPLICATE KEY UPDATE c=c+1000; SELECT * FROM t1; INSERT t1 VALUES (1,4,60) ON DUPLICATE KEY UPDATE c=c+10000; SELECT * FROM t1; --- error 1062 +-- error ER_DUP_ENTRY INSERT t1 VALUES (1,9,70) ON DUPLICATE KEY UPDATE c=c+100000, b=4; SELECT * FROM t1; TRUNCATE TABLE t1; @@ -63,7 +63,7 @@ INSERT t1 SELECT 8,4,50 FROM DUAL ON DUPLICATE KEY UPDATE c=c+1000; SELECT * FROM t1; INSERT t1 SELECT 1,4,60 FROM DUAL ON DUPLICATE KEY UPDATE c=c+10000; SELECT * FROM t1; --- error 1062 +-- error ER_DUP_ENTRY INSERT t1 SELECT 1,9,70 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100000, b=4; SELECT * FROM t1; TRUNCATE TABLE t1; @@ -76,7 +76,7 @@ INSERT t1 SELECT a,b,c FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=t1.c+100; SELECT * FROM t1; INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0; SELECT * FROM t1; ---error 1052 +--error ER_NON_UNIQ_ERROR INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a); INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=t1.c+VALUES(t1.a); SELECT *, VALUES(a) FROM t1; @@ -95,9 +95,9 @@ insert ignore into t1 select a from t1 as t2 on duplicate key update a=t1.a+1 ; select * from t1; insert into t1 select 1 on duplicate key update a=2; select * from t1; ---error 1052 +--error ER_NON_UNIQ_ERROR insert into t1 select a from t1 on duplicate key update a=a+1 ; ---error 1052 +--error ER_NON_UNIQ_ERROR insert ignore into t1 select a from t1 on duplicate key update a=t1.a+1 ; drop table t1; @@ -171,13 +171,13 @@ SET SQL_MODE = 'TRADITIONAL'; CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL); ---error 1364 +--error ER_NO_DEFAULT_FOR_FIELD INSERT INTO t1 (a) VALUES (1); ---error 1364 +--error ER_NO_DEFAULT_FOR_FIELD INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE a = b; ---error 1364 +--error ER_NO_DEFAULT_FOR_FIELD INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE b = b; SELECT * FROM t1; @@ -278,7 +278,7 @@ INSERT INTO t1 (id,c1) VALUES (1,10); SELECT * FROM t1; CREATE TABLE t2 (id INT, c1 INT); INSERT INTO t2 VALUES (1,NULL), (2,2); ---error 1048 +--error ER_BAD_NULL_ERROR INSERT INTO t1 (id,c1) SELECT 1,NULL ON DUPLICATE KEY UPDATE c1=NULL; SELECT * FROM t1; @@ -290,6 +290,7 @@ INSERT IGNORE INTO t1 (id,c1) SELECT * FROM t2 SELECT * FROM t1; DROP TABLE t1; +DROP TABLE t2; # # Bug#28904: INSERT .. ON DUPLICATE was silently updating rows when it diff --git a/mysql-test/t/sp_trans_log.test b/mysql-test/t/sp_trans_log.test index 93605722f6b..effa3ca80cf 100644 --- a/mysql-test/t/sp_trans_log.test +++ b/mysql-test/t/sp_trans_log.test @@ -4,11 +4,15 @@ delimiter |; # -# Bug #13270 INSERT,UPDATE,etc that calls func with side-effect does not binlog -# Bug #23333 stored function + non-transac table + transac table = -# breaks stmt-based binlog -# Bug #27395 OPTION_STATUS_NO_TRANS_UPDATE is not preserved at the end of SF() +# Bug#13270 INSERT,UPDATE,etc that calls func with side-effect does not binlog +# Bug#23333 stored function + non-transac table + transac table = +# breaks stmt-based binlog +# Bug#27395 OPTION_STATUS_NO_TRANS_UPDATE is not preserved at the end of SF() # +--disable_warnings +drop function if exists bug23333| +drop table if exists t1,t2| +--enable_warnings CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM| CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB| @@ -29,5 +33,10 @@ insert into t2 values (bug23333(),1)| --replace_column 2 # 5 # 6 # show binlog events from 98 /* with fixes for #23333 will show there are 2 queries */| select count(*),@a from t1 /* must be 1,1 */| -drop table t1, t2| +delimiter ;| + +# clean-up + +drop table t1,t2; +drop function if exists bug23333; diff --git a/mysql-test/t/varbinary.test b/mysql-test/t/varbinary.test index 427c1a6b84a..a53a3b8d5b4 100644 --- a/mysql-test/t/varbinary.test +++ b/mysql-test/t/varbinary.test @@ -83,6 +83,7 @@ insert into t1 values("aaa "); select length(a) from t1; alter table t1 modify a varchar(255); select length(a) from t1; +drop table t1; # # Bug#35658 (An empty binary value leads to mysqld crash) From f51e62cfa31f6bcdd7ddadfe197ddd7012d3732b Mon Sep 17 00:00:00 2001 From: Narayanan V Date: Wed, 29 Apr 2009 16:51:14 +0530 Subject: [PATCH 73/85] Bug#44337 Select query using index merge fails with MCH3601 The storage engine was not correctly handling the case in which rnd_pos is executed for a handler without a preceding rnd_next or index read operation. As a result, an unitialized file handle was sometimes being passed to the QMY_READ API. The fix clears the rrnAssocHandle at the beginning of each read operation and then checks to see whether it has been set to a valid handle value before attempting to use it in rnd_pos. If rrnAssocHandle has not been set by a previous read operation, rnd_pos instead falls back to the use of the currently active handle. --- storage/ibmdb2i/ha_ibmdb2i.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/storage/ibmdb2i/ha_ibmdb2i.cc b/storage/ibmdb2i/ha_ibmdb2i.cc index ad80a80fc97..46c84de4aee 100644 --- a/storage/ibmdb2i/ha_ibmdb2i.cc +++ b/storage/ibmdb2i/ha_ibmdb2i.cc @@ -898,6 +898,8 @@ int ha_ibmdb2i::index_init(uint idx, bool sorted) releaseIndexFile(idx); } + rrnAssocHandle= 0; + DBUG_RETURN(rc); } @@ -1154,6 +1156,8 @@ int ha_ibmdb2i::rnd_init(bool scan) releaseDataFile(); } + rrnAssocHandle= 0; + DBUG_RETURN(0); // MySQL sometimes does not check the return code, causing // an assert in ha_rnd_end later on if we return a non-zero // value here. @@ -1251,7 +1255,8 @@ int ha_ibmdb2i::rnd_pos(uchar * buf, uchar *pos) int rc = 0; - if (activeHandle != rrnAssocHandle) + if (rrnAssocHandle && + (activeHandle != rrnAssocHandle)) { if (activeHandle) releaseActiveHandle(); rc = useFileByHandle(QMY_UPDATABLE, rrnAssocHandle); From 57b4295d2b7693dc15e047b6a5d0f6b86b612fa2 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 29 Apr 2009 13:51:10 +0200 Subject: [PATCH 74/85] Bug#43932 myisam index corruption with large index and large key_buffer_size. The cause of corruption was number overflow when multiplying two ulong values, number of used keycache blocks with size of a single block. The result of multiplication exceeded ulong range (4G) and this lead to incorrectly calculated buffer offset in the key cache. The fix is to use size_t for multiplication result. This patch also fixes pointless cast in safemalloc (size of allocated block to uint), that creates lot of false alarm warnings when using big keycache (> 4GB) in debug mode. --- mysys/mf_keycache.c | 6 ++++-- mysys/safemalloc.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 397a3332740..16bcb11eb91 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -2044,13 +2044,15 @@ restart: } else { + size_t block_mem_offset; /* There are some never used blocks, take first of them */ DBUG_ASSERT(keycache->blocks_used < (ulong) keycache->disk_blocks); block= &keycache->block_root[keycache->blocks_used]; + block_mem_offset= + ((size_t) keycache->blocks_used) * keycache->key_cache_block_size; block->buffer= ADD_TO_PTR(keycache->block_mem, - ((ulong) keycache->blocks_used* - keycache->key_cache_block_size), + block_mem_offset, uchar*); keycache->blocks_used++; DBUG_ASSERT(!block->next_used); diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 36d07b475e9..c484f1d4c54 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -174,7 +174,7 @@ void *_mymalloc(size_t size, const char *filename, uint lineno, myf MyFlags) data[size + 3]= MAGICEND3; irem->filename= (char *) filename; irem->linenum= lineno; - irem->datasize= (uint32) size; + irem->datasize= size; irem->prev= NULL; /* Add this remember structure to the linked list */ From 7d24441119b3887e2373762254acb28e7aeef84f Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Wed, 29 Apr 2009 14:00:34 +0200 Subject: [PATCH 75/85] Bug#43737: Select query return bad result A bug in the initialization of key segment information made it point to the wrong bit, since a bit index was used when its int value was needed. This lead to misinterpretation of bit columns read from MyISAM record format when a NULL bit pushed them over a byte boundary. Fixed by using the int value of the bit instead. --- mysql-test/r/myisam.result | 26 ++++++++++++++++++++++++++ mysql-test/t/myisam.test | 25 +++++++++++++++++++++++++ storage/myisam/mi_open.c | 3 ++- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 6f26135ce45..732b1b260f8 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -2226,4 +2226,30 @@ Key Start Len Index Type 1 2 30 multip. varchar 2 33 30 multip. char NULL DROP TABLE t1; +CREATE TABLE t1 ( +c INT, +d bit(1), +e INT, +f VARCHAR(1), +g BIT(1), +h BIT(1), +KEY (h, d, e, g) +); +INSERT INTO t1 VALUES +( 3, 1, 1, 'a', 0, 0 ), +( 3, 1, 5, 'a', 0, 0 ), +( 10, 1, 2, 'a', 0, 1 ), +( 10, 1, 3, 'a', 0, 1 ), +( 10, 1, 4, 'a', 0, 1 ); +SELECT f FROM t1 WHERE d = 1 AND e = 2 AND g = 0 AND h = 1; +f +a +SELECT h+0, d + 0, e, g + 0 FROM t1; +h+0 d + 0 e g + 0 +0 1 1 0 +0 1 5 0 +1 1 2 0 +1 1 3 0 +1 1 4 0 +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 6d7e03b1c28..ba6bc05cfea 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1478,5 +1478,30 @@ let $MYSQLD_DATADIR= `select @@datadir`; --exec $MYISAMCHK -d $MYSQLD_DATADIR/test/t1 DROP TABLE t1; +# +# Bug#43737: Select query return bad result +# +CREATE TABLE t1 ( + c INT, + d bit(1), + e INT, + f VARCHAR(1), + g BIT(1), + h BIT(1), + KEY (h, d, e, g) +); +INSERT INTO t1 VALUES + ( 3, 1, 1, 'a', 0, 0 ), + ( 3, 1, 5, 'a', 0, 0 ), + ( 10, 1, 2, 'a', 0, 1 ), + ( 10, 1, 3, 'a', 0, 1 ), + ( 10, 1, 4, 'a', 0, 1 ); + +SELECT f FROM t1 WHERE d = 1 AND e = 2 AND g = 0 AND h = 1; + +SELECT h+0, d + 0, e, g + 0 FROM t1; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index 78749d50fe5..328cde20923 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -1160,7 +1160,8 @@ uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg) keyseg->null_pos = mi_uint4korr(ptr); ptr +=4; keyseg->charset=0; /* Will be filled in later */ if (keyseg->null_bit) - keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == 7)); + /* We adjust bit_pos if null_bit is last in the byte */ + keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == (1 << 7))); else { keyseg->bit_pos= (uint16)keyseg->null_pos; From d7ad0a04d16f1da063c5cad84dad4a6911219a20 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Thu, 30 Apr 2009 12:52:27 +0500 Subject: [PATCH 76/85] mysql_client_test fixed. per-file comments: tests/mysql_client_test.c the test for bug 37956 isn't relevant anymore. The query there 'select point(?,?)' doesn't produce an error. --- tests/mysql_client_test.c | 58 --------------------------------------- 1 file changed, 58 deletions(-) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index d006a557819..9e026a27b6d 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -15904,61 +15904,6 @@ static void test_bug28934() } -#ifdef HAVE_SPATIAL -/** - Bug#37956 memory leak and / or crash with geometry and prepared statements! -*/ - -static void test_bug37956(void) -{ - const char *query="select point(?,?)"; - MYSQL_STMT *stmt=NULL; - ulong val=0; - MYSQL_BIND bind_param[2]; - unsigned char buff[2]= { 134, 211 }; - DBUG_ENTER("test_bug37956"); - myheader("test_bug37956"); - - stmt= mysql_simple_prepare(mysql, query); - check_stmt(stmt); - - val=1; - mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void *)&val); - val=CURSOR_TYPE_READ_ONLY; - mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void *)&val); - val=0; - mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS, (void *)&val); - - memset(bind_param, 0, sizeof(bind_param)); - bind_param[0].buffer_type=MYSQL_TYPE_TINY; - bind_param[0].buffer= (void *)buff; - bind_param[0].is_null=NULL; - bind_param[0].error=NULL; - bind_param[0].is_unsigned=1; - bind_param[1].buffer_type=MYSQL_TYPE_TINY; - bind_param[1].buffer= (void *)(buff+1); - bind_param[1].is_null=NULL; - bind_param[1].error=NULL; - bind_param[1].is_unsigned=1; - - if (mysql_stmt_bind_param(stmt, bind_param)) - { - mysql_stmt_close(stmt); - DIE_UNLESS(0); - } - - if (mysql_stmt_execute(stmt)) - { - mysql_stmt_close(stmt); - DBUG_VOID_RETURN; - } - /* Should never reach here: execution returns an error. */ - mysql_stmt_close(stmt); - DIE_UNLESS(0); - DBUG_VOID_RETURN; -} -#endif - /* Bug#27592 (stack overrun when storing datetime value using prepared statements) */ @@ -16945,9 +16890,6 @@ static struct my_tests_st my_tests[]= { { "test_bug32265", test_bug32265 }, { "test_bug38486", test_bug38486 }, { "test_bug40365", test_bug40365 }, -#ifdef HAVE_SPATIAL - { "test_bug37956", test_bug37956 }, -#endif #ifdef HAVE_QUERY_CACHE { "test_bug36326", test_bug36326 }, #endif From 430406a68fc261cfc72806b20b2a26a8bdb67c42 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 30 Apr 2009 14:37:29 +0500 Subject: [PATCH 77/85] Bug#43962 "Packets out of order" calling a SHOW TABLE STATUS Error happens because sp_head::MULTI_RESULTS is not set for SP which has 'show table status' command. The fix is to add a SQLCOM_SHOW_TABLE_STATUS case into sp_get_flags_for_command() func. --- mysql-test/r/sp.result | 15 +++++++++++++++ mysql-test/t/sp.test | 27 +++++++++++++++++++++++++++ sql/sp_head.cc | 1 + 3 files changed, 43 insertions(+) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 772cedac751..9574841bc35 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6994,6 +6994,21 @@ select name from mysql.proc where name = 'p' and sql_mode = @full_mode; name p drop procedure p; +CREATE DEFINER = 'root'@'localhost' PROCEDURE p1() +NOT DETERMINISTIC +CONTAINS SQL +SQL SECURITY DEFINER +COMMENT '' +BEGIN +SHOW TABLE STATUS like 't1'; +END;// +CREATE TABLE t1 (f1 INT); +CALL p1(); +CALL p1(); +CALL p1(); +CALL p1(); +DROP PROCEDURE p1; +DROP TABLE t1; # ------------------------------------------------------------------ # -- End of 5.1 tests # ------------------------------------------------------------------ diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index b71a9653b7d..fdf6ed8f382 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -8270,6 +8270,33 @@ select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mo select name from mysql.proc where name = 'p' and sql_mode = @full_mode; drop procedure p; +# +# Bug#43962 "Packets out of order" calling a SHOW TABLE STATUS +# +DELIMITER //; +CREATE DEFINER = 'root'@'localhost' PROCEDURE p1() +NOT DETERMINISTIC +CONTAINS SQL +SQL SECURITY DEFINER +COMMENT '' +BEGIN + SHOW TABLE STATUS like 't1'; +END;// +DELIMITER ;// + + +CREATE TABLE t1 (f1 INT); +--disable_result_log +let $tab_count= 4; +while ($tab_count) +{ + EVAL CALL p1(); + dec $tab_count ; +} +--enable_result_log +DROP PROCEDURE p1; +DROP TABLE t1; + --echo # ------------------------------------------------------------------ --echo # -- End of 5.1 tests --echo # ------------------------------------------------------------------ diff --git a/sql/sp_head.cc b/sql/sp_head.cc index b50247e2e5a..1dba8a45926 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -207,6 +207,7 @@ sp_get_flags_for_command(LEX *lex) case SQLCOM_SHOW_STATUS_PROC: case SQLCOM_SHOW_STORAGE_ENGINES: case SQLCOM_SHOW_TABLES: + case SQLCOM_SHOW_TABLE_STATUS: case SQLCOM_SHOW_VARIABLES: case SQLCOM_SHOW_WARNS: case SQLCOM_REPAIR: From 49e3fe95fea51b7b395ad1b95c51f62dbf39ade8 Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 30 Apr 2009 16:33:44 +0530 Subject: [PATCH 78/85] Addition to the fix for BUG#40827 - Killing insert-select to MyISAM can cause table corruption Moved the testcase from the file myisam.test to the new testfile mysiam_debug.test --- mysql-test/r/myisam.result | 39 ----------------------- mysql-test/r/myisam_debug.result | 39 +++++++++++++++++++++++ mysql-test/t/myisam.test | 52 ------------------------------ mysql-test/t/myisam_debug.test | 54 ++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 91 deletions(-) create mode 100644 mysql-test/r/myisam_debug.result create mode 100644 mysql-test/t/myisam_debug.test diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index c3eede79754..732b1b260f8 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -2252,43 +2252,4 @@ h+0 d + 0 e g + 0 1 1 3 0 1 1 4 0 DROP TABLE t1; -# -# BUG#40827 - Killing insert-select to MyISAM can cause table corruption -# -CREATE TABLE `t1` ( -`id` BIGINT(20) , -`id1` BIGINT(20) AUTO_INCREMENT, -KEY(id1), KEY(id) -) ENGINE=MyISAM; -CREATE TABLE `t2` ( -`id` BIGINT(20) , -`id1` BIGINT(20) AUTO_INCREMENT, -KEY (id1), KEY(id) -) ENGINE=MyISAM; -INSERT INTO t2 (id) VALUES (123); -INSERT INTO t2 (id) SELECT id FROM t2; -INSERT INTO t2 (id) SELECT id FROM t2; -INSERT INTO t2 (id) SELECT id FROM t2; -INSERT INTO t2 (id) SELECT id FROM t2; -INSERT INTO t2 (id) SELECT id FROM t2; -INSERT INTO t2 (id) SELECT id FROM t2; -INSERT INTO t2 (id) SELECT id FROM t2; -INSERT INTO t2 (id) SELECT id FROM t2; -INSERT INTO t2 (id) SELECT id FROM t2; -INSERT INTO t2 (id) SELECT id FROM t2; -# Switch to insert Connection -SET SESSION debug='+d,wait_in_enable_indexes'; -# Send insert data -INSERT INTO t1(id) SELECT id FROM t2; -# Switch to default Connection -# Wait for insert data to reach the debug point -SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST -WHERE STATE = 'wait_in_enable_indexes' AND -INFO = "INSERT INTO t1(id) SELECT id FROM t2" -INTO @thread_id; -KILL QUERY @thread_id; -CHECK TABLE t1; -Table Op Msg_type Msg_text -test.t1 check status OK -DROP TABLE t1,t2; End of 5.1 tests diff --git a/mysql-test/r/myisam_debug.result b/mysql-test/r/myisam_debug.result new file mode 100644 index 00000000000..c128bfffce9 --- /dev/null +++ b/mysql-test/r/myisam_debug.result @@ -0,0 +1,39 @@ +# +# BUG#40827 - Killing insert-select to MyISAM can cause table corruption +# +CREATE TABLE `t1` ( +`id` BIGINT(20) , +`id1` BIGINT(20) AUTO_INCREMENT, +KEY(id1), KEY(id) +) ENGINE=MyISAM; +CREATE TABLE `t2` ( +`id` BIGINT(20) , +`id1` BIGINT(20) AUTO_INCREMENT, +KEY (id1), KEY(id) +) ENGINE=MyISAM; +INSERT INTO t2 (id) VALUES (123); +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +INSERT INTO t2 (id) SELECT id FROM t2; +# Switch to insert Connection +SET SESSION debug='+d,wait_in_enable_indexes'; +# Send insert data +INSERT INTO t1(id) SELECT id FROM t2; +# Switch to default Connection +# Wait for insert data to reach the debug point +SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST +WHERE STATE = 'wait_in_enable_indexes' AND +INFO = "INSERT INTO t1(id) SELECT id FROM t2" +INTO @thread_id; +KILL QUERY @thread_id; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1,t2; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 21ee1cffbd0..ba6bc05cfea 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1503,57 +1503,5 @@ SELECT h+0, d + 0, e, g + 0 FROM t1; DROP TABLE t1; ---echo # ---echo # BUG#40827 - Killing insert-select to MyISAM can cause table corruption ---echo # - -CONNECT (insertConn, localhost, root,,); - -CREATE TABLE `t1` ( -`id` BIGINT(20) , -`id1` BIGINT(20) AUTO_INCREMENT, - KEY(id1), KEY(id) -) ENGINE=MyISAM; - -CREATE TABLE `t2` ( -`id` BIGINT(20) , -`id1` BIGINT(20) AUTO_INCREMENT, - KEY (id1), KEY(id) -) ENGINE=MyISAM; - -INSERT INTO t2 (id) VALUES (123); - -let $i = 10; -while ($i) -{ - INSERT INTO t2 (id) SELECT id FROM t2; - dec $i; -} - ---echo # Switch to insert Connection -CONNECTION insertConn; -SET SESSION debug='+d,wait_in_enable_indexes'; ---echo # Send insert data -SEND INSERT INTO t1(id) SELECT id FROM t2; - ---echo # Switch to default Connection -CONNECTION default; ---echo # Wait for insert data to reach the debug point - -let $wait_condition= - SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST - WHERE STATE = "wait_in_enable_indexes" AND - INFO = "INSERT INTO t1(id) SELECT id FROM t2"; ---source include/wait_condition.inc - -SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST -WHERE STATE = 'wait_in_enable_indexes' AND -INFO = "INSERT INTO t1(id) SELECT id FROM t2" -INTO @thread_id; - -KILL QUERY @thread_id; -CHECK TABLE t1; -DROP TABLE t1,t2; -DISCONNECT insertConn; --echo End of 5.1 tests diff --git a/mysql-test/t/myisam_debug.test b/mysql-test/t/myisam_debug.test new file mode 100644 index 00000000000..a73187cd2ca --- /dev/null +++ b/mysql-test/t/myisam_debug.test @@ -0,0 +1,54 @@ +--source include/have_debug.inc + +--echo # +--echo # BUG#40827 - Killing insert-select to MyISAM can cause table corruption +--echo # + +CONNECT (insertConn, localhost, root,,); + +CREATE TABLE `t1` ( +`id` BIGINT(20) , +`id1` BIGINT(20) AUTO_INCREMENT, + KEY(id1), KEY(id) +) ENGINE=MyISAM; + +CREATE TABLE `t2` ( +`id` BIGINT(20) , +`id1` BIGINT(20) AUTO_INCREMENT, + KEY (id1), KEY(id) +) ENGINE=MyISAM; + +INSERT INTO t2 (id) VALUES (123); + +let $i = 10; +while ($i) +{ + INSERT INTO t2 (id) SELECT id FROM t2; + dec $i; +} + +--echo # Switch to insert Connection +CONNECTION insertConn; +SET SESSION debug='+d,wait_in_enable_indexes'; +--echo # Send insert data +SEND INSERT INTO t1(id) SELECT id FROM t2; + +--echo # Switch to default Connection +CONNECTION default; +--echo # Wait for insert data to reach the debug point + +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST + WHERE STATE = "wait_in_enable_indexes" AND + INFO = "INSERT INTO t1(id) SELECT id FROM t2"; +--source include/wait_condition.inc + +SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST +WHERE STATE = 'wait_in_enable_indexes' AND +INFO = "INSERT INTO t1(id) SELECT id FROM t2" +INTO @thread_id; + +KILL QUERY @thread_id; +CHECK TABLE t1; +DROP TABLE t1,t2; +DISCONNECT insertConn; From 0c4a79c1329d24d87f7bb4c92c6c3dde6fc4420f Mon Sep 17 00:00:00 2001 From: Matthias Leich Date: Thu, 30 Apr 2009 12:26:11 +0200 Subject: [PATCH 79/85] Merge of fix for Bug#44522 main.not_embedded_server fails with "--check-testcases" into actual tree --- mysql-test/r/not_embedded_server.result | 7 +------ mysql-test/t/not_embedded_server.test | 10 ++++++++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/not_embedded_server.result b/mysql-test/r/not_embedded_server.result index edb698ade83..69175ca446f 100644 --- a/mysql-test/r/not_embedded_server.result +++ b/mysql-test/r/not_embedded_server.result @@ -4,9 +4,4 @@ Id User Host db Command Time State Info number root localhost test Query time NULL show full processlist deallocate prepare stmt1; FLUSH STATUS; -SHOW GLOBAL STATUS LIKE 'com_select'; -Variable_name Value -Com_select 101 -SHOW GLOBAL STATUS LIKE 'com_select'; -Variable_name Value -Com_select 101 +Value of com_select did not change diff --git a/mysql-test/t/not_embedded_server.test b/mysql-test/t/not_embedded_server.test index 044d8665a18..fcbcc389b15 100644 --- a/mysql-test/t/not_embedded_server.test +++ b/mysql-test/t/not_embedded_server.test @@ -39,8 +39,14 @@ while ($i) --enable_query_log --enable_result_log -SHOW GLOBAL STATUS LIKE 'com_select'; +let $before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_select',Value,1); --change_user -SHOW GLOBAL STATUS LIKE 'com_select'; +let $after= query_get_value(SHOW GLOBAL STATUS LIKE 'com_select',Value,1); + +if (`select $after != $before`){ + SHOW GLOBAL STATUS LIKE 'com_select'; + die The value of com_select changed during change_user; +} +echo Value of com_select did not change; From b3190a4528b634199ab5e4aefc97bd4d7ecdb95d Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Thu, 30 Apr 2009 15:28:07 +0300 Subject: [PATCH 80/85] Bug #44179 reset slave crashes in my_error when reset_logs returns non-zero my_error() was invoked in reset_slave()'s with purge_relay_logs()-failing branch without passing sql_errno to it. Fixed with setting sql_errno= ER_RELAY_LOG_FAIL in the purge_relay_logs()-failing branch. --- sql/sql_repl.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 6285a2dfb55..06c6c022780 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1026,7 +1026,10 @@ int reset_slave(THD *thd, Master_info* mi) if ((error= purge_relay_logs(&mi->rli, thd, 1 /* just reset */, &errmsg))) + { + sql_errno= ER_RELAY_LOG_FAIL; goto err; + } /* Clear master's log coordinates and reset host/user/etc to the values From 2b491daa1cd91fbb03f0a425cb57ec85c5a72bf2 Mon Sep 17 00:00:00 2001 From: Narayanan V Date: Thu, 30 Apr 2009 18:16:49 +0530 Subject: [PATCH 81/85] BUG#37631 - Incorrect key file for table after upgrading from 5.0 to 5.1 This patch adds corrections to the original patch submitted 2009-04-08 (http://lists.mysql.com/commits/71607): - fixed that the original patch didn't work because of an incorrect condition; - added a test case. --- mysql-test/r/upgrade.result | 12 ++++++++++++ mysql-test/std_data/bug37631.MYD | 0 mysql-test/std_data/bug37631.MYI | Bin 0 -> 1024 bytes mysql-test/std_data/bug37631.frm | Bin 0 -> 8590 bytes mysql-test/t/upgrade.test | 14 ++++++++++++++ storage/myisam/ha_myisam.cc | 4 ++-- 6 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 mysql-test/std_data/bug37631.MYD create mode 100644 mysql-test/std_data/bug37631.MYI create mode 100644 mysql-test/std_data/bug37631.frm diff --git a/mysql-test/r/upgrade.result b/mysql-test/r/upgrade.result index 711e69094f7..da6201692a9 100644 --- a/mysql-test/r/upgrade.result +++ b/mysql-test/r/upgrade.result @@ -57,6 +57,18 @@ s1 1 drop table `txu@0023p@0023p1`; drop table `txu#p#p1`; +# +# Bug#37631 Incorrect key file for table after upgrading from 5.0 to 5.1 +# +# copy table created using mysql4.0 into the data dir +# check the table created using mysql 4.0 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check error Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! +# query the table created using mysql 4.0 +SELECT * FROM t1; +c1 c2 c3 +DROP TABLE t1; truncate t1; drop table t1; drop database if exists `tabc`; diff --git a/mysql-test/std_data/bug37631.MYD b/mysql-test/std_data/bug37631.MYD new file mode 100644 index 00000000000..e69de29bb2d diff --git a/mysql-test/std_data/bug37631.MYI b/mysql-test/std_data/bug37631.MYI new file mode 100644 index 0000000000000000000000000000000000000000..8bf14b46add28b82cb45f9017f45ed63ed9b8fa6 GIT binary patch literal 1024 zcmezOkDZZ$iLsAi149bK83tws21W)BMg|c04<@k?|DgaP#ezizE+Ov2$TBc!h&BtA?DHX7n;2BO`g1~dd2ivamx%`D6iqktR(uth8gLxBOr4;0sAU}w-` t4XbHm5frOAwZ81008!jB|88B literal 0 HcmV?d00001 diff --git a/mysql-test/std_data/bug37631.frm b/mysql-test/std_data/bug37631.frm new file mode 100644 index 0000000000000000000000000000000000000000..2742a387c383c603c5af688a8b932855c09aedb2 GIT binary patch literal 8590 zcmeI$Jqm+B5C!13JI4GqDMD&N6q3fj6C_=VfY_z>BAy`E%q_B+m|!P@5KwqiEbHoy z!&knSS*``x86X9oh|!fzvFaZBHc0{meJ^=V0SZun0u-PC1t>rP3Q&Lo6rjK)1dK%3 zz(x?$*v~{EY!gAx45ZOC;InaMb-kUdyPL$wV}@|SaErP3Q&Lo6rcbF zC_sT(2s{jSvl#SGLu$%_3r^ZS# Date: Thu, 30 Apr 2009 16:20:38 +0300 Subject: [PATCH 82/85] moving bug#38694 test files into rpl suite --- mysql-test/{ => suite/rpl}/r/rpl_bug38694.result | 0 mysql-test/{ => suite/rpl}/t/rpl_bug38694-slave.opt | 0 mysql-test/{ => suite/rpl}/t/rpl_bug38694.test | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename mysql-test/{ => suite/rpl}/r/rpl_bug38694.result (100%) rename mysql-test/{ => suite/rpl}/t/rpl_bug38694-slave.opt (100%) rename mysql-test/{ => suite/rpl}/t/rpl_bug38694.test (100%) diff --git a/mysql-test/r/rpl_bug38694.result b/mysql-test/suite/rpl/r/rpl_bug38694.result similarity index 100% rename from mysql-test/r/rpl_bug38694.result rename to mysql-test/suite/rpl/r/rpl_bug38694.result diff --git a/mysql-test/t/rpl_bug38694-slave.opt b/mysql-test/suite/rpl/t/rpl_bug38694-slave.opt similarity index 100% rename from mysql-test/t/rpl_bug38694-slave.opt rename to mysql-test/suite/rpl/t/rpl_bug38694-slave.opt diff --git a/mysql-test/t/rpl_bug38694.test b/mysql-test/suite/rpl/t/rpl_bug38694.test similarity index 100% rename from mysql-test/t/rpl_bug38694.test rename to mysql-test/suite/rpl/t/rpl_bug38694.test From a2b1133e3a9288160aaf72b88b9e23293528c930 Mon Sep 17 00:00:00 2001 From: Satya B Date: Mon, 4 May 2009 14:35:16 +0530 Subject: [PATCH 83/85] Additional Fix for BUG#40827 - Killing insert-select to MyISAM can cause table corruption Disabling the mysiam_debug.test in embedded mode because of BUG#43733 --- mysql-test/t/myisam_debug.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/t/myisam_debug.test b/mysql-test/t/myisam_debug.test index a73187cd2ca..913668c5f22 100644 --- a/mysql-test/t/myisam_debug.test +++ b/mysql-test/t/myisam_debug.test @@ -1,5 +1,8 @@ --source include/have_debug.inc +# We disable this test in embedded mode because of BUG#43733 +--source include/not_embedded.inc + --echo # --echo # BUG#40827 - Killing insert-select to MyISAM can cause table corruption --echo # From 1d94d21c2f8856b5c2dd0195f65e599650446fd9 Mon Sep 17 00:00:00 2001 From: "kent.boort@sun.com" <> Date: Tue, 5 May 2009 16:27:35 +0200 Subject: [PATCH 84/85] Added clarification about GPL v2, changed to Sun Microsystems, Inc. --- README | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README b/README index 56bd912d3d6..1a96d708a7e 100644 --- a/README +++ b/README @@ -1,11 +1,19 @@ This is a release of MySQL, a dual-license SQL database server. -MySQL is brought to you by the MySQL team at MySQL AB. +MySQL is brought to you by the MySQL team at Sun Microsystems, Inc. License information can be found in these files: - For GPL (free) distributions, see the COPYING file and the EXCEPTIONS-CLIENT file. - For commercial distributions, see the LICENSE.mysql file. +GPLv2 Disclaimer +For the avoidance of doubt, except that if any license choice +other than GPL or LGPL is available it will apply instead, Sun +elects to use only the General Public License version 2 (GPLv2) +at this time for any software where a choice of GPL license versions +is made available with the language indicating that GPLv2 or any +later version may be used, or where a choice of which version of +the GPL is applied is otherwise unspecified. For further information about MySQL or additional documentation, see: - The latest information about MySQL: http://www.mysql.com From 262906f7bc32121325e1ffb6d6e99921cbcc29e4 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 5 May 2009 20:47:43 +0200 Subject: [PATCH 85/85] Remove unused variable. --- sql/slave.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index 9ba0788a5e4..a6264dfb0ac 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -465,8 +465,6 @@ terminate_slave_thread(THD *thd, volatile uint *slave_running, bool skip_lock) { - int error; - DBUG_ENTER("terminate_slave_thread"); if (!skip_lock) {