From 79c8175c36084403dd716844aa0ec069c530a645 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 17 Oct 2008 13:55:16 +0300 Subject: Bug #38637: COUNT DISTINCT prevents NULL testing in HAVING clause IS NULL was not checking the correct row in a HAVING context. At the first row of a new group (where the HAVING clause is evaluated) the column and SELECT list references in the HAVING clause should refer to the last row of the previous group and not to the current one. This was not done for IS NULL, because it was using Item::is_null() doesn't have a Item_is_null_result() counterpart to access the data from the last row of the previous group. Note that all the Item::val_xxx() functions (e.g. Item::val_int()) have their _result counterparts (e.g. Item::val_int_result()). Fixed by implementing a is_null_result() (similarly to int_result()) and calling this instead of is_null() column and SELECT list references inside the HAVING clause. mysql-test/r/having.result: Bug #38637: test case mysql-test/t/having.test: Bug #38637: test case sql/item.cc: Bug #38637: implement Item::is_null_result() and call it from Item_ref and Item_field as appropriate. sql/item.h: Bug #38637: implement Item::is_null_result() and call it from Item_ref and Item_field as appropriate. sql/item_func.cc: Bug #38637: implement Item::is_null_result() and call it from Item_ref and Item_field as appropriate. sql/item_func.h: Bug #38637: implement Item::is_null_result() and call it from Item_ref and Item_field as appropriate. --- mysql-test/r/having.result | 7 +++++++ mysql-test/t/having.test | 11 +++++++++++ sql/item.cc | 19 ++++++++++++++++++- sql/item.h | 3 +++ sql/item_func.cc | 9 +++++++++ sql/item_func.h | 1 + 6 files changed, 49 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index f113304c767..bc8596100f8 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -424,3 +424,10 @@ select f1 from t1 group by f1 having max(f1)=f1; f1 set session sql_mode=''; drop table t1; +CREATE TABLE t1 ( a INT, b INT); +INSERT INTO t1 VALUES (1, 1), (2,2), (3, NULL); +SELECT b, COUNT(DISTINCT a) FROM t1 GROUP BY b HAVING b is NULL; +b COUNT(DISTINCT a) +NULL 1 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index 827b83f11a0..adabbb711d4 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -432,3 +432,14 @@ select f1 from t1 having max(f1)=f1; select f1 from t1 group by f1 having max(f1)=f1; set session sql_mode=''; drop table t1; + + +# +# Bug #38637: COUNT DISTINCT prevents NULL testing in HAVING clause +# +CREATE TABLE t1 ( a INT, b INT); +INSERT INTO t1 VALUES (1, 1), (2,2), (3, NULL); +SELECT b, COUNT(DISTINCT a) FROM t1 GROUP BY b HAVING b is NULL; +DROP TABLE t1; + +--echo End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index 182f4abdfe6..e71268724b4 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2041,6 +2041,12 @@ bool Item_field::val_bool_result() } +bool Item_field::is_null_result() +{ + return (null_value=result_field->is_null()); +} + + bool Item_field::eq(const Item *item, bool binary_cmp) const { Item *real_item= ((Item *) item)->real_item(); @@ -5626,6 +5632,15 @@ double Item_ref::val_result() } +bool Item_ref::is_null_result() +{ + if (result_field) + return (null_value=result_field->is_null()); + + return is_null(); +} + + longlong Item_ref::val_int_result() { if (result_field) @@ -5731,7 +5746,9 @@ String *Item_ref::val_str(String* tmp) bool Item_ref::is_null() { DBUG_ASSERT(fixed); - return (*ref)->is_null(); + bool tmp=(*ref)->is_null_result(); + null_value=(*ref)->null_value; + return tmp; } diff --git a/sql/item.h b/sql/item.h index 250bb3f67ef..1058cc5dbb8 100644 --- a/sql/item.h +++ b/sql/item.h @@ -652,6 +652,7 @@ public: virtual my_decimal *val_decimal_result(my_decimal *val) { return val_decimal(val); } virtual bool val_bool_result() { return val_bool(); } + virtual bool is_null_result() { return is_null(); } /* bit map of tables used by item */ virtual table_map used_tables() const { return (table_map) 0L; } @@ -1301,6 +1302,7 @@ public: String *str_result(String* tmp); my_decimal *val_decimal_result(my_decimal *); bool val_bool_result(); + bool is_null_result(); bool send(Protocol *protocol, String *str_arg); void reset_field(Field *f); bool fix_fields(THD *, Item **); @@ -1942,6 +1944,7 @@ public: String *str_result(String* tmp); my_decimal *val_decimal_result(my_decimal *); bool val_bool_result(); + bool is_null_result(); bool send(Protocol *prot, String *tmp); void make_field(Send_field *field); bool fix_fields(THD *, Item **); diff --git a/sql/item_func.cc b/sql/item_func.cc index e663e1fcf83..382fea6dfe2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4283,6 +4283,15 @@ my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val) } +bool Item_func_set_user_var::is_null_result() +{ + DBUG_ASSERT(fixed == 1); + check(TRUE); + update(); // Store expression + return is_null(); +} + + void Item_func_set_user_var::print(String *str) { str->append(STRING_WITH_LEN("(@")); diff --git a/sql/item_func.h b/sql/item_func.h index 6dcf32cba07..8c7becb681b 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1299,6 +1299,7 @@ public: longlong val_int_result(); String *str_result(String *str); my_decimal *val_decimal_result(my_decimal *); + bool is_null_result(); bool update_hash(void *ptr, uint length, enum Item_result type, CHARSET_INFO *cs, Derivation dv, bool unsigned_arg); bool send(Protocol *protocol, String *str_arg); -- cgit v1.2.1 From 625ed30fd8e19fafdbbd926b4d6fb610b245002d Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 23 Oct 2008 19:04:52 +0200 Subject: Raise version number for 5.0.66sp1 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index a1dc9d36d82..8c177892f18 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.66a) +AM_INIT_AUTOMAKE(mysql, 5.0.66sp1) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 -- cgit v1.2.1 From 51fccee36dab386d463902341a1d665f62639dea Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 23 Oct 2008 19:36:48 +0200 Subject: Merge fix for bug#38296 into 5.0.66sp1 --- mysys/my_alloc.c | 2 +- sql/field.h | 3 +- sql/item.h | 4 +- sql/sp_head.cc | 2 +- sql/sql_lex.h | 4 +- sql/sql_list.h | 4 +- sql/sql_string.h | 2 +- sql/sql_yacc.yy | 1775 +++++++++++++++++++++++++++++++++++++++++++---------- sql/thr_malloc.cc | 31 +- 9 files changed, 1483 insertions(+), 344 deletions(-) diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index 5983a29a3e1..99b5aec7eea 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -202,7 +202,7 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size) { if (mem_root->error_handler) (*mem_root->error_handler)(); - return((gptr) 0); /* purecov: inspected */ + DBUG_RETURN((gptr) 0); /* purecov: inspected */ } mem_root->block_num++; next->next= *prev; diff --git a/sql/field.h b/sql/field.h index 8d771a151a7..241ad61f339 100644 --- a/sql/field.h +++ b/sql/field.h @@ -48,7 +48,8 @@ class Field Field(const Item &); /* Prevent use of these */ void operator=(Field &); public: - static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); } + static void *operator new(size_t size) throw () + { return (void*) sql_alloc((uint) size); } static void operator delete(void *ptr_arg, size_t size) { TRASH(ptr_arg, size); } char *ptr; // Position to field in record diff --git a/sql/item.h b/sql/item.h index a948c5a45f7..126730bb892 100644 --- a/sql/item.h +++ b/sql/item.h @@ -439,9 +439,9 @@ class Item { Item(const Item &); /* Prevent use of these */ void operator=(Item &); public: - static void *operator new(size_t size) + static void *operator new(size_t size) throw () { return (void*) sql_alloc((uint) size); } - static void *operator new(size_t size, MEM_ROOT *mem_root) + static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return (void*) alloc_root(mem_root, (uint) size); } static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } static void operator delete(void *ptr, MEM_ROOT *mem_root) {} diff --git a/sql/sp_head.cc b/sql/sp_head.cc index aea81e301ef..7cc551a76c0 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -446,7 +446,7 @@ sp_head::operator new(size_t size) throw() init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); sp= (sp_head *) alloc_root(&own_root, size); if (sp == NULL) - return NULL; + DBUG_RETURN(NULL); sp->main_mem_root= own_root; DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root)); DBUG_RETURN(sp); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index cde4c3a97b3..79cc0b6b3f2 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -331,11 +331,11 @@ public: bool no_table_names_allowed; /* used for global order by */ bool no_error; /* suppress error message (convert it to warnings) */ - static void *operator new(size_t size) + static void *operator new(size_t size) throw () { return (void*) sql_alloc((uint) size); } - static void *operator new(size_t size, MEM_ROOT *mem_root) + static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return (void*) alloc_root(mem_root, (uint) size); } static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } static void operator delete(void *ptr, MEM_ROOT *mem_root) {} diff --git a/sql/sql_list.h b/sql/sql_list.h index 7913acfd086..1ad2051f065 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -27,7 +27,7 @@ public: { return (void*) sql_alloc((uint) size); } - static void *operator new[](size_t size) + static void *operator new[](size_t size) throw () { return (void*) sql_alloc((uint) size); } @@ -466,7 +466,7 @@ public: struct ilink { struct ilink **prev,*next; - static void *operator new(size_t size) + static void *operator new(size_t size) throw () { return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE)); } diff --git a/sql/sql_string.h b/sql/sql_string.h index c1d27cb1791..4432451464e 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -78,7 +78,7 @@ public: Alloced_length=str.Alloced_length; alloced=0; str_charset=str.str_charset; } - static void *operator new(size_t size, MEM_ROOT *mem_root) + static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return (void*) alloc_root(mem_root, (uint) size); } static void operator delete(void *ptr_arg,size_t size) { TRASH(ptr_arg, size); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 090585392a0..c89676d0bde 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1539,6 +1539,8 @@ create: { LEX *lex=Lex; Key *key= new Key($2, $4.str, $5, 0, lex->col_list); + if (key == NULL) + MYSQL_YYABORT; lex->alter_info.key_list.push_back(key); lex->col_list.empty(); @@ -1598,6 +1600,8 @@ sp_name: MYSQL_YYABORT; } $$= new sp_name($1, $3, true); + if ($$ == NULL) + MYSQL_YYABORT; $$->init_qname(YYTHD); } | ident @@ -1613,8 +1617,9 @@ sp_name: if (lex->copy_db_to(&db.str, &db.length)) MYSQL_YYABORT; $$= new sp_name(db, $1, false); - if ($$) - $$->init_qname(YYTHD); + if ($$ == NULL) + MYSQL_YYABORT; + $$->init_qname(YYTHD); } ; @@ -1865,6 +1870,8 @@ sp_decl: if (!dflt_value_item) { dflt_value_item= new Item_null(); + if (dflt_value_item == NULL) + MYSQL_YYABORT; /* QQ Set to the var_type with null_value? */ } @@ -1890,10 +1897,17 @@ sp_decl: /* The last instruction is responsible for freeing LEX. */ - lex->sphead->add_instr( - new sp_instr_set(lex->sphead->instructions(), pctx, var_idx, - dflt_value_item, var_type, lex, - (i == num_vars - 1))); + sp_instr_set *is= new sp_instr_set(lex->sphead->instructions(), + pctx, + var_idx, + dflt_value_item, + var_type, + lex, + (i == num_vars - 1)); + if (is == NULL) + MYSQL_YYABORT; + + lex->sphead->add_instr(is); } pctx->declare_var_boundary(0); @@ -1927,6 +1941,8 @@ sp_decl: sp_instr_hpush_jump *i= new sp_instr_hpush_jump(sp->instructions(), ctx, $2, ctx->current_var_count()); + if (i == NULL) + MYSQL_YYABORT; sp->add_instr(i); sp->push_backpatch(i, ctx->push_label((char *)"", 0)); @@ -1979,7 +1995,7 @@ sp_decl: } i= new sp_instr_cpush(sp->instructions(), ctx, $5, ctx->current_cursor_count()); - if ( i==NULL ) + if (i == NULL) MYSQL_YYABORT; sp->add_instr(i); ctx->push_cursor(&$2); @@ -2060,6 +2076,8 @@ sp_cond: ulong_num { /* mysql errno */ $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + if ($$ == NULL) + YYABORT; $$->type= sp_cond_type_t::number; $$->mysqlerr= $1; } @@ -2071,6 +2089,8 @@ sp_cond: MYSQL_YYABORT; } $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + if ($$ == NULL) + YYABORT; $$->type= sp_cond_type_t::state; memcpy($$->sqlstate, $3.str, 5); $$->sqlstate[5]= '\0'; @@ -2099,16 +2119,22 @@ sp_hcond: | SQLWARNING_SYM /* SQLSTATEs 01??? */ { $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + if ($$ == NULL) + YYABORT; $$->type= sp_cond_type_t::warning; } | not FOUND_SYM /* SQLSTATEs 02??? */ { $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + if ($$ == NULL) + YYABORT; $$->type= sp_cond_type_t::notfound; } | SQLEXCEPTION_SYM /* All other SQLSTATEs */ { $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + if ($$ == NULL) + YYABORT; $$->type= sp_cond_type_t::exception; } ; @@ -3084,6 +3110,8 @@ key_def: { LEX *lex=Lex; Key *key= new Key($1, $2, $7 ? $7 : $3, 0, lex->col_list); + if (key == NULL) + MYSQL_YYABORT; lex->alter_info.key_list.push_back(key); lex->col_list.empty(); /* Alloced by sql_alloc */ @@ -3093,6 +3121,8 @@ key_def: LEX *lex=Lex; const char *key_name= $3 ? $3:$1; Key *key= new Key($2, key_name, $4, 0, lex->col_list); + if (key == NULL) + MYSQL_YYABORT; lex->alter_info.key_list.push_back(key); lex->col_list.empty(); /* Alloced by sql_alloc */ } @@ -3106,10 +3136,14 @@ key_def: lex->fk_delete_opt, lex->fk_update_opt, lex->fk_match_option); + if (key == NULL) + MYSQL_YYABORT; lex->alter_info.key_list.push_back(key); key= new Key(Key::MULTIPLE, key_name, HA_KEY_ALG_UNDEF, 1, lex->col_list); + if (key == NULL) + MYSQL_YYABORT; lex->alter_info.key_list.push_back(key); lex->col_list.empty(); /* Alloced by sql_alloc */ } @@ -3399,7 +3433,12 @@ attribute: ; now_or_signed_literal: - NOW_SYM optional_braces { $$= new Item_func_now_local(); } + NOW_SYM optional_braces + { + $$= new Item_func_now_local(); + if ($$ == NULL) + MYSQL_YYABORT; + } | signed_literal { $$=$1; } ; @@ -3525,8 +3564,21 @@ opt_ref_list: | '(' ref_list ')' opt_on_delete {}; ref_list: - ref_list ',' ident { Lex->ref_list.push_back(new key_part_spec($3.str)); } - | ident { Lex->ref_list.push_back(new key_part_spec($1.str)); }; + ref_list ',' ident + { + key_part_spec *key= new key_part_spec($3.str); + if (key == NULL) + MYSQL_YYABORT; + Lex->ref_list.push_back(key); + } + | ident + { + key_part_spec *key= new key_part_spec($1.str); + if (key == NULL) + MYSQL_YYABORT; + Lex->ref_list.push_back(key); + } + ; opt_on_delete: @@ -3617,16 +3669,24 @@ key_list: | key_part order_dir { Lex->col_list.push_back($1); }; key_part: - ident { $$=new key_part_spec($1.str); } - | ident '(' NUM ')' - { - int key_part_len= atoi($3.str); - if (!key_part_len) + ident { - my_error(ER_KEY_PART_0, MYF(0), $1.str); + $$= new key_part_spec($1.str); + if ($$ == NULL) + MYSQL_YYABORT; } - $$=new key_part_spec($1.str,(uint) key_part_len); - }; + | ident '(' NUM ')' + { + int key_part_len= atoi($3.str); + if (!key_part_len) + { + my_error(ER_KEY_PART_0, MYF(0), $1.str); + } + $$=new key_part_spec($1.str,(uint) key_part_len); + if ($$ == NULL) + MYSQL_YYABORT; + } + ; opt_ident: /* empty */ { $$=(char*) 0; } /* Defaultlength */ @@ -3796,8 +3856,10 @@ alter_list_item: | DROP opt_column field_ident opt_restrict { LEX *lex=Lex; - lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::COLUMN, - $3.str)); + Alter_drop *ad= new Alter_drop(Alter_drop::COLUMN, $3.str); + if (ad == NULL) + MYSQL_YYABORT; + lex->alter_info.drop_list.push_back(ad); lex->alter_info.flags|= ALTER_DROP_COLUMN; } | DROP FOREIGN KEY_SYM opt_ident @@ -3807,15 +3869,19 @@ alter_list_item: | DROP PRIMARY_SYM KEY_SYM { LEX *lex=Lex; - lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY, - primary_key_name)); + Alter_drop *ad= new Alter_drop(Alter_drop::KEY, primary_key_name); + if (ad == NULL) + MYSQL_YYABORT; + lex->alter_info.drop_list.push_back(ad); lex->alter_info.flags|= ALTER_DROP_INDEX; } | DROP key_or_index field_ident { LEX *lex=Lex; - lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY, - $3.str)); + Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str); + if (ad == NULL) + MYSQL_YYABORT; + lex->alter_info.drop_list.push_back(ad); lex->alter_info.flags|= ALTER_DROP_INDEX; } | DISABLE_SYM KEYS @@ -3833,14 +3899,19 @@ alter_list_item: | ALTER opt_column field_ident SET DEFAULT signed_literal { LEX *lex=Lex; - lex->alter_info.alter_list.push_back(new Alter_column($3.str,$6)); + Alter_column *ac= new Alter_column($3.str, $6); + if (ac == NULL) + MYSQL_YYABORT; + lex->alter_info.alter_list.push_back(ac); lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT; } | ALTER opt_column field_ident DROP DEFAULT { LEX *lex=Lex; - lex->alter_info.alter_list.push_back(new Alter_column($3.str, - (Item*) 0)); + Alter_column *ac= new Alter_column($3.str, (Item*) 0); + if (ac == NULL) + MYSQL_YYABORT; + lex->alter_info.alter_list.push_back(ac); lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT; } | RENAME opt_to table_ident @@ -4466,10 +4537,11 @@ select_item_list: | '*' { THD *thd= YYTHD; - if (add_item_to_list(thd, - new Item_field(&thd->lex->current_select-> - context, - NULL, NULL, "*"))) + Item *item= new Item_field(&thd->lex->current_select->context, + NULL, NULL, "*"); + if (item == NULL) + MYSQL_YYABORT; + if (add_item_to_list(thd, item)) MYSQL_YYABORT; (thd->lex->current_select->with_wild)++; }; @@ -4580,12 +4652,16 @@ expr: { /* X OR Y */ $$ = new (YYTHD->mem_root) Item_cond_or($1, $3); + if ($$ == NULL) + MYSQL_YYABORT; } } | expr XOR expr %prec XOR { /* XOR is a proprietary extension */ $$ = new (YYTHD->mem_root) Item_cond_xor($1, $3); + if ($$ == NULL) + MYSQL_YYABORT; } | expr and expr %prec AND_SYM { @@ -4626,62 +4702,124 @@ expr: { /* X AND Y */ $$ = new (YYTHD->mem_root) Item_cond_and($1, $3); + if ($$ == NULL) + MYSQL_YYABORT; } } | NOT_SYM expr %prec NOT_SYM - { $$= negate_expression(YYTHD, $2); } + { + $$= negate_expression(YYTHD, $2); + if ($$ == NULL) + MYSQL_YYABORT; + } | bool_pri IS TRUE_SYM %prec IS - { $$= new (YYTHD->mem_root) Item_func_istrue($1); } + { + $$= new (YYTHD->mem_root) Item_func_istrue($1); + if ($$ == NULL) + MYSQL_YYABORT; + } | bool_pri IS not TRUE_SYM %prec IS - { $$= new (YYTHD->mem_root) Item_func_isnottrue($1); } + { + $$= new (YYTHD->mem_root) Item_func_isnottrue($1); + if ($$ == NULL) + MYSQL_YYABORT; + } | bool_pri IS FALSE_SYM %prec IS - { $$= new (YYTHD->mem_root) Item_func_isfalse($1); } + { + $$= new (YYTHD->mem_root) Item_func_isfalse($1); + if ($$ == NULL) + MYSQL_YYABORT; + } | bool_pri IS not FALSE_SYM %prec IS - { $$= new (YYTHD->mem_root) Item_func_isnotfalse($1); } + { + $$= new (YYTHD->mem_root) Item_func_isnotfalse($1); + if ($$ == NULL) + MYSQL_YYABORT; + } | bool_pri IS UNKNOWN_SYM %prec IS - { $$= new Item_func_isnull($1); } + { + $$= new Item_func_isnull($1); + if ($$ == NULL) + MYSQL_YYABORT; + } | bool_pri IS not UNKNOWN_SYM %prec IS - { $$= new Item_func_isnotnull($1); } + { + $$= new Item_func_isnotnull($1); + if ($$ == NULL) + MYSQL_YYABORT; + } | bool_pri ; bool_pri: bool_pri IS NULL_SYM %prec IS - { $$= new Item_func_isnull($1); } + { + $$= new Item_func_isnull($1); + if ($$ == NULL) + MYSQL_YYABORT; + } | bool_pri IS not NULL_SYM %prec IS - { $$= new Item_func_isnotnull($1); } + { + $$= new Item_func_isnotnull($1); + if ($$ == NULL) + MYSQL_YYABORT; + } | bool_pri EQUAL_SYM predicate %prec EQUAL_SYM - { $$= new Item_func_equal($1,$3); } + { + $$= new Item_func_equal($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bool_pri comp_op predicate %prec EQ - { $$= (*$2)(0)->create($1,$3); } + { + $$= (*$2)(0)->create($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bool_pri comp_op all_or_any '(' subselect ')' %prec EQ - { $$= all_any_subquery_creator($1, $2, $3, $5); } + { + $$= all_any_subquery_creator($1, $2, $3, $5); + if ($$ == NULL) + MYSQL_YYABORT; + } | predicate ; predicate: bit_expr IN_SYM '(' subselect ')' { $$= new (YYTHD->mem_root) Item_in_subselect($1, $4); + if ($$ == NULL) + MYSQL_YYABORT; } | bit_expr not IN_SYM '(' subselect ')' { THD *thd= YYTHD; Item *item= new (thd->mem_root) Item_in_subselect($1, $5); + if (item == NULL) + MYSQL_YYABORT; $$= negate_expression(thd, item); + if ($$ == NULL) + MYSQL_YYABORT; } | bit_expr IN_SYM '(' expr ')' { $$= handle_sql2003_note184_exception(YYTHD, $1, true, $4); + if ($$ == NULL) + MYSQL_YYABORT; } | bit_expr IN_SYM '(' expr ',' expr_list ')' { $6->push_front($4); $6->push_front($1); $$= new (YYTHD->mem_root) Item_func_in(*$6); + if ($$ == NULL) + MYSQL_YYABORT; } | bit_expr not IN_SYM '(' expr ')' { $$= handle_sql2003_note184_exception(YYTHD, $1, false, $5); + if ($$ == NULL) + MYSQL_YYABORT; } | bit_expr not IN_SYM '(' expr ',' expr_list ')' { @@ -4694,54 +4832,146 @@ predicate: $$= item; } | bit_expr BETWEEN_SYM bit_expr AND_SYM predicate - { $$= new Item_func_between($1,$3,$5); } + { + $$= new Item_func_between($1,$3,$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate { Item_func_between *item= new Item_func_between($1,$4,$6); + if (item == NULL) + MYSQL_YYABORT; item->negate(); $$= item; } | bit_expr SOUNDS_SYM LIKE bit_expr - { $$= new Item_func_eq(new Item_func_soundex($1), - new Item_func_soundex($4)); } + { + Item *item1= new Item_func_soundex($1); + Item *item4= new Item_func_soundex($4); + if ((item1 == NULL) || (item4 == NULL)) + MYSQL_YYABORT; + $$= new Item_func_eq(item1, item4); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr LIKE simple_expr opt_escape - { $$= new Item_func_like($1,$3,$4,Lex->escape_used); } + { + $$= new Item_func_like($1,$3,$4,Lex->escape_used); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr not LIKE simple_expr opt_escape - { $$= new Item_func_not(new Item_func_like($1,$4,$5, Lex->escape_used)); } - | bit_expr REGEXP bit_expr { $$= new Item_func_regex($1,$3); } + { + Item *item= new Item_func_like($1,$4,$5, Lex->escape_used); + if (item == NULL) + MYSQL_YYABORT; + $$= new Item_func_not(item); + if ($$ == NULL) + MYSQL_YYABORT; + } + | bit_expr REGEXP bit_expr + { + $$= new Item_func_regex($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr not REGEXP bit_expr - { $$= negate_expression(YYTHD, new Item_func_regex($1,$4)); } + { + Item *item= new Item_func_regex($1,$4); + if (item == NULL) + MYSQL_YYABORT; + $$= negate_expression(YYTHD, item); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr ; bit_expr: bit_expr '|' bit_expr %prec '|' - { $$= new Item_func_bit_or($1,$3); } + { + $$= new Item_func_bit_or($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr '&' bit_expr %prec '&' - { $$= new Item_func_bit_and($1,$3); } + { + $$= new Item_func_bit_and($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr SHIFT_LEFT bit_expr %prec SHIFT_LEFT - { $$= new Item_func_shift_left($1,$3); } + { + $$= new Item_func_shift_left($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr SHIFT_RIGHT bit_expr %prec SHIFT_RIGHT - { $$= new Item_func_shift_right($1,$3); } + { + $$= new Item_func_shift_right($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr '+' bit_expr %prec '+' - { $$= new Item_func_plus($1,$3); } + { + $$= new Item_func_plus($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr '-' bit_expr %prec '-' - { $$= new Item_func_minus($1,$3); } + { + $$= new Item_func_minus($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr '+' interval_expr interval %prec '+' - { $$= new Item_date_add_interval($1,$3,$4,0); } + { + $$= new Item_date_add_interval($1,$3,$4,0); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr '-' interval_expr interval %prec '-' - { $$= new Item_date_add_interval($1,$3,$4,1); } + { + $$= new Item_date_add_interval($1,$3,$4,1); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr '*' bit_expr %prec '*' - { $$= new Item_func_mul($1,$3); } + { + $$= new Item_func_mul($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr '/' bit_expr %prec '/' - { $$= new Item_func_div($1,$3); } + { + $$= new Item_func_div($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr '%' bit_expr %prec '%' - { $$= new Item_func_mod($1,$3); } + { + $$= new Item_func_mod($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr DIV_SYM bit_expr %prec DIV_SYM - { $$= new Item_func_int_div($1,$3); } + { + $$= new Item_func_int_div($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr MOD_SYM bit_expr %prec MOD_SYM - { $$= new Item_func_mod($1,$3); } + { + $$= new Item_func_mod($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | bit_expr '^' bit_expr - { $$= new Item_func_bit_xor($1,$3); } + { + $$= new Item_func_bit_xor($1,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | simple_expr ; @@ -4771,67 +5001,118 @@ simple_expr: simple_ident | simple_expr COLLATE_SYM ident_or_text %prec NEG { - $$= new Item_func_set_collation($1, - new Item_string($3.str, - $3.length, - YYTHD->charset())); + Item *item= new Item_string($3.str, $3.length, YYTHD->charset()); + if (item == NULL) + MYSQL_YYABORT; + $$= new Item_func_set_collation($1, item); + if ($$ == NULL) + MYSQL_YYABORT; } | literal | param_marker | variable | sum_expr | simple_expr OR_OR_SYM simple_expr - { $$= new Item_func_concat($1, $3); } - | '+' simple_expr %prec NEG { $$= $2; } - | '-' simple_expr %prec NEG { $$= new Item_func_neg($2); } - | '~' simple_expr %prec NEG { $$= new Item_func_bit_neg($2); } - | not2 simple_expr %prec NEG { $$= negate_expression(YYTHD, $2); } + { + $$= new Item_func_concat($1, $3); + if ($$ == NULL) + MYSQL_YYABORT; + } + | '+' simple_expr %prec NEG + { $$= $2; } + | '-' simple_expr %prec NEG + { + $$= new Item_func_neg($2); + if ($$ == NULL) + MYSQL_YYABORT; + } + | '~' simple_expr %prec NEG + { + $$= new Item_func_bit_neg($2); + if ($$ == NULL) + MYSQL_YYABORT; + } + | not2 simple_expr %prec NEG + { + $$= negate_expression(YYTHD, $2); + if ($$ == NULL) + MYSQL_YYABORT; + } | '(' subselect ')' { $$= new Item_singlerow_subselect($2); + if ($$ == NULL) + MYSQL_YYABORT; } | '(' expr ')' { $$= $2; } | '(' expr ',' expr_list ')' { $4->push_front($2); $$= new Item_row(*$4); + if ($$ == NULL) + MYSQL_YYABORT; } | ROW_SYM '(' expr ',' expr_list ')' { $5->push_front($3); $$= new Item_row(*$5); + if ($$ == NULL) + MYSQL_YYABORT; } | EXISTS '(' subselect ')' { $$= new Item_exists_subselect($3); + if ($$ == NULL) + MYSQL_YYABORT; } - | '{' ident expr '}' { $$= $3; } + | '{' ident expr '}' + { $$= $3; } | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')' - { $2->push_front($5); - Select->add_ftfunc_to_list((Item_func_match*) - ($$=new Item_func_match(*$2,$6))); } - | ASCII_SYM '(' expr ')' { $$= new Item_func_ascii($3); } + { + $2->push_front($5); + Item_func_match *item= new Item_func_match(*$2,$6); + if (item == NULL) + MYSQL_YYABORT; + Select->add_ftfunc_to_list(item); + $$= item; + } + | ASCII_SYM '(' expr ')' + { + $$= new Item_func_ascii($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | BINARY simple_expr %prec NEG { $$= create_func_cast($2, ITEM_CAST_CHAR, NULL, NULL, &my_charset_bin); + if ($$ == NULL) + MYSQL_YYABORT; } | CAST_SYM '(' expr AS cast_type ')' { LEX *lex= Lex; $$= create_func_cast($3, $5, lex->length, lex->dec, lex->charset); - if (!$$) + if ($$ == NULL) MYSQL_YYABORT; } | CASE_SYM opt_expr when_list opt_else END - { $$= new Item_func_case(* $3, $2, $4 ); } + { + $$= new Item_func_case(* $3, $2, $4 ); + if ($$ == NULL) + MYSQL_YYABORT; + } | CONVERT_SYM '(' expr ',' cast_type ')' { $$= create_func_cast($3, $5, Lex->length, Lex->dec, Lex->charset); - if (!$$) + if ($$ == NULL) MYSQL_YYABORT; } | CONVERT_SYM '(' expr USING charset_name ')' - { $$= new Item_func_conv_charset($3,$5); } + { + $$= new Item_func_conv_charset($3,$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | DEFAULT '(' simple_ident ')' { if ($3->is_splocal()) @@ -4842,9 +5123,15 @@ simple_expr: MYSQL_YYABORT; } $$= new Item_default_value(Lex->current_context(), $3); + if ($$ == NULL) + MYSQL_YYABORT; } | VALUES '(' simple_ident_nospvar ')' - { $$= new Item_insert_value(Lex->current_context(), $3); } + { + $$= new Item_insert_value(Lex->current_context(), $3); + if ($$ == NULL) + MYSQL_YYABORT; + } | FUNC_ARG0 '(' ')' { if (!$1.symbol->create_func) @@ -4855,6 +5142,8 @@ simple_expr: MYSQL_YYABORT; } $$= ((Item*(*)(void))($1.symbol->create_func))(); + if ($$ == NULL) + MYSQL_YYABORT; } | FUNC_ARG1 '(' expr ')' { @@ -4866,6 +5155,8 @@ simple_expr: MYSQL_YYABORT; } $$= ((Item*(*)(Item*))($1.symbol->create_func))($3); + if ($$ == NULL) + MYSQL_YYABORT; } | FUNC_ARG2 '(' expr ',' expr ')' { @@ -4877,6 +5168,8 @@ simple_expr: MYSQL_YYABORT; } $$= ((Item*(*)(Item*,Item*))($1.symbol->create_func))($3,$5); + if ($$ == NULL) + MYSQL_YYABORT; } | FUNC_ARG3 '(' expr ',' expr ',' expr ')' { @@ -4888,106 +5181,264 @@ simple_expr: MYSQL_YYABORT; } $$= ((Item*(*)(Item*,Item*,Item*))($1.symbol->create_func))($3,$5,$7); + if ($$ == NULL) + MYSQL_YYABORT; } | ADDDATE_SYM '(' expr ',' expr ')' - { $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 0);} + { + $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 0); + if ($$ == NULL) + MYSQL_YYABORT; + } | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')' - { $$= new Item_date_add_interval($3, $6, $7, 0); } + { + $$= new Item_date_add_interval($3, $6, $7, 0); + if ($$ == NULL) + MYSQL_YYABORT; + } | REPEAT_SYM '(' expr ',' expr ')' - { $$= new Item_func_repeat($3,$5); } + { + $$= new Item_func_repeat($3,$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | ATAN '(' expr ')' - { $$= new Item_func_atan($3); } + { + $$= new Item_func_atan($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | ATAN '(' expr ',' expr ')' - { $$= new Item_func_atan($3,$5); } + { + $$= new Item_func_atan($3,$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | CHAR_SYM '(' expr_list ')' - { $$= new Item_func_char(*$3); } + { + $$= new Item_func_char(*$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | CHAR_SYM '(' expr_list USING charset_name ')' - { $$= new Item_func_char(*$3, $5); } + { + $$= new Item_func_char(*$3, $5); + if ($$ == NULL) + MYSQL_YYABORT; + } | CHARSET '(' expr ')' - { $$= new Item_func_charset($3); } + { + $$= new Item_func_charset($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | COALESCE '(' expr_list ')' - { $$= new Item_func_coalesce(* $3); } + { + $$= new Item_func_coalesce(* $3); + if ($$ == NULL) + MYSQL_YYABORT; + } | COLLATION_SYM '(' expr ')' - { $$= new Item_func_collation($3); } + { + $$= new Item_func_collation($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | CONCAT '(' expr_list ')' - { $$= new Item_func_concat(* $3); } + { + $$= new Item_func_concat(* $3); + if ($$ == NULL) + MYSQL_YYABORT; + } | CONCAT_WS '(' expr ',' expr_list ')' - { $5->push_front($3); $$= new Item_func_concat_ws(*$5); } + { + $5->push_front($3); + $$= new Item_func_concat_ws(*$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | CONVERT_TZ_SYM '(' expr ',' expr ',' expr ')' { if (Lex->add_time_zone_tables_to_query_tables(YYTHD)) MYSQL_YYABORT; $$= new Item_func_convert_tz($3, $5, $7); + if ($$ == NULL) + MYSQL_YYABORT; } | CURDATE optional_braces - { $$= new Item_func_curdate_local(); Lex->safe_to_cache_query=0; } + { + $$= new Item_func_curdate_local(); + if ($$ == NULL) + MYSQL_YYABORT; + Lex->safe_to_cache_query=0; + } | CURTIME optional_braces - { $$= new Item_func_curtime_local(); Lex->safe_to_cache_query=0; } + { + $$= new Item_func_curtime_local(); + if ($$ == NULL) + MYSQL_YYABORT; + Lex->safe_to_cache_query=0; + } | CURTIME '(' expr ')' { $$= new Item_func_curtime_local($3); + if ($$ == NULL) + MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | CURRENT_USER optional_braces { $$= new Item_func_current_user(Lex->current_context()); + if ($$ == NULL) + MYSQL_YYABORT; Lex->safe_to_cache_query= 0; } | DATE_ADD_INTERVAL '(' expr ',' interval_expr interval ')' - { $$= new Item_date_add_interval($3,$5,$6,0); } + { + $$= new Item_date_add_interval($3,$5,$6,0); + if ($$ == NULL) + MYSQL_YYABORT; + } | DATE_SUB_INTERVAL '(' expr ',' interval_expr interval ')' - { $$= new Item_date_add_interval($3,$5,$6,1); } + { + $$= new Item_date_add_interval($3,$5,$6,1); + if ($$ == NULL) + MYSQL_YYABORT; + } | DATABASE '(' ')' { $$= new Item_func_database(); + if ($$ == NULL) + MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | DATE_SYM '(' expr ')' - { $$= new Item_date_typecast($3); } + { + $$= new Item_date_typecast($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | DAY_SYM '(' expr ')' - { $$= new Item_func_dayofmonth($3); } + { + $$= new Item_func_dayofmonth($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | ELT_FUNC '(' expr ',' expr_list ')' - { $5->push_front($3); $$= new Item_func_elt(*$5); } + { + $5->push_front($3); + $$= new Item_func_elt(*$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | MAKE_SET_SYM '(' expr ',' expr_list ')' - { $$= new Item_func_make_set($3, *$5); } + { + $$= new Item_func_make_set($3, *$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | ENCRYPT '(' expr ')' { $$= new Item_func_encrypt($3); + if ($$ == NULL) + MYSQL_YYABORT; Lex->uncacheable(UNCACHEABLE_RAND); } - | ENCRYPT '(' expr ',' expr ')' { $$= new Item_func_encrypt($3,$5); } + | ENCRYPT '(' expr ',' expr ')' + { + $$= new Item_func_encrypt($3,$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | DECODE_SYM '(' expr ',' TEXT_STRING_literal ')' - { $$= new Item_func_decode($3,$5.str); } + { + $$= new Item_func_decode($3,$5.str); + if ($$ == NULL) + MYSQL_YYABORT; + } | ENCODE_SYM '(' expr ',' TEXT_STRING_literal ')' - { $$= new Item_func_encode($3,$5.str); } + { + $$= new Item_func_encode($3,$5.str); + if ($$ == NULL) + MYSQL_YYABORT; + } | DES_DECRYPT_SYM '(' expr ')' - { $$= new Item_func_des_decrypt($3); } + { + $$= new Item_func_des_decrypt($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | DES_DECRYPT_SYM '(' expr ',' expr ')' - { $$= new Item_func_des_decrypt($3,$5); } + { + $$= new Item_func_des_decrypt($3,$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | DES_ENCRYPT_SYM '(' expr ')' - { $$= new Item_func_des_encrypt($3); } + { + $$= new Item_func_des_encrypt($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | DES_ENCRYPT_SYM '(' expr ',' expr ')' - { $$= new Item_func_des_encrypt($3,$5); } + { + $$= new Item_func_des_encrypt($3,$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | EXPORT_SET '(' expr ',' expr ',' expr ')' - { $$= new Item_func_export_set($3, $5, $7); } + { + $$= new Item_func_export_set($3, $5, $7); + if ($$ == NULL) + MYSQL_YYABORT; + } | EXPORT_SET '(' expr ',' expr ',' expr ',' expr ')' - { $$= new Item_func_export_set($3, $5, $7, $9); } + { + $$= new Item_func_export_set($3, $5, $7, $9); + if ($$ == NULL) + MYSQL_YYABORT; + } | EXPORT_SET '(' expr ',' expr ',' expr ',' expr ',' expr ')' - { $$= new Item_func_export_set($3, $5, $7, $9, $11); } + { + $$= new Item_func_export_set($3, $5, $7, $9, $11); + if ($$ == NULL) + MYSQL_YYABORT; + } | FORMAT_SYM '(' expr ',' NUM ')' - { $$= new Item_func_format($3,atoi($5.str)); } + { + $$= new Item_func_format($3,atoi($5.str)); + if ($$ == NULL) + MYSQL_YYABORT; + } | FROM_UNIXTIME '(' expr ')' - { $$= new Item_func_from_unixtime($3); } + { + $$= new Item_func_from_unixtime($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | FROM_UNIXTIME '(' expr ',' expr ')' { - $$= new Item_func_date_format (new Item_func_from_unixtime($3),$5,0); + Item *item= new Item_func_from_unixtime($3); + if (item == NULL) + MYSQL_YYABORT; + $$= new Item_func_date_format (item, $5, 0); + if ($$ == NULL) + MYSQL_YYABORT; } | FIELD_FUNC '(' expr ',' expr_list ')' - { $5->push_front($3); $$= new Item_func_field(*$5); } + { + $5->push_front($3); + $$= new Item_func_field(*$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | geometry_function { #ifdef HAVE_SPATIAL $$= $1; + /* $1 may be NULL, GEOM_NEW not tested for out of memory */ + if ($$ == NULL) + MYSQL_YYABORT; #else my_error(ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, sym_group_geom.needed_define); @@ -4995,16 +5446,36 @@ simple_expr: #endif } | GET_FORMAT '(' date_time_type ',' expr ')' - { $$= new Item_func_get_format($3, $5); } + { + $$= new Item_func_get_format($3, $5); + if ($$ == NULL) + MYSQL_YYABORT; + } | HOUR_SYM '(' expr ')' - { $$= new Item_func_hour($3); } + { + $$= new Item_func_hour($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | IF '(' expr ',' expr ',' expr ')' - { $$= new Item_func_if($3,$5,$7); } + { + $$= new Item_func_if($3,$5,$7); + if ($$ == NULL) + MYSQL_YYABORT; + } | INSERT '(' expr ',' expr ',' expr ',' expr ')' - { $$= new Item_func_insert($3,$5,$7,$9); } + { + $$= new Item_func_insert($3,$5,$7,$9); + if ($$ == NULL) + MYSQL_YYABORT; + } | interval_expr interval '+' expr /* we cannot put interval before - */ - { $$= new Item_date_add_interval($4,$1,$2,0); } + { + $$= new Item_date_add_interval($4,$1,$2,0); + if ($$ == NULL) + MYSQL_YYABORT; + } | interval_expr { if ($1->type() != Item::ROW_ITEM) @@ -5013,102 +5484,248 @@ simple_expr: MYSQL_YYABORT; } $$= new Item_func_interval((Item_row *)$1); + if ($$ == NULL) + MYSQL_YYABORT; } | LAST_INSERT_ID '(' ')' { $$= new Item_func_last_insert_id(); + if ($$ == NULL) + MYSQL_YYABORT; Lex->safe_to_cache_query= 0; } | LAST_INSERT_ID '(' expr ')' { $$= new Item_func_last_insert_id($3); + if ($$ == NULL) + MYSQL_YYABORT; Lex->safe_to_cache_query= 0; } | LEFT '(' expr ',' expr ')' - { $$= new Item_func_left($3,$5); } + { + $$= new Item_func_left($3,$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | LOCATE '(' expr ',' expr ')' - { $$= new Item_func_locate($5,$3); } + { + $$= new Item_func_locate($5,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | LOCATE '(' expr ',' expr ',' expr ')' - { $$= new Item_func_locate($5,$3,$7); } + { + $$= new Item_func_locate($5,$3,$7); + if ($$ == NULL) + MYSQL_YYABORT; + } | GREATEST_SYM '(' expr ',' expr_list ')' - { $5->push_front($3); $$= new Item_func_max(*$5); } + { + $5->push_front($3); + $$= new Item_func_max(*$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | LEAST_SYM '(' expr ',' expr_list ')' - { $5->push_front($3); $$= new Item_func_min(*$5); } + { + $5->push_front($3); + $$= new Item_func_min(*$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | LOG_SYM '(' expr ')' - { $$= new Item_func_log($3); } + { + $$= new Item_func_log($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | LOG_SYM '(' expr ',' expr ')' - { $$= new Item_func_log($3, $5); } + { + $$= new Item_func_log($3, $5); + if ($$ == NULL) + MYSQL_YYABORT; + } | MASTER_POS_WAIT '(' expr ',' expr ')' { $$= new Item_master_pos_wait($3, $5); + if ($$ == NULL) + MYSQL_YYABORT; Lex->safe_to_cache_query=0; - } + } | MASTER_POS_WAIT '(' expr ',' expr ',' expr ')' { $$= new Item_master_pos_wait($3, $5, $7); + if ($$ == NULL) + MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | MICROSECOND_SYM '(' expr ')' - { $$= new Item_func_microsecond($3); } + { + $$= new Item_func_microsecond($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | MINUTE_SYM '(' expr ')' - { $$= new Item_func_minute($3); } + { + $$= new Item_func_minute($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | MOD_SYM '(' expr ',' expr ')' - { $$ = new Item_func_mod( $3, $5); } + { + $$= new Item_func_mod( $3, $5); + if ($$ == NULL) + MYSQL_YYABORT; + } | MONTH_SYM '(' expr ')' - { $$= new Item_func_month($3); } + { + $$= new Item_func_month($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | NOW_SYM optional_braces - { $$= new Item_func_now_local(); Lex->safe_to_cache_query=0;} + { + $$= new Item_func_now_local(); + if ($$ == NULL) + MYSQL_YYABORT; + Lex->safe_to_cache_query=0; + } | NOW_SYM '(' expr ')' - { $$= new Item_func_now_local($3); Lex->safe_to_cache_query=0;} + { + $$= new Item_func_now_local($3); + if ($$ == NULL) + MYSQL_YYABORT; + Lex->safe_to_cache_query=0; + } | PASSWORD '(' expr ')' { $$= YYTHD->variables.old_passwords ? (Item *) new Item_func_old_password($3) : (Item *) new Item_func_password($3); + if ($$ == NULL) + MYSQL_YYABORT; } | OLD_PASSWORD '(' expr ')' - { $$= new Item_func_old_password($3); } + { + $$= new Item_func_old_password($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | POSITION_SYM '(' bit_expr IN_SYM expr ')' - { $$ = new Item_func_locate($5,$3); } + { + $$= new Item_func_locate($5,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | QUARTER_SYM '(' expr ')' - { $$ = new Item_func_quarter($3); } + { + $$= new Item_func_quarter($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | RAND '(' expr ')' - { $$= new Item_func_rand($3); Lex->uncacheable(UNCACHEABLE_RAND);} + { + $$= new Item_func_rand($3); + if ($$ == NULL) + MYSQL_YYABORT; + Lex->uncacheable(UNCACHEABLE_RAND); + } | RAND '(' ')' - { $$= new Item_func_rand(); Lex->uncacheable(UNCACHEABLE_RAND);} + { + $$= new Item_func_rand(); + if ($$ == NULL) + MYSQL_YYABORT; + Lex->uncacheable(UNCACHEABLE_RAND); + } | REPLACE '(' expr ',' expr ',' expr ')' - { $$= new Item_func_replace($3,$5,$7); } + { + $$= new Item_func_replace($3,$5,$7); + if ($$ == NULL) + MYSQL_YYABORT; + } | RIGHT '(' expr ',' expr ')' - { $$= new Item_func_right($3,$5); } + { + $$= new Item_func_right($3,$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | ROUND '(' expr ')' - { $$= new Item_func_round($3, new Item_int((char*)"0",0,1),0); } - | ROUND '(' expr ',' expr ')' { $$= new Item_func_round($3,$5,0); } + { + Item *item= new Item_int((char*)"0",0,1); + if (item == NULL) + MYSQL_YYABORT; + $$= new Item_func_round($3, item, 0); + if ($$ == NULL) + MYSQL_YYABORT; + } + | ROUND '(' expr ',' expr ')' + { + $$= new Item_func_round($3,$5,0); + if ($$ == NULL) + MYSQL_YYABORT; + } | ROW_COUNT_SYM '(' ')' { $$= new Item_func_row_count(); + if ($$ == NULL) + MYSQL_YYABORT; Lex->safe_to_cache_query= 0; } | SUBDATE_SYM '(' expr ',' expr ')' - { $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 1);} + { + $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 1); + if ($$ == NULL) + MYSQL_YYABORT; + } | SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')' - { $$= new Item_date_add_interval($3, $6, $7, 1); } + { + $$= new Item_date_add_interval($3, $6, $7, 1); + if ($$ == NULL) + MYSQL_YYABORT; + } | SECOND_SYM '(' expr ')' - { $$= new Item_func_second($3); } + { + $$= new Item_func_second($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | SUBSTRING '(' expr ',' expr ',' expr ')' - { $$= new Item_func_substr($3,$5,$7); } + { + $$= new Item_func_substr($3,$5,$7); + if ($$ == NULL) + MYSQL_YYABORT; + } | SUBSTRING '(' expr ',' expr ')' - { $$= new Item_func_substr($3,$5); } + { + $$= new Item_func_substr($3,$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | SUBSTRING '(' expr FROM expr FOR_SYM expr ')' - { $$= new Item_func_substr($3,$5,$7); } + { + $$= new Item_func_substr($3,$5,$7); + if ($$ == NULL) + MYSQL_YYABORT; + } | SUBSTRING '(' expr FROM expr ')' - { $$= new Item_func_substr($3,$5); } + { + $$= new Item_func_substr($3,$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | SUBSTRING_INDEX '(' expr ',' expr ',' expr ')' - { $$= new Item_func_substr_index($3,$5,$7); } + { + $$= new Item_func_substr_index($3,$5,$7); + if ($$ == NULL) + MYSQL_YYABORT; + } | SYSDATE optional_braces { if (global_system_variables.sysdate_is_now == 0) $$= new Item_func_sysdate_local(); else $$= new Item_func_now_local(); + if ($$ == NULL) + MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | SYSDATE '(' expr ')' @@ -5116,36 +5733,94 @@ simple_expr: if (global_system_variables.sysdate_is_now == 0) $$= new Item_func_sysdate_local($3); else $$= new Item_func_now_local($3); + if ($$ == NULL) + MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | TIME_SYM '(' expr ')' - { $$= new Item_time_typecast($3); } + { + $$= new Item_time_typecast($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | TIMESTAMP '(' expr ')' - { $$= new Item_datetime_typecast($3); } + { + $$= new Item_datetime_typecast($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | TIMESTAMP '(' expr ',' expr ')' - { $$= new Item_func_add_time($3, $5, 1, 0); } + { + $$= new Item_func_add_time($3, $5, 1, 0); + if ($$ == NULL) + MYSQL_YYABORT; + } | TIMESTAMP_ADD '(' interval_time_stamp ',' expr ',' expr ')' - { $$= new Item_date_add_interval($7,$5,$3,0); } + { + $$= new Item_date_add_interval($7,$5,$3,0); + if ($$ == NULL) + MYSQL_YYABORT; + } | TIMESTAMP_DIFF '(' interval_time_stamp ',' expr ',' expr ')' - { $$= new Item_func_timestamp_diff($5,$7,$3); } + { + $$= new Item_func_timestamp_diff($5,$7,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | TRIM '(' expr ')' - { $$= new Item_func_trim($3); } + { + $$= new Item_func_trim($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | TRIM '(' LEADING expr FROM expr ')' - { $$= new Item_func_ltrim($6,$4); } + { + $$= new Item_func_ltrim($6,$4); + if ($$ == NULL) + MYSQL_YYABORT; + } | TRIM '(' TRAILING expr FROM expr ')' - { $$= new Item_func_rtrim($6,$4); } + { + $$= new Item_func_rtrim($6,$4); + if ($$ == NULL) + MYSQL_YYABORT; + } | TRIM '(' BOTH expr FROM expr ')' - { $$= new Item_func_trim($6,$4); } + { + $$= new Item_func_trim($6,$4); + if ($$ == NULL) + MYSQL_YYABORT; + } | TRIM '(' LEADING FROM expr ')' - { $$= new Item_func_ltrim($5); } + { + $$= new Item_func_ltrim($5); + if ($$ == NULL) + MYSQL_YYABORT; + } | TRIM '(' TRAILING FROM expr ')' - { $$= new Item_func_rtrim($5); } + { + $$= new Item_func_rtrim($5); + if ($$ == NULL) + MYSQL_YYABORT; + } | TRIM '(' BOTH FROM expr ')' - { $$= new Item_func_trim($5); } + { + $$= new Item_func_trim($5); + if ($$ == NULL) + MYSQL_YYABORT; + } | TRIM '(' expr FROM expr ')' - { $$= new Item_func_trim($5,$3); } + { + $$= new Item_func_trim($5,$3); + if ($$ == NULL) + MYSQL_YYABORT; + } | TRUNCATE_SYM '(' expr ',' expr ')' - { $$= new Item_func_round($3,$5,1); } + { + $$= new Item_func_round($3,$5,1); + if ($$ == NULL) + MYSQL_YYABORT; + } | ident '.' ident '(' opt_expr_list ')' { LEX *lex= Lex; @@ -5158,6 +5833,8 @@ simple_expr: $$= new Item_func_sp(Lex->current_context(), name, *$5); else $$= new Item_func_sp(Lex->current_context(), name); + if ($$ == NULL) + MYSQL_YYABORT; lex->safe_to_cache_query=0; } | IDENT_sys '(' @@ -5298,47 +5975,110 @@ simple_expr: else $$= new Item_func_sp(Lex->current_context(), name); } - lex->safe_to_cache_query=0; + lex->safe_to_cache_query=0; + + if ($$ == NULL) + MYSQL_YYABORT; } | UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')' { $$= new Item_func_unique_users($3,atoi($5.str),atoi($7.str), * $9); + if ($$ == NULL) + MYSQL_YYABORT; } | UNIX_TIMESTAMP '(' ')' { $$= new Item_func_unix_timestamp(); + if ($$ == NULL) + MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | UNIX_TIMESTAMP '(' expr ')' - { $$= new Item_func_unix_timestamp($3); } + { + $$= new Item_func_unix_timestamp($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | USER '(' ')' - { $$= new Item_func_user(); Lex->safe_to_cache_query=0; } + { + $$= new Item_func_user(); + if ($$ == NULL) + MYSQL_YYABORT; + Lex->safe_to_cache_query=0; + } | UTC_DATE_SYM optional_braces - { $$= new Item_func_curdate_utc(); Lex->safe_to_cache_query=0;} + { + $$= new Item_func_curdate_utc(); + if ($$ == NULL) + MYSQL_YYABORT; + Lex->safe_to_cache_query=0; + } | UTC_TIME_SYM optional_braces - { $$= new Item_func_curtime_utc(); Lex->safe_to_cache_query=0;} + { + $$= new Item_func_curtime_utc(); + if ($$ == NULL) + MYSQL_YYABORT; + Lex->safe_to_cache_query=0; + } | UTC_TIMESTAMP_SYM optional_braces - { $$= new Item_func_now_utc(); Lex->safe_to_cache_query=0;} + { + $$= new Item_func_now_utc(); + if ($$ == NULL) + MYSQL_YYABORT; + Lex->safe_to_cache_query=0; + } | WEEK_SYM '(' expr ')' { - $$= new Item_func_week($3,new Item_int((char*) "0", - YYTHD->variables.default_week_format,1)); + Item *item= new Item_int((char*) "0", + YYTHD->variables.default_week_format, + 1); + if (item == NULL) + MYSQL_YYABORT; + $$= new Item_func_week($3, item); + if ($$ == NULL) + MYSQL_YYABORT; } | WEEK_SYM '(' expr ',' expr ')' - { $$= new Item_func_week($3,$5); } + { + $$= new Item_func_week($3,$5); + if ($$ == NULL) + MYSQL_YYABORT; + } | YEAR_SYM '(' expr ')' - { $$= new Item_func_year($3); } + { + $$= new Item_func_year($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | YEARWEEK '(' expr ')' - { $$= new Item_func_yearweek($3,new Item_int((char*) "0",0,1)); } + { + Item *item= new Item_int((char*) "0",0,1); + if (item == NULL) + MYSQL_YYABORT; + $$= new Item_func_yearweek($3, item); + if ($$ == NULL) + MYSQL_YYABORT; + } | YEARWEEK '(' expr ',' expr ')' - { $$= new Item_func_yearweek($3, $5); } + { + $$= new Item_func_yearweek($3, $5); + if ($$ == NULL) + MYSQL_YYABORT; + } | BENCHMARK_SYM '(' ulong_num ',' expr ')' { $$=new Item_func_benchmark($3,$5); + if ($$ == NULL) + MYSQL_YYABORT; Lex->uncacheable(UNCACHEABLE_SIDEEFFECT); } | EXTRACT_SYM '(' interval FROM expr ')' - { $$=new Item_extract( $3, $5); }; + { + $$=new Item_extract( $3, $5); + if ($$ == NULL) + MYSQL_YYABORT; + } + ; geometry_function: CONTAINS_SYM '(' expr ',' expr ')' @@ -5414,7 +6154,12 @@ udf_expr_list: ; udf_expr_list2: - { Select->expr_list.push_front(new List); } + { + List *list= new List; + if (list == NULL) + MYSQL_YYABORT; + Select->expr_list.push_front(list); + } udf_expr_list3 { $$= Select->expr_list.pop(); } ; @@ -5462,53 +6207,132 @@ udf_expr: ; sum_expr: - AVG_SYM '(' in_sum_expr ')' - { $$=new Item_sum_avg($3); } + AVG_SYM '(' in_sum_expr ')' + { + $$=new Item_sum_avg($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | AVG_SYM '(' DISTINCT in_sum_expr ')' - { $$=new Item_sum_avg_distinct($4); } + { + $$=new Item_sum_avg_distinct($4); + if ($$ == NULL) + MYSQL_YYABORT; + } | BIT_AND '(' in_sum_expr ')' - { $$=new Item_sum_and($3); } + { + $$=new Item_sum_and($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | BIT_OR '(' in_sum_expr ')' - { $$=new Item_sum_or($3); } + { + $$=new Item_sum_or($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | BIT_XOR '(' in_sum_expr ')' - { $$=new Item_sum_xor($3); } + { + $$=new Item_sum_xor($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | COUNT_SYM '(' opt_all '*' ')' - { $$=new Item_sum_count(new Item_int((int32) 0L,1)); } + { + Item *item= new Item_int((int32) 0L,1); + if (item == NULL) + MYSQL_YYABORT; + $$=new Item_sum_count(new Item_int((int32) 0L,1)); + if ($$ == NULL) + MYSQL_YYABORT; + } | COUNT_SYM '(' in_sum_expr ')' - { $$=new Item_sum_count($3); } + { + $$=new Item_sum_count($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | COUNT_SYM '(' DISTINCT { Select->in_sum_expr++; } expr_list { Select->in_sum_expr--; } ')' - { $$=new Item_sum_count_distinct(* $5); } + { + $$=new Item_sum_count_distinct(* $5); + if ($$ == NULL) + MYSQL_YYABORT; + } | GROUP_UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' in_sum_expr ')' - { $$= new Item_sum_unique_users($3,atoi($5.str),atoi($7.str),$9); } + { + $$= new Item_sum_unique_users($3,atoi($5.str),atoi($7.str),$9); + if ($$ == NULL) + MYSQL_YYABORT; + } | MIN_SYM '(' in_sum_expr ')' - { $$=new Item_sum_min($3); } + { + $$=new Item_sum_min($3); + if ($$ == NULL) + MYSQL_YYABORT; + } /* According to ANSI SQL, DISTINCT is allowed and has no sence inside MIN and MAX grouping functions; so MIN|MAX(DISTINCT ...) is processed like an ordinary MIN | MAX() */ | MIN_SYM '(' DISTINCT in_sum_expr ')' - { $$=new Item_sum_min($4); } + { + $$=new Item_sum_min($4); + if ($$ == NULL) + MYSQL_YYABORT; + } | MAX_SYM '(' in_sum_expr ')' - { $$=new Item_sum_max($3); } + { + $$=new Item_sum_max($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | MAX_SYM '(' DISTINCT in_sum_expr ')' - { $$=new Item_sum_max($4); } + { + $$=new Item_sum_max($4); + if ($$ == NULL) + MYSQL_YYABORT; + } | STD_SYM '(' in_sum_expr ')' - { $$=new Item_sum_std($3, 0); } + { + $$=new Item_sum_std($3, 0); + if ($$ == NULL) + MYSQL_YYABORT; + } | VARIANCE_SYM '(' in_sum_expr ')' - { $$=new Item_sum_variance($3, 0); } + { + $$=new Item_sum_variance($3, 0); + if ($$ == NULL) + MYSQL_YYABORT; + } | STDDEV_SAMP_SYM '(' in_sum_expr ')' - { $$=new Item_sum_std($3, 1); } + { + $$=new Item_sum_std($3, 1); + if ($$ == NULL) + MYSQL_YYABORT; + } | VAR_SAMP_SYM '(' in_sum_expr ')' - { $$=new Item_sum_variance($3, 1); } + { + $$=new Item_sum_variance($3, 1); + if ($$ == NULL) + MYSQL_YYABORT; + } | SUM_SYM '(' in_sum_expr ')' - { $$=new Item_sum_sum($3); } + { + $$=new Item_sum_sum($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | SUM_SYM '(' DISTINCT in_sum_expr ')' - { $$=new Item_sum_sum_distinct($4); } + { + $$=new Item_sum_sum_distinct($4); + if ($$ == NULL) + MYSQL_YYABORT; + } | GROUP_CONCAT_SYM '(' opt_distinct { Select->in_sum_expr++; } expr_list opt_gorder_clause @@ -5519,6 +6343,8 @@ sum_expr: sel->in_sum_expr--; $$=new Item_func_group_concat(Lex->current_context(), $3, $5, sel->gorder_list, $7); + if ($$ == NULL) + MYSQL_YYABORT; $5->empty(); }; @@ -5541,12 +6367,16 @@ variable_aux: ident_or_text SET_VAR expr { $$= new Item_func_set_user_var($1, $3); + if ($$ == NULL) + MYSQL_YYABORT; LEX *lex= Lex; lex->uncacheable(UNCACHEABLE_RAND); } | ident_or_text { $$= new Item_func_get_user_var($1); + if ($$ == NULL) + MYSQL_YYABORT; LEX *lex= Lex; lex->uncacheable(UNCACHEABLE_RAND); } @@ -5567,11 +6397,14 @@ opt_distinct: |DISTINCT { $$ = 1; }; opt_gconcat_separator: - /* empty */ - { - $$= new (YYTHD->mem_root) String(",", 1, &my_charset_latin1); - } - | SEPARATOR_SYM text_string { $$ = $2; }; + /* empty */ + { + $$= new (YYTHD->mem_root) String(",", 1, &my_charset_latin1); + if ($$ == NULL) + MYSQL_YYABORT; + } + | SEPARATOR_SYM text_string { $$ = $2; } + ; opt_gorder_clause: @@ -5585,6 +6418,8 @@ opt_gorder_clause: select->gorder_list= (SQL_LIST*) sql_memdup((char*) &select->order_list, sizeof(st_sql_list)); + if (select->gorder_list == NULL) + MYSQL_YYABORT; select->order_list.empty(); }; @@ -5625,7 +6460,12 @@ opt_expr_list: ; expr_list: - { Select->expr_list.push_front(new List); } + { + List *list= new List; + if (list == NULL) + MYSQL_YYABORT; + Select->expr_list.push_front(list); + } expr_list2 { $$= Select->expr_list.pop(); }; @@ -5638,7 +6478,12 @@ ident_list_arg: | '(' ident_list ')' { $$= $2; }; ident_list: - { Select->expr_list.push_front(new List); } + { + List *list= new List; + if (list == NULL) + MYSQL_YYABORT; + Select->expr_list.push_front(new List); + } ident_list2 { $$= Select->expr_list.pop(); }; @@ -5658,6 +6503,8 @@ when_list: WHEN_SYM expr THEN_SYM expr { $$= new List; + if ($$ == NULL) + MYSQL_YYABORT; $$->push_back($2); $$->push_back($4); } @@ -6064,32 +6911,53 @@ key_list_or_empty: key_usage_list2: key_usage_list2 ',' ident - { Select-> - interval_list.push_back(new (YYTHD->mem_root) String((const char*) $3.str, $3.length, - system_charset_info)); } + { + String *s= new (YYTHD->mem_root) String((const char*) $3.str, + $3.length, + system_charset_info); + if (s == NULL) + MYSQL_YYABORT; + Select->interval_list.push_back(s); + } | ident - { Select-> - interval_list.push_back(new (YYTHD->mem_root) String((const char*) $1.str, $1.length, - system_charset_info)); } + { + String *s= new (YYTHD->mem_root) String((const char*) $1.str, + $1.length, + system_charset_info); + if (s == NULL) + MYSQL_YYABORT; + Select->interval_list.push_back(s); + } | PRIMARY_SYM - { Select-> - interval_list.push_back(new (YYTHD->mem_root) String("PRIMARY", 7, - system_charset_info)); }; + { + String *s= new (YYTHD->mem_root) String("PRIMARY", 7, + system_charset_info); + if (s == NULL) + MYSQL_YYABORT; + Select->interval_list.push_back(s); + } + ; using_list: ident { if (!($$= new List)) MYSQL_YYABORT; - $$->push_back(new (YYTHD->mem_root) - String((const char *) $1.str, $1.length, - system_charset_info)); + String *s= new (YYTHD->mem_root) String((const char *) $1.str, + $1.length, + system_charset_info); + if (s == NULL) + MYSQL_YYABORT; + $$->push_back(s); } | using_list ',' ident { - $1->push_back(new (YYTHD->mem_root) - String((const char *) $3.str, $3.length, - system_charset_info)); + String *s= new (YYTHD->mem_root) String((const char *) $3.str, + $3.length, + system_charset_info); + if (s == NULL) + MYSQL_YYABORT; + $1->push_back(s); $$= $1; }; @@ -6154,7 +7022,12 @@ table_alias: opt_table_alias: /* empty */ { $$=0; } | table_alias ident - { $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)); }; + { + $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)); + if ($$ == NULL) + MYSQL_YYABORT; + } + ; opt_all: /* empty */ @@ -6205,6 +7078,8 @@ opt_escape: $$= ((YYTHD->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) ? new Item_string("", 0, &my_charset_latin1) : new Item_string("\\", 1, &my_charset_latin1)); + if ($$ == NULL) + MYSQL_YYABORT; } ; @@ -6375,9 +7250,24 @@ limit_option: { ((Item_param *) $1)->limit_clause_param= TRUE; } - | ULONGLONG_NUM { $$= new Item_uint($1.str, $1.length); } - | LONG_NUM { $$= new Item_uint($1.str, $1.length); } - | NUM { $$= new Item_uint($1.str, $1.length); } + | ULONGLONG_NUM + { + $$= new Item_uint($1.str, $1.length); + if ($$ == NULL) + MYSQL_YYABORT; + } + | LONG_NUM + { + $$= new Item_uint($1.str, $1.length); + if ($$ == NULL) + MYSQL_YYABORT; + } + | NUM + { + $$= new Item_uint($1.str, $1.length); + if ($$ == NULL) + MYSQL_YYABORT; + } ; delete_limit_clause: @@ -6430,10 +7320,11 @@ procedure_clause: lex->proc_list.elements=0; lex->proc_list.first=0; lex->proc_list.next= (byte**) &lex->proc_list.first; - if (add_proc_to_list(lex->thd, new Item_field(&lex-> - current_select-> - context, - NULL,NULL,$2.str))) + Item_field *item= new Item_field(&lex->current_select->context, + NULL,NULL,$2.str); + if (item == NULL) + MYSQL_YYABORT; + if (add_proc_to_list(lex->thd, item)) MYSQL_YYABORT; Lex->uncacheable(UNCACHEABLE_SIDEEFFECT); } @@ -6484,13 +7375,20 @@ select_var_ident: { LEX *lex=Lex; if (lex->result) - ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($2,0,0,(enum_field_types)0)); + { + my_var *var= new my_var($2,0,0,(enum_field_types)0); + if (var == NULL) + MYSQL_YYABORT; + ((select_dumpvar *)lex->result)->var_list.push_back(var); + } else + { /* The parser won't create select_result instance only if it's an EXPLAIN. */ DBUG_ASSERT(lex->describe); + } } | ident_or_text { @@ -6504,12 +7402,12 @@ select_var_ident: } if (lex->result) { - my_var *var; - ((select_dumpvar *)lex->result)-> - var_list.push_back(var= new my_var($1,1,t->offset,t->type)); + my_var *var= new my_var($1,1,t->offset,t->type); + if (var == NULL) + MYSQL_YYABORT; + ((select_dumpvar *)lex->result)->var_list.push_back(var); #ifndef DBUG_OFF - if (var) - var->sp= lex->sphead; + var->sp= lex->sphead; #endif } else @@ -6594,11 +7492,13 @@ drop: | DROP INDEX_SYM ident ON table_ident {} { LEX *lex=Lex; + Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str); + if (ad == NULL) + MYSQL_YYABORT; lex->sql_command= SQLCOM_DROP_INDEX; lex->alter_info.reset(); lex->alter_info.flags= ALTER_DROP_INDEX; - lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY, - $3.str)); + lex->alter_info.drop_list.push_back(ad); if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL, TL_OPTION_UPDATING)) MYSQL_YYABORT; @@ -6623,6 +7523,8 @@ drop: lex->sql_command = SQLCOM_DROP_FUNCTION; lex->drop_if_exists= $3; spname= new sp_name($4, $6, true); + if (spname == NULL) + MYSQL_YYABORT; spname->init_qname(thd); lex->spname= spname; } @@ -6642,6 +7544,8 @@ drop: lex->sql_command = SQLCOM_DROP_FUNCTION; lex->drop_if_exists= $3; spname= new sp_name(db, $4, false); + if (spname == NULL) + MYSQL_YYABORT; spname->init_qname(thd); lex->spname= spname; } @@ -6856,7 +7760,12 @@ values: expr_or_default: expr { $$= $1;} - | DEFAULT {$$= new Item_default_value(Lex->current_context()); } + | DEFAULT + { + $$= new Item_default_value(Lex->current_context()); + if ($$ == NULL) + MYSQL_YYABORT; + } ; opt_insert_update: @@ -6974,15 +7883,21 @@ table_wild_list: table_wild_one: ident opt_wild opt_table_alias { - if (!Select->add_table_to_list(YYTHD, new Table_ident($1), $3, + Table_ident *ti= new Table_ident($1); + if (ti == NULL) + MYSQL_YYABORT; + if (!Select->add_table_to_list(YYTHD, ti, $3, TL_OPTION_UPDATING | TL_OPTION_ALIAS, Lex->lock_option)) MYSQL_YYABORT; } | ident '.' ident opt_wild opt_table_alias { + Table_ident *ti= new Table_ident(YYTHD, $1, $3, 0); + if (ti == NULL) + MYSQL_YYABORT; if (!Select->add_table_to_list(YYTHD, - new Table_ident(YYTHD, $1, $3, 0), + ti, $5, TL_OPTION_UPDATING | TL_OPTION_ALIAS, @@ -7360,8 +8275,12 @@ binlog_from: wild_and_where: /* empty */ | LIKE TEXT_STRING_sys - { Lex->wild= new (YYTHD->mem_root) String($2.str, $2.length, - system_charset_info); } + { + Lex->wild= new (YYTHD->mem_root) String($2.str, $2.length, + system_charset_info); + if (Lex->wild == NULL) + MYSQL_YYABORT; + } | WHERE expr { Select->where= $2; @@ -7409,7 +8328,14 @@ opt_describe_column: /* empty */ {} | text_string { Lex->wild= $1; } | ident - { Lex->wild= new (YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info); }; + { + Lex->wild= new (YYTHD->mem_root) String((const char*) $1.str, + $1.length, + system_charset_info); + if (Lex->wild == NULL) + MYSQL_YYABORT; + } + ; /* flush things */ @@ -7696,7 +8622,11 @@ fields_or_vars: field_or_var: simple_ident_nospvar {$$= $1;} | '@' ident_or_text - { $$= new Item_user_var_as_out_param($2); } + { + $$= new Item_user_var_as_out_param($2); + if ($$ == NULL) + MYSQL_YYABORT; + } ; opt_load_data_set_spec: @@ -7721,9 +8651,14 @@ text_literal: my_charset_is_ascii_based(cs_con))) tmp= $1; else - thd->convert_string(&tmp, cs_con, $1.str, $1.length, cs_cli); + { + if (thd->convert_string(&tmp, cs_con, $1.str, $1.length, cs_cli)) + MYSQL_YYABORT; + } $$= new Item_string(tmp.str, tmp.length, cs_con, DERIVATION_COERCIBLE, repertoire); + if ($$ == NULL) + MYSQL_YYABORT; } | NCHAR_STRING { @@ -7732,10 +8667,14 @@ text_literal: DBUG_ASSERT(my_charset_is_ascii_based(national_charset_info)); $$= new Item_string($1.str, $1.length, national_charset_info, DERIVATION_COERCIBLE, repertoire); + if ($$ == NULL) + MYSQL_YYABORT; } | UNDERSCORE_CHARSET TEXT_STRING { $$= new Item_string($2.str, $2.length, Lex->underscore_charset); + if ($$ == NULL) + MYSQL_YYABORT; ((Item_string*) $$)->set_repertoire_from_value(); } | text_literal TEXT_STRING_literal @@ -7757,28 +8696,37 @@ text_literal: ; text_string: - TEXT_STRING_literal - { $$= new (YYTHD->mem_root) String($1.str,$1.length,YYTHD->variables.collation_connection); } + TEXT_STRING_literal + { + $$= new (YYTHD->mem_root) String($1.str, + $1.length, + YYTHD->variables.collation_connection); + if ($$ == NULL) + MYSQL_YYABORT; + } | HEX_NUM { Item *tmp= new Item_hex_string($1.str, $1.length); + if (tmp == NULL) + MYSQL_YYABORT; /* it is OK only emulate fix_fields, because we need only value of constant */ - $$= tmp ? - tmp->quick_fix_field(), tmp->val_str((String*) 0) : - (String*) 0; + tmp->quick_fix_field(); + $$= tmp->val_str((String*) 0); } | BIN_NUM { Item *tmp= new Item_bin_string($1.str, $1.length); + if (tmp == NULL) + MYSQL_YYABORT; /* it is OK only emulate fix_fields, because we need only value of constant */ - $$= tmp ? tmp->quick_fix_field(), tmp->val_str((String*) 0) : - (String*) 0; + tmp->quick_fix_field(); + $$= tmp->val_str((String*) 0); } ; @@ -7820,76 +8768,121 @@ literal: | NULL_SYM { $$ = new Item_null(); + if ($$ == NULL) + MYSQL_YYABORT; YYTHD->m_lip->next_state=MY_LEX_OPERATOR_OR_IDENT; } - | FALSE_SYM { $$= new Item_int((char*) "FALSE",0,1); } - | TRUE_SYM { $$= new Item_int((char*) "TRUE",1,1); } - | HEX_NUM { $$ = new Item_hex_string($1.str, $1.length);} - | BIN_NUM { $$= new Item_bin_string($1.str, $1.length); } + | FALSE_SYM + { + $$= new Item_int((char*) "FALSE",0,1); + if ($$ == NULL) + MYSQL_YYABORT; + } + | TRUE_SYM + { + $$= new Item_int((char*) "TRUE",1,1); + if ($$ == NULL) + MYSQL_YYABORT; + } + | HEX_NUM + { + $$= new Item_hex_string($1.str, $1.length); + if ($$ == NULL) + MYSQL_YYABORT; + } + | BIN_NUM + { + $$= new Item_bin_string($1.str, $1.length); + if ($$ == NULL) + MYSQL_YYABORT; + } | UNDERSCORE_CHARSET HEX_NUM { Item *tmp= new Item_hex_string($2.str, $2.length); + if (tmp == NULL) + MYSQL_YYABORT; /* it is OK only emulate fix_fieds, because we need only value of constant */ - String *str= tmp ? - tmp->quick_fix_field(), tmp->val_str((String*) 0) : - (String*) 0; - $$= new Item_string(NULL, /* name will be set in select_item */ - str ? str->ptr() : "", - str ? str->length() : 0, - Lex->underscore_charset); - if (!$$ || !$$->check_well_formed_result(&$$->str_value, TRUE)) + tmp->quick_fix_field(); + String *str= tmp->val_str((String*) 0); + Item_string *item_str; + item_str= new Item_string(NULL, /* name will be set in select_item */ + str ? str->ptr() : "", + str ? str->length() : 0, + Lex->underscore_charset); + if (!item_str || + !item_str->check_well_formed_result(&item_str->str_value, TRUE)) { MYSQL_YYABORT; } - ((Item_string *) $$)->set_repertoire_from_value(); + item_str->set_repertoire_from_value(); + $$= item_str; } | UNDERSCORE_CHARSET BIN_NUM { Item *tmp= new Item_bin_string($2.str, $2.length); + if (tmp == NULL) + MYSQL_YYABORT; /* it is OK only emulate fix_fieds, because we need only value of constant */ - String *str= tmp ? - tmp->quick_fix_field(), tmp->val_str((String*) 0) : - (String*) 0; - $$= new Item_string(NULL, /* name will be set in select_item */ - str ? str->ptr() : "", - str ? str->length() : 0, - Lex->underscore_charset); - if (!$$ || !$$->check_well_formed_result(&$$->str_value, TRUE)) + tmp->quick_fix_field(); + String *str= tmp->val_str((String*) 0); + Item_string *item_str; + item_str= new Item_string(NULL, /* name will be set in select_item */ + str ? str->ptr() : "", + str ? str->length() : 0, + Lex->underscore_charset); + if (!item_str || + !item_str->check_well_formed_result(&item_str->str_value, TRUE)) { MYSQL_YYABORT; } + $$= item_str; } | DATE_SYM text_literal { $$ = $2; } | TIME_SYM text_literal { $$ = $2; } | TIMESTAMP text_literal { $$ = $2; }; NUM_literal: - NUM { int error; $$ = new Item_int($1.str, (longlong) my_strtoll10($1.str, NULL, &error), $1.length); } - | LONG_NUM { int error; $$ = new Item_int($1.str, (longlong) my_strtoll10($1.str, NULL, &error), $1.length); } - | ULONGLONG_NUM { $$ = new Item_uint($1.str, $1.length); } + NUM + { + int error; + $$ = new Item_int($1.str, + (longlong) my_strtoll10($1.str, NULL, &error), + $1.length); + } + | LONG_NUM + { + int error; + $$ = new Item_int($1.str, + (longlong) my_strtoll10($1.str, NULL, &error), + $1.length); + } + | ULONGLONG_NUM + { + $$= new Item_uint($1.str, $1.length); + } | DECIMAL_NUM - { - $$= new Item_decimal($1.str, $1.length, YYTHD->charset()); - if (YYTHD->net.report_error) - { - MYSQL_YYABORT; - } - } + { + $$= new Item_decimal($1.str, $1.length, YYTHD->charset()); + if (($$ == NULL) || (YYTHD->net.report_error)) + { + MYSQL_YYABORT; + } + } | FLOAT_NUM - { - $$ = new Item_float($1.str, $1.length); - if (YYTHD->net.report_error) - { - MYSQL_YYABORT; - } - } - ; + { + $$= new Item_float($1.str, $1.length); + if (($$ == NULL) || (YYTHD->net.report_error)) + { + MYSQL_YYABORT; + } + } + ; /********************************************************************** ** Creating different items. @@ -7904,6 +8897,8 @@ table_wild: { SELECT_LEX *sel= Select; $$ = new Item_field(Lex->current_context(), NullS, $1.str, "*"); + if ($$ == NULL) + MYSQL_YYABORT; sel->with_wild++; } | ident '.' ident '.' '*' @@ -7912,6 +8907,8 @@ table_wild: $$ = new Item_field(Lex->current_context(), (YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS : $1.str), $3.str,"*"); + if ($$ == NULL) + MYSQL_YYABORT; sel->with_wild++; } ; @@ -7941,11 +8938,12 @@ simple_ident: lip->tok_start_prev - lex->sphead->m_tmp_query, lip->tok_end - lip->tok_start_prev); + if (splocal == NULL) + MYSQL_YYABORT; #ifndef DBUG_OFF - if (splocal) - splocal->m_sp= lex->sphead; + splocal->m_sp= lex->sphead; #endif - $$ = (Item*) splocal; + $$= splocal; lex->safe_to_cache_query=0; } else @@ -7955,6 +8953,8 @@ simple_ident: sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(Lex->current_context(), NullS, NullS, $1.str) : (Item*) new Item_ref(Lex->current_context(), NullS, NullS, $1.str); + if ($$ == NULL) + MYSQL_YYABORT; } } | simple_ident_q { $$= $1; } @@ -7968,6 +8968,8 @@ simple_ident_nospvar: sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(Lex->current_context(), NullS, NullS, $1.str) : (Item*) new Item_ref(Lex->current_context(), NullS, NullS, $1.str); + if ($$ == NULL) + MYSQL_YYABORT; } | simple_ident_q { $$= $1; } ; @@ -8039,6 +9041,8 @@ simple_ident_q: sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(Lex->current_context(), NullS, $1.str, $3.str) : (Item*) new Item_ref(Lex->current_context(), NullS, $1.str, $3.str); + if ($$ == NULL) + MYSQL_YYABORT; } } | '.' ident '.' ident @@ -8055,6 +9059,8 @@ simple_ident_q: sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(Lex->current_context(), NullS, $2.str, $4.str) : (Item*) new Item_ref(Lex->current_context(), NullS, $2.str, $4.str); + if ($$ == NULL) + MYSQL_YYABORT; } | ident '.' ident '.' ident { @@ -8076,6 +9082,8 @@ simple_ident_q: (YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS : $1.str), $3.str, $5.str); + if ($$ == NULL) + MYSQL_YYABORT; }; @@ -8110,13 +9118,34 @@ field_ident: | '.' ident { $$=$2;} /* For Delphi */; table_ident: - ident { $$=new Table_ident($1); } - | ident '.' ident { $$=new Table_ident(YYTHD, $1,$3,0);} - | '.' ident { $$=new Table_ident($2);} /* For Delphi */ + ident + { + $$=new Table_ident($1); + if ($$ == NULL) + MYSQL_YYABORT; + } + | ident '.' ident + { + $$=new Table_ident(YYTHD, $1,$3,0); + if ($$ == NULL) + MYSQL_YYABORT; + } + | '.' ident + { + $$=new Table_ident($2); /* For Delphi */ + if ($$ == NULL) + MYSQL_YYABORT; + } ; table_ident_nodb: - ident { LEX_STRING db={(char*) any_db,3}; $$=new Table_ident(YYTHD, db,$1,0); } + ident + { + LEX_STRING db={(char*) any_db,3}; + $$=new Table_ident(YYTHD, db,$1,0); + if ($$ == NULL) + MYSQL_YYABORT; + } ; IDENT_sys: @@ -8140,8 +9169,11 @@ IDENT_sys: $$= $1; } else - thd->convert_string(&$$, system_charset_info, - $1.str, $1.length, thd->charset()); + { + if (thd->convert_string(&$$, system_charset_info, + $1.str, $1.length, thd->charset())) + MYSQL_YYABORT; + } } ; @@ -8152,8 +9184,11 @@ TEXT_STRING_sys: if (thd->charset_is_system_charset) $$= $1; else - thd->convert_string(&$$, system_charset_info, - $1.str, $1.length, thd->charset()); + { + if (thd->convert_string(&$$, system_charset_info, + $1.str, $1.length, thd->charset())) + MYSQL_YYABORT; + } } ; @@ -8164,8 +9199,11 @@ TEXT_STRING_literal: if (thd->charset_is_collation_connection) $$= $1; else - thd->convert_string(&$$, thd->variables.collation_connection, - $1.str, $1.length, thd->charset()); + { + if (thd->convert_string(&$$, thd->variables.collation_connection, + $1.str, $1.length, thd->charset())) + MYSQL_YYABORT; + } } ; @@ -8177,8 +9215,11 @@ TEXT_STRING_filesystem: if (thd->charset_is_character_set_filesystem) $$= $1; else - thd->convert_string(&$$, thd->variables.character_set_filesystem, - $1.str, $1.length, thd->charset()); + { + if (thd->convert_string(&$$, thd->variables.character_set_filesystem, + $1.str, $1.length, thd->charset())) + MYSQL_YYABORT; + } } ; @@ -8188,6 +9229,8 @@ ident: { THD *thd= YYTHD; $$.str= thd->strmake($1.str, $1.length); + if ($$.str == NULL) + MYSQL_YYABORT; $$.length= $1.length; } ; @@ -8198,6 +9241,8 @@ label_ident: { THD *thd= YYTHD; $$.str= thd->strmake($1.str, $1.length); + if ($$.str == NULL) + MYSQL_YYABORT; $$.length= $1.length; } ; @@ -8729,29 +9774,50 @@ sys_option_value: LEX *lex=Lex; if ($1) lex->option_type= $1; - lex->var_list.push_back(new set_var(lex->option_type, - find_sys_var("tx_isolation"), - &null_lex_str, - new Item_int((int32) $5))); + Item *item= new Item_int((int32) $5); + if (item == NULL) + MYSQL_YYABORT; + set_var *var= new set_var(lex->option_type, + find_sys_var("tx_isolation"), + &null_lex_str, + item); + if (var == NULL) + MYSQL_YYABORT; + lex->var_list.push_back(var); } ; option_value: '@' ident_or_text equal expr { - Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4))); + Item_func_set_user_var *item= new Item_func_set_user_var($2,$4); + if (item == NULL) + MYSQL_YYABORT; + set_var_user *var= new set_var_user(item); + if (var == NULL) + MYSQL_YYABORT; + Lex->var_list.push_back(var); } | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default { LEX *lex=Lex; - lex->var_list.push_back(new set_var($3, $4.var, &$4.base_name, $6)); + set_var *var= new set_var($3, $4.var, &$4.base_name, $6); + if (var == NULL) + MYSQL_YYABORT; + lex->var_list.push_back(var); } | charset old_or_new_charset_name_or_default { THD *thd= YYTHD; LEX *lex= Lex; $2= $2 ? $2: global_system_variables.character_set_client; - lex->var_list.push_back(new set_var_collation_client($2,thd->variables.collation_database,$2)); + set_var_collation_client *var; + var= new set_var_collation_client($2, + thd->variables.collation_database, + $2); + if (var == NULL) + MYSQL_YYABORT; + lex->var_list.push_back(var); } | NAMES_SYM equal expr { @@ -8779,7 +9845,11 @@ option_value: $3->name, $2->csname); MYSQL_YYABORT; } - lex->var_list.push_back(new set_var_collation_client($3,$3,$3)); + set_var_collation_client *var; + var= new set_var_collation_client($3,$3,$3); + if (var == NULL) + MYSQL_YYABORT; + lex->var_list.push_back(var); } | PASSWORD equal text_or_password { @@ -8800,11 +9870,17 @@ option_value: MYSQL_YYABORT; user->host=null_lex_str; user->user.str=thd->security_ctx->priv_user; - thd->lex->var_list.push_back(new set_var_password(user, $3)); + set_var_password *var= new set_var_password(user, $3); + if (var == NULL) + MYSQL_YYABORT; + thd->lex->var_list.push_back(var); } | PASSWORD FOR_SYM user equal text_or_password { - Lex->var_list.push_back(new set_var_password($3,$5)); + set_var_password *var= new set_var_password($3,$5); + if (var == NULL) + MYSQL_YYABORT; + Lex->var_list.push_back(var); } ; @@ -8918,11 +9994,15 @@ text_or_password: Item_func_old_password::alloc(YYTHD, $3.str) : Item_func_password::alloc(YYTHD, $3.str) : $3.str; + if ($$ == NULL) + MYSQL_YYABORT; } | OLD_PASSWORD '(' TEXT_STRING ')' { $$= $3.length ? Item_func_old_password::alloc(YYTHD, $3.str) : $3.str; + if ($$ == NULL) + MYSQL_YYABORT; } ; @@ -8930,9 +10010,24 @@ text_or_password: set_expr_or_default: expr { $$=$1; } | DEFAULT { $$=0; } - | ON { $$=new Item_string("ON", 2, system_charset_info); } - | ALL { $$=new Item_string("ALL", 3, system_charset_info); } - | BINARY { $$=new Item_string("binary", 6, system_charset_info); } + | ON + { + $$=new Item_string("ON", 2, system_charset_info); + if ($$ == NULL) + MYSQL_YYABORT; + } + | ALL + { + $$=new Item_string("ALL", 3, system_charset_info); + if ($$ == NULL) + MYSQL_YYABORT; + } + | BINARY + { + $$=new Item_string("binary", 6, system_charset_info); + if ($$ == NULL) + MYSQL_YYABORT; + } ; @@ -9033,7 +10128,10 @@ handler: } lex->sql_command = SQLCOM_HA_READ; lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */ - lex->current_select->select_limit= new Item_int((int32) 1); + Item *one= new Item_int((int32) 1); + if (one == NULL) + MYSQL_YYABORT; + lex->current_select->select_limit= one; lex->current_select->offset_limit= 0; if (!lex->current_select->add_table_to_list(lex->thd, $2, 0, 0)) MYSQL_YYABORT; @@ -9340,8 +10438,9 @@ grant_user: { char *buff= (char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1); - if (buff) - make_scrambled_password_323(buff, $4.str); + if (buff == NULL) + MYSQL_YYABORT; + make_scrambled_password_323(buff, $4.str); $1->password.str= buff; $1->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; } @@ -9349,8 +10448,9 @@ grant_user: { char *buff= (char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1); - if (buff) - make_scrambled_password(buff, $4.str); + if (buff == NULL) + MYSQL_YYABORT; + make_scrambled_password(buff, $4.str); $1->password.str= buff; $1->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH; } @@ -9379,6 +10479,8 @@ column_list_id: ident { String *new_str = new (YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info); + if (new_str == NULL) + MYSQL_YYABORT; List_iterator iter(Lex->columns); class LEX_COLUMN *point; LEX *lex=Lex; @@ -9392,7 +10494,12 @@ column_list_id: if (point) point->rights |= lex->which_columns; else - lex->columns.push_back(new LEX_COLUMN (*new_str,lex->which_columns)); + { + LEX_COLUMN *col= new LEX_COLUMN (*new_str,lex->which_columns); + if (col == NULL) + MYSQL_YYABORT; + lex->columns.push_back(col); + } } ; @@ -9806,13 +10913,17 @@ view_list_opt: view_list: ident { - Lex->view_list.push_back((LEX_STRING*) - sql_memdup(&$1, sizeof(LEX_STRING))); + LEX_STRING *ls= (LEX_STRING*) sql_memdup(&$1, sizeof(LEX_STRING)); + if (ls == NULL) + MYSQL_YYABORT; + Lex->view_list.push_back(ls); } | view_list ',' ident { - Lex->view_list.push_back((LEX_STRING*) - sql_memdup(&$3, sizeof(LEX_STRING))); + LEX_STRING *ls= (LEX_STRING*) sql_memdup(&$3, sizeof(LEX_STRING)); + if (ls == NULL) + MYSQL_YYABORT; + Lex->view_list.push_back(ls); } ; @@ -9985,6 +11096,8 @@ sf_tail: /* Order is important here: new - reset - init */ sp= new sp_head(); + if (sp == NULL) + MYSQL_YYABORT; sp->reset_thd_mem_root(thd); sp->init(lex); sp->init_sp_name(thd, lex->spname); diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc index 392db9224c3..4ebcf1c50af 100644 --- a/sql/thr_malloc.cc +++ b/sql/thr_malloc.cc @@ -21,10 +21,35 @@ extern "C" { void sql_alloc_error_handler(void) { - THD *thd=current_thd; - if (thd) // QQ; To be removed - thd->fatal_error(); /* purecov: inspected */ sql_print_error(ER(ER_OUT_OF_RESOURCES)); + + THD *thd=current_thd; + if (thd) + { + /* + This thread is Out Of Memory. + An OOM condition is a fatal error. + It should not be caught by error handlers in stored procedures. + Also, recording that SQL condition in the condition area could + cause more memory allocations, which in turn could raise more + OOM conditions, causing recursion in the error handling code itself. + As a result, my_error() should not be invoked, and the + thread diagnostics area is set to an error status directly. + The visible result for a client application will be: + - a query fails with an ER_OUT_OF_RESOURCES error, + returned in the error packet. + - SHOW ERROR/SHOW WARNINGS may be empty. + */ + + NET *net= &thd->net; + thd->fatal_error(); + if (!net->last_error[0]) // Return only first message + { + strmake(net->last_error, ER(ER_OUT_OF_RESOURCES), + sizeof(net->last_error)-1); + net->last_errno= ER_OUT_OF_RESOURCES; + } + } } } -- cgit v1.2.1 From a4ffb3f8661792651674dc02cdc78cac5349fe3c Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 23 Oct 2008 19:39:56 +0200 Subject: Merge fixes for bug#32167 and bug#37428 into 5.0.66sp1 --- include/my_sys.h | 1 + include/myisam.h | 4 ++++ myisam/mi_check.c | 6 ++--- myisam/mi_open.c | 42 +++++++++++++++++++++++++++------- myisam/mi_static.c | 9 ++++++++ myisam/myisamchk.c | 2 +- myisam/myisamdef.h | 4 +++- mysql-test/r/symlink.result | 2 -- mysql-test/r/udf.result | 6 +++++ mysql-test/t/symlink.test | 8 +++---- mysys/my_symlink.c | 55 ++++++++++++++++++++++++++------------------- mysys/thr_lock.c | 2 +- sql/mysql_priv.h | 6 +++++ sql/mysqld.cc | 22 +++++++++++++++--- sql/set_var.cc | 1 + sql/sql_parse.cc | 33 ++++++++++++++++----------- sql/sql_udf.cc | 26 ++++++++++++++++++--- sql/unireg.h | 3 +++ 18 files changed, 170 insertions(+), 62 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index db01223602d..5dc73bf84d9 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -574,6 +574,7 @@ extern int my_close(File Filedes,myf MyFlags); extern File my_dup(File file, myf MyFlags); extern int my_mkdir(const char *dir, int Flags, myf MyFlags); extern int my_readlink(char *to, const char *filename, myf MyFlags); +extern int my_is_symlink(const char *filename); extern int my_realpath(char *to, const char *filename, myf MyFlags); extern File my_create_with_symlink(const char *linkname, const char *filename, int createflags, int access_flags, diff --git a/include/myisam.h b/include/myisam.h index 61b9f39e63b..ad585f79608 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -267,6 +267,10 @@ extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user; extern my_off_t myisam_max_temp_length; extern ulong myisam_bulk_insert_tree_size, myisam_data_pointer_size; +/* usually used to check if a symlink points into the mysql data home */ +/* which is normally forbidden */ +extern int (*myisam_test_invalid_symlink)(const char *filename); + /* Prototypes for myisam-functions */ extern int mi_close(struct st_myisam_info *file); diff --git a/myisam/mi_check.c b/myisam/mi_check.c index daa5886f3ba..4f8883f377e 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1732,7 +1732,7 @@ err: DATA_TMP_EXT, share->base.raid_chunks, (param->testflag & T_BACKUP_DATA ? MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || - mi_open_datafile(info,share,-1)) + mi_open_datafile(info,share,name,-1)) got_error=1; } } @@ -2519,7 +2519,7 @@ err: DATA_TMP_EXT, share->base.raid_chunks, (param->testflag & T_BACKUP_DATA ? MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || - mi_open_datafile(info,share,-1)) + mi_open_datafile(info,share,name,-1)) got_error=1; } } @@ -3050,7 +3050,7 @@ err: DATA_TMP_EXT, share->base.raid_chunks, (param->testflag & T_BACKUP_DATA ? MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || - mi_open_datafile(info,share,-1)) + mi_open_datafile(info,share,name,-1)) got_error=1; } } diff --git a/myisam/mi_open.c b/myisam/mi_open.c index 6865708a941..8e2f61a3b4b 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -74,7 +74,7 @@ MI_INFO *test_if_reopen(char *filename) MI_INFO *mi_open(const char *name, int mode, uint open_flags) { - int lock_error,kfile,open_mode,save_errno,have_rtree=0; + int lock_error,kfile,open_mode,save_errno,have_rtree=0, realpath_err; uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys, key_parts,unique_key_parts,fulltext_keys,uniques; char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN], @@ -94,7 +94,16 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) head_length=sizeof(share_buff.state.header); bzero((byte*) &info,sizeof(info)); - my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,4),MYF(0)); + realpath_err= my_realpath(name_buff, + fn_format(org_name,name,"",MI_NAME_IEXT,4),MYF(0)); + if (my_is_symlink(org_name) && + (realpath_err || (*myisam_test_invalid_symlink)(name_buff))) + { + my_errno= HA_WRONG_CREATE_OPTION; + DBUG_RETURN (NULL); + } + + pthread_mutex_lock(&THR_LOCK_myisam); if (!(old_info=test_if_reopen(name_buff))) { @@ -463,7 +472,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) lock_error=1; /* Database unlocked */ } - if (mi_open_datafile(&info, share, -1)) + if (mi_open_datafile(&info, share, name, -1)) goto err; errpos=5; @@ -534,7 +543,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) my_errno=EACCES; /* Can't open in write mode */ goto err; } - if (mi_open_datafile(&info, share, old_info->dfile)) + if (mi_open_datafile(&info, share, name, old_info->dfile)) goto err; errpos=5; have_rtree= old_info->rtree_recursion_state != NULL; @@ -1191,12 +1200,30 @@ The argument file_to_dup is here for the future if there would on some OS exist a dup()-like call that would give us two different file descriptors. *************************************************************************/ -int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup __attribute__((unused))) +int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *org_name, + File file_to_dup __attribute__((unused))) { + char *data_name= share->data_file_name; + char real_data_name[FN_REFLEN]; + + if (org_name) + { + fn_format(real_data_name,org_name,"",MI_NAME_DEXT,4); + if (my_is_symlink(real_data_name)) + { + if (my_realpath(real_data_name, real_data_name, MYF(0)) || + (*myisam_test_invalid_symlink)(real_data_name)) + { + my_errno= HA_WRONG_CREATE_OPTION; + return 1; + } + data_name= real_data_name; + } + } #ifdef USE_RAID if (share->base.raid_type) { - info->dfile=my_raid_open(share->data_file_name, + info->dfile=my_raid_open(data_name, share->mode | O_SHARE, share->base.raid_type, share->base.raid_chunks, @@ -1205,8 +1232,7 @@ int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup __attr } else #endif - info->dfile=my_open(share->data_file_name, share->mode | O_SHARE, - MYF(MY_WME)); + info->dfile=my_open(data_name, share->mode | O_SHARE, MYF(MY_WME)); return info->dfile >= 0 ? 0 : 1; } diff --git a/myisam/mi_static.c b/myisam/mi_static.c index 21a25f66b7c..ab7d3dc592b 100644 --- a/myisam/mi_static.c +++ b/myisam/mi_static.c @@ -41,6 +41,15 @@ my_off_t myisam_max_temp_length= MAX_FILE_SIZE; ulong myisam_bulk_insert_tree_size=8192*1024; ulong myisam_data_pointer_size=4; + +static int always_valid(const char *filename __attribute__((unused))) +{ + return 0; +} + +int (*myisam_test_invalid_symlink)(const char *filename)= always_valid; + + /* read_vec[] is used for converting between P_READ_KEY.. and SEARCH_ Position is , == , >= , <= , > , < diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index d421bbc92ed..29fb2ea1a60 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -1039,7 +1039,7 @@ static int myisamchk(MI_CHECK *param, my_string filename) error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT, raid_chunks, MYF(0)); - if (mi_open_datafile(info,info->s, -1)) + if (mi_open_datafile(info,info->s, NULL, -1)) error=1; param->out_flag&= ~O_NEW_DATA; /* We are using new datafile */ param->read_cache.file=info->dfile; diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 1a04cbe74fc..4ebd5648d26 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -739,7 +739,9 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows); extern MI_INFO *test_if_reopen(char *filename); my_bool check_table_is_closed(const char *name, const char *where); -int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup); +int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *orn_name, + File file_to_dup); + int mi_open_keyfile(MYISAM_SHARE *share); void mi_setup_functions(register MYISAM_SHARE *share); diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 689aa724935..47901a5d896 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -57,8 +57,6 @@ t9 CREATE TABLE `t9` ( Got one of the listed errors Got one of the listed errors Got one of the listed errors -Got one of the listed errors -Got one of the listed errors alter table t9 rename mysqltest.t9; select count(*) from mysqltest.t9; count(*) diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result index a79be1c3189..92185962d1f 100644 --- a/mysql-test/r/udf.result +++ b/mysql-test/r/udf.result @@ -1,5 +1,7 @@ drop table if exists t1; CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB"; +Warnings: +Warning 1105 plugin_dir was not specified CREATE FUNCTION myfunc_double RETURNS REAL SONAME "UDF_EXAMPLE_LIB"; CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB"; ERROR HY000: Can't find function 'myfunc_nonexist' in library @@ -197,6 +199,8 @@ DROP FUNCTION avgcost; select * from mysql.func; name ret dl type CREATE FUNCTION is_const RETURNS STRING SONAME "UDF_EXAMPLE_LIB"; +Warnings: +Warning 1105 plugin_dir was not specified select IS_const(3); IS_const(3) const @@ -206,6 +210,8 @@ name ret dl type select is_const(3); ERROR 42000: FUNCTION test.is_const does not exist CREATE FUNCTION is_const RETURNS STRING SONAME "UDF_EXAMPLE_LIB"; +Warnings: +Warning 1105 plugin_dir was not specified select is_const(3) as const, is_const(3.14) as const, diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index 10d8f355c98..9478abe1224 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -71,8 +71,6 @@ drop table t1; SHOW CREATE TABLE t9; disable_query_log; ---error 1103,1103 -create table t1 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="tmp"; # Check that we cannot link over a table from another database. @@ -81,8 +79,9 @@ create database mysqltest; --error 1,1 create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="/this-dir-does-not-exist"; ---error 1103,1103 -create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="not-hard-path"; +# temporarily disabled as it returns different result in the embedded server +# --error 1210, 1210 +# create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="not-hard-path"; # Should fail becasue the file t9.MYI already exist in 'run' --error 1,1,1105 @@ -230,6 +229,7 @@ SET SESSION keep_files_on_create = TRUE; EOF --disable_abort_on_error --error 1 +--replace_result $MYSQLTEST_VARDIR . master-data/ '' CREATE TABLE t1 (a INT) ENGINE MYISAM; --error 0,1 --remove_file $MYSQLTEST_VARDIR/master-data/test/t1.MYD; diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c index 810c0c72632..7f2be5644e8 100644 --- a/mysys/my_symlink.c +++ b/mysys/my_symlink.c @@ -106,38 +106,47 @@ int my_symlink(const char *content, const char *linkname, myf MyFlags) #define BUFF_LEN FN_LEN #endif + +int my_is_symlink(const char *filename __attribute__((unused))) +{ +#if defined (HAVE_LSTAT) && defined (S_ISLNK) + struct stat stat_buff; + return !lstat(filename, &stat_buff) && S_ISLNK(stat_buff.st_mode); +#elif defined (_WIN32) + DWORD dwAttr = GetFileAttributes(filename); + return (dwAttr != INVALID_FILE_ATTRIBUTES) && + (dwAttr & FILE_ATTRIBUTE_REPARSE_POINT); +#else /* No symlinks */ + return 0; +#endif +} + + int my_realpath(char *to, const char *filename, myf MyFlags __attribute__((unused))) { #if defined(HAVE_REALPATH) && !defined(HAVE_purify) && !defined(HAVE_BROKEN_REALPATH) int result=0; char buff[BUFF_LEN]; - struct stat stat_buff; + char *ptr; DBUG_ENTER("my_realpath"); - if (!(MyFlags & MY_RESOLVE_LINK) || - (!lstat(filename,&stat_buff) && S_ISLNK(stat_buff.st_mode))) - { - char *ptr; - DBUG_PRINT("info",("executing realpath")); - if ((ptr=realpath(filename,buff))) - { + DBUG_PRINT("info",("executing realpath")); + if ((ptr=realpath(filename,buff))) strmake(to,ptr,FN_REFLEN-1); - } - else - { - /* - Realpath didn't work; Use my_load_path() which is a poor substitute - original name but will at least be able to resolve paths that starts - with '.'. - */ - DBUG_PRINT("error",("realpath failed with errno: %d", errno)); - my_errno=errno; - if (MyFlags & MY_WME) - my_error(EE_REALPATH, MYF(0), filename, my_errno); - my_load_path(to, filename, NullS); - result= -1; - } + else + { + /* + Realpath didn't work; Use my_load_path() which is a poor substitute + original name but will at least be able to resolve paths that starts + with '.'. + */ + DBUG_PRINT("error",("realpath failed with errno: %d", errno)); + my_errno=errno; + if (MyFlags & MY_WME) + my_error(EE_REALPATH, MYF(0), filename, my_errno); + my_load_path(to, filename, NullS); + result= -1; } DBUG_RETURN(result); #else diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 02c9f08c946..853e1f96b49 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -333,10 +333,10 @@ void thr_lock_init(THR_LOCK *lock) void thr_lock_delete(THR_LOCK *lock) { DBUG_ENTER("thr_lock_delete"); - VOID(pthread_mutex_destroy(&lock->mutex)); pthread_mutex_lock(&THR_LOCK_lock); thr_lock_thread_list=list_delete(thr_lock_thread_list,&lock->list); pthread_mutex_unlock(&THR_LOCK_lock); + pthread_mutex_destroy(&lock->mutex); DBUG_VOID_RETURN; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 607c06f55d2..cc82e60fc62 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1264,6 +1264,7 @@ extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH], mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[], mysql_unpacked_real_data_home[], def_ft_boolean_syntax[sizeof(ft_boolean_syntax)]; +extern int mysql_unpacked_real_data_home_len; #define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list)) extern MY_TMPDIR mysql_tmpdir_list; extern const char *command_name[]; @@ -1342,6 +1343,9 @@ extern char *default_tz_name; extern my_bool opt_large_pages; extern uint opt_large_page_size; +extern char *opt_plugin_dir_ptr; +extern char opt_plugin_dir[FN_REFLEN]; + extern MYSQL_LOG mysql_log,mysql_slow_log,mysql_bin_log; extern FILE *bootstrap_file; extern int bootstrap_error; @@ -1764,6 +1768,8 @@ inline void kill_delayed_threads(void) {} #define check_stack_overrun(A, B, C) 0 #endif +extern "C" int test_if_data_home_dir(const char *dir); + #endif /* MYSQL_CLIENT */ #endif diff --git a/sql/mysqld.cc b/sql/mysqld.cc index cdae94f0a61..757427f9fdf 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -324,6 +324,9 @@ arg_cmp_func Arg_comparator::comparator_matrix[5][2] = /* static variables */ +char opt_plugin_dir[FN_REFLEN]; +char *opt_plugin_dir_ptr; + static bool lower_case_table_names_used= 0; static bool volatile select_thread_in_use, signal_thread_in_use; static bool volatile ready_to_exit; @@ -477,6 +480,7 @@ char mysql_real_data_home[FN_REFLEN], *opt_init_file, *opt_tc_log_file, mysql_unpacked_real_data_home[FN_REFLEN], def_ft_boolean_syntax[sizeof(ft_boolean_syntax)]; +int mysql_unpacked_real_data_home_len; char *mysql_data_home= mysql_real_data_home; const key_map key_map_empty(0); key_map key_map_full(0); // Will be initialized later @@ -4984,6 +4988,7 @@ enum options_mysqld OPT_OLD_STYLE_USER_LIMITS, OPT_LOG_SLOW_ADMIN_STATEMENTS, OPT_TABLE_LOCK_WAIT_TIMEOUT, + OPT_PLUGIN_DIR, OPT_PORT_OPEN_TIMEOUT, OPT_MERGE, OPT_INNODB_ROLLBACK_ON_TIMEOUT, @@ -6216,6 +6221,10 @@ The minimum value for this variable is 4096.", (gptr*) &global_system_variables.optimizer_search_depth, (gptr*) &max_system_variables.optimizer_search_depth, 0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0}, + {"plugin_dir", OPT_PLUGIN_DIR, + "Directory for plugins.", + (gptr*) &opt_plugin_dir_ptr, (gptr*) &opt_plugin_dir_ptr, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE, "The size of the buffer that is allocated when preloading indexes", (gptr*) &global_system_variables.preload_buff_size, @@ -6696,6 +6705,7 @@ static void mysql_init_variables(void) /* Things reset to zero */ opt_skip_slave_start= opt_reckless_slave = 0; mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0; + myisam_test_invalid_symlink= test_if_data_home_dir; opt_log= opt_slow_log= 0; opt_update_log= 0; opt_bin_log= 0; @@ -7746,13 +7756,19 @@ static void fix_paths(void) pos[1]= 0; } convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS); - (void) fn_format(buff, mysql_real_data_home, "", "", - (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS)); - (void) unpack_dirname(mysql_unpacked_real_data_home, buff); + my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0)); + mysql_unpacked_real_data_home_len= strlen(mysql_unpacked_real_data_home); + if (mysql_unpacked_real_data_home[mysql_unpacked_real_data_home_len-1] == FN_LIBCHAR) + --mysql_unpacked_real_data_home_len; + + convert_dirname(language,language,NullS); (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home); (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home); + (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr : + "", ""); + opt_plugin_dir_ptr= opt_plugin_dir; char *sharedir=get_relative_path(SHAREDIR); if (test_if_hard_path(sharedir)) diff --git a/sql/set_var.cc b/sql/set_var.cc index 84766e511ca..6bc19f2e6eb 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1026,6 +1026,7 @@ struct show_var_st init_vars[]= { {sys_optimizer_search_depth.name,(char*) &sys_optimizer_search_depth, SHOW_SYS}, {"pid_file", (char*) pidfile_name, SHOW_CHAR}, + {"plugin_dir", (char*) opt_plugin_dir, SHOW_CHAR}, {"port", (char*) &mysqld_port, SHOW_INT}, {sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS}, {"protocol_version", (char*) &protocol_version, SHOW_INT}, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 62a5a79a833..d9339437f50 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -76,7 +76,6 @@ static void remove_escape(char *name); static bool append_file_to_dir(THD *thd, const char **filename_ptr, const char *table_name); static bool check_show_create_table_access(THD *thd, TABLE_LIST *table); -static bool test_if_data_home_dir(const char *dir); const char *any_db="*any*"; // Special symbol for check_access @@ -3044,13 +3043,13 @@ mysql_execute_command(THD *thd) if (test_if_data_home_dir(lex->create_info.data_file_name)) { - my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECORY"); + my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECTORY"); res= -1; break; } if (test_if_data_home_dir(lex->create_info.index_file_name)) { - my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECORY"); + my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECTORY"); res= -1; break; } @@ -7919,10 +7918,12 @@ bool check_string_length(LEX_STRING *str, const char *err_msg, 1 error */ -static bool test_if_data_home_dir(const char *dir) +C_MODE_START + +int test_if_data_home_dir(const char *dir) { - char path[FN_REFLEN], conv_path[FN_REFLEN]; - uint dir_len, home_dir_len= strlen(mysql_unpacked_real_data_home); + char path[FN_REFLEN]; + int dir_len; DBUG_ENTER("test_if_data_home_dir"); if (!dir) @@ -7930,21 +7931,27 @@ static bool test_if_data_home_dir(const char *dir) (void) fn_format(path, dir, "", "", (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS)); - dir_len= unpack_dirname(conv_path, dir); - - if (home_dir_len <= dir_len) + dir_len= strlen(path); + if (mysql_unpacked_real_data_home_len<= dir_len) { + if (dir_len > mysql_unpacked_real_data_home_len && + path[mysql_unpacked_real_data_home_len] != FN_LIBCHAR) + DBUG_RETURN(0); + if (lower_case_file_system) { - if (!my_strnncoll(default_charset_info, (const uchar*) conv_path, - home_dir_len, + if (!my_strnncoll(default_charset_info, (const uchar*) path, + mysql_unpacked_real_data_home_len, (const uchar*) mysql_unpacked_real_data_home, - home_dir_len)) + mysql_unpacked_real_data_home_len)) DBUG_RETURN(1); } - else if (!memcmp(conv_path, mysql_unpacked_real_data_home, home_dir_len)) + else if (!memcmp(path, mysql_unpacked_real_data_home, + mysql_unpacked_real_data_home_len)) DBUG_RETURN(1); } DBUG_RETURN(0); } +C_MODE_END + diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 34ca18d5c39..e3a0230d2fb 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -214,7 +214,17 @@ void udf_init() void *dl = find_udf_dl(tmp->dl); if (dl == NULL) { - if (!(dl = dlopen(tmp->dl, RTLD_NOW))) + char dlpath[FN_REFLEN]; + if (*opt_plugin_dir) + strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", tmp->dl, + NullS); + else + { + strxnmov(dlpath, sizeof(dlpath)-1, tmp->dl, NullS); + push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, + "plugin_dir was not specified"); + } + if (!(dl = dlopen(dlpath, RTLD_NOW))) { /* Print warning to log */ sql_print_error(ER(ER_CANT_OPEN_LIBRARY), tmp->dl,errno,dlerror()); @@ -443,8 +453,18 @@ int mysql_create_function(THD *thd,udf_func *udf) } if (!(dl = find_udf_dl(udf->dl))) { - DBUG_PRINT("info", ("Calling dlopen, udf->dl: %s", udf->dl)); - if (!(dl = dlopen(udf->dl, RTLD_NOW))) + char dlpath[FN_REFLEN]; + if (*opt_plugin_dir) + strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", udf->dl, + NullS); + else + { + strxnmov(dlpath, sizeof(dlpath)-1, udf->dl, NullS); + push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, + "plugin_dir was not specified"); + } + DBUG_PRINT("info", ("Calling dlopen, udf->dl: %s", dlpath)); + if (!(dl = dlopen(dlpath, RTLD_NOW))) { DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)", udf->dl,errno,dlerror())); diff --git a/sql/unireg.h b/sql/unireg.h index 1326b22c8c9..8e01e6222e6 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -35,6 +35,9 @@ #ifndef SHAREDIR #define SHAREDIR "share/" #endif +#ifndef PLUGINDIR +#define PLUGINDIR "lib/plugin" +#endif #define ER(X) errmesg[(X) - ER_ERROR_FIRST] #define ER_SAFE(X) (((X) >= ER_ERROR_FIRST && (X) <= ER_ERROR_LAST) ? ER(X) : "Invalid error code") -- cgit v1.2.1 From 0d0f4051348db7b28048e28824957f3329bbb41e Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 23 Oct 2008 21:46:46 +0200 Subject: Revert part of last change, it was not related to a security fix. --- mysys/thr_lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 853e1f96b49..02c9f08c946 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -333,10 +333,10 @@ void thr_lock_init(THR_LOCK *lock) void thr_lock_delete(THR_LOCK *lock) { DBUG_ENTER("thr_lock_delete"); + VOID(pthread_mutex_destroy(&lock->mutex)); pthread_mutex_lock(&THR_LOCK_lock); thr_lock_thread_list=list_delete(thr_lock_thread_list,&lock->list); pthread_mutex_unlock(&THR_LOCK_lock); - pthread_mutex_destroy(&lock->mutex); DBUG_VOID_RETURN; } -- cgit v1.2.1 From 52107b1c9bd0376c7ea6c4742edb290ecfc7efb2 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Fri, 24 Oct 2008 17:34:17 +0200 Subject: Fix a "configure" syntax error. It had been introduced with the patch for bug entry 37098 and affected runs "--without-server" only. configure.in: The conditional "BUILD_INNODB_TOOLS" is set depending on whether InnoDB is configured in the build, but that check is done only when building the server. For builds without the server it must also be set, or else "configure" reports an error. Set it to "false" in such builds, as this conditional only affects a tool that is useless in client installations. --- configure.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 85021ba8dde..f48f1544677 100644 --- a/configure.in +++ b/configure.in @@ -2728,8 +2728,10 @@ then AC_SUBST(THREAD_LOBJECTS) fi -if test "$with_server" != "no" +if test "$with_server" = "no" then + AM_CONDITIONAL([BUILD_INNODB_TOOLS], [false]) +else server_scripts="mysqld_safe mysql_install_db" sql_server_dirs="strings mysys dbug extra regex" -- cgit v1.2.1 From 8ec89d3b508d4e5e2336e52231746f8975cdf616 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 10 Nov 2008 21:18:04 +0100 Subject: Bug#36279 - mysql built with Visual Studio 2005 does not display japanese characters. Fix - removed obsolvete setlocale from my_init.c . In MBCS environments it caused unwanted character-to-byte translations in fputc() in client code and wrong output as result. --- mysys/my_init.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/mysys/my_init.c b/mysys/my_init.c index 8154a5fce51..07469e48e6c 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -305,8 +305,6 @@ static void my_win_init(void) const char *targetKey = "Software\\MySQL" ; DBUG_ENTER("my_win_init"); - setlocale(LC_CTYPE, ""); /* To get right sortorder */ - #if defined(_MSC_VER) #if _MSC_VER < 1300 /* -- cgit v1.2.1 From b02b90b72aa41ba794b9dc7745a9f2c980300352 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 11 Nov 2008 13:10:51 +0400 Subject: BUG#38842 - Fix for 25951 seems incorrect With fix for bug 25951 index hints are ignored for fulltext searches, as handling of fulltext indexes is different from handling regular indexes. Meaning it is not possible to implement true index hints support for fulltext indexes within the scope of current fulltext architecture. The problem is that prior to fix for bug 25951, some useful index hints still could be given for boolean mode searches. This patch implements special index hints support for fulltext indexes with the following characteristics: - all index hints are still ignored for NLQ mode searches - it cannot work without an index; - for 5.1 and up index hints FOR ORDER BY and FOR GROUP BY are still ignored for fulltext indexes; - boolean mode searches honor USE/FORCE/IGNORE INDEX hints; - as opposed to index hints for regular indexes, index hints for fulltext BOOLEAN mode searches affect the usage of the index for the whole query. mysql-test/r/fulltext.result: A test case for BUG#38842. mysql-test/t/fulltext.test: A test case for BUG#38842. sql/item_func.cc: For boolean mode searches, which can work without fulltext index, use keys_in_use_for_query bitmap instead of keys_in_use. The effect is that boolean mode searches now honor index hints. --- mysql-test/r/fulltext.result | 28 ++++++++++++++++++++++++++++ mysql-test/t/fulltext.test | 27 +++++++++++++++++++++++++++ sql/item_func.cc | 4 +++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 29fb430bb97..e73f8af405c 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -469,3 +469,31 @@ SELECT * FROM t1 WHERE MATCH(a) AGAINST ('"aaaa"' IN BOOLEAN MODE); a aaaaa aaaa DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(255), b INT, FULLTEXT(a), KEY(b)); +INSERT INTO t1 VALUES('test', 1),('test', 1),('test', 1),('test', 1), +('test', 1),('test', 2),('test', 3),('test', 4); +EXPLAIN SELECT * FROM t1 +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext b,a a 0 1 Using where +EXPLAIN SELECT * FROM t1 USE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext a a 0 1 Using where +EXPLAIN SELECT * FROM t1 FORCE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext a a 0 1 Using where +EXPLAIN SELECT * FROM t1 IGNORE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref b b 5 const 4 Using where +EXPLAIN SELECT * FROM t1 USE INDEX(b) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref b b 5 const 4 Using where +EXPLAIN SELECT * FROM t1 FORCE INDEX(b) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref b b 5 const 4 Using where +DROP TABLE t1; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index e5f1db14b7f..fa087d89efb 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -396,3 +396,30 @@ SELECT * FROM t1 WHERE MATCH(a) AGAINST ('"aaaa"' IN BOOLEAN MODE); DROP TABLE t1; # End of 4.1 tests + +# +# BUG#38842 - Fix for 25951 seems incorrect +# +CREATE TABLE t1 (a VARCHAR(255), b INT, FULLTEXT(a), KEY(b)); +INSERT INTO t1 VALUES('test', 1),('test', 1),('test', 1),('test', 1), + ('test', 1),('test', 2),('test', 3),('test', 4); + +EXPLAIN SELECT * FROM t1 +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 USE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 FORCE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 IGNORE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 USE INDEX(b) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 FORCE INDEX(b) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +DROP TABLE t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index e663e1fcf83..66fbf1eb4d2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5022,7 +5022,9 @@ bool Item_func_match::fix_index() for (keynr=0 ; keynr < table->s->keys ; keynr++) { if ((table->key_info[keynr].flags & HA_FULLTEXT) && - (table->s->keys_in_use.is_set(keynr))) + (flags & FT_BOOL ? table->keys_in_use_for_query.is_set(keynr) : + table->s->keys_in_use.is_set(keynr))) + { ft_to_key[fts]=keynr; ft_cnt[fts]=0; -- cgit v1.2.1 From eea579b5cde65ce84154faf346382a4c7dc49eab Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Tue, 11 Nov 2008 14:42:32 +0400 Subject: Bug#31435 ha_innodb.cc:3983: ulint convert_search_mode_to_innobase(ha_rkey_function): Asse I think we don't need to issue an error statement in the convert_search_mode_to_innobase(). Returning the PAGE_CUR_UNSUPP value is enough as allows to handle this case depending on the requirements. per-file comments: sql/ha_innodb.cc Bug#31435 ha_innodb.cc:3983: ulint convert_search_mode_to_innobase(ha_rkey_function): Asse no error issued in convert_search_mode_to_innobase. ha_innobase::records_in_range() returns HA_POS_ERROR if search mode isn't supported. --- sql/ha_innodb.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 1c0f8a6e9b3..611a1197215 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3723,7 +3723,6 @@ convert_search_mode_to_innobase( case HA_READ_MBR_WITHIN: case HA_READ_MBR_DISJOINT: case HA_READ_MBR_EQUAL: - my_error(ER_TABLE_CANT_HANDLE_SPKEYS, MYF(0)); return(PAGE_CUR_UNSUPP); /* do not use "default:" in order to produce a gcc warning: enumeration value '...' not handled in switch @@ -5204,7 +5203,7 @@ ha_innobase::records_in_range( mode2); } else { - n_rows = 0; + n_rows = HA_POS_ERROR; } dtuple_free_for_mysql(heap1); -- cgit v1.2.1 From 59f7518fdc9b69f593b86027cf85fbe0d74ce193 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 13 Nov 2008 17:06:48 +0400 Subject: Bug#39541 CHECK TABLE on information_schema myisam tables produces error issue 'The storage engine for the table doesn't support check' note for I_S tables mysql-test/r/mysqlcheck.result: test result mysql-test/t/mysqlcheck.test: test case sql/sql_table.cc: issue 'The storage engine for the table doesn't support check' note for I_S tables --- mysql-test/r/mysqlcheck.result | 6 ++++++ mysql-test/t/mysqlcheck.test | 7 +++++++ sql/sql_table.cc | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 8d7a2d41649..89f853e88f7 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -57,4 +57,10 @@ drop view v_bug25347; drop table t_bug25347; drop database d_bug25347; use test; +create view v1 as select * from information_schema.routines; +check table v1, information_schema.routines; +Table Op Msg_type Msg_text +test.v1 check status OK +information_schema.routines check note The storage engine for the table doesn't support check +drop view v1; End of 5.0 tests diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index 8d5e1a1c4c5..09ca98d01ad 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -58,4 +58,11 @@ drop table t_bug25347; drop database d_bug25347; use test; +# +# Bug#39541 CHECK TABLE on information_schema myisam tables produces error +# +create view v1 as select * from information_schema.routines; +check table v1, information_schema.routines; +drop view v1; + --echo End of 5.0 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1724513eb8f..8baeca9ccf7 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2322,6 +2322,12 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, goto send_result; } + if (table->schema_table) + { + result_code= HA_ADMIN_NOT_IMPLEMENTED; + goto send_result; + } + if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify) { char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE]; -- cgit v1.2.1 From 4c49e228bff07865b7a893984f93998834562722 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Thu, 13 Nov 2008 16:01:01 -0500 Subject: Bug#40645 Test main.federated_innodb does not always clean up after itself Reordered include files so that no mess will be left if this test is run without InnoDB Previously, this test would leave a database named 'federated' in such a case and would cause tests that examined existing databases to fail. --- mysql-test/t/federated_innodb.test | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mysql-test/t/federated_innodb.test b/mysql-test/t/federated_innodb.test index 772e37a2929..0617cb15d97 100644 --- a/mysql-test/t/federated_innodb.test +++ b/mysql-test/t/federated_innodb.test @@ -1,5 +1,10 @@ -source include/federated.inc; +# NOTE: Keep any include/ files that will kill / skip a test BEFORE any others +# having federated.inc before have_innodb.inc allows for an orphaned database +# that can cause other tests to fail. +# See Bug #40645 Test main.federated_innodb does not always clean up after itself + source include/have_innodb.inc; +source include/federated.inc; # # Bug#25513 Federated transaction failures -- cgit v1.2.1 From 3305a68bc23eb46fa48dd518b835a6b447afc942 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 14 Nov 2008 02:01:41 +0100 Subject: Bug #20430 mysqld.exe windows service stuck in "SERVICE_STOP_PENDING" status The problem appears to be a race condition, when service is being stopped right after startup. We set the service status to SERVICE_RUNNING way too early it cannot yet handle stop requests - initialization has not finished and hEventShutdown that signals server to stop is not yet created. If somebody issues "net stop MySQL" at this time, MySQL is not informed about the stop and continues to run as usual, while NTService::ServiceMain() stucks forever waiting for mysql's "main" thread to finish. Solution is to remain in SERVICE_START_PENDING status until after server initialization is fully complete and only then change the status to SERVICE_RUNNING. In SERVICE_START_PENDING we do not accept service control requests, i.e it is not possible to stop service in that time. sql/mysqld.cc: Set service status to running after all initialization is complete sql/nt_servc.cc: New method SetRunning() to be called by application to set service status to SERVICE_RUNNING when apllication has finished initialization. sql/nt_servc.h: New method SetRunning() to be called by application when initialization completes --- sql/mysqld.cc | 3 +++ sql/nt_servc.cc | 12 ++++++++---- sql/nt_servc.h | 14 +++++++++++++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c3e5449b22b..ba6c8c6169f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3840,6 +3840,9 @@ we force server id to 2, but this MySQL server will not act as a slave."); : mysqld_unix_port), mysqld_port, MYSQL_COMPILATION_COMMENT); +#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY) + Service.SetRunning(); +#endif #if defined(__NT__) || defined(HAVE_SMEM) handle_connections_methods(); diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index a04f284a3de..e570898f373 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -245,10 +245,6 @@ void NTService::ServiceMain(DWORD argc, LPTSTR *argv) if (!pService->StartService()) goto error; - // Check that the service is now running. - if (!pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0)) - goto error; - // wait for exit event WaitForSingleObject (pService->hExitEvent, INFINITE); @@ -264,6 +260,14 @@ error: return; } + +void NTService::SetRunning() +{ + if (pService) + pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0); +} + + /* ------------------------------------------------------------------------ StartService() - starts the appliaction thread -------------------------------------------------------------------------- */ diff --git a/sql/nt_servc.h b/sql/nt_servc.h index a3c12569114..9b689e434e1 100644 --- a/sql/nt_servc.h +++ b/sql/nt_servc.h @@ -56,7 +56,19 @@ class NTService BOOL IsService(LPCSTR ServiceName); BOOL got_service_option(char **argv, char *service_option); BOOL is_super_user(); - void Stop(void); //to be called from app. to stop service + + /* + SetRunning() is to be called by the application + when initialization completes and it can accept + stop request + */ + void SetRunning(void); + + /* + Stop() is to be called by the application to stop + the service + */ + void Stop(void); protected: LPSTR ServiceName; -- cgit v1.2.1 From 6558e18b2e40b14350b04ce7c91a580cba9da205 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 14 Nov 2008 11:40:46 +0400 Subject: Fix for bug#37527: mysqlcheck fails to report entire database when InnoDB frm file corruption Problem: mysqlcheck runs 'SHOW FULL TABLE' queries to get table lists. The query may fail for some reasons (e.g. null .frm file) then mysqlcheck doesn't process the database tables. Fix: try to run 'SHOW TABLES' if 'SHOW FULL TABLES' failed. client/mysqlcheck.c: Fix for bug#37527: mysqlcheck fails to report entire database when InnoDB frm file corruption - run "SHOW TABLES" query if "SHOW /*!50002 FULL*/ TABLES" failed; - print error info if both failed. mysql-test/r/mysqlcheck.result: Fix for bug#37527: mysqlcheck fails to report entire database when InnoDB frm file corruption - test result. mysql-test/t/mysqlcheck.test: Fix for bug#37527: mysqlcheck fails to report entire database when InnoDB frm file corruption - test case. --- client/mysqlcheck.c | 9 +++++++-- mysql-test/r/mysqlcheck.result | 7 +++++++ mysql-test/t/mysqlcheck.test | 20 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 473e172adf9..513d1974ed0 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -488,9 +488,14 @@ static int process_all_tables_in_db(char *database) LINT_INIT(res); if (use_db(database)) return 1; - if (mysql_query(sock, "SHOW /*!50002 FULL*/ TABLES") || - !((res= mysql_store_result(sock)))) + if ((mysql_query(sock, "SHOW /*!50002 FULL*/ TABLES") && + mysql_query(sock, "SHOW TABLES")) || + !(res= mysql_store_result(sock))) + { + my_printf_error(0, "Error: Couldn't get table list for database %s: %s", + MYF(0), database, mysql_error(sock)); return 1; + } num_columns= mysql_num_fields(res); diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 89f853e88f7..f8dad6a7769 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -63,4 +63,11 @@ Table Op Msg_type Msg_text test.v1 check status OK information_schema.routines check note The storage engine for the table doesn't support check drop view v1; +CREATE TABLE t1(a INT); +CREATE TABLE t2(a INT); +test.t1 +Error : Incorrect information in file: './test/t1.frm' +error : Corrupt +test.t2 OK +DROP TABLE t1, t2; End of 5.0 tests diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index 09ca98d01ad..91006d280a8 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -65,4 +65,24 @@ create view v1 as select * from information_schema.routines; check table v1, information_schema.routines; drop view v1; + +# +# Bug#37527: mysqlcheck fails to report entire database +# when frm file corruption +# +CREATE TABLE t1(a INT); +CREATE TABLE t2(a INT); +# backup then null t1.frm +--copy_file $MYSQLTEST_VARDIR/master-data/test/t1.frm $MYSQLTEST_VARDIR/master-data/test/t1.frm.bak +--remove_file $MYSQLTEST_VARDIR/master-data/test/t1.frm +--write_file $MYSQLTEST_VARDIR/master-data/test/t1.frm +EOF +--exec $MYSQL_CHECK test +# restore t1.frm +--remove_file $MYSQLTEST_VARDIR/master-data/test/t1.frm +--copy_file $MYSQLTEST_VARDIR/master-data/test/t1.frm.bak $MYSQLTEST_VARDIR/master-data/test/t1.frm +--remove_file $MYSQLTEST_VARDIR/master-data/test/t1.frm.bak +DROP TABLE t1, t2; + + --echo End of 5.0 tests -- cgit v1.2.1 From 914edc4219e300bd62b783ef93a19c06c8845366 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 14 Nov 2008 11:42:29 +0400 Subject: Test case for bug #34774: key prefix on text field in federated tables can cause server to crash! The bug will be fixed by patch for #34779: "crash in checksum table on federated tables with blobs containing nulls" Only a test case commited. mysql-test/r/federated.result: Test case for bug #34774: key prefix on text field in federated tables can cause server to crash! - test result. mysql-test/t/federated.test: Test case for bug #34774: key prefix on text field in federated tables can cause server to crash! - test case. --- mysql-test/r/federated.result | 9 +++++++++ mysql-test/t/federated.test | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result index 45b615864ac..f0de3e9b04a 100644 --- a/mysql-test/r/federated.result +++ b/mysql-test/r/federated.result @@ -2085,6 +2085,15 @@ Table Checksum test.t1 2465757603 DROP TABLE t1; DROP TABLE t1; +CREATE TABLE t1 (a TEXT, b TEXT, KEY(b(1))); +INSERT INTO t1 VALUES (NULL, NULL), (NULL, NULL), (NULL, NULL), (NULL, NULL); +CREATE TABLE t1 +(a TEXT, b TEXT, KEY(b(1))) ENGINE=FEDERATED +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1'; +SELECT t1.a FROM t1, t1 as t2 WHERE t2.b NOT LIKE t1.b; +a +DROP TABLE t1; +DROP TABLE t1; End of 5.0 tests SET @@GLOBAL.CONCURRENT_INSERT= @OLD_MASTER_CONCURRENT_INSERT; SET @@GLOBAL.CONCURRENT_INSERT= @OLD_SLAVE_CONCURRENT_INSERT; diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test index 8bbb87ccd9c..c977cb65fa0 100644 --- a/mysql-test/t/federated.test +++ b/mysql-test/t/federated.test @@ -1824,6 +1824,25 @@ DROP TABLE t1; connection master; DROP TABLE t1; + +# +# Bug #34774 key prefix on text field in federated tables can cause +# server to crash! +# +connection slave; +CREATE TABLE t1 (a TEXT, b TEXT, KEY(b(1))); +INSERT INTO t1 VALUES (NULL, NULL), (NULL, NULL), (NULL, NULL), (NULL, NULL); +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 + (a TEXT, b TEXT, KEY(b(1))) ENGINE=FEDERATED + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; +SELECT t1.a FROM t1, t1 as t2 WHERE t2.b NOT LIKE t1.b; +connection slave; +DROP TABLE t1; +connection master; +DROP TABLE t1; + connection default; --echo End of 5.0 tests -- cgit v1.2.1 From 8c9e7a64c55ecbb8da837f932203a697cac04c55 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Fri, 14 Nov 2008 21:25:57 +0400 Subject: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade Obsolete arc/ directory and view .frm file backup support has been removed by the patch for bug 17823. However, that bugfix caused a problem with "live downgrades" of the server: if we rename some view 4 times under 5.1.29/5.0.72 and then try to rename it under 5.1.28/5.0.70 on the same database, the server fails with a error: query 'RENAME TABLE ... TO ...' failed: 6: Error on delete of '....frm-0001' (Errcode: 2) Also .frm file of that view may be lost (renamed to .frm~). The server failed because it tried to rename latest 3 backup .frm files renaming the view: the server used an integer value of the "revision" field of .frm file to extract those file names. After the fix for bug 17823 those files were not created/maintained any more, however the "revision" field was incremented as usual. So, the server failed renaming non existent files. This fix solves the problem by removing the support for "revision" .frm file field: 1. New server silently ignores existent "revision" fields in old .frm files and never write it down; 2. Old server assumes, that missing "revision" field in new .frm files means default value of 0. 3. Accordingly to the fix for bug 17823 the new server drops arc/ directory on alter/rename view, so after "live downgrade" old server begins maintenance of the arc/ directory from scratch without conflicts with .frm files. sql/parse_file.cc: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade 1. static write_parameter(): the old_version parameter and the section for FILE_OPTIONS_REV have been re moved. 2. write_parameter(): the max_versions parameter has been removed; 3. sql_create_definition_file(): removal of dead code; 4. rename_in_schema_file(): revision and num_view_backups parameters and dead code have been removed; 5. File_parser::parse(): FILE_OPTIONS_REV section has been removed. sql/parse_file.h: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade 1. The FILE_OPTIONS_REV constant has been removed. 2. sql_create_definition_file and rename_in_schema_file functions: obsolete versions, revision and num_view_backups parameters have been removed. sql/sql_db.cc: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade Commentary update. sql/sql_trigger.cc: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade sql_create_definition_file() calls have been updates to new parameter lists. sql/sql_view.cc: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade 1. The mysql_create_view function code is used for both CREATE VIEW and ALTER queries, but query cache is necessary for ALTER command only. Check for a non first view revision has been replaced with a direct check for ALTER query. 2. The num_view_backups global constant has been removed. 3. view_parameters: the "revision" .frm field support has been removed. 4. sql_create_definition_file and rename_in_schema_file function calls have been updates to new parameter lists. sql/table.h: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade TABLE_LIST: the revision field has been removed. --- sql/parse_file.cc | 93 +++--------------------------------------------------- sql/parse_file.h | 6 ++-- sql/sql_db.cc | 2 -- sql/sql_trigger.cc | 8 ++--- sql/sql_view.cc | 33 ++++--------------- sql/table.h | 1 - 6 files changed, 17 insertions(+), 126 deletions(-) diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 2b947fcac4f..ade0709cf0d 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -88,7 +88,6 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s) file pointer to IO_CACHE structure for writing base pointer to data structure parameter pointer to parameter descriptor - old_version for returning back old version number value RETURN FALSE - OK @@ -96,8 +95,7 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s) */ static my_bool -write_parameter(IO_CACHE *file, gptr base, File_option *parameter, - ulonglong *old_version) +write_parameter(IO_CACHE *file, gptr base, File_option *parameter) { char num_buf[20]; // buffer for numeric operations // string for numeric operations @@ -125,15 +123,6 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter, DBUG_RETURN(TRUE); break; } - case FILE_OPTIONS_REV: - { - ulonglong *val_i= (ulonglong *)(base + parameter->offset); - *old_version= (*val_i)++; - num.set(*val_i, &my_charset_bin); - if (my_b_append(file, (const byte *)num.ptr(), num.length())) - DBUG_RETURN(TRUE); - break; - } case FILE_OPTIONS_TIMESTAMP: { /* string have to be allocated already */ @@ -205,7 +194,6 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter, base base address for parameter reading (structure like TABLE) parameters parameters description - max_versions number of versions to save RETURN FALSE - OK @@ -215,13 +203,11 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter, my_bool sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, const LEX_STRING *type, - gptr base, File_option *parameters, - uint max_versions) + gptr base, File_option *parameters) { File handler; IO_CACHE file; char path[FN_REFLEN+1]; // +1 to put temporary file name for sure - ulonglong old_version= ULONGLONG_MAX; int path_end; File_option *param; DBUG_ENTER("sql_create_definition_file"); @@ -255,7 +241,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, if (my_b_append(&file, (const byte *)param->name.str, param->name.length) || my_b_append(&file, (const byte *)STRING_WITH_LEN("=")) || - write_parameter(&file, base, param, &old_version) || + write_parameter(&file, base, param) || my_b_append(&file, (const byte *)STRING_WITH_LEN("\n"))) goto err_w_cache; } @@ -269,55 +255,6 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, } path[path_end]='\0'; -#ifdef FRM_ARCHIVE - // archive copies management: disabled unused feature (see bug #17823). - if (!access(path, F_OK)) - { - if (old_version != ULONGLONG_MAX && max_versions != 0) - { - // save backup - char path_arc[FN_REFLEN]; - // backup old version - char path_to[FN_REFLEN]; - - // check archive directory existence - fn_format(path_arc, "arc", dir->str, "", MY_UNPACK_FILENAME); - if (access(path_arc, F_OK)) - { - if (my_mkdir(path_arc, 0777, MYF(MY_WME))) - { - DBUG_RETURN(TRUE); - } - } - - my_snprintf(path_to, FN_REFLEN, "%s/%s-%04lu", - path_arc, file_name->str, (ulong) old_version); - if (my_rename(path, path_to, MYF(MY_WME))) - { - DBUG_RETURN(TRUE); - } - - // remove very old version - if (old_version > max_versions) - { - my_snprintf(path_to, FN_REFLEN, "%s/%s-%04lu", - path_arc, file_name->str, - (ulong)(old_version - max_versions)); - if (!access(path_arc, F_OK) && my_delete(path_to, MYF(MY_WME))) - { - DBUG_RETURN(TRUE); - } - } - } - else - { - if (my_delete(path, MYF(MY_WME))) // no backups - { - DBUG_RETURN(TRUE); - } - } - } -#endif//FRM_ARCHIVE { // rename temporary file @@ -346,8 +283,6 @@ err_w_file: schema name of given schema old_name original file name new_name new file name - revision revision number - num_view_backups number of backups RETURN 0 - OK @@ -356,8 +291,7 @@ err_w_file: */ my_bool rename_in_schema_file(THD *thd, const char *schema, const char *old_name, - const char *new_name, ulonglong revision, - uint num_view_backups) + const char *new_name) { char old_path[FN_REFLEN], new_path[FN_REFLEN], arc_path[FN_REFLEN]; @@ -376,23 +310,6 @@ my_bool rename_in_schema_file(THD *thd, strxnmov(arc_path, FN_REFLEN, mysql_data_home, "/", schema, "/arc", NullS); (void) unpack_filename(arc_path, arc_path); -#ifdef FRM_ARCHIVE - if (revision > 0 && !access(arc_path, F_OK)) - { - ulonglong limit= ((revision > num_view_backups) ? - revision - num_view_backups : 0); - for (; revision > limit ; revision--) - { - my_snprintf(old_path, FN_REFLEN, "%s/%s%s-%04lu", - arc_path, old_name, reg_ext, (ulong)revision); - (void) unpack_filename(old_path, old_path); - my_snprintf(new_path, FN_REFLEN, "%s/%s%s-%04lu", - arc_path, new_name, reg_ext, (ulong)revision); - (void) unpack_filename(new_path, new_path); - my_rename(old_path, new_path, MYF(0)); - } - } -#else//FRM_ARCHIVE { // remove obsolete 'arc' directory and files if any MY_DIR *new_dirp; if ((new_dirp = my_dir(arc_path, MYF(MY_DONT_SORT)))) @@ -401,7 +318,6 @@ my_bool rename_in_schema_file(THD *thd, (void) mysql_rm_arc_files(thd, new_dirp, arc_path); } } -#endif//FRM_ARCHIVE return 0; } @@ -838,7 +754,6 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, break; } case FILE_OPTIONS_ULONGLONG: - case FILE_OPTIONS_REV: if (!(eol= strchr(ptr, '\n'))) { my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), diff --git a/sql/parse_file.h b/sql/parse_file.h index ec920b58667..ad7d1629e0a 100644 --- a/sql/parse_file.h +++ b/sql/parse_file.h @@ -23,7 +23,6 @@ enum file_opt_type { FILE_OPTIONS_STRING, /* String (LEX_STRING) */ FILE_OPTIONS_ESTRING, /* Escaped string (LEX_STRING) */ FILE_OPTIONS_ULONGLONG, /* ulonglong parameter (ulonglong) */ - FILE_OPTIONS_REV, /* Revision version number (ulonglong) */ FILE_OPTIONS_TIMESTAMP, /* timestamp (LEX_STRING have to be allocated with length 20 (19+1) */ FILE_OPTIONS_STRLIST, /* list of escaped strings @@ -81,11 +80,10 @@ File_parser *sql_parse_prepare(const LEX_STRING *file_name, my_bool sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, const LEX_STRING *type, - gptr base, File_option *parameters, uint versions); + gptr base, File_option *parameters); my_bool rename_in_schema_file(THD *thd, const char *schema, const char *old_name, - const char *new_name, ulonglong revision, - uint num_view_backups); + const char *new_name); class File_parser: public Sql_alloc { diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 8fbb407555a..c3cf7429222 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -909,7 +909,6 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, /* .frm archive: Those archives are obsolete, but following code should exist to remove existent "arc" directories. - See #ifdef FRM_ARCHIVE directives for obsolete code. */ char newpath[FN_REFLEN]; MY_DIR *new_dirp; @@ -1069,7 +1068,6 @@ static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error) NOTE A support of "arc" directories is obsolete, however this function should exist to remove existent "arc" directories. - See #ifdef FRM_ARCHIVE directives for obsolete code. */ long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path) { diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index bead50e1da8..d3b5289cd68 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -479,7 +479,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, trigname.trigger_table.length= tables->table_name_length; if (sql_create_definition_file(&dir, &trigname_file, &trigname_file_type, - (gptr)&trigname, trigname_file_parameters, 0)) + (gptr)&trigname, trigname_file_parameters)) return 1; /* @@ -569,7 +569,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, /* Create trigger definition file. */ if (!sql_create_definition_file(&dir, &file, &triggers_file_type, - (gptr)this, triggers_file_parameters, 0)) + (gptr)this, triggers_file_parameters)) return 0; err_with_cleanup: @@ -656,7 +656,7 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db, file.str= file_buff; return sql_create_definition_file(&dir, &file, &triggers_file_type, - (gptr)triggers, triggers_file_parameters, 0); + (gptr)triggers, triggers_file_parameters); } @@ -1427,7 +1427,7 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name, trigname.trigger_table= *new_table_name; if (sql_create_definition_file(&dir, &trigname_file, &trigname_file_type, - (gptr)&trigname, trigname_file_parameters, 0)) + (gptr)&trigname, trigname_file_parameters)) return trigger; } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 8e6d3ed583a..f65a62bed75 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -660,7 +660,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, } VOID(pthread_mutex_unlock(&LOCK_open)); - if (view->revision != 1) + if (mode != VIEW_CREATE_NEW) query_cache_invalidate3(thd, view, 0); start_waiting_global_read_lock(thd); if (res) @@ -678,12 +678,8 @@ err: } -/* index of revision number in following table */ -static const int revision_number_position= 8; -/* index of last required parameter for making view */ -static const int required_view_parameters= 10; -/* number of backups */ -static const int num_view_backups= 3; +/* number of required parameters for making view */ +static const int required_view_parameters= 9; /* table of VIEW .frm field descriptors @@ -716,9 +712,6 @@ static File_option view_parameters[]= {{(char*) STRING_WITH_LEN("with_check_option")}, my_offsetof(TABLE_LIST, with_check), FILE_OPTIONS_ULONGLONG}, - {{(char*) STRING_WITH_LEN("revision")}, - my_offsetof(TABLE_LIST, revision), - FILE_OPTIONS_REV}, {{(char*) STRING_WITH_LEN("timestamp")}, my_offsetof(TABLE_LIST, timestamp), FILE_OPTIONS_TIMESTAMP}, @@ -880,18 +873,9 @@ loop_out: } /* - read revision number - TODO: read dependence list, too, to process cascade/restrict TODO: special cascade/restrict procedure for alter? */ - if (parser->parse((gptr)view, thd->mem_root, - view_parameters + revision_number_position, 1, - &file_parser_dummy_hook)) - { - error= thd->net.report_error? -1 : 0; - goto err; - } } else { @@ -933,7 +917,7 @@ loop_out: } if (sql_create_definition_file(&dir, &file, view_file_type, - (gptr)view, view_parameters, num_view_backups)) + (gptr)view, view_parameters)) { error= thd->net.report_error? -1 : 1; goto err; @@ -1868,8 +1852,7 @@ 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, - view_def.revision - 1, num_view_backups)) + if (rename_in_schema_file(thd, view->db, view->table_name, new_name)) goto err; strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", view->db, "/", NullS); @@ -1883,12 +1866,10 @@ mysql_rename_view(THD *thd, - file_buff); if (sql_create_definition_file(&pathstr, &file, view_file_type, - (gptr)&view_def, view_parameters, - num_view_backups)) + (gptr)&view_def, view_parameters)) { /* restore renamed view in case of error */ - rename_in_schema_file(thd, view->db, new_name, view->table_name, - view_def.revision - 1, num_view_backups); + rename_in_schema_file(thd, view->db, new_name, view->table_name); goto err; } } else diff --git a/sql/table.h b/sql/table.h index 08326e2fbe0..0884f5ba3d2 100644 --- a/sql/table.h +++ b/sql/table.h @@ -657,7 +657,6 @@ struct TABLE_LIST st_lex_user definer; /* definer of view */ ulonglong file_version; /* version of file's field set */ ulonglong updatable_view; /* VIEW can be updated */ - ulonglong revision; /* revision control number */ ulonglong algorithm; /* 0 any, 1 tmp tables , 2 merging */ ulonglong view_suid; /* view is suid (TRUE dy default) */ ulonglong with_check; /* WITH CHECK OPTION */ -- cgit v1.2.1 From 4b03b2c5ca6bc60dd4bbd4d5026e3f1c5f528ee0 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Mon, 17 Nov 2008 19:41:09 +0400 Subject: Bug#31616 div_precision_increment description looks wrong Item_func_div didn't calculate the precision of the result properly. The result of 5/0.0001 is 5000 so we have to add decimals of the divisor to the planned precision. per-file comments: mysql-test/r/type_newdecimal.result Bug#31616 div_precision_increment description looks wrong test result fixed mysql-test/t/type_newdecimal.test Bug#31616 div_precision_increment description looks wrong test case sql/item_func.cc Bug#31616 div_precision_increment description looks wrong precision must be increased with args[1]->decimals parameter --- mysql-test/r/type_newdecimal.result | 15 +++++++++++++++ mysql-test/t/type_newdecimal.test | 10 ++++++++++ sql/item_func.cc | 6 ++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 1bb07534a7f..90b6f524692 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -1524,4 +1524,19 @@ select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 * (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 * 1.01500000 * 1.01500000 * 0.99500000) 0.812988073953673124592306939480 +create table t1 as select 5.05 / 0.014; +Warnings: +Note 1265 Data truncated for column '5.05 / 0.014' at row 1 +show warnings; +Level Code Message +Note 1265 Data truncated for column '5.05 / 0.014' at row 1 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `5.05 / 0.014` decimal(10,6) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select * from t1; +5.05 / 0.014 +360.714286 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index c44abdb144e..a5331582df6 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1225,4 +1225,14 @@ DROP TABLE t1; select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 * 1.01500000 * 1.01500000 * 0.99500000); +# +# Bug #31616 div_precision_increment description looks wrong +# + +create table t1 as select 5.05 / 0.014; +show warnings; +show create table t1; +select * from t1; +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index e663e1fcf83..dfe1082fd73 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1316,8 +1316,10 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value) void Item_func_div::result_precision() { - uint arg_prec= args[0]->decimal_precision() + prec_increment; - uint precision=min(arg_prec, DECIMAL_MAX_PRECISION); + uint precision=min(args[0]->decimal_precision() + + args[1]->decimals + prec_increment, + DECIMAL_MAX_PRECISION); + /* Integer operations keep unsigned_flag if one of arguments is unsigned */ if (result_type() == INT_RESULT) unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag; -- cgit v1.2.1 From 5aa9b1bc1eb8c638d012e0e91392f76339f9ff6b Mon Sep 17 00:00:00 2001 From: V Narayanan Date: Tue, 18 Nov 2008 11:31:03 +0530 Subject: Bug#39616: Missing quotes from .CSV crashes server When a CSV file contained comma separated elements that were not enclosed in quotes, it was causing the mysql server to crash. The old algorithm that parsed the content of a row in mysql 5.0 was assuming that the values of the fields in a .CSV file will be enclosed in quotes and will be separated by commas. This was causing the old algorithm to fail when the content of the file resembled the following 3,"sans quotes" The CSV engine that is part of mysql 5.0 was expecting the above to be "3","sans quotes" The above is just one example of where the engine was failing for what would be recognized as a valid .CSV file content otherwise. The proposed fix changes the old algorithm being used to parse rows from the .CSV file to handle two separate cases 1) When the current field of the row is enclosed in quotes 2) When the current field of the row is not enclosed in quotes mysql-test/r/csv.result: Contains additional test output corresponding to the new tests added. mysql-test/t/csv.test: Contains additional tests for testing the behaviour of the CSV storage engine when the fields are not enclosed in quotes. sql/examples/ha_tina.cc: Changes the parsing logic of the rows in a CSV file to account for fields that are not enclosed in quotes. --- mysql-test/r/csv.result | 15 +++++++ mysql-test/t/csv.test | 43 +++++++++++++++++++++ sql/examples/ha_tina.cc | 101 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 138 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index dca4e349c8a..ac1aee6cc9a 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -5071,4 +5071,19 @@ select * from t1; a foo drop table t1; +create table bug39616_1(id int NOT NULL, d varchar(50) NOT NULL) ENGINE=csv; +select * from bug39616_1; +id d +1 integer sans quotes +1 string sans quotes +1 string end quotes" +1 quotes"in between" strings +1 Integer with quote and string with no quote +1 escape sequence + " \ \a within quotes +drop table bug39616_1; +create table bug39616_1(id int NOT NULL, d varchar(50) NOT NULL) ENGINE=csv; +select * from bug39616_1; +id d +drop table bug39616_1; End of 5.0 tests diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index db5cb92c3e6..72d61fc7781 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1460,4 +1460,47 @@ insert into t1 values(); select * from t1; drop table t1; +# +# Bug #39616 Missing quotes from .CSV crashes server +# +# Editing the .CSV file and leaving out quotes from around an integer field +# crashes the server. +# + +# +# Test for the integers and strings enclosed in quotes, not enclosed in quotes, +# \X characters. +# +create table bug39616_1(id int NOT NULL, d varchar(50) NOT NULL) ENGINE=csv; + +--remove_file $MYSQLTEST_VARDIR/master-data/test/bug39616_1.CSV +--write_file $MYSQLTEST_VARDIR/master-data/test/bug39616_1.CSV +1,"integer sans quotes" +1,string sans quotes +1,string end quotes" +1,quotes"in between" strings +"1",Integer with quote and string with no quote +1,"escape sequence \n \" \\ \r \a within quotes" +EOF + +select * from bug39616_1; + +drop table bug39616_1; + +# +# Test for he case when a field begins with a quote, but does not end in a +# quote. +# Note: This results in an empty set. +# +create table bug39616_1(id int NOT NULL, d varchar(50) NOT NULL) ENGINE=csv; + +--remove_file $MYSQLTEST_VARDIR/master-data/test/bug39616_1.CSV +--write_file $MYSQLTEST_VARDIR/master-data/test/bug39616_1.CSV +1,"string only at the beginning quotes +EOF + +select * from bug39616_1; + +drop table bug39616_1; + --echo End of 5.0 tests diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index 0b57fe86e62..aaaa3b8ffb4 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -416,37 +416,96 @@ int ha_tina::find_current_row(byte *buf) if ((end_ptr= find_eoln(share->mapped_file, current_position, share->file_stat.st_size)) == 0) DBUG_RETURN(HA_ERR_END_OF_FILE); + /* + Parse the line obtained using the following algorithm + + BEGIN + 1) Store the EOL (end of line) for the current row + 2) Until all the fields in the current query have not been + filled + 2.1) If the current character begins with a quote + 2.1.1) Until EOL has not been reached + a) If end of current field is reached, move + to next field and jump to step 2.3 + b) If current character begins with \\ handle + \\n, \\r, \\, \\" + c) else append the current character into the buffer + before checking that EOL has not been reached. + 2.2) If the current character does not begin with a quote + 2.2.1) Until EOL has not been reached + a) If the end of field has been reached move to the + next field and jump to step 2.3 + b) append the current character into the buffer + 2.3) Store the current field value and jump to 2) + TERMINATE + */ + for (Field **field=table->field ; *field ; field++) { buffer.length(0); - mapped_ptr++; // Increment past the first quote - for(;mapped_ptr != end_ptr; mapped_ptr++) + /* Handle the case where the first character begins with a quote */ + if (*mapped_ptr == '"') { - //Need to convert line feeds! - if (*mapped_ptr == '"' && - (((mapped_ptr[1] == ',') && (mapped_ptr[2] == '"')) || (mapped_ptr == end_ptr -1 ))) + /* Increment past the first quote */ + mapped_ptr++; + /* Loop through the row to extract the values for the current field */ + for(; mapped_ptr != end_ptr; mapped_ptr++) { - mapped_ptr += 2; // Move past the , and the " - break; - } - if (*mapped_ptr == '\\' && mapped_ptr != (end_ptr - 1)) - { - mapped_ptr++; - if (*mapped_ptr == 'r') - buffer.append('\r'); - else if (*mapped_ptr == 'n' ) - buffer.append('\n'); - else if ((*mapped_ptr == '\\') || (*mapped_ptr == '"')) - buffer.append(*mapped_ptr); - else /* This could only happed with an externally created file */ + /* check for end of the current field */ + if (*mapped_ptr == '"' && + (mapped_ptr[1] == ',' || mapped_ptr == end_ptr -1 )) { - buffer.append('\\'); + /* Move past the , and the " */ + mapped_ptr += 2; + break; + } + if (*mapped_ptr == '\\' && mapped_ptr != (end_ptr - 1)) + { + mapped_ptr++; + if (*mapped_ptr == 'r') + buffer.append('\r'); + else if (*mapped_ptr == 'n' ) + buffer.append('\n'); + else if ((*mapped_ptr == '\\') || (*mapped_ptr == '"')) + buffer.append(*mapped_ptr); + else /* This could only happed with an externally created file */ + { + buffer.append('\\'); + buffer.append(*mapped_ptr); + } + } + else + { + /* + If no last quote was found, but the end of row has been reached + it implies that there has been error. + */ + if (mapped_ptr == end_ptr -1) + DBUG_RETURN(HA_ERR_END_OF_FILE); + /* Store current character in the buffer for the field */ buffer.append(*mapped_ptr); } - } - else + } + } + else + { + /* Handle the case where the current row does not start with quotes */ + + /* Loop through the row to extract the values for the current field */ + for (; mapped_ptr != end_ptr; mapped_ptr++) + { + /* check for end of current field */ + if (*mapped_ptr == ',') + { + /* Increment past the current comma */ + mapped_ptr++; + break; + } + /* store the current character in the buffer for the field */ buffer.append(*mapped_ptr); + } } + /* Store the field value from the buffer */ (*field)->store(buffer.ptr(), buffer.length(), buffer.charset()); } next_position= (end_ptr - share->mapped_file)+1; -- cgit v1.2.1 -- cgit v1.2.1 From 50237690093fcb0d0810d95245047e16cc4d963f Mon Sep 17 00:00:00 2001 From: Matthias Leich Date: Wed, 19 Nov 2008 19:17:26 +0100 Subject: Fix for Bug#26890 main.multi_update times out The test itself is not faulty. The testcase timeout problem happens if this IMHO mid size resource (space in vardir, virtual memory, amount of disk I/O) consuming test meets a weak (excessive disk I/O caused by parallel applications or paging) testing box. The modifications: - Move the most time and disk I/O consuming subtest for Bug 1820 into its own script (multi_update2) This will reduce the likelihood that we exceed the testcase timeout. - Replace error numbers with error names - Minor improvements of the formatting - --- mysql-test/r/multi_update.result | 23 -------------- mysql-test/r/multi_update2.result | 25 +++++++++++++++ mysql-test/t/multi_update.test | 57 +++++++---------------------------- mysql-test/t/multi_update2-master.opt | 1 + mysql-test/t/multi_update2.test | 43 ++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 69 deletions(-) create mode 100644 mysql-test/r/multi_update2.result create mode 100644 mysql-test/t/multi_update2-master.opt create mode 100644 mysql-test/t/multi_update2.test diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 18394bfc88a..b85fb559e8c 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -378,29 +378,6 @@ where 0=1; delete t1, t2 from t2,t1 where t1.id1=t2.id2 and 0=1; drop table t1,t2; -create table t1 ( a int not null, b int not null) ; -alter table t1 add index i1(a); -delete from t1 where a > 2000000; -create table t2 like t1; -insert into t2 select * from t1; -select 't2 rows before small delete', count(*) from t1; -t2 rows before small delete count(*) -t2 rows before small delete 2000000 -delete t1,t2 from t1,t2 where t1.b=t2.a and t1.a < 2; -select 't2 rows after small delete', count(*) from t2; -t2 rows after small delete count(*) -t2 rows after small delete 1999999 -select 't1 rows after small delete', count(*) from t1; -t1 rows after small delete count(*) -t1 rows after small delete 1999999 -delete t1,t2 from t1,t2 where t1.b=t2.a and t1.a < 100*1000; -select 't2 rows after big delete', count(*) from t2; -t2 rows after big delete count(*) -t2 rows after big delete 1900001 -select 't1 rows after big delete', count(*) from t1; -t1 rows after big delete count(*) -t1 rows after big delete 1900001 -drop table t1,t2; CREATE TABLE t1 ( a int ); CREATE TABLE t2 ( a int ); DELETE t1 FROM t1, t2 AS t3; diff --git a/mysql-test/r/multi_update2.result b/mysql-test/r/multi_update2.result new file mode 100644 index 00000000000..3712e638f40 --- /dev/null +++ b/mysql-test/r/multi_update2.result @@ -0,0 +1,25 @@ +DROP TABLE IF EXISTS t1,t2; +CREATE TABLE t1 ( a INT NOT NULL, b INT NOT NULL) ; +# The protocolling of many inserts into t1 is suppressed. +ALTER TABLE t1 ADD INDEX i1(a); +DELETE FROM t1 WHERE a > 2000000; +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 SELECT * FROM t1; +SELECT 't2 rows before small delete', COUNT(*) FROM t1; +t2 rows before small delete COUNT(*) +t2 rows before small delete 2000000 +DELETE t1,t2 FROM t1,t2 WHERE t1.b=t2.a AND t1.a < 2; +SELECT 't2 rows after small delete', COUNT(*) FROM t2; +t2 rows after small delete COUNT(*) +t2 rows after small delete 1999999 +SELECT 't1 rows after small delete', COUNT(*) FROM t1; +t1 rows after small delete COUNT(*) +t1 rows after small delete 1999999 +DELETE t1,t2 FROM t1,t2 WHERE t1.b=t2.a AND t1.a < 100*1000; +SELECT 't2 rows after big delete', COUNT(*) FROM t2; +t2 rows after big delete COUNT(*) +t2 rows after big delete 1900001 +SELECT 't1 rows after big delete', COUNT(*) FROM t1; +t1 rows after big delete COUNT(*) +t1 rows after big delete 1900001 +DROP TABLE t1,t2; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 37cdfcf5f26..2bb3b17340c 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -9,9 +9,9 @@ drop table if exists t1,t2,t3; drop database if exists mysqltest; drop view if exists v1; ---error 0,1141,1147 +--error 0,ER_NONEXISTING_GRANT,ER_NONEXISTING_TABLE_GRANT revoke all privileges on mysqltest.t1 from mysqltest_1@localhost; ---error 0,1141,1147 +--error 0,ER_NONEXISTING_GRANT,ER_NONEXISTING_TABLE_GRANT revoke all privileges on mysqltest.* from mysqltest_1@localhost; delete from mysql.user where user=_binary'mysqltest_1'; --enable_warnings @@ -159,9 +159,9 @@ create table t2 (n int(10) not null primary key, d int(10)); insert into t1 values(1,1); insert into t2 values(1,10),(2,20); LOCK TABLES t1 write, t2 read; ---error 1099 +--error ER_TABLE_NOT_LOCKED_FOR_WRITE DELETE t1.*, t2.* FROM t1,t2 where t1.n=t2.n; ---error 1099 +--error ER_TABLE_NOT_LOCKED_FOR_WRITE UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n; UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n; unlock tables; @@ -182,7 +182,7 @@ create table t1 (n int(10), d int(10)); create table t2 (n int(10), d int(10)); insert into t1 values(1,1); insert into t2 values(1,10),(2,20); ---error 1175 +--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n; set sql_safe_updates=0; drop table t1,t2; @@ -195,7 +195,7 @@ set timestamp=1038000000; UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n; select n,d,unix_timestamp(t) from t1; select n,d,unix_timestamp(t) from t2; ---error 1064 +--error ER_PARSE_ERROR UPDATE t1,t2 SET 1=2 WHERE t1.n=t2.n; drop table t1,t2; set timestamp=0; @@ -322,41 +322,6 @@ delete t1, t2 from t2,t1 drop table t1,t2; -# -# Test for bug #1820. -# - -create table t1 ( a int not null, b int not null) ; ---disable_query_log -insert into t1 values (1,1),(2,2),(3,3),(4,4); -let $1=19; -set @d=4; -while ($1) -{ - eval insert into t1 select a+@d,b+@d from t1; - eval set @d=@d*2; - dec $1; -} - ---enable_query_log -alter table t1 add index i1(a); -delete from t1 where a > 2000000; -create table t2 like t1; -insert into t2 select * from t1; - -select 't2 rows before small delete', count(*) from t1; -delete t1,t2 from t1,t2 where t1.b=t2.a and t1.a < 2; -select 't2 rows after small delete', count(*) from t2; -select 't1 rows after small delete', count(*) from t1; - -## Try deleting many rows - -delete t1,t2 from t1,t2 where t1.b=t2.a and t1.a < 100*1000; -select 't2 rows after big delete', count(*) from t2; -select 't1 rows after big delete', count(*) from t1; - -drop table t1,t2; - # # Test alias (this is not correct in 4.0) # @@ -366,7 +331,7 @@ CREATE TABLE t2 ( a int ); DELETE t1 FROM t1, t2 AS t3; DELETE t4 FROM t1, t1 AS t4; DELETE t3 FROM t1 AS t3, t1 AS t4; ---error 1109 +--error ER_UNKNOWN_TABLE DELETE t1 FROM t1 AS t3, t2 AS t4; INSERT INTO t1 values (1),(2); INSERT INTO t2 values (1),(2); @@ -421,7 +386,7 @@ drop database mysqltest; create table t1 (a int, primary key (a)); create table t2 (a int, primary key (a)); create table t3 (a int, primary key (a)); --- error 1109 +-- error ER_UNKNOWN_TABLE delete t1,t3 from t1,t2 where t1.a=t2.a and t2.a=(select t3.a from t3 where t1.a=t3.a); drop table t1, t2, t3; @@ -430,9 +395,9 @@ drop table t1, t2, t3; # create table t1 (col1 int); create table t2 (col1 int); --- error 1093 +-- error ER_UPDATE_TABLE_USED update t1,t2 set t1.col1 = (select max(col1) from t1) where t1.col1 = t2.col1; --- error 1093 +-- error ER_UPDATE_TABLE_USED delete t1 from t1,t2 where t1.col1 < (select max(col1) from t1) and t1.col1 = t2.col1; drop table t1,t2; @@ -457,7 +422,7 @@ drop table t1, t2; # create table t1(a int); create table t2(a int); ---error 1093 +--error ER_UPDATE_TABLE_USED delete from t1,t2 using t1,t2 where t1.a=(select a from t1); drop table t1, t2; # End of 4.1 tests diff --git a/mysql-test/t/multi_update2-master.opt b/mysql-test/t/multi_update2-master.opt new file mode 100644 index 00000000000..9f1a29461ff --- /dev/null +++ b/mysql-test/t/multi_update2-master.opt @@ -0,0 +1 @@ +--set-variable=tmp_table_size=1024 diff --git a/mysql-test/t/multi_update2.test b/mysql-test/t/multi_update2.test new file mode 100644 index 00000000000..47f9bc7bad7 --- /dev/null +++ b/mysql-test/t/multi_update2.test @@ -0,0 +1,43 @@ +# +# Test of update statement that uses many tables. +# + +--disable_warnings +DROP TABLE IF EXISTS t1,t2; +--enable_warnings + +# +# Bug#1820 Rows not deleted from second table on multi-table delete +# + +CREATE TABLE t1 ( a INT NOT NULL, b INT NOT NULL) ; +--echo # The protocolling of many inserts into t1 is suppressed. +--disable_query_log +INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4); +let $1=19; +set @d=4; +while ($1) +{ + eval INSERT INTO t1 SELECT a+@d,b+@d FROM t1; + eval SET @d=@d*2; + dec $1; +} + +--enable_query_log +ALTER TABLE t1 ADD INDEX i1(a); +DELETE FROM t1 WHERE a > 2000000; +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 SELECT * FROM t1; + +SELECT 't2 rows before small delete', COUNT(*) FROM t1; +DELETE t1,t2 FROM t1,t2 WHERE t1.b=t2.a AND t1.a < 2; +SELECT 't2 rows after small delete', COUNT(*) FROM t2; +SELECT 't1 rows after small delete', COUNT(*) FROM t1; + +## Try deleting many rows + +DELETE t1,t2 FROM t1,t2 WHERE t1.b=t2.a AND t1.a < 100*1000; +SELECT 't2 rows after big delete', COUNT(*) FROM t2; +SELECT 't1 rows after big delete', COUNT(*) FROM t1; + +DROP TABLE t1,t2; -- cgit v1.2.1 From 82ee1ccba459150fb31ab457797d1f7bc6aee327 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Thu, 20 Nov 2008 14:08:36 +0400 Subject: Fix for bug#40875: Memory leak in FEDERATED handler Problem: memory leak occurs when we open a federated table that has its share in the hash. Fix: free not used memory. Note: the fix should NOT be merged to 5.1 (the code changed). sql/ha_federated.cc: Fix for bug#40875: Memory leak in FEDERATED handler - free memory (tmp_share.scheme) allocated in the parse_url() if it isn't used anymore. --- sql/ha_federated.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index b4788dd9c87..d4144a41a2a 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -1320,6 +1320,14 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table) thr_lock_init(&share->lock); pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST); } + else + { + /* + Free tmp_share.scheme allocated in the parse_url() + as we found share in the hash and tmp_share isn't needed anymore. + */ + my_free((gptr) tmp_share.scheme, MYF(MY_ALLOW_ZERO_PTR)); + } share->use_count++; pthread_mutex_unlock(&federated_mutex); -- cgit v1.2.1 From 2c4c0e04f6dcb794e4b7881e725b29a64071691b Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Thu, 20 Nov 2008 15:39:39 +0100 Subject: Bug#39591: Crash if table comment is longer than 62 characters It was possible to crash a mysqld build with EXTRA_DEBUG using CREATE TABLE ... COMMENT with a specially-crafted UTF-8 string. This CS removes the check that caused it since it no longer applies in current servers anyway, and adds comments instead to avoid future confusion. mysql-test/r/strict.result: Try to crash mysqld with a "suitable" multi-byte (3-byte UTF-8) string for a table comment. mysql-test/t/strict.test: Try to crash mysqld with a "suitable" multi-byte (3-byte UTF-8) string for a table comment. sql/unireg.cc: Talk at length about limits in .frm form-info, characters vs bytes, inlined vs extra-segement TABLE-COMMENTS, and the differences in 6.0+ vs <6.0 when it comes to UTF-8. Also, remove a check that no longer applies and that could lead to problems in pathological cases. --- mysql-test/r/strict.result | 7 +++++++ mysql-test/t/strict.test | 9 +++++++++ sql/unireg.cc | 26 ++++++++++++++++++-------- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index 34869862a63..c31b5ea2189 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -1348,6 +1348,13 @@ t1 CREATE TABLE `t1` ( `i` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='123456789*123456789*123456789*123456789*123456789*123456789*' drop table t1; +CREATE TABLE t3 (f1 INT) COMMENT 'כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן'; +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `f1` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן' +DROP TABLE t3; set sql_mode= 'traditional'; create table t1(col1 tinyint, col2 tinyint unsigned, col3 smallint, col4 smallint unsigned, diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index 2b71bf1093c..f66c2913ac9 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -1199,6 +1199,15 @@ comment '123456789*123456789*123456789*123456789*123456789*123456789*'; show create table t1; drop table t1; +# +# Bug #39591: Crash if table comment is longer than 62 characters +# + +#60 chars, 120 (+1) bytes (UTF-8 with 2-byte chars) +CREATE TABLE t3 (f1 INT) COMMENT 'כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן'; +SHOW CREATE TABLE t3; +DROP TABLE t3; + # # Bug #26359: Strings becoming truncated and converted to numbers under STRICT mode # diff --git a/sql/unireg.cc b/sql/unireg.cc index b581ad4655a..f20d3e8cc6b 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -143,6 +143,24 @@ bool mysql_create_frm(THD *thd, my_string file_name, (create_info->min_rows == 1) && (keys == 0)); int2store(fileinfo+28,key_info_length); + /* + This gives us the byte-position of the character at + (character-position, not byte-position) TABLE_COMMENT_MAXLEN. + The trick here is that character-positions start at 0, so the last + character in a maximum-allowed length string would be at char-pos + MAXLEN-1; charpos MAXLEN will be the position of the terminator. + Consequently, bytepos(charpos(MAXLEN)) should be equal to + comment[length] (which should also be the terminator, or at least + the first byte after the payload in the strict sense). If this is + not so (bytepos(charpos(MAXLEN)) comes /before/ the end of the + string), the string is too long. + + For additional credit, realise that UTF-8 has 1-3 bytes before 6.0, + and 1-4 bytes in 6.0 (6.0 also has UTF-32). This means that the + inlined COMMENT supposedly does not exceed 60 character plus + terminator, vulgo, 181 bytes. + */ + tmp_len= system_charset_info->cset->charpos(system_charset_info, create_info->comment.str, create_info->comment.str + @@ -165,14 +183,6 @@ bool mysql_create_frm(THD *thd, my_string file_name, strmake((char*) forminfo+47, create_info->comment.str ? create_info->comment.str : "", create_info->comment.length); forminfo[46]=(uchar) create_info->comment.length; -#ifdef EXTRA_DEBUG - /* - EXTRA_DEBUG causes strmake() to initialize its buffer behind the - payload with a magic value to detect wrong buffer-sizes. We - explicitly zero that segment again. - */ - memset((char*) forminfo+47 + forminfo[46], 0, 61 - forminfo[46]); -#endif if (my_pwrite(file,(byte*) fileinfo,64,0L,MYF_RW) || my_pwrite(file,(byte*) keybuff,key_info_length, (ulong) uint2korr(fileinfo+6),MYF_RW)) -- cgit v1.2.1 From d16a9a68fe887f16a16dad98ff46ee93743f9b84 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 21 Nov 2008 13:48:22 +0400 Subject: Fix for bug#36772: When using UTF8, CONVERT with GROUP BY returns truncated results Problem: performig conversion from {INT, DECIMAL, REAL} to CHAR we incorrectly set its max length in some cases that may lead to truncated results returned. Fix: properly set CONVERT({INT, DECIMAL, REAL}, CHAR) result's max length. mysql-test/r/ctype_utf8.result: Fix for bug#36772: When using UTF8, CONVERT with GROUP BY returns truncated results - test result. mysql-test/t/ctype_utf8.test: Fix for bug#36772: When using UTF8, CONVERT with GROUP BY returns truncated results - test case. sql/item_timefunc.cc: Fix for bug#36772: When using UTF8, CONVERT with GROUP BY returns truncated results - calculating Item_char_typecast::max_length use initial argument's charset mbmaxlen instead of from_cs->mbmaxlen, as from_cs may differ in some case (see comment above). --- mysql-test/r/ctype_utf8.result | 32 ++++++++++++++++++++++++++++++++ mysql-test/t/ctype_utf8.test | 17 +++++++++++++++++ sql/item_timefunc.cc | 13 ++++++++----- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 5ca1d578d2a..a4d7ca2558f 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1813,3 +1813,35 @@ select hex(_utf8 B'001111111111'); ERROR HY000: Invalid utf8 character string: 'FF' select (_utf8 X'616263FF'); ERROR HY000: Invalid utf8 character string: 'FF' +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL); +INSERT INTO t1 VALUES (70000, 1092), (70001, 1085), (70002, 1065); +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b; +CONVERT(a, CHAR) CONVERT(b, CHAR) +70002 1065 +70001 1085 +70000 1092 +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1; +CONVERT(a, CHAR) CONVERT(b, CHAR) +70000 1092 +70001 1085 +70002 1065 +ALTER TABLE t1 ADD UNIQUE (b); +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b; +CONVERT(a, CHAR) CONVERT(b, CHAR) +70002 1065 +70001 1085 +70000 1092 +DROP INDEX b ON t1; +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b; +CONVERT(a, CHAR) CONVERT(b, CHAR) +70002 1065 +70001 1085 +70000 1092 +ALTER TABLE t1 ADD INDEX (b); +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) from t1 GROUP BY b; +CONVERT(a, CHAR) CONVERT(b, CHAR) +70002 1065 +70001 1085 +70000 1092 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index d184200ad5a..5111660bcbe 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1437,3 +1437,20 @@ select hex(_utf8 X'616263FF'); select hex(_utf8 B'001111111111'); --error ER_INVALID_CHARACTER_STRING select (_utf8 X'616263FF'); + +# +# Bug #36772: When using UTF8, CONVERT with GROUP BY returns truncated results +# +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL); +INSERT INTO t1 VALUES (70000, 1092), (70001, 1085), (70002, 1065); +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b; +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1; +ALTER TABLE t1 ADD UNIQUE (b); +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b; +DROP INDEX b ON t1; +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b; +ALTER TABLE t1 ADD INDEX (b); +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) from t1 GROUP BY b; +DROP TABLE t1; + +--echo End of 5.0 tests diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 0cb3c963dad..e9e92952908 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2550,6 +2550,8 @@ void Item_char_typecast::fix_length_and_dec() and thus avoid unnecessary character set conversion. - If the argument is not a number, then from_cs is set to the argument's charset. + + Note (TODO): we could use repertoire technique here. */ from_cs= (args[0]->result_type() == INT_RESULT || args[0]->result_type() == DECIMAL_RESULT || @@ -2557,12 +2559,13 @@ void Item_char_typecast::fix_length_and_dec() (cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) : args[0]->collation.collation; charset_conversion= (cast_cs->mbmaxlen > 1) || - !my_charset_same(from_cs, cast_cs) && - from_cs != &my_charset_bin && - cast_cs != &my_charset_bin; + (!my_charset_same(from_cs, cast_cs) && + from_cs != &my_charset_bin && + cast_cs != &my_charset_bin); collation.set(cast_cs, DERIVATION_IMPLICIT); - char_length= (cast_length >= 0) ? cast_length : - args[0]->max_length/from_cs->mbmaxlen; + char_length= (cast_length >= 0) ? + cast_length : + args[0]->max_length / args[0]->collation.collation->mbmaxlen; max_length= char_length * cast_cs->mbmaxlen; } -- cgit v1.2.1 From 20689fa194ea629ea28bba286600172a97e4dfb4 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 21 Nov 2008 16:39:59 +0400 Subject: Bug#34760 Character set autodetection appears to fail the problem is the same as reported in bug#20835, so the fix is backport of bug#20835 patch. mysql-test/r/subselect.result: test result mysql-test/t/subselect.test: test case --- mysql-test/r/subselect.result | 15 +++++++++++++++ mysql-test/t/subselect.test | 19 ++++++++++++++++++- sql/item_cmpfunc.cc | 3 ++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index c5bae840214..6eeb652e3c1 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4407,4 +4407,19 @@ pk a 3 30 2 20 DROP TABLE t1,t2; +CREATE TABLE t1 (s1 char(1)); +INSERT INTO t1 VALUES ('a'); +SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1); +s1 +a +DROP TABLE t1; +CREATE TABLE t1(id BIGINT); +CREATE TABLE t2(id1 BIGINT, id2 BIGINT); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (2,1),(3,1); +SELECT * FROM t1 i WHERE 1 IN (SELECT l.id2 FROM t2 l WHERE i.id=l.id1); +id +2 +3 +DROP TABLE t1, t2; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 2dfad2c58dd..d28e31fb545 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3307,5 +3307,22 @@ SELECT * FROM t1 WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b); DROP TABLE t1,t2; ---echo End of 5.0 tests. +# +# Bug#20835 (literal string with =any values) +# +CREATE TABLE t1 (s1 char(1)); +INSERT INTO t1 VALUES ('a'); +SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1); +DROP TABLE t1; +# +# Bug#40519 Subselect query using bigint fails +# +CREATE TABLE t1(id BIGINT); +CREATE TABLE t2(id1 BIGINT, id2 BIGINT); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (2,1),(3,1); +SELECT * FROM t1 i WHERE 1 IN (SELECT l.id2 FROM t2 l WHERE i.id=l.id1); +DROP TABLE t1, t2; + +--echo End of 5.0 tests. diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 0410c781590..4bfae376acc 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1434,7 +1434,8 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref) } not_null_tables_cache= args[0]->not_null_tables(); with_sum_func= args[0]->with_sum_func; - const_item_cache= args[0]->const_item(); + if ((const_item_cache= args[0]->const_item())) + cache->store(args[0]); return 0; } -- cgit v1.2.1 From e964a00884db9e3bda6a391243c8d23d3e0d787b Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 24 Nov 2008 17:30:47 +0200 Subject: Bug #39656: Behaviour different for agg functions with & without where - ONLY_FULL_GROUP_BY The check for non-aggregated columns in queries with aggregate function, but without GROUP BY was treating all the parts of the query as if they are in the SELECT list. Fixed by ignoring the non-aggregated fields in the WHERE clause. mysql-test/r/func_group.result: Bug #39656: test case mysql-test/t/func_group.test: Bug #39656: test case sql/sql_select.cc: Bug #39656: ignore the new non-aggregated column refs in a WHERE by saving the state so far and then adding only the new values of the other parts of the bitmask. --- mysql-test/r/func_group.result | 23 +++++++++++++++++++++++ mysql-test/t/func_group.test | 29 +++++++++++++++++++++++++++++ sql/sql_select.cc | 10 ++++++++++ 3 files changed, 62 insertions(+) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 772e432355b..a7f4c58f4af 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1425,4 +1425,27 @@ SELECT AVG(a), CAST(AVG(a) AS DECIMAL) FROM t1; AVG(a) CAST(AVG(a) AS DECIMAL) 15 15 DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,1), (1,2), (1,3); +SET SQL_MODE='ONLY_FULL_GROUP_BY'; +SELECT COUNT(*) FROM t1; +COUNT(*) +3 +SELECT COUNT(*) FROM t1 where a=1; +COUNT(*) +3 +SELECT COUNT(*),a FROM t1; +ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause +SELECT COUNT(*) FROM t1 a JOIN t1 b ON a.a= b.a; +COUNT(*) +9 +SELECT COUNT(*), (SELECT count(*) FROM t1 inr WHERE inr.a = outr.a) +FROM t1 outr; +ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause +SELECT COUNT(*) FROM t1 a JOIN t1 outr +ON a.a= (SELECT count(*) FROM t1 inr WHERE inr.a = outr.a); +COUNT(*) +0 +SET SQL_MODE=default; +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index dbe6d3113d5..38779ac1a2f 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -926,5 +926,34 @@ SELECT AVG(a), CAST(AVG(a) AS DECIMAL) FROM t1; DROP TABLE t1; +# +# Bug #39656: Behaviour different for agg functions with & without where - +# ONLY_FULL_GROUP_BY +# + +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,1), (1,2), (1,3); + +SET SQL_MODE='ONLY_FULL_GROUP_BY'; + +SELECT COUNT(*) FROM t1; +SELECT COUNT(*) FROM t1 where a=1; + +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS +SELECT COUNT(*),a FROM t1; + +SELECT COUNT(*) FROM t1 a JOIN t1 b ON a.a= b.a; + +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS +SELECT COUNT(*), (SELECT count(*) FROM t1 inr WHERE inr.a = outr.a) + FROM t1 outr; + +SELECT COUNT(*) FROM t1 a JOIN t1 outr + ON a.a= (SELECT count(*) FROM t1 inr WHERE inr.a = outr.a); + +SET SQL_MODE=default; +DROP TABLE t1; + + ### --echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 428d1709f94..2ac33c4e07f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -390,11 +390,21 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array, { int res; nesting_map save_allow_sum_func=thd->lex->allow_sum_func ; + /* + Need to save the value, so we can turn off only the new NON_AGG_FIELD + additions coming from the WHERE + */ + uint8 saved_flag= thd->lex->current_select->full_group_by_flag; DBUG_ENTER("setup_without_group"); thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level); res= setup_conds(thd, tables, leaves, conds); + /* it's not wrong to have non-aggregated columns in a WHERE */ + if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) + thd->lex->current_select->full_group_by_flag= saved_flag | + (thd->lex->current_select->full_group_by_flag & ~NON_AGG_FIELD_USED); + thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields, order); -- cgit v1.2.1 From 3fd29444e3639e1c098f4fb9f54e18f66a233259 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Mon, 24 Nov 2008 16:53:32 -0500 Subject: Bug#40866: mysql-test-run's check of tests provides false failures due to timestamp Altering how MTR checks global variable status to exclude timestamp Changed SQL statements to update style. --- mysql-test/include/check-testcase.test | 38 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test index 30cb7391f30..a9885f7b0ec 100644 --- a/mysql-test/include/check-testcase.test +++ b/mysql-test/include/check-testcase.test @@ -11,12 +11,12 @@ # # Dump all global variables # -show global variables; +SHOW GLOBAL VARIABLES WHERE variable_name != 'timestamp'; # # Dump all databases # -show databases; +SHOW DATABASES; # # Dump the "test" database, all it's tables and their data @@ -29,23 +29,23 @@ show databases; # --exec $MYSQL_DUMP --skip-comments --no-data mysql use mysql; -select * from columns_priv; -select * from db order by host, db, user; -select * from func; -select * from help_category; -select * from help_keyword; -select * from help_relation; -select * from help_relation; -select * from host; -select * from proc; -select * from procs_priv; -select * from tables_priv; -select * from time_zone; -select * from time_zone_leap_second; -select * from time_zone_name; -select * from time_zone_transition; -select * from time_zone_transition_type; -select * from user; +SELECT * FROM columns_priv; +SELECT * FROM db ORDER BY host, db, user; +SELECT * FROM func; +SELECT * FROM help_category; +SELECT * FROM help_keyword; +SELECT * FROM help_relation; +SELECT * FROM help_relation; +SELECT * FROM host; +SELECT * FROM proc; +SELECT * FROM procs_priv; +SELECT * FROM tables_priv; +SELECT * FROM time_zone; +SELECT * FROM time_zone_leap_second; +SELECT * FROM time_zone_name; +SELECT * FROM time_zone_transition; +SELECT * FROM time_zone_transition_type; +SELECT * FROM user; -- cgit v1.2.1 From a44c7be118aff856c28b455ae7b525992174da58 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Tue, 25 Nov 2008 10:22:02 +0400 Subject: Fix for bug#40984: backport fix from 39585 into 5.0 Problem: in 5.0 'check table for upgrade' doesn't detect incompatible collation changes made in 5.0.48. Fix: backport #39585 fix to 5.0 sql/handler.cc: Fix for bug#40984: backport fix from 39585 into 5.0 - backport of #39585 fix sql/handler.h: Fix for bug#40984: backport fix from 39585 into 5.0 - backport of #39585 fix --- sql/handler.cc | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ sql/handler.h | 1 + 2 files changed, 50 insertions(+) diff --git a/sql/handler.cc b/sql/handler.cc index 67ec5f3e759..71d184ad84b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1957,8 +1957,53 @@ bool handler::get_error_message(int error, String* buf) } +/** + Check for incompatible collation changes. + + @retval + HA_ADMIN_NEEDS_UPGRADE Table may have data requiring upgrade. + @retval + 0 No upgrade required. +*/ + +int handler::check_collation_compatibility() +{ + ulong mysql_version= table->s->mysql_version; + + if (mysql_version < 50048) + { + KEY *key= table->key_info; + KEY *key_end= key + table->s->keys; + for (; key < key_end; key++) + { + KEY_PART_INFO *key_part= key->key_part; + KEY_PART_INFO *key_part_end= key_part + key->key_parts; + for (; key_part < key_part_end; key_part++) + { + if (!key_part->fieldnr) + continue; + Field *field= table->field[key_part->fieldnr - 1]; + uint cs_number= field->charset()->number; + if (mysql_version < 50048 && + (cs_number == 11 || /* ascii_general_ci - bug #29499, bug #27562 */ + cs_number == 41 || /* latin7_general_ci - bug #29461 */ + cs_number == 42 || /* latin7_general_cs - bug #29461 */ + cs_number == 20 || /* latin7_estonian_cs - bug #29461 */ + cs_number == 21 || /* latin2_hungarian_ci - bug #29461 */ + cs_number == 22 || /* koi8u_general_ci - bug #29461 */ + cs_number == 23 || /* cp1251_ukrainian_ci - bug #29461 */ + cs_number == 26)) /* cp1250_general_ci - bug #29461 */ + return HA_ADMIN_NEEDS_UPGRADE; + } + } + } + return 0; +} + + int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt) { + int error; KEY *keyinfo, *keyend; KEY_PART_INFO *keypart, *keypartend; @@ -1987,6 +2032,10 @@ int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt) } if (table->s->frm_version != FRM_VER_TRUE_VARCHAR) return HA_ADMIN_NEEDS_ALTER; + + if ((error= check_collation_compatibility())) + return error; + return check_for_upgrade(check_opt); } diff --git a/sql/handler.h b/sql/handler.h index aa3377c3868..8706aae5fce 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -787,6 +787,7 @@ protected: virtual int check_for_upgrade(HA_CHECK_OPT *check_opt) { return 0; } public: + int check_collation_compatibility(); int ha_check_for_upgrade(HA_CHECK_OPT *check_opt); int check_old_types(); /* to be actually called to get 'check()' functionality*/ -- cgit v1.2.1 From 9910b86795888edb9257f5a39381eb29378b7a22 Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Wed, 26 Nov 2008 09:28:17 +0100 Subject: Bug#37553: MySql Error Compare TimeDiff & Time We pretended that TIMEDIFF() would always return positive results; this gave strange results in comparisons of the TIMEDIFF(low,hi) =) sql/item_func.cc: signed now sql/item_timefunc.h: Functions such as TIMEDIFF() return signed results! The file-comments pretended we were doing that all along, anyway... sql/my_decimal.cc: heed sign when converting time to my_decimal; times may actually be negative! Needed for SELECT CAST(time('-73:42:12') AS DECIMAL); sql/mysql_priv.h: using signed for dates and times now --- mysql-test/r/func_sapdb.result | 12 ++++++++++++ mysql-test/t/func_sapdb.test | 17 +++++++++++++++++ sql/item_cmpfunc.cc | 14 +++++++------- sql/item_cmpfunc.h | 6 +++--- sql/item_func.cc | 2 +- sql/item_timefunc.h | 1 + sql/my_decimal.cc | 2 +- sql/mysql_priv.h | 4 ++-- 8 files changed, 44 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index 4db0416bdce..a06d7004908 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -256,3 +256,15 @@ a select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f"); str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") 2003-01-02 10:11:12.001200 +select timediff('2008-09-29 20:10:10','2008-09-30 20:10:10'),time('00:00:00'); +timediff('2008-09-29 20:10:10','2008-09-30 20:10:10') time('00:00:00') +-24:00:00 00:00:00 +select timediff('2008-09-29 20:10:10','2008-09-30 20:10:10')>time('00:00:00'); +timediff('2008-09-29 20:10:10','2008-09-30 20:10:10')>time('00:00:00') +0 +select timediff('2008-09-29 20:10:10','2008-09-30 20:10:10')time('00:00:00'); +select timediff('2008-09-29 20:10:10','2008-09-30 20:10:10')get_time(<ime); - value= !*is_null ? TIME_to_ulonglong_datetime(<ime) : 0; + value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(<ime) : 0; } /* Do not cache GET_USER_VAR() function as its const_item() may return TRUE @@ -886,11 +886,11 @@ void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1) obtained value */ -ulonglong +longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, Item *warn_item, bool *is_null) { - ulonglong value= 0; + longlong value= 0; String buf, *str= 0; Item *item= **item_arg; @@ -925,7 +925,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, enum_field_types f_type= warn_item->field_type(); timestamp_type t_type= f_type == MYSQL_TYPE_DATE ? MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME; - value= get_date_from_str(thd, str, t_type, warn_item->name, &error); + value= (longlong) get_date_from_str(thd, str, t_type, warn_item->name, &error); /* If str did not contain a valid date according to the current SQL_MODE, get_date_from_str() has already thrown a warning, @@ -979,7 +979,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, int Arg_comparator::compare_datetime() { bool a_is_null, b_is_null; - ulonglong a_value, b_value; + longlong a_value, b_value; /* Get DATE/DATETIME/TIME value of the 'a' item. */ a_value= (*get_value_func)(thd, &a, &a_cache, *b, &a_is_null); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 1bd60ff37d9..db831c7030c 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -42,8 +42,8 @@ class Arg_comparator: public Sql_alloc bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE, CMP_DATE_WITH_STR, CMP_STR_WITH_DATE }; - ulonglong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg, - Item *warn_item, bool *is_null); + longlong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg, + Item *warn_item, bool *is_null); public: DTCollation cmp_collation; @@ -1028,7 +1028,7 @@ public: */ class cmp_item_datetime :public cmp_item { - ulonglong value; + longlong value; public: THD *thd; /* Item used for issuing warnings. */ diff --git a/sql/item_func.cc b/sql/item_func.cc index 45aa8e9bea0..8295bd41334 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2283,7 +2283,7 @@ uint Item_func_min_max::cmp_datetimes(ulonglong *value) { Item **arg= args + i; bool is_null; - ulonglong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null); + longlong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null); if ((null_value= args[i]->null_value)) return 0; if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0) diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 7960c03d2e5..81a6c3e98bd 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -408,6 +408,7 @@ public: { return save_time_in_field(field); } + bool result_as_longlong() { return TRUE; } }; diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc index 31a5b09370a..a235edbd73c 100644 --- a/sql/my_decimal.cc +++ b/sql/my_decimal.cc @@ -216,7 +216,7 @@ my_decimal *date2my_decimal(MYSQL_TIME *ltime, my_decimal *dec) date = (ltime->year*100L + ltime->month)*100L + ltime->day; if (ltime->time_type > MYSQL_TIMESTAMP_DATE) date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second; - if (int2my_decimal(E_DEC_FATAL_ERROR, date, FALSE, dec)) + if (int2my_decimal(E_DEC_FATAL_ERROR, ltime->neg ? -date : date, FALSE, dec)) return dec; if (ltime->second_part) { diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 1568f042b7e..d112c2b2f39 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1556,8 +1556,8 @@ void make_date(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time, String *str); void make_time(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time, String *str); -ulonglong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, - Item *warn_item, bool *is_null); +longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, + Item *warn_item, bool *is_null); int test_if_number(char *str,int *res,bool allow_wildcards); void change_byte(byte *,uint,char,char); -- cgit v1.2.1 From 00c299a886f133ef1cd5e9b1895a8a3bb9131a23 Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Wed, 26 Nov 2008 10:51:59 -0500 Subject: Bug#32136: mysqld_multi --defaults-file not respected while using \ --mysqld=mysqld_safe The server run didn't know the correct section to read in a configuration file, and would read from "[mysqld]" even though mysqld_multi had already read the defaults and made them into explicit parameters. Worse, the "defaults-file" parameter says that it means "Read only this configuration file, do not read the standard system-wide and user-specific files", which should apply not only to mysql-multi, but to the server also. So, now if "defaults-file" is given, put "no-defaults" before all the explicit parameters we read from the defaults-file and feed to the mysqld or mysqld_safe. --- scripts/mysqld_multi.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index 3cb4665eb1c..631e1e38cc7 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -293,7 +293,12 @@ 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)); -- cgit v1.2.1 From 03a5f8337081d5d4d9b9351e368c6c01922a2ff4 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 27 Nov 2008 16:33:40 +0400 Subject: Bug#34825 perror on windows doesn't know about win32 error codes extended perror to enable printing of Win32 system errors extra/perror.c: extended perror to enable printing of Win32 system errors mysql-test/r/perror-win.result: test result mysql-test/t/perror-win.test: test case --- extra/perror.c | 40 ++++++++++++++++++++++++++++++++++++++-- mysql-test/r/perror-win.result | 5 +++++ mysql-test/t/perror-win.test | 11 +++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/perror-win.result create mode 100644 mysql-test/t/perror-win.test diff --git a/extra/perror.c b/extra/perror.c index 4d19f4dd7eb..37d6b45c8dd 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -185,11 +185,36 @@ static const char *get_ha_error_msg(int code) } +#if defined(__WIN__) +static my_bool print_win_error_msg(DWORD error, my_bool verbose) +{ + LPTSTR s; + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, 0, (LPTSTR)&s, 0, + NULL)) + { + if (verbose) + printf("Win32 error code %d: %s", error, s); + else + puts(s); + LocalFree(s); + return 0; + } + return 1; +} +#endif + + + int main(int argc,char *argv[]) { int error,code,found; const char *msg; char *unknown_error = 0; +#if defined(__WIN__) + my_bool skip_win_message= 0; +#endif MY_INIT(argv[0]); if (get_options(&argc,&argv)) @@ -286,8 +311,15 @@ int main(int argc,char *argv[]) /* Error message still not found, look in handler error codes */ if (!(msg=get_ha_error_msg(code))) { - fprintf(stderr,"Illegal error code: %d\n",code); - error=1; +#if defined(__WIN__) + if (!(skip_win_message= !print_win_error_msg((DWORD)code, verbose))) + { +#endif + fprintf(stderr,"Illegal error code: %d\n",code); + error=1; +#if defined(__WIN__) + } +#endif } else { @@ -298,6 +330,10 @@ int main(int argc,char *argv[]) puts(msg); } } +#if defined(__WIN__) + if (!skip_win_message) + print_win_error_msg((DWORD)code, verbose); +#endif } } diff --git a/mysql-test/r/perror-win.result b/mysql-test/r/perror-win.result new file mode 100644 index 00000000000..61e6fcaab4e --- /dev/null +++ b/mysql-test/r/perror-win.result @@ -0,0 +1,5 @@ +MySQL error code 150: Foreign key constraint is incorrectly formed +Win32 error code 150: System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed. +OS error code 23: Too many open files in system +Win32 error code 23: Data error (cyclic redundancy check). +Win32 error code 15000: The specified channel path is invalid. diff --git a/mysql-test/t/perror-win.test b/mysql-test/t/perror-win.test new file mode 100644 index 00000000000..56615e72a5a --- /dev/null +++ b/mysql-test/t/perror-win.test @@ -0,0 +1,11 @@ +# Windows-specific tests +--source include/windows.inc +--require r/have_perror.require +disable_query_log; +eval select LENGTH("$MY_PERROR") > 0 as "have_perror"; +enable_query_log; + + +--exec $MY_PERROR 150 +--exec $MY_PERROR 23 +--exec $MY_PERROR 15000 -- cgit v1.2.1 From 842b9cc4bd4e9c615055de0cbe204ab22fd119c8 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 27 Nov 2008 16:41:25 +0400 Subject: Bug#40365 Prepared statements may insert invalid dates. set DATE|DATETIME value to 0 if ALLOW_INVALID_DATES sql_mode is not enabled. sql/field.cc: set DATE|DATETIME value to 0 if ALLOW_INVALID_DATES sql_mode is not enabled. tests/mysql_client_test.c: test case --- sql/field.cc | 2 ++ tests/mysql_client_test.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/sql/field.cc b/sql/field.cc index 3d3f698f912..8188b51d4d1 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5372,6 +5372,7 @@ int Field_newdate::store_time(MYSQL_TIME *ltime, timestamp_type time_type) { char buff[MAX_DATE_STRING_REP_LENGTH]; String str(buff, sizeof(buff), &my_charset_latin1); + tmp= 0; make_date((DATE_TIME_FORMAT *) 0, ltime, &str); set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, str.ptr(), str.length(), MYSQL_TIMESTAMP_DATE, 1); @@ -5608,6 +5609,7 @@ int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type) { char buff[MAX_DATE_STRING_REP_LENGTH]; String str(buff, sizeof(buff), &my_charset_latin1); + tmp= 0; make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str); set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, str.ptr(), str.length(), MYSQL_TIMESTAMP_DATETIME,1); diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 9270a2a9d60..a9ec7eb358a 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16218,7 +16218,87 @@ static void test_bug38486(void) DBUG_VOID_RETURN; } +static void test_bug40365(void) +{ + uint rc, i, count= 1; + MYSQL_STMT *stmt= 0; + MYSQL_BIND my_bind[2]; + my_bool is_null[2]= {0}; + MYSQL_TIME tm[2]; + + DBUG_ENTER("test_bug40365"); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + rc= mysql_query(mysql, "CREATE TABLE t1(c1 DATETIME, \ + c2 DATE)"); + myquery(rc); + + stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES(?, ?)"); + check_stmt(stmt); + verify_param_count(stmt, 2); + + bzero((char*) my_bind, sizeof(my_bind)); + my_bind[0].buffer_type= MYSQL_TYPE_DATETIME; + my_bind[1].buffer_type= MYSQL_TYPE_DATE; + for (i= 0; i < (int) array_elements(my_bind); i++) + { + my_bind[i].buffer= (void *) &tm[i]; + my_bind[i].is_null= &is_null[i]; + } + + rc= mysql_stmt_bind_param(stmt, my_bind); + check_execute(stmt, rc); + + for (i= 0; i < (int) array_elements(my_bind); i++) + { + tm[i].neg= 0; + tm[i].second_part= 0; + tm[i].year= 2009; + tm[i].month= 2; + tm[i].day= 29; + tm[i].hour= 0; + tm[i].minute= 0; + tm[i].second= 0; + } + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + rc= mysql_commit(mysql); + myquery(rc); + mysql_stmt_close(stmt); + + stmt= mysql_simple_prepare(mysql, "SELECT * FROM t1"); + check_stmt(stmt); + + rc= mysql_stmt_bind_result(stmt, my_bind); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + rc= mysql_stmt_store_result(stmt); + check_execute(stmt, rc); + rc= mysql_stmt_fetch(stmt); + check_execute(stmt, rc); + + if (!opt_silent) + fprintf(stdout, "\n"); + + for (i= 0; i < array_elements(my_bind); i++) + { + if (!opt_silent) + fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d ", + i, tm[i].year, tm[i].month, tm[i].day); + DIE_UNLESS(tm[i].year == 0); + DIE_UNLESS(tm[i].month == 0); + DIE_UNLESS(tm[i].day == 0); + } + mysql_stmt_close(stmt); + + DBUG_VOID_RETURN; +} /* Read and parse arguments and MySQL options from my.cnf */ @@ -16514,6 +16594,7 @@ static struct my_tests_st my_tests[]= { { "test_bug31669", test_bug31669 }, { "test_bug32265", test_bug32265 }, { "test_bug38486", test_bug38486 }, + { "test_bug40365", test_bug40365 }, { 0, 0 } }; -- cgit v1.2.1 From b241dc2156c3af9f4c999c055ecabfbb01b1d1b6 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 27 Nov 2008 17:57:34 +0400 Subject: Bug#37460 Assertion failed: !table->file || table->file->inited == handler::NONE enable uncacheable flag if we update a view with check option and check option has a subselect, otherwise, the check option can be evaluated after the subselect was freed as independent (See full_local in JOIN::join_free()) mysql-test/r/subselect.result: test result mysql-test/t/subselect.test: test case sql/mysql_priv.h: added UNCACHEABLE_CHECKOPTION flag sql/sql_update.cc: enable uncacheable flag if we update a view with check option and check option has a subselect, otherwise, the check option can be evaluated after the subselect was freed as independent (See full_local in JOIN::join_free()) --- mysql-test/r/subselect.result | 30 ++++++++++++++++++++++++++++++ mysql-test/t/subselect.test | 35 +++++++++++++++++++++++++++++++++++ sql/mysql_priv.h | 1 + sql/sql_update.cc | 26 ++++++++++++++++++++++++++ 4 files changed, 92 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 6eeb652e3c1..8830ea11f97 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4422,4 +4422,34 @@ id 2 3 DROP TABLE t1, t2; +CREATE TABLE t1 (id int); +CREATE TABLE t2 (id int, c int); +INSERT INTO t1 (id) VALUES (1); +INSERT INTO t2 (id) VALUES (1); +INSERT INTO t1 (id) VALUES (1); +INSERT INTO t2 (id) VALUES (1); +CREATE VIEW v1 AS +SELECT t2.c AS c FROM t1, t2 +WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION; +UPDATE v1 SET c=1; +CREATE VIEW v2 (a,b) AS +SELECT t2.id, t2.c AS c FROM t1, t2 +WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION; +INSERT INTO v2(a,b) VALUES (2,2); +ERROR HY000: CHECK OPTION failed 'test.v2' +INSERT INTO v2(a,b) VALUES (1,2); +SELECT * FROM v1; +c +1 +1 +1 +1 +2 +2 +CREATE VIEW v3 AS +SELECT t2.c AS c FROM t2 +WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION; +DELETE FROM v3; +DROP VIEW v1,v2,v3; +DROP TABLE t1,t2; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index d28e31fb545..ea911e4912d 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3325,4 +3325,39 @@ INSERT INTO t2 VALUES (2,1),(3,1); SELECT * FROM t1 i WHERE 1 IN (SELECT l.id2 FROM t2 l WHERE i.id=l.id1); DROP TABLE t1, t2; +# +# Bug#37460 Assertion failed: +# !table->file || table->file->inited == handler::NONE +# +CREATE TABLE t1 (id int); +CREATE TABLE t2 (id int, c int); + +INSERT INTO t1 (id) VALUES (1); +INSERT INTO t2 (id) VALUES (1); +INSERT INTO t1 (id) VALUES (1); +INSERT INTO t2 (id) VALUES (1); + +CREATE VIEW v1 AS + SELECT t2.c AS c FROM t1, t2 + WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION; +UPDATE v1 SET c=1; + +CREATE VIEW v2 (a,b) AS + SELECT t2.id, t2.c AS c FROM t1, t2 + WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION; + +--error 1369 +INSERT INTO v2(a,b) VALUES (2,2); +INSERT INTO v2(a,b) VALUES (1,2); +SELECT * FROM v1; + +CREATE VIEW v3 AS + SELECT t2.c AS c FROM t2 + WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION; + +DELETE FROM v3; + +DROP VIEW v1,v2,v3; +DROP TABLE t1,t2; + --echo End of 5.0 tests. diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 1568f042b7e..75c95834ac9 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -435,6 +435,7 @@ MY_LOCALE *my_locale_by_number(uint number); #define UNCACHEABLE_PREPARE 16 /* For uncorrelated SELECT in an UNION with some correlated SELECTs */ #define UNCACHEABLE_UNITED 32 +#define UNCACHEABLE_CHECKOPTION 64 /* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */ #define UNDEF_POS (-1) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index eb4e9b7ed73..f15db220a3b 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1249,6 +1249,32 @@ multi_update::initialize_tables(JOIN *join) } } + /* + enable uncacheable flag if we update a view with check option + and check option has a subselect, otherwise, the check option + can be evaluated after the subselect was freed as independent + (See full_local in JOIN::join_free()). + */ + if (table_ref->check_option && !join->select_lex->uncacheable) + { + SELECT_LEX_UNIT *tmp_unit; + SELECT_LEX *sl; + for (tmp_unit= join->select_lex->first_inner_unit(); + tmp_unit; + tmp_unit= tmp_unit->next_unit()) + { + for (sl= tmp_unit->first_select(); sl; sl= sl->next_select()) + { + if (sl->master_unit()->item) + { + join->select_lex->uncacheable|= UNCACHEABLE_CHECKOPTION; + goto loop_end; + } + } + } + } +loop_end: + if (table == first_table_for_update && table_ref->check_option) { table_map unupdated_tables= table_ref->check_option->used_tables() & -- cgit v1.2.1 From 3abcbf2729ce730fccfd0d4cc8709195cc770254 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 27 Nov 2008 18:26:22 +0400 Subject: removed unused variable --- tests/mysql_client_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index a9ec7eb358a..ee3a053f8bd 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16220,7 +16220,7 @@ static void test_bug38486(void) static void test_bug40365(void) { - uint rc, i, count= 1; + uint rc, i; MYSQL_STMT *stmt= 0; MYSQL_BIND my_bind[2]; my_bool is_null[2]= {0}; -- cgit v1.2.1 From 8a5273b89956337c24bbf25a89e3a992c5d82b5f Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 27 Nov 2008 18:54:23 +0400 Subject: Bug#37284 Crash in Field_string::type() The bug is repeatable with latest(1.0.1) InnoDB plugin on Linux, Win, If MySQL is compiled with valgrind there are errors about using of uninitialized variable(orig_table). The fix is to set field->orig_table correct value. mysql-test/r/innodb_mysql.result: test result mysql-test/t/innodb_mysql.test: test case sql/sql_base.cc: set field->orig_table to 'table' value because it may be bogus and it leads to crash on Field_string::type() function. --- mysql-test/r/innodb_mysql.result | 6 ++++++ mysql-test/t/innodb_mysql.test | 11 +++++++++++ sql/sql_base.cc | 3 +++ 3 files changed, 20 insertions(+) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 47fa331c9ab..682cc2e82e2 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1261,4 +1261,10 @@ a b c 5 1 1 4 1 1 DROP TABLE t1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a char(50)) ENGINE=InnoDB; +CREATE INDEX i1 on t1 (a(3)); +SELECT * FROM t1 WHERE a = 'abcde'; +a +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index e15d1aee08a..b4fc425cb7c 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -1014,4 +1014,15 @@ SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5; DROP TABLE t1; +# +# Bug#37284 Crash in Field_string::type() +# +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TABLE t1 (a char(50)) ENGINE=InnoDB; +CREATE INDEX i1 on t1 (a(3)); +SELECT * FROM t1 WHERE a = 'abcde'; +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 873a3eac24e..881c6a421e8 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2102,7 +2102,10 @@ bool reopen_table(TABLE *table,bool locked) for (key=0 ; key < table->s->keys ; key++) { for (part=0 ; part < table->key_info[key].usable_key_parts ; part++) + { table->key_info[key].key_part[part].field->table= table; + table->key_info[key].key_part[part].field->orig_table= table; + } } if (table->triggers) table->triggers->set_table(table); -- cgit v1.2.1 From ed62e8905b6538c2f9427d3334612b4bce90be42 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 28 Nov 2008 14:50:13 +0400 Subject: pushbuild failure fixes mysql-test/r/perror-win.result: pushbuild failure fix mysql-test/t/perror-win.test: pushbuild failure fix sql/item_func.cc: pushbuild failure fix --- mysql-test/r/perror-win.result | 7 ++++--- mysql-test/t/perror-win.test | 9 ++++++--- sql/item_func.cc | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/perror-win.result b/mysql-test/r/perror-win.result index 61e6fcaab4e..8d3026bc331 100644 --- a/mysql-test/r/perror-win.result +++ b/mysql-test/r/perror-win.result @@ -1,5 +1,6 @@ MySQL error code 150: Foreign key constraint is incorrectly formed -Win32 error code 150: System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed. +Win32 error code 150: System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed. OS error code 23: Too many open files in system -Win32 error code 23: Data error (cyclic redundancy check). -Win32 error code 15000: The specified channel path is invalid. +Win32 error code 23: Data error (cyclic redundancy check). +Win32 error code 500: User profile cannot be loaded. +Illegal error code: 30000 diff --git a/mysql-test/t/perror-win.test b/mysql-test/t/perror-win.test index 56615e72a5a..2b38c5fad54 100644 --- a/mysql-test/t/perror-win.test +++ b/mysql-test/t/perror-win.test @@ -6,6 +6,9 @@ eval select LENGTH("$MY_PERROR") > 0 as "have_perror"; enable_query_log; ---exec $MY_PERROR 150 ---exec $MY_PERROR 23 ---exec $MY_PERROR 15000 +--exec $MY_PERROR 150 2>&1 +--exec $MY_PERROR 23 2>&1 +--exec $MY_PERROR 500 2>&1 +--error 1 +--exec $MY_PERROR 30000 2>&1 + diff --git a/sql/item_func.cc b/sql/item_func.cc index 8295bd41334..c0d08d9b213 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2275,7 +2275,7 @@ void Item_func_min_max::fix_length_and_dec() uint Item_func_min_max::cmp_datetimes(ulonglong *value) { - ulonglong min_max; + longlong min_max; uint min_max_idx= 0; LINT_INIT(min_max); -- cgit v1.2.1 From d9b8c0d497576dd715a911524bddf9f62566d867 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 28 Nov 2008 17:12:43 +0400 Subject: error code is changed to satisfy Win NT --- mysql-test/r/perror-win.result | 2 +- mysql-test/t/perror-win.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/perror-win.result b/mysql-test/r/perror-win.result index 8d3026bc331..1d42235cc14 100644 --- a/mysql-test/r/perror-win.result +++ b/mysql-test/r/perror-win.result @@ -2,5 +2,5 @@ MySQL error code 150: Foreign key constraint is incorrectly formed Win32 error code 150: System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed. OS error code 23: Too many open files in system Win32 error code 23: Data error (cyclic redundancy check). -Win32 error code 500: User profile cannot be loaded. +Win32 error code 1062: The service has not been started. Illegal error code: 30000 diff --git a/mysql-test/t/perror-win.test b/mysql-test/t/perror-win.test index 2b38c5fad54..cc09b8527be 100644 --- a/mysql-test/t/perror-win.test +++ b/mysql-test/t/perror-win.test @@ -8,7 +8,7 @@ enable_query_log; --exec $MY_PERROR 150 2>&1 --exec $MY_PERROR 23 2>&1 ---exec $MY_PERROR 500 2>&1 +--exec $MY_PERROR 1062 2>&1 --error 1 --exec $MY_PERROR 30000 2>&1 -- cgit v1.2.1 From e2119738eea97f40dd88bd794754be4eea4fe0d1 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 28 Nov 2008 18:17:13 +0400 Subject: BUG#37245 - Full text search problem Certain boolean mode queries with truncation operator did not return matching records and calculate relevancy incorrectly. myisam/ft_boolean_search.c: Sort ftb->list in ascending order. This helps to fix binary search in ft_boolean_find_relevance() without rewriting it much. Fixed binary search in ft_boolean_find_relevance(), so it finds right-most element in an array. Fixed that ft_boolean_find_relevance() didn't return match for words with truncation operator in case query has other non- matching words. mysql-test/r/fulltext.result: A test case for BUG#37245. mysql-test/t/fulltext.test: A test case for BUG#37245. --- myisam/ft_boolean_search.c | 38 ++++++++++++++++++++++++++++++++------ mysql-test/r/fulltext.result | 9 +++++++++ mysql-test/t/fulltext.test | 9 +++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c index 57de75ee4be..255c51fd33a 100644 --- a/myisam/ft_boolean_search.c +++ b/myisam/ft_boolean_search.c @@ -122,11 +122,11 @@ static int FTB_WORD_cmp(my_off_t *v, FTB_WORD *a, FTB_WORD *b) static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b) { - /* ORDER BY word DESC, ndepth DESC */ - int i= mi_compare_text(cs, (uchar*) (*b)->word+1,(*b)->len-1, - (uchar*) (*a)->word+1,(*a)->len-1,0,0); + /* ORDER BY word, ndepth */ + int i= mi_compare_text(cs, (uchar*) (*a)->word + 1, (*a)->len - 1, + (uchar*) (*b)->word + 1, (*b)->len - 1, 0, 0); if (!i) - i=CMP_NUM((*b)->ndepth,(*a)->ndepth); + i= CMP_NUM((*a)->ndepth, (*b)->ndepth); return i; } @@ -674,23 +674,49 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) (byte *) end, &word, TRUE)) { int a, b, c; + /* + Find right-most element in the array of query words matching this + word from a document. + */ for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2) { ftbw=ftb->list[c]; if (mi_compare_text(ftb->charset, (uchar*) word.pos, word.len, (uchar*) ftbw->word+1, ftbw->len-1, - (my_bool) (ftbw->flags&FTB_FLAG_TRUNC),0) >0) + (my_bool) (ftbw->flags & FTB_FLAG_TRUNC), 0) < 0) b=c; else a=c; } + /* + If there were no words with truncation operator, we iterate to the + beginning of an array until array element is equal to the word from + a document. This is done mainly because the same word may be + mentioned twice (or more) in the query. + + In case query has words with truncation operator we must iterate + to the beginning of the array. There may be non-matching query words + between matching word with truncation operator and the right-most + matching element. E.g., if we're looking for 'aaa15' in an array of + 'aaa1* aaa14 aaa15 aaa16'. + + Worse of that there still may be match even if the binary search + above didn't find matching element. E.g., if we're looking for + 'aaa15' in an array of 'aaa1* aaa14 aaa16'. The binary search will + stop at 'aaa16'. + */ for (; c>=0; c--) { ftbw=ftb->list[c]; if (mi_compare_text(ftb->charset, (uchar*) word.pos, word.len, (uchar*) ftbw->word+1,ftbw->len-1, (my_bool) (ftbw->flags&FTB_FLAG_TRUNC),0)) - break; + { + if (ftb->with_scan & FTB_FLAG_TRUNC) + continue; + else + break; + } if (ftbw->docid[1] == docid) continue; ftbw->docid[1]=docid; diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index e73f8af405c..6821691c9d0 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -497,3 +497,12 @@ WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref b b 5 const 4 Using where DROP TABLE t1; +CREATE TABLE t1(a CHAR(10)); +INSERT INTO t1 VALUES('aaa15'); +SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa16' IN BOOLEAN MODE) FROM t1; +MATCH(a) AGAINST('aaa1* aaa14 aaa16' IN BOOLEAN MODE) +1 +SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) FROM t1; +MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) +2 +DROP TABLE t1; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index fa087d89efb..77d84c730d9 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -423,3 +423,12 @@ EXPLAIN SELECT * FROM t1 FORCE INDEX(b) WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; DROP TABLE t1; + +# +# BUG#37245 - Full text search problem +# +CREATE TABLE t1(a CHAR(10)); +INSERT INTO t1 VALUES('aaa15'); +SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa16' IN BOOLEAN MODE) FROM t1; +SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) FROM t1; +DROP TABLE t1; -- cgit v1.2.1 From 171ef77f4476ca878617aa3681d80f763747467e Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 28 Nov 2008 16:25:16 +0200 Subject: Bug #37339: SHOW VARIABLES not working properly with multi-byte datadir The SHOW VARIABLES LIKE .../SELECT @@/SELECT ... FROM INFORMATION_SCHEMA.VARIABLES were assuming that all the system variables are in system charset (UTF-8). However the variables that are settable through command line will have a different character set (character_set_filesystem). Fixed the server to remember the correct character set of basedir, datadir, tmpdir, ssl, plugin_dir, slave_load_tmpdir, innodb variables; init_connect and init_slave variables and use it when processing data. mysql-test/r/ctype_filesystem.result: Bug #37339: test case (should be in utf-8) mysql-test/t/ctype_filesystem-master.opt: Bug #37339: test case (should be in ISO-8859-1) mysql-test/t/ctype_filesystem.test: Bug #37339: test case sql/mysqld.cc: Bug #37339: remember the correct character set for init_slave and init_connect sql/set_var.cc: Bug #37339: - remember the character set of the relevant variables - implement storing and using the correct character set sql/set_var.h: Bug #37339: implement storing and using the correct character set sql/sql_show.cc: Bug #37339: implement storing and using the correct character set --- mysql-test/r/ctype_filesystem.result | 11 ++++++ mysql-test/t/ctype_filesystem-master.opt | 2 + mysql-test/t/ctype_filesystem.test | 5 +++ sql/mysqld.cc | 2 + sql/set_var.cc | 67 +++++++++++++++++++++----------- sql/set_var.h | 47 +++++++++++++++++++++- sql/sql_show.cc | 10 +++-- 7 files changed, 116 insertions(+), 28 deletions(-) create mode 100644 mysql-test/r/ctype_filesystem.result create mode 100644 mysql-test/t/ctype_filesystem-master.opt create mode 100644 mysql-test/t/ctype_filesystem.test diff --git a/mysql-test/r/ctype_filesystem.result b/mysql-test/r/ctype_filesystem.result new file mode 100644 index 00000000000..8a8f0f7f8cc --- /dev/null +++ b/mysql-test/r/ctype_filesystem.result @@ -0,0 +1,11 @@ +SET CHARACTER SET utf8; +SHOW VARIABLES like 'character_sets_dir'; +Variable_name Value +character_sets_dir /ß/ +SHOW VARIABLES like 'character_set_filesystem'; +Variable_name Value +character_set_filesystem latin1 +SHOW VARIABLES like 'character_set_client'; +Variable_name Value +character_set_client utf8 +SET CHARACTER SET default; diff --git a/mysql-test/t/ctype_filesystem-master.opt b/mysql-test/t/ctype_filesystem-master.opt new file mode 100644 index 00000000000..cb3427571b5 --- /dev/null +++ b/mysql-test/t/ctype_filesystem-master.opt @@ -0,0 +1,2 @@ +--character-sets-dir=/ß +--character-set-filesystem=latin1 diff --git a/mysql-test/t/ctype_filesystem.test b/mysql-test/t/ctype_filesystem.test new file mode 100644 index 00000000000..30b1607008b --- /dev/null +++ b/mysql-test/t/ctype_filesystem.test @@ -0,0 +1,5 @@ +SET CHARACTER SET utf8; +SHOW VARIABLES like 'character_sets_dir'; +SHOW VARIABLES like 'character_set_filesystem'; +SHOW VARIABLES like 'character_set_client'; +SET CHARACTER SET default; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c3e5449b22b..dd2bebfdd2d 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3035,12 +3035,14 @@ static int init_common_variables(const char *conf_file_name, int argc, sys_init_connect.value_length= strlen(opt_init_connect); else sys_init_connect.value=my_strdup("",MYF(0)); + sys_init_connect.is_os_charset= TRUE; sys_init_slave.value_length= 0; if ((sys_init_slave.value= opt_init_slave)) sys_init_slave.value_length= strlen(opt_init_slave); else sys_init_slave.value=my_strdup("",MYF(0)); + sys_init_slave.is_os_charset= TRUE; if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1)) return 1; diff --git a/sql/set_var.cc b/sql/set_var.cc index 6bc19f2e6eb..59741e5683d 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -138,7 +138,7 @@ sys_var_thd_ulong sys_auto_increment_offset("auto_increment_offset", sys_var_bool_ptr sys_automatic_sp_privileges("automatic_sp_privileges", &sp_automatic_privileges); -sys_var_const_str sys_basedir("basedir", mysql_home); +sys_var_const_os_str sys_basedir("basedir", mysql_home); sys_var_long_ptr sys_binlog_cache_size("binlog_cache_size", &binlog_cache_size); sys_var_thd_ulong sys_bulk_insert_buff_size("bulk_insert_buffer_size", @@ -151,6 +151,8 @@ sys_var_character_set_client sys_character_set_client("character_set_client"); sys_var_character_set_connection sys_character_set_connection("character_set_connection"); sys_var_character_set_results sys_character_set_results("character_set_results"); sys_var_character_set_filesystem sys_character_set_filesystem("character_set_filesystem"); +sys_var_const_os_str sys_character_sets_dir("character_sets_dir", + mysql_charsets_dir); sys_var_thd_ulong sys_completion_type("completion_type", &SV::completion_type, check_completion_type, @@ -162,7 +164,7 @@ sys_var_long_ptr sys_concurrent_insert("concurrent_insert", &myisam_concurrent_insert); sys_var_long_ptr sys_connect_timeout("connect_timeout", &connect_timeout); -sys_var_const_str sys_datadir("datadir", mysql_real_data_home); +sys_var_const_os_str sys_datadir("datadir", mysql_real_data_home); sys_var_enum sys_delay_key_write("delay_key_write", &delay_key_write_options, &delay_key_write_typelib, @@ -311,6 +313,7 @@ sys_var_thd_ulong sys_optimizer_prune_level("optimizer_prune_level", &SV::optimizer_prune_level); sys_var_thd_ulong sys_optimizer_search_depth("optimizer_search_depth", &SV::optimizer_search_depth); +sys_var_const_os_str sys_plugin_dir("plugin_dir", opt_plugin_dir); sys_var_thd_ulong sys_preload_buff_size("preload_buffer_size", &SV::preload_buff_size); sys_var_thd_ulong sys_read_buff_size("read_buffer_size", @@ -338,7 +341,7 @@ sys_var_thd_ulong sys_query_alloc_block_size("query_alloc_block_size", sys_var_thd_ulong sys_query_prealloc_size("query_prealloc_size", &SV::query_prealloc_size, 0, fix_thd_mem_root); -sys_var_readonly sys_tmpdir("tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir); +sys_var_readonly_os sys_tmpdir("tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir); sys_var_thd_ulong sys_trans_alloc_block_size("transaction_alloc_block_size", &SV::trans_alloc_block_size, 0, fix_trans_mem_root); @@ -363,9 +366,11 @@ sys_var_bool_ptr sys_secure_auth("secure_auth", &opt_secure_auth); sys_var_const_str_ptr sys_secure_file_priv("secure_file_priv", &opt_secure_file_priv); sys_var_long_ptr sys_server_id("server_id", &server_id, fix_server_id); +#ifdef HAVE_REPLICATION sys_var_bool_ptr sys_slave_compressed_protocol("slave_compressed_protocol", &opt_slave_compressed_protocol); -#ifdef HAVE_REPLICATION +sys_var_const_os_str_ptr sys_slave_load_tmpdir("slave_load_tmpdir", + &slave_load_tmpdir); sys_var_long_ptr sys_slave_net_timeout("slave_net_timeout", &slave_net_timeout); sys_var_long_ptr sys_slave_trans_retries("slave_transaction_retries", @@ -380,17 +385,17 @@ sys_var_thd_sql_mode sys_sql_mode("sql_mode", #ifdef HAVE_OPENSSL extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher, *opt_ssl_key; -sys_var_const_str_ptr sys_ssl_ca("ssl_ca", &opt_ssl_ca); -sys_var_const_str_ptr sys_ssl_capath("ssl_capath", &opt_ssl_capath); -sys_var_const_str_ptr sys_ssl_cert("ssl_cert", &opt_ssl_cert); -sys_var_const_str_ptr sys_ssl_cipher("ssl_cipher", &opt_ssl_cipher); -sys_var_const_str_ptr sys_ssl_key("ssl_key", &opt_ssl_key); +sys_var_const_os_str_ptr sys_ssl_ca("ssl_ca", &opt_ssl_ca); +sys_var_const_os_str_ptr sys_ssl_capath("ssl_capath", &opt_ssl_capath); +sys_var_const_os_str_ptr sys_ssl_cert("ssl_cert", &opt_ssl_cert); +sys_var_const_os_str_ptr sys_ssl_cipher("ssl_cipher", &opt_ssl_cipher); +sys_var_const_os_str_ptr sys_ssl_key("ssl_key", &opt_ssl_key); #else -sys_var_const_str sys_ssl_ca("ssl_ca", NULL); -sys_var_const_str sys_ssl_capath("ssl_capath", NULL); -sys_var_const_str sys_ssl_cert("ssl_cert", NULL); -sys_var_const_str sys_ssl_cipher("ssl_cipher", NULL); -sys_var_const_str sys_ssl_key("ssl_key", NULL); +sys_var_const_os_str sys_ssl_ca("ssl_ca", NULL); +sys_var_const_os_str sys_ssl_capath("ssl_capath", NULL); +sys_var_const_os_str sys_ssl_cert("ssl_cert", NULL); +sys_var_const_os_str sys_ssl_cipher("ssl_cipher", NULL); +sys_var_const_os_str sys_ssl_key("ssl_key", NULL); #endif sys_var_thd_enum sys_updatable_views_with_limit("updatable_views_with_limit", @@ -460,6 +465,14 @@ sys_var_long_ptr sys_innodb_commit_concurrency("innodb_commit_concurrency", sys_var_long_ptr sys_innodb_flush_log_at_trx_commit( "innodb_flush_log_at_trx_commit", &srv_flush_log_at_trx_commit); +sys_var_const_os_str_ptr sys_innodb_data_file_path("innodb_data_file_path", + &innobase_data_file_path); +sys_var_const_os_str_ptr sys_innodb_data_home_dir("innodb_data_home_dir", + &innobase_data_home_dir); +sys_var_const_os_str_ptr sys_innodb_log_arch_dir("innodb_log_arch_dir", + &innobase_log_arch_dir); +sys_var_const_os_str_ptr sys_innodb_log_group_home_dir("innodb_log_group_home_dir", + &innobase_log_group_home_dir); #endif /* Condition pushdown to storage engine */ @@ -844,7 +857,7 @@ struct show_var_st init_vars[]= { {sys_character_set_results.name,(char*) &sys_character_set_results, SHOW_SYS}, {sys_character_set_server.name, (char*) &sys_character_set_server,SHOW_SYS}, {sys_charset_system.name, (char*) &sys_charset_system, SHOW_SYS}, - {"character_sets_dir", mysql_charsets_dir, SHOW_CHAR}, + {sys_character_sets_dir.name, (char *) &sys_character_sets_dir, SHOW_SYS}, {sys_collation_connection.name,(char*) &sys_collation_connection, SHOW_SYS}, {sys_collation_database.name,(char*) &sys_collation_database, SHOW_SYS}, {sys_collation_server.name,(char*) &sys_collation_server, SHOW_SYS}, @@ -905,8 +918,8 @@ struct show_var_st init_vars[]= { {"innodb_checksums", (char*) &innobase_use_checksums, SHOW_MY_BOOL}, {sys_innodb_commit_concurrency.name, (char*) &sys_innodb_commit_concurrency, SHOW_SYS}, {sys_innodb_concurrency_tickets.name, (char*) &sys_innodb_concurrency_tickets, SHOW_SYS}, - {"innodb_data_file_path", (char*) &innobase_data_file_path, SHOW_CHAR_PTR}, - {"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR}, + {sys_innodb_data_file_path.name, (char*) &sys_innodb_data_file_path, SHOW_SYS}, + {sys_innodb_data_home_dir.name, (char*) &sys_innodb_data_home_dir, SHOW_SYS}, {"innodb_adaptive_hash_index", (char*) &innobase_adaptive_hash_index, SHOW_MY_BOOL}, {"innodb_doublewrite", (char*) &innobase_use_doublewrite, SHOW_MY_BOOL}, {sys_innodb_fast_shutdown.name,(char*) &sys_innodb_fast_shutdown, SHOW_SYS}, @@ -917,12 +930,12 @@ struct show_var_st init_vars[]= { {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG }, {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG }, {"innodb_locks_unsafe_for_binlog", (char*) &innobase_locks_unsafe_for_binlog, SHOW_MY_BOOL}, - {"innodb_log_arch_dir", (char*) &innobase_log_arch_dir, SHOW_CHAR_PTR}, + {sys_innodb_log_arch_dir.name, (char*) &sys_innodb_log_arch_dir, SHOW_SYS}, {"innodb_log_archive", (char*) &innobase_log_archive, SHOW_MY_BOOL}, {"innodb_log_buffer_size", (char*) &innobase_log_buffer_size, SHOW_LONG }, {"innodb_log_file_size", (char*) &innobase_log_file_size, SHOW_LONGLONG}, {"innodb_log_files_in_group", (char*) &innobase_log_files_in_group, SHOW_LONG}, - {"innodb_log_group_home_dir", (char*) &innobase_log_group_home_dir, SHOW_CHAR_PTR}, + {sys_innodb_log_group_home_dir.name, (char*) &sys_innodb_log_group_home_dir, SHOW_SYS}, {sys_innodb_max_dirty_pages_pct.name, (char*) &sys_innodb_max_dirty_pages_pct, SHOW_SYS}, {sys_innodb_max_purge_lag.name, (char*) &sys_innodb_max_purge_lag, SHOW_SYS}, {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG}, @@ -1026,7 +1039,7 @@ struct show_var_st init_vars[]= { {sys_optimizer_search_depth.name,(char*) &sys_optimizer_search_depth, SHOW_SYS}, {"pid_file", (char*) pidfile_name, SHOW_CHAR}, - {"plugin_dir", (char*) opt_plugin_dir, SHOW_CHAR}, + {sys_plugin_dir.name, (char*) &sys_plugin_dir, SHOW_SYS}, {"port", (char*) &mysqld_port, SHOW_INT}, {sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS}, {"protocol_version", (char*) &protocol_version, SHOW_INT}, @@ -1068,7 +1081,7 @@ struct show_var_st init_vars[]= { #ifdef HAVE_REPLICATION {sys_slave_compressed_protocol.name, (char*) &sys_slave_compressed_protocol, SHOW_SYS}, - {"slave_load_tmpdir", (char*) &slave_load_tmpdir, SHOW_CHAR_PTR}, + {sys_slave_load_tmpdir.name,(char*) &sys_slave_load_tmpdir, SHOW_SYS}, {sys_slave_net_timeout.name,(char*) &sys_slave_net_timeout, SHOW_SYS}, {"slave_skip_errors", (char*) &slave_error_mask, SHOW_SLAVE_SKIP_ERRORS}, {sys_slave_trans_retries.name,(char*) &sys_slave_trans_retries, SHOW_SYS}, @@ -1175,6 +1188,7 @@ bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex, old_value= var_str->value; var_str->value= res; var_str->value_length= new_length; + var_str->is_os_charset= FALSE; rw_unlock(var_mutex); my_free(old_value, MYF(MY_ALLOW_ZERO_PTR)); return 0; @@ -1914,11 +1928,11 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) char *str= (char*) value_ptr(thd, var_type, base); if (str) tmp= new Item_string(str, strlen(str), - system_charset_info, DERIVATION_SYSCONST); + charset(thd), DERIVATION_SYSCONST); else { tmp= new Item_null(); - tmp->collation.set(system_charset_info, DERIVATION_SYSCONST); + tmp->collation.set(charset(thd), DERIVATION_SYSCONST); } pthread_mutex_unlock(&LOCK_global_system_variables); return tmp; @@ -1930,6 +1944,13 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) } +CHARSET_INFO *sys_var::charset(THD *thd) +{ + return is_os_charset ? thd->variables.character_set_filesystem : + system_charset_info; +} + + bool sys_var_thd_enum::update(THD *thd, set_var *var) { if (var->type == OPT_GLOBAL) diff --git a/sql/set_var.h b/sql/set_var.h index c37cc400e43..f43d3b75cee 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -46,9 +46,17 @@ public: sys_after_update_func after_update; bool no_support_one_shot; + /* + true if the value is in character_set_filesystem, + false otherwise. + Note that we can't use a pointer to the charset as the system var is + instantiated in global scope and the charset pointers are initialized + later. + */ + bool is_os_charset; sys_var(const char *name_arg, sys_after_update_func func= NULL) :name(name_arg), after_update(func) - , no_support_one_shot(1) + , no_support_one_shot(1), is_os_charset(FALSE) {} virtual ~sys_var() {} virtual bool check(THD *thd, set_var *var); @@ -68,6 +76,7 @@ public: Item *item(THD *thd, enum_var_type type, LEX_STRING *base); virtual bool is_struct() { return 0; } virtual bool is_readonly() const { return 0; } + CHARSET_INFO *charset(THD *thd); }; @@ -247,6 +256,17 @@ public: }; +class sys_var_const_os_str: public sys_var_const_str +{ +public: + sys_var_const_os_str(const char *name_arg, const char *value_arg) + :sys_var_const_str(name_arg, value_arg) + { + is_os_charset= TRUE; + } +}; + + class sys_var_const_str_ptr :public sys_var { public: @@ -276,6 +296,17 @@ public: }; +class sys_var_const_os_str_ptr :public sys_var_const_str_ptr +{ +public: + sys_var_const_os_str_ptr(const char *name_arg, char **value_arg) + :sys_var_const_str_ptr(name_arg, value_arg) + { + is_os_charset= TRUE; + } +}; + + class sys_var_enum :public sys_var { uint *value; @@ -791,6 +822,20 @@ public: bool is_readonly() const { return 1; } }; + +class sys_var_readonly_os: public sys_var_readonly +{ +public: + sys_var_readonly_os(const char *name_arg, enum_var_type type, + SHOW_TYPE show_type_arg, + sys_value_ptr_func value_ptr_func_arg) + :sys_var_readonly(name_arg, type, show_type_arg, value_ptr_func_arg) + { + is_os_charset= TRUE; + } +}; + + class sys_var_thd_time_zone :public sys_var_thd { public: diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5a4772e9847..4e3d209f674 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1441,6 +1441,7 @@ static bool show_status_array(THD *thd, const char *wild, char name_buffer[80]; int len; LEX_STRING null_lex_str; + CHARSET_INFO *charset= system_charset_info; DBUG_ENTER("show_status_array"); null_lex_str.str= 0; // For sys_var->value_ptr() @@ -1469,9 +1470,10 @@ static bool show_status_array(THD *thd, const char *wild, long nr; if (show_type == SHOW_SYS) { - show_type= ((sys_var*) value)->show_type(); - value= (char*) ((sys_var*) value)->value_ptr(thd, value_type, - &null_lex_str); + sys_var *var= ((sys_var *) value); + show_type= var->show_type(); + value= (char*) var->value_ptr(thd, value_type, &null_lex_str); + charset= var->charset(thd); } pos= end= buff; @@ -1794,7 +1796,7 @@ static bool show_status_array(THD *thd, const char *wild, restore_record(table, s->default_values); table->field[0]->store(name_buffer, strlen(name_buffer), system_charset_info); - table->field[1]->store(pos, (uint32) (end - pos), system_charset_info); + table->field[1]->store(pos, (uint32) (end - pos), charset); if (schema_table_store_record(thd, table)) DBUG_RETURN(TRUE); } -- cgit v1.2.1 From 854ef1be38dba453e4507780bced27ff6c159e3c Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Fri, 28 Nov 2008 20:13:12 +0400 Subject: Bug #33461: SELECT ... FROM USE INDEX (...) throws an error Even after the fix for bug 28701 visible behaviors of SELECT FROM a view and SELECT FROM a regular table are little bit different: 1. "SELECT FROM regular table USE/FORCE/IGNORE(non existent index)" fails with a "ERROR 1176 (HY000): Key '...' doesn't exist in table '...'" 2. "SELECT FROM view USING/FORCE/IGNORE(any index)" fails with a "ERROR 1221 (HY000): Incorrect usage of USE/IGNORE INDEX and VIEW". OTOH "SHOW INDEX FROM view" always returns empty result set, so from the point of same behaviour view we trying to use/ignore non existent index. To harmonize the behaviour of USE/FORCE/IGNORE(index) clauses in SELECT from a view and from a regular table the "ERROR 1221 (HY000): Incorrect usage of USE/IGNORE INDEX and VIEW" message has been replaced with the "ERROR 1176 (HY000): Key '...' doesn't exist in table '...'" message like for tables and non existent keys. mysql-test/r/view.result: Added test case for bug #33461. Updated test case for bug 28701. mysql-test/t/view.test: Added test case for bug #33461. Updated test case for bug 28701. sql/sql_view.cc: Bug #33461: SELECT ... FROM USE INDEX (...) throws an error To harmonize the behaviour of USE/FORCE/IGNORE(index) clauses in SELECT from a view and from a regular table the "ERROR 1221 (HY000): Incorrect usage of USE/IGNORE INDEX and VIEW" message has been replaced with the "ERROR 1176 (HY000): Key '...' doesn't exist in table '...'" message like for tables and non existent keys. --- mysql-test/r/view.result | 33 +++++++++++++++++++++++++++++---- mysql-test/t/view.test | 34 ++++++++++++++++++++++++++++++---- sql/sql_view.cc | 13 +++++++------ 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 8cbe3fc36cf..311b77e7a99 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -625,7 +625,7 @@ drop table t1; create table t1 (a int, b int); create view v1 as select a, sum(b) from t1 group by a; select b from v1 use index (some_index) where b=1; -ERROR HY000: Incorrect usage of USE INDEX and VIEW +ERROR HY000: Key 'some_index' doesn't exist in table 'v1' drop view v1; drop table t1; create table t1 (col1 char(5),col2 char(5)); @@ -3567,11 +3567,11 @@ CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2); CREATE VIEW v1 AS SELECT * FROM t1; SELECT * FROM v1 USE KEY(non_existant); -ERROR HY000: Incorrect usage of USE INDEX and VIEW +ERROR HY000: Key 'non_existant' doesn't exist in table 'v1' SELECT * FROM v1 FORCE KEY(non_existant); -ERROR HY000: Incorrect usage of FORCE INDEX and VIEW +ERROR HY000: Key 'non_existant' doesn't exist in table 'v1' SELECT * FROM v1 IGNORE KEY(non_existant); -ERROR HY000: Incorrect usage of IGNORE INDEX and VIEW +ERROR HY000: Key 'non_existant' doesn't exist in table 'v1' DROP VIEW v1; DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT, b INT NOT NULL DEFAULT 0, @@ -3679,6 +3679,31 @@ DROP VIEW v1; CREATE VIEW v1 AS SELECT 1; DROP VIEW v1; +CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT, INDEX (c2)); +INSERT INTO t1 VALUES (1,1), (2,2), (3,3); +SELECT * FROM t1 USE INDEX (PRIMARY) WHERE c1=2; +c1 c2 +2 2 +SELECT * FROM t1 USE INDEX (c2) WHERE c2=2; +c1 c2 +2 2 +CREATE VIEW v1 AS SELECT c1, c2 FROM t1; +SHOW INDEX FROM v1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +SELECT * FROM v1 USE INDEX (PRIMARY) WHERE c1=2; +ERROR HY000: Key 'PRIMARY' doesn't exist in table 'v1' +SELECT * FROM v1 FORCE INDEX (PRIMARY) WHERE c1=2; +ERROR HY000: Key 'PRIMARY' doesn't exist in table 'v1' +SELECT * FROM v1 IGNORE INDEX (PRIMARY) WHERE c1=2; +ERROR HY000: Key 'PRIMARY' doesn't exist in table 'v1' +SELECT * FROM v1 USE INDEX (c2) WHERE c2=2; +ERROR HY000: Key 'c2' doesn't exist in table 'v1' +SELECT * FROM v1 FORCE INDEX (c2) WHERE c2=2; +ERROR HY000: Key 'c2' doesn't exist in table 'v1' +SELECT * FROM v1 IGNORE INDEX (c2) WHERE c2=2; +ERROR HY000: Key 'c2' doesn't exist in table 'v1' +DROP VIEW v1; +DROP TABLE t1; # ----------------------------------------------------------------- # -- End of 5.0 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index bcf31a4501d..2892ee7dd69 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -510,7 +510,7 @@ drop table t1; # create table t1 (a int, b int); create view v1 as select a, sum(b) from t1 group by a; ---error ER_WRONG_USAGE +--error ER_KEY_DOES_NOT_EXITS select b from v1 use index (some_index) where b=1; drop view v1; drop table t1; @@ -3424,11 +3424,11 @@ drop table t1; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2); CREATE VIEW v1 AS SELECT * FROM t1; ---error ER_WRONG_USAGE +--error ER_KEY_DOES_NOT_EXITS SELECT * FROM v1 USE KEY(non_existant); ---error ER_WRONG_USAGE +--error ER_KEY_DOES_NOT_EXITS SELECT * FROM v1 FORCE KEY(non_existant); ---error ER_WRONG_USAGE +--error ER_KEY_DOES_NOT_EXITS SELECT * FROM v1 IGNORE KEY(non_existant); DROP VIEW v1; @@ -3568,6 +3568,32 @@ DROP VIEW v1; CREATE VIEW v1 AS SELECT 1; DROP VIEW v1; +# +# Bug #33461: SELECT ... FROM USE INDEX (...) throws an error +# + +CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT, INDEX (c2)); +INSERT INTO t1 VALUES (1,1), (2,2), (3,3); +SELECT * FROM t1 USE INDEX (PRIMARY) WHERE c1=2; +SELECT * FROM t1 USE INDEX (c2) WHERE c2=2; + +CREATE VIEW v1 AS SELECT c1, c2 FROM t1; +SHOW INDEX FROM v1; +--error ER_KEY_DOES_NOT_EXITS +SELECT * FROM v1 USE INDEX (PRIMARY) WHERE c1=2; +--error ER_KEY_DOES_NOT_EXITS +SELECT * FROM v1 FORCE INDEX (PRIMARY) WHERE c1=2; +--error ER_KEY_DOES_NOT_EXITS +SELECT * FROM v1 IGNORE INDEX (PRIMARY) WHERE c1=2; +--error ER_KEY_DOES_NOT_EXITS +SELECT * FROM v1 USE INDEX (c2) WHERE c2=2; +--error ER_KEY_DOES_NOT_EXITS +SELECT * FROM v1 FORCE INDEX (c2) WHERE c2=2; +--error ER_KEY_DOES_NOT_EXITS +SELECT * FROM v1 IGNORE INDEX (c2) WHERE c2=2; + +DROP VIEW v1; +DROP TABLE t1; --echo # ----------------------------------------------------------------- --echo # -- End of 5.0 tests. diff --git a/sql/sql_view.cc b/sql/sql_view.cc index f65a62bed75..5bd3c09a289 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -980,13 +980,14 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, DBUG_RETURN(0); } - if (table->use_index || table->ignore_index) + List *index_list= table->use_index ? table->use_index + : table->ignore_index; + if (index_list) { - my_error(ER_WRONG_USAGE, MYF(0), - table->ignore_index ? "IGNORE INDEX" : - (table->force_index ? "FORCE INDEX" : "USE INDEX"), - "VIEW"); - DBUG_RETURN(TRUE); + DBUG_ASSERT(index_list->head()); // should never fail + my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), index_list->head()->c_ptr_safe(), + table->table_name); + DBUG_RETURN(TRUE); } /* check loop via view definition */ -- cgit v1.2.1 From a9384a075ae79751c98577ca954cb5f32d4099f3 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Mon, 1 Dec 2008 12:14:02 +0400 Subject: After-push commit for bug #33461 to make valgrind happy: TABLE_LIST doesn't free Strings in its string lists (TABLE_LIST::use_index and TABLE_liST::ignore_index), so calling c_ptr_safe() on that Strings leads to memleaks. OTOH "safe" c_ptr_safe() is not necessary there and we can replace it with c_ptr(). --- sql/sql_view.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 5bd3c09a289..41a638b2618 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -985,7 +985,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, if (index_list) { DBUG_ASSERT(index_list->head()); // should never fail - my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), index_list->head()->c_ptr_safe(), + my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), index_list->head()->c_ptr(), table->table_name); DBUG_RETURN(TRUE); } -- cgit v1.2.1 From 3c53e76eb4a48a5edd6844f7d1db7f572c0c3833 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 1 Dec 2008 13:34:53 +0200 Subject: Addendum to bug #37339 : make the test case portable to windows by using and taking out a full path. mysql-test/r/ctype_filesystem.result: Bug #37399: use MYSQL_TEST_DIR rooted test mysql-test/t/ctype_filesystem-master.opt: Bug #37399: use MYSQL_TEST_DIR rooted test mysql-test/t/ctype_filesystem.test: Bug #37399: use MYSQL_TEST_DIR rooted test --- mysql-test/r/ctype_filesystem.result | 2 +- mysql-test/t/ctype_filesystem-master.opt | 2 +- mysql-test/t/ctype_filesystem.test | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ctype_filesystem.result b/mysql-test/r/ctype_filesystem.result index 8a8f0f7f8cc..b461cf2a1a4 100644 --- a/mysql-test/r/ctype_filesystem.result +++ b/mysql-test/r/ctype_filesystem.result @@ -1,7 +1,7 @@ SET CHARACTER SET utf8; SHOW VARIABLES like 'character_sets_dir'; Variable_name Value -character_sets_dir /ß/ +character_sets_dir MYSQL_TEST_DIR/ß/ SHOW VARIABLES like 'character_set_filesystem'; Variable_name Value character_set_filesystem latin1 diff --git a/mysql-test/t/ctype_filesystem-master.opt b/mysql-test/t/ctype_filesystem-master.opt index cb3427571b5..44127f68664 100644 --- a/mysql-test/t/ctype_filesystem-master.opt +++ b/mysql-test/t/ctype_filesystem-master.opt @@ -1,2 +1,2 @@ ---character-sets-dir=/ß +--character-sets-dir=$MYSQL_TEST_DIR/ß --character-set-filesystem=latin1 diff --git a/mysql-test/t/ctype_filesystem.test b/mysql-test/t/ctype_filesystem.test index 30b1607008b..2b993c2b924 100644 --- a/mysql-test/t/ctype_filesystem.test +++ b/mysql-test/t/ctype_filesystem.test @@ -1,4 +1,5 @@ SET CHARACTER SET utf8; +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR SHOW VARIABLES like 'character_sets_dir'; SHOW VARIABLES like 'character_set_filesystem'; SHOW VARIABLES like 'character_set_client'; -- cgit v1.2.1 From 4a10c789c09c167453d6bf0e4e5512f774105ab9 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 1 Dec 2008 16:18:35 +0200 Subject: Bug #39920: MySQL cannot deal with Leap Second expression in string literal. Updated MySQL time handling code to react correctly on UTC leap second additions. MySQL functions that return the OS current time, like e.g. CURDATE(), NOW() etc will return :59:59 instead of :59:60 or 59:61. As a result the reader will receive :59:59 for 2 or 3 consecutive seconds during the leap second. This fix will not affect the values returned by UNIX_TIMESTAMP() for leap seconds. But note that when converting the value returned by UNIX_TIMESTAMP() to broken down time the correction of leap seconds will still be applied. Note that this fix will make a difference *only* if the OS is specially configured to return leap seconds from the OS time calls or when using a MySQL time zone defintion that has leap seconds. Even after this change date/time literals (or other broken down time representations) with leap seconds (ending on :59:60 or 59:61) will still be considered illegal and discarded by the server with an error or a warning depending on the sql mode. Added a test case to demonstrate the effect of the fix. mysql-test/r/timezone3.result: Bug #39920: test case mysql-test/std_data/Moscow_leap: Bug #39920: updated the Moscow time zone to Dr. Olson's tzdata 2008i to accomodate for the 2008 leap second mysql-test/t/timezone3.test: Bug #39920: test case sql/tztime.cc: Bug #39920: adjust leap seconds (:60 or :61) to :59 sql/tztime.h: Bug #39920: adjust leap seconds (:60 or :61) to :59 --- mysql-test/r/timezone3.result | 8 ++++++++ mysql-test/std_data/Moscow_leap | Bin 991 -> 2674 bytes mysql-test/t/timezone3.test | 12 ++++++++++++ sql/tztime.cc | 22 ++++++++++++++++++++++ sql/tztime.h | 3 +++ 5 files changed, 45 insertions(+) diff --git a/mysql-test/r/timezone3.result b/mysql-test/r/timezone3.result index ec0b6045f93..ceac4a5aefb 100644 --- a/mysql-test/r/timezone3.result +++ b/mysql-test/r/timezone3.result @@ -17,6 +17,9 @@ insert into t1 values insert into t1 values (unix_timestamp('1981-07-01 03:59:59'),'1981-07-01 03:59:59'), (unix_timestamp('1981-07-01 04:00:00'),'1981-07-01 04:00:00'); +insert into t1 values +(unix_timestamp('2009-01-01 02:59:59'),'2009-01-01 02:59:59'), +(unix_timestamp('2009-01-01 03:00:00'),'2009-01-01 03:00:00'); select i, from_unixtime(i), c from t1; i from_unixtime(i) c 1072904422 2004-01-01 00:00:00 2004-01-01 00:00:00 @@ -31,6 +34,8 @@ i from_unixtime(i) c 1099180821 2004-10-31 02:59:59 2004-10-31 02:59:59 362793608 1981-07-01 03:59:59 1981-07-01 03:59:59 362793610 1981-07-01 04:00:00 1981-07-01 04:00:00 +1230768022 2009-01-01 02:59:59 2009-01-01 02:59:59 +1230768024 2009-01-01 03:00:00 2009-01-01 03:00:00 drop table t1; create table t1 (ts timestamp); insert into t1 values (19730101235900), (20040101235900); @@ -39,3 +44,6 @@ ts 1973-01-01 23:59:00 2004-01-01 23:59:00 drop table t1; +SELECT FROM_UNIXTIME(1230768022), FROM_UNIXTIME(1230768023), FROM_UNIXTIME(1230768024); +FROM_UNIXTIME(1230768022) FROM_UNIXTIME(1230768023) FROM_UNIXTIME(1230768024) +2009-01-01 02:59:59 2009-01-01 02:59:59 2009-01-01 03:00:00 diff --git a/mysql-test/std_data/Moscow_leap b/mysql-test/std_data/Moscow_leap index 4994c005595..3e73923cfb3 100644 Binary files a/mysql-test/std_data/Moscow_leap and b/mysql-test/std_data/Moscow_leap differ diff --git a/mysql-test/t/timezone3.test b/mysql-test/t/timezone3.test index 0aedbafcec4..8a9941f6383 100644 --- a/mysql-test/t/timezone3.test +++ b/mysql-test/t/timezone3.test @@ -45,6 +45,10 @@ insert into t1 values (unix_timestamp('1981-07-01 03:59:59'),'1981-07-01 03:59:59'), (unix_timestamp('1981-07-01 04:00:00'),'1981-07-01 04:00:00'); +insert into t1 values + (unix_timestamp('2009-01-01 02:59:59'),'2009-01-01 02:59:59'), + (unix_timestamp('2009-01-01 03:00:00'),'2009-01-01 03:00:00'); + select i, from_unixtime(i), c from t1; drop table t1; @@ -58,4 +62,12 @@ insert into t1 values (19730101235900), (20040101235900); select * from t1; drop table t1; +# +# Test Bug #39920: MySQL cannot deal with Leap Second expression in string +# literal +# + +# 2009-01-01 02:59:59, 2009-01-01 02:59:60 and 2009-01-01 03:00:00 +SELECT FROM_UNIXTIME(1230768022), FROM_UNIXTIME(1230768023), FROM_UNIXTIME(1230768024); + # End of 4.1 tests diff --git a/sql/tztime.cc b/sql/tztime.cc index 709e3b64752..d3d952e3c1e 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1073,6 +1073,7 @@ Time_zone_system::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const localtime_r(&tmp_t, &tmp_tm); localtime_to_TIME(tmp, &tmp_tm); tmp->time_type= MYSQL_TIMESTAMP_DATETIME; + adjust_leap_second(tmp); } @@ -1157,6 +1158,7 @@ Time_zone_utc::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const gmtime_r(&tmp_t, &tmp_tm); localtime_to_TIME(tmp, &tmp_tm); tmp->time_type= MYSQL_TIMESTAMP_DATETIME; + adjust_leap_second(tmp); } @@ -1260,6 +1262,7 @@ void Time_zone_db::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const { ::gmt_sec_to_TIME(tmp, t, tz_info); + adjust_leap_second(tmp); } @@ -2373,6 +2376,25 @@ Time_zone *my_tz_find_with_opening_tz_tables(THD *thd, const String *name) DBUG_RETURN(tz); } + +/** + Convert leap seconds into non-leap + + This function will convert the leap seconds added by the OS to + non-leap seconds, e.g. 23:59:59, 23:59:60 -> 23:59:59, 00:00:01 ... + This check is not checking for years on purpose : although it's not a + complete check this way it doesn't require looking (and having installed) + the leap seconds table. + + @param[in,out] broken down time structure as filled in by the OS +*/ + +void Time_zone::adjust_leap_second(MYSQL_TIME *t) +{ + if (t->second == 60 || t->second == 61) + t->second= 59; +} + #endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */ diff --git a/sql/tztime.h b/sql/tztime.h index 32a942a26e1..750b8dacbe1 100644 --- a/sql/tztime.h +++ b/sql/tztime.h @@ -55,6 +55,9 @@ public: allocated on MEM_ROOT and should not require destruction. */ virtual ~Time_zone() {}; + +protected: + static inline void adjust_leap_second(MYSQL_TIME *t); }; extern Time_zone * my_tz_UTC; -- cgit v1.2.1 From 0cc91d084a45983b88bdb09b2bf5a7a1e77a4827 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 1 Dec 2008 17:41:06 +0200 Subject: addendum to the fix for bug #39920 : post-merge test suite fixes --- mysql-test/r/timezone2.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/timezone2.result b/mysql-test/r/timezone2.result index bb1d764ac8c..e115ce16fa4 100644 --- a/mysql-test/r/timezone2.result +++ b/mysql-test/r/timezone2.result @@ -110,7 +110,7 @@ i ts 362793610 1981-07-01 04:00:00 select from_unixtime(362793609); from_unixtime(362793609) -1981-07-01 03:59:60 +1981-07-01 03:59:59 drop table t1; create table t1 (ts timestamp); set time_zone='UTC'; -- cgit v1.2.1 From 13d8f68a6e498e8028ed630b8026a43dbb209fea Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 2 Dec 2008 14:50:40 +0200 Subject: moved the version to 5.0-main --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..f79c1cd6319 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.0-bugteam" +tree_name = "mysql-5.0" -- cgit v1.2.1 From 0e55999388f307bad6c6024c092d517f48cc9841 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 3 Dec 2008 01:09:05 +0100 Subject: Raise version number after cloning 5.0.74 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 83220a879f0..2d942bc7e85 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.74) +AM_INIT_AUTOMAKE(mysql, 5.0.76) 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=74 +NDB_VERSION_BUILD=76 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? -- cgit v1.2.1 From 285d774ece6d2aba6123b9b054ecb59fbe9738e5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 3 Dec 2008 05:11:48 +0100 Subject: Remove bashisms from BUILD/compile-dist and configure.in, so Bootstrap works on Solaris box; force GNU make in compile-dist; remove unportable "grep -q" from configure.in --- BUILD/compile-dist | 36 ++++++++++++++++++++++++++++-------- configure.in | 28 ++++++++++++++++------------ 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/BUILD/compile-dist b/BUILD/compile-dist index 613f2643c56..7c2dbe00dc5 100755 --- a/BUILD/compile-dist +++ b/BUILD/compile-dist @@ -15,30 +15,49 @@ autoconf (cd bdb/dist && sh s_all) (cd innobase && aclocal && autoheader && aclocal && automake && autoconf) +gmake= +for x in gmake gnumake make; do + if $x --version 2>/dev/null | grep GNU > /dev/null; then + gmake=$x + break; + fi +done + +if [ -z "$gmake" ]; then + # Our build may not depend on GNU make, but I wouldn't count on it + echo "Please install GNU make, and ensure it is in your path as gnumake, gmake, or make" >&2 + exit 2 +fi + # Default to gcc for CC and CXX if test -z "$CXX" ; then - export CXX=gcc + export CXX + CXX=gcc # Set some required compile options if test -z "$CXXFLAGS" ; then - export CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" + export CXXFLAGS + CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" fi fi if test -z "$CC" ; then - export CC=gcc + export CC + CC=gcc fi # Use ccache, if available if ccache -V > /dev/null 2>&1 then - if ! (echo "$CC" | grep "ccache" > /dev/null) + if echo "$CC" | grep -v ccache > /dev/null then - export CC="ccache $CC" + export CC + CC="ccache $CC" fi - if ! (echo "$CXX" | grep "ccache" > /dev/null) + if echo "$CXX" | grep -v ccache > /dev/null then - export CXX="ccache $CXX" + export CXX + CXX="ccache $CXX" fi fi @@ -50,4 +69,5 @@ fi --enable-thread-safe-client \ --with-extra-charsets=complex \ --with-ndbcluster -make + +$gmake diff --git a/configure.in b/configure.in index 83220a879f0..448d3c90a26 100644 --- a/configure.in +++ b/configure.in @@ -409,7 +409,7 @@ fi MYSQL_PROG_AR # libmysqlclient versioning when linked with GNU ld. -if $LD --version 2>/dev/null|grep -q GNU; then +if $LD --version 2>/dev/null|grep GNU > /dev/null; then LD_VERSION_SCRIPT="-Wl,--version-script=\$(top_builddir)/libmysql/libmysql.ver" AC_CONFIG_FILES(libmysql/libmysql.ver) fi @@ -437,11 +437,13 @@ dnl Find paths to some shell programs AC_PATH_PROG(LN, ln, ln) # This must be able to take a -f flag like normal unix ln. AC_PATH_PROG(LN_CP_F, ln, ln) -if ! ( expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null ); then -# If ln -f does not exists use -s (AFS systems) -if test -n "$LN_CP_F"; then - LN_CP_F="$LN_CP_F -s" -fi +if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then + : +else + # If ln -f does not exists use -s (AFS systems) + if test -n "$LN_CP_F"; then + LN_CP_F="$LN_CP_F -s" + fi fi AC_PATH_PROG(MV, mv, mv) @@ -1940,14 +1942,16 @@ MYSQL_CHECK_IN_ADDR_T # Do the c++ compiler have a bool type MYSQL_CXX_BOOL # Check some common bugs with gcc 2.8.# on sparc -if ! ( expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null ); then -MYSQL_CHECK_LONGLONG_TO_FLOAT -if test "$ac_cv_conv_longlong_to_float" != "yes" -then - AC_MSG_ERROR([Your compiler cannot convert a longlong value to a float! +if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then + : +else + MYSQL_CHECK_LONGLONG_TO_FLOAT + if test "$ac_cv_conv_longlong_to_float" != "yes" + then + AC_MSG_ERROR([Your compiler cannot convert a longlong value to a float! If you are using gcc 2.8.# you should upgrade to egcs 1.0.3 or newer and try again]) -fi + fi fi AC_CHECK_TYPES([sigset_t, off_t], [], [], [#include ]) AC_CHECK_TYPES([size_t], [], [], [#include ]) -- cgit v1.2.1 From 7aa1074c23212ba89477ef098d6bcdcb3f0fb895 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Wed, 3 Dec 2008 19:15:39 +0300 Subject: Fix for bug #27483: Casting 'scientific notation type' to 'unsigned bigint' fails on windows. Visual Studio does not take into account some x86 hardware limitations which leads to incorrect results when converting large DOUBLE values to BIGINT UNSIGNED ones. Fixed by adding a workaround for double->ulonglong conversion on Windows. include/config-win.h: Added double2ulonglong(double) function implementing a workaround for broken double->ulonglong conversion on Windows/x86. include/my_global.h: Define double2ulonglong() as a simple typecast for anything but Windows. mysql-test/r/type_float.result: Added a test case for bug #27483. mysql-test/t/type_float.test: Added a test case for bug #27483. --- include/config-win.h | 9 +++++++++ include/my_global.h | 3 +++ mysql-test/r/type_float.result | 13 +++++++++++++ mysql-test/t/type_float.test | 17 +++++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/include/config-win.h b/include/config-win.h index 2628095a181..eba699159c7 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -245,6 +245,15 @@ inline double ulonglong2double(ulonglong value) #define my_off_t2double(A) ulonglong2double(A) #endif /* _WIN64 */ +inline ulonglong double2ulonglong(double d) +{ + double t= d - (double) 0x8000000000000000ULL; + + if (t >= 0) + return ((ulonglong) t) + 0x8000000000000000ULL; + return (ulonglong) d; +} + #if SIZEOF_OFF_T > 4 #define lseek(A,B,C) _lseeki64((A),(longlong) (B),(C)) #define tell(A) _telli64(A) diff --git a/include/my_global.h b/include/my_global.h index e474b620d27..845ae042a42 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -713,6 +713,9 @@ typedef SOCKET_SIZE_TYPE size_socket; #define ulonglong2double(A) ((double) (ulonglong) (A)) #define my_off_t2double(A) ((double) (my_off_t) (A)) #endif +#ifndef double2ulonglong +#define double2ulonglong(A) ((ulonglong) (double) (A)) +#endif #endif #ifndef offsetof diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index f1075604ca9..e7f17bd75a7 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -392,4 +392,17 @@ f1 + 0e0 1.0000000150475e+30 -1.0000000150475e+30 drop table t1; +create table t1(d double, u bigint unsigned); +insert into t1(d) values (9.2233720368547777e+18), +(9.223372036854779e18), +(9.22337203685479e18), +(1.84e19); +update t1 set u = d; +select * from t1; +d u +9.22337203685478e+18 9223372036854775808 +9.22337203685478e+18 9223372036854779904 +9.22337203685479e+18 9223372036854790144 +1.84e+19 18400000000000000000 +drop table t1; End of 5.0 tests diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 9aa8c00d24a..b23755b44fb 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -252,4 +252,21 @@ insert into t1 values (2e30), (-2e30); select f1 + 0e0 from t1; drop table t1; +# +# Bug #27483: Casting 'scientific notation type' to 'unsigned bigint' fails on +# windows. +# + +create table t1(d double, u bigint unsigned); + +insert into t1(d) values (9.2233720368547777e+18), + (9.223372036854779e18), + (9.22337203685479e18), + (1.84e19); + +update t1 set u = d; +select * from t1; + +drop table t1; + --echo End of 5.0 tests -- cgit v1.2.1 From abeed3f879a3ba089652a6cc4a65537f6851dd3e Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 4 Dec 2008 01:01:03 +0000 Subject: BUG#38826 Race in MYSQL_LOG::purge_logs is impossible to debug in production BUG#39325 Server crash inside MYSQL_LOG::purge_first_log halts replicaiton The patch reverses the order of the purging and updating events for log and relay-log.info/index files respectively. This solves the problem of having holes caused by crashes happening between updating info/index files and purging logs. NOTE: This is a combined patch for BUG#38826 and BUG#39325. This patch is based on bugteam tree and takes into account reviewers suggestions. --- mysql-test/r/binlog_index.result | 1 + sql/log.cc | 212 ++++++++++++++++++++++++--------------- sql/sql_class.h | 7 ++ 3 files changed, 141 insertions(+), 79 deletions(-) diff --git a/mysql-test/r/binlog_index.result b/mysql-test/r/binlog_index.result index 82fc26092f4..b307b97e460 100644 --- a/mysql-test/r/binlog_index.result +++ b/mysql-test/r/binlog_index.result @@ -21,6 +21,7 @@ flush logs; *** must be a warning master-bin.000001 was not found *** Warnings: Warning 1477 Being purged log MYSQLTEST_VARDIR/log/master-bin.000001 was not found +Warning 1477 Being purged log MYSQLTEST_VARDIR/log/master-bin.000001 was not found *** must show one record, of the active binlog, left in the index file after PURGE *** show binary logs; Log_name File_size diff --git a/sql/log.cc b/sql/log.cc index 5a1cfe46686..477cb21b2f3 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -417,6 +417,7 @@ MYSQL_LOG::MYSQL_LOG() index_file_name[0] = 0; bzero((char*) &log_file,sizeof(log_file)); bzero((char*) &index_file, sizeof(index_file)); + bzero((char*) &purge_temp, sizeof(purge_temp)); } /* this is called only once */ @@ -1059,10 +1060,10 @@ err: IMPLEMENTATION - Protects index file with LOCK_index + - Read the next file name from the index file and store in rli->linfo - Delete relevant relay log files - Copy all file names after these ones to the front of the index file - If the OS has truncate, truncate the file, else fill it with \n' - - Read the next file name from the index file and store in rli->linfo RETURN VALUES 0 ok @@ -1076,6 +1077,7 @@ err: int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli, bool included) { int error; + char *to_purge_if_included= NULL; DBUG_ENTER("purge_first_log"); DBUG_ASSERT(is_open()); @@ -1083,36 +1085,20 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli, bool included) DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->event_relay_log_name)); pthread_mutex_lock(&LOCK_index); - pthread_mutex_lock(&rli->log_space_lock); - rli->relay_log.purge_logs(rli->group_relay_log_name, included, - 0, 0, &rli->log_space_total); - // Tell the I/O thread to take the relay_log_space_limit into account - rli->ignore_log_space_limit= 0; - pthread_mutex_unlock(&rli->log_space_lock); + to_purge_if_included= my_strdup(rli->group_relay_log_name, MYF(0)); - /* - Ok to broadcast after the critical region as there is no risk of - the mutex being destroyed by this thread later - this helps save - context switches - */ - pthread_cond_broadcast(&rli->log_space_cond); - /* Read the next log file name from the index file and pass it back to - the caller - If included is true, we want the first relay log; - otherwise we want the one after event_relay_log_name. + the caller. */ - if ((included && (error=find_log_pos(&rli->linfo, NullS, 0))) || - (!included && - ((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)) || - (error=find_next_log(&rli->linfo, 0))))) + if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)) || + (error=find_next_log(&rli->linfo, 0))) { char buff[22]; sql_print_error("next log error: %d offset: %s log: %s included: %d", error, llstr(rli->linfo.index_file_offset,buff), - rli->group_relay_log_name, + rli->event_relay_log_name, included); goto err; } @@ -1140,7 +1126,42 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli, bool included) /* Store where we are in the new file for the execution thread */ flush_relay_log_info(rli); + DBUG_EXECUTE_IF("crash_before_purge_logs", abort();); + + pthread_mutex_lock(&rli->log_space_lock); + rli->relay_log.purge_logs(to_purge_if_included, included, + 0, 0, &rli->log_space_total); + // Tell the I/O thread to take the relay_log_space_limit into account + rli->ignore_log_space_limit= 0; + pthread_mutex_unlock(&rli->log_space_lock); + + /* + Ok to broadcast after the critical region as there is no risk of + the mutex being destroyed by this thread later - this helps save + context switches + */ + pthread_cond_broadcast(&rli->log_space_cond); + + /* + * Need to update the log pos because purge logs has been called + * after fetching initially the log pos at the begining of the method. + */ + if(error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)) + { + char buff[22]; + sql_print_error("next log error: %d offset: %s log: %s included: %d", + error, + llstr(rli->linfo.index_file_offset,buff), + rli->group_relay_log_name, + included); + goto err; + } + + /* If included was passed, rli->linfo should be the first entry. */ + DBUG_ASSERT(!included || rli->linfo.index_file_start_offset == 0); + err: + my_free(to_purge_if_included, MYF(0)); pthread_mutex_unlock(&LOCK_index); DBUG_RETURN(error); } @@ -1199,8 +1220,36 @@ int MYSQL_LOG::purge_logs(const char *to_log, if (need_mutex) pthread_mutex_lock(&LOCK_index); - if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/))) + if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/))) + { + sql_print_error("MYSQL_LOG::purge_logs was called with file %s not " + "listed in the index.", to_log); goto err; + } + + /* + For crash recovery reasons the index needs to be updated before + any files are deleted. Move files to be deleted into a temp file + to be processed after the index is updated. + */ + if (!my_b_inited(&purge_temp)) + { + if (error=open_cached_file(&purge_temp, mysql_tmpdir, TEMP_PREFIX, + DISK_BUFFER_SIZE, MYF(MY_WME))) + { + sql_print_error("MYSQL_LOG::purge_logs failed to open purge_temp"); + goto err; + } + } + else + { + if (error=reinit_io_cache(&purge_temp, WRITE_CACHE, 0, 0, 1)) + { + sql_print_error("MYSQL_LOG::purge_logs failed to reinit purge_temp " + "for write"); + goto err; + } + } /* File name exists in index file; delete until we find this file @@ -1211,6 +1260,59 @@ int MYSQL_LOG::purge_logs(const char *to_log, while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) && !log_in_use(log_info.log_file_name)) { + if ((error=my_b_write(&purge_temp, (byte*)log_info.log_file_name, + strlen(log_info.log_file_name))) || + (error=my_b_write(&purge_temp, (byte*)"\n", 1))) + { + sql_print_error("MYSQL_LOG::purge_logs failed to copy %s to purge_temp", + log_info.log_file_name); + goto err; + } + + if (find_next_log(&log_info, 0) || exit_loop) + break; + } + + /* We know how many files to delete. Update index file. */ + if (error=update_log_index(&log_info, need_update_threads)) + { + sql_print_error("MSYQL_LOG::purge_logs failed to update the index file"); + goto err; + } + + DBUG_EXECUTE_IF("crash_after_update_index", abort();); + + /* Switch purge_temp for read. */ + if (error=reinit_io_cache(&purge_temp, READ_CACHE, 0, 0, 0)) + { + sql_print_error("MSYQL_LOG::purge_logs failed to reinit purge_temp " + "for read"); + goto err; + } + + /* Read each entry from purge_temp and delete the file. */ + for (;;) + { + uint length; + + if ((length=my_b_gets(&purge_temp, log_info.log_file_name, + FN_REFLEN)) <= 1) + { + if (purge_temp.error) + { + error= purge_temp.error; + sql_print_error("MSYQL_LOG::purge_logs error %d reading from " + "purge_temp", error); + goto err; + } + + /* Reached EOF */ + break; + } + + /* Get rid of the trailing '\n' */ + log_info.log_file_name[length-1]= 0; + MY_STAT s; if (!my_stat(log_info.log_file_name, &s, MYF(0))) { @@ -1304,15 +1406,7 @@ int MYSQL_LOG::purge_logs(const char *to_log, } } } - if (find_next_log(&log_info, 0) || exit_loop) - break; } - - /* - If we get killed -9 here, the sysadmin would have to edit - the log index file after restart - otherwise, this should be safe - */ - error= update_log_index(&log_info, need_update_threads); err: if (need_mutex) @@ -1326,7 +1420,6 @@ err: SYNOPSIS purge_logs_before_date() - thd Thread pointer before_date Delete all log files before given date. NOTES @@ -1343,6 +1436,7 @@ err: int MYSQL_LOG::purge_logs_before_date(time_t purge_time) { int error; + char to_log[FN_REFLEN]; LOG_INFO log_info; MY_STAT stat_area; THD *thd= current_thd; @@ -1350,12 +1444,8 @@ int MYSQL_LOG::purge_logs_before_date(time_t purge_time) DBUG_ENTER("purge_logs_before_date"); pthread_mutex_lock(&LOCK_index); + to_log[0]= 0; - /* - Delete until we find curren file - or a file that is used or a file - that is older than purge_time. - */ if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/))) goto err; @@ -1405,54 +1495,18 @@ int MYSQL_LOG::purge_logs_before_date(time_t purge_time) } else { - if (stat_area.st_mtime >= purge_time) + if (stat_area.st_mtime < purge_time) + strmake(to_log, + log_info.log_file_name, + sizeof(log_info.log_file_name)); + else break; - if (my_delete(log_info.log_file_name, MYF(0))) - { - if (my_errno == ENOENT) - { - /* It's not fatal even if we can't delete a log file */ - if (thd) - { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE), - log_info.log_file_name); - } - sql_print_information("Failed to delete file '%s'", - log_info.log_file_name); - my_errno= 0; - } - else - { - if (thd) - { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, - ER_BINLOG_PURGE_FATAL_ERR, - "a problem with deleting %s; " - "consider examining correspondence " - "of your binlog index file " - "to the actual binlog files", - log_info.log_file_name); - } - else - { - sql_print_information("Failed to delete log file '%s'", - log_info.log_file_name); - } - error= LOG_INFO_FATAL; - goto err; - } - } } if (find_next_log(&log_info, 0)) break; } - /* - If we get killed -9 here, the sysadmin would have to edit - the log index file after restart - otherwise, this should be safe - */ - error= update_log_index(&log_info, 1); + error= (to_log[0] ? purge_logs(to_log, 1, 0, 1, (ulonglong *) 0) : 0); err: pthread_mutex_unlock(&LOCK_index); diff --git a/sql/sql_class.h b/sql/sql_class.h index c8d42d44df7..cc7ef7809d4 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -205,6 +205,13 @@ class MYSQL_LOG: public TC_LOG time_t last_time,query_start; IO_CACHE log_file; IO_CACHE index_file; + /* + purge_temp is a temp file used in purge_logs so that the index file + can be updated before deleting files from disk, yielding better crash + recovery. It is created on demand the first time purge_logs is called + and then reused for subsequent calls. It is cleaned up in cleanup(). + */ + IO_CACHE purge_temp; char *name; char time_buff[20],db[NAME_LEN+1]; char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN]; -- cgit v1.2.1 From 8425ef4665c0e3a119b69b922eae519f28216d45 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Thu, 4 Dec 2008 18:36:45 +0200 Subject: Bug #33420 Test 'rpl_packet' fails randomly with changed "Exec_Master_Log_Pos" Bug #41173 rpl_packet fails sporadically on pushbuild: query 'DROP TABLE t1' failed The both issues appeared to be a race between the SQL thread executing CREATE table t1 and the IO thread that is expected to stop at the consequent big size event. The two events need serialization which is implemented. The early bug required back-porting a part fixes for bug#38350 exclusively for 5.0 version. mysql-test/r/rpl_packet.result: results changed due to bug#33420, bug#41173. mysql-test/t/rpl_packet.test: adding synchronization for sql and io thread (bug#41173 problem). simplifying the output to show only a relevant info (5.0 sole problem bug#33420). --- mysql-test/r/rpl_packet.result | 40 +++++----------------------------------- mysql-test/t/rpl_packet.test | 22 ++++++++++++++++------ 2 files changed, 21 insertions(+), 41 deletions(-) diff --git a/mysql-test/r/rpl_packet.result b/mysql-test/r/rpl_packet.result index 88c63994fff..f84ce18810e 100644 --- a/mysql-test/r/rpl_packet.result +++ b/mysql-test/r/rpl_packet.result @@ -23,39 +23,9 @@ SET @@global.max_allowed_packet=4096; SET @@global.net_buffer_length=4096; STOP SLAVE; START SLAVE; -CREATE TABLe `t1` (`f1` LONGTEXT) ENGINE=MyISAM; +CREATE TABLE `t1` (`f1` LONGTEXT) ENGINE=MyISAM; INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048'); -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 2138 -Relay_Log_File # -Relay_Log_Pos # -Relay_Master_Log_File master-bin.000001 -Slave_IO_Running No -Slave_SQL_Running # -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 2138 -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 # +Slave_IO_Running = No (expect No) +==== clean up ==== +DROP TABLE t1; +DROP TABLE t1; diff --git a/mysql-test/t/rpl_packet.test b/mysql-test/t/rpl_packet.test index a3efdf24bce..f7066c93b30 100644 --- a/mysql-test/t/rpl_packet.test +++ b/mysql-test/t/rpl_packet.test @@ -73,16 +73,26 @@ disconnect master; connect (master, localhost, root); connection master; -CREATE TABLe `t1` (`f1` LONGTEXT) ENGINE=MyISAM; +CREATE TABLE `t1` (`f1` LONGTEXT) ENGINE=MyISAM; + +sync_slave_with_master; + +connection master; INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048'); # The slave I/O thread must stop after trying to read the above event connection slave; ---source include/wait_for_slave_io_to_stop.inc ---replace_result $MASTER_MYPORT MASTER_MYPORT -# import is only the 11th column Slave_IO_Running ---replace_column 1 # 8 # 9 # 12 # 23 # 33 # -query_vertical show slave status; +--source include/wait_for_slave_io_to_stop.inc +let $slave_io_running= query_get_value(SHOW SLAVE STATUS, Slave_IO_Running, 1); +--echo Slave_IO_Running = $slave_io_running (expect No) + + +--echo ==== clean up ==== +connection master; +DROP TABLE t1; +# slave is stopped +connection slave; +DROP TABLE t1; # End of tests -- cgit v1.2.1 From 1fc3a49a7dfb0ed341cee908c9e2dab7b3bc74d5 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Fri, 5 Dec 2008 08:21:03 -0500 Subject: Bug#41258: mysql-test-run does not copy subdirectories of std_data on Windows (5.0 only) Altered how we copy data from mysql-test/std_data on Windows to match what we are doing in 5.1 and 6.0 --- mysql-test/mysql-test-run.pl | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 268dd3fbd16..70637034b6e 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2380,13 +2380,7 @@ sub setup_vardir() { { # on windows, copy all files from std_data into var/std_data_ln mkpath("$opt_vardir/std_data_ln"); - opendir(DIR, "$glob_mysql_test_dir/std_data") - or mtr_error("Can't find the std_data directory: $!"); - for(readdir(DIR)) { - next if -d "$glob_mysql_test_dir/std_data/$_"; - copy("$glob_mysql_test_dir/std_data/$_", "$opt_vardir/std_data_ln/$_"); - } - closedir(DIR); + mtr_copy_dir("$glob_mysql_test_dir/std_data", "$opt_vardir/std_data_ln"); } # Remove old log files -- cgit v1.2.1 From fbbcf450f4527cb2ee7c2130cfe1ba9a3472c7df Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Tue, 9 Dec 2008 11:05:36 +0300 Subject: Fixed type_float failures in --ps-protocol mode introduced by the test case for bug #27483. The reason for the failures was bug #21205 (fixed in 6.0 by dtoa, but still present in 5.0/5.1). mysql-test/r/type_float.result: Modified the failing test case so that bug #21205 does not occur. mysql-test/t/type_float.test: Modified the failing test case so that bug #21205 does not occur. --- mysql-test/r/type_float.result | 12 ++++++------ mysql-test/t/type_float.test | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index e7f17bd75a7..d86c515062a 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -398,11 +398,11 @@ insert into t1(d) values (9.2233720368547777e+18), (9.22337203685479e18), (1.84e19); update t1 set u = d; -select * from t1; -d u -9.22337203685478e+18 9223372036854775808 -9.22337203685478e+18 9223372036854779904 -9.22337203685479e+18 9223372036854790144 -1.84e+19 18400000000000000000 +select u from t1; +u +9223372036854775808 +9223372036854779904 +9223372036854790144 +18400000000000000000 drop table t1; End of 5.0 tests diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index b23755b44fb..3ceef129912 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -265,7 +265,7 @@ insert into t1(d) values (9.2233720368547777e+18), (1.84e19); update t1 set u = d; -select * from t1; +select u from t1; drop table t1; -- cgit v1.2.1 From 3cba827620befa5d3cb0d4240332534bce519d14 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 9 Dec 2008 13:53:23 +0400 Subject: Bug#35796 SHOW CREATE TABLE and default value for BIT field show default value for BIT field in printable format mysql-test/r/type_bit.result: Bug#35796 SHOW CREATE TABLE and default value for BIT field test result mysql-test/t/type_bit.test: Bug#35796 SHOW CREATE TABLE and default value for BIT field test case sql/item.cc: Bug#35796 SHOW CREATE TABLE and default value for BIT field issue an error if BIN|HEX deafult value is empty value (behaviour like for INT fields) --- mysql-test/r/type_bit.result | 15 +++++++++++++++ mysql-test/t/type_bit.test | 15 +++++++++++++++ sql/item.cc | 3 +++ sql/sql_show.cc | 18 +++++++++++++++--- 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 68c0e1635a3..2a83d9b4c62 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -708,4 +708,19 @@ HEX(b1) HEX(b2) i2 1 0 100 1 0 200 DROP TABLE t1, t2; +CREATE TABLE IF NOT EXISTS t1 ( +f1 bit(2) NOT NULL default b'10', +f2 bit(14) NOT NULL default b'11110000111100' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` bit(2) NOT NULL default b'10', + `f2` bit(14) NOT NULL default b'11110000111100' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci +DROP TABLE t1; +CREATE TABLE IF NOT EXISTS t1 ( +f1 bit(2) NOT NULL default b'' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci; +ERROR 42000: Invalid default value for 'f1' End of 5.0 tests diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index 6a6b29deda4..81dca17f112 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -352,4 +352,19 @@ SELECT HEX(b1), HEX(b2), i2 FROM t2 DROP TABLE t1, t2; +# +# Bug #35796 SHOW CREATE TABLE and default value for BIT field +# +CREATE TABLE IF NOT EXISTS t1 ( +f1 bit(2) NOT NULL default b'10', +f2 bit(14) NOT NULL default b'11110000111100' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--error ER_INVALID_DEFAULT +CREATE TABLE IF NOT EXISTS t1 ( +f1 bit(2) NOT NULL default b'' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci; + --echo End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index 182f4abdfe6..243c22bb7e6 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4950,6 +4950,9 @@ int Item_hex_string::save_in_field(Field *field, bool no_conversions) ulonglong nr; uint32 length= str_value.length(); + if (!length) + return 1; + if (length > 8) { nr= field->flags & UNSIGNED_FLAG ? ULONGLONG_MAX : LONGLONG_MAX; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 4e3d209f674..59082e0a295 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -798,7 +798,7 @@ static bool get_field_default_value(THD *thd, TABLE *table, { bool has_default; bool has_now_default; - + enum enum_field_types field_type= field->type(); /* We are using CURRENT_TIMESTAMP instead of NOW because it is more standard @@ -806,7 +806,7 @@ static bool get_field_default_value(THD *thd, TABLE *table, has_now_default= table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_UN_FIELD; - has_default= (field->type() != FIELD_TYPE_BLOB && + has_default= (field_type != FIELD_TYPE_BLOB && !(field->flags & NO_DEFAULT_VALUE_FLAG) && field->unireg_check != Field::NEXT_NUMBER && !((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) @@ -821,7 +821,19 @@ static bool get_field_default_value(THD *thd, TABLE *table, { // Not null by default char tmp[MAX_FIELD_WIDTH]; String type(tmp, sizeof(tmp), field->charset()); - field->val_str(&type); + if (field_type == MYSQL_TYPE_BIT) + { + longlong dec= field->val_int(); + char *ptr= longlong2str(dec, tmp + 2, 2); + uint32 length= (uint32) (ptr - tmp); + tmp[0]= 'b'; + tmp[1]= '\''; + tmp[length]= '\''; + type.length(length + 1); + quoted= 0; + } + else + field->val_str(&type); if (type.length()) { String def_val; -- cgit v1.2.1 From e51aca0322bc386c877db6ea2f179817558c93e5 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 9 Dec 2008 14:00:43 +0400 Subject: bug#35558 Wrong server metadata blows up the client the problem: FORMAT func max_length value was calculated incorrectly the fix: correct calculation of max_length mysql-test/r/func_str.result: test result mysql-test/t/func_str.test: test case sql/item_strfunc.h: the problem: FORMAT func max_length value was calculated incorrectly the fix: correct calculation of max_length --- mysql-test/r/func_str.result | 12 +++++++++--- mysql-test/t/func_str.test | 10 ++++++++++ sql/item_strfunc.h | 5 +++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index d0809eca65b..c121c8937d7 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -717,8 +717,6 @@ insert(_latin2'abcd',2,3,_latin2'ef'), replace(_latin2'abcd',_latin2'b',_latin2'B'), encode('abcd','ab') ; -Warnings: -Warning 1265 Data truncated for column 'format(130,10)' at row 1 show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -727,7 +725,7 @@ t1 CREATE TABLE `t1` ( `conv(130,16,10)` varchar(64) default NULL, `hex(130)` varchar(6) NOT NULL default '', `char(130)` varbinary(4) NOT NULL default '', - `format(130,10)` varchar(4) NOT NULL default '', + `format(130,10)` varchar(16) NOT NULL default '', `left(_latin2'a',1)` varchar(1) character set latin2 NOT NULL default '', `right(_latin2'a',1)` varchar(1) character set latin2 NOT NULL default '', `lcase(_latin2'a')` varchar(1) character set latin2 NOT NULL default '', @@ -2175,4 +2173,12 @@ SELECT HEX(c1) from v1; HEX(c1) 414243 DROP VIEW v1; +create table t1(a float); +insert into t1 values (1.33); +select format(a, 2) from t1; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def format(a, 2) 253 20 4 Y 0 2 8 +format(a, 2) +1.33 +drop table t1; End of 5.0 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 1ca2bbfaf4c..8298a50c277 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1149,4 +1149,14 @@ CREATE VIEW v1 AS SELECT CHAR(0x414243) as c1; SELECT HEX(c1) from v1; DROP VIEW v1; +# +# Bug #35558 Wrong server metadata blows up the client +# +create table t1(a float); +insert into t1 values (1.33); +--enable_metadata +select format(a, 2) from t1; +--disable_metadata +drop table t1; + --echo End of 5.0 tests diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 3648438a69b..23ac20a4017 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -516,8 +516,9 @@ public: { collation.set(default_charset()); uint char_length= args[0]->max_length/args[0]->collation.collation->mbmaxlen; - max_length= ((char_length + (char_length-args[0]->decimals)/3) * - collation.collation->mbmaxlen); + uint max_sep_count= char_length/3 + (decimals ? 1 : 0) + /*sign*/1; + max_length= (char_length + max_sep_count + decimals) * + collation.collation->mbmaxlen; } const char *func_name() const { return "format"; } void print(String *); -- cgit v1.2.1 From 348837925586a2f7acf42ab716457bb8a743e8b4 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Tue, 9 Dec 2008 13:19:46 +0300 Subject: Added a missing bit from the original patch for bug #27483 which was lost when re-applying the patch manually to another tree. --- sql/field.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/field.cc b/sql/field.cc index 8188b51d4d1..f8ab4b852ec 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3473,7 +3473,7 @@ int Field_longlong::store(double nr) error= 1; } else - res=(longlong) (ulonglong) nr; + res=(longlong) double2ulonglong(nr); } else { -- cgit v1.2.1 From 3f8a506a8f26f09ba622f2b5113e1bc9693de542 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 9 Dec 2008 16:38:52 +0400 Subject: Bug#31291 ALTER TABLE CONVERT TO CHARACTER SET does not change some data types added ability for TINY[MEDIUM] text fields to be converted to greater subtype during alter if necessary(altered charset) mysql-test/r/alter_table.result: test result mysql-test/t/alter_table.test: test case sql/sql_table.cc: added ability for TINY[MEDIUM] text fields to be converted to greater subtype during alter if necessary(altered charset) --- mysql-test/r/alter_table.result | 16 ++++++++++++++++ mysql-test/t/alter_table.test | 13 +++++++++++++ sql/sql_table.cc | 4 +++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 95c652055ec..d81086682f1 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -915,3 +915,19 @@ check table t1; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; +create table t1 (a tinytext character set latin1); +alter table t1 convert to character set utf8; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` text +) ENGINE=MyISAM DEFAULT CHARSET=utf8 +drop table t1; +create table t1 (a mediumtext character set latin1); +alter table t1 convert to character set utf8; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` longtext +) ENGINE=MyISAM DEFAULT CHARSET=utf8 +drop table t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index bcca122f9f8..18481291bba 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -696,3 +696,16 @@ unlock tables; select * from t1; check table t1; drop table t1; + + +# +# Bug#31291 ALTER TABLE CONVERT TO CHARACTER SET does not change some data types +# +create table t1 (a tinytext character set latin1); +alter table t1 convert to character set utf8; +show create table t1; +drop table t1; +create table t1 (a mediumtext character set latin1); +alter table t1 convert to character set utf8; +show create table t1; +drop table t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8baeca9ccf7..eefe2a5596e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1535,7 +1535,9 @@ static bool prepare_blob_field(THD *thd, create_field *sql_field) if ((sql_field->flags & BLOB_FLAG) && sql_field->length) { - if (sql_field->sql_type == FIELD_TYPE_BLOB) + if (sql_field->sql_type == FIELD_TYPE_BLOB || + sql_field->sql_type == FIELD_TYPE_TINY_BLOB || + sql_field->sql_type == FIELD_TYPE_MEDIUM_BLOB) { /* The user has given a length to the blob column */ sql_field->sql_type= get_blob_type_from_length(sql_field->length); -- cgit v1.2.1 From 0294c8bd103beddc01b8f9662ae78d399b3e28a7 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 9 Dec 2008 16:59:47 +0400 Subject: Bug#31399 Wrong query result when doing join buffering over BIT fields if table has bit fields then uneven bits(if exist) are stored into null bits place. So we need to copy null bits in case of uneven bit field presence. mysql-test/r/type_bit.result: test result mysql-test/t/type_bit.test: test case sql/sql_select.cc: if table has bit fields then uneven bits(if exist) are stored into null bits place. So we need to copy null bits in case of uneven bit field presence. --- mysql-test/r/type_bit.result | 26 ++++++++++++++++++++++++++ mysql-test/t/type_bit.test | 30 ++++++++++++++++++++++++++++++ sql/sql_select.cc | 8 ++++++-- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 2a83d9b4c62..63dec0297d0 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -723,4 +723,30 @@ CREATE TABLE IF NOT EXISTS t1 ( f1 bit(2) NOT NULL default b'' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci; ERROR 42000: Invalid default value for 'f1' +create table t1bit7 (a1 bit(7) not null) engine=MyISAM; +create table t2bit7 (b1 bit(7)) engine=MyISAM; +insert into t1bit7 values (b'1100000'); +insert into t1bit7 values (b'1100001'); +insert into t1bit7 values (b'1100010'); +insert into t2bit7 values (b'1100001'); +insert into t2bit7 values (b'1100010'); +insert into t2bit7 values (b'1100110'); +select bin(a1) from t1bit7, t2bit7 where t1bit7.a1=t2bit7.b1; +bin(a1) +1100001 +1100010 +drop table t1bit7, t2bit7; +create table t1bit7 (a1 bit(15) not null) engine=MyISAM; +create table t2bit7 (b1 bit(15)) engine=MyISAM; +insert into t1bit7 values (b'110000011111111'); +insert into t1bit7 values (b'110000111111111'); +insert into t1bit7 values (b'110001011111111'); +insert into t2bit7 values (b'110000111111111'); +insert into t2bit7 values (b'110001011111111'); +insert into t2bit7 values (b'110011011111111'); +select bin(a1) from t1bit7, t2bit7 where t1bit7.a1=t2bit7.b1; +bin(a1) +110000111111111 +110001011111111 +drop table t1bit7, t2bit7; End of 5.0 tests diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index 81dca17f112..bdc678688f1 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -367,4 +367,34 @@ CREATE TABLE IF NOT EXISTS t1 ( f1 bit(2) NOT NULL default b'' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci; + +# +# Bug#31399 Wrong query result when doing join buffering over BIT fields +# +create table t1bit7 (a1 bit(7) not null) engine=MyISAM; +create table t2bit7 (b1 bit(7)) engine=MyISAM; + +insert into t1bit7 values (b'1100000'); +insert into t1bit7 values (b'1100001'); +insert into t1bit7 values (b'1100010'); +insert into t2bit7 values (b'1100001'); +insert into t2bit7 values (b'1100010'); +insert into t2bit7 values (b'1100110'); + +select bin(a1) from t1bit7, t2bit7 where t1bit7.a1=t2bit7.b1; +drop table t1bit7, t2bit7; + +create table t1bit7 (a1 bit(15) not null) engine=MyISAM; +create table t2bit7 (b1 bit(15)) engine=MyISAM; + +insert into t1bit7 values (b'110000011111111'); +insert into t1bit7 values (b'110000111111111'); +insert into t1bit7 values (b'110001011111111'); +insert into t2bit7 values (b'110000111111111'); +insert into t2bit7 values (b'110001011111111'); +insert into t2bit7 values (b'110011011111111'); + +select bin(a1) from t1bit7, t2bit7 where t1bit7.a1=t2bit7.b1; +drop table t1bit7, t2bit7; + --echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2ac33c4e07f..b080fff8725 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13233,6 +13233,7 @@ join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count) length=0; for (i=0 ; i < table_count ; i++) { + bool have_bit_fields= FALSE; uint null_fields=0,used_fields; Field **f_ptr,*field; @@ -13247,13 +13248,16 @@ join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count) length+=field->fill_cache_field(copy); if (copy->blob_field) (*blob_ptr++)=copy; - if (field->maybe_null()) + if (field->real_maybe_null()) null_fields++; + if (field->type() == MYSQL_TYPE_BIT && + ((Field_bit*)field)->bit_len) + have_bit_fields= TRUE; copy++; } } /* Copy null bits from table */ - if (null_fields && tables[i].table->s->null_fields) + if (null_fields || have_bit_fields) { /* must copy null bits */ copy->str=(char*) tables[i].table->null_flags; copy->length= tables[i].table->s->null_bytes; -- cgit v1.2.1 From e9e17decd2034c254dad91a9c76f84fd1b7171bf Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 9 Dec 2008 20:35:02 +0200 Subject: backported the fix for bug #34773 to 5.0 --- mysql-test/r/explain.result | 48 +++++++++++++++++++++++++++++++++++++++++++++ mysql-test/t/explain.test | 29 +++++++++++++++++++++++++++ sql/item.cc | 4 ++-- sql/item_sum.cc | 37 +++++++++++++++++++++++++++++++--- sql/item_sum.h | 25 ++++++++++++++++------- sql/opt_range.cc | 2 +- sql/opt_sum.cc | 6 +++--- sql/sql_select.cc | 16 +++++++-------- 8 files changed, 143 insertions(+), 24 deletions(-) diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result index a4c8432d2a4..3aa189f4a9d 100644 --- a/mysql-test/r/explain.result +++ b/mysql-test/r/explain.result @@ -107,3 +107,51 @@ X X X X X X X X X X X X X X X X X X Range checked for each record (index map: 0xFFFFFFFFFF) DROP TABLE t2; DROP TABLE t1; +CREATE TABLE t1(a INT); +CREATE TABLE t2(a INT); +INSERT INTO t1 VALUES (1),(2); +INSERT INTO t2 VALUES (1),(2); +EXPLAIN EXTENDED SELECT 1 +FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +2 DERIVED t2 ALL NULL NULL NULL NULL 2 +Warnings: +Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1` +EXPLAIN EXTENDED SELECT 1 +FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +2 DERIVED t2 ALL NULL NULL NULL NULL 2 +Warnings: +Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1` +prepare s1 from +'EXPLAIN EXTENDED SELECT 1 + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1'; +execute s1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +2 DERIVED t2 ALL NULL NULL NULL NULL 2 +Warnings: +Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1` +prepare s1 from +'EXPLAIN EXTENDED SELECT 1 + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1'; +execute s1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +2 DERIVED t2 ALL NULL NULL NULL NULL 2 +Warnings: +Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1` +execute s1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +2 DERIVED t2 ALL NULL NULL NULL NULL 2 +Warnings: +Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1` +DROP TABLE t1,t2; diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test index c9ae8aceaf6..0247aca82df 100644 --- a/mysql-test/t/explain.test +++ b/mysql-test/t/explain.test @@ -94,4 +94,33 @@ EXPLAIN SELECT 1 FROM DROP TABLE t2; DROP TABLE t1; +# +# Bug #34773: query with explain extended and derived table / other table +# crashes server +# + +CREATE TABLE t1(a INT); +CREATE TABLE t2(a INT); +INSERT INTO t1 VALUES (1),(2); +INSERT INTO t2 VALUES (1),(2); + +EXPLAIN EXTENDED SELECT 1 + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1; + +EXPLAIN EXTENDED SELECT 1 + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1; + +prepare s1 from +'EXPLAIN EXTENDED SELECT 1 + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1'; +execute s1; + +prepare s1 from +'EXPLAIN EXTENDED SELECT 1 + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1'; +execute s1; +execute s1; + +DROP TABLE t1,t2; + # End of 5.0 tests. diff --git a/sql/item.cc b/sql/item.cc index 243c22bb7e6..2a89c86cd88 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -6795,7 +6795,7 @@ enum_field_types Item_type_holder::get_real_type(Item *item) */ Item_sum *item_sum= (Item_sum *) item; if (item_sum->keep_field_type()) - return get_real_type(item_sum->args[0]); + return get_real_type(item_sum->get_arg(0)); break; } case FUNC_ITEM: @@ -7059,7 +7059,7 @@ void Item_type_holder::get_full_info(Item *item) if (item->type() == Item::SUM_FUNC_ITEM && (((Item_sum*)item)->sum_func() == Item_sum::MAX_FUNC || ((Item_sum*)item)->sum_func() == Item_sum::MIN_FUNC)) - item = ((Item_sum*)item)->args[0]; + item = ((Item_sum*)item)->get_arg(0); /* We can have enum/set type after merging only if we have one enum|set field (or MIN|MAX(enum|set field)) and number of NULL fields diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 91320d6b56b..d33d92a5238 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -370,6 +370,10 @@ Item_sum::Item_sum(List &list) :arg_count(list.elements), args[i++]= item; } } + if (!(orig_args= (Item **) sql_alloc(sizeof(Item *) * arg_count))) + { + args= NULL; + } mark_as_sum_func(); list.empty(); // Fields are used } @@ -380,18 +384,28 @@ Item_sum::Item_sum(List &list) :arg_count(list.elements), */ Item_sum::Item_sum(THD *thd, Item_sum *item): - Item_result_field(thd, item), arg_count(item->arg_count), + Item_result_field(thd, item), aggr_sel(item->aggr_sel), nest_level(item->nest_level), aggr_level(item->aggr_level), - quick_group(item->quick_group), used_tables_cache(item->used_tables_cache), + quick_group(item->quick_group), + arg_count(item->arg_count), orig_args(NULL), + used_tables_cache(item->used_tables_cache), forced_const(item->forced_const) { if (arg_count <= 2) + { args=tmp_args; + orig_args=tmp_orig_args; + } else + { if (!(args= (Item**) thd->alloc(sizeof(Item*)*arg_count))) return; + if (!(orig_args= (Item**) thd->alloc(sizeof(Item*)*arg_count))) + return; + } memcpy(args, item->args, sizeof(Item*)*arg_count); + memcpy(orig_args, item->orig_args, sizeof(Item*)*arg_count); } @@ -426,12 +440,13 @@ void Item_sum::make_field(Send_field *tmp_field) void Item_sum::print(String *str) { + Item **pargs= orig_args; str->append(func_name()); for (uint i=0 ; i < arg_count ; i++) { if (i) str->append(','); - args[i]->print(str); + pargs[i]->print(str); } str->append(')'); } @@ -532,6 +547,13 @@ void Item_sum::update_used_tables () } +Item *Item_sum::set_arg(int i, THD *thd, Item *new_val) +{ + thd->change_item_tree(args + i, new_val); + return new_val; +} + + String * Item_sum_num::val_str(String *str) { @@ -583,6 +605,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref) if (check_sum_func(thd, ref)) return TRUE; + memcpy (orig_args, args, sizeof (Item *) * arg_count); fixed= 1; return FALSE; } @@ -670,6 +693,7 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref) if (check_sum_func(thd, ref)) return TRUE; + orig_args[0]= args[0]; fixed= 1; return FALSE; } @@ -3107,6 +3131,12 @@ Item_func_group_concat(Name_resolution_context *context_arg, sizeof(ORDER*)*arg_count_order))) return; + if (!(orig_args= (Item **) sql_alloc(sizeof(Item *) * arg_count))) + { + args= NULL; + return; + } + order= (ORDER**)(args + arg_count); /* fill args items of show and sort */ @@ -3334,6 +3364,7 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref) if (check_sum_func(thd, ref)) return TRUE; + memcpy (orig_args, args, sizeof (Item *) * arg_count); fixed= 1; return FALSE; } diff --git a/sql/item_sum.h b/sql/item_sum.h index d39fc96e254..51a1eff9bbf 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -228,10 +228,8 @@ public: VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC }; - Item **args, *tmp_args[2]; Item **ref_by; /* pointer to a ref to the object used to register it */ Item_sum *next; /* next in the circular chain of registered objects */ - uint arg_count; Item_sum *in_sum_func; /* embedding set function if any */ st_select_lex * aggr_sel; /* select where the function is aggregated */ int8 nest_level; /* number of the nesting level of the set function */ @@ -248,24 +246,32 @@ public: List outer_fields; protected: + uint arg_count; + Item **args, *tmp_args[2]; + /* + Copy of the arguments list to hold the original set of arguments. + Used in EXPLAIN EXTENDED instead of the current argument list because + the current argument list can be altered by usage of temporary tables. + */ + Item **orig_args, *tmp_orig_args[2]; table_map used_tables_cache; bool forced_const; public: void mark_as_sum_func(); - Item_sum() :arg_count(0), quick_group(1), forced_const(FALSE) + Item_sum() :quick_group(1), arg_count(0), forced_const(FALSE) { mark_as_sum_func(); } - Item_sum(Item *a) :args(tmp_args), arg_count(1), quick_group(1), - forced_const(FALSE) + Item_sum(Item *a) :quick_group(1), arg_count(1), args(tmp_args), + orig_args(tmp_orig_args), forced_const(FALSE) { args[0]=a; mark_as_sum_func(); } - Item_sum( Item *a, Item *b ) :args(tmp_args), arg_count(2), quick_group(1), - forced_const(FALSE) + Item_sum( Item *a, Item *b ) :quick_group(1), arg_count(2), args(tmp_args), + orig_args(tmp_orig_args), forced_const(FALSE) { args[0]=a; args[1]=b; mark_as_sum_func(); @@ -374,6 +380,10 @@ public: bool register_sum_func(THD *thd, Item **ref); st_select_lex *depended_from() { return (nest_level == aggr_level ? 0 : aggr_sel); } + + Item *get_arg(int i) { return args[i]; } + Item *set_arg(int i, THD *thd, Item *new_val); + uint get_arg_count() { return arg_count; } }; @@ -981,6 +991,7 @@ public: if (udf.fix_fields(thd, this, this->arg_count, this->args)) return TRUE; + memcpy (orig_args, args, sizeof (Item *) * arg_count); return check_sum_func(thd, ref); } enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 204ebdb6f33..7d9b1179d87 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7735,7 +7735,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) DBUG_RETURN(NULL); /* The argument of MIN/MAX. */ - Item *expr= min_max_item->args[0]->real_item(); + Item *expr= min_max_item->get_arg(0)->real_item(); if (expr->type() == Item::FIELD_ITEM) /* Is it an attribute? */ { if (! min_max_arg_item) diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 3fc62d05ae5..39db1344588 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -160,7 +160,7 @@ int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds) to the number of rows in the tables if this number is exact and there are no outer joins. */ - if (!conds && !((Item_sum_count*) item)->args[0]->maybe_null && + if (!conds && !((Item_sum_count*) item)->get_arg(0)->maybe_null && !outer_tables && is_exact_count) { ((Item_sum_count*) item)->make_const(count); @@ -176,7 +176,7 @@ int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds) parts of the key is found in the COND, then we can use indexes to find the key. */ - Item *expr=item_sum->args[0]; + Item *expr=item_sum->get_arg(0); if (expr->real_item()->type() == Item::FIELD_ITEM) { byte key_buff[MAX_KEY_LENGTH]; @@ -319,7 +319,7 @@ int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds) parts of the key is found in the COND, then we can use indexes to find the key. */ - Item *expr=item_sum->args[0]; + Item *expr=item_sum->get_arg(0); if (expr->real_item()->type() == Item::FIELD_ITEM) { byte key_buff[MAX_KEY_LENGTH]; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b080fff8725..48276170caf 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9444,11 +9444,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, } if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields) { /* Can't calc group yet */ - ((Item_sum*) item)->result_field=0; - for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++) + Item_sum *sum_item= (Item_sum *) item; + sum_item->result_field=0; + for (i=0 ; i < sum_item->get_arg_count() ; i++) { - Item **argp= ((Item_sum*) item)->args + i; - Item *arg= *argp; + Item *arg= sum_item->get_arg(i); if (!arg->const_item()) { uint field_index= (uint) (reg_field - table->field); @@ -9478,7 +9478,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, string_total_length+= new_field->pack_length(); } thd->mem_root= mem_root_save; - thd->change_item_tree(argp, new Item_field(new_field)); + arg= sum_item->set_arg(i, thd, new Item_field(new_field)); thd->mem_root= &table->mem_root; if (!(new_field->flags & NOT_NULL_FLAG)) { @@ -9487,7 +9487,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, new_field->maybe_null() is still false, it will be changed below. But we have to setup Item_field correctly */ - (*argp)->maybe_null=1; + arg->maybe_null=1; } new_field->query_id= thd->query_id; } @@ -13922,9 +13922,9 @@ count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param, param->quick_group=0; // UDF SUM function param->sum_func_count++; - for (uint i=0 ; i < sum_item->arg_count ; i++) + for (uint i=0 ; i < sum_item->get_arg_count() ; i++) { - if (sum_item->args[0]->real_item()->type() == Item::FIELD_ITEM) + if (sum_item->get_arg(i)->real_item()->type() == Item::FIELD_ITEM) param->field_count++; else param->func_count++; -- cgit v1.2.1 From 84c0d0d4fbe4c1ea1f48d4ae2c9dfb8d374ef76d Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Wed, 10 Dec 2008 16:07:32 +0300 Subject: Fix for a test failure on Solaris/x86/gcc introduced by the patch for bug #27483. Removed values with more than 15 significant digits from the test case. Results of reading/printing such values using system library functions depend on implementation and thus are not portable. mysql-test/r/type_float.result: Removed values with more than 15 significant digits from the test case. mysql-test/t/type_float.test: Removed values with more than 15 significant digits from the test case. --- mysql-test/r/type_float.result | 6 +----- mysql-test/t/type_float.test | 4 +--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index d86c515062a..8caabbff047 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -393,15 +393,11 @@ f1 + 0e0 -1.0000000150475e+30 drop table t1; create table t1(d double, u bigint unsigned); -insert into t1(d) values (9.2233720368547777e+18), -(9.223372036854779e18), -(9.22337203685479e18), +insert into t1(d) values (9.22337203685479e18), (1.84e19); update t1 set u = d; select u from t1; u -9223372036854775808 -9223372036854779904 9223372036854790144 18400000000000000000 drop table t1; diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 3ceef129912..53bcf44061d 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -259,9 +259,7 @@ drop table t1; create table t1(d double, u bigint unsigned); -insert into t1(d) values (9.2233720368547777e+18), - (9.223372036854779e18), - (9.22337203685479e18), +insert into t1(d) values (9.22337203685479e18), (1.84e19); update t1 set u = d; -- cgit v1.2.1 From c700b4cfab73ca9e88d6167913064e787aca646b Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 10 Dec 2008 18:13:11 +0400 Subject: Bug#37956 memory leak and / or crash with geometry and prepared statements! Bug#37671 crash on prepared statement + cursor + geometry + too many open files! if mysql_execute_command() returns error then free materialized_cursor object. is_rnd_inited is added to satisfy rnd_end() assertion (handler may be uninitialized in some cases) sql/sql_cursor.cc: if mysql_execute_command() returns error then free materialized_cursor object. is_rnd_inited is added to satisfy rnd_end() assertion (handler may be uninitialized in some cases) sql/sql_select.cc: added result check tests/mysql_client_test.c: test case --- sql/sql_cursor.cc | 18 +++++++++++----- sql/sql_select.cc | 7 ++++-- tests/mysql_client_test.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 7 deletions(-) diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index 16567765ba6..83c60814cf3 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -85,6 +85,7 @@ class Materialized_cursor: public Server_side_cursor List item_list; ulong fetch_limit; ulong fetch_count; + bool is_rnd_inited; public: Materialized_cursor(select_result *result, TABLE *table); @@ -191,7 +192,11 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result, such command is SHOW VARIABLES or SHOW STATUS. */ if (rc) + { + if (result_materialize->materialized_cursor) + delete result_materialize->materialized_cursor; goto err_open; + } if (sensitive_cursor->is_open()) { @@ -532,7 +537,8 @@ Materialized_cursor::Materialized_cursor(select_result *result_arg, :Server_side_cursor(&table_arg->mem_root, result_arg), table(table_arg), fetch_limit(0), - fetch_count(0) + fetch_count(0), + is_rnd_inited(0) { fake_unit.init_query(); fake_unit.thd= table->in_use; @@ -589,11 +595,12 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused))) THD *thd= fake_unit.thd; int rc; Query_arena backup_arena; - thd->set_n_backup_active_arena(this, &backup_arena); /* Create a list of fields and start sequential scan */ - rc= (result->prepare(item_list, &fake_unit) || - table->file->ha_rnd_init(TRUE)); + rc= result->prepare(item_list, &fake_unit); + if (!rc && !(rc= table->file->ha_rnd_init(TRUE))) + is_rnd_inited= 1; + thd->restore_active_arena(this, &backup_arena); if (rc == 0) { @@ -673,7 +680,8 @@ void Materialized_cursor::close() { /* Free item_list items */ free_items(); - (void) table->file->ha_rnd_end(); + if (is_rnd_inited) + (void) table->file->ha_rnd_end(); /* We need to grab table->mem_root to prevent free_tmp_table from freeing: the cursor object was allocated in this memory. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 48276170caf..d2c469f99da 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1599,8 +1599,11 @@ JOIN::exec() (zero_result_cause?zero_result_cause:"No tables used")); else { - result->send_fields(*columns_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); + if (result->send_fields(*columns_list, + Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) + { + DBUG_VOID_RETURN; + } /* We have to test for 'conds' here as the WHERE may not be constant even if we don't have any tables for prepared statements or if diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index ee3a053f8bd..ea4d363bdac 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -15899,6 +15899,59 @@ static void test_bug28934() } +/** + 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; + unsigned int 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; +} + /* Bug#27592 (stack overrun when storing datetime value using prepared statements) */ @@ -16595,6 +16648,7 @@ static struct my_tests_st my_tests[]= { { "test_bug32265", test_bug32265 }, { "test_bug38486", test_bug38486 }, { "test_bug40365", test_bug40365 }, + { "test_bug37956", test_bug37956 }, { 0, 0 } }; -- cgit v1.2.1 From c4e4ac1249188bd6effaaf234b77d1660e9f2d6e Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 11 Dec 2008 12:57:59 +0400 Subject: disable bug37956 test if geometry package is not enabled --- tests/mysql_client_test.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index ea4d363bdac..79d188c252c 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -15899,6 +15899,7 @@ static void test_bug28934() } +#ifdef HAVE_SPATIAL /** Bug#37956 memory leak and / or crash with geometry and prepared statements! */ @@ -15951,6 +15952,7 @@ static void test_bug37956(void) DIE_UNLESS(0); DBUG_VOID_RETURN; } +#endif /* Bug#27592 (stack overrun when storing datetime value using prepared statements) @@ -16648,7 +16650,9 @@ 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 { 0, 0 } }; -- cgit v1.2.1 From 3b3594b6d530265758993dc7f376aa9b91c21a49 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 11 Dec 2008 14:37:18 +0400 Subject: fix for pushbuild failure on 64 linux --- tests/mysql_client_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 79d188c252c..50f03a1a086 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -15908,7 +15908,7 @@ static void test_bug37956(void) { const char *query="select point(?,?)"; MYSQL_STMT *stmt=NULL; - unsigned int val=0; + ulong val=0; MYSQL_BIND bind_param[2]; unsigned char buff[2]= { 134, 211 }; DBUG_ENTER("test_bug37956"); -- cgit v1.2.1 From c4e3f7f9dadc1def6eabae5c31900a9ea0de9572 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 11 Dec 2008 11:06:50 +0000 Subject: Fix PB warnings for parenthesis and valgrind leak report. BUG#38826 --- sql/log.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 477cb21b2f3..c411f7c8238 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1146,7 +1146,7 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli, bool included) * Need to update the log pos because purge logs has been called * after fetching initially the log pos at the begining of the method. */ - if(error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)) + if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0))) { char buff[22]; sql_print_error("next log error: %d offset: %s log: %s included: %d", @@ -1234,8 +1234,8 @@ int MYSQL_LOG::purge_logs(const char *to_log, */ if (!my_b_inited(&purge_temp)) { - if (error=open_cached_file(&purge_temp, mysql_tmpdir, TEMP_PREFIX, - DISK_BUFFER_SIZE, MYF(MY_WME))) + if ((error=open_cached_file(&purge_temp, mysql_tmpdir, TEMP_PREFIX, + DISK_BUFFER_SIZE, MYF(MY_WME)))) { sql_print_error("MYSQL_LOG::purge_logs failed to open purge_temp"); goto err; @@ -1243,7 +1243,7 @@ int MYSQL_LOG::purge_logs(const char *to_log, } else { - if (error=reinit_io_cache(&purge_temp, WRITE_CACHE, 0, 0, 1)) + if ((error=reinit_io_cache(&purge_temp, WRITE_CACHE, 0, 0, 1))) { sql_print_error("MYSQL_LOG::purge_logs failed to reinit purge_temp " "for write"); @@ -1274,7 +1274,7 @@ int MYSQL_LOG::purge_logs(const char *to_log, } /* We know how many files to delete. Update index file. */ - if (error=update_log_index(&log_info, need_update_threads)) + if ((error=update_log_index(&log_info, need_update_threads))) { sql_print_error("MSYQL_LOG::purge_logs failed to update the index file"); goto err; @@ -1283,7 +1283,7 @@ int MYSQL_LOG::purge_logs(const char *to_log, DBUG_EXECUTE_IF("crash_after_update_index", abort();); /* Switch purge_temp for read. */ - if (error=reinit_io_cache(&purge_temp, READ_CACHE, 0, 0, 0)) + if ((error=reinit_io_cache(&purge_temp, READ_CACHE, 0, 0, 0))) { sql_print_error("MSYQL_LOG::purge_logs failed to reinit purge_temp " "for read"); @@ -1409,6 +1409,7 @@ int MYSQL_LOG::purge_logs(const char *to_log, } err: + close_cached_file(&purge_temp); if (need_mutex) pthread_mutex_unlock(&LOCK_index); DBUG_RETURN(error); -- cgit v1.2.1 From b109150d79ff9be8590e6d7e7ac78c63a11464ac Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Thu, 11 Dec 2008 12:26:03 -0500 Subject: Bug#33812: mysql client incorrectly parsing DELIMITER Fix parsing of mysql client commands, especially in relation to single-line comments when --comments was specified. This is a little tricky, because we need to allow single-line comments in the middle of statements, but we don't want to allow client commands in the middle of statements. So in comment-preservation mode, we go ahead and send single-line comments to the server immediately when we encounter them on their own. This is still slightly flawed, in that it does not handle a single-line comment with leading spaces, followed by a client-side command when --comment has been enabled. But this isn't a new problem, and it is quite an edge condition. Fixing it would require a more extensive overall of how the mysql client parses commands. --- client/mysql.cc | 49 ++++++++++++++++------------------------------- mysql-test/r/mysql.result | 6 ++++++ mysql-test/t/mysql.test | 19 ++++++++++++++++++ 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 9b14f9fb3ef..20f87d5cdcd 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1998,7 +1998,7 @@ static bool add_line(String &buffer,char *line,char *in_string, { if (!preserve_comments) { - // Skip spaces at the beggining of a statement + // Skip spaces at the beginning of a statement if (my_isspace(charset_info,inchar) && (out == line) && buffer.is_empty()) continue; @@ -2081,37 +2081,6 @@ static bool add_line(String &buffer,char *line,char *in_string, continue; } } - else if (!*ml_comment && !*in_string && - (end_of_line - pos) >= 10 && - !my_strnncoll(charset_info, (uchar*) pos, 10, - (const uchar*) "delimiter ", 10)) - { - // Flush previously accepted characters - if (out != line) - { - buffer.append(line, (uint32) (out - line)); - out= line; - } - - // Flush possible comments in the buffer - if (!buffer.is_empty()) - { - if (com_go(&buffer, 0) > 0) // < 0 is not fatal - DBUG_RETURN(1); - buffer.length(0); - } - - /* - Delimiter wants the get rest of the given line as argument to - allow one to change ';' to ';;' and back - */ - buffer.append(pos); - if (com_delimiter(&buffer, pos) > 0) - DBUG_RETURN(1); - - buffer.length(0); - break; - } else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter)) { // Found a statement. Continue parsing after the delimiter @@ -2174,8 +2143,24 @@ static bool add_line(String &buffer,char *line,char *in_string, // comment to end of line if (preserve_comments) + { + bool started_with_nothing= !buffer.length(); + buffer.append(pos); + /* + A single-line comment by itself gets sent immediately so that + client commands (delimiter, status, etc) will be interpreted on + the next line. + */ + if (started_with_nothing) + { + if (com_go(&buffer, 0) > 0) // < 0 is not fatal + DBUG_RETURN(1); + buffer.length(0); + } + } + break; } else if (!*in_string && inchar == '/' && *(pos+1) == '*' && diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index eded1a3fc3b..95bdcab6ba1 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -180,4 +180,10 @@ ERROR at line 1: DELIMITER cannot contain a backslash character 1 This is a file starting with UTF8 BOM 0xEFBBBF This is a file starting with UTF8 BOM 0xEFBBBF +delimiter +1 +2 +2 +2 +2 End of 5.0 tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 182b292c817..76941af893a 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -290,4 +290,23 @@ EOF --exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug29323.sql 2>&1 remove_file $MYSQLTEST_VARDIR/tmp/bug29323.sql; +# +# Bug #33812: mysql client incorrectly parsing DELIMITER +# +# The space and ; after delimiter are important +--exec $MYSQL -e "select 1 delimiter ;" + +# +# Bug #38158: mysql client regression, can't read dump files +# +--write_file $MYSQLTEST_VARDIR/tmp/bug38158.sql +-- Testing +-- +delimiter || +select 2 || +EOF +--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug38158.sql 2>&1 +--exec $MYSQL -c < $MYSQLTEST_VARDIR/tmp/bug38158.sql 2>&1 +remove_file $MYSQLTEST_VARDIR/tmp/bug38158.sql; + --echo End of 5.0 tests -- cgit v1.2.1 From 3aadda917131b1685befc93e722566d5f40f02a5 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Fri, 12 Dec 2008 00:57:32 +0400 Subject: Bug #40761: Assert on sum function on IF(..., CAST(longtext AS UNSIGNED), signed_val) (was: LEFT JOIN on inline view crashes server) Select from a LONGTEXT column wrapped with an expression like "IF(..., CAST(longtext_column AS UNSIGNED), smth_signed)" failed an assertion or crashed the server. IFNULL function was affected too. LONGTEXT column item has a maximum length of 32^2-1 bytes, at the same time this is a maximum possible length of any MySQL item. CAST(longtext_column AS UNSIGNED) returns some unsigned numeric result of length 32^2-1, so the result of IF/IFNULL function of this number and some other signed number will have text length of (32^2-1)+1=32^2 (one byte for the minus sign) - there is integer overflow, and the length is equal to zero. That caused assert/crash. The bug has been fixed by the same solution as in the CASE function implementation. mysql-test/r/func_if.result: Added test case for bug #40761. mysql-test/t/func_if.test: Added test case for bug #40761. sql/item_cmpfunc.cc: Bug #40761: Assert on sum function on IF(..., CAST(longtext AS UNSIGNED), signed_val) 1. Item_func_case::agg_str_lengths method has been moved to the Item_func superclass. 2. Item_func_ifnull/Item_func_if::fix_length_and_dec methods have been updated to calculate max_length, decimals and unsigned flag like Item_func_case. sql/item_cmpfunc.h: Bug #40761: Assert on sum function on IF(..., CAST(longtext AS UNSIGNED), signed_val) Item_func_case::agg_str_lengths method has been moved to the Item_func superclass. sql/item_func.cc: Bug #40761: Assert on sum function on IF(..., CAST(longtext AS UNSIGNED), signed_val) Item_func_case::agg_str_lengths method has been moved to the Item_func superclass. sql/item_func.h: Bug #40761: Assert on sum function on IF(..., CAST(longtext AS UNSIGNED), signed_val) Item_func_case::agg_str_lengths method has been moved to the Item_func superclass. --- mysql-test/r/func_if.result | 9 ++++++++ mysql-test/t/func_if.test | 13 ++++++++++++ sql/item_cmpfunc.cc | 50 ++++++++++++++++++++------------------------- sql/item_cmpfunc.h | 1 - sql/item_func.cc | 10 +++++++++ sql/item_func.h | 2 ++ 6 files changed, 56 insertions(+), 29 deletions(-) diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result index 7ffc957e285..16d6b435dc7 100644 --- a/mysql-test/r/func_if.result +++ b/mysql-test/r/func_if.result @@ -176,4 +176,13 @@ IF((ROUND(t1.a,2)=1), 2, IF((ROUND(t1.a,2)=1), 2, IF((R DROP TABLE t1; +CREATE TABLE t1 (c LONGTEXT); +INSERT INTO t1 VALUES(1), (2), (3), (4), ('12345678901234567890'); +SELECT * FROM (SELECT MAX(IF(1, CAST(c AS UNSIGNED), 0)) FROM t1) AS te; +MAX(IF(1, CAST(c AS UNSIGNED), 0)) +12345678901234567890 +SELECT * FROM (SELECT MAX(IFNULL(CAST(c AS UNSIGNED), 0)) FROM t1) AS te; +MAX(IFNULL(CAST(c AS UNSIGNED), 0)) +12345678901234567890 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test index 8da10f36cbe..68728d6697e 100644 --- a/mysql-test/t/func_if.test +++ b/mysql-test/t/func_if.test @@ -150,4 +150,17 @@ FROM t1; DROP TABLE t1; +# +# Bug #40761: Assert on sum func on IF(..., CAST(longtext AS UNSIGNED), signed) +# (was: LEFT JOIN on inline view crashes server) +# + +CREATE TABLE t1 (c LONGTEXT); +INSERT INTO t1 VALUES(1), (2), (3), (4), ('12345678901234567890'); + +SELECT * FROM (SELECT MAX(IF(1, CAST(c AS UNSIGNED), 0)) FROM t1) AS te; +SELECT * FROM (SELECT MAX(IFNULL(CAST(c AS UNSIGNED), 0)) FROM t1) AS te; + +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3b1d18b4252..759e912cc82 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2069,21 +2069,23 @@ Item_func_ifnull::fix_length_and_dec() { agg_result_type(&hybrid_type, args, 2); maybe_null=args[1]->maybe_null; - decimals= max(args[0]->decimals, args[1]->decimals); - unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag; if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) { - int len0= args[0]->max_length - args[0]->decimals - - (args[0]->unsigned_flag ? 0 : 1); - - int len1= args[1]->max_length - args[1]->decimals - - (args[1]->unsigned_flag ? 0 : 1); - - max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1); + max_length= 0; + decimals= 0; + unsigned_flag= TRUE; + agg_num_lengths(args[0]); + agg_num_lengths(args[1]); + max_length= my_decimal_precision_to_length(max_length + decimals, decimals, + unsigned_flag); } else + { max_length= max(args[0]->max_length, args[1]->max_length); + decimals= max(args[0]->decimals, args[1]->decimals); + unsigned_flag=args[0]->unsigned_flag && args[1]->unsigned_flag; + } switch (hybrid_type) { case STRING_RESULT: @@ -2238,8 +2240,6 @@ void Item_func_if::fix_length_and_dec() { maybe_null=args[1]->maybe_null || args[2]->maybe_null; - decimals= max(args[1]->decimals, args[2]->decimals); - unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag; enum Item_result arg1_type=args[1]->result_type(); enum Item_result arg2_type=args[2]->result_type(); @@ -2276,16 +2276,20 @@ Item_func_if::fix_length_and_dec() if ((cached_result_type == DECIMAL_RESULT ) || (cached_result_type == INT_RESULT)) { - int len1= args[1]->max_length - args[1]->decimals - - (args[1]->unsigned_flag ? 0 : 1); - - int len2= args[2]->max_length - args[2]->decimals - - (args[2]->unsigned_flag ? 0 : 1); - - max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1); + max_length= 0; + decimals= 0; + unsigned_flag= TRUE; + agg_num_lengths(args[1]); + agg_num_lengths(args[2]); + max_length= my_decimal_precision_to_length(max_length + decimals, decimals, + unsigned_flag); } else + { max_length= max(args[1]->max_length, args[2]->max_length); + decimals= max(args[1]->decimals, args[2]->decimals); + unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag; + } } @@ -2633,16 +2637,6 @@ void Item_func_case::agg_str_lengths(Item* arg) } -void Item_func_case::agg_num_lengths(Item *arg) -{ - uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals, - arg->unsigned_flag) - arg->decimals; - set_if_bigger(max_length, len); - set_if_bigger(decimals, arg->decimals); - unsigned_flag= unsigned_flag && arg->unsigned_flag; -} - - void Item_func_case::fix_length_and_dec() { Item **agg; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index db831c7030c..6ecbfba140f 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -759,7 +759,6 @@ public: Item *find_item(String *str); CHARSET_INFO *compare_collation() { return cmp_collation.collation; } void agg_str_lengths(Item *arg); - void agg_num_lengths(Item *arg); }; diff --git a/sql/item_func.cc b/sql/item_func.cc index c0d08d9b213..c650b0ae933 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5668,3 +5668,13 @@ void Item_func_sp::update_used_tables() const_item_cache= FALSE; } } + + +void Item_func::agg_num_lengths(Item *arg) +{ + uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals, + arg->unsigned_flag) - arg->decimals; + set_if_bigger(max_length, len); + set_if_bigger(decimals, arg->decimals); + unsigned_flag= unsigned_flag && arg->unsigned_flag; +} diff --git a/sql/item_func.h b/sql/item_func.h index 6dcf32cba07..d4da0b7a853 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -193,6 +193,8 @@ public: void * arg, traverse_order order); bool is_expensive_processor(byte *arg); virtual bool is_expensive() { return 0; } +protected: + void agg_num_lengths(Item *arg); }; -- cgit v1.2.1 From 646d87da0a2fcb416e37f20a7e3a7d56b2bf3756 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Fri, 12 Dec 2008 14:59:10 +0400 Subject: rollback of bug #40761 fix --- mysql-test/r/func_if.result | 9 -------- mysql-test/t/func_if.test | 13 ------------ sql/item_cmpfunc.cc | 50 +++++++++++++++++++++++++-------------------- sql/item_cmpfunc.h | 1 + sql/item_func.cc | 10 --------- sql/item_func.h | 2 -- 6 files changed, 29 insertions(+), 56 deletions(-) diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result index 16d6b435dc7..7ffc957e285 100644 --- a/mysql-test/r/func_if.result +++ b/mysql-test/r/func_if.result @@ -176,13 +176,4 @@ IF((ROUND(t1.a,2)=1), 2, IF((ROUND(t1.a,2)=1), 2, IF((R DROP TABLE t1; -CREATE TABLE t1 (c LONGTEXT); -INSERT INTO t1 VALUES(1), (2), (3), (4), ('12345678901234567890'); -SELECT * FROM (SELECT MAX(IF(1, CAST(c AS UNSIGNED), 0)) FROM t1) AS te; -MAX(IF(1, CAST(c AS UNSIGNED), 0)) -12345678901234567890 -SELECT * FROM (SELECT MAX(IFNULL(CAST(c AS UNSIGNED), 0)) FROM t1) AS te; -MAX(IFNULL(CAST(c AS UNSIGNED), 0)) -12345678901234567890 -DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test index 68728d6697e..8da10f36cbe 100644 --- a/mysql-test/t/func_if.test +++ b/mysql-test/t/func_if.test @@ -150,17 +150,4 @@ FROM t1; DROP TABLE t1; -# -# Bug #40761: Assert on sum func on IF(..., CAST(longtext AS UNSIGNED), signed) -# (was: LEFT JOIN on inline view crashes server) -# - -CREATE TABLE t1 (c LONGTEXT); -INSERT INTO t1 VALUES(1), (2), (3), (4), ('12345678901234567890'); - -SELECT * FROM (SELECT MAX(IF(1, CAST(c AS UNSIGNED), 0)) FROM t1) AS te; -SELECT * FROM (SELECT MAX(IFNULL(CAST(c AS UNSIGNED), 0)) FROM t1) AS te; - -DROP TABLE t1; - --echo End of 5.0 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 759e912cc82..3b1d18b4252 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2069,23 +2069,21 @@ Item_func_ifnull::fix_length_and_dec() { agg_result_type(&hybrid_type, args, 2); maybe_null=args[1]->maybe_null; + decimals= max(args[0]->decimals, args[1]->decimals); + unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag; if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) { - max_length= 0; - decimals= 0; - unsigned_flag= TRUE; - agg_num_lengths(args[0]); - agg_num_lengths(args[1]); - max_length= my_decimal_precision_to_length(max_length + decimals, decimals, - unsigned_flag); + int len0= args[0]->max_length - args[0]->decimals + - (args[0]->unsigned_flag ? 0 : 1); + + int len1= args[1]->max_length - args[1]->decimals + - (args[1]->unsigned_flag ? 0 : 1); + + max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1); } else - { max_length= max(args[0]->max_length, args[1]->max_length); - decimals= max(args[0]->decimals, args[1]->decimals); - unsigned_flag=args[0]->unsigned_flag && args[1]->unsigned_flag; - } switch (hybrid_type) { case STRING_RESULT: @@ -2240,6 +2238,8 @@ void Item_func_if::fix_length_and_dec() { maybe_null=args[1]->maybe_null || args[2]->maybe_null; + decimals= max(args[1]->decimals, args[2]->decimals); + unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag; enum Item_result arg1_type=args[1]->result_type(); enum Item_result arg2_type=args[2]->result_type(); @@ -2276,20 +2276,16 @@ Item_func_if::fix_length_and_dec() if ((cached_result_type == DECIMAL_RESULT ) || (cached_result_type == INT_RESULT)) { - max_length= 0; - decimals= 0; - unsigned_flag= TRUE; - agg_num_lengths(args[1]); - agg_num_lengths(args[2]); - max_length= my_decimal_precision_to_length(max_length + decimals, decimals, - unsigned_flag); + int len1= args[1]->max_length - args[1]->decimals + - (args[1]->unsigned_flag ? 0 : 1); + + int len2= args[2]->max_length - args[2]->decimals + - (args[2]->unsigned_flag ? 0 : 1); + + max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1); } else - { max_length= max(args[1]->max_length, args[2]->max_length); - decimals= max(args[1]->decimals, args[2]->decimals); - unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag; - } } @@ -2637,6 +2633,16 @@ void Item_func_case::agg_str_lengths(Item* arg) } +void Item_func_case::agg_num_lengths(Item *arg) +{ + uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals, + arg->unsigned_flag) - arg->decimals; + set_if_bigger(max_length, len); + set_if_bigger(decimals, arg->decimals); + unsigned_flag= unsigned_flag && arg->unsigned_flag; +} + + void Item_func_case::fix_length_and_dec() { Item **agg; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 6ecbfba140f..db831c7030c 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -759,6 +759,7 @@ public: Item *find_item(String *str); CHARSET_INFO *compare_collation() { return cmp_collation.collation; } void agg_str_lengths(Item *arg); + void agg_num_lengths(Item *arg); }; diff --git a/sql/item_func.cc b/sql/item_func.cc index c650b0ae933..c0d08d9b213 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5668,13 +5668,3 @@ void Item_func_sp::update_used_tables() const_item_cache= FALSE; } } - - -void Item_func::agg_num_lengths(Item *arg) -{ - uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals, - arg->unsigned_flag) - arg->decimals; - set_if_bigger(max_length, len); - set_if_bigger(decimals, arg->decimals); - unsigned_flag= unsigned_flag && arg->unsigned_flag; -} diff --git a/sql/item_func.h b/sql/item_func.h index d4da0b7a853..6dcf32cba07 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -193,8 +193,6 @@ public: void * arg, traverse_order order); bool is_expensive_processor(byte *arg); virtual bool is_expensive() { return 0; } -protected: - void agg_num_lengths(Item *arg); }; -- cgit v1.2.1 From 423ca289814d90ac9b0b75adfd2d88a0de4e743c Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Fri, 12 Dec 2008 17:16:25 +0400 Subject: Bug #40761: Assert on sum function on IF(..., CAST(longtext AS UNSIGNED), signed_val) (was: LEFT JOIN on inline view crashes server) Select from a LONGTEXT column wrapped with an expression like "IF(..., CAST(longtext_column AS UNSIGNED), smth_signed)" failed an assertion or crashed the server. IFNULL function was affected too. LONGTEXT column item has a maximum length of 32^2-1 bytes, at the same time this is a maximum possible length of any MySQL item. CAST(longtext_column AS UNSIGNED) returns some unsigned numeric result of length 32^2-1, so the result of IF/IFNULL function of this number and some other signed number will have text length of (32^2-1)+1=32^2 (one byte for the minus sign) - there is integer overflow, and the length is equal to zero. That caused assert/crash. CAST AS UNSIGNED function has been modified to limit maximal length of resulting number to 67 (maximal length of DECIMAL and two characters for minus sign and dot). mysql-test/r/func_if.result: Added test case for bug #40761. mysql-test/t/func_if.test: Added test case for bug #40761. sql/item_func.h: Bug #40761: Assert on sum function on IF(..., CAST(longtext AS UNSIGNED), signed_val) CAST AS UNSIGNED function has been modified to limit maximal length of resulting number to 67 (maximal length of DECIMAL and two characters for minus sign and dot). --- mysql-test/r/func_if.result | 9 +++++++++ mysql-test/t/func_if.test | 14 ++++++++++++++ sql/item_func.h | 5 ++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result index 7ffc957e285..16d6b435dc7 100644 --- a/mysql-test/r/func_if.result +++ b/mysql-test/r/func_if.result @@ -176,4 +176,13 @@ IF((ROUND(t1.a,2)=1), 2, IF((ROUND(t1.a,2)=1), 2, IF((R DROP TABLE t1; +CREATE TABLE t1 (c LONGTEXT); +INSERT INTO t1 VALUES(1), (2), (3), (4), ('12345678901234567890'); +SELECT * FROM (SELECT MAX(IF(1, CAST(c AS UNSIGNED), 0)) FROM t1) AS te; +MAX(IF(1, CAST(c AS UNSIGNED), 0)) +12345678901234567890 +SELECT * FROM (SELECT MAX(IFNULL(CAST(c AS UNSIGNED), 0)) FROM t1) AS te; +MAX(IFNULL(CAST(c AS UNSIGNED), 0)) +12345678901234567890 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test index 8da10f36cbe..4efea8e195e 100644 --- a/mysql-test/t/func_if.test +++ b/mysql-test/t/func_if.test @@ -150,4 +150,18 @@ FROM t1; DROP TABLE t1; +# +# Bug #40761: Assert on sum func on IF(..., CAST(longtext AS UNSIGNED), signed) +# (was: LEFT JOIN on inline view crashes server) +# + +CREATE TABLE t1 (c LONGTEXT); +INSERT INTO t1 VALUES(1), (2), (3), (4), ('12345678901234567890'); + +SELECT * FROM (SELECT MAX(IF(1, CAST(c AS UNSIGNED), 0)) FROM t1) AS te; +SELECT * FROM (SELECT MAX(IFNULL(CAST(c AS UNSIGNED), 0)) FROM t1) AS te; + +DROP TABLE t1; + + --echo End of 5.0 tests diff --git a/sql/item_func.h b/sql/item_func.h index 6dcf32cba07..89c841abb75 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -351,7 +351,10 @@ public: Item_func_unsigned(Item *a) :Item_func_signed(a) {} const char *func_name() const { return "cast_as_unsigned"; } void fix_length_and_dec() - { max_length=args[0]->max_length; unsigned_flag=1; } + { + max_length= min(args[0]->max_length, DECIMAL_MAX_PRECISION + 2); + unsigned_flag=1; + } longlong val_int(); void print(String *str); }; -- cgit v1.2.1 From 5ee9db712cdcebde7bbc3cfa6940881a9b12e103 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Fri, 12 Dec 2008 15:10:56 +0100 Subject: Bug #31983 Running mysql-test from RPM fails for NDB Added $glob_basedir/sbin to search path for relevant binaries --- mysql-test/mysql-test-run.pl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 268dd3fbd16..add0d6cc22e 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1508,15 +1508,21 @@ sub executable_setup_ndb () { "$glob_basedir/storage/ndb", "$glob_basedir/bin"); + # Some might be found in sbin, not bin. + my $daemon_path= mtr_file_exists("$glob_basedir/ndb", + "$glob_basedir/storage/ndb", + "$glob_basedir/sbin", + "$glob_basedir/bin"); + $exe_ndbd= mtr_exe_maybe_exists("$ndb_path/src/kernel/ndbd", - "$ndb_path/ndbd"); + "$daemon_path/ndbd"); $exe_ndb_mgm= mtr_exe_maybe_exists("$ndb_path/src/mgmclient/ndb_mgm", "$ndb_path/ndb_mgm"); $exe_ndb_mgmd= mtr_exe_maybe_exists("$ndb_path/src/mgmsrv/ndb_mgmd", - "$ndb_path/ndb_mgmd"); + "$daemon_path/ndb_mgmd"); $exe_ndb_waiter= mtr_exe_maybe_exists("$ndb_path/tools/ndb_waiter", "$ndb_path/ndb_waiter"); -- cgit v1.2.1 From dbb060b238f1a7bb0e6d56900f949a7b72cbf9a0 Mon Sep 17 00:00:00 2001 From: Timothy Smith Date: Fri, 12 Dec 2008 15:48:26 -0700 Subject: Apply the rest of innodb-5.0-ss2475. This fixes Bug#36819, "ut_usectime does not handle errors from gettimeofday". r2475 | vasil | 2008-05-22 19:35:30 +0300 (Thu, 22 May 2008) | 13 lines Fix by retrying gettimeofday() several times if it fails in ut_usectime(). If it fails on all calls then return error to the caller to be handled at higher level. Update the variable innodb_row_lock_time_max in SHOW STATUS output only if ut_usectime() was successful. --- innobase/btr/btr0cur.c | 2 +- innobase/include/ut0ut.h | 8 ++++++-- innobase/srv/srv0srv.c | 21 +++++++++++++++------ innobase/ut/ut0ut.c | 36 +++++++++++++++++++++++++++++++----- 4 files changed, 53 insertions(+), 14 deletions(-) diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index d51a090be75..509b2ba3119 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -52,7 +52,7 @@ can be released by page reorganize, then it is reorganized */ #define BTR_CUR_PAGE_REORGANIZE_LIMIT (UNIV_PAGE_SIZE / 32) -/* When estimating number of different kay values in an index sample +/* When estimating number of different key values in an index, sample this many index pages */ #define BTR_KEY_VAL_ESTIMATE_N_PAGES 8 diff --git a/innobase/include/ut0ut.h b/innobase/include/ut0ut.h index 8938957cd12..b1c1602fd30 100644 --- a/innobase/include/ut0ut.h +++ b/innobase/include/ut0ut.h @@ -139,11 +139,15 @@ ib_time_t ut_time(void); /*=========*/ /************************************************************** -Returns system time. */ +Returns system time. +Upon successful completion, the value 0 is returned; otherwise the +value -1 is returned and the global variable errno is set to indicate the +error. */ -void +int ut_usectime( /*========*/ + /* out: 0 on success, -1 otherwise */ ulint* sec, /* out: seconds since the Epoch */ ulint* ms); /* out: microseconds since the Epoch+*sec */ /************************************************************** diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 431138400b6..6b755ae9816 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -1372,7 +1372,7 @@ srv_table_reserve_slot_for_mysql(void) /******************************************************************* Puts a MySQL OS thread to wait for a lock to be released. If an error -occurs during the wait trx->error_state associated with thr is +occurs during the wait, then trx->error_state associated with thr is != DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK are possible errors. DB_DEADLOCK is returned if selective deadlock resolution chose this transaction as a victim. */ @@ -1442,8 +1442,11 @@ srv_suspend_mysql_thread( srv_n_lock_wait_count++; srv_n_lock_wait_current_count++; - ut_usectime(&sec, &ms); - start_time = (ib_longlong)sec * 1000000 + ms; + if (ut_usectime(&sec, &ms) == -1) { + start_time = -1; + } else { + start_time = (ib_longlong)sec * 1000000 + ms; + } } /* Wake the lock timeout monitor thread, if it is suspended */ @@ -1497,14 +1500,20 @@ srv_suspend_mysql_thread( wait_time = ut_difftime(ut_time(), slot->suspend_time); if (thr->lock_state == QUE_THR_LOCK_ROW) { - ut_usectime(&sec, &ms); - finish_time = (ib_longlong)sec * 1000000 + ms; + if (ut_usectime(&sec, &ms) == -1) { + finish_time = -1; + } else { + finish_time = (ib_longlong)sec * 1000000 + ms; + } diff_time = (ulint) (finish_time - start_time); srv_n_lock_wait_current_count--; srv_n_lock_wait_time = srv_n_lock_wait_time + diff_time; - if (diff_time > srv_n_lock_max_wait_time) { + if (diff_time > srv_n_lock_max_wait_time && + /* only update the variable if we successfully + retrieved the start and finish times. See Bug#36819. */ + start_time != -1 && finish_time != -1) { srv_n_lock_max_wait_time = diff_time; } } diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c index feb03269d91..b93838a1885 100644 --- a/innobase/ut/ut0ut.c +++ b/innobase/ut/ut0ut.c @@ -123,19 +123,45 @@ ut_time(void) } /************************************************************** -Returns system time. */ +Returns system time. +Upon successful completion, the value 0 is returned; otherwise the +value -1 is returned and the global variable errno is set to indicate the +error. */ -void +int ut_usectime( /*========*/ + /* out: 0 on success, -1 otherwise */ ulint* sec, /* out: seconds since the Epoch */ ulint* ms) /* out: microseconds since the Epoch+*sec */ { struct timeval tv; + int ret; + int errno_gettimeofday; + int i; + + for (i = 0; i < 10; i++) { + + ret = ut_gettimeofday(&tv, NULL); + + if (ret == -1) { + errno_gettimeofday = errno; + ut_print_timestamp(stderr); + fprintf(stderr, " InnoDB: gettimeofday(): %s\n", + strerror(errno_gettimeofday)); + os_thread_sleep(100000); /* 0.1 sec */ + errno = errno_gettimeofday; + } else { + break; + } + } + + if (ret != -1) { + *sec = (ulint) tv.tv_sec; + *ms = (ulint) tv.tv_usec; + } - ut_gettimeofday(&tv, NULL); - *sec = (ulint) tv.tv_sec; - *ms = (ulint) tv.tv_usec; + return(ret); } /************************************************************** -- cgit v1.2.1 From 955d8184b3c9c3277124f285ef600a209a278d27 Mon Sep 17 00:00:00 2001 From: Timothy Smith Date: Fri, 12 Dec 2008 17:40:31 -0700 Subject: Apply 3 patches from innodb-5.0-ss2637. This fixes Bug#36149: Read buffer overflow in srv0start.c found during "make test" Per-revision comments: r2484 | vasil | 2008-05-28 15:32:48 +0300 (Wed, 28 May 2008) | 9 lines Fix Bug#36149 Read buffer overflow in srv0start.c found during "make test" Use strncmp(3) instead of memcmp(3) to avoid reading past end of the string if it is empty (*str == '\0'). This bug is _not_ a buffer overflow. Discussed with: Sunny (via IM) r2538 | inaam | 2008-07-15 21:24:02 +0300 (Tue, 15 Jul 2008) | 15 lines Fix of issue# 4 Fixed a timing hole where a thread dropping an index can free the in-memory index struct while another thread is still using that structure to remove entries from adaptive hash index belonging to one of the pages that belongs to the index being dropped. The fix is to have a reference counter in the index struct and to wait for this counter to drop to zero beforing freeing the struct. Reviewed by: Heikki r2544 | inaam | 2008-07-22 18:58:11 +0300 (Tue, 22 Jul 2008) | 8 lines Removed UNIV_INLINE qualifier from btr_search_info_get_ref_count(). Otherwise compilation failed on non-debug builds. Pointed by: Vasil --- innobase/btr/btr0sea.c | 40 +++++++++++++++++++++++++++++++++++++++ innobase/dict/dict0dict.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ innobase/include/btr0sea.h | 21 +++++++++++++++++++-- innobase/srv/srv0start.c | 8 ++++---- 4 files changed, 110 insertions(+), 6 deletions(-) diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index ed746bcf12c..3c202c5a3bf 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -162,6 +162,8 @@ btr_search_info_create( info->last_search = NULL; info->n_direction = 0; + + info->ref_count = 0; info->root_guess = NULL; info->hash_analysis = 0; @@ -183,6 +185,31 @@ btr_search_info_create( return(info); } +/********************************************************************* +Returns the value of ref_count. The value is protected by +btr_search_latch. */ +ulint +btr_search_info_get_ref_count( +/*==========================*/ + /* out: ref_count value. */ + btr_search_t* info) /* in: search info. */ +{ + ulint ret; + + ut_ad(info); + +#ifdef UNIV_SYNC_DEBUG + ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED)); + ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ + + rw_lock_s_lock(&btr_search_latch); + ret = info->ref_count; + rw_lock_s_unlock(&btr_search_latch); + + return(ret); +} + /************************************************************************* Updates the search info of an index about hash successes. NOTE that info is NOT protected by any semaphore, to save CPU time! Do not assume its fields @@ -1019,8 +1046,12 @@ next_rec: ha_remove_all_nodes_to_page(table, folds[i], page); } + ut_a(index->search_info->ref_count > 0); + index->search_info->ref_count--; + block->is_hashed = FALSE; block->index = NULL; + cleanup: if (UNIV_UNLIKELY(block->n_pointers)) { /* Corruption */ @@ -1241,6 +1272,15 @@ btr_search_build_page_hash_index( goto exit_func; } + /* This counter is decremented every time we drop page + hash index entries and is incremented here. Since we can + rebuild hash index for a page that is already hashed, we + have to take care not to increment the counter in that + case. */ + if (!block->is_hashed) { + index->search_info->ref_count++; + } + block->is_hashed = TRUE; block->n_hash_helps = 0; diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index b8d9f362b06..b0d95597153 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -1556,6 +1556,8 @@ dict_index_remove_from_cache( dict_field_t* field; ulint size; ulint i; + ulint retries = 0; + btr_search_t* info; ut_ad(table && index); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); @@ -1564,6 +1566,51 @@ dict_index_remove_from_cache( ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ + /* We always create search info whether or not adaptive + hash index is enabled or not. */ + info = index->search_info; + ut_ad(info); + + /* We are not allowed to free the in-memory index struct + dict_index_t until all entries in the adaptive hash index + that point to any of the page belonging to his b-tree index + are dropped. This is so because dropping of these entries + require access to dict_index_t struct. To avoid such scenario + We keep a count of number of such pages in the search_info and + only free the dict_index_t struct when this count drops to + zero. */ + + for (;;) { + ulint ref_count = btr_search_info_get_ref_count(info); + if (ref_count == 0) { + break; + } + + /* Sleep for 10ms before trying again. */ + os_thread_sleep(10000); + ++retries; + + if (retries % 500 == 0) { + /* No luck after 5 seconds of wait. */ + fprintf(stderr, "InnoDB: Error: Waited for" + " %lu secs for hash index" + " ref_count (%lu) to drop" + " to 0.\n" + "index: \"%s\"" + " table: \"%s\"\n", + retries/100, + ref_count, + index->name, + table->name); + } + + /* To avoid a hang here we commit suicide if the + ref_count doesn't drop to zero in 600 seconds. */ + if (retries >= 60000) { + ut_error; + } + } + ut_ad(UT_LIST_GET_LEN((index->tree)->tree_indexes) == 1); dict_tree_free(index->tree); diff --git a/innobase/include/btr0sea.h b/innobase/include/btr0sea.h index 78e88a24083..370132af60d 100644 --- a/innobase/include/btr0sea.h +++ b/innobase/include/btr0sea.h @@ -40,6 +40,14 @@ btr_search_info_create( /*===================*/ /* out, own: search info struct */ mem_heap_t* heap); /* in: heap where created */ +/********************************************************************* +Returns the value of ref_count. The value is protected by +btr_search_latch. */ +ulint +btr_search_info_get_ref_count( +/*==========================*/ + /* out: ref_count value. */ + btr_search_t* info); /* in: search info. */ /************************************************************************* Updates the search info. */ UNIV_INLINE @@ -144,6 +152,13 @@ btr_search_validate(void); struct btr_search_struct{ ulint magic_n; /* magic number */ + ulint ref_count; /* Number of blocks in this index tree + that have search index built + i.e. block->index points to this index. + Protected by btr_search_latch except + when during initialization in + btr_search_info_create(). */ + /* The following 4 fields are currently not used: */ rec_t* last_search; /* pointer to the lower limit record of the previous search; NULL if not known */ @@ -154,8 +169,10 @@ struct btr_search_struct{ or BTR_SEA_SAME_PAGE */ dulint modify_clock; /* value of modify clock at the time last_search was stored */ - /*----------------------*/ - /* The following 4 fields are not protected by any latch: */ + + /* The following fields are not protected by any latch. + Unfortunately, this means that they must be aligned to + the machine word, i.e., they cannot be turned into bit-fields. */ page_t* root_guess; /* the root page frame when it was last time fetched, or NULL */ ulint hash_analysis; /* when this exceeds a certain value, the diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 5f8707a661c..d380eb14710 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -180,11 +180,11 @@ srv_parse_data_file_paths_and_sizes( str++; } - if (0 == memcmp(str, ":autoextend", (sizeof ":autoextend") - 1)) { + if (0 == strncmp(str, ":autoextend", (sizeof ":autoextend") - 1)) { str += (sizeof ":autoextend") - 1; - if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) { + if (0 == strncmp(str, ":max:", (sizeof ":max:") - 1)) { str += (sizeof ":max:") - 1; @@ -288,13 +288,13 @@ srv_parse_data_file_paths_and_sizes( (*data_file_names)[i] = path; (*data_file_sizes)[i] = size; - if (0 == memcmp(str, ":autoextend", (sizeof ":autoextend") - 1)) { + if (0 == strncmp(str, ":autoextend", (sizeof ":autoextend") - 1)) { *is_auto_extending = TRUE; str += (sizeof ":autoextend") - 1; - if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) { + if (0 == strncmp(str, ":max:", (sizeof ":max:") - 1)) { str += (sizeof ":max:") - 1; -- cgit v1.2.1 From 879254e935bc9b95f0dfb9315a392bd119d1186e Mon Sep 17 00:00:00 2001 From: Timothy Smith Date: Fri, 12 Dec 2008 17:42:34 -0700 Subject: r2629 | inaam | 2008-09-16 18:46:00 +0300 (Tue, 16 Sep 2008) | 9 lines branches/5.0 bug#39483 InnoDB hang on adaptive hash because of out of order ::open() call by MySQL Under some conditions MySQL calls ::open with search_latch leading to a deadlock as we try to acquire dict_sys->mutex inside ::open breaking the latching order. The fix is to release search_latch. Reviewed by: Heikki --- sql/ha_innodb.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 1c0f8a6e9b3..83e2d025f18 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2158,6 +2158,14 @@ ha_innobase::open( UT_NOT_USED(test_if_locked); thd = current_thd; + + /* Under some cases MySQL seems to call this function while + holding btr_search_latch. This breaks the latching order as + we acquire dict_sys->mutex below and leads to a deadlock. */ + if (thd != NULL) { + innobase_release_temporary_latches(thd); + } + normalize_table_name(norm_name, name); user_thd = NULL; -- cgit v1.2.1 From 8cecb71d1d24da8260e996d02be171e02d495bbc Mon Sep 17 00:00:00 2001 From: Sergey Petrunia Date: Fri, 19 Dec 2008 16:38:39 +0300 Subject: BUG#40974: Incorrect query results when using clause evaluated using range check - QUICK_INDEX_MERGE_SELECT deinitializes its rnd_pos() scan when it reaches EOF, but we need to make the deinitialization in QUICK_INDEX_MERGE_SELECT destructor also. This is because certain execution strategies can stop scanning without reaching EOF, then then try to do a full table scan on this table. Failure to deinitialize caused the full scan to use (already empty) table->sort and produce zero records. mysql-test/r/index_merge.result: BUG#40974: Incorrect query results when using clause evaluated using range check - Testcase mysql-test/t/index_merge.test: BUG#40974: Incorrect query results when using clause evaluated using range check - Testcase --- mysql-test/r/index_merge.result | 28 ++++++++++++++++++++++++++++ mysql-test/t/index_merge.test | 26 ++++++++++++++++++++++++++ sql/opt_range.cc | 3 +++ 3 files changed, 57 insertions(+) diff --git a/mysql-test/r/index_merge.result b/mysql-test/r/index_merge.result index ed397e8fdc8..f3fce29c910 100644 --- a/mysql-test/r/index_merge.result +++ b/mysql-test/r/index_merge.result @@ -527,4 +527,32 @@ b a y z DROP TABLE t1; +# +# BUG#40974: Incorrect query results when using clause evaluated using range check +# +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a int); +insert into t1 values (1),(2); +create table t2(a int, b int); +insert into t2 values (1,1), (2, 1000); +create table t3 (a int, b int, filler char(100), key(a), key(b)); +insert into t3 select 1000, 1000,'filler' from t0 A, t0 B, t0 C; +insert into t3 values (1,1,'data'); +insert into t3 values (1,1,'data'); +The plan should be ALL/ALL/ALL(Range checked for each record (index map: 0x3) +explain select * from t1 +where exists (select 1 from t2, t3 +where t2.a=t1.a and (t3.a=t2.b or t3.b=t2.b or t3.b=t2.b+1)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t3 ALL a,b NULL NULL NULL 1002 Range checked for each record (index map: 0x3) +select * from t1 +where exists (select 1 from t2, t3 +where t2.a=t1.a and (t3.a=t2.b or t3.b=t2.b or t3.b=t2.b+1)); +a +1 +2 +drop table t0, t1, t2, t3; End of 5.0 tests diff --git a/mysql-test/t/index_merge.test b/mysql-test/t/index_merge.test index 970b9a87454..7f176a4cd11 100644 --- a/mysql-test/t/index_merge.test +++ b/mysql-test/t/index_merge.test @@ -477,4 +477,30 @@ SELECT b,a from t1 WHERE (b!='c' AND b!='f' && b!='h') OR DROP TABLE t1; +--echo # +--echo # BUG#40974: Incorrect query results when using clause evaluated using range check +--echo # +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t1 (a int); +insert into t1 values (1),(2); +create table t2(a int, b int); +insert into t2 values (1,1), (2, 1000); +create table t3 (a int, b int, filler char(100), key(a), key(b)); + +insert into t3 select 1000, 1000,'filler' from t0 A, t0 B, t0 C; +insert into t3 values (1,1,'data'); +insert into t3 values (1,1,'data'); +-- echo The plan should be ALL/ALL/ALL(Range checked for each record (index map: 0x3) +explain select * from t1 +where exists (select 1 from t2, t3 + where t2.a=t1.a and (t3.a=t2.b or t3.b=t2.b or t3.b=t2.b+1)); + +select * from t1 +where exists (select 1 from t2, t3 + where t2.a=t1.a and (t3.a=t2.b or t3.b=t2.b or t3.b=t2.b+1)); + +drop table t0, t1, t2, t3; + --echo End of 5.0 tests diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 204ebdb6f33..744415fa2fe 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1109,6 +1109,9 @@ QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT() quick->file= NULL; quick_selects.delete_elements(); delete pk_quick_select; + /* It's ok to call the next two even if they are already deinitialized */ + end_read_record(&read_record); + free_io_cache(head); free_root(&alloc,MYF(0)); DBUG_VOID_RETURN; } -- cgit v1.2.1 From 43ee0f9f972a10ca888fcf509c2a0e6ad1e66d6d Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 23 Dec 2008 18:08:04 +0400 Subject: Bug#37575 UCASE fails on monthname The MONTHNAME/DAYNAME functions returns binary string, so the LOWER/UPPER functions are not effective on the result of MONTHNAME/DAYNAME call. Character set of the MONTHNAME/DAYNAME function result has been changed to connection character set. include/m_ctype.h: added my_charset_repertoire function mysql-test/r/ctype_ucs.result: test result mysql-test/r/func_time.result: test result mysql-test/t/ctype_ucs.test: test case mysql-test/t/func_time.test: test case sql/item_timefunc.cc: Item_func_monthname::fix_length_and_dec and Item_func_dayname::fix_length_and_dec methods have been modified to use connection character set sql/item_timefunc.h: Item_func_monthname::fix_length_and_dec and Item_func_dayname::fix_length_and_dec methods have been modified to use connection character set sql/mysql_priv.h: added max_month_name_length, max_day_name_length fields into MY_LOCALE struct sql/mysqld.cc: The test_lc_time_sz function controls modifications of the locale database in debugging mode. sql/sql_locale.cc: initialization of max_month_name_length, max_day_name_length fields strings/ctype.c: added my_charset_repertoire function --- include/m_ctype.h | 1 + mysql-test/r/ctype_ucs.result | 53 +++++ mysql-test/r/func_time.result | 15 ++ mysql-test/t/ctype_ucs.test | 25 +++ mysql-test/t/func_time.test | 9 + sql/item_timefunc.cc | 41 +++- sql/item_timefunc.h | 18 +- sql/mysql_priv.h | 9 +- sql/mysqld.cc | 42 ++++ sql/sql_locale.cc | 436 +++++++++++++++++++++++++++++++----------- strings/ctype.c | 10 + 11 files changed, 527 insertions(+), 132 deletions(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index 218ec2daadb..007edaf7740 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -445,6 +445,7 @@ my_bool my_propagate_complex(CHARSET_INFO *cs, const uchar *str, uint len); uint my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong len); my_bool my_charset_is_ascii_based(CHARSET_INFO *cs); my_bool my_charset_is_8bit_pure_ascii(CHARSET_INFO *cs); +uint my_charset_repertoire(CHARSET_INFO *cs); #define _MY_U 01 /* Upper case */ diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 89e8f1f6221..8c0f1a108a6 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -1111,4 +1111,57 @@ set names latin1; select hex(char(0x41 using ucs2)); hex(char(0x41 using ucs2)) 0041 +SET character_set_connection=ucs2; +SELECT CHARSET(DAYNAME(19700101)); +CHARSET(DAYNAME(19700101)) +ucs2 +SELECT CHARSET(MONTHNAME(19700101)); +CHARSET(MONTHNAME(19700101)) +ucs2 +SELECT LOWER(DAYNAME(19700101)); +LOWER(DAYNAME(19700101)) +thursday +SELECT LOWER(MONTHNAME(19700101)); +LOWER(MONTHNAME(19700101)) +january +SELECT UPPER(DAYNAME(19700101)); +UPPER(DAYNAME(19700101)) +THURSDAY +SELECT UPPER(MONTHNAME(19700101)); +UPPER(MONTHNAME(19700101)) +JANUARY +SELECT HEX(MONTHNAME(19700101)); +HEX(MONTHNAME(19700101)) +004A0061006E0075006100720079 +SELECT HEX(DAYNAME(19700101)); +HEX(DAYNAME(19700101)) +00540068007500720073006400610079 +SET LC_TIME_NAMES=ru_RU; +SET NAMES utf8; +SET character_set_connection=ucs2; +SELECT CHARSET(DAYNAME(19700101)); +CHARSET(DAYNAME(19700101)) +ucs2 +SELECT CHARSET(MONTHNAME(19700101)); +CHARSET(MONTHNAME(19700101)) +ucs2 +SELECT LOWER(DAYNAME(19700101)); +LOWER(DAYNAME(19700101)) +четверг +SELECT LOWER(MONTHNAME(19700101)); +LOWER(MONTHNAME(19700101)) +ÑÐ½Ð²Ð°Ñ€Ñ +SELECT UPPER(DAYNAME(19700101)); +UPPER(DAYNAME(19700101)) +ЧЕТВЕРГ +SELECT UPPER(MONTHNAME(19700101)); +UPPER(MONTHNAME(19700101)) +ЯÐÐ’ÐРЯ +SELECT HEX(MONTHNAME(19700101)); +HEX(MONTHNAME(19700101)) +042F043D043204300440044F +SELECT HEX(DAYNAME(19700101)); +HEX(DAYNAME(19700101)) +0427043504420432043504400433 +SET character_set_connection=latin1; End of 5.0 tests diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index d397947d7ca..b3505795494 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -592,6 +592,21 @@ unix_timestamp('1970-01-01 03:00:01') select unix_timestamp('2038-01-19 07:14:07'); unix_timestamp('2038-01-19 07:14:07') 0 +SELECT CHARSET(DAYNAME(19700101)); +CHARSET(DAYNAME(19700101)) +latin1 +SELECT CHARSET(MONTHNAME(19700101)); +CHARSET(MONTHNAME(19700101)) +latin1 +SELECT LOWER(DAYNAME(19700101)); +LOWER(DAYNAME(19700101)) +thursday +SELECT LOWER(MONTHNAME(19700101)); +LOWER(MONTHNAME(19700101)) +january +SELECT COERCIBILITY(MONTHNAME('1970-01-01')),COERCIBILITY(DAYNAME('1970-01-01')); +COERCIBILITY(MONTHNAME('1970-01-01')) COERCIBILITY(DAYNAME('1970-01-01')) +4 4 CREATE TABLE t1 (datetime datetime, timestamp timestamp, date date, time time); INSERT INTO t1 values ("2001-01-02 03:04:05", "2002-01-02 03:04:05", "2003-01-02", "06:07:08"); SELECT * from t1; diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index 854a2fa3c5e..715b74dd2a8 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -685,4 +685,29 @@ set names latin1; # select hex(char(0x41 using ucs2)); +# +# Bug#37575: UCASE fails on monthname +# +SET character_set_connection=ucs2; +SELECT CHARSET(DAYNAME(19700101)); +SELECT CHARSET(MONTHNAME(19700101)); +SELECT LOWER(DAYNAME(19700101)); +SELECT LOWER(MONTHNAME(19700101)); +SELECT UPPER(DAYNAME(19700101)); +SELECT UPPER(MONTHNAME(19700101)); +SELECT HEX(MONTHNAME(19700101)); +SELECT HEX(DAYNAME(19700101)); +SET LC_TIME_NAMES=ru_RU; +SET NAMES utf8; +SET character_set_connection=ucs2; +SELECT CHARSET(DAYNAME(19700101)); +SELECT CHARSET(MONTHNAME(19700101)); +SELECT LOWER(DAYNAME(19700101)); +SELECT LOWER(MONTHNAME(19700101)); +SELECT UPPER(DAYNAME(19700101)); +SELECT UPPER(MONTHNAME(19700101)); +SELECT HEX(MONTHNAME(19700101)); +SELECT HEX(DAYNAME(19700101)); +SET character_set_connection=latin1; + --echo End of 5.0 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index ef22adb4251..65d8764f2ce 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -304,6 +304,15 @@ select unix_timestamp('1970-01-01 03:00:01'); # check bad date, close to the boundary (we cut them off in the very end) select unix_timestamp('2038-01-19 07:14:07'); +# +# Bug #28759: DAYNAME() and MONTHNAME() return binary string +# + +SELECT CHARSET(DAYNAME(19700101)); +SELECT CHARSET(MONTHNAME(19700101)); +SELECT LOWER(DAYNAME(19700101)); +SELECT LOWER(MONTHNAME(19700101)); +SELECT COERCIBILITY(MONTHNAME('1970-01-01')),COERCIBILITY(DAYNAME('1970-01-01')); # # Test types from + INTERVAL diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index e9e92952908..38d9d62bd99 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1036,12 +1036,25 @@ longlong Item_func_month::val_int() } +void Item_func_monthname::fix_length_and_dec() +{ + THD* thd= current_thd; + CHARSET_INFO *cs= thd->variables.collation_connection; + uint32 repertoire= my_charset_repertoire(cs); + locale= thd->variables.lc_time_names; + collation.set(cs, DERIVATION_COERCIBLE, repertoire); + decimals=0; + max_length= locale->max_month_name_length * collation.collation->mbmaxlen; + maybe_null=1; +} + + String* Item_func_monthname::val_str(String* str) { DBUG_ASSERT(fixed == 1); const char *month_name; - uint month= (uint) val_int(); - THD *thd= current_thd; + uint month= (uint) val_int(); + uint err; if (null_value || !month) { @@ -1049,8 +1062,9 @@ String* Item_func_monthname::val_str(String* str) return (String*) 0; } null_value=0; - month_name= thd->variables.lc_time_names->month_names->type_names[month-1]; - str->set(month_name, strlen(month_name), system_charset_info); + month_name= locale->month_names->type_names[month-1]; + str->copy(month_name, strlen(month_name), &my_charset_utf8_bin, + collation.collation, &err); return str; } @@ -1169,19 +1183,32 @@ longlong Item_func_weekday::val_int() odbc_type) + test(odbc_type); } +void Item_func_dayname::fix_length_and_dec() +{ + THD* thd= current_thd; + CHARSET_INFO *cs= thd->variables.collation_connection; + uint32 repertoire= my_charset_repertoire(cs); + locale= thd->variables.lc_time_names; + collation.set(cs, DERIVATION_COERCIBLE, repertoire); + decimals=0; + max_length= locale->max_day_name_length * collation.collation->mbmaxlen; + maybe_null=1; +} + String* Item_func_dayname::val_str(String* str) { DBUG_ASSERT(fixed == 1); uint weekday=(uint) val_int(); // Always Item_func_daynr() const char *day_name; - THD *thd= current_thd; + uint err; if (null_value) return (String*) 0; - day_name= thd->variables.lc_time_names->day_names->type_names[weekday]; - str->set(day_name, strlen(day_name), system_charset_info); + day_name= locale->day_names->type_names[weekday]; + str->copy(day_name, strlen(day_name), &my_charset_utf8_bin, + collation.collation, &err); return str; } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 81a6c3e98bd..161a77f60b4 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -108,18 +108,13 @@ public: class Item_func_monthname :public Item_func_month { + MY_LOCALE *locale; public: Item_func_monthname(Item *a) :Item_func_month(a) {} const char *func_name() const { return "monthname"; } String *val_str(String *str); enum Item_result result_type () const { return STRING_RESULT; } - void fix_length_and_dec() - { - collation.set(&my_charset_bin); - decimals=0; - max_length=10*my_charset_bin.mbmaxlen; - maybe_null=1; - } + void fix_length_and_dec(); }; @@ -272,18 +267,13 @@ public: class Item_func_dayname :public Item_func_weekday { + MY_LOCALE *locale; public: Item_func_dayname(Item *a) :Item_func_weekday(a,0) {} const char *func_name() const { return "dayname"; } String *val_str(String *str); enum Item_result result_type () const { return STRING_RESULT; } - void fix_length_and_dec() - { - collation.set(&my_charset_bin); - decimals=0; - max_length=9*MY_CHARSET_BIN_MB_MAXLEN; - maybe_null=1; - } + void fix_length_and_dec(); }; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 520d97b5e9f..a06a7e7d6e3 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -132,15 +132,20 @@ typedef struct my_locale_st TYPELIB *ab_month_names; TYPELIB *day_names; TYPELIB *ab_day_names; + uint max_month_name_length; + uint max_day_name_length; #ifdef __cplusplus my_locale_st(uint number_par, const char *name_par, const char *descr_par, bool is_ascii_par, TYPELIB *month_names_par, TYPELIB *ab_month_names_par, - TYPELIB *day_names_par, TYPELIB *ab_day_names_par) : + TYPELIB *day_names_par, TYPELIB *ab_day_names_par, + uint max_month_name_length_par, uint max_day_name_length_par) : number(number_par), name(name_par), description(descr_par), is_ascii(is_ascii_par), month_names(month_names_par), ab_month_names(ab_month_names_par), - day_names(day_names_par), ab_day_names(ab_day_names_par) + day_names(day_names_par), ab_day_names(ab_day_names_par), + max_month_name_length(max_month_name_length_par), + max_day_name_length(max_day_name_length_par) {} #endif } MY_LOCALE; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 8232cefc880..f5e5b881a37 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3616,6 +3616,44 @@ void decrement_handler_count() #endif /* defined(__NT__) || defined(HAVE_SMEM) */ +#ifndef DBUG_OFF +/* + Debugging helper function to keep the locale database + (see sql_locale.cc) and max_month_name_length and + max_day_name_length variable values in consistent state. +*/ +static void test_lc_time_sz() +{ + DBUG_ENTER("test_lc_time_sz"); + for (MY_LOCALE **loc= my_locales; *loc; loc++) + { + uint max_month_len= 0; + uint max_day_len = 0; + for (const char **month= (*loc)->month_names->type_names; *month; month++) + { + set_if_bigger(max_month_len, + my_numchars_mb(&my_charset_utf8_general_ci, + *month, *month + strlen(*month))); + } + for (const char **day= (*loc)->day_names->type_names; *day; day++) + { + set_if_bigger(max_day_len, + my_numchars_mb(&my_charset_utf8_general_ci, + *day, *day + strlen(*day))); + } + if ((*loc)->max_month_name_length != max_month_len || + (*loc)->max_day_name_length != max_day_len) + { + DBUG_PRINT("Wrong max day name(or month name) length for locale:", + ("%s", (*loc)->name)); + DBUG_ASSERT(0); + } + } + DBUG_VOID_RETURN; +} +#endif//DBUG_OFF + + #ifndef EMBEDDED_LIBRARY #ifdef __WIN__ int win_main(int argc, char **argv) @@ -3712,6 +3750,10 @@ int main(int argc, char **argv) openlog(libwrapName, LOG_PID, LOG_AUTH); #endif +#ifndef DBUG_OFF + test_lc_time_sz(); +#endif + /* We have enough space for fiddling with the argv, continue */ diff --git a/sql/sql_locale.cc b/sql/sql_locale.cc index 4e61c664106..3def9864c29 100644 --- a/sql/sql_locale.cc +++ b/sql/sql_locale.cc @@ -49,7 +49,9 @@ MY_LOCALE my_locale_ar_AE &my_locale_typelib_month_names_ar_AE, &my_locale_typelib_ab_month_names_ar_AE, &my_locale_typelib_day_names_ar_AE, - &my_locale_typelib_ab_day_names_ar_AE + &my_locale_typelib_ab_day_names_ar_AE, + 6, + 8 ); /***** LOCALE END ar_AE *****/ @@ -79,7 +81,9 @@ MY_LOCALE my_locale_ar_BH &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, - &my_locale_typelib_ab_day_names_ar_BH + &my_locale_typelib_ab_day_names_ar_BH, + 6, + 8 ); /***** LOCALE END ar_BH *****/ @@ -109,7 +113,9 @@ MY_LOCALE my_locale_ar_JO &my_locale_typelib_month_names_ar_JO, &my_locale_typelib_ab_month_names_ar_JO, &my_locale_typelib_day_names_ar_JO, - &my_locale_typelib_ab_day_names_ar_JO + &my_locale_typelib_ab_day_names_ar_JO, + 12, + 8 ); /***** LOCALE END ar_JO *****/ @@ -139,7 +145,9 @@ MY_LOCALE my_locale_ar_SA &my_locale_typelib_month_names_ar_SA, &my_locale_typelib_ab_month_names_ar_SA, &my_locale_typelib_day_names_ar_SA, - &my_locale_typelib_ab_day_names_ar_SA + &my_locale_typelib_ab_day_names_ar_SA, + 12, + 8 ); /***** LOCALE END ar_SA *****/ @@ -169,7 +177,9 @@ MY_LOCALE my_locale_ar_SY &my_locale_typelib_month_names_ar_SY, &my_locale_typelib_ab_month_names_ar_SY, &my_locale_typelib_day_names_ar_SY, - &my_locale_typelib_ab_day_names_ar_SY + &my_locale_typelib_ab_day_names_ar_SY, + 12, + 8 ); /***** LOCALE END ar_SY *****/ @@ -199,7 +209,9 @@ MY_LOCALE my_locale_be_BY &my_locale_typelib_month_names_be_BY, &my_locale_typelib_ab_month_names_be_BY, &my_locale_typelib_day_names_be_BY, - &my_locale_typelib_ab_day_names_be_BY + &my_locale_typelib_ab_day_names_be_BY, + 10, + 10 ); /***** LOCALE END be_BY *****/ @@ -229,7 +241,9 @@ MY_LOCALE my_locale_bg_BG &my_locale_typelib_month_names_bg_BG, &my_locale_typelib_ab_month_names_bg_BG, &my_locale_typelib_day_names_bg_BG, - &my_locale_typelib_ab_day_names_bg_BG + &my_locale_typelib_ab_day_names_bg_BG, + 9, + 10 ); /***** LOCALE END bg_BG *****/ @@ -259,7 +273,9 @@ MY_LOCALE my_locale_ca_ES &my_locale_typelib_month_names_ca_ES, &my_locale_typelib_ab_month_names_ca_ES, &my_locale_typelib_day_names_ca_ES, - &my_locale_typelib_ab_day_names_ca_ES + &my_locale_typelib_ab_day_names_ca_ES, + 8, + 9 ); /***** LOCALE END ca_ES *****/ @@ -289,7 +305,9 @@ MY_LOCALE my_locale_cs_CZ &my_locale_typelib_month_names_cs_CZ, &my_locale_typelib_ab_month_names_cs_CZ, &my_locale_typelib_day_names_cs_CZ, - &my_locale_typelib_ab_day_names_cs_CZ + &my_locale_typelib_ab_day_names_cs_CZ, + 8, + 7 ); /***** LOCALE END cs_CZ *****/ @@ -319,7 +337,9 @@ MY_LOCALE my_locale_da_DK &my_locale_typelib_month_names_da_DK, &my_locale_typelib_ab_month_names_da_DK, &my_locale_typelib_day_names_da_DK, - &my_locale_typelib_ab_day_names_da_DK + &my_locale_typelib_ab_day_names_da_DK, + 9, + 7 ); /***** LOCALE END da_DK *****/ @@ -349,7 +369,9 @@ MY_LOCALE my_locale_de_AT &my_locale_typelib_month_names_de_AT, &my_locale_typelib_ab_month_names_de_AT, &my_locale_typelib_day_names_de_AT, - &my_locale_typelib_ab_day_names_de_AT + &my_locale_typelib_ab_day_names_de_AT, + 9, + 10 ); /***** LOCALE END de_AT *****/ @@ -379,7 +401,9 @@ MY_LOCALE my_locale_de_DE &my_locale_typelib_month_names_de_DE, &my_locale_typelib_ab_month_names_de_DE, &my_locale_typelib_day_names_de_DE, - &my_locale_typelib_ab_day_names_de_DE + &my_locale_typelib_ab_day_names_de_DE, + 9, + 10 ); /***** LOCALE END de_DE *****/ @@ -409,7 +433,9 @@ MY_LOCALE my_locale_en_US &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, - &my_locale_typelib_ab_day_names_en_US + &my_locale_typelib_ab_day_names_en_US, + 9, + 9 ); /***** LOCALE END en_US *****/ @@ -439,7 +465,9 @@ MY_LOCALE my_locale_es_ES &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_ES *****/ @@ -469,7 +497,9 @@ MY_LOCALE my_locale_et_EE &my_locale_typelib_month_names_et_EE, &my_locale_typelib_ab_month_names_et_EE, &my_locale_typelib_day_names_et_EE, - &my_locale_typelib_ab_day_names_et_EE + &my_locale_typelib_ab_day_names_et_EE, + 9, + 9 ); /***** LOCALE END et_EE *****/ @@ -499,7 +529,9 @@ MY_LOCALE my_locale_eu_ES &my_locale_typelib_month_names_eu_ES, &my_locale_typelib_ab_month_names_eu_ES, &my_locale_typelib_day_names_eu_ES, - &my_locale_typelib_ab_day_names_eu_ES + &my_locale_typelib_ab_day_names_eu_ES, + 9, + 10 ); /***** LOCALE END eu_ES *****/ @@ -529,7 +561,9 @@ MY_LOCALE my_locale_fi_FI &my_locale_typelib_month_names_fi_FI, &my_locale_typelib_ab_month_names_fi_FI, &my_locale_typelib_day_names_fi_FI, - &my_locale_typelib_ab_day_names_fi_FI + &my_locale_typelib_ab_day_names_fi_FI, + 9, + 11 ); /***** LOCALE END fi_FI *****/ @@ -559,7 +593,9 @@ MY_LOCALE my_locale_fo_FO &my_locale_typelib_month_names_fo_FO, &my_locale_typelib_ab_month_names_fo_FO, &my_locale_typelib_day_names_fo_FO, - &my_locale_typelib_ab_day_names_fo_FO + &my_locale_typelib_ab_day_names_fo_FO, + 9, + 12 ); /***** LOCALE END fo_FO *****/ @@ -589,7 +625,9 @@ MY_LOCALE my_locale_fr_FR &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, - &my_locale_typelib_ab_day_names_fr_FR + &my_locale_typelib_ab_day_names_fr_FR, + 9, + 8 ); /***** LOCALE END fr_FR *****/ @@ -619,7 +657,9 @@ MY_LOCALE my_locale_gl_ES &my_locale_typelib_month_names_gl_ES, &my_locale_typelib_ab_month_names_gl_ES, &my_locale_typelib_day_names_gl_ES, - &my_locale_typelib_ab_day_names_gl_ES + &my_locale_typelib_ab_day_names_gl_ES, + 8, + 8 ); /***** LOCALE END gl_ES *****/ @@ -649,7 +689,9 @@ MY_LOCALE my_locale_gu_IN &my_locale_typelib_month_names_gu_IN, &my_locale_typelib_ab_month_names_gu_IN, &my_locale_typelib_day_names_gu_IN, - &my_locale_typelib_ab_day_names_gu_IN + &my_locale_typelib_ab_day_names_gu_IN, + 10, + 8 ); /***** LOCALE END gu_IN *****/ @@ -679,7 +721,9 @@ MY_LOCALE my_locale_he_IL &my_locale_typelib_month_names_he_IL, &my_locale_typelib_ab_month_names_he_IL, &my_locale_typelib_day_names_he_IL, - &my_locale_typelib_ab_day_names_he_IL + &my_locale_typelib_ab_day_names_he_IL, + 7, + 5 ); /***** LOCALE END he_IL *****/ @@ -709,7 +753,9 @@ MY_LOCALE my_locale_hi_IN &my_locale_typelib_month_names_hi_IN, &my_locale_typelib_ab_month_names_hi_IN, &my_locale_typelib_day_names_hi_IN, - &my_locale_typelib_ab_day_names_hi_IN + &my_locale_typelib_ab_day_names_hi_IN, + 7, + 9 ); /***** LOCALE END hi_IN *****/ @@ -739,7 +785,9 @@ MY_LOCALE my_locale_hr_HR &my_locale_typelib_month_names_hr_HR, &my_locale_typelib_ab_month_names_hr_HR, &my_locale_typelib_day_names_hr_HR, - &my_locale_typelib_ab_day_names_hr_HR + &my_locale_typelib_ab_day_names_hr_HR, + 8, + 11 ); /***** LOCALE END hr_HR *****/ @@ -769,7 +817,9 @@ MY_LOCALE my_locale_hu_HU &my_locale_typelib_month_names_hu_HU, &my_locale_typelib_ab_month_names_hu_HU, &my_locale_typelib_day_names_hu_HU, - &my_locale_typelib_ab_day_names_hu_HU + &my_locale_typelib_ab_day_names_hu_HU, + 10, + 9 ); /***** LOCALE END hu_HU *****/ @@ -799,7 +849,9 @@ MY_LOCALE my_locale_id_ID &my_locale_typelib_month_names_id_ID, &my_locale_typelib_ab_month_names_id_ID, &my_locale_typelib_day_names_id_ID, - &my_locale_typelib_ab_day_names_id_ID + &my_locale_typelib_ab_day_names_id_ID, + 9, + 6 ); /***** LOCALE END id_ID *****/ @@ -829,7 +881,9 @@ MY_LOCALE my_locale_is_IS &my_locale_typelib_month_names_is_IS, &my_locale_typelib_ab_month_names_is_IS, &my_locale_typelib_day_names_is_IS, - &my_locale_typelib_ab_day_names_is_IS + &my_locale_typelib_ab_day_names_is_IS, + 9, + 12 ); /***** LOCALE END is_IS *****/ @@ -859,7 +913,9 @@ MY_LOCALE my_locale_it_CH &my_locale_typelib_month_names_it_CH, &my_locale_typelib_ab_month_names_it_CH, &my_locale_typelib_day_names_it_CH, - &my_locale_typelib_ab_day_names_it_CH + &my_locale_typelib_ab_day_names_it_CH, + 9, + 9 ); /***** LOCALE END it_CH *****/ @@ -889,7 +945,9 @@ MY_LOCALE my_locale_ja_JP &my_locale_typelib_month_names_ja_JP, &my_locale_typelib_ab_month_names_ja_JP, &my_locale_typelib_day_names_ja_JP, - &my_locale_typelib_ab_day_names_ja_JP + &my_locale_typelib_ab_day_names_ja_JP, + 3, + 3 ); /***** LOCALE END ja_JP *****/ @@ -919,7 +977,9 @@ MY_LOCALE my_locale_ko_KR &my_locale_typelib_month_names_ko_KR, &my_locale_typelib_ab_month_names_ko_KR, &my_locale_typelib_day_names_ko_KR, - &my_locale_typelib_ab_day_names_ko_KR + &my_locale_typelib_ab_day_names_ko_KR, + 3, + 3 ); /***** LOCALE END ko_KR *****/ @@ -949,7 +1009,9 @@ MY_LOCALE my_locale_lt_LT &my_locale_typelib_month_names_lt_LT, &my_locale_typelib_ab_month_names_lt_LT, &my_locale_typelib_day_names_lt_LT, - &my_locale_typelib_ab_day_names_lt_LT + &my_locale_typelib_ab_day_names_lt_LT, + 9, + 14 ); /***** LOCALE END lt_LT *****/ @@ -979,7 +1041,9 @@ MY_LOCALE my_locale_lv_LV &my_locale_typelib_month_names_lv_LV, &my_locale_typelib_ab_month_names_lv_LV, &my_locale_typelib_day_names_lv_LV, - &my_locale_typelib_ab_day_names_lv_LV + &my_locale_typelib_ab_day_names_lv_LV, + 10, + 11 ); /***** LOCALE END lv_LV *****/ @@ -1009,7 +1073,9 @@ MY_LOCALE my_locale_mk_MK &my_locale_typelib_month_names_mk_MK, &my_locale_typelib_ab_month_names_mk_MK, &my_locale_typelib_day_names_mk_MK, - &my_locale_typelib_ab_day_names_mk_MK + &my_locale_typelib_ab_day_names_mk_MK, + 9, + 10 ); /***** LOCALE END mk_MK *****/ @@ -1039,7 +1105,9 @@ MY_LOCALE my_locale_mn_MN &my_locale_typelib_month_names_mn_MN, &my_locale_typelib_ab_month_names_mn_MN, &my_locale_typelib_day_names_mn_MN, - &my_locale_typelib_ab_day_names_mn_MN + &my_locale_typelib_ab_day_names_mn_MN, + 18, + 6 ); /***** LOCALE END mn_MN *****/ @@ -1069,7 +1137,9 @@ MY_LOCALE my_locale_ms_MY &my_locale_typelib_month_names_ms_MY, &my_locale_typelib_ab_month_names_ms_MY, &my_locale_typelib_day_names_ms_MY, - &my_locale_typelib_ab_day_names_ms_MY + &my_locale_typelib_ab_day_names_ms_MY, + 9, + 6 ); /***** LOCALE END ms_MY *****/ @@ -1099,7 +1169,9 @@ MY_LOCALE my_locale_nb_NO &my_locale_typelib_month_names_nb_NO, &my_locale_typelib_ab_month_names_nb_NO, &my_locale_typelib_day_names_nb_NO, - &my_locale_typelib_ab_day_names_nb_NO + &my_locale_typelib_ab_day_names_nb_NO, + 9, + 7 ); /***** LOCALE END nb_NO *****/ @@ -1129,7 +1201,9 @@ MY_LOCALE my_locale_nl_NL &my_locale_typelib_month_names_nl_NL, &my_locale_typelib_ab_month_names_nl_NL, &my_locale_typelib_day_names_nl_NL, - &my_locale_typelib_ab_day_names_nl_NL + &my_locale_typelib_ab_day_names_nl_NL, + 9, + 9 ); /***** LOCALE END nl_NL *****/ @@ -1159,7 +1233,9 @@ MY_LOCALE my_locale_pl_PL &my_locale_typelib_month_names_pl_PL, &my_locale_typelib_ab_month_names_pl_PL, &my_locale_typelib_day_names_pl_PL, - &my_locale_typelib_ab_day_names_pl_PL + &my_locale_typelib_ab_day_names_pl_PL, + 11, + 12 ); /***** LOCALE END pl_PL *****/ @@ -1189,7 +1265,9 @@ MY_LOCALE my_locale_pt_BR &my_locale_typelib_month_names_pt_BR, &my_locale_typelib_ab_month_names_pt_BR, &my_locale_typelib_day_names_pt_BR, - &my_locale_typelib_ab_day_names_pt_BR + &my_locale_typelib_ab_day_names_pt_BR, + 9, + 7 ); /***** LOCALE END pt_BR *****/ @@ -1219,7 +1297,9 @@ MY_LOCALE my_locale_pt_PT &my_locale_typelib_month_names_pt_PT, &my_locale_typelib_ab_month_names_pt_PT, &my_locale_typelib_day_names_pt_PT, - &my_locale_typelib_ab_day_names_pt_PT + &my_locale_typelib_ab_day_names_pt_PT, + 9, + 7 ); /***** LOCALE END pt_PT *****/ @@ -1249,7 +1329,9 @@ MY_LOCALE my_locale_ro_RO &my_locale_typelib_month_names_ro_RO, &my_locale_typelib_ab_month_names_ro_RO, &my_locale_typelib_day_names_ro_RO, - &my_locale_typelib_ab_day_names_ro_RO + &my_locale_typelib_ab_day_names_ro_RO, + 10, + 8 ); /***** LOCALE END ro_RO *****/ @@ -1279,7 +1361,9 @@ MY_LOCALE my_locale_ru_RU &my_locale_typelib_month_names_ru_RU, &my_locale_typelib_ab_month_names_ru_RU, &my_locale_typelib_day_names_ru_RU, - &my_locale_typelib_ab_day_names_ru_RU + &my_locale_typelib_ab_day_names_ru_RU, + 8, + 11 ); /***** LOCALE END ru_RU *****/ @@ -1309,7 +1393,9 @@ MY_LOCALE my_locale_ru_UA &my_locale_typelib_month_names_ru_UA, &my_locale_typelib_ab_month_names_ru_UA, &my_locale_typelib_day_names_ru_UA, - &my_locale_typelib_ab_day_names_ru_UA + &my_locale_typelib_ab_day_names_ru_UA, + 8, + 11 ); /***** LOCALE END ru_UA *****/ @@ -1339,7 +1425,9 @@ MY_LOCALE my_locale_sk_SK &my_locale_typelib_month_names_sk_SK, &my_locale_typelib_ab_month_names_sk_SK, &my_locale_typelib_day_names_sk_SK, - &my_locale_typelib_ab_day_names_sk_SK + &my_locale_typelib_ab_day_names_sk_SK, + 9, + 8 ); /***** LOCALE END sk_SK *****/ @@ -1369,7 +1457,9 @@ MY_LOCALE my_locale_sl_SI &my_locale_typelib_month_names_sl_SI, &my_locale_typelib_ab_month_names_sl_SI, &my_locale_typelib_day_names_sl_SI, - &my_locale_typelib_ab_day_names_sl_SI + &my_locale_typelib_ab_day_names_sl_SI, + 9, + 10 ); /***** LOCALE END sl_SI *****/ @@ -1399,7 +1489,9 @@ MY_LOCALE my_locale_sq_AL &my_locale_typelib_month_names_sq_AL, &my_locale_typelib_ab_month_names_sq_AL, &my_locale_typelib_day_names_sq_AL, - &my_locale_typelib_ab_day_names_sq_AL + &my_locale_typelib_ab_day_names_sq_AL, + 7, + 10 ); /***** LOCALE END sq_AL *****/ @@ -1429,7 +1521,9 @@ MY_LOCALE my_locale_sr_YU &my_locale_typelib_month_names_sr_YU, &my_locale_typelib_ab_month_names_sr_YU, &my_locale_typelib_day_names_sr_YU, - &my_locale_typelib_ab_day_names_sr_YU + &my_locale_typelib_ab_day_names_sr_YU, + 9, + 10 ); /***** LOCALE END sr_YU *****/ @@ -1459,7 +1553,9 @@ MY_LOCALE my_locale_sv_SE &my_locale_typelib_month_names_sv_SE, &my_locale_typelib_ab_month_names_sv_SE, &my_locale_typelib_day_names_sv_SE, - &my_locale_typelib_ab_day_names_sv_SE + &my_locale_typelib_ab_day_names_sv_SE, + 9, + 7 ); /***** LOCALE END sv_SE *****/ @@ -1489,7 +1585,9 @@ MY_LOCALE my_locale_ta_IN &my_locale_typelib_month_names_ta_IN, &my_locale_typelib_ab_month_names_ta_IN, &my_locale_typelib_day_names_ta_IN, - &my_locale_typelib_ab_day_names_ta_IN + &my_locale_typelib_ab_day_names_ta_IN, + 10, + 8 ); /***** LOCALE END ta_IN *****/ @@ -1519,7 +1617,9 @@ MY_LOCALE my_locale_te_IN &my_locale_typelib_month_names_te_IN, &my_locale_typelib_ab_month_names_te_IN, &my_locale_typelib_day_names_te_IN, - &my_locale_typelib_ab_day_names_te_IN + &my_locale_typelib_ab_day_names_te_IN, + 10, + 9 ); /***** LOCALE END te_IN *****/ @@ -1549,7 +1649,9 @@ MY_LOCALE my_locale_th_TH &my_locale_typelib_month_names_th_TH, &my_locale_typelib_ab_month_names_th_TH, &my_locale_typelib_day_names_th_TH, - &my_locale_typelib_ab_day_names_th_TH + &my_locale_typelib_ab_day_names_th_TH, + 10, + 8 ); /***** LOCALE END th_TH *****/ @@ -1579,7 +1681,9 @@ MY_LOCALE my_locale_tr_TR &my_locale_typelib_month_names_tr_TR, &my_locale_typelib_ab_month_names_tr_TR, &my_locale_typelib_day_names_tr_TR, - &my_locale_typelib_ab_day_names_tr_TR + &my_locale_typelib_ab_day_names_tr_TR, + 7, + 9 ); /***** LOCALE END tr_TR *****/ @@ -1609,7 +1713,9 @@ MY_LOCALE my_locale_uk_UA &my_locale_typelib_month_names_uk_UA, &my_locale_typelib_ab_month_names_uk_UA, &my_locale_typelib_day_names_uk_UA, - &my_locale_typelib_ab_day_names_uk_UA + &my_locale_typelib_ab_day_names_uk_UA, + 8, + 9 ); /***** LOCALE END uk_UA *****/ @@ -1639,7 +1745,9 @@ MY_LOCALE my_locale_ur_PK &my_locale_typelib_month_names_ur_PK, &my_locale_typelib_ab_month_names_ur_PK, &my_locale_typelib_day_names_ur_PK, - &my_locale_typelib_ab_day_names_ur_PK + &my_locale_typelib_ab_day_names_ur_PK, + 6, + 6 ); /***** LOCALE END ur_PK *****/ @@ -1669,7 +1777,9 @@ MY_LOCALE my_locale_vi_VN &my_locale_typelib_month_names_vi_VN, &my_locale_typelib_ab_month_names_vi_VN, &my_locale_typelib_day_names_vi_VN, - &my_locale_typelib_ab_day_names_vi_VN + &my_locale_typelib_ab_day_names_vi_VN, + 16, + 11 ); /***** LOCALE END vi_VN *****/ @@ -1699,7 +1809,9 @@ MY_LOCALE my_locale_zh_CN &my_locale_typelib_month_names_zh_CN, &my_locale_typelib_ab_month_names_zh_CN, &my_locale_typelib_day_names_zh_CN, - &my_locale_typelib_ab_day_names_zh_CN + &my_locale_typelib_ab_day_names_zh_CN, + 3, + 3 ); /***** LOCALE END zh_CN *****/ @@ -1729,7 +1841,9 @@ MY_LOCALE my_locale_zh_TW &my_locale_typelib_month_names_zh_TW, &my_locale_typelib_ab_month_names_zh_TW, &my_locale_typelib_day_names_zh_TW, - &my_locale_typelib_ab_day_names_zh_TW + &my_locale_typelib_ab_day_names_zh_TW, + 3, + 2 ); /***** LOCALE END zh_TW *****/ @@ -1743,7 +1857,9 @@ MY_LOCALE my_locale_ar_DZ &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, - &my_locale_typelib_ab_day_names_ar_BH + &my_locale_typelib_ab_day_names_ar_BH, + 6, + 8 ); /***** LOCALE END ar_DZ *****/ @@ -1757,7 +1873,9 @@ MY_LOCALE my_locale_ar_EG &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, - &my_locale_typelib_ab_day_names_ar_BH + &my_locale_typelib_ab_day_names_ar_BH, + 6, + 8 ); /***** LOCALE END ar_EG *****/ @@ -1771,7 +1889,9 @@ MY_LOCALE my_locale_ar_IN &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, - &my_locale_typelib_ab_day_names_ar_BH + &my_locale_typelib_ab_day_names_ar_BH, + 6, + 8 ); /***** LOCALE END ar_IN *****/ @@ -1785,7 +1905,9 @@ MY_LOCALE my_locale_ar_IQ &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, - &my_locale_typelib_ab_day_names_ar_BH + &my_locale_typelib_ab_day_names_ar_BH, + 6, + 8 ); /***** LOCALE END ar_IQ *****/ @@ -1799,7 +1921,9 @@ MY_LOCALE my_locale_ar_KW &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, - &my_locale_typelib_ab_day_names_ar_BH + &my_locale_typelib_ab_day_names_ar_BH, + 6, + 8 ); /***** LOCALE END ar_KW *****/ @@ -1813,7 +1937,9 @@ MY_LOCALE my_locale_ar_LB &my_locale_typelib_month_names_ar_JO, &my_locale_typelib_ab_month_names_ar_JO, &my_locale_typelib_day_names_ar_JO, - &my_locale_typelib_ab_day_names_ar_JO + &my_locale_typelib_ab_day_names_ar_JO, + 12, + 8 ); /***** LOCALE END ar_LB *****/ @@ -1827,7 +1953,9 @@ MY_LOCALE my_locale_ar_LY &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, - &my_locale_typelib_ab_day_names_ar_BH + &my_locale_typelib_ab_day_names_ar_BH, + 6, + 8 ); /***** LOCALE END ar_LY *****/ @@ -1841,7 +1969,9 @@ MY_LOCALE my_locale_ar_MA &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, - &my_locale_typelib_ab_day_names_ar_BH + &my_locale_typelib_ab_day_names_ar_BH, + 6, + 8 ); /***** LOCALE END ar_MA *****/ @@ -1855,7 +1985,9 @@ MY_LOCALE my_locale_ar_OM &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, - &my_locale_typelib_ab_day_names_ar_BH + &my_locale_typelib_ab_day_names_ar_BH, + 6, + 8 ); /***** LOCALE END ar_OM *****/ @@ -1869,7 +2001,9 @@ MY_LOCALE my_locale_ar_QA &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, - &my_locale_typelib_ab_day_names_ar_BH + &my_locale_typelib_ab_day_names_ar_BH, + 6, + 8 ); /***** LOCALE END ar_QA *****/ @@ -1883,7 +2017,9 @@ MY_LOCALE my_locale_ar_SD &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, - &my_locale_typelib_ab_day_names_ar_BH + &my_locale_typelib_ab_day_names_ar_BH, + 6, + 8 ); /***** LOCALE END ar_SD *****/ @@ -1897,7 +2033,9 @@ MY_LOCALE my_locale_ar_TN &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, - &my_locale_typelib_ab_day_names_ar_BH + &my_locale_typelib_ab_day_names_ar_BH, + 6, + 8 ); /***** LOCALE END ar_TN *****/ @@ -1911,7 +2049,9 @@ MY_LOCALE my_locale_ar_YE &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, - &my_locale_typelib_ab_day_names_ar_BH + &my_locale_typelib_ab_day_names_ar_BH, + 6, + 8 ); /***** LOCALE END ar_YE *****/ @@ -1925,7 +2065,9 @@ MY_LOCALE my_locale_de_BE &my_locale_typelib_month_names_de_DE, &my_locale_typelib_ab_month_names_de_DE, &my_locale_typelib_day_names_de_DE, - &my_locale_typelib_ab_day_names_de_DE + &my_locale_typelib_ab_day_names_de_DE, + 9, + 10 ); /***** LOCALE END de_BE *****/ @@ -1939,7 +2081,9 @@ MY_LOCALE my_locale_de_CH &my_locale_typelib_month_names_de_DE, &my_locale_typelib_ab_month_names_de_DE, &my_locale_typelib_day_names_de_DE, - &my_locale_typelib_ab_day_names_de_DE + &my_locale_typelib_ab_day_names_de_DE, + 9, + 10 ); /***** LOCALE END de_CH *****/ @@ -1953,7 +2097,9 @@ MY_LOCALE my_locale_de_LU &my_locale_typelib_month_names_de_DE, &my_locale_typelib_ab_month_names_de_DE, &my_locale_typelib_day_names_de_DE, - &my_locale_typelib_ab_day_names_de_DE + &my_locale_typelib_ab_day_names_de_DE, + 9, + 10 ); /***** LOCALE END de_LU *****/ @@ -1967,7 +2113,9 @@ MY_LOCALE my_locale_en_AU &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, - &my_locale_typelib_ab_day_names_en_US + &my_locale_typelib_ab_day_names_en_US, + 9, + 9 ); /***** LOCALE END en_AU *****/ @@ -1981,7 +2129,9 @@ MY_LOCALE my_locale_en_CA &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, - &my_locale_typelib_ab_day_names_en_US + &my_locale_typelib_ab_day_names_en_US, + 9, + 9 ); /***** LOCALE END en_CA *****/ @@ -1995,7 +2145,9 @@ MY_LOCALE my_locale_en_GB &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, - &my_locale_typelib_ab_day_names_en_US + &my_locale_typelib_ab_day_names_en_US, + 9, + 9 ); /***** LOCALE END en_GB *****/ @@ -2009,7 +2161,9 @@ MY_LOCALE my_locale_en_IN &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, - &my_locale_typelib_ab_day_names_en_US + &my_locale_typelib_ab_day_names_en_US, + 9, + 9 ); /***** LOCALE END en_IN *****/ @@ -2023,7 +2177,9 @@ MY_LOCALE my_locale_en_NZ &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, - &my_locale_typelib_ab_day_names_en_US + &my_locale_typelib_ab_day_names_en_US, + 9, + 9 ); /***** LOCALE END en_NZ *****/ @@ -2037,7 +2193,9 @@ MY_LOCALE my_locale_en_PH &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, - &my_locale_typelib_ab_day_names_en_US + &my_locale_typelib_ab_day_names_en_US, + 9, + 9 ); /***** LOCALE END en_PH *****/ @@ -2051,7 +2209,9 @@ MY_LOCALE my_locale_en_ZA &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, - &my_locale_typelib_ab_day_names_en_US + &my_locale_typelib_ab_day_names_en_US, + 9, + 9 ); /***** LOCALE END en_ZA *****/ @@ -2065,7 +2225,9 @@ MY_LOCALE my_locale_en_ZW &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, - &my_locale_typelib_ab_day_names_en_US + &my_locale_typelib_ab_day_names_en_US, + 9, + 9 ); /***** LOCALE END en_ZW *****/ @@ -2079,7 +2241,9 @@ MY_LOCALE my_locale_es_AR &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_AR *****/ @@ -2093,7 +2257,9 @@ MY_LOCALE my_locale_es_BO &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_BO *****/ @@ -2107,7 +2273,9 @@ MY_LOCALE my_locale_es_CL &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_CL *****/ @@ -2121,7 +2289,9 @@ MY_LOCALE my_locale_es_CO &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_CO *****/ @@ -2135,7 +2305,9 @@ MY_LOCALE my_locale_es_CR &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_CR *****/ @@ -2149,7 +2321,9 @@ MY_LOCALE my_locale_es_DO &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_DO *****/ @@ -2163,7 +2337,9 @@ MY_LOCALE my_locale_es_EC &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_EC *****/ @@ -2177,7 +2353,9 @@ MY_LOCALE my_locale_es_GT &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_GT *****/ @@ -2191,7 +2369,9 @@ MY_LOCALE my_locale_es_HN &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_HN *****/ @@ -2205,7 +2385,9 @@ MY_LOCALE my_locale_es_MX &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_MX *****/ @@ -2219,7 +2401,9 @@ MY_LOCALE my_locale_es_NI &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_NI *****/ @@ -2233,7 +2417,9 @@ MY_LOCALE my_locale_es_PA &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_PA *****/ @@ -2247,7 +2433,9 @@ MY_LOCALE my_locale_es_PE &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_PE *****/ @@ -2261,7 +2449,9 @@ MY_LOCALE my_locale_es_PR &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_PR *****/ @@ -2275,7 +2465,9 @@ MY_LOCALE my_locale_es_PY &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_PY *****/ @@ -2289,7 +2481,9 @@ MY_LOCALE my_locale_es_SV &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_SV *****/ @@ -2303,7 +2497,9 @@ MY_LOCALE my_locale_es_US &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_US *****/ @@ -2317,7 +2513,9 @@ MY_LOCALE my_locale_es_UY &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_UY *****/ @@ -2331,7 +2529,9 @@ MY_LOCALE my_locale_es_VE &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, - &my_locale_typelib_ab_day_names_es_ES + &my_locale_typelib_ab_day_names_es_ES, + 10, + 9 ); /***** LOCALE END es_VE *****/ @@ -2345,7 +2545,9 @@ MY_LOCALE my_locale_fr_BE &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, - &my_locale_typelib_ab_day_names_fr_FR + &my_locale_typelib_ab_day_names_fr_FR, + 9, + 8 ); /***** LOCALE END fr_BE *****/ @@ -2359,7 +2561,9 @@ MY_LOCALE my_locale_fr_CA &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, - &my_locale_typelib_ab_day_names_fr_FR + &my_locale_typelib_ab_day_names_fr_FR, + 9, + 8 ); /***** LOCALE END fr_CA *****/ @@ -2373,7 +2577,9 @@ MY_LOCALE my_locale_fr_CH &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, - &my_locale_typelib_ab_day_names_fr_FR + &my_locale_typelib_ab_day_names_fr_FR, + 9, + 8 ); /***** LOCALE END fr_CH *****/ @@ -2387,7 +2593,9 @@ MY_LOCALE my_locale_fr_LU &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, - &my_locale_typelib_ab_day_names_fr_FR + &my_locale_typelib_ab_day_names_fr_FR, + 9, + 8 ); /***** LOCALE END fr_LU *****/ @@ -2401,7 +2609,9 @@ MY_LOCALE my_locale_it_IT &my_locale_typelib_month_names_it_CH, &my_locale_typelib_ab_month_names_it_CH, &my_locale_typelib_day_names_it_CH, - &my_locale_typelib_ab_day_names_it_CH + &my_locale_typelib_ab_day_names_it_CH, + 9, + 9 ); /***** LOCALE END it_IT *****/ @@ -2415,7 +2625,9 @@ MY_LOCALE my_locale_nl_BE &my_locale_typelib_month_names_nl_NL, &my_locale_typelib_ab_month_names_nl_NL, &my_locale_typelib_day_names_nl_NL, - &my_locale_typelib_ab_day_names_nl_NL + &my_locale_typelib_ab_day_names_nl_NL, + 9, + 9 ); /***** LOCALE END nl_BE *****/ @@ -2429,7 +2641,9 @@ MY_LOCALE my_locale_no_NO &my_locale_typelib_month_names_nb_NO, &my_locale_typelib_ab_month_names_nb_NO, &my_locale_typelib_day_names_nb_NO, - &my_locale_typelib_ab_day_names_nb_NO + &my_locale_typelib_ab_day_names_nb_NO, + 9, + 7 ); /***** LOCALE END no_NO *****/ @@ -2443,7 +2657,9 @@ MY_LOCALE my_locale_sv_FI &my_locale_typelib_month_names_sv_SE, &my_locale_typelib_ab_month_names_sv_SE, &my_locale_typelib_day_names_sv_SE, - &my_locale_typelib_ab_day_names_sv_SE + &my_locale_typelib_ab_day_names_sv_SE, + 9, + 7 ); /***** LOCALE END sv_FI *****/ @@ -2457,7 +2673,9 @@ MY_LOCALE my_locale_zh_HK &my_locale_typelib_month_names_zh_CN, &my_locale_typelib_ab_month_names_zh_CN, &my_locale_typelib_day_names_zh_CN, - &my_locale_typelib_ab_day_names_zh_CN + &my_locale_typelib_ab_day_names_zh_CN, + 3, + 3 ); /***** LOCALE END zh_HK *****/ diff --git a/strings/ctype.c b/strings/ctype.c index 372a1a8a468..548005f8463 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -337,6 +337,16 @@ my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong length) } +/* + Returns repertoire for charset +*/ +uint my_charset_repertoire(CHARSET_INFO *cs) +{ + return cs->state & MY_CS_PUREASCII ? + MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30; +} + + /* Detect whether a character set is ASCII compatible. -- cgit v1.2.1 From 5f8ed9c96838c7e95394a8634d4c3918ef4c685a Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 23 Dec 2008 18:56:08 +0400 Subject: Bug#41079 information_schema.schema_privileges is limited to 7680 records. The problem is that we cannot insert new record into memory table when table size exceeds max memory table size. The fix is to use schema_table_store_record() function which converts memory table into MyISAM in case of table size exceeding. Note: There is no test case for this bug, the reason is that 1. The code that was added already is checked(i.e. works) with existing tests 2. Correct work of schema_table_store_record() is checked with other test cases (information_schema tests) So new code is fully covered with existing test cases. sql/mysql_priv.h: make schema_table_store_record() function global sql/sql_acl.cc: The problem is that we cannot insert new record into memory table when table size exceeds max memory table size. The fix is to use schema_table_store_record() function which converts memory table into MyISAM in case of table size exceeding. sql/sql_show.cc: make schema_table_store_record() function global --- sql/mysql_priv.h | 1 + sql/sql_acl.cc | 119 +++++++++++++++++++++++++++++++++++++++---------------- sql/sql_show.cc | 4 +- 3 files changed, 87 insertions(+), 37 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index a06a7e7d6e3..8a8513ac745 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -983,6 +983,7 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond); bool get_schema_tables_result(JOIN *join, enum enum_schema_table_state executed_place); enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table); +bool schema_table_store_record(THD *thd, TABLE *table); #define is_schema_db(X) \ !my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str, (X)) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index df5e844749f..57029f46162 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5953,10 +5953,11 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr) } -void update_schema_privilege(TABLE *table, char *buff, const char* db, - const char* t_name, const char* column, - uint col_length, const char *priv, - uint priv_length, const char* is_grantable) +static bool update_schema_privilege(THD *thd, TABLE *table, char *buff, + const char* db, const char* t_name, + const char* column, uint col_length, + const char *priv, uint priv_length, + const char* is_grantable) { int i= 2; CHARSET_INFO *cs= system_charset_info; @@ -5970,13 +5971,14 @@ void update_schema_privilege(TABLE *table, char *buff, const char* db, table->field[i++]->store(column, col_length, cs); table->field[i++]->store(priv, priv_length, cs); table->field[i]->store(is_grantable, strlen(is_grantable), cs); - table->file->write_row(table->record[0]); + return schema_table_store_record(thd, table); } int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) { #ifndef NO_EMBEDDED_ACCESS_CHECKS + int error= 0; uint counter; ACL_USER *acl_user; ulong want_access; @@ -6010,8 +6012,14 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) strxmov(buff,"'",user,"'@'",host,"'",NullS); if (!(want_access & ~GRANT_ACL)) - update_schema_privilege(table, buff, 0, 0, 0, 0, - STRING_WITH_LEN("USAGE"), is_grantable); + { + if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0, + STRING_WITH_LEN("USAGE"), is_grantable)) + { + error= 1; + goto err; + } + } else { uint priv_id; @@ -6019,16 +6027,22 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) for (priv_id=0, j = SELECT_ACL;j <= GLOBAL_ACLS; priv_id++,j <<= 1) { if (test_access & j) - update_schema_privilege(table, buff, 0, 0, 0, 0, - command_array[priv_id], - command_lengths[priv_id], is_grantable); + { + if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0, + command_array[priv_id], + command_lengths[priv_id], is_grantable)) + { + error= 1; + goto err; + } + } } } } - +err: pthread_mutex_unlock(&acl_cache->lock); - DBUG_RETURN(0); + DBUG_RETURN(error); #else return(0); #endif @@ -6038,6 +6052,7 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) { #ifndef NO_EMBEDDED_ACCESS_CHECKS + int error= 0; uint counter; ACL_DB *acl_db; ulong want_access; @@ -6075,24 +6090,36 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) } strxmov(buff,"'",user,"'@'",host,"'",NullS); if (!(want_access & ~GRANT_ACL)) - update_schema_privilege(table, buff, acl_db->db, 0, 0, - 0, STRING_WITH_LEN("USAGE"), is_grantable); + { + if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0, + 0, STRING_WITH_LEN("USAGE"), is_grantable)) + { + error= 1; + goto err; + } + } else { int cnt; ulong j,test_access= want_access & ~GRANT_ACL; for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1) if (test_access & j) - update_schema_privilege(table, buff, acl_db->db, 0, 0, 0, - command_array[cnt], command_lengths[cnt], - is_grantable); + { + if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0, 0, + command_array[cnt], command_lengths[cnt], + is_grantable)) + { + error= 1; + goto err; + } + } } } } - +err: pthread_mutex_unlock(&acl_cache->lock); - DBUG_RETURN(0); + DBUG_RETURN(error); #else return (0); #endif @@ -6102,6 +6129,7 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) { #ifndef NO_EMBEDDED_ACCESS_CHECKS + int error= 0; uint index; char buff[100]; TABLE *table= tables->table; @@ -6141,8 +6169,15 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) strxmov(buff, "'", user, "'@'", host, "'", NullS); if (!test_access) - update_schema_privilege(table, buff, grant_table->db, grant_table->tname, - 0, 0, STRING_WITH_LEN("USAGE"), is_grantable); + { + if (update_schema_privilege(thd, table, buff, grant_table->db, + grant_table->tname, 0, 0, + STRING_WITH_LEN("USAGE"), is_grantable)) + { + error= 1; + goto err; + } + } else { ulong j; @@ -6150,17 +6185,24 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) for (cnt= 0, j= SELECT_ACL; j <= TABLE_ACLS; cnt++, j<<= 1) { if (test_access & j) - update_schema_privilege(table, buff, grant_table->db, - grant_table->tname, 0, 0, command_array[cnt], - command_lengths[cnt], is_grantable); + { + if (update_schema_privilege(thd, table, buff, grant_table->db, + grant_table->tname, 0, 0, + command_array[cnt], + command_lengths[cnt], is_grantable)) + { + error= 1; + goto err; + } + } } } - } + } } - +err: rw_unlock(&LOCK_grant); - DBUG_RETURN(0); + DBUG_RETURN(error); #else return (0); #endif @@ -6170,6 +6212,7 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) { #ifndef NO_EMBEDDED_ACCESS_CHECKS + int error= 0; uint index; char buff[100]; TABLE *table= tables->table; @@ -6219,22 +6262,28 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) GRANT_COLUMN *grant_column = (GRANT_COLUMN*) hash_element(&grant_table->hash_columns,col_index); if ((grant_column->rights & j) && (table_access & j)) - update_schema_privilege(table, buff, grant_table->db, - grant_table->tname, - grant_column->column, - grant_column->key_length, - command_array[cnt], - command_lengths[cnt], is_grantable); + { + if (update_schema_privilege(thd, table, buff, grant_table->db, + grant_table->tname, + grant_column->column, + grant_column->key_length, + command_array[cnt], + command_lengths[cnt], is_grantable)) + { + error= 1; + goto err; + } + } } } } } } } - +err: rw_unlock(&LOCK_grant); - DBUG_RETURN(0); + DBUG_RETURN(error); #else return (0); #endif diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 59082e0a295..c10580e8913 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -44,7 +44,7 @@ static void append_algorithm(TABLE_LIST *table, String *buff); static int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff); -static bool schema_table_store_record(THD *thd, TABLE *table); +bool schema_table_store_record(THD *thd, TABLE *table); /*************************************************************************** @@ -1884,7 +1884,7 @@ typedef struct st_index_field_values 1 error */ -static bool schema_table_store_record(THD *thd, TABLE *table) +bool schema_table_store_record(THD *thd, TABLE *table) { int error; if ((error= table->file->write_row(table->record[0]))) -- cgit v1.2.1 From ccc8a8c27f16fb6f14d4a221af77163f074ddcfb Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 24 Dec 2008 18:45:47 +0400 Subject: compiler warning fix --- sql/mysqld.cc | 2 +- sql/sql_acl.cc | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index f5e5b881a37..269e1aed7cc 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3616,6 +3616,7 @@ void decrement_handler_count() #endif /* defined(__NT__) || defined(HAVE_SMEM) */ +#ifndef EMBEDDED_LIBRARY #ifndef DBUG_OFF /* Debugging helper function to keep the locale database @@ -3654,7 +3655,6 @@ static void test_lc_time_sz() #endif//DBUG_OFF -#ifndef EMBEDDED_LIBRARY #ifdef __WIN__ int win_main(int argc, char **argv) #else diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 57029f46162..22135d376fe 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5953,6 +5953,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr) } +#ifndef NO_EMBEDDED_ACCESS_CHECKS static bool update_schema_privilege(THD *thd, TABLE *table, char *buff, const char* db, const char* t_name, const char* column, uint col_length, @@ -5973,6 +5974,7 @@ static bool update_schema_privilege(THD *thd, TABLE *table, char *buff, table->field[i]->store(is_grantable, strlen(is_grantable), cs); return schema_table_store_record(thd, table); } +#endif int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) -- cgit v1.2.1 From 9c7f798a4ef6e5a055dc600d9e1154138fb3b266 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 24 Dec 2008 19:01:41 +0400 Subject: Bug#25830 SHOW TABLE STATUS behaves differently depending on table name replace wild_case_compare with my_wildcmp which is multibyte safe function mysql-test/r/lowercase_utf8.result: test result mysql-test/t/lowercase_utf8-master.opt: test case mysql-test/t/lowercase_utf8.test: test case sql/sql_show.cc: replace wild_case_compare with my_wildcmp which is multibyte safe function --- mysql-test/r/lowercase_utf8.result | 9 +++++++++ mysql-test/t/lowercase_utf8-master.opt | 4 ++++ mysql-test/t/lowercase_utf8.test | 9 +++++++++ sql/sql_show.cc | 17 +++++++++++++---- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 mysql-test/r/lowercase_utf8.result create mode 100644 mysql-test/t/lowercase_utf8-master.opt create mode 100644 mysql-test/t/lowercase_utf8.test diff --git a/mysql-test/r/lowercase_utf8.result b/mysql-test/r/lowercase_utf8.result new file mode 100644 index 00000000000..043226e1f64 --- /dev/null +++ b/mysql-test/r/lowercase_utf8.result @@ -0,0 +1,9 @@ +set names utf8; +create table `Ö` (id int); +show tables from test like 'Ö'; +Tables_in_test (Ö) +ö +show tables from test like 'ö'; +Tables_in_test (ö) +ö +drop table `Ö`; diff --git a/mysql-test/t/lowercase_utf8-master.opt b/mysql-test/t/lowercase_utf8-master.opt new file mode 100644 index 00000000000..1b70aa33023 --- /dev/null +++ b/mysql-test/t/lowercase_utf8-master.opt @@ -0,0 +1,4 @@ +--lower-case-table-names=1 --character-set-server=utf8 + + + diff --git a/mysql-test/t/lowercase_utf8.test b/mysql-test/t/lowercase_utf8.test new file mode 100644 index 00000000000..01b154598fd --- /dev/null +++ b/mysql-test/t/lowercase_utf8.test @@ -0,0 +1,9 @@ +# +# Bug#25830 SHOW TABLE STATUS behaves differently depending on table name +# +set names utf8; +create table `Ö` (id int); +show tables from test like 'Ö'; +show tables from test like 'ö'; +drop table `Ö`; + diff --git a/sql/sql_show.cc b/sql/sql_show.cc index c10580e8913..322b1851560 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -287,11 +287,17 @@ find_files(THD *thd, List *files, const char *db, #ifndef NO_EMBEDDED_ACCESS_CHECKS uint col_access=thd->col_access; #endif + uint wild_length= 0; TABLE_LIST table_list; DBUG_ENTER("find_files"); - if (wild && !wild[0]) - wild=0; + if (wild) + { + if (!wild[0]) + wild= 0; + else + wild_length= strlen(wild); + } bzero((char*) &table_list,sizeof(table_list)); @@ -340,8 +346,11 @@ find_files(THD *thd, List *files, const char *db, { if (lower_case_table_names) { - if (wild_case_compare(files_charset_info, file->name, wild)) - continue; + if (my_wildcmp(files_charset_info, + file->name, file->name + strlen(file->name), + wild, wild + wild_length, + wild_prefix, wild_one, wild_many)) + continue; } else if (wild_compare(file->name,wild,0)) continue; -- cgit v1.2.1 From 0efc5005aad6ba27480a423237a7cbe4209e088c Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 24 Dec 2008 19:14:59 +0400 Subject: Bug#41456 SET PASSWORD hates CURRENT_USER() init user->user struct with thd->security_ctx->priv_user context if user->user is not initializied mysql-test/r/grant.result: test result mysql-test/t/grant.test: test case sql/set_var.cc: init user->user struct with thd->security_ctx->priv_user context if user->user is not initializied --- mysql-test/r/grant.result | 5 +++++ mysql-test/t/grant.test | 7 +++++++ sql/set_var.cc | 7 +++++++ 3 files changed, 19 insertions(+) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index d56020c3090..ee328d461ac 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1151,4 +1151,9 @@ drop user 'greg'@'localhost'; drop view v1; drop table test; drop function test_function; +SELECT CURRENT_USER(); +CURRENT_USER() +root@localhost +SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin"); +SET PASSWORD FOR CURRENT_USER() = PASSWORD(""); End of 5.0 tests diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index e4b95502143..14c5879d007 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1175,4 +1175,11 @@ drop view v1; drop table test; drop function test_function; +# +# Bug#41456 SET PASSWORD hates CURRENT_USER() +# +SELECT CURRENT_USER(); +SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin"); +SET PASSWORD FOR CURRENT_USER() = PASSWORD(""); + --echo End of 5.0 tests diff --git a/sql/set_var.cc b/sql/set_var.cc index 59741e5683d..a29abe6581f 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -3475,6 +3475,7 @@ int set_var_password::check(THD *thd) #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!user->host.str) { + DBUG_ASSERT(thd->security_ctx->priv_host); if (*thd->security_ctx->priv_host != 0) { user->host.str= (char *) thd->security_ctx->priv_host; @@ -3486,6 +3487,12 @@ int set_var_password::check(THD *thd) user->host.length= 1; } } + if (!user->user.str) + { + DBUG_ASSERT(thd->security_ctx->priv_user); + user->user.str= (char *) thd->security_ctx->priv_user; + user->user.length= strlen(thd->security_ctx->priv_user); + } /* Returns 1 as the function sends error to client */ return check_change_password(thd, user->host.str, user->user.str, password, strlen(password)) ? 1 : 0; -- cgit v1.2.1 From 4c689750bb7d46cb2e1d7774991824f2d7257f47 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 24 Dec 2008 19:24:11 +0400 Subject: Bug#40953 SELECT query throws "ERROR 1062 (23000): Duplicate entry..." error Table could be marked dependent because it is either 1) an inner table of an outer join, or 2) it is a part of STRAIGHT_JOIN. In case of STRAIGHT_JOIN table->maybe_null should not be assigned. The fix is to set st_table::maybe_null to 'true' only for those tables which are used in outer join. mysql-test/r/select.result: test result mysql-test/t/select.test: test case sql/sql_select.cc: Table could be marked dependent because it is either 1) an inner table of an outer join, or 2) it is a part of STRAIGHT_JOIN. In case of STRAIGHT_JOIN table->maybe_null should not be assigned. The fix is to set st_table::maybe_null to 'true' only for those tables which are used in outer join. sql/sql_select.h: added comment --- mysql-test/r/select.result | 33 +++++++++++++++++++++++++++++++++ mysql-test/t/select.test | 36 ++++++++++++++++++++++++++++++++++++ sql/sql_select.cc | 2 +- sql/sql_select.h | 6 +++++- 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index c2cd2129a32..67ce231a157 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4355,4 +4355,37 @@ Handler_read_prev 0 Handler_read_rnd 0 Handler_read_rnd_next 6 DROP TABLE t1, t2; +CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0', +f2 int(11) NOT NULL default '0', +f3 bigint(20) NOT NULL default '0', +f4 varchar(255) NOT NULL default '', +PRIMARY KEY (f1), +KEY key1 (f4), +KEY key2 (f2)); +CREATE TABLE t2 (f1 int(11) NOT NULL default '0', +f2 enum('A1','A2','A3') NOT NULL default 'A1', +f3 int(11) NOT NULL default '0', +PRIMARY KEY (f1), +KEY key1 (f3)); +CREATE TABLE t3 (f1 bigint(20) NOT NULL default '0', +f2 datetime NOT NULL default '1980-01-01 00:00:00', +PRIMARY KEY (f1)); +insert into t1 values (1, 1, 1, 'abc'); +insert into t1 values (2, 1, 2, 'def'); +insert into t1 values (3, 1, 2, 'def'); +insert into t2 values (1, 'A1', 1); +insert into t3 values (1, '1980-01-01'); +SELECT a.f3, cr.f4, count(*) count +FROM t2 a +STRAIGHT_JOIN t1 cr ON cr.f2 = a.f1 +LEFT JOIN +(t1 cr2 +JOIN t3 ae2 ON cr2.f3 = ae2.f1 +) ON a.f1 = cr2.f2 AND ae2.f2 < now() - INTERVAL 7 DAY AND +cr.f4 = cr2.f4 +GROUP BY a.f3, cr.f4; +f3 f4 count +1 abc 1 +1 def 2 +drop table t1, t2, t3; End of 5.0 tests diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 1ee87957643..1e8dc7ac2f6 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3701,4 +3701,40 @@ SELECT DISTINCT b FROM t1 LEFT JOIN t2 USING(a) WHERE c <= 3; SHOW STATUS LIKE 'Handler_read%'; DROP TABLE t1, t2; +# +# Bug#40953 SELECT query throws "ERROR 1062 (23000): Duplicate entry..." error +# +CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0', + f2 int(11) NOT NULL default '0', + f3 bigint(20) NOT NULL default '0', + f4 varchar(255) NOT NULL default '', + PRIMARY KEY (f1), + KEY key1 (f4), + KEY key2 (f2)); +CREATE TABLE t2 (f1 int(11) NOT NULL default '0', + f2 enum('A1','A2','A3') NOT NULL default 'A1', + f3 int(11) NOT NULL default '0', + PRIMARY KEY (f1), + KEY key1 (f3)); +CREATE TABLE t3 (f1 bigint(20) NOT NULL default '0', + f2 datetime NOT NULL default '1980-01-01 00:00:00', + PRIMARY KEY (f1)); + +insert into t1 values (1, 1, 1, 'abc'); +insert into t1 values (2, 1, 2, 'def'); +insert into t1 values (3, 1, 2, 'def'); +insert into t2 values (1, 'A1', 1); +insert into t3 values (1, '1980-01-01'); + +SELECT a.f3, cr.f4, count(*) count +FROM t2 a +STRAIGHT_JOIN t1 cr ON cr.f2 = a.f1 +LEFT JOIN +(t1 cr2 + JOIN t3 ae2 ON cr2.f3 = ae2.f1 +) ON a.f1 = cr2.f2 AND ae2.f2 < now() - INTERVAL 7 DAY AND +cr.f4 = cr2.f4 +GROUP BY a.f3, cr.f4; + +drop table t1, t2, t3; --echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d2c469f99da..230b9bb36cf 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2489,7 +2489,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if (s->dependent & table->map) s->dependent |= table->reginfo.join_tab->dependent; } - if (s->dependent) + if (outer_join & s->table->map) s->table->maybe_null= 1; } /* Catch illegal cross references for outer joins */ diff --git a/sql/sql_select.h b/sql/sql_select.h index c2f0780f5be..8ece01d3286 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -235,7 +235,11 @@ public: fetching data from a cursor */ bool resume_nested_loop; - table_map const_table_map,found_const_table_map,outer_join; + table_map const_table_map,found_const_table_map; + /* + Bitmap of all inner tables from outer joins + */ + table_map outer_join; ha_rows send_records,found_records,examined_rows,row_limit, select_limit; /* Used to fetch no more than given amount of rows per one -- cgit v1.2.1 From 4a24f7a8d34494fe8852a3674edf3cddc689fe8b Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Sun, 28 Dec 2008 07:57:09 +0100 Subject: Increased thread stack size to 128K, as this is the minimum (Bug#41577) --- support-files/my-small.cnf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/my-small.cnf.sh b/support-files/my-small.cnf.sh index cf2ebed463c..24c08408b46 100644 --- a/support-files/my-small.cnf.sh +++ b/support-files/my-small.cnf.sh @@ -34,7 +34,7 @@ sort_buffer_size = 64K read_buffer_size = 256K read_rnd_buffer_size = 256K net_buffer_length = 2K -thread_stack = 64K +thread_stack = 128K # Don't listen on a TCP/IP port at all. This can be a security enhancement, # if all processes that need to connect to mysqld run on the same host. -- cgit v1.2.1 From 397a36c7438f69e37ea0725941140d665016781e Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Mon, 29 Dec 2008 16:06:53 +0400 Subject: Bug#41131 "Questions" fails to increment - ignores statements instead stored procs(5.0 ver) Added global status variable 'Queries' which represents total amount of queries executed by server including statements executed by SPs. note: It's old behaviour of 'Questions' variable. mysql-test/r/status.result: test result mysql-test/t/status.test: test case sql/mysqld.cc: Added global status variable 'Queries' which represents total amount of queries executed by server including statements executed by SPs. note: It's old behaviour of 'Questions' variable. sql/sql_show.cc: Added global status variable 'Queries' which represents total amount of queries executed by server including statements executed by SPs. note: It's old behaviour of 'Questions' variable. sql/structs.h: Added global status variable 'Queries' which represents total amount of queries executed by server including statements executed by SPs. note: It's old behaviour of 'Questions' variable. --- mysql-test/r/status.result | 25 +++++++++++++++++++++++++ mysql-test/t/status.test | 36 ++++++++++++++++++++++++++++++++++++ sql/mysqld.cc | 1 + sql/sql_show.cc | 3 +++ sql/structs.h | 2 +- 5 files changed, 66 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index 36857e22aaf..971e399a3b6 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -91,3 +91,28 @@ SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 4.805836 DROP TABLE t1; +DROP PROCEDURE IF EXISTS p1; +DROP FUNCTION IF EXISTS f1; +CREATE FUNCTION f1() RETURNS INTEGER +BEGIN +DECLARE foo INTEGER; +DECLARE bar INTEGER; +SET foo=1; +SET bar=2; +RETURN foo; +END $$ +CREATE PROCEDURE p1() +BEGIN +SELECT 1; +END $$ +SELECT f1(); +f1() +1 +CALL p1(); +1 +1 +SELECT 9; +9 +9 +DROP PROCEDURE p1; +DROP FUNCTION f1; diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test index 33bba3a626a..ee92d649f47 100644 --- a/mysql-test/t/status.test +++ b/mysql-test/t/status.test @@ -171,4 +171,40 @@ SHOW SESSION STATUS LIKE 'Last_query_cost'; DROP TABLE t1; +# +# Bug#41131 "Questions" fails to increment - ignores statements instead stored procs +# +connect (con1,localhost,root,,); +connection con1; +--disable_warnings +DROP PROCEDURE IF EXISTS p1; +DROP FUNCTION IF EXISTS f1; +--enable_warnings +DELIMITER $$; +CREATE FUNCTION f1() RETURNS INTEGER +BEGIN + DECLARE foo INTEGER; + DECLARE bar INTEGER; + SET foo=1; + SET bar=2; + RETURN foo; +END $$ +CREATE PROCEDURE p1() + BEGIN + SELECT 1; +END $$ +DELIMITER ;$$ +let $org_queries= `SHOW STATUS LIKE 'Queries'`; +SELECT f1(); +CALL p1(); +let $new_queries= `SHOW STATUS LIKE 'Queries'`; +--disable_log +let $diff= `SELECT SUBSTRING('$new_queries',9)-SUBSTRING('$org_queries',9)`; +--enable_log +eval SELECT $diff; +disconnect con1; +connection default; +DROP PROCEDURE p1; +DROP FUNCTION f1; + # End of 5.0 tests diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 269e1aed7cc..ca68976d939 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6620,6 +6620,7 @@ struct show_var_st status_vars[]= { {"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST}, {"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_CONST}, #endif /*HAVE_QUERY_CACHE*/ + {"Queries", (char*) 0, SHOW_QUERIES}, {"Questions", (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS}, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 322b1851560..2d8d6b13d4e 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1543,6 +1543,9 @@ static bool show_status_array(THD *thd, const char *wild, nr= (long) (thd->query_start() - server_start_time); end= int10_to_str(nr, buff, 10); break; + case SHOW_QUERIES: + end= int10_to_str((long) thd->query_id, buff, 10); + break; #ifdef HAVE_REPLICATION case SHOW_RPL_STATUS: end= strmov(buff, rpl_status_type[(int)rpl_status]); diff --git a/sql/structs.h b/sql/structs.h index ab8537612fa..9882119b7c5 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -170,7 +170,7 @@ enum SHOW_TYPE SHOW_UNDEF, SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_DOUBLE_STATUS, - SHOW_BOOL, SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME, + SHOW_BOOL, SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME, SHOW_QUERIES, SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS, SHOW_VARS, #ifdef HAVE_OPENSSL -- cgit v1.2.1 From 61e62a8b5417438cc98d82a97b89c4e5c1e10782 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 5 Jan 2009 12:37:56 +0200 Subject: Reverted the fix for bug #25830 because of omissions and non-complete test case. --- mysql-test/r/lowercase_utf8.result | 9 --------- mysql-test/t/lowercase_utf8-master.opt | 4 ---- mysql-test/t/lowercase_utf8.test | 9 --------- sql/sql_show.cc | 17 ++++------------- 4 files changed, 4 insertions(+), 35 deletions(-) delete mode 100644 mysql-test/r/lowercase_utf8.result delete mode 100644 mysql-test/t/lowercase_utf8-master.opt delete mode 100644 mysql-test/t/lowercase_utf8.test diff --git a/mysql-test/r/lowercase_utf8.result b/mysql-test/r/lowercase_utf8.result deleted file mode 100644 index 043226e1f64..00000000000 --- a/mysql-test/r/lowercase_utf8.result +++ /dev/null @@ -1,9 +0,0 @@ -set names utf8; -create table `Ö` (id int); -show tables from test like 'Ö'; -Tables_in_test (Ö) -ö -show tables from test like 'ö'; -Tables_in_test (ö) -ö -drop table `Ö`; diff --git a/mysql-test/t/lowercase_utf8-master.opt b/mysql-test/t/lowercase_utf8-master.opt deleted file mode 100644 index 1b70aa33023..00000000000 --- a/mysql-test/t/lowercase_utf8-master.opt +++ /dev/null @@ -1,4 +0,0 @@ ---lower-case-table-names=1 --character-set-server=utf8 - - - diff --git a/mysql-test/t/lowercase_utf8.test b/mysql-test/t/lowercase_utf8.test deleted file mode 100644 index 01b154598fd..00000000000 --- a/mysql-test/t/lowercase_utf8.test +++ /dev/null @@ -1,9 +0,0 @@ -# -# Bug#25830 SHOW TABLE STATUS behaves differently depending on table name -# -set names utf8; -create table `Ö` (id int); -show tables from test like 'Ö'; -show tables from test like 'ö'; -drop table `Ö`; - diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2d8d6b13d4e..d6bb3427fe4 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -287,17 +287,11 @@ find_files(THD *thd, List *files, const char *db, #ifndef NO_EMBEDDED_ACCESS_CHECKS uint col_access=thd->col_access; #endif - uint wild_length= 0; TABLE_LIST table_list; DBUG_ENTER("find_files"); - if (wild) - { - if (!wild[0]) - wild= 0; - else - wild_length= strlen(wild); - } + if (wild && !wild[0]) + wild=0; bzero((char*) &table_list,sizeof(table_list)); @@ -346,11 +340,8 @@ find_files(THD *thd, List *files, const char *db, { if (lower_case_table_names) { - if (my_wildcmp(files_charset_info, - file->name, file->name + strlen(file->name), - wild, wild + wild_length, - wild_prefix, wild_one, wild_many)) - continue; + if (wild_case_compare(files_charset_info, file->name, wild)) + continue; } else if (wild_compare(file->name,wild,0)) continue; -- cgit v1.2.1 From c7481d62047fb52ff4385b1302a4c6d80e5cb6c3 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Mon, 5 Jan 2009 12:10:22 -0500 Subject: Bug#38833: mysql-test-run needs diff. Problem w/ error handling in calling diff on Windows. Added function to check for diff and return an error message if the utility is not present. Previously, the way we did this didn't work on Windows, but did work on *Nix systems. --- client/mysqltest.c | 81 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 9c7c4d62f6f..d73cf78d9d4 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1329,6 +1329,35 @@ static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...) DBUG_RETURN(ret); } +/* + Test if diff is present. This is needed on Windows systems + as the OS returns 1 whether diff is successful or if it is + not present. + + We run diff -v and look for output in stdout. + We don't redirect stderr to stdout to make for a simplified check + Windows will output '"diff"' is not recognized... to stderr if it is + not present. +*/ + +int diff_check() +{ + char buf[512]= {0}; + FILE *res_file; + char *cmd = "diff -v"; + int have_diff = 0; + + if (!(res_file= popen(cmd, "r"))) + die("popen(\"%s\", \"r\") failed", cmd); + +/* if diff is not present, nothing will be in stdout to increment have_diff */ + if (fgets(buf, sizeof(buf), res_file)) + { + have_diff += 1; + } + pclose(res_file); + return have_diff; +} /* Show the diff of two files using the systems builtin diff @@ -1348,34 +1377,51 @@ void show_diff(DYNAMIC_STRING* ds, { DYNAMIC_STRING ds_tmp; + int have_diff = 0; if (init_dynamic_string(&ds_tmp, "", 256, 256)) die("Out of memory"); + + /* determine if we have diff on Windows + needs special processing due to return values + on that OS + */ + have_diff = diff_check(); - /* First try with unified diff */ - if (run_tool("diff", - &ds_tmp, /* Get output from diff in ds_tmp */ - "-u", - filename1, - filename2, - "2>&1", - NULL) > 1) /* Most "diff" tools return >1 if error */ + if (have_diff) { - dynstr_set(&ds_tmp, ""); - - /* Fallback to context diff with "diff -c" */ + /* First try with unified diff */ if (run_tool("diff", &ds_tmp, /* Get output from diff in ds_tmp */ - "-c", + "-u", filename1, filename2, "2>&1", NULL) > 1) /* Most "diff" tools return >1 if error */ { - /* - Fallback to dump both files to result file and inform - about installing "diff" - */ + dynstr_set(&ds_tmp, ""); + + /* Fallback to context diff with "diff -c" */ + if (run_tool("diff", + &ds_tmp, /* Get output from diff in ds_tmp */ + "-c", + filename1, + filename2, + "2>&1", + NULL) > 1) /* Most "diff" tools return >1 if error */ + { + have_diff= 1; + } + } + } + +if (!(have_diff)) + { + /* + Fallback to dump both files to result file and inform + about installing "diff" + */ + dynstr_set(&ds_tmp, ""); dynstr_append(&ds_tmp, @@ -1399,8 +1445,7 @@ void show_diff(DYNAMIC_STRING* ds, dynstr_append(&ds_tmp, " >>>\n"); cat_file(&ds_tmp, filename2); dynstr_append(&ds_tmp, "<<<<\n"); - } - } + } if (ds) { -- cgit v1.2.1 From 1dee1dd437e49a4500db550209c08cb9c7f04b54 Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Thu, 8 Jan 2009 10:25:31 +0100 Subject: Bug#41470: DATE_FORMAT() crashes the complete server with a valid date Passing dubious "year zero" in non-zero date (not "0000-00-00") could lead to negative value for year internally, while variable was unsigned. This led to Really Bad Things further down the line. Now doing calculations with signed type for year internally. mysql-test/r/date_formats.result: show that very early dates no longer break DATE_FORMAT(..., '%W') mysql-test/t/date_formats.test: show that very early dates no longer break DATE_FORMAT(..., '%W') sql-common/my_time.c: Allow negative years numbers internally while keeping the interface. otherwise if somebody passes year zero for whatever reason, we'll get an integer wrap-around that can lead to Really Bad Things further down the line. Note that amusingly, calcday_nr() already had signed output and calc_weekday() already had signed input, anyway. --- mysql-test/r/date_formats.result | 10 ++++++++++ mysql-test/t/date_formats.test | 12 ++++++++++++ sql-common/my_time.c | 13 +++++++------ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 6833a7f1594..43f656e3c99 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -593,3 +593,13 @@ select str_to_date('04/30/2004 ', '%m/%d/%Y '); str_to_date('04/30/2004 ', '%m/%d/%Y ') 2004-04-30 "End of 4.1 tests" +SELECT DATE_FORMAT("0000-01-01",'%W %d %M %Y') as valid_date; +valid_date +Sunday 01 January 0000 +SELECT DATE_FORMAT("0000-02-28",'%W %d %M %Y') as valid_date; +valid_date +Tuesday 28 February 0000 +SELECT DATE_FORMAT("2009-01-01",'%W %d %M %Y') as valid_date; +valid_date +Thursday 01 January 2009 +"End of 5.0 tests" diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index faa6d4242db..0c02398acc1 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -337,3 +337,15 @@ select str_to_date('04/30 /2004', '%m /%d /%Y'); select str_to_date('04/30/2004 ', '%m/%d/%Y '); --echo "End of 4.1 tests" + +# +# Bug #41470: DATE_FORMAT() crashes the complete server with a valid date +# + +# show that these two do not crash the server: +SELECT DATE_FORMAT("0000-01-01",'%W %d %M %Y') as valid_date; +SELECT DATE_FORMAT("0000-02-28",'%W %d %M %Y') as valid_date; +# show that date within the Gregorian range render correct results: (THU) +SELECT DATE_FORMAT("2009-01-01",'%W %d %M %Y') as valid_date; + +--echo "End of 5.0 tests" diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 1781251fca1..16a64ebd947 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -765,19 +765,20 @@ long calc_daynr(uint year,uint month,uint day) { long delsum; int temp; + int y= year; /* may be < 0 temporarily */ DBUG_ENTER("calc_daynr"); - if (year == 0 && month == 0 && day == 0) + if (y == 0 && month == 0 && day == 0) DBUG_RETURN(0); /* Skip errors */ - delsum= (long) (365L * year+ 31*(month-1) +day); + delsum= (long) (365L * y+ 31*(month-1) +day); if (month <= 2) - year--; + y--; else delsum-= (long) (month*4+23)/10; - temp=(int) ((year/100+1)*3)/4; + temp=(int) ((y/100+1)*3)/4; DBUG_PRINT("exit",("year: %d month: %d day: %d -> daynr: %ld", - year+(month <= 2),month,day,delsum+year/4-temp)); - DBUG_RETURN(delsum+(int) year/4-temp); + y+(month <= 2),month,day,delsum+y/4-temp)); + DBUG_RETURN(delsum+(int) y/4-temp); } /* calc_daynr */ -- cgit v1.2.1 From 20195aa25ac725b21a3d16c2f3e1e9f2eba181c5 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 9 Jan 2009 13:50:18 +0200 Subject: Bug #41437: Value stored in 'case' lacks charset, causes segfault When substituting system constant functions with a constant result the server was not expecting that the function may return NULL. Fixed by checking for NULL and returning Item_null (in the relevant collation) if the result of the system constant function was NULL. mysql-test/r/mysql.result: Bug #41437: test case mysql-test/t/mysql.test: Bug #41437: test case. Relies on database() returning NULL if no database is selected. sql/item_strfunc.cc: Bug #41437: Check for NULL result on evaluating the system constant function and return a constant NULL item. --- mysql-test/r/mysql.result | 2 ++ mysql-test/t/mysql.test | 5 +++++ sql/item_strfunc.cc | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 95bdcab6ba1..9bad3b9f791 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -186,4 +186,6 @@ delimiter 2 2 2 +@z:='1' @z=database() +1 NULL End of 5.0 tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 76941af893a..68a01a309d4 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -309,4 +309,9 @@ EOF --exec $MYSQL -c < $MYSQLTEST_VARDIR/tmp/bug38158.sql 2>&1 remove_file $MYSQLTEST_VARDIR/tmp/bug38158.sql; +# +# Bug #41437: Value stored in 'case' lacks charset, causees segfault +# +--exec $MYSQL -e "select @z:='1',@z=database()" + --echo End of 5.0 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index d1e3f45bba1..34f974042a5 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1696,6 +1696,12 @@ Item *Item_func_sysconst::safe_charset_converter(CHARSET_INFO *tocs) Item_string *conv; uint conv_errors; String tmp, cstr, *ostr= val_str(&tmp); + if (null_value) + { + Item *null_item= new Item_null((char *) fully_qualified_func_name()); + null_item->collation.set (tocs); + return null_item; + } cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors); if (conv_errors || !(conv= new Item_static_string_func(fully_qualified_func_name(), -- cgit v1.2.1 From 4d49743139cb1636f64f45111bec4ff67a544443 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 9 Jan 2009 20:30:55 +0200 Subject: fixed a compile warning --- client/mysqltest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index d73cf78d9d4..62ec5a88599 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1344,7 +1344,7 @@ int diff_check() { char buf[512]= {0}; FILE *res_file; - char *cmd = "diff -v"; + const char *cmd = "diff -v"; int have_diff = 0; if (!(res_file= popen(cmd, "r"))) -- cgit v1.2.1 From 3c998489219a088723c83216fda3f87ffa39c93a Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Mon, 12 Jan 2009 16:46:19 +0100 Subject: Backport of a 5.0.74 fix into 5.0.72sp1: Remove bashisms from BUILD/compile-dist and configure.in, so Bootstrap works on Solaris box; - force GNU make in compile-dist; - remove unportable "grep -q" from configure.in Original changeset: revision-id: build@mysql.com-20081203041148-icwscut3bk09ds47 parent: kgeorge@mysql.com-20081202125040-eiu6s7bk6s96s4xh author: timothy.smith@sun.com committer: MySQL Build Team branch nick: mysql-5.0.74-release timestamp: Wed 2008-12-03 05:11:48 +0100 --- BUILD/compile-dist | 36 ++++++++++++++++++++++++++++-------- configure.in | 28 ++++++++++++++++------------ 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/BUILD/compile-dist b/BUILD/compile-dist index 613f2643c56..7c2dbe00dc5 100755 --- a/BUILD/compile-dist +++ b/BUILD/compile-dist @@ -15,30 +15,49 @@ autoconf (cd bdb/dist && sh s_all) (cd innobase && aclocal && autoheader && aclocal && automake && autoconf) +gmake= +for x in gmake gnumake make; do + if $x --version 2>/dev/null | grep GNU > /dev/null; then + gmake=$x + break; + fi +done + +if [ -z "$gmake" ]; then + # Our build may not depend on GNU make, but I wouldn't count on it + echo "Please install GNU make, and ensure it is in your path as gnumake, gmake, or make" >&2 + exit 2 +fi + # Default to gcc for CC and CXX if test -z "$CXX" ; then - export CXX=gcc + export CXX + CXX=gcc # Set some required compile options if test -z "$CXXFLAGS" ; then - export CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" + export CXXFLAGS + CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" fi fi if test -z "$CC" ; then - export CC=gcc + export CC + CC=gcc fi # Use ccache, if available if ccache -V > /dev/null 2>&1 then - if ! (echo "$CC" | grep "ccache" > /dev/null) + if echo "$CC" | grep -v ccache > /dev/null then - export CC="ccache $CC" + export CC + CC="ccache $CC" fi - if ! (echo "$CXX" | grep "ccache" > /dev/null) + if echo "$CXX" | grep -v ccache > /dev/null then - export CXX="ccache $CXX" + export CXX + CXX="ccache $CXX" fi fi @@ -50,4 +69,5 @@ fi --enable-thread-safe-client \ --with-extra-charsets=complex \ --with-ndbcluster -make + +$gmake diff --git a/configure.in b/configure.in index f48f1544677..162e21d9d75 100644 --- a/configure.in +++ b/configure.in @@ -409,7 +409,7 @@ fi MYSQL_PROG_AR # libmysqlclient versioning when linked with GNU ld. -if $LD --version 2>/dev/null|grep -q GNU; then +if $LD --version 2>/dev/null|grep GNU > /dev/null; then LD_VERSION_SCRIPT="-Wl,--version-script=\$(top_builddir)/libmysql/libmysql.ver" AC_CONFIG_FILES(libmysql/libmysql.ver) fi @@ -437,11 +437,13 @@ dnl Find paths to some shell programs AC_PATH_PROG(LN, ln, ln) # This must be able to take a -f flag like normal unix ln. AC_PATH_PROG(LN_CP_F, ln, ln) -if ! ( expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null ); then -# If ln -f does not exists use -s (AFS systems) -if test -n "$LN_CP_F"; then - LN_CP_F="$LN_CP_F -s" -fi +if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then + : +else + # If ln -f does not exists use -s (AFS systems) + if test -n "$LN_CP_F"; then + LN_CP_F="$LN_CP_F -s" + fi fi AC_PATH_PROG(MV, mv, mv) @@ -1940,14 +1942,16 @@ MYSQL_CHECK_IN_ADDR_T # Do the c++ compiler have a bool type MYSQL_CXX_BOOL # Check some common bugs with gcc 2.8.# on sparc -if ! ( expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null ); then -MYSQL_CHECK_LONGLONG_TO_FLOAT -if test "$ac_cv_conv_longlong_to_float" != "yes" -then - AC_MSG_ERROR([Your compiler cannot convert a longlong value to a float! +if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then + : +else + MYSQL_CHECK_LONGLONG_TO_FLOAT + if test "$ac_cv_conv_longlong_to_float" != "yes" + then + AC_MSG_ERROR([Your compiler cannot convert a longlong value to a float! If you are using gcc 2.8.# you should upgrade to egcs 1.0.3 or newer and try again]) -fi + fi fi AC_CHECK_TYPES([sigset_t, off_t], [], [], [#include ]) AC_CHECK_TYPES([size_t], [], [], [#include ]) -- cgit v1.2.1 From 75b00971be4f5c266e9e98201e387c35bc97fd05 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Mon, 12 Jan 2009 17:09:03 +0100 Subject: Backport of a 5.0.74 fix into 5.0.72sp1: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade Original changeset: > revision-id: gshchepa@mysql.com-20081114172557-xh0jlzwal8ze3cy6 > parent: ramil@mysql.com-20081114074229-vj4fvfrpmz8jfub9 > committer: Gleb Shchepa > branch nick: mysql-5.0-bugteam > timestamp: Fri 2008-11-14 21:25:57 +0400 --- sql/parse_file.cc | 93 +++--------------------------------------------------- sql/parse_file.h | 6 ++-- sql/sql_db.cc | 2 -- sql/sql_trigger.cc | 8 ++--- sql/sql_view.cc | 33 ++++--------------- sql/table.h | 1 - 6 files changed, 17 insertions(+), 126 deletions(-) diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 2b947fcac4f..ade0709cf0d 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -88,7 +88,6 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s) file pointer to IO_CACHE structure for writing base pointer to data structure parameter pointer to parameter descriptor - old_version for returning back old version number value RETURN FALSE - OK @@ -96,8 +95,7 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s) */ static my_bool -write_parameter(IO_CACHE *file, gptr base, File_option *parameter, - ulonglong *old_version) +write_parameter(IO_CACHE *file, gptr base, File_option *parameter) { char num_buf[20]; // buffer for numeric operations // string for numeric operations @@ -125,15 +123,6 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter, DBUG_RETURN(TRUE); break; } - case FILE_OPTIONS_REV: - { - ulonglong *val_i= (ulonglong *)(base + parameter->offset); - *old_version= (*val_i)++; - num.set(*val_i, &my_charset_bin); - if (my_b_append(file, (const byte *)num.ptr(), num.length())) - DBUG_RETURN(TRUE); - break; - } case FILE_OPTIONS_TIMESTAMP: { /* string have to be allocated already */ @@ -205,7 +194,6 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter, base base address for parameter reading (structure like TABLE) parameters parameters description - max_versions number of versions to save RETURN FALSE - OK @@ -215,13 +203,11 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter, my_bool sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, const LEX_STRING *type, - gptr base, File_option *parameters, - uint max_versions) + gptr base, File_option *parameters) { File handler; IO_CACHE file; char path[FN_REFLEN+1]; // +1 to put temporary file name for sure - ulonglong old_version= ULONGLONG_MAX; int path_end; File_option *param; DBUG_ENTER("sql_create_definition_file"); @@ -255,7 +241,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, if (my_b_append(&file, (const byte *)param->name.str, param->name.length) || my_b_append(&file, (const byte *)STRING_WITH_LEN("=")) || - write_parameter(&file, base, param, &old_version) || + write_parameter(&file, base, param) || my_b_append(&file, (const byte *)STRING_WITH_LEN("\n"))) goto err_w_cache; } @@ -269,55 +255,6 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, } path[path_end]='\0'; -#ifdef FRM_ARCHIVE - // archive copies management: disabled unused feature (see bug #17823). - if (!access(path, F_OK)) - { - if (old_version != ULONGLONG_MAX && max_versions != 0) - { - // save backup - char path_arc[FN_REFLEN]; - // backup old version - char path_to[FN_REFLEN]; - - // check archive directory existence - fn_format(path_arc, "arc", dir->str, "", MY_UNPACK_FILENAME); - if (access(path_arc, F_OK)) - { - if (my_mkdir(path_arc, 0777, MYF(MY_WME))) - { - DBUG_RETURN(TRUE); - } - } - - my_snprintf(path_to, FN_REFLEN, "%s/%s-%04lu", - path_arc, file_name->str, (ulong) old_version); - if (my_rename(path, path_to, MYF(MY_WME))) - { - DBUG_RETURN(TRUE); - } - - // remove very old version - if (old_version > max_versions) - { - my_snprintf(path_to, FN_REFLEN, "%s/%s-%04lu", - path_arc, file_name->str, - (ulong)(old_version - max_versions)); - if (!access(path_arc, F_OK) && my_delete(path_to, MYF(MY_WME))) - { - DBUG_RETURN(TRUE); - } - } - } - else - { - if (my_delete(path, MYF(MY_WME))) // no backups - { - DBUG_RETURN(TRUE); - } - } - } -#endif//FRM_ARCHIVE { // rename temporary file @@ -346,8 +283,6 @@ err_w_file: schema name of given schema old_name original file name new_name new file name - revision revision number - num_view_backups number of backups RETURN 0 - OK @@ -356,8 +291,7 @@ err_w_file: */ my_bool rename_in_schema_file(THD *thd, const char *schema, const char *old_name, - const char *new_name, ulonglong revision, - uint num_view_backups) + const char *new_name) { char old_path[FN_REFLEN], new_path[FN_REFLEN], arc_path[FN_REFLEN]; @@ -376,23 +310,6 @@ my_bool rename_in_schema_file(THD *thd, strxnmov(arc_path, FN_REFLEN, mysql_data_home, "/", schema, "/arc", NullS); (void) unpack_filename(arc_path, arc_path); -#ifdef FRM_ARCHIVE - if (revision > 0 && !access(arc_path, F_OK)) - { - ulonglong limit= ((revision > num_view_backups) ? - revision - num_view_backups : 0); - for (; revision > limit ; revision--) - { - my_snprintf(old_path, FN_REFLEN, "%s/%s%s-%04lu", - arc_path, old_name, reg_ext, (ulong)revision); - (void) unpack_filename(old_path, old_path); - my_snprintf(new_path, FN_REFLEN, "%s/%s%s-%04lu", - arc_path, new_name, reg_ext, (ulong)revision); - (void) unpack_filename(new_path, new_path); - my_rename(old_path, new_path, MYF(0)); - } - } -#else//FRM_ARCHIVE { // remove obsolete 'arc' directory and files if any MY_DIR *new_dirp; if ((new_dirp = my_dir(arc_path, MYF(MY_DONT_SORT)))) @@ -401,7 +318,6 @@ my_bool rename_in_schema_file(THD *thd, (void) mysql_rm_arc_files(thd, new_dirp, arc_path); } } -#endif//FRM_ARCHIVE return 0; } @@ -838,7 +754,6 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, break; } case FILE_OPTIONS_ULONGLONG: - case FILE_OPTIONS_REV: if (!(eol= strchr(ptr, '\n'))) { my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), diff --git a/sql/parse_file.h b/sql/parse_file.h index ec920b58667..ad7d1629e0a 100644 --- a/sql/parse_file.h +++ b/sql/parse_file.h @@ -23,7 +23,6 @@ enum file_opt_type { FILE_OPTIONS_STRING, /* String (LEX_STRING) */ FILE_OPTIONS_ESTRING, /* Escaped string (LEX_STRING) */ FILE_OPTIONS_ULONGLONG, /* ulonglong parameter (ulonglong) */ - FILE_OPTIONS_REV, /* Revision version number (ulonglong) */ FILE_OPTIONS_TIMESTAMP, /* timestamp (LEX_STRING have to be allocated with length 20 (19+1) */ FILE_OPTIONS_STRLIST, /* list of escaped strings @@ -81,11 +80,10 @@ File_parser *sql_parse_prepare(const LEX_STRING *file_name, my_bool sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, const LEX_STRING *type, - gptr base, File_option *parameters, uint versions); + gptr base, File_option *parameters); my_bool rename_in_schema_file(THD *thd, const char *schema, const char *old_name, - const char *new_name, ulonglong revision, - uint num_view_backups); + const char *new_name); class File_parser: public Sql_alloc { diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 8fbb407555a..c3cf7429222 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -909,7 +909,6 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, /* .frm archive: Those archives are obsolete, but following code should exist to remove existent "arc" directories. - See #ifdef FRM_ARCHIVE directives for obsolete code. */ char newpath[FN_REFLEN]; MY_DIR *new_dirp; @@ -1069,7 +1068,6 @@ static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error) NOTE A support of "arc" directories is obsolete, however this function should exist to remove existent "arc" directories. - See #ifdef FRM_ARCHIVE directives for obsolete code. */ long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path) { diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index bead50e1da8..d3b5289cd68 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -479,7 +479,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, trigname.trigger_table.length= tables->table_name_length; if (sql_create_definition_file(&dir, &trigname_file, &trigname_file_type, - (gptr)&trigname, trigname_file_parameters, 0)) + (gptr)&trigname, trigname_file_parameters)) return 1; /* @@ -569,7 +569,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, /* Create trigger definition file. */ if (!sql_create_definition_file(&dir, &file, &triggers_file_type, - (gptr)this, triggers_file_parameters, 0)) + (gptr)this, triggers_file_parameters)) return 0; err_with_cleanup: @@ -656,7 +656,7 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db, file.str= file_buff; return sql_create_definition_file(&dir, &file, &triggers_file_type, - (gptr)triggers, triggers_file_parameters, 0); + (gptr)triggers, triggers_file_parameters); } @@ -1427,7 +1427,7 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name, trigname.trigger_table= *new_table_name; if (sql_create_definition_file(&dir, &trigname_file, &trigname_file_type, - (gptr)&trigname, trigname_file_parameters, 0)) + (gptr)&trigname, trigname_file_parameters)) return trigger; } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index dffad0cc575..91991ce77bb 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -660,7 +660,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, } VOID(pthread_mutex_unlock(&LOCK_open)); - if (view->revision != 1) + if (mode != VIEW_CREATE_NEW) query_cache_invalidate3(thd, view, 0); start_waiting_global_read_lock(thd); if (res) @@ -678,12 +678,8 @@ err: } -/* index of revision number in following table */ -static const int revision_number_position= 8; -/* index of last required parameter for making view */ -static const int required_view_parameters= 10; -/* number of backups */ -static const int num_view_backups= 3; +/* number of required parameters for making view */ +static const int required_view_parameters= 9; /* table of VIEW .frm field descriptors @@ -716,9 +712,6 @@ static File_option view_parameters[]= {{(char*) STRING_WITH_LEN("with_check_option")}, my_offsetof(TABLE_LIST, with_check), FILE_OPTIONS_ULONGLONG}, - {{(char*) STRING_WITH_LEN("revision")}, - my_offsetof(TABLE_LIST, revision), - FILE_OPTIONS_REV}, {{(char*) STRING_WITH_LEN("timestamp")}, my_offsetof(TABLE_LIST, timestamp), FILE_OPTIONS_TIMESTAMP}, @@ -870,18 +863,9 @@ loop_out: } /* - read revision number - TODO: read dependence list, too, to process cascade/restrict TODO: special cascade/restrict procedure for alter? */ - if (parser->parse((gptr)view, thd->mem_root, - view_parameters + revision_number_position, 1, - &file_parser_dummy_hook)) - { - error= thd->net.report_error? -1 : 0; - goto err; - } } else { @@ -923,7 +907,7 @@ loop_out: } if (sql_create_definition_file(&dir, &file, view_file_type, - (gptr)view, view_parameters, num_view_backups)) + (gptr)view, view_parameters)) { error= thd->net.report_error? -1 : 1; goto err; @@ -1858,8 +1842,7 @@ 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, - view_def.revision - 1, num_view_backups)) + if (rename_in_schema_file(thd, view->db, view->table_name, new_name)) goto err; strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", view->db, "/", NullS); @@ -1873,12 +1856,10 @@ mysql_rename_view(THD *thd, - file_buff); if (sql_create_definition_file(&pathstr, &file, view_file_type, - (gptr)&view_def, view_parameters, - num_view_backups)) + (gptr)&view_def, view_parameters)) { /* restore renamed view in case of error */ - rename_in_schema_file(thd, view->db, new_name, view->table_name, - view_def.revision - 1, num_view_backups); + rename_in_schema_file(thd, view->db, new_name, view->table_name); goto err; } } else diff --git a/sql/table.h b/sql/table.h index 08326e2fbe0..0884f5ba3d2 100644 --- a/sql/table.h +++ b/sql/table.h @@ -657,7 +657,6 @@ struct TABLE_LIST st_lex_user definer; /* definer of view */ ulonglong file_version; /* version of file's field set */ ulonglong updatable_view; /* VIEW can be updated */ - ulonglong revision; /* revision control number */ ulonglong algorithm; /* 0 any, 1 tmp tables , 2 merging */ ulonglong view_suid; /* view is suid (TRUE dy default) */ ulonglong with_check; /* WITH CHECK OPTION */ -- cgit v1.2.1 From cd617234dc418147273005227807adf7cf40bb73 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Mon, 12 Jan 2009 17:18:53 +0100 Subject: Backport of a 5.0.74 fix into 5.0.72sp1: BUG#38842 - Fix for 25951 seems incorrect Original changeset: > revision-id: svoj@mysql.com-20081111091051-54pr96nf1z2s30gx > parent: vvaintroub@mysql.com-20081110201804-bi98gcs9avsf58ff > committer: Sergey Vojtovich > branch nick: mysql-5.0-bugteam-bug38842 > timestamp: Tue 2008-11-11 13:10:51 +0400 --- mysql-test/r/fulltext.result | 28 ++++++++++++++++++++++++++++ mysql-test/t/fulltext.test | 27 +++++++++++++++++++++++++++ sql/item_func.cc | 4 +++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 29fb430bb97..e73f8af405c 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -469,3 +469,31 @@ SELECT * FROM t1 WHERE MATCH(a) AGAINST ('"aaaa"' IN BOOLEAN MODE); a aaaaa aaaa DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(255), b INT, FULLTEXT(a), KEY(b)); +INSERT INTO t1 VALUES('test', 1),('test', 1),('test', 1),('test', 1), +('test', 1),('test', 2),('test', 3),('test', 4); +EXPLAIN SELECT * FROM t1 +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext b,a a 0 1 Using where +EXPLAIN SELECT * FROM t1 USE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext a a 0 1 Using where +EXPLAIN SELECT * FROM t1 FORCE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext a a 0 1 Using where +EXPLAIN SELECT * FROM t1 IGNORE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref b b 5 const 4 Using where +EXPLAIN SELECT * FROM t1 USE INDEX(b) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref b b 5 const 4 Using where +EXPLAIN SELECT * FROM t1 FORCE INDEX(b) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref b b 5 const 4 Using where +DROP TABLE t1; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index e5f1db14b7f..fa087d89efb 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -396,3 +396,30 @@ SELECT * FROM t1 WHERE MATCH(a) AGAINST ('"aaaa"' IN BOOLEAN MODE); DROP TABLE t1; # End of 4.1 tests + +# +# BUG#38842 - Fix for 25951 seems incorrect +# +CREATE TABLE t1 (a VARCHAR(255), b INT, FULLTEXT(a), KEY(b)); +INSERT INTO t1 VALUES('test', 1),('test', 1),('test', 1),('test', 1), + ('test', 1),('test', 2),('test', 3),('test', 4); + +EXPLAIN SELECT * FROM t1 +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 USE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 FORCE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 IGNORE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 USE INDEX(b) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 FORCE INDEX(b) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +DROP TABLE t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index e663e1fcf83..66fbf1eb4d2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5022,7 +5022,9 @@ bool Item_func_match::fix_index() for (keynr=0 ; keynr < table->s->keys ; keynr++) { if ((table->key_info[keynr].flags & HA_FULLTEXT) && - (table->s->keys_in_use.is_set(keynr))) + (flags & FT_BOOL ? table->keys_in_use_for_query.is_set(keynr) : + table->s->keys_in_use.is_set(keynr))) + { ft_to_key[fts]=keynr; ft_cnt[fts]=0; -- cgit v1.2.1 From 68416c4c1c662dc9860f39746442dde0293f1882 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Mon, 12 Jan 2009 17:24:00 +0100 Subject: Backport of a 5.0.74 fix into 5.0.72sp1: Bug#34760 Character set autodetection appears to fail the problem is the same as reported in bug#20835, so the fix is backport of bug#20835 patch. Original changeset: > revision-id: sergey.glukhov@sun.com-20081121123959-58ffhp2nitg7f40h > parent: ramil@mysql.com-20081120100836-gct60cm67b1rui29 > committer: Sergey Glukhov > branch nick: mysql-5.0-bugteam > timestamp: Fri 2008-11-21 16:39:59 +0400 --- mysql-test/r/subselect.result | 15 +++++++++++++++ mysql-test/t/subselect.test | 19 ++++++++++++++++++- sql/item_cmpfunc.cc | 3 ++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index c5bae840214..6eeb652e3c1 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4407,4 +4407,19 @@ pk a 3 30 2 20 DROP TABLE t1,t2; +CREATE TABLE t1 (s1 char(1)); +INSERT INTO t1 VALUES ('a'); +SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1); +s1 +a +DROP TABLE t1; +CREATE TABLE t1(id BIGINT); +CREATE TABLE t2(id1 BIGINT, id2 BIGINT); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (2,1),(3,1); +SELECT * FROM t1 i WHERE 1 IN (SELECT l.id2 FROM t2 l WHERE i.id=l.id1); +id +2 +3 +DROP TABLE t1, t2; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 2dfad2c58dd..d28e31fb545 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3307,5 +3307,22 @@ SELECT * FROM t1 WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b); DROP TABLE t1,t2; ---echo End of 5.0 tests. +# +# Bug#20835 (literal string with =any values) +# +CREATE TABLE t1 (s1 char(1)); +INSERT INTO t1 VALUES ('a'); +SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1); +DROP TABLE t1; +# +# Bug#40519 Subselect query using bigint fails +# +CREATE TABLE t1(id BIGINT); +CREATE TABLE t2(id1 BIGINT, id2 BIGINT); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (2,1),(3,1); +SELECT * FROM t1 i WHERE 1 IN (SELECT l.id2 FROM t2 l WHERE i.id=l.id1); +DROP TABLE t1, t2; + +--echo End of 5.0 tests. diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 0410c781590..4bfae376acc 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1434,7 +1434,8 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref) } not_null_tables_cache= args[0]->not_null_tables(); with_sum_func= args[0]->with_sum_func; - const_item_cache= args[0]->const_item(); + if ((const_item_cache= args[0]->const_item())) + cache->store(args[0]); return 0; } -- cgit v1.2.1 From 858584a36bebc8fe3df40904ea2729196758cc55 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Mon, 12 Jan 2009 17:40:29 +0100 Subject: Backport of a 5.0.74 fix into 5.0.72sp1: Bug #39920: MySQL cannot deal with Leap Second expression in string literal. Updated MySQL time handling code to react correctly on UTC leap second additions. MySQL functions that return the OS current time, like e.g. CURDATE(), NOW() etc will return :59:59 instead of :59:60 or 59:61. As a result the reader will receive :59:59 for 2 or 3 consecutive seconds during the leap second. Original changesets: > revision-id: kgeorge@mysql.com-20081201141835-rg8nnnadujj5wl9f > parent: gshchepa@mysql.com-20081114172557-xh0jlzwal8ze3cy6 > committer: Georgi Kodinov > branch nick: B39920-5.0-bugteam > timestamp: Mon 2008-12-01 16:18:35 +0200 > revision-id: kgeorge@mysql.com-20081201154106-c310zzy5or043rqa > parent: kgeorge@mysql.com-20081201145656-6kjq91oga5nxbbob > committer: Georgi Kodinov > branch nick: B39920-merge-5.0-bugteam > timestamp: Mon 2008-12-01 17:41:06 +0200 --- mysql-test/r/timezone2.result | 2 +- mysql-test/r/timezone3.result | 8 ++++++++ mysql-test/std_data/Moscow_leap | Bin 991 -> 2674 bytes mysql-test/t/timezone3.test | 12 ++++++++++++ sql/tztime.cc | 22 ++++++++++++++++++++++ sql/tztime.h | 3 +++ 6 files changed, 46 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/timezone2.result b/mysql-test/r/timezone2.result index bb1d764ac8c..e115ce16fa4 100644 --- a/mysql-test/r/timezone2.result +++ b/mysql-test/r/timezone2.result @@ -110,7 +110,7 @@ i ts 362793610 1981-07-01 04:00:00 select from_unixtime(362793609); from_unixtime(362793609) -1981-07-01 03:59:60 +1981-07-01 03:59:59 drop table t1; create table t1 (ts timestamp); set time_zone='UTC'; diff --git a/mysql-test/r/timezone3.result b/mysql-test/r/timezone3.result index ec0b6045f93..ceac4a5aefb 100644 --- a/mysql-test/r/timezone3.result +++ b/mysql-test/r/timezone3.result @@ -17,6 +17,9 @@ insert into t1 values insert into t1 values (unix_timestamp('1981-07-01 03:59:59'),'1981-07-01 03:59:59'), (unix_timestamp('1981-07-01 04:00:00'),'1981-07-01 04:00:00'); +insert into t1 values +(unix_timestamp('2009-01-01 02:59:59'),'2009-01-01 02:59:59'), +(unix_timestamp('2009-01-01 03:00:00'),'2009-01-01 03:00:00'); select i, from_unixtime(i), c from t1; i from_unixtime(i) c 1072904422 2004-01-01 00:00:00 2004-01-01 00:00:00 @@ -31,6 +34,8 @@ i from_unixtime(i) c 1099180821 2004-10-31 02:59:59 2004-10-31 02:59:59 362793608 1981-07-01 03:59:59 1981-07-01 03:59:59 362793610 1981-07-01 04:00:00 1981-07-01 04:00:00 +1230768022 2009-01-01 02:59:59 2009-01-01 02:59:59 +1230768024 2009-01-01 03:00:00 2009-01-01 03:00:00 drop table t1; create table t1 (ts timestamp); insert into t1 values (19730101235900), (20040101235900); @@ -39,3 +44,6 @@ ts 1973-01-01 23:59:00 2004-01-01 23:59:00 drop table t1; +SELECT FROM_UNIXTIME(1230768022), FROM_UNIXTIME(1230768023), FROM_UNIXTIME(1230768024); +FROM_UNIXTIME(1230768022) FROM_UNIXTIME(1230768023) FROM_UNIXTIME(1230768024) +2009-01-01 02:59:59 2009-01-01 02:59:59 2009-01-01 03:00:00 diff --git a/mysql-test/std_data/Moscow_leap b/mysql-test/std_data/Moscow_leap index 4994c005595..3e73923cfb3 100644 Binary files a/mysql-test/std_data/Moscow_leap and b/mysql-test/std_data/Moscow_leap differ diff --git a/mysql-test/t/timezone3.test b/mysql-test/t/timezone3.test index 0aedbafcec4..8a9941f6383 100644 --- a/mysql-test/t/timezone3.test +++ b/mysql-test/t/timezone3.test @@ -45,6 +45,10 @@ insert into t1 values (unix_timestamp('1981-07-01 03:59:59'),'1981-07-01 03:59:59'), (unix_timestamp('1981-07-01 04:00:00'),'1981-07-01 04:00:00'); +insert into t1 values + (unix_timestamp('2009-01-01 02:59:59'),'2009-01-01 02:59:59'), + (unix_timestamp('2009-01-01 03:00:00'),'2009-01-01 03:00:00'); + select i, from_unixtime(i), c from t1; drop table t1; @@ -58,4 +62,12 @@ insert into t1 values (19730101235900), (20040101235900); select * from t1; drop table t1; +# +# Test Bug #39920: MySQL cannot deal with Leap Second expression in string +# literal +# + +# 2009-01-01 02:59:59, 2009-01-01 02:59:60 and 2009-01-01 03:00:00 +SELECT FROM_UNIXTIME(1230768022), FROM_UNIXTIME(1230768023), FROM_UNIXTIME(1230768024); + # End of 4.1 tests diff --git a/sql/tztime.cc b/sql/tztime.cc index 709e3b64752..d3d952e3c1e 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1073,6 +1073,7 @@ Time_zone_system::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const localtime_r(&tmp_t, &tmp_tm); localtime_to_TIME(tmp, &tmp_tm); tmp->time_type= MYSQL_TIMESTAMP_DATETIME; + adjust_leap_second(tmp); } @@ -1157,6 +1158,7 @@ Time_zone_utc::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const gmtime_r(&tmp_t, &tmp_tm); localtime_to_TIME(tmp, &tmp_tm); tmp->time_type= MYSQL_TIMESTAMP_DATETIME; + adjust_leap_second(tmp); } @@ -1260,6 +1262,7 @@ void Time_zone_db::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const { ::gmt_sec_to_TIME(tmp, t, tz_info); + adjust_leap_second(tmp); } @@ -2373,6 +2376,25 @@ Time_zone *my_tz_find_with_opening_tz_tables(THD *thd, const String *name) DBUG_RETURN(tz); } + +/** + Convert leap seconds into non-leap + + This function will convert the leap seconds added by the OS to + non-leap seconds, e.g. 23:59:59, 23:59:60 -> 23:59:59, 00:00:01 ... + This check is not checking for years on purpose : although it's not a + complete check this way it doesn't require looking (and having installed) + the leap seconds table. + + @param[in,out] broken down time structure as filled in by the OS +*/ + +void Time_zone::adjust_leap_second(MYSQL_TIME *t) +{ + if (t->second == 60 || t->second == 61) + t->second= 59; +} + #endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */ diff --git a/sql/tztime.h b/sql/tztime.h index 32a942a26e1..750b8dacbe1 100644 --- a/sql/tztime.h +++ b/sql/tztime.h @@ -55,6 +55,9 @@ public: allocated on MEM_ROOT and should not require destruction. */ virtual ~Time_zone() {}; + +protected: + static inline void adjust_leap_second(MYSQL_TIME *t); }; extern Time_zone * my_tz_UTC; -- cgit v1.2.1 From 131d689e58b28930931fe99db4797a067ef80f8a Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Mon, 12 Jan 2009 22:02:40 +0100 Subject: Set the version: 5.0.72sp1 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 162e21d9d75..2f36c6c0816 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.72) +AM_INIT_AUTOMAKE(mysql, 5.0.72sp1) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 -- cgit v1.2.1 From 2bba19148fb138757f6b59c19e4b7cd11dee73da Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 13 Jan 2009 13:09:12 +0200 Subject: Bug #38795: Automatic search depth and nested join's results in server crash The greedy optimizer tracks the current level of nested joins and the position inside these by setting and maintaining a state that's global for the whole FROM clause. This state was correctly maintained inside the selection of the next partial plan table (in best_extension_by_limited_search()). greedy_search() also moves the current position by adding the last partial match table when there's not enough tables in the partial plan found by best_extension_by_limited_search(). This may require update of the global state variables that describe the current position in the plan if the last table placed by greedy_search is not a top-level join table. Fixed by updating the state after placing the partial plan table in greedy_search() in the same way this is done on entering the best_extension_by_limited_search(). Fixed the signature of the function called to update the state : check_interleaving_with_nj mysql-test/r/greedy_optimizer.result: Bug #38795: test case mysql-test/t/greedy_optimizer.test: Bug #38795: test case sql/sql_select.cc: Bug #38795: correctly update current position when placing the next partial plan table in greedy_search(). --- mysql-test/r/greedy_optimizer.result | 77 ++++++++++++++++++++++++++++++++++++ mysql-test/t/greedy_optimizer.test | 73 ++++++++++++++++++++++++++++++++++ sql/sql_select.cc | 27 ++++++++----- 3 files changed, 168 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/greedy_optimizer.result b/mysql-test/r/greedy_optimizer.result index 1da49fbedb0..534038ee626 100644 --- a/mysql-test/r/greedy_optimizer.result +++ b/mysql-test/r/greedy_optimizer.result @@ -655,3 +655,80 @@ show status like 'Last_query_cost'; Variable_name Value Last_query_cost 794.837037 drop table t1,t2,t3,t4,t5,t6,t7; +CREATE TABLE t1 (a int, b int, d int, i int); +INSERT INTO t1 VALUES (1,1,1,1); +CREATE TABLE t2 (b int, c int, j int); +INSERT INTO t2 VALUES (1,1,1); +CREATE TABLE t2_1 (j int); +INSERT INTO t2_1 VALUES (1); +CREATE TABLE t3 (c int, f int); +INSERT INTO t3 VALUES (1,1); +CREATE TABLE t3_1 (f int); +INSERT INTO t3_1 VALUES (1); +CREATE TABLE t4 (d int, e int, k int); +INSERT INTO t4 VALUES (1,1,1); +CREATE TABLE t4_1 (k int); +INSERT INTO t4_1 VALUES (1); +CREATE TABLE t5 (g int, d int, h int, l int); +INSERT INTO t5 VALUES (1,1,1,1); +CREATE TABLE t5_1 (l int); +INSERT INTO t5_1 VALUES (1); +SET optimizer_search_depth = 3; +SELECT 1 +FROM t1 +LEFT JOIN ( +t2 JOIN t3 ON t3.c = t2.c +) ON t2.b = t1.b +LEFT JOIN ( +t4 JOIN t5 ON t5.d = t4.d +) ON t4.d = t1.d +; +1 +1 +SELECT 1 +FROM t1 +LEFT JOIN ( +t2 LEFT JOIN (t3 JOIN t3_1 ON t3.f = t3_1.f) ON t3.c = t2.c +) ON t2.b = t1.b +LEFT JOIN ( +t4 JOIN t5 ON t5.d = t4.d +) ON t4.d = t1.d +; +1 +1 +SELECT 1 +FROM t1 +LEFT JOIN ( +(t2 JOIN t2_1 ON t2.j = t2_1.j) JOIN t3 ON t3.c = t2.c +) ON t2.b = t1.b +LEFT JOIN ( +t4 JOIN t5 ON t5.d = t4.d +) ON t4.d = t1.d +; +1 +1 +SELECT 1 +FROM t1 +LEFT JOIN ( +t2 JOIN t3 ON t3.c = t2.c +) ON t2.b = t1.b +LEFT JOIN ( +(t4 JOIN t4_1 ON t4.k = t4_1.k) LEFT JOIN t5 ON t5.d = t4.d +) ON t4.d = t1.d +; +1 +1 +SELECT 1 +FROM t1 +LEFT JOIN ( +t2 JOIN t3 ON t3.c = t2.c +) ON t2.b = t1.b +LEFT JOIN ( +t4 LEFT JOIN (t5 JOIN t5_1 ON t5.l = t5_1.l) ON t5.d = t4.d +) ON t4.d = t1.d +; +1 +1 +SET optimizer_search_depth = DEFAULT; +DROP TABLE t1,t2,t2_1,t3,t3_1,t4,t4_1,t5,t5_1; +End of 5.0 tests diff --git a/mysql-test/t/greedy_optimizer.test b/mysql-test/t/greedy_optimizer.test index b73f70c6a3e..5131c97f122 100644 --- a/mysql-test/t/greedy_optimizer.test +++ b/mysql-test/t/greedy_optimizer.test @@ -311,3 +311,76 @@ explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and show status like 'Last_query_cost'; drop table t1,t2,t3,t4,t5,t6,t7; + + +# +# Bug # 38795: Automatic search depth and nested join's results in server +# crash +# + +CREATE TABLE t1 (a int, b int, d int, i int); INSERT INTO t1 VALUES (1,1,1,1); +CREATE TABLE t2 (b int, c int, j int); INSERT INTO t2 VALUES (1,1,1); +CREATE TABLE t2_1 (j int); INSERT INTO t2_1 VALUES (1); +CREATE TABLE t3 (c int, f int); INSERT INTO t3 VALUES (1,1); +CREATE TABLE t3_1 (f int); INSERT INTO t3_1 VALUES (1); +CREATE TABLE t4 (d int, e int, k int); INSERT INTO t4 VALUES (1,1,1); +CREATE TABLE t4_1 (k int); INSERT INTO t4_1 VALUES (1); +CREATE TABLE t5 (g int, d int, h int, l int); INSERT INTO t5 VALUES (1,1,1,1); +CREATE TABLE t5_1 (l int); INSERT INTO t5_1 VALUES (1); + +SET optimizer_search_depth = 3; + +SELECT 1 +FROM t1 +LEFT JOIN ( + t2 JOIN t3 ON t3.c = t2.c +) ON t2.b = t1.b +LEFT JOIN ( + t4 JOIN t5 ON t5.d = t4.d +) ON t4.d = t1.d +; + +SELECT 1 +FROM t1 +LEFT JOIN ( + t2 LEFT JOIN (t3 JOIN t3_1 ON t3.f = t3_1.f) ON t3.c = t2.c +) ON t2.b = t1.b +LEFT JOIN ( + t4 JOIN t5 ON t5.d = t4.d +) ON t4.d = t1.d +; + +SELECT 1 +FROM t1 +LEFT JOIN ( + (t2 JOIN t2_1 ON t2.j = t2_1.j) JOIN t3 ON t3.c = t2.c +) ON t2.b = t1.b +LEFT JOIN ( + t4 JOIN t5 ON t5.d = t4.d +) ON t4.d = t1.d +; + +SELECT 1 +FROM t1 +LEFT JOIN ( + t2 JOIN t3 ON t3.c = t2.c +) ON t2.b = t1.b +LEFT JOIN ( + (t4 JOIN t4_1 ON t4.k = t4_1.k) LEFT JOIN t5 ON t5.d = t4.d +) ON t4.d = t1.d +; + +SELECT 1 +FROM t1 +LEFT JOIN ( + t2 JOIN t3 ON t3.c = t2.c +) ON t2.b = t1.b +LEFT JOIN ( + t4 LEFT JOIN (t5 JOIN t5_1 ON t5.l = t5_1.l) ON t5.d = t4.d +) ON t4.d = t1.d +; + +SET optimizer_search_depth = DEFAULT; +DROP TABLE t1,t2,t2_1,t3,t3_1,t4,t4_1,t5,t5_1; + +--echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9723dd8c4e4..c49b0f0b723 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -100,7 +100,7 @@ static COND* substitute_for_best_equal_field(COND *cond, void *table_join_idx); static COND *simplify_joins(JOIN *join, List *join_list, COND *conds, bool top); -static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next); +static bool check_interleaving_with_nj(JOIN_TAB *next); static void restore_prev_nj_state(JOIN_TAB *last); static void reset_nj_counters(List *join_list); static uint build_bitmap_for_nested_joins(List *join_list, @@ -4705,6 +4705,18 @@ greedy_search(JOIN *join, */ join->positions[idx]= best_pos; + /* + Update the interleaving state after extending the current partial plan + with a new table. + We are doing this here because best_extension_by_limited_search reverts + the interleaving state to the one of the non-extended partial plan + on exit. + */ + IF_DBUG(bool is_interleave_error= ) + check_interleaving_with_nj (best_table); + /* This has been already checked by best_extension_by_limited_search */ + DBUG_ASSERT(!is_interleave_error); + /* find the position of 'best_table' in 'join->best_ref' */ best_idx= idx; JOIN_TAB *pos= join->best_ref[best_idx]; @@ -4722,7 +4734,7 @@ greedy_search(JOIN *join, --size_remain; ++idx; - DBUG_EXECUTE("opt", print_plan(join, join->tables, + DBUG_EXECUTE("opt", print_plan(join, idx, record_count, read_time, read_time, "extended");); } while (TRUE); @@ -4873,7 +4885,7 @@ best_extension_by_limited_search(JOIN *join, table_map real_table_bit= s->table->map; if ((remaining_tables & real_table_bit) && !(remaining_tables & s->dependent) && - (!idx || !check_interleaving_with_nj(join->positions[idx-1].table, s))) + (!idx || !check_interleaving_with_nj(s))) { double current_record_count, current_read_time; @@ -5018,7 +5030,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, { table_map real_table_bit=s->table->map; if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) && - (!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s))) + (!idx|| !check_interleaving_with_nj(s))) { double records, best; best_access_path(join, s, thd, rest_tables, idx, record_count, @@ -8380,9 +8392,6 @@ static void reset_nj_counters(List *join_list) SYNOPSIS check_interleaving_with_nj() - join Join being processed - last_tab Last table in current partial join order (this function is - not called for empty partial join orders) next_tab Table we're going to extend the current partial join with DESCRIPTION @@ -8467,10 +8476,10 @@ static void reset_nj_counters(List *join_list) TRUE Requested join order extension not allowed. */ -static bool check_interleaving_with_nj(JOIN_TAB *last_tab, JOIN_TAB *next_tab) +static bool check_interleaving_with_nj(JOIN_TAB *next_tab) { TABLE_LIST *next_emb= next_tab->table->pos_in_table_list->embedding; - JOIN *join= last_tab->join; + JOIN *join= next_tab->join; if (join->cur_embedding_map & ~next_tab->embedding_map) { -- cgit v1.2.1 From 94361be12364fd47c997882b7abe8227b6a13c54 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Tue, 13 Jan 2009 14:52:22 +0100 Subject: Tool fix, needed for "compile-dist" to succeed on Solaris: The default "awk" there cannot handle some of the scripts which are used by BDB for configuration. The fix: 1) Introduce a variable "AWK" in some of the BDB shell scripts, 2) search "gawk" and give it precedence over "awk" when assigning a value to the "AWK" variable, fail if neither is found, 3) use that variable when calling an "awk" program with one of the critical scripts. The perfect solution would be to use the "awk" program found by "configure", but we cannot follow that approach because BDB's configuration is handled as a special case before the overall "configure" is run. Because of this, 1) the "configure" result isn't yet available, 2) "configure" will not handle these BDB files. Searching "gawk" is a (not-so-nice) way out. Note that all this need not be perfectly portable, it is needed only when we create a source distribution tarball from a develkopment tree. bdb/dist/s_all: Search "gawk" if available, give it precedence over "awk", fail if neither is found. bdb/dist/s_include: Ensure we use a modern AWK, similar to GNU awk, the default awk on Solaris cannot handle BDB's script. bdb/dist/s_recover: Ensure we use a modern AWK, similar to GNU awk, the default awk on Solaris cannot handle BDB's script. bdb/dist/s_rpc: Ensure we use a modern AWK, similar to GNU awk, the default awk on Solaris cannot handle BDB's script. --- bdb/dist/s_all | 15 +++++++++++++++ bdb/dist/s_include | 6 +++--- bdb/dist/s_recover | 2 +- bdb/dist/s_rpc | 2 +- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/bdb/dist/s_all b/bdb/dist/s_all index 132017def3c..97ce572a4ae 100644 --- a/bdb/dist/s_all +++ b/bdb/dist/s_all @@ -1,6 +1,21 @@ #!/bin/sh - # $Id: s_all,v 1.10 2001/08/04 14:01:44 bostic Exp $ +# Search an AWK program, use GNU awk if available +for x in gawk awk ; do + if type $x; then + AWK=$x + break + fi +done + +if test -z "$AWK"; then + echo 'No AWK program found' + exit 1 +fi +export AWK +# end of AWK search + sh s_dir #sh s_perm # permissions. diff --git a/bdb/dist/s_include b/bdb/dist/s_include index 878b4a38af1..5cb3a666dc0 100755 --- a/bdb/dist/s_include +++ b/bdb/dist/s_include @@ -79,7 +79,7 @@ for i in db btree clib common dbreg env fileops hash hmac \ [ $i = os ] && f="$f ../os_win32/*.c" [ $i = rpc_server ] && f="../$i/c/*.c" [ $i = crypto ] && f="../$i/*.c ../$i/*/*.c" - awk -f gen_inc.awk \ + $AWK -f gen_inc.awk \ -v db_version_unique_name=$DB_VERSION_UNIQUE_NAME \ -v e_dfile=$e_dfile \ -v e_pfile=$e_pfile \ @@ -97,7 +97,7 @@ done # files. for i in dbm hsearch; do f="../$i/*.c" - awk -f gen_inc.awk \ + $AWK -f gen_inc.awk \ -v db_version_unique_name=$DB_VERSION_UNIQUE_NAME \ -v e_dfile=$e_dfile \ -v e_pfile=$e_pfile \ @@ -142,7 +142,7 @@ head space defonly _DB_EXT_185_DEF_IN_ > $e_dfile head space _DB_EXT_185_PROT_IN_ > $e_pfile f="../db185/*.c" -awk -f gen_inc.awk \ +$AWK -f gen_inc.awk \ -v db_version_unique_name=$DB_VERSION_UNIQUE_NAME \ -v e_dfile=$e_dfile \ -v e_pfile=$e_pfile \ diff --git a/bdb/dist/s_recover b/bdb/dist/s_recover index fc2e160c083..f6d2ad33e5a 100755 --- a/bdb/dist/s_recover +++ b/bdb/dist/s_recover @@ -45,7 +45,7 @@ cmp $loglist $f > /dev/null 2>&1 || for i in db dbreg btree fileops hash qam txn; do for f in ../$i/*.src; do subsystem=`basename $f .src` - awk -f gen_rec.awk \ + $AWK -f gen_rec.awk \ -v source_file=$source \ -v header_file=$header \ -v template_file=$template < $f diff --git a/bdb/dist/s_rpc b/bdb/dist/s_rpc index cdafa669d85..f9495ec121f 100644 --- a/bdb/dist/s_rpc +++ b/bdb/dist/s_rpc @@ -43,7 +43,7 @@ rm -f $client_file \ xidsize=\ `awk '/^#define/ { if ($2 == "DB_XIDDATASIZE") { print $3 }}' $dbinc_file` -awk -f gen_rpc.awk \ +$AWK -f gen_rpc.awk \ -v major=$DB_VERSION_MAJOR \ -v minor=$DB_VERSION_MINOR \ -v xidsize=$xidsize \ -- cgit v1.2.1 From a9aaa09b212d9275f79a557fc9f09b161490b79b Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 13 Jan 2009 20:07:06 -0200 Subject: Bug#36326: nested transaction and select The problem is that the query cache stores packets containing the server status of the time when the cached statement was run. This might lead to a wrong transaction status in the client side if a statement is cached during a transaction and is later served outside a transaction context (and vice-versa). The solution is to take into account the transaction status when storing in and serving from the query cache. mysql-test/r/innodb_cache.result: Update test case result. mysql-test/r/query_cache.result: Add test case result for Bug#36326 mysql-test/t/query_cache.test: Add test case for Bug#36326 sql/mysql_priv.h: Add new flags. sql/sql_cache.cc: Remember the transaction and autocommit status stored in the packet. tests/mysql_client_test.c: Add test case for Bug#36326 --- mysql-test/r/innodb_cache.result | 10 +++---- mysql-test/r/query_cache.result | 51 ++++++++++++++++++++++++++++++++++ mysql-test/t/query_cache.test | 27 ++++++++++++++++++ sql/mysql_priv.h | 2 ++ sql/sql_cache.cc | 17 +++++++++--- tests/mysql_client_test.c | 60 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 158 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/innodb_cache.result b/mysql-test/r/innodb_cache.result index 5e8611655a2..36fa3c5c352 100644 --- a/mysql-test/r/innodb_cache.result +++ b/mysql-test/r/innodb_cache.result @@ -66,10 +66,10 @@ a 2 show status like "Qcache_queries_in_cache"; Variable_name Value -Qcache_queries_in_cache 3 +Qcache_queries_in_cache 6 show status like "Qcache_hits"; Variable_name Value -Qcache_hits 3 +Qcache_hits 0 insert into t1 values (3); insert into t2 values (3); insert into t1 values (4); @@ -90,14 +90,14 @@ a 2 show status like "Qcache_queries_in_cache"; Variable_name Value -Qcache_queries_in_cache 1 +Qcache_queries_in_cache 2 show status like "Qcache_hits"; Variable_name Value -Qcache_hits 4 +Qcache_hits 1 commit; show status like "Qcache_queries_in_cache"; Variable_name Value -Qcache_queries_in_cache 1 +Qcache_queries_in_cache 2 drop table t3,t2,t1; CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) ENGINE=InnoDB; select count(*) from t1; diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index fa80a44c177..a2b73db77a9 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -1681,3 +1681,54 @@ Qcache_hits 1 DROP TABLE t1; SET GLOBAL concurrent_insert= @save_concurrent_insert; SET GLOBAL query_cache_size= default; +DROP TABLE IF EXISTS t1; +FLUSH STATUS; +SET GLOBAL query_cache_size=1048576; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +SHOW STATUS LIKE 'Qcache_queries_in_cache'; +Variable_name Value +Qcache_queries_in_cache 0 +SELECT * FROM t1; +a +1 +2 +3 +4 +5 +BEGIN; +SELECT * FROM t1; +a +1 +2 +3 +4 +5 +COMMIT; +SHOW STATUS LIKE 'Qcache_queries_in_cache'; +Variable_name Value +Qcache_queries_in_cache 2 +SHOW STATUS LIKE "Qcache_hits"; +Variable_name Value +Qcache_hits 0 +SELECT * FROM t1; +a +1 +2 +3 +4 +5 +BEGIN; +SELECT * FROM t1; +a +1 +2 +3 +4 +5 +COMMIT; +SHOW STATUS LIKE "Qcache_hits"; +Variable_name Value +Qcache_hits 2 +DROP TABLE t1; +SET GLOBAL query_cache_size= default; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index ebd24bf2b89..2dd70f415a1 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -1276,4 +1276,31 @@ DROP TABLE t1; SET GLOBAL concurrent_insert= @save_concurrent_insert; SET GLOBAL query_cache_size= default; +# +# Bug#36326: nested transaction and select +# + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +FLUSH STATUS; +SET GLOBAL query_cache_size=1048576; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +SHOW STATUS LIKE 'Qcache_queries_in_cache'; +SELECT * FROM t1; +BEGIN; +SELECT * FROM t1; +COMMIT; +SHOW STATUS LIKE 'Qcache_queries_in_cache'; +SHOW STATUS LIKE "Qcache_hits"; +SELECT * FROM t1; +BEGIN; +SELECT * FROM t1; +COMMIT; +SHOW STATUS LIKE "Qcache_hits"; +DROP TABLE t1; +SET GLOBAL query_cache_size= default; + # End of 5.0 tests diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 8a8513ac745..b855af9a8d3 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -651,6 +651,8 @@ struct Query_cache_query_flags unsigned int client_long_flag:1; unsigned int client_protocol_41:1; unsigned int more_results_exists:1; + unsigned int in_trans:1; + unsigned int autocommit:1; unsigned int pkt_nr; uint character_set_client_num; uint character_set_results_num; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index b487f092f75..4a521d83192 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -859,6 +859,8 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) CLIENT_PROTOCOL_41); flags.more_results_exists= test(thd->server_status & SERVER_MORE_RESULTS_EXISTS); + flags.in_trans= test(thd->server_status & SERVER_STATUS_IN_TRANS); + flags.autocommit= test(thd->server_status & SERVER_STATUS_AUTOCOMMIT); flags.pkt_nr= net->pkt_nr; flags.character_set_client_num= thd->variables.character_set_client->number; @@ -879,7 +881,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) DBUG_PRINT("qcache", ("long %d, 4.1: %d, more results %d, pkt_nr: %d, \ CS client: %u, CS result: %u, CS conn: %u, limit: %lu, TZ: 0x%lx, \ sql mode: 0x%lx, sort len: %lu, conncat len: %lu, div_precision: %lu, \ -def_week_frmt: %lu", +def_week_frmt: %lu, in_trans: %d, autocommit: %d", (int)flags.client_long_flag, (int)flags.client_protocol_41, (int)flags.more_results_exists, @@ -893,7 +895,10 @@ def_week_frmt: %lu", flags.max_sort_length, flags.group_concat_max_len, flags.div_precision_increment, - flags.default_week_format)); + flags.default_week_format, + (int)flags.in_trans, + (int)flags.autocommit)); + /* Make InnoDB to release the adaptive hash index latch before acquiring the query cache mutex. @@ -1144,6 +1149,8 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) CLIENT_PROTOCOL_41); flags.more_results_exists= test(thd->server_status & SERVER_MORE_RESULTS_EXISTS); + flags.in_trans= test(thd->server_status & SERVER_STATUS_IN_TRANS); + flags.autocommit= test(thd->server_status & SERVER_STATUS_AUTOCOMMIT); flags.pkt_nr= thd->net.pkt_nr; flags.character_set_client_num= thd->variables.character_set_client->number; flags.character_set_results_num= @@ -1162,7 +1169,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) DBUG_PRINT("qcache", ("long %d, 4.1: %d, more results %d, pkt_nr: %d, \ CS client: %u, CS result: %u, CS conn: %u, limit: %lu, TZ: 0x%lx, \ sql mode: 0x%lx, sort len: %lu, conncat len: %lu, div_precision: %lu, \ -def_week_frmt: %lu", +def_week_frmt: %lu, in_trans: %d, autocommit: %d", (int)flags.client_long_flag, (int)flags.client_protocol_41, (int)flags.more_results_exists, @@ -1176,7 +1183,9 @@ def_week_frmt: %lu", flags.max_sort_length, flags.group_concat_max_len, flags.div_precision_increment, - flags.default_week_format)); + flags.default_week_format, + (int)flags.in_trans, + (int)flags.autocommit)); memcpy((void *)(sql + (tot_length - QUERY_CACHE_FLAGS_SIZE)), &flags, QUERY_CACHE_FLAGS_SIZE); query_block = (Query_cache_block *) hash_search(&queries, (byte*) sql, diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 50f03a1a086..0fddffebf82 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16354,6 +16354,63 @@ static void test_bug40365(void) DBUG_VOID_RETURN; } + + +/** + Bug#36326: nested transaction and select +*/ + +#ifdef HAVE_QUERY_CACHE + +static void test_bug36326() +{ + int rc; + + DBUG_ENTER("test_bug36326"); + myheader("test_bug36326"); + + rc= mysql_autocommit(mysql, TRUE); + myquery(rc); + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + rc= mysql_query(mysql, "CREATE TABLE t1 (a INTEGER)"); + myquery(rc); + rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)"); + myquery(rc); + rc= mysql_query(mysql, "SET GLOBAL query_cache_type = 1"); + myquery(rc); + rc= mysql_query(mysql, "SET GLOBAL query_cache_size = 1048576"); + myquery(rc); + DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS)); + DIE_UNLESS(mysql->server_status & SERVER_STATUS_AUTOCOMMIT); + rc= mysql_query(mysql, "BEGIN"); + myquery(rc); + DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS); + rc= mysql_query(mysql, "SELECT * FROM t1"); + myquery(rc); + rc= my_process_result(mysql); + DIE_UNLESS(rc == 1); + rc= mysql_rollback(mysql); + myquery(rc); + rc= mysql_query(mysql, "ROLLBACK"); + myquery(rc); + DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS)); + rc= mysql_query(mysql, "SELECT * FROM t1"); + myquery(rc); + DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS)); + rc= my_process_result(mysql); + DIE_UNLESS(rc == 1); + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); + rc= mysql_query(mysql, "SET GLOBAL query_cache_size = 0"); + myquery(rc); + + DBUG_VOID_RETURN; +} + +#endif + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -16652,6 +16709,9 @@ static struct my_tests_st my_tests[]= { { "test_bug40365", test_bug40365 }, #ifdef HAVE_SPATIAL { "test_bug37956", test_bug37956 }, +#endif +#ifdef HAVE_QUERY_CACHE + { "test_bug36326", test_bug36326 }, #endif { 0, 0 } }; -- cgit v1.2.1 From 075c7b354a40a94a9dd8de0d2169d59a037e34fc Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Wed, 14 Jan 2009 11:10:36 -0500 Subject: Fix comment. Boolean function returns true/false, not zero/one. --- sql/unireg.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/unireg.cc b/sql/unireg.cc index b581ad4655a..0aac7873d11 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -63,8 +63,8 @@ static bool make_empty_rec(THD *thd, int file, enum db_type table_type, db_file Handler to use. May be zero, in which case we use create_info->db_type RETURN - 0 ok - 1 error + false ok + true error */ bool mysql_create_frm(THD *thd, my_string file_name, -- cgit v1.2.1 From 23e62084c7dcf6141405320e9cfe2b851cedb99b Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Wed, 14 Jan 2009 11:11:31 -0500 Subject: Bug#38145: .frm file isn't sync'd with sync_frm enabled Views weren't sync()d the same way other structures were. In creating the FRM for views, obey the same rules for variable "sync_frm" as for everything else. --- sql/parse_file.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 2b947fcac4f..c9bbdfd417e 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -263,6 +263,11 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, if (end_io_cache(&file)) goto err_w_file; + if (opt_sync_frm) { + if (my_sync(handler, MYF(MY_WME))) + goto err_w_file; + } + if (my_close(handler, MYF(MY_WME))) { DBUG_RETURN(TRUE); -- cgit v1.2.1 From 9c68e0b3cb0c8fe160027339894d9d31b5aa0343 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 14 Jan 2009 20:16:10 +0100 Subject: Raise version number after cloning 5.0.76 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 06586d6487e..12c31b33d1b 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.76) +AM_INIT_AUTOMAKE(mysql, 5.0.78) 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=76 +NDB_VERSION_BUILD=78 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? -- cgit v1.2.1 From 5e1647245fc8dd8989191c28a7efee595b98722b Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Thu, 15 Jan 2009 00:14:07 +0100 Subject: Oops, bumped version too high. Drop it back down from 5.0.78 to 5.0.77. --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 12c31b33d1b..ff0e9de9ec2 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.78) +AM_INIT_AUTOMAKE(mysql, 5.0.77) 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=78 +NDB_VERSION_BUILD=77 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? -- cgit v1.2.1 From 3369c67d11f37ca1b23e15862f9e80cb9a06fe57 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Thu, 15 Jan 2009 12:36:34 +0300 Subject: Backport patch for Bug#31222 (com_% global status counters behave randomly with mysql_change_user) to 5.0. --- mysql-test/r/not_embedded_server.result | 7 +++++++ mysql-test/t/not_embedded_server.test | 28 ++++++++++++++++++++++++++++ sql/sql_class.cc | 4 ++++ 3 files changed, 39 insertions(+) diff --git a/mysql-test/r/not_embedded_server.result b/mysql-test/r/not_embedded_server.result index e471b5a3afa..edb698ade83 100644 --- a/mysql-test/r/not_embedded_server.result +++ b/mysql-test/r/not_embedded_server.result @@ -3,3 +3,10 @@ execute stmt1; 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 diff --git a/mysql-test/t/not_embedded_server.test b/mysql-test/t/not_embedded_server.test index 83ec03d6706..044d8665a18 100644 --- a/mysql-test/t/not_embedded_server.test +++ b/mysql-test/t/not_embedded_server.test @@ -16,3 +16,31 @@ execute stmt1; deallocate prepare stmt1; # End of 4.1 tests + +# +# Bug#31222: com_% global status counters behave randomly with +# mysql_change_user. +# + +FLUSH STATUS; + +--disable_result_log +--disable_query_log + +let $i = 100; + +while ($i) +{ + dec $i; + + SELECT 1; +} + +--enable_query_log +--enable_result_log + +SHOW GLOBAL STATUS LIKE 'com_select'; + +--change_user + +SHOW GLOBAL STATUS LIKE 'com_select'; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 883291ec460..91c0aa66761 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -391,6 +391,10 @@ void THD::init_for_queries() void THD::change_user(void) { + pthread_mutex_lock(&LOCK_status); + add_to_status(&global_status_var, &status_var); + pthread_mutex_unlock(&LOCK_status); + cleanup(); cleanup_done= 0; init(); -- cgit v1.2.1 From ae4d8dc69a578e917c1cffb19550afea57673570 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 22 Jan 2009 08:28:01 -0200 Subject: Bug#40264: Aborted cached query causes query to hang indefinitely on next cache hit The problem is that the query cache was storing partial results if the statement failed when sending the results to the client. This could cause clients to hang when trying to read the results from the cache as they would, for example, wait indefinitely for a eof packet that wasn't saved. The solution is to always discard the caching of a query that failed to send its results to the associated client. mysql-test/r/query_cache_notembedded.result: Add test case result for Bug#40264 mysql-test/t/query_cache_notembedded.test: Add test case for Bug#40264 sql/sql_cache.cc: Abort if a unreported error was raised. --- mysql-test/r/query_cache_notembedded.result | 16 +++++++++++++++ mysql-test/t/query_cache_notembedded.test | 31 +++++++++++++++++++++++++++++ sql/sql_cache.cc | 7 ++++++- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/query_cache_notembedded.result b/mysql-test/r/query_cache_notembedded.result index 8e5df012cfb..bf582bfaec6 100644 --- a/mysql-test/r/query_cache_notembedded.result +++ b/mysql-test/r/query_cache_notembedded.result @@ -345,3 +345,19 @@ id drop table t1; drop function f1; set GLOBAL query_cache_size=0; +DROP TABLE IF EXISTS t1; +FLUSH STATUS; +SET GLOBAL query_cache_size=1048576; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +SHOW STATUS LIKE 'Qcache_queries_in_cache'; +Variable_name Value +Qcache_queries_in_cache 0 +LOCK TABLES t1 WRITE; +SELECT * FROM t1; +UNLOCK TABLES; +SHOW STATUS LIKE 'Qcache_queries_in_cache'; +Variable_name Value +Qcache_queries_in_cache 0 +DROP TABLE t1; +SET GLOBAL query_cache_size= default; diff --git a/mysql-test/t/query_cache_notembedded.test b/mysql-test/t/query_cache_notembedded.test index a4f4144d9c6..c427e0d1afc 100644 --- a/mysql-test/t/query_cache_notembedded.test +++ b/mysql-test/t/query_cache_notembedded.test @@ -222,3 +222,34 @@ disconnect con2; connection default; set GLOBAL query_cache_size=0; + +# +# Bug#40264: Aborted cached query causes query to hang indefinitely on next cache hit +# + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +FLUSH STATUS; +SET GLOBAL query_cache_size=1048576; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +SHOW STATUS LIKE 'Qcache_queries_in_cache'; +LOCK TABLES t1 WRITE; +connect(con1,localhost,root,,); +--send SELECT * FROM t1 +connection default; +let $show_type= open tables where `table`='t1' and in_use=2; +let $show_pattern= '%t1%2%'; +--source include/wait_show_pattern.inc +dirty_close con1; +UNLOCK TABLES; +let $show_type= open tables where `table`='t1' and in_use=0; +let $show_pattern= '%t1%0%'; +--source include/wait_show_pattern.inc +SHOW STATUS LIKE 'Qcache_queries_in_cache'; +DROP TABLE t1; +SET GLOBAL query_cache_size= default; + +# End of 5.0 tests diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 4a521d83192..b55fa148e24 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -710,7 +710,12 @@ void query_cache_end_of_result(THD *thd) if (thd->net.query_cache_query == 0) DBUG_VOID_RETURN; - if (thd->killed) + /* + Check if the NET layer raised a unreported error -- my_error() and + as a consequence query_cache_abort() haven't been called. Abort the + cached result as it might be only partially complete. + */ + if (thd->killed || thd->net.report_error) { query_cache_abort(&thd->net); DBUG_VOID_RETURN; -- cgit v1.2.1 From 47dd10877011aed029e1fc8faa5588522fb5d3a9 Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Fri, 23 Jan 2009 02:59:03 +0100 Subject: From 5.0.48 the NDB client libraries has been missing in the cluster packages, this is now corrected (Bug#42278) --- scripts/make_binary_distribution.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index e5e08038bff..f156ea3b986 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -372,8 +372,8 @@ fi # NDB Cluster if [ x$NDBCLUSTER = x1 ]; then - ( cd ndb ; @MAKE@ DESTDIR=$BASE/ndb-stage install ) - ( cd mysql-test/ndb ; @MAKE@ DESTDIR=$BASE/ndb-stage install ) + ( cd ndb ; @MAKE@ DESTDIR=$BASE/ndb-stage install pkglibdir=@pkglibdir@ ) + ( cd mysql-test/ndb ; @MAKE@ DESTDIR=$BASE/ndb-stage install pkglibdir=@pkglibdir@ ) $CP $BASE/ndb-stage@bindir@/* $BASE/bin/. $CP $BASE/ndb-stage@libexecdir@/* $BASE/bin/. $CP $BASE/ndb-stage@pkglibdir@/* $BASE/lib/. -- cgit v1.2.1 From d6c8d3062b4b1cfee14efa28a6bb40d257cc9133 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Mon, 26 Jan 2009 22:06:42 +0100 Subject: Backport of a fix done by Kent for bug#42278 into the 5.0.72sp1 branch. Original changeset (in the main 5.0 branch): > committer: Kent Boortz > branch nick: mysql-5.0-build-bug42278 > timestamp: Fri 2009-01-23 02:59:03 +0100 scripts/make_binary_distribution.sh: From 5.0.48 the NDB client libraries has been missing in the cluster packages, this is now corrected (Bug#42278) --- scripts/make_binary_distribution.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index e5e08038bff..f156ea3b986 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -372,8 +372,8 @@ fi # NDB Cluster if [ x$NDBCLUSTER = x1 ]; then - ( cd ndb ; @MAKE@ DESTDIR=$BASE/ndb-stage install ) - ( cd mysql-test/ndb ; @MAKE@ DESTDIR=$BASE/ndb-stage install ) + ( cd ndb ; @MAKE@ DESTDIR=$BASE/ndb-stage install pkglibdir=@pkglibdir@ ) + ( cd mysql-test/ndb ; @MAKE@ DESTDIR=$BASE/ndb-stage install pkglibdir=@pkglibdir@ ) $CP $BASE/ndb-stage@bindir@/* $BASE/bin/. $CP $BASE/ndb-stage@libexecdir@/* $BASE/bin/. $CP $BASE/ndb-stage@pkglibdir@/* $BASE/lib/. -- cgit v1.2.1 From 2b2a5fb7a17327d8ddb34fad390b52ed2833f5fb Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 28 Jan 2009 14:14:05 +0100 Subject: Bug #42216 mysqltest: Use of diff belonging to current OS, with wrong option for Solaris Check for existence of diff fails on Solaris due to unsupported "-v" Fix is to do this check only on Windows where it was needed --- client/mysqltest.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 62ec5a88599..d7fbb6f1f18 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1385,8 +1385,15 @@ void show_diff(DYNAMIC_STRING* ds, /* determine if we have diff on Windows needs special processing due to return values on that OS + This test is only done on Windows since it's only needed there + in order to correctly detect non-availibility of 'diff', and + the way it's implemented does not work with default 'diff' on Solaris. */ +#ifdef __WIN__ have_diff = diff_check(); +#else + have_diff = 1; +#endif if (have_diff) { @@ -1410,7 +1417,7 @@ void show_diff(DYNAMIC_STRING* ds, "2>&1", NULL) > 1) /* Most "diff" tools return >1 if error */ { - have_diff= 1; + have_diff= 0; } } } -- cgit v1.2.1 From 5c1975fa42c23081a79e5ff4e58cb9856d081561 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 28 Jan 2009 16:18:50 +0200 Subject: Bug #42366: server-cert.pem expired: "Not After : Jan 27 08:54:13 2009 GMT" Re-generated the PKI files needed. Removed the ones that are not needed. Updated the tests to reference the correct SSL subject. mysql-test/r/openssl_1.result: Bug #42366: Updated the tests to reference the correct SSL subject mysql-test/std_data/cacert.pem: Bug #42366: Re-generated the PKI files needed. mysql-test/std_data/client-cert.pem: Bug #42366: Re-generated the PKI files needed. mysql-test/std_data/client-key.pem: Bug #42366: Re-generated the PKI files needed. mysql-test/std_data/server-cert-des.pem: Bug #42366: Removed the ones that are not needed. mysql-test/std_data/server-cert.pem: Bug #42366: Re-generated the PKI files needed. mysql-test/std_data/server-key-des.pem: Bug #42366: Removed the ones that are not needed. mysql-test/std_data/server-key.pem: Bug #42366: Re-generated the PKI files needed. mysql-test/std_data/server8k-cert.pem: Bug #42366: Re-generated the PKI files needed. mysql-test/std_data/server8k-key.pem: Bug #42366: Re-generated the PKI files needed. mysql-test/t/openssl_1.test: Bug #42366: Updated the tests to reference the correct SSL subject --- mysql-test/r/openssl_1.result | 4 +- mysql-test/std_data/cacert.pem | 24 ++-- mysql-test/std_data/client-cert.pem | 75 +++++++----- mysql-test/std_data/client-key.pem | 14 +-- mysql-test/std_data/server-cert-des.pem | 16 --- mysql-test/std_data/server-cert.pem | 73 +++++++----- mysql-test/std_data/server-key-des.pem | 18 --- mysql-test/std_data/server-key.pem | 14 +-- mysql-test/std_data/server8k-cert.pem | 185 ++++++++++++++++++++++-------- mysql-test/std_data/server8k-key.pem | 194 ++++++++++++++++---------------- mysql-test/t/openssl_1.test | 4 +- 11 files changed, 350 insertions(+), 271 deletions(-) delete mode 100644 mysql-test/std_data/server-cert-des.pem delete mode 100644 mysql-test/std_data/server-key-des.pem diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result index 9c6c29eea47..3e87b5b76b3 100644 --- a/mysql-test/r/openssl_1.result +++ b/mysql-test/r/openssl_1.result @@ -3,8 +3,8 @@ create table t1(f1 int); insert into t1 values (5); grant select on test.* to ssl_user1@localhost require SSL; grant select on test.* to ssl_user2@localhost require cipher "DHE-RSA-AES256-SHA"; -grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com"; -grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com"; +grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; grant select on test.* to ssl_user5@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "xxx"; flush privileges; connect(localhost,ssl_user5,,test,MASTER_PORT,MASTER_SOCKET); diff --git a/mysql-test/std_data/cacert.pem b/mysql-test/std_data/cacert.pem index b445e77d7c4..5473e4b153e 100644 --- a/mysql-test/std_data/cacert.pem +++ b/mysql-test/std_data/cacert.pem @@ -1,17 +1,17 @@ -----BEGIN CERTIFICATE----- -MIICrTCCAhagAwIBAgIJAIAO/Ybiptv1MA0GCSqGSIb3DQEBBAUAMEQxCzAJBgNV +MIICrTCCAhagAwIBAgIJAJXpePU0UOTVMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV BAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxhMREwDwYD -VQQKEwhNeVNRTCBBQjAeFw0wNjA1MDMwODQ4NTRaFw0wOTAxMjcwODQ4NTRaMEQx +VQQKEwhNeVNRTCBBQjAeFw0wOTAxMjgxMDQ5NDZaFw0xNDAxMjcxMDQ5NDZaMEQx CzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxh MREwDwYDVQQKEwhNeVNRTCBBQjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA -+C46EQl1u7tQ6gb9eqc8V079gr8YmDPCEqtjO8bCIbchpjOpDITx0WZz36Sn9E72 -GPJwNip4FxLaPRIA3xNQHM5cE5U53qznlRx1Fc4O3hcWCvyCqNDl/vzPAh3pI6Bl -Ku9hfHXpp93W812smVPe9haShEXGgbEPYGzvOfVdu/MCAwEAAaOBpjCBozAdBgNV -HQ4EFgQUjIy/6OCTmqtPHBFha6/qzVk3yTcwdAYDVR0jBG0wa4AUjIy/6OCTmqtP -HBFha6/qzVk3yTehSKRGMEQxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxh -MRAwDgYDVQQHEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQoIJAIAO/Ybiptv1 -MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEA8lD9zyB820Oq1aj7ZafX -De/hbdt9RIl2tzgw2K3r1KZGdXJVL0vSt5fZ51Nq9lg7OPJy3iXf+caBJEp0IJpB -uf4Gfr6zfXw+UlY6ZthRtHQHoXKcbskECjH5/ps/Uaa+dpVQ9O+Ii1rPzmgo6ztM -s+xZ46ESBt4WiHXm8kwbU9Y= +4XQHAe5R1+TXC8noZtWf+d5E0v1C59FWpn9SWEUCBjE5UiIwuJvi4Y+7xWGOXLAI +/JzJx5gNXLBiTsE/zh0uX9fKlajLhxB0GN+QU0ZlpQ1BeYipEcNXeI/7cT499f6v +XWabnTflivdCgHSWUOQ20/Lzs6kP6/e6OoZd/DPSjPECAwEAAaOBpjCBozAdBgNV +HQ4EFgQU8uLqVWWkmuKsnZf1RWz294wRrd8wdAYDVR0jBG0wa4AU8uLqVWWkmuKs +nZf1RWz294wRrd+hSKRGMEQxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxh +MRAwDgYDVQQHEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQoIJAJXpePU0UOTV +MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAMMTE5sDN+Z0ZlV7KvH3g +6+aKvql8dTpRT3hYukeQlWua0nq74WPGVw0c4e/M/vbiMwmJcCYpB9pd4+dHqzSw +aPyoenjY6UF8n7B4quWy3SIUk2LSHeJLW+kzJn2afN9gvipFhdVh/uU2TIyLGOur +Z/vmJX2W7hF1uqPnbfa8Lrw= -----END CERTIFICATE----- diff --git a/mysql-test/std_data/client-cert.pem b/mysql-test/std_data/client-cert.pem index fdd5c86a23f..9300520793e 100644 --- a/mysql-test/std_data/client-cert.pem +++ b/mysql-test/std_data/client-cert.pem @@ -1,42 +1,55 @@ Certificate: Data: - Version: 1 (0x0) - Serial Number: 1 (0x1) - Signature Algorithm: md5WithRSAEncryption + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: sha1WithRSAEncryption Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB Validity - Not Before: May 3 08:55:39 2006 GMT - Not After : Jan 27 08:55:39 2009 GMT - Subject: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com + Not Before: Jan 28 11:04:39 2009 GMT + Not After : Jan 28 11:04:39 2010 GMT + Subject: C=SE, ST=Uppsala, O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (512 bit) Modulus (512 bit): - 00:d8:db:68:28:49:84:4d:d6:0f:5c:bc:3d:9a:ab: - 70:d5:3e:f5:b5:17:ba:ef:e1:f8:87:54:30:22:1f: - 81:07:bf:f9:24:7f:8a:54:10:e9:5f:e6:99:50:04: - d4:3b:55:a9:f1:52:ad:12:2b:5a:da:5c:be:8c:3e: - 5b:9e:b0:5a:19 + 00:e1:52:30:2c:d9:be:64:28:91:5d:7a:fd:d9:e9: + 14:35:7a:d2:94:4e:91:46:e0:db:9f:6b:79:f4:4c: + ac:6e:07:61:34:86:74:62:a7:a8:44:af:fa:87:87: + a8:7d:42:61:ff:ab:50:d4:7b:bf:75:fa:d5:d5:b3: + 74:fb:56:1e:37 Exponent: 65537 (0x10001) - Signature Algorithm: md5WithRSAEncryption - 07:57:bf:07:92:c2:8e:86:24:6b:0a:bf:e5:31:21:44:c3:60: - 02:a6:ac:9e:f7:db:7a:6e:fc:4f:d4:7b:54:18:80:47:d2:4a: - 63:0e:e3:f8:af:6e:58:e3:97:5a:2b:82:5d:76:20:d1:33:a0: - f5:43:a1:d1:51:f4:ca:c8:b3:1a:66:4e:0e:55:df:d2:e8:fa: - 83:18:42:f5:ec:66:40:f0:39:e8:f9:d7:cf:f6:dd:e4:7b:69: - dd:0c:92:d8:52:95:43:6f:29:3d:f0:8d:4c:dd:52:ea:6b:a0: - 39:0f:dc:59:a7:5c:37:6b:8b:05:44:b7:69:ea:a3:58:e0:4e: - ce:d6 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 58:30:B5:9B:2C:05:94:06:BA:3D:3C:F0:B2:CD:1D:67:65:E3:7F:85 + X509v3 Authority Key Identifier: + keyid:F2:E2:EA:55:65:A4:9A:E2:AC:9D:97:F5:45:6C:F6:F7:8C:11:AD:DF + DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB + serial:95:E9:78:F5:34:50:E4:D5 + + Signature Algorithm: sha1WithRSAEncryption + 05:19:e3:13:14:fc:c5:28:bf:69:f8:00:b3:25:cb:bd:ca:9f: + 2f:4c:b3:a8:04:11:f0:74:27:bd:82:2c:b4:49:9b:a7:59:f0: + f7:87:d1:e0:ba:99:a2:fe:4b:1d:10:6f:e4:a2:b3:cd:7f:8b: + 68:31:46:ee:cd:9e:e2:47:e1:4c:fa:74:d1:e2:8b:cc:a0:4b: + a8:24:d1:a4:c3:6b:2a:c6:28:cd:41:e0:06:48:e6:cf:f2:3c: + ca:37:95:d7:29:64:6b:91:91:83:e7:ac:c8:0b:87:bc:da:a6: + aa:f1:44:43:c8:74:7b:15:26:91:2e:03:c4:71:50:6c:f8:68: + dc:8c -----BEGIN CERTIFICATE----- -MIIB5jCCAU8CAQEwDQYJKoZIhvcNAQEEBQAwRDELMAkGA1UEBhMCU0UxEDAOBgNV -BAgTB1VwcHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFC -MB4XDTA2MDUwMzA4NTUzOVoXDTA5MDEyNzA4NTUzOVowdzELMAkGA1UEBhMCU0Ux -EDAOBgNVBAgTB1VwcHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15 -U1FMIEFCMTEwLwYJKoZIhvcNAQkBFiJhYnN0cmFjdC5teXNxbC5kZXZlbG9wZXJA -bXlzcWwuY29tMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANjbaChJhE3WD1y8PZqr -cNU+9bUXuu/h+IdUMCIfgQe/+SR/ilQQ6V/mmVAE1DtVqfFSrRIrWtpcvow+W56w -WhkCAwEAATANBgkqhkiG9w0BAQQFAAOBgQAHV78HksKOhiRrCr/lMSFEw2ACpqye -99t6bvxP1HtUGIBH0kpjDuP4r25Y45daK4JddiDRM6D1Q6HRUfTKyLMaZk4OVd/S -6PqDGEL17GZA8Dno+dfP9t3ke2ndDJLYUpVDbyk98I1M3VLqa6A5D9xZp1w3a4sF -RLdp6qNY4E7O1g== +MIICfzCCAeigAwIBAgIBAzANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ +MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT +UUwgQUIwHhcNMDkwMTI4MTEwNDM5WhcNMTAwMTI4MTEwNDM5WjBlMQswCQYDVQQG +EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxMTAvBgkq +hkiG9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wXDAN +BgkqhkiG9w0BAQEFAANLADBIAkEA4VIwLNm+ZCiRXXr92ekUNXrSlE6RRuDbn2t5 +9EysbgdhNIZ0YqeoRK/6h4eofUJh/6tQ1Hu/dfrV1bN0+1YeNwIDAQABo4GjMIGg +MAkGA1UdEwQCMAAwHQYDVR0OBBYEFFgwtZssBZQGuj088LLNHWdl43+FMHQGA1Ud +IwRtMGuAFPLi6lVlpJrirJ2X9UVs9veMEa3foUikRjBEMQswCQYDVQQGEwJTRTEQ +MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT +UUwgQUKCCQCV6Xj1NFDk1TANBgkqhkiG9w0BAQUFAAOBgQAFGeMTFPzFKL9p+ACz +Jcu9yp8vTLOoBBHwdCe9giy0SZunWfD3h9Hgupmi/ksdEG/korPNf4toMUbuzZ7i +R+FM+nTR4ovMoEuoJNGkw2sqxijNQeAGSObP8jzKN5XXKWRrkZGD56zIC4e82qaq +8URDyHR7FSaRLgPEcVBs+GjcjA== -----END CERTIFICATE----- diff --git a/mysql-test/std_data/client-key.pem b/mysql-test/std_data/client-key.pem index 22f8e23ab2a..9ef464d0875 100644 --- a/mysql-test/std_data/client-key.pem +++ b/mysql-test/std_data/client-key.pem @@ -1,9 +1,9 @@ -----BEGIN RSA PRIVATE KEY----- -MIIBOgIBAAJBANjbaChJhE3WD1y8PZqrcNU+9bUXuu/h+IdUMCIfgQe/+SR/ilQQ -6V/mmVAE1DtVqfFSrRIrWtpcvow+W56wWhkCAwEAAQJAK27WT6tZylUjQomZNQ89 -TBiOEbUtBbqWklQ0R8FTkH9uKV+8KYQ+k+tMkoAEGFfChB0YfofNQ2KZYWWw4yOB -WQIhAPXXDQt73aou10s+cmKM3C3WzLmIZtrvm9wNBXWDGxgTAiEA4dG4cXrZfa1M -TTbjzNU1/Jf50/M8SvZDWMPQWxJ8oqMCIH6zBpYUkHlVCsBMvsbrsc4uFfTIx7mu -I7WVQGr/1sbhAiBf4uFirjtztgZUMx5/d3k5DH80lG/hlLf8FQl/4lWx6QIhAPHw -CXfPUbUFl4r/i9Br5+exGol50qX4F3aP5Sh5EnZT +MIIBOQIBAAJBAOFSMCzZvmQokV16/dnpFDV60pROkUbg259refRMrG4HYTSGdGKn +qESv+oeHqH1CYf+rUNR7v3X61dWzdPtWHjcCAwEAAQJAXYooM8ZlcuEgj+VKU1ee +qyEFIMqJJxqcMk+E/nWCM96WxCP3zHNSrqNfSpI3ld7QzMwhdRz+gFLxT2gGNpIw +MQIhAPxzM/lDihe67X3ADYtDl9ZjA8Pm430x9sXlcxI17tCZAiEA5H1SyFl4mUee +9VnfSC2XGW7lwz72ZygfVX+b7tLWF08CIEh40gzW5MfXM+KLxdea+fXjyursV5ZT +R6KcMiKiNQLRAiAcmHqlzFzFgisotai2Fc6VRkXHG7gmzOSvBJt1VjmpDQIge6jf +2N7whTdvC4ferB+zUlgWQdyvx1c3T4gnt6PYdaY= -----END RSA PRIVATE KEY----- diff --git a/mysql-test/std_data/server-cert-des.pem b/mysql-test/std_data/server-cert-des.pem deleted file mode 100644 index 3b93d865d5b..00000000000 --- a/mysql-test/std_data/server-cert-des.pem +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICljCCAX4CAQEwDQYJKoZIhvcNAQEEBQAwUTELMAkGA1UEBhMCU0UxEDAOBgNV -BAgTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMRAwDgYDVQQLEwdTdXBwb3J0 -MQswCQYDVQQDEwJDQTAeFw0wNjA4MjgxMTA4NTlaFw0wOTA1MjQxMTA4NTlaMFUx -CzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBB -QjEQMA4GA1UECxMHU3VwcG9ydDEPMA0GA1UEAxMGc2VydmVyMIGfMA0GCSqGSIb3 -DQEBAQUAA4GNADCBiQKBgQDEiOVZcWYzZe7I8xhhUwCzvmkZifAXeMTH+8XKGLHX -NWF3FLduAmeAad9oOZgBKb+oWTdRDWXqwu6nYYUBfrUpaY27/wLkgWRgewL3LZnw -W2FjhNsjx3gI2NK+Pix47q9d+a+5T4AW5+lK499l0K0k2cvyFdIerhDW8R0t8Uru -twIDAQABMA0GCSqGSIb3DQEBBAUAA4IBAQC2LQcqLg52RbelWrKutlJ5E6rzugnJ -ZAlbN9sM98O2xFiIGDA3tb5j9LAEjE0E+RqdptEYnvy9b3szhLYXtIILZTkClf9r -Uwu1nUYPTyp+9ZYCa4fovOU5h1Ogv+9UZPds/LPDwWEn8K+lvscB4X57wJyuoEck -1Mu41OA6h77181MydSdgZo0oquJDWhdCsYHXVFVs0F6naMm2uPMCTDiQVlhHJuTO -VQMNIwxRFtvsv2tpsXsaP/8sT32d5CFebfxxSVnqQvJ4ZdIrphl6L43XU01rsEcE -K8KYujZQ6SKws+HVcGqsr7TPgJfJE6D+5RazvvIQISPvx4eduebqzqdC ------END CERTIFICATE----- diff --git a/mysql-test/std_data/server-cert.pem b/mysql-test/std_data/server-cert.pem index f420b4f3124..cab54db8b23 100644 --- a/mysql-test/std_data/server-cert.pem +++ b/mysql-test/std_data/server-cert.pem @@ -1,42 +1,55 @@ Certificate: Data: - Version: 1 (0x0) + Version: 3 (0x2) Serial Number: 1 (0x1) - Signature Algorithm: md5WithRSAEncryption + Signature Algorithm: sha1WithRSAEncryption Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB Validity - Not Before: May 3 08:54:13 2006 GMT - Not After : Jan 27 08:54:13 2009 GMT - Subject: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB, CN=localhost/emailAddress=abstract.mysql.developer@mysql.com + Not Before: Jan 28 10:55:13 2009 GMT + Not After : Jan 28 10:55:13 2010 GMT + Subject: C=SE, ST=Uppsala, O=MySQL AB, CN=localhost/emailAddress=abstract.mysql.developer@mysql.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (512 bit) Modulus (512 bit): - 00:d9:fd:da:b3:fb:7c:e0:b0:03:be:97:c6:a4:36: - ac:71:af:bb:2d:e5:84:ed:f3:8f:2b:eb:11:e5:aa: - 66:ed:bf:62:6b:e3:ce:fa:80:ed:90:ff:b9:4a:39: - 20:40:b6:f2:99:bf:2f:33:b5:f2:ec:3a:90:60:1d: - 9e:94:7e:a4:1b + 00:b6:8f:e5:b7:b4:86:83:13:8a:f9:bf:63:cb:64: + 2d:b9:51:d1:de:ab:7b:45:1f:aa:b5:66:73:13:f9: + a6:07:d5:ba:7c:fa:92:bd:37:e2:ad:87:db:3e:b6: + 6a:12:64:f8:ee:17:e3:15:06:2f:a8:82:68:bf:57: + 8d:c3:04:98:27 Exponent: 65537 (0x10001) - Signature Algorithm: md5WithRSAEncryption - de:5e:35:cd:7b:11:e6:7c:c5:7c:d6:27:4e:72:12:49:42:eb: - 6f:2c:96:f3:f4:00:78:a7:4f:9f:2d:7b:d7:30:39:af:49:4d: - df:b1:55:0d:30:be:23:6f:06:67:fd:dd:ba:98:66:36:c6:32: - b7:ed:63:fc:aa:49:cd:4f:72:98:3b:13:0e:f6:28:d7:d4:eb: - 04:6b:dc:e8:c7:04:80:92:e4:04:86:0b:ed:32:25:76:1d:a9: - 5c:a9:2c:18:2c:bd:bc:15:ed:e1:76:96:4d:bb:0d:41:44:06: - 2c:ad:45:bb:db:61:ad:17:11:cb:49:70:67:eb:c6:27:d3:91: - c8:f2 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + D9:9A:B8:5F:22:EA:04:10:C8:25:7D:82:57:E6:2E:FD:19:29:E7:DA + X509v3 Authority Key Identifier: + keyid:F2:E2:EA:55:65:A4:9A:E2:AC:9D:97:F5:45:6C:F6:F7:8C:11:AD:DF + DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB + serial:95:E9:78:F5:34:50:E4:D5 + + Signature Algorithm: sha1WithRSAEncryption + 54:07:2d:21:0b:a5:af:3b:58:23:32:5e:56:7f:ab:58:63:48: + 91:aa:38:90:89:16:f9:cc:bf:a4:0e:78:2b:9f:c5:1b:58:a6: + e6:08:8f:2e:ae:97:03:21:9b:f1:cd:c0:26:8f:1d:d7:28:27: + a0:8e:81:09:1b:1c:0f:c9:a5:41:3a:2d:44:3f:9c:fa:87:ff: + c8:4c:2b:44:f7:1b:c1:3e:4f:01:7f:e9:26:cc:9f:1c:06:b5: + 0b:27:d1:10:90:be:93:0c:9c:e7:b0:d1:ea:27:99:4e:06:14: + 0c:7a:e9:c1:52:c5:33:68:bc:61:0d:db:81:3b:57:48:57:bf: + 42:9a -----BEGIN CERTIFICATE----- -MIIB+zCCAWQCAQEwDQYJKoZIhvcNAQEEBQAwRDELMAkGA1UEBhMCU0UxEDAOBgNV -BAgTB1VwcHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFC -MB4XDTA2MDUwMzA4NTQxM1oXDTA5MDEyNzA4NTQxM1owgYsxCzAJBgNVBAYTAlNF -MRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxhMREwDwYDVQQKEwhN -eVNRTCBBQjESMBAGA1UEAxMJbG9jYWxob3N0MTEwLwYJKoZIhvcNAQkBFiJhYnN0 -cmFjdC5teXNxbC5kZXZlbG9wZXJAbXlzcWwuY29tMFwwDQYJKoZIhvcNAQEBBQAD -SwAwSAJBANn92rP7fOCwA76XxqQ2rHGvuy3lhO3zjyvrEeWqZu2/YmvjzvqA7ZD/ -uUo5IEC28pm/LzO18uw6kGAdnpR+pBsCAwEAATANBgkqhkiG9w0BAQQFAAOBgQDe -XjXNexHmfMV81idOchJJQutvLJbz9AB4p0+fLXvXMDmvSU3fsVUNML4jbwZn/d26 -mGY2xjK37WP8qknNT3KYOxMO9ijX1OsEa9zoxwSAkuQEhgvtMiV2HalcqSwYLL28 -Fe3hdpZNuw1BRAYsrUW722GtFxHLSXBn68Yn05HI8g== +MIICkzCCAfygAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ +MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT +UUwgQUIwHhcNMDkwMTI4MTA1NTEzWhcNMTAwMTI4MTA1NTEzWjB5MQswCQYDVQQG +EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxEjAQBgNV +BAMTCWxvY2FsaG9zdDExMC8GCSqGSIb3DQEJARYiYWJzdHJhY3QubXlzcWwuZGV2 +ZWxvcGVyQG15c3FsLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC2j+W3tIaD +E4r5v2PLZC25UdHeq3tFH6q1ZnMT+aYH1bp8+pK9N+Kth9s+tmoSZPjuF+MVBi+o +gmi/V43DBJgnAgMBAAGjgaMwgaAwCQYDVR0TBAIwADAdBgNVHQ4EFgQU2Zq4XyLq +BBDIJX2CV+Yu/Rkp59owdAYDVR0jBG0wa4AU8uLqVWWkmuKsnZf1RWz294wRrd+h +SKRGMEQxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdV +cHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQoIJAJXpePU0UOTVMA0GCSqGSIb3DQEB +BQUAA4GBAFQHLSELpa87WCMyXlZ/q1hjSJGqOJCJFvnMv6QOeCufxRtYpuYIjy6u +lwMhm/HNwCaPHdcoJ6COgQkbHA/JpUE6LUQ/nPqH/8hMK0T3G8E+TwF/6SbMnxwG +tQsn0RCQvpMMnOew0eonmU4GFAx66cFSxTNovGEN24E7V0hXv0Ka -----END CERTIFICATE----- diff --git a/mysql-test/std_data/server-key-des.pem b/mysql-test/std_data/server-key-des.pem deleted file mode 100644 index b35d4ab223b..00000000000 --- a/mysql-test/std_data/server-key-des.pem +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,D2BE7598C7E3BDA5 - -1W3qPgw5ut80OhaAGVZZe/tfFiBAlwpX1SohdApWj+QYP+dK/mdEBhgI3BXTFNLW -pJqDTzGlKtft7hHN6QDFEdZMKxej5+2iLu14V62o+5yQgUoqswoXcmmqJCJ7AvyJ -yMBmGAzxRFlQsT8lf6o5TS1/efBvjvWhh3NG2Zq2LpyhWRRqA3kNhzktzt2WjDZe -ZkKmZJJnArr/Aw7jEBC4sH+nmgxoR18GzDddRG12hv1AWyHc3+VisTBpyNzeBy17 -rxuQtqLzkAJmId723ddw83RVNSvBUUS3G0rx5O3HPobvZK89UqVxcXtIgc11WTVU -N3DbcJq5it43Loo0W3gAngtESDm2E3rTadrmdUSDGv2wQ5dNFl6cQ1f397Sdd/WC -A0grn1tKjJ6COp80Ymdyvn+stjv/+Rl1/KHSeG0lNeZxqjPPOJ7NHaKv7qjYsJ6W -LT35/Xc3oCo5qk9FOlq/0tGjHxf6RcFr5U7k5ILKZs+RmvJ4Sv/VYShLfLTcfGbJ -wBNfRKvcHZBQJQBb1+s/kRrjFFtvhrUwLz4+c9kskp+t4qRVYywUAnGGGsMs/GPm -wYsLQZO6Bs5/taaVUyaJQW015J7FGGv+/7/A1dIhu73S/Xl/YcFbX/CMEVq2Lxxd -hZdFIuaZ7LE+0MDQWsvYMYPDPLDH11diczb/jeKBdLPOzk/FUqVx3Fin1PpcaBxY -b+7oZJhYdg/rAWDeQ/nji9qnEG8waK6x1hdkYPOrqqWQPfgM/LPsSrgWeuTSdx2B -Ixi01UlBb5UP4K7UrjyddPobmcVjXaQLNe7zaq0+OS3UnIG85GtHrQ== ------END RSA PRIVATE KEY----- diff --git a/mysql-test/std_data/server-key.pem b/mysql-test/std_data/server-key.pem index a4842624c0c..0d8274b77f6 100644 --- a/mysql-test/std_data/server-key.pem +++ b/mysql-test/std_data/server-key.pem @@ -1,9 +1,9 @@ -----BEGIN RSA PRIVATE KEY----- -MIIBOgIBAAJBANn92rP7fOCwA76XxqQ2rHGvuy3lhO3zjyvrEeWqZu2/YmvjzvqA -7ZD/uUo5IEC28pm/LzO18uw6kGAdnpR+pBsCAwEAAQJBAMieYdpmRoUaODf9wqh6 -ULXH/sG8i1vaXRcUHcJ50oRVfVK8/tGGvUuTDu6MeINTdahNDlYfjwOjKWVXys1w -h6ECIQDs6s7DfczK2bKCLt0zqg24mZL3rOpGmDU+TatwN1yVgwIhAOuMzdVTX39p -328+5WxJvBOFfxmSmqdDhIFpnRMvgguJAiByvKjT/km+970+1OllyvaIL0AA2OpA -tBgdC0p6tyUMdwIgKuHAWzTJbu28UolVxQgLaFZmVCZ/ZzIAfnrWsLZ2a1kCIBq/ -ywJ2cpyFlgazu8AH6KCQa0ok9s70ElaB6FEC85Al +MIIBOQIBAAJBALaP5be0hoMTivm/Y8tkLblR0d6re0UfqrVmcxP5pgfVunz6kr03 +4q2H2z62ahJk+O4X4xUGL6iCaL9XjcMEmCcCAwEAAQJASA5VwgNb0CKHiPm0ntOk +hG+54SRX3DmafEy6gRjZIl/bZ/asSLhXUZ+CeohyrQh7BZgYWvykd8pRISL9eKsU +GQIhAOXkUrOtP/EtjyqNluEqZdG+RZi/7p61JS3Ce13Myu+LAiEAy0uMlV34AJpM +b40FPKqlHxw8DD/Dt1iKhNVAg8+LDVUCIFjv7fbJDbW2VG63/Cj8CAwOukoP5rbL +iaicVrHBKrllAiB9+MiaXeopZXNrxDS0jQFYr8Q9yt1aJVFgUkxx4Q9HKQIgZPs0 +KlF3NNNWw78INaAEkyf0IEssnLMsuoCWw0DIOak= -----END RSA PRIVATE KEY----- diff --git a/mysql-test/std_data/server8k-cert.pem b/mysql-test/std_data/server8k-cert.pem index a0750f9e69e..3b86effd699 100644 --- a/mysql-test/std_data/server8k-cert.pem +++ b/mysql-test/std_data/server8k-cert.pem @@ -1,51 +1,138 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4 (0x4) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB + Validity + Not Before: Jan 28 11:12:27 2009 GMT + Not After : Jan 28 11:12:27 2010 GMT + Subject: C=SE, ST=Uppsala, O=MySQL AB, CN=server + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (8192 bit) + Modulus (8192 bit): + 00:c0:8f:22:03:24:59:67:46:14:d6:8f:60:09:58: + 06:07:45:f1:78:71:55:f1:ea:b9:30:8a:cd:c3:3c: + b9:bf:65:6e:18:ed:a0:b8:c9:19:56:6f:c4:90:19: + c8:65:09:db:ff:bf:82:a1:08:ad:01:4f:5a:a3:d4: + 3d:78:7e:4b:4a:01:a4:7d:e8:7b:05:3e:7d:d8:b9: + 55:58:60:d6:1c:ce:e8:32:62:2c:19:60:f3:ed:05: + 99:6d:c9:77:07:2e:11:6d:0b:9a:c7:68:38:46:e8: + fa:31:80:df:e8:79:f0:f1:fd:a9:94:c3:fa:0d:f5: + 78:ac:49:7e:d5:17:fd:e1:ee:44:f3:c7:0e:30:32: + 5d:a9:19:25:e4:bb:21:1d:fe:3c:84:48:40:f5:58: + f4:bf:13:8c:85:68:bb:ec:f5:dd:c6:38:d1:b0:77: + 1f:a6:8e:4f:8d:e2:6f:49:74:f5:3f:90:65:8e:99: + 1e:59:9c:1c:b5:26:24:c4:b1:de:1e:fb:96:65:c4: + 31:14:1a:53:b8:5e:62:8a:c7:04:f7:b4:36:a4:af: + 07:c8:27:06:ed:dd:e6:f4:8c:62:f1:65:40:d0:9f: + 9f:a9:14:c8:8e:8b:74:d6:67:5a:d0:c9:4d:35:a1: + d5:7b:39:3a:42:9f:e4:d0:f4:c6:0f:2e:42:30:4b: + 56:b2:3d:6d:8e:2d:58:c5:69:99:35:49:95:95:99: + b6:87:29:2b:32:d1:50:08:cd:25:14:48:6d:10:99: + 85:61:3c:41:26:21:55:cc:1f:cf:ad:b0:2f:b9:89: + d8:4e:a0:18:ff:75:1d:b6:97:7c:c5:fa:8b:dc:93: + 17:86:0a:64:d4:09:35:d5:83:34:6d:5c:6d:c6:8c: + cd:b9:ec:c2:93:c6:c1:b7:cc:04:6f:22:e0:07:bf: + e0:d9:9b:2f:d5:a0:50:cc:f9:f0:95:83:8f:f4:30: + 83:72:94:d7:b5:4b:da:cc:9f:54:3b:8d:78:77:0b: + 24:6c:0f:c2:96:61:96:2f:b8:5f:b5:7a:ab:7a:5b: + 97:7a:a9:ad:40:8b:f2:d6:c6:8d:81:d9:94:61:8f: + 9d:03:c5:b9:10:03:68:83:bf:04:81:cc:ac:bd:34: + 89:e8:d4:8d:43:20:e2:b6:a4:11:3d:15:2a:82:0c: + d6:3a:6a:8c:62:d4:93:bc:c3:80:bf:1b:b4:2b:0a: + 7a:34:f0:cd:1e:82:3f:25:0f:d1:04:a8:0a:05:19: + b0:d6:16:83:39:af:0b:45:7d:cb:14:7e:4d:aa:aa: + c2:39:a8:46:38:ab:bd:ab:2a:bd:34:43:7f:da:25: + de:2b:fb:69:3b:fe:3b:87:fd:98:94:76:4a:bf:04: + a3:31:e3:3a:ff:6f:04:fa:fa:24:e4:2a:89:e9:0e: + bf:44:4c:72:85:82:3c:89:4a:03:63:01:41:92:53: + d0:82:60:6e:d8:ff:8c:a2:b4:1a:3b:20:6d:ae:74: + 92:30:4e:48:e3:51:a6:cb:73:97:06:13:03:32:23: + 9b:7d:a2:c7:3a:a9:af:97:8c:51:ed:fe:fa:b4:b4: + 1a:a3:87:fc:cf:8c:8e:e6:80:15:03:fd:fe:7d:bd: + b1:76:f1:5f:b3:09:2b:4c:4d:a7:7c:b5:72:b1:d6: + db:38:c0:67:a4:54:bc:87:09:a5:39:ba:1a:7e:3f: + 74:60:ad:3d:4b:be:94:53:f3:64:16:c7:33:35:ec: + 41:00:95:b6:de:99:62:a2:7a:28:9a:45:4d:fa:cd: + a6:77:f6:de:58:72:50:c8:7d:69:38:db:07:04:84: + d8:4d:39:f7:50:13:43:ae:2d:af:45:a4:2a:39:56: + 3c:b8:b7:d8:26:a4:36:c9:23:aa:aa:b8:49:0b:21: + ba:9e:7a:2b:7f:4d:29:9f:0e:00:1e:b4:5e:a6:fa: + 49:fe:8d:e5:74:57:d8:ba:d9:92:2c:d2:ac:84:1d: + f2:a6:a4:44:1c:bf:88:41:32:7e:d1:c3:2f:6e:bc: + 0f:5d:19:a6:8f:74:2b:67:ba:dd:a9:db:68:b5:ce: + 9d:25:48:df:54:08:d0:1d:4f:2e:5b:24:bc:05:0f: + fb:58:46:fa:02:ca:53:93:29:cf:10:27:c2:a0:18: + d0:f5:d4:b9:3c:5e:df:8e:6c:f5:7c:b9:b4:54:cc: + 39:16:5d:3c:da:96:b3:c3:6c:d4:70:5d:d3:30:a7: + a6:bd:6f:dd:41:bc:a8:de:42:60:59:9a:85:25:0d: + 2a:45:c3:05:b4:6e:7a:4a:4d:ca:8c:0a:e5:6c:34: + bc:20:9b:6d:4a:ca:ca:b6:a6:3a:a0:db:c3:0e:20: + 1a:12:1b:77:dd:cb:1d:7f:c3:0d:0d:e7:c1:fd:96: + d2:c7:68:80:99:a0:d9:8a:33:21:a3:8b:a2:5a:a7: + 7e:27:06:02:7f:ed:60:11:37:34:54:17:7f:4d:90: + 14:1e:69:37:0d:ba:f0:2b:f0:a3:2d:62:79:c8:76: + a8:ea:c8:e7:3b:1f:c6:4f:c2:0c:d7:ac:f0:77:53: + 5d:f0:50:b4:df:9b:03:ca:4d:41:e1:18:b2:25:30: + 86:1d:63:e5:67:b1:53:cd:6b:4e:83:1a:b9:5e:2d: + 05:15:6b:d4:8e:b1:97:fc:31:03:57:cb:bf:27:7f: + cd:5f:27:7e:66:e7:3c:17:09:b6:11:2a:4f:33:cd: + eb:1a:d3:6f:d5:15:8b:8b:ce:68:6b:7e:9a:95:e5: + 74:7f:17:57:d9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 58:12:24:59:A7:3C:29:15:89:5A:C2:12:DB:E7:A5:42:10:21:B7:BA + X509v3 Authority Key Identifier: + keyid:F2:E2:EA:55:65:A4:9A:E2:AC:9D:97:F5:45:6C:F6:F7:8C:11:AD:DF + DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB + serial:95:E9:78:F5:34:50:E4:D5 + + Signature Algorithm: sha1WithRSAEncryption + cd:cb:5c:83:35:ea:cb:cb:c3:a8:c3:95:e2:e6:6f:4d:d8:e4: + ee:41:dd:3f:35:82:ac:2f:fd:63:89:4f:3a:19:d7:81:75:b3: + a3:fc:36:b2:12:d5:c6:56:bc:13:60:37:33:6e:a0:d8:ae:7c: + 88:f9:4b:ee:7b:1f:c8:f0:56:19:07:4d:bb:45:52:1c:78:81: + 07:7c:13:86:b8:86:70:85:e4:71:25:58:78:d1:be:de:22:82: + 6d:1a:4b:06:ac:f0:e8:50:87:c7:69:64:c2:61:43:cd:96:06: + a6:7e:09:a9:02:01:2a:a2:40:f3:cd:10:80:48:d0:34:55:40: + b9:ce -----BEGIN CERTIFICATE----- -MIIJHDCCBQQCAQEwDQYJKoZIhvcNAQEEBQAwTjELMAkGA1UEBhMCU0UxEDAOBgNV -BAgTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMQ0wCwYDVQQLEwRUZXN0MQsw -CQYDVQQDEwJDQTAeFw0wNzA3MTMwNzU2MjVaFw0xMDA0MDgwNzU2MjVaMFoxCzAJ -BgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRkwFwYDVQQKFBBNeVNRTCAgIAog -ICAgIEFCMQ0wCwYDVQQLEwRUZXN0MQ8wDQYDVQQDEwZzZXJ2ZXIwggQiMA0GCSqG -SIb3DQEBAQUAA4IEDwAwggQKAoIEAQDUFlh/3mwov5YaICFXOdJXgHV/uDkTjXB6 -9oxlipshQaYPX8LDT5vhI3gPciS1Z1sRE2dTcC4Mk2K4LDUIjp3WkeTfFAHZPV3E -Y+3OH/ftH4N6SEIBTKE4EY6ah0nJtU98M0JhxOh5zHje6zQp1SkBnhEOQYexYRqj -OtGloZ9RyF0iFAXcyu2Ap14u37l5Yla0cyPzvZqP4mFYlcXwaRfAacJmqMM1vuQv -Fx1JITUTBugMF3VGZ1F0tw63EIUH/FW/WWncPqvG18na40qlv9ZkBw0FhZeKS8cK -JIY5y4J30jn/eV8p1lTO7K+ASTuGZWmdRDgjUG0Y9OGuKsPPoaE6ml0HTnMBsBSQ -fXUq9XkwGt8DTgPioAKHBHjLbILEy4FMYWrlTZlPTzNqyhayec/2T15oDladNSt7 -JpDLpX70UECXFhdEGxsGxtXdKbIBvNm2yT4X2nxW9ItsECjSSgD+94TgGoa8QKDw -rpmgq+Wqpm54CZ1vN1oqyMUw1sjNEX/iLByHAjSALby2Kffk5cl5mnsR6d/k4jsi -c3Qsciwkd+rQt/8VMhS2ns3nkez/BK3FvQA2Ms8xJhFLfszVrBhnjcFRTNT2+/KM -lr1oT5Q1XZKL7qVXTpabPL51JlVBL5CSHl1QRkffsqfqcgJkcHBq+kKjUiFs4lad -hTrvNBCXYa5+NkA2QqIfdOpNwl62/gdE7/7zU1uh40vkVKyzL+APkLPywPEXBOpQ -yIDNkgoXmS10+JMD44K7uZyUmxZL7W7Xbi30NuEFrVOzoUmVXhapPbpQnkQHxn8n -tqKPYXdBcvXcCKyJ6i79H2Vk9fM6rBYiwNcE7QyWqfd2QMjzr76veF04sXkPR+tG -5Y1lrF9Zp3vabFXQg2RJuGA3rV6MR2GFNXuChIYu410vhIhPNtmdKEVoIVZsFsug -+dtn0PDCFrR8VEd/sshp0naNa9Ad1lY+marJkOJOVpPgCs2yJDPAUB/YdvSJ4avW -6ZdvNTwhBL8fEJMS2DSqkaa6A3+i/SqITpU8ToJxsMGagBsLieXgvJALFysSRfR/ -2dmEu9/J0PPc28inHXwjiLb99VKlkuEz8wX9UkuoqFl0pLa8jrlM8hzdPQ9QHb3k -9c5knfgPCYkOIWwGXH+NwANHdQRK7CmGAFV24k9+P3q0g5ikabVHr+4ZQ3WPd+1H -K0+Msbb/vv53vFJWa+pYeNeFcwNCyW2kJBTMiI6qmlL4IWCcX+QDzpRLalbAWWHj -l5Zk39QEaCL024DYK948IDXCqDg6utEs7YnMdaIF0meYMKjehZFp0fVQ8e8Od+rp -bbjdj/w60wMgBpSOeYxVrs3QKNZd/if4Az3LggoVHB09SjXKiWpvAgMBAAEwDQYJ -KoZIhvcNAQEEBQADggQBABncOBW0wQwJdEB6W3d9CrhFp40q1OM54GPfX0/0aUfP -aOQPxS1uCKcFhxAmR4OT9RiJx+0bhDctekkuMkj5yy3u0a/4PxHIhnVxXTyB0/Hj -N1gLz6cQricunl6Q4Ldi54gR5/KUehKLBWnqsfxhgzWBHosvhlJC0xh/uio7JTqz -ns60djyL7R4wGbSqiGdhT9L2HfpJo3dmmWLDxe02jaHkbL1Z6NQMxrRgs3+gctp/ -Wd5UxNl4BHbNsSbzaK9V9gXUcj4TjZGGSqVki0+pEZ3dmksGZdoW9cSKtzKvgUQ6 -vhhqO4dcopxkY2zYeVOpspgTm0XLZSbNPXv5rSFwa4cpWSfD7u8o8KhHvkkSMahw -cMuH17W4voHHFDtWP8Oq9rA7uE/4/LKCl0JmJl2RWM+G6PMH8w4X4auHPssgRvb/ -Ge1AvgqQJrvi7zWx3XYKKJ0ISBy7fi5Jo/wYgLagRYcG3mwdm1+gAdw+77C/ZGmG -FbWFIPB1+Mc6azhhk9m/vqP7o/Wuncc99mp2zPMzdAEzuzp/IJ9UJNat0edA7jiC -bQ7JSRJ1DSzdJZSWWHdardLNKipPfrEHVm7f5QvL5DQLnGpt+rCWL361KsGtvETC -o+Ph7+kDJsJLokUYfs/BEZopzspNPy/NQ2ECwQp7T4Yq/PBE6Ce/dFaoZysMUOrG -TcALtJW6It98dRmTJPiqjlrlHNTrfoV3Aiy+tK4rpyGuApSHc+1Y+t7YvWotRlQ4 -GEboBqR8evjDPJ1xAaUZqwLkebf3mlpl4MzHM9uNWBkQdJilkQs/IrAaApG3Ayt0 -nIymNHmDslBEdrRGmT4aNWAWYvVYzyKDy3H0fzYdWwuA9goJUL4tj3eMJa8pgEU/ -rG3HfflVi+xuwm1UnLXPSIE8hixgV8ebnwcCnEjlUBvwpl7f5Ub40jKcdycdGvVu -gcTUzuRl1+Ikfk/MXKPbdi4A5Pjtz6AG4Ez9q5j7X77JqskTI5Z/f1RPiKwFBJHg -cN4+BPnEuSWGcjiNDOfQxhk5exlWRf/gpEhnQpGHe3a7tZgfxHUb/pWU9BYpf8OH -vtV3WSDXlUqsEEH6/bmvj8lmFWJLmeZv+qLy1wHxcXR9/GJ6TwCF8niQIl3MrBAL -sKPLft1drmpqdIQpZQIJxtN/AQuD9mxEdW7XA6rkvFySKcswJpS1QjkSWpafCBWE -wu+SPxZL8oFrnNMTU3JloUjcRp70FkNXLLm/Dy+MjW2qFBtIoBgNptVGp94L1uZS -amd2XJMcOQ+X9fcH3wAdM3IHGn3NiLf6eTW92JNNA0IN6aNtyVaJKmFJ1JfXOl9r -ujr4SorRSesaerjIcuzW1u1YE5RlgeI4kizV2/D5kYc= +MIIGJTCCBY6gAwIBAgIBBDANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ +MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT +UUwgQUIwHhcNMDkwMTI4MTExMjI3WhcNMTAwMTI4MTExMjI3WjBDMQswCQYDVQQG +EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxDzANBgNV +BAMTBnNlcnZlcjCCBCIwDQYJKoZIhvcNAQEBBQADggQPADCCBAoCggQBAMCPIgMk +WWdGFNaPYAlYBgdF8XhxVfHquTCKzcM8ub9lbhjtoLjJGVZvxJAZyGUJ2/+/gqEI +rQFPWqPUPXh+S0oBpH3oewU+fdi5VVhg1hzO6DJiLBlg8+0FmW3JdwcuEW0Lmsdo +OEbo+jGA3+h58PH9qZTD+g31eKxJftUX/eHuRPPHDjAyXakZJeS7IR3+PIRIQPVY +9L8TjIVou+z13cY40bB3H6aOT43ib0l09T+QZY6ZHlmcHLUmJMSx3h77lmXEMRQa +U7heYorHBPe0NqSvB8gnBu3d5vSMYvFlQNCfn6kUyI6LdNZnWtDJTTWh1Xs5OkKf +5ND0xg8uQjBLVrI9bY4tWMVpmTVJlZWZtocpKzLRUAjNJRRIbRCZhWE8QSYhVcwf +z62wL7mJ2E6gGP91HbaXfMX6i9yTF4YKZNQJNdWDNG1cbcaMzbnswpPGwbfMBG8i +4Ae/4NmbL9WgUMz58JWDj/Qwg3KU17VL2syfVDuNeHcLJGwPwpZhli+4X7V6q3pb +l3qprUCL8tbGjYHZlGGPnQPFuRADaIO/BIHMrL00iejUjUMg4rakET0VKoIM1jpq +jGLUk7zDgL8btCsKejTwzR6CPyUP0QSoCgUZsNYWgzmvC0V9yxR+TaqqwjmoRjir +vasqvTRDf9ol3iv7aTv+O4f9mJR2Sr8EozHjOv9vBPr6JOQqiekOv0RMcoWCPIlK +A2MBQZJT0IJgbtj/jKK0Gjsgba50kjBOSONRpstzlwYTAzIjm32ixzqpr5eMUe3+ ++rS0GqOH/M+MjuaAFQP9/n29sXbxX7MJK0xNp3y1crHW2zjAZ6RUvIcJpTm6Gn4/ +dGCtPUu+lFPzZBbHMzXsQQCVtt6ZYqJ6KJpFTfrNpnf23lhyUMh9aTjbBwSE2E05 +91ATQ64tr0WkKjlWPLi32CakNskjqqq4SQshup56K39NKZ8OAB60Xqb6Sf6N5XRX +2LrZkizSrIQd8qakRBy/iEEyftHDL268D10Zpo90K2e63anbaLXOnSVI31QI0B1P +LlskvAUP+1hG+gLKU5MpzxAnwqAY0PXUuTxe345s9Xy5tFTMORZdPNqWs8Ns1HBd +0zCnpr1v3UG8qN5CYFmahSUNKkXDBbRuekpNyowK5Ww0vCCbbUrKyramOqDbww4g +GhIbd93LHX/DDQ3nwf2W0sdogJmg2YozIaOLolqnficGAn/tYBE3NFQXf02QFB5p +Nw268Cvwoy1iech2qOrI5zsfxk/CDNes8HdTXfBQtN+bA8pNQeEYsiUwhh1j5Wex +U81rToMauV4tBRVr1I6xl/wxA1fLvyd/zV8nfmbnPBcJthEqTzPN6xrTb9UVi4vO +aGt+mpXldH8XV9kCAwEAAaOBozCBoDAJBgNVHRMEAjAAMB0GA1UdDgQWBBRYEiRZ +pzwpFYlawhLb56VCECG3ujB0BgNVHSMEbTBrgBTy4upVZaSa4qydl/VFbPb3jBGt +36FIpEYwRDELMAkGA1UEBhMCU0UxEDAOBgNVBAgTB1VwcHNhbGExEDAOBgNVBAcT +B1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCggkAlel49TRQ5NUwDQYJKoZIhvcN +AQEFBQADgYEAzctcgzXqy8vDqMOV4uZvTdjk7kHdPzWCrC/9Y4lPOhnXgXWzo/w2 +shLVxla8E2A3M26g2K58iPlL7nsfyPBWGQdNu0VSHHiBB3wThriGcIXkcSVYeNG+ +3iKCbRpLBqzw6FCHx2lkwmFDzZYGpn4JqQIBKqJA880QgEjQNFVAuc4= -----END CERTIFICATE----- diff --git a/mysql-test/std_data/server8k-key.pem b/mysql-test/std_data/server8k-key.pem index 608593a5096..493ad2350c8 100644 --- a/mysql-test/std_data/server8k-key.pem +++ b/mysql-test/std_data/server8k-key.pem @@ -1,99 +1,99 @@ -----BEGIN RSA PRIVATE KEY----- -MIISKQIBAAKCBAEA1BZYf95sKL+WGiAhVznSV4B1f7g5E41wevaMZYqbIUGmD1/C -w0+b4SN4D3IktWdbERNnU3AuDJNiuCw1CI6d1pHk3xQB2T1dxGPtzh/37R+DekhC -AUyhOBGOmodJybVPfDNCYcToecx43us0KdUpAZ4RDkGHsWEaozrRpaGfUchdIhQF -3MrtgKdeLt+5eWJWtHMj872aj+JhWJXF8GkXwGnCZqjDNb7kLxcdSSE1EwboDBd1 -RmdRdLcOtxCFB/xVv1lp3D6rxtfJ2uNKpb/WZAcNBYWXikvHCiSGOcuCd9I5/3lf -KdZUzuyvgEk7hmVpnUQ4I1BtGPThrirDz6GhOppdB05zAbAUkH11KvV5MBrfA04D -4qAChwR4y2yCxMuBTGFq5U2ZT08zasoWsnnP9k9eaA5WnTUreyaQy6V+9FBAlxYX -RBsbBsbV3SmyAbzZtsk+F9p8VvSLbBAo0koA/veE4BqGvECg8K6ZoKvlqqZueAmd -bzdaKsjFMNbIzRF/4iwchwI0gC28tin35OXJeZp7Eenf5OI7InN0LHIsJHfq0Lf/ -FTIUtp7N55Hs/wStxb0ANjLPMSYRS37M1awYZ43BUUzU9vvyjJa9aE+UNV2Si+6l -V06Wmzy+dSZVQS+Qkh5dUEZH37Kn6nICZHBwavpCo1IhbOJWnYU67zQQl2GufjZA -NkKiH3TqTcJetv4HRO/+81NboeNL5FSssy/gD5Cz8sDxFwTqUMiAzZIKF5ktdPiT -A+OCu7mclJsWS+1u124t9DbhBa1Ts6FJlV4WqT26UJ5EB8Z/J7aij2F3QXL13Ais -ieou/R9lZPXzOqwWIsDXBO0Mlqn3dkDI86++r3hdOLF5D0frRuWNZaxfWad72mxV -0INkSbhgN61ejEdhhTV7goSGLuNdL4SITzbZnShFaCFWbBbLoPnbZ9Dwwha0fFRH -f7LIadJ2jWvQHdZWPpmqyZDiTlaT4ArNsiQzwFAf2Hb0ieGr1umXbzU8IQS/HxCT -Etg0qpGmugN/ov0qiE6VPE6CcbDBmoAbC4nl4LyQCxcrEkX0f9nZhLvfydDz3NvI -px18I4i2/fVSpZLhM/MF/VJLqKhZdKS2vI65TPIc3T0PUB295PXOZJ34DwmJDiFs -Blx/jcADR3UESuwphgBVduJPfj96tIOYpGm1R6/uGUN1j3ftRytPjLG2/77+d7xS -VmvqWHjXhXMDQsltpCQUzIiOqppS+CFgnF/kA86US2pWwFlh45eWZN/UBGgi9NuA -2CvePCA1wqg4OrrRLO2JzHWiBdJnmDCo3oWRadH1UPHvDnfq6W243Y/8OtMDIAaU -jnmMVa7N0CjWXf4n+AM9y4IKFRwdPUo1yolqbwIDAQABAoIEAQDI3u0tFoWMRoCs -99d8HLiaxYED2YC9gw2QeKjal198LQhRsVnu0ByMLKLOxkX8RgrbbmxDe5Exufob -A0urciAOFJoXqoRhs5x2oEqgGmkf/ePx0jQptOFREFfnBdGeKIpC0O3DWdLxYPbt -8wixwkEXVhVDUk9pcdXf2ZqsbBpQRBvpZdtzlgNCAcLTVHP/gmMqf48CkIauVjPq -ydfybibfx4sm3hodclH+Q78p/zicb8MhiKo7ZymgCKz4N743pQe1tsLrpbPeHY0C -MpoFyF8O2Bq+KxwvELxQX+19GcHVKJhj3hmCr4wde9BxCWtGTBCusekVkVvy8iQ5 -aCmTIrtonMEVZXjJlXK0sw5hBKOmKx0jrSVC5FfgdxzNVlW4fCJXLEEpMsjMc+/3 -6bV7jqGn4N5CYaopNS2ccxdaucE3NjcmofahO6bqUTJHSPFecfYmCA42W2m+ldjj -HZ78JLkyw03nT1hjPjbwHf5FTem1KfKg4EJrDprowMT7D8KZb0SW+z59pFoDOM5u -Heu6sOSUtvpvKfozdw2ZAI58dhpW4/jTfCEtewRhPqE3/V7g3haTnQFxU8gm/a4N -uefZTCjFE16QWNuvnUrJWw/DlvOBY8GjpQCWY0mDeBHPNOI0Xg9oRTgOCrKSLUya -YSbg6BmhSKwKsYQU834jrQb3fXFlXZVIxlcNePOWMhHFFNAHucHF822Nr7u/3FOT -twcbBIOXCGfDT6ed8d4dNum1L7k9Blju16CWkfuciL8PGXY4mGAmF4nZMXGZgK8B -Cz9cxhtvFLe8gz5615DtBAsuVm7Q4AAHiULAMg6t6auyxCb8pXbAL0Ec5X4zS3+f -I2riODYiyHCh/qTtjawOzUZZEtjZRMSDi+jk8wjjDdkFU8McOaYoPyqT3TDy2v6m -NiPJs8GWQ2NCNo9CNoGbEIIFFP5iSz18XLFAOF+2dN/KHHl9nKyi7kOhYbbzoNku -2wQV40yVsrS4E/hd/7+2IB2Muduxiu7NxCUSUXsw6p0hZTYMpIoduEfRSk1al0lS -862GD8JgJ4RhJ0uIOTDJS52MQmO8zFIL86emdjjV1CzVvadYSQLTX7ZgR0i8g46A -y0muCFAC8EJpnEtHzqtQ/z22zB8TCJShFuUK9KF6K8nOlbc6ShcUXU2J6r1sc8aT -Dx0yzRXfCL15fpCJBP49EYaKhArTNmFRa2GaLiJP0OYkTrrwVOGuS6x2+kRVoP/8 -BcNMZ5x8mXP1LgotHCztgMKX30Hn5CLxbH8QfcWKemGva1jBmhCWxS17Gh3Ld9T3 -/WKkBa6JDq83rlO84x/iF3mB3tYkZPfcYtYURn5wwm/BmVV/9G1VwAatJdxmfCSy -5JwC9WDBAoICAQD7xStPk3lq+qYHAtLZidujmzSNv7XG+E8UC9yvMRFuBwSM5ZE4 -YGD2LDev2nghB+7OSR8KJIkxeaNjP91Zf3s8wjCuxLg/cLGI6mf6uWy9+zypFg3i -J+ylDKa6NBuqYyY75W7Pj63xvGQlw5kX5+mB3ulQbActT4cUiVdEkyDytzubqLzY -s15QGFrL9gqLow+C+7LKQKdeXq8OavFV1PWkMDAJUki6cIir9m+f5Mqr2cQCLKgx -38aX8c9UWJv6pI5zQQuBjpaBOwz07WnyTXiFpc71x/8i85uLGDM0e3VO5ZPGeRBj -jZ0ucHatOHJ3i/nPRG16rsPR+q97QiDHoLF0quHEG+ND+rwTBzNGIwzYRE16p1o3 -UdzFk1RzlDCfOX7QgszCwK6mf8TbCK9f/FxJ5e6TCkt3iHXSrlLS4op6k9nEpKFH -KHf4nPtCy9GriP+A8+dA6K1s+DgejoIojBMBTsnl4TEf+m8BaenTXGuU7KYyc8dR -JqmpmDggDRT/ImHRhXirY7lIIYXnI7tRjN5gmnKpEiHScT1r848zpQ4gWH1Dx/ks -mKT6NZ8nF45saQCYbKEYc0RH9Kw0O7vr1kVtNPc2dEZtVgt4bC5fnl7xX1/YTk3m -+h1qfzbku/+MX5rRjHLR2l8a71UltlnnnpP5NKBBgtxll6aCIkk6CdH8YQKCAgEA -16aBaVa0cOZmiOQwPQkpuXIbV7msz1ttWEAHElCy6waniOCON89PYFCb7F0NjV3Q -i+pGaRgG1iZGbjjHwyqTrHhMloFm+IsSWZqOZzrHgSJgA4bgTJFgp+5b31sQXGfJ -14QQSqMJLC61/M+CnrNtiuI3IVHx6BFRxI42uE7PfTyUMaFhL9F0/SLl0Mw0oMPj -S5kmarduuKpRn1tN9WO+ywEvYwopvH3e9PBssZzPpttlLiE/Wulb0iEtlVXYB9DS -Vzc94N2dzFMIvWUDF9BQ+IBMRzXRm15Psy6LfzoK+9S6w38Dx3BVV8ykSMKeW1UR -ZwTajjdnIBLdE3onD5XMmrSOPw/WtV5zXEYY4DObhIPoN2iD8GJP0IubPb6fonH5 -VHmuVZoXrroFEe7rdt2wgmBdPPl6fqvBKVhjJOpYQctrFLgWh63bXZKaBWqbQM9W -fECq8We1VN3fzqwfwJQit3z5R/DjQNk8eQx7SnnkOzAY6ZgpysHCwaoPOnPVuiYF -ZU0+X3iwfsdeefWmGEDIzoZk6nYaljs61lOhhEoWHngZHDkMOp5kg0n9f8BUP02+ -WJ4QhwzZ73hr4FPBuPHHXECw9TCAgCBHBFrnrXg5QalDhRXz4F+3tCY7UUpD/ikZ -L6Daxm5zGJ5u3rXs6WwKy2EHVVS9zfqs4Q259pQdWM8CggIAcIKpGzOVM+h033c0 -kIBZxeAq+Rlt+0+lzxiJ80RjPJ8oOmqwndf8HKaf8BcaTfCEmGz20QqIwLJSAJ1e -posgoINLTB6fE8Kho8TU2KeaX7/xWMKBS8p5pzxjGZ0Fq/wI7wVVoq3blsaQnout -U5CQujfKXeUYw/fhLp09gWiadbzKh4I9ej2V7QclNDZsegBRg0BForqH0NVRN4k0 -9h1n9IqQPOonlCGMAgTr1zFgHLIBNNOOClOtJOOruk6qzbRR8FFl+eyld3TTEnUy -PlS+gkMZnJ5WduEUZnFXGKH/R1Wy1yPs3gA/+KvLbRdnl+LWrPgwUH3fBmwXlWZ0 -zaETDEb9Ay1PP2bCO2KhWDt7lv3W/fPhjg0oMqbnO4tCuzTvZfC93l5K7h708skL -zkIxX9i/57fXB8DUnmTGoHUaWzLNQ2IqrGj6TACjDDOXLCfZvl/AvTH9pk+6jHU0 -1zfZmmECOpeK43Z/ussA8jI/5Vpn3u38aVh0w1RB6JjQBD/yJLaXuUekWgaZFzTR -ldz014jNqp5uvONcBmzeVr7w9CV3PR4VTQed2i6yQ770J6A44uTQjOOd5OYDOohj -Lz4e4nGj9BK8Eko8cAEwLAzS8tyjMT+08n5dPOVCu68DwVBMGE7CVONYUuoXS/YU -cTxddiU9ZGk9Yq0FfOwjeys+SqECggIAdn3M2b6Egwx2Bn2ra74fKQBjub4SEBWi -bT0xJYUl6jHL2E/alRvZ94gTRLqUebq0nkxpx9El4IFDbcjRKpG4dqnbG0+a7rIr -sQRVfq8zc+cZbparpCa1P1CfNojo4n080KiF8xzGK3q3EGRM1zqr1AYcWLiX/PWX -QjMKKhdTtvKUUvjjV8z1RSnpsOKjgDpiJ+XM0BJeSiV7l94pZc4axZyvFvI8oI9g -9KEueCE7j+k5HTGziBZ1F26Xh1iVzSWWjcmSvH3I+L4fLUHVgz45X3HPd8lAlOgr -Tr8icxPHeTwYKtcdknZMzmNpWXlmXbTOTRbDqCUVCvCSfOM/lzauJ8tR5aCkTx/I -r0js3jQ9HYEFFXzeEjVSubob4L9fI3kQkLQTcIGsxZr8si/fPX7uP5UHZjuGbRee -mUMxptUFDZHiEo5cAs0qna2x54v+JoxGbxtxUhez8R/Am+TDxaMfuEZ5Cmh31egH -bFPJYtC68TKqXZ/4RqpUgukYWPvQ0emWSWU6AmdkQyT06nppeyYNsDz0MkgWr7l3 -yNBHDVNP+Anxcip+Z68kd2cuXQWmxOnIzxR67FnJXeWDEM20whRHgI8jLHYsBTq3 -CtOQPSaz/zosGXJIgF7Xp6riKPZvibW3Ww49Z47EuyBCtyirNk7hV4LG7sITUJyO -ZVKPfcdAoM0CggIBANz3EBZGyt3af2UjFFKbazV01KcHF8OxqdQzsLqHCXWb98V6 -PggQnrF76U7DvqOWho9djDBPrbQU55HG5nXq+eZKPwhsOdwQ8bxOhaVxQcATZOI7 -FtJYnjM1/+zMzzS0iPR5DA2pbB3AKH2Z+wODmF23CK2XTwoJyPKxvlyGKrIqq3gN -kOmocNu2Qm5bJf+D/hYPm5Ust2wzD52NnvJU536bZ0ZMo1/kaK2idqSAzqo4TkR1 -j9U0fdW2rIBDo/qFmBBdJhYVjYLj4qR8CEEoIjshD4Nztf1xRM5C8irE/gJcT5+r -4bPJJ5TjAtHxPiQqZruSprSEUbMsPqBap64ow0SmbNNWSgyaz2ha1rG0p52NBzH4 -XM52LBqS9QHPHvB0ooYfBTfPpDM3CePuuNyzjPAw86ncUo38FKXuc2oViJJ6C5I7 -v2sKhLK5gu3uPBB2ludDEXSpWBqiraynolOT/o52r+taYp9YY2WU3GrhOiV/A1FV -Nl118xiF6FOFpEeTbhHvy27A8kZEKXgeSs+f4aC0XG9kLVD1CiCbQiqHTDcDS4nV -O1N1eQxhP81X+YKE4Lgufh07REqYVwtCj2lQcMp73WDyfBLKTEFlmHusoqmT5JCH -X0BWNjk5Dn1g5h63/lQb+EjNRILBhDFYhrDRDQtw5p0/7IY3AcNKDUHv+XGn +MIISKAIBAAKCBAEAwI8iAyRZZ0YU1o9gCVgGB0XxeHFV8eq5MIrNwzy5v2VuGO2g +uMkZVm/EkBnIZQnb/7+CoQitAU9ao9Q9eH5LSgGkfeh7BT592LlVWGDWHM7oMmIs +GWDz7QWZbcl3By4RbQuax2g4Ruj6MYDf6Hnw8f2plMP6DfV4rEl+1Rf94e5E88cO +MDJdqRkl5LshHf48hEhA9Vj0vxOMhWi77PXdxjjRsHcfpo5PjeJvSXT1P5Bljpke +WZwctSYkxLHeHvuWZcQxFBpTuF5iiscE97Q2pK8HyCcG7d3m9Ixi8WVA0J+fqRTI +jot01mda0MlNNaHVezk6Qp/k0PTGDy5CMEtWsj1tji1YxWmZNUmVlZm2hykrMtFQ +CM0lFEhtEJmFYTxBJiFVzB/PrbAvuYnYTqAY/3Udtpd8xfqL3JMXhgpk1Ak11YM0 +bVxtxozNuezCk8bBt8wEbyLgB7/g2Zsv1aBQzPnwlYOP9DCDcpTXtUvazJ9UO414 +dwskbA/ClmGWL7hftXqreluXeqmtQIvy1saNgdmUYY+dA8W5EANog78EgcysvTSJ +6NSNQyDitqQRPRUqggzWOmqMYtSTvMOAvxu0Kwp6NPDNHoI/JQ/RBKgKBRmw1haD +Oa8LRX3LFH5NqqrCOahGOKu9qyq9NEN/2iXeK/tpO/47h/2YlHZKvwSjMeM6/28E ++vok5CqJ6Q6/RExyhYI8iUoDYwFBklPQgmBu2P+MorQaOyBtrnSSME5I41Gmy3OX +BhMDMiObfaLHOqmvl4xR7f76tLQao4f8z4yO5oAVA/3+fb2xdvFfswkrTE2nfLVy +sdbbOMBnpFS8hwmlOboafj90YK09S76UU/NkFsczNexBAJW23plionoomkVN+s2m +d/beWHJQyH1pONsHBITYTTn3UBNDri2vRaQqOVY8uLfYJqQ2ySOqqrhJCyG6nnor +f00pnw4AHrRepvpJ/o3ldFfYutmSLNKshB3ypqREHL+IQTJ+0cMvbrwPXRmmj3Qr +Z7rdqdtotc6dJUjfVAjQHU8uWyS8BQ/7WEb6AspTkynPECfCoBjQ9dS5PF7fjmz1 +fLm0VMw5Fl082pazw2zUcF3TMKemvW/dQbyo3kJgWZqFJQ0qRcMFtG56Sk3KjArl +bDS8IJttSsrKtqY6oNvDDiAaEht33csdf8MNDefB/ZbSx2iAmaDZijMho4uiWqd+ +JwYCf+1gETc0VBd/TZAUHmk3DbrwK/CjLWJ5yHao6sjnOx/GT8IM16zwd1Nd8FC0 +35sDyk1B4RiyJTCGHWPlZ7FTzWtOgxq5Xi0FFWvUjrGX/DEDV8u/J3/NXyd+Zuc8 +Fwm2ESpPM83rGtNv1RWLi85oa36aleV0fxdX2QIDAQABAoIEAGv5ltvmLQ/A93xc +x0BWEINRkBa2jrfpo9B5dOnuikWtza/Cx+X2NfQHFlSrcHhfr/JX5BsCb2iVo8DM +CXAgeX1VMHS9wQXuxciaHCZDnqxmxUNDU3EjsYQOKLusRcdL6M+Zuz/ny+7PQ0Qw +/N0yS46Wa9oUjon3RKRvTeSV4HIpFpcP3n/eLjDc/ielWuujnTGcBnjNWegvQROp +5/7221YElGh8U84kbK2l9DtfjwoGoTv11lPvOxXE/scg6em7r9j+y3p3TMzMeDtT +YBC6CA4Oa7GrWLJXROOKOQ0ddtvFNlUsZ02vG2QCbqU2y8mwJrJDI80qNbeKGel3 +SfwkssedtGoOOYHxNczwpyVNHVHrHuMPBe75gbo+5pFxVJ5ymCGWfbLJf73oVsqW +ZimoknvkozW4+mlVlcmo3X73IxTW2U4RlXthYdj9KXsBLRaKVCQJDc934eHWkXHU +GF2U2NonqOVd8YG/FmZQ2ig6EcW97hC6wnsWT2Uc7UNAE2RM4bY0xCUHaQiKTrEs +CI6wpbbTV+XhDu2HmL9G+fsuSIu0RoSOCmr5jQDAVwCNPXFgBgcIxbPZ/UCJ7RHj +GrWPBldAN8ip4osiA+B3XwBabcvwXP2fgBP/eLWN1St3q3tw5xpHpqCuhNuPSqsc +0ntz0oIdJyRR6fXWmRFex4kXQ597z5ozm0uyg8arV3HJFxDC3DI6kKfs86/oqMSW +l+9g+d4x6VrUOCTDk0bjN3T8HQ9ASfy9JVacqk6yuXX7a0WeeT+x9JsvFAjg2KmG +CJUtm5w5siItMDSPpcRE4hlfgh+M7ZKS3PFgH3vvwfPMbC/IC93QoSaFzRJMyobX +ei6PNwqJvL+HADlMfLmehE2w9ycp4Fe1Gw/NW0Ed1S6Ajo45hgXQJSIrzla6eglg +JPsPpQ8b+weZNQ8zvc0KvfRJmZKKEb9dHvFdi68I1kV8aapQsjrMOjwHC2pnCFh/ +axkVc7a59fKUs7L6nAJhCs2sSixTorZz5PvJ6mXhWu72TCzu+kThNnEORrlWPHQl +RFEAFpDDaGSzOMlhb92CWUMPyZU2qtzMzv4QGbP5YqTy121hXuT5OBKCF3eNLihV +aje16k0RMFqqW3Olbm7Mp2P1C6DuwzsUJBnNwB5JzhC79Po88zNAl2d1h+qysKU1 +jxF316nhpWJ2dGJ/sbJ+XpUMd/tVrNFQMA254GFfXycsfBoQOSY5d6GfRwKUDOou +xImbIzGUAaIYdsGKDuKtqs5S21JMJjJ/J5CwjLu9tbpP/jsp22KHCpraHAQCupSp ++SFwWI7tRUXzREuxJixfUOnJFQYOATnMFvvtk1d6v4xoPYCVEhHq8gHqJkTyTi3Y +BPVwT1UCggIBAOEy5gThTrEqSVFUcFJm9bJxtWZt/YhOIJWNNxeaxExHzy5hPpsw +fZXtN4MUCeMSWI4isgIujmltwgOHMjQqsJPISn/1gVrqLmrZ2PnFzko/WA8rMUfd +EUnOOpj2bKpChlRGHi76ZV4XGgoTXyO6mrVUcUgf3reSImdcdQ5IHa7J+lWhCQGb +neZIyDOk41LX1TxjcYkY7vuUgmbBYComXPm2UaY3HN4E/3ElXntj6PrlozL33A56 +z4UPfv2Vv9kl0ydkTJe/WcUN2htqLFCYygF2XLlwbv2SYDCT31PkJUORbScUM46A +DOhlxvLBFcpF+l0RtCtvnrKyFy9yZJKrcLh9x6xVChZ/aQqSptSHjll5IEcVm54Y +Z1TjWizCI4txnaBFV0UCLt1CZrllXnyIksZLS4/dVqUIKmkxPBQUpiD5dmgDcmPB +/LdWzS6k4MH3J3Y3tu3MNPHDwgUtnifSZrsWSYPK0F8J0dMU/mLaS9eOplAH7Eo1 +t7OrrImvitM6tUdErRYilIaoS/6YPmsPST5gY1N4n8Lf4sAE/tY8fwaWRpTVSrIw +CoFwLtHESUOhqfuAOdr1EkDfo/RQTUVdnmWZ+D0j3du8MmsMje4x3f2CjBDXqArl +gNnBQELDmrdif8KELNjlEpTIz0T7wEfquhVQ2dzhFpL7RLAgggD+oEBLAoICAQDa +5WOWrAtaI1cC5C7LFxM2qXTHGRttfAtVxuigJapLqNASJuu59GGRxsCVwhthbNFh +aCMSj+fZK7QNFkaoPwuZCEtzy0ErkVZzxYp3cP6b99mzGoCcuqiHiW5qhEkbxwdC +f3YEsSGqE6j8TPW8feiziqo8q+QPSudI9ngkH1gjgbIrTu9iaxKJcF2CwBxe5tfB +uFBNPIgJAaLPejRKQu17MAV2jDnBDIsZUZnm53IxQ+giIYUBay3cfC1KMJu/AnZ/ +CxETjgqqnzqdFW0b0o49Q6YQa6QXAiSjs+lL/BhjbdA5quVdFmA3CoASFQbihYfM +4vilUg7Y4wXfzS7DyBZdfppIn+HI8PPSMv/lfdsQXecl5TU1fBDPRWYPpTZqm1II +HDCkmGRKet/j4/oobabNRrJ6PJcxNjqeMVv/a72pypDRPIXzNxLb1BkfWDGfgu2R +YAdRNBSJSpdoHDZ+1VO2A+/8gz9Zuiv1WxoX7+u3pCAd+0vCfHiaXiFVc7fI8F+m +rtDmN5p3DD9l1+/v7yd+7eUezwxYecElw5E5MyAJRTYGrim8g7XvF/u9rXvH09VP +TeIE8oJ7XzrxCmtGIxlJs6FmgUbUblOyfPZDUqPnzlo8Ru1H2iKRo2FPiMfij8mh +H3wgFTnZpGDQjw/xop51bxVueXrmOeguS0wmk/8Z6wKCAgEA0y+bPApadJRWS1nn +N69sTBqMZfFR6Eh0ECts9criuTJCXZk+T+SqcTYTb+4T04k52Jk63Aby8HXIkuxv +LTK3gu86xkLiOvMP8o43Bwz0BvbeSuNThLQQ6Wjn1NiLUSOvu0pCNgYFl7YMalR+ +TRBK0y/MSDny762wa8Pt1iXVCDxLcY/h1UstSW8JqDzCHcdgJhCPwWTLgMxleZ1w +5DYzzM2oRjq67I49Sssjjo1ESD2fzUVZbY7IG11L1t1fG3F4UiGiHlCJC92Qo1Lv +Geoezj5EeHay70Mcx5F0xsRWGcZAWXx9WO5GrI39g1uFZro3Lp5SmsVDSwrt6UXa +gR0bSThTTw40tqJnTE34+6ff25JWrbLay+jQxm+q+fxZvwQeMNW2IHYKot4JXWVt +tVWSZzjnNJP6FCvTMfDFCYPPw26OFr7cwCaEKx7QriRazitMK3XWK6zsHalZwudj +wK50PpCJAnno7KdVySCP6v4ST6Rr3POBKJq1ml2tITWo96u/ooUJ2I83QAyFr8zw +BBBCvKdBnl6pW+P/TdmhbiEvcmrs59gaA34/6+DbV0Y++piZwswd9XML2iCgLZY8 +0IcZ6uf4PsXq4Yzcrz0HwM+tAXcyiPzkjstpCUxMShALgFxzuWOgdwpjYXnrviJk +0EyUkzbOCHBhbhcK9CyYHfyrJX8CggIAdWwgJC9eV5glkPN+9osGT4hPkI4zXGPy +YK03FNGfrL59/37JbRNfU6fen3dk4LpTB4Gpbserg6AiEfMlLBPF0O3WK+OYrhpk +2e3Z/YCr1Fb8fUt2Op0W0r4ycQlNfo0ho9ZkJNgwSuAJAm72U4rnTYjREYLT8DAq +KcWtZRM7YLCuNvU9DPqLExcn0n/juDT1AIIy8XvLLamnAM15R2znn/F+vL00Lg7g +f1B60pbNdwgKemSoyL4J+ADU+rtgkPJtRnFVU7walLSd6K4ZvZcRnmOvrZdQitcn +eHmGaLBvFMdPr9+w8mKScnQ7h3eoHdOrqYkIAQcn18jQ2eFjeLrY5IaJlPPPVs+K +u/OHuj/tR7ZXzMhL5skK62U6/qGNs1pmgts8bM8i3aFUgRdGlnFbzTpje5cNM+T3 +RO0NgNL3ByIW1Wc2I+YjQ7FfWKUi2YKOljGBO1pIue09kyevRBKDuVwbXMW7MhLg +idm5AaY+OGDeqbaoSUgkGgrsrr5IlI39gZi9jwG85qe3Spavq3ILKdfL1N8UrFGD +/xIN0TVPtilede7vjKTK79tZu8JYaDWGc+g/mo/M1wmawLrqGNGzOwoVRruKl2In +m9PU9wBZ1HuphDQ4DRdC/AU8qkGhmDOx4bDWEQ/R3KKFHNvhnamyfyR7xqt79gyS +NGNIElnJuskCggIARFaK6yAVmaL74Qu3iiELj8FU9Cw8kPP5HeWUfGxCjlegdH3R +FBtoQlDcQjYzO2uZR94Itg3yk3Dt+xbf7KxUsODwlgLj1UhV4eOXUDTosBFTrbTG +v9gnRVH0Eyu9tF+CMUcCXhq6tnIrQOVv1ozcdXfIpk9gvIbfh4rlo6X0iM8Xge2t +Vo7awq05t4wJBkO1xUtOaw9HabaszK/CU1iNV7cIBmaFF3AEP/KVfOs+kjubc9AF +mqC+LVVClvJPNzm1YA5JZlxmQ0u1xXFqZv0OMoibgY+gSzaiAQz3eKB6vEv4Xv4U +kaF9nEUTEjowpTE6uX9X0mGkXXT2wXmlTjosZFnxRX5IIrRNug30plRra5CNYPGp +3uTmD/D7Nzi1iYitJg3yhrTQmCWiJY3x4Z0xophLkio2nlJ9WoTKf1AwTIATY7fa +pX9bxEKldYXrYZNFlbqBPFgA/36v+JDVfMf2E9yRMCt0LAJ0HUM6zP0ngMv+S1TP +Pu6X0WXR9JeuoaF4uJSty/xwdpST/CkHflFLVsk5n3tNQfWGjqoTSOJMgL9NRY9e +Pc/OshHZHeCVFUSXtcf1pfmmBtT6FHX0L4cgVqA5xO8RYapnLDAFLXq2/dRv3NwW +W9CzZcZKh7jmJw4iSIY5IU1+ThgugWoxlkcmjs/egjBclL8BBfqRIwx/vOE= -----END RSA PRIVATE KEY----- diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test index a752e990846..14c14fca0c6 100644 --- a/mysql-test/t/openssl_1.test +++ b/mysql-test/t/openssl_1.test @@ -11,8 +11,8 @@ insert into t1 values (5); grant select on test.* to ssl_user1@localhost require SSL; grant select on test.* to ssl_user2@localhost require cipher "DHE-RSA-AES256-SHA"; -grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com"; -grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com"; +grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; grant select on test.* to ssl_user5@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "xxx"; flush privileges; -- cgit v1.2.1 From 10470974643796204f13c631bfa964695237584f Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 28 Jan 2009 14:33:33 -0200 Subject: Remove test case for bug 40264. Dirty close tricky does not work on Windows. mysql-test/r/query_cache_notembedded.result: Remove test case result. mysql-test/t/query_cache_notembedded.test: Remove test case. --- mysql-test/r/query_cache_notembedded.result | 16 ---------------- mysql-test/t/query_cache_notembedded.test | 29 ----------------------------- 2 files changed, 45 deletions(-) diff --git a/mysql-test/r/query_cache_notembedded.result b/mysql-test/r/query_cache_notembedded.result index bf582bfaec6..8e5df012cfb 100644 --- a/mysql-test/r/query_cache_notembedded.result +++ b/mysql-test/r/query_cache_notembedded.result @@ -345,19 +345,3 @@ id drop table t1; drop function f1; set GLOBAL query_cache_size=0; -DROP TABLE IF EXISTS t1; -FLUSH STATUS; -SET GLOBAL query_cache_size=1048576; -CREATE TABLE t1 (a INT); -INSERT INTO t1 VALUES (1),(2),(3),(4),(5); -SHOW STATUS LIKE 'Qcache_queries_in_cache'; -Variable_name Value -Qcache_queries_in_cache 0 -LOCK TABLES t1 WRITE; -SELECT * FROM t1; -UNLOCK TABLES; -SHOW STATUS LIKE 'Qcache_queries_in_cache'; -Variable_name Value -Qcache_queries_in_cache 0 -DROP TABLE t1; -SET GLOBAL query_cache_size= default; diff --git a/mysql-test/t/query_cache_notembedded.test b/mysql-test/t/query_cache_notembedded.test index c427e0d1afc..421ec913e5d 100644 --- a/mysql-test/t/query_cache_notembedded.test +++ b/mysql-test/t/query_cache_notembedded.test @@ -223,33 +223,4 @@ connection default; set GLOBAL query_cache_size=0; -# -# Bug#40264: Aborted cached query causes query to hang indefinitely on next cache hit -# - ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - -FLUSH STATUS; -SET GLOBAL query_cache_size=1048576; -CREATE TABLE t1 (a INT); -INSERT INTO t1 VALUES (1),(2),(3),(4),(5); -SHOW STATUS LIKE 'Qcache_queries_in_cache'; -LOCK TABLES t1 WRITE; -connect(con1,localhost,root,,); ---send SELECT * FROM t1 -connection default; -let $show_type= open tables where `table`='t1' and in_use=2; -let $show_pattern= '%t1%2%'; ---source include/wait_show_pattern.inc -dirty_close con1; -UNLOCK TABLES; -let $show_type= open tables where `table`='t1' and in_use=0; -let $show_pattern= '%t1%0%'; ---source include/wait_show_pattern.inc -SHOW STATUS LIKE 'Qcache_queries_in_cache'; -DROP TABLE t1; -SET GLOBAL query_cache_size= default; - # End of 5.0 tests -- cgit v1.2.1 From cdac80a93a20b81232a1f1d0bc95abaead4505c5 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Wed, 28 Jan 2009 20:59:08 +0300 Subject: Fix for bug #21205: Different number of digits for float/double/real in --ps-protocol Various parts of code used different 'precision' arguments for sprintf("%g") when converting floating point numbers to a string. This led to differences in results in some cases depending on whether the text-based or prepared statements protocol is used for a query. Fixed by changing arguments to sprintf("%g") to always be 15 (DBL_DIG) so that results are consistent regardless of the protocol. This patch will be null-merged to 6.0 as the problem does not exists there (fixed by the patch for WL#2934). client/sql_string.cc: Use 15 (DBL_DIG) as a precision argument for sprintf(), as Field_double::val_str() does. libmysql/libmysql.c: Use 15 (DBL_DIG) as a precision argument for sprintf(), as Field_double::val_str() does. mysql-test/r/archive_gis.result: Fixed test results to take additional precision into account. mysql-test/r/func_group.result: Fixed test results to take additional precision into account. mysql-test/r/func_math.result: Fixed test results to take additional precision into account. mysql-test/r/func_str.result: Fixed test results to take additional precision into account. mysql-test/r/gis.result: Fixed test results to take additional precision into account. mysql-test/r/innodb_gis.result: Fixed test results to take additional precision into account. mysql-test/r/select.result: Fixed test results to take additional precision into account. mysql-test/r/sp.result: Fixed test results to take additional precision into account. mysql-test/r/type_float.result: Fixed test results to take additional precision into account. mysql-test/t/type_float.test: Fixed test results to take additional precision into account. sql/sql_string.cc: Use 15 (DBL_DIG) as a precision argument for sprintf(), as Field_double::val_str() does. --- client/sql_string.cc | 4 ++-- libmysql/libmysql.c | 4 ++-- mysql-test/r/archive_gis.result | 6 +++--- mysql-test/r/func_group.result | 8 ++++---- mysql-test/r/func_math.result | 10 +++++----- mysql-test/r/func_str.result | 4 ++-- mysql-test/r/gis.result | 10 +++++----- mysql-test/r/innodb_gis.result | 6 +++--- mysql-test/r/select.result | 14 +++++++------- mysql-test/r/sp.result | 8 ++++---- mysql-test/r/type_float.result | 17 +++++++++++------ mysql-test/t/type_float.test | 8 ++++++++ sql/sql_string.cc | 4 ++-- 13 files changed, 58 insertions(+), 45 deletions(-) diff --git a/client/sql_string.cc b/client/sql_string.cc index 9d887ff031c..7767711e62f 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -125,7 +125,7 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs) str_charset=cs; if (decimals >= NOT_FIXED_DEC) { - uint32 len= my_sprintf(buff,(buff, "%.14g",num));// Enough for a DATETIME + uint32 len= my_sprintf(buff,(buff, "%.15g",num));// Enough for a DATETIME return copy(buff, len, &my_charset_latin1, cs, &dummy_errors); } #ifdef HAVE_FCONVERT @@ -677,7 +677,7 @@ void String::qs_append(const char *str, uint32 len) void String::qs_append(double d) { char *buff = Ptr + str_length; - str_length+= my_sprintf(buff, (buff, "%.14g", d)); + str_length+= my_sprintf(buff, (buff, "%.15g", d)); } void String::qs_append(double *d) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index dd66a325169..2a5e1cc657b 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3786,13 +3786,13 @@ static void fetch_float_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field, #undef NOT_FIXED_DEC { /* - The 14 below is to ensure that the server and client has the same + DBL_DIG below is to ensure that the server and client has the same precisions. This will ensure that on the same machine you get the same value as a string independent of the protocol you use. */ sprintf(buff, "%-*.*g", (int) min(sizeof(buff)-1, param->buffer_length), - min(14,width), value); + min(DBL_DIG, width), value); end= strcend(buff, ' '); *end= 0; } diff --git a/mysql-test/r/archive_gis.result b/mysql-test/r/archive_gis.result index 3137d43ec3a..5a8ccea7cc5 100644 --- a/mysql-test/r/archive_gis.result +++ b/mysql-test/r/archive_gis.result @@ -291,7 +291,7 @@ Note 1003 select astext(startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint SELECT fid, AsText(Centroid(g)) FROM gis_polygon ORDER by fid; fid AsText(Centroid(g)) 108 POINT(15 15) -109 POINT(25.416666666667 25.416666666667) +109 POINT(25.4166666666667 25.4166666666667) 110 POINT(20 10) SELECT fid, Area(g) FROM gis_polygon ORDER by fid; fid Area(g) @@ -325,8 +325,8 @@ fid IsClosed(g) 116 0 SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid; fid AsText(Centroid(g)) -117 POINT(55.588527753042 17.426536064114) -118 POINT(55.588527753042 17.426536064114) +117 POINT(55.5885277530424 17.426536064114) +118 POINT(55.5885277530424 17.426536064114) 119 POINT(2 2) SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid; fid Area(g) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index a7f4c58f4af..85ddfaac4e0 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -61,7 +61,7 @@ grp sum NULL NULL 1 7 2 20.25 -3 45.483163247594 +3 45.4831632475944 create table t2 (grp int, a bigint unsigned, c char(10)); insert into t2 select grp,max(a)+max(grp),max(c) from t1 group by grp; replace into t2 select grp, a, c from t1 limit 2,1; @@ -1195,7 +1195,7 @@ std(s1/s2) 0.21325764 select std(o1/o2) from bug22555; std(o1/o2) -0.21325763586649 +0.213257635866493 select std(e1/e2) from bug22555; std(e1/e2) 0.21325764 @@ -1221,7 +1221,7 @@ round(std(s1/s2), 17) 0.21325763586649341 select std(o1/o2) from bug22555; std(o1/o2) -0.21325763586649 +0.213257635866493 select round(std(e1/e2), 17) from bug22555; round(std(e1/e2), 17) 0.21325763586649341 @@ -1246,7 +1246,7 @@ round(std(s1/s2), 17) 0.21325763586649341 select std(o1/o2) from bug22555; std(o1/o2) -0.21325763586649 +0.213257635866493 select round(std(e1/e2), 17) from bug22555; round(std(e1/e2), 17) 0.21325763586649341 diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index 150b6003dbe..0d7adbbba5e 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -60,7 +60,7 @@ Warnings: Note 1003 select ln(exp(10)) AS `ln(exp(10))`,exp((ln(sqrt(10)) * 2)) AS `exp(ln(sqrt(10))*2)`,ln(-(1)) AS `ln(-1)`,ln(0) AS `ln(0)`,ln(NULL) AS `ln(NULL)` select log2(8),log2(15),log2(-2),log2(0),log2(NULL); log2(8) log2(15) log2(-2) log2(0) log2(NULL) -3 3.9068905956085 NULL NULL NULL +3 3.90689059560852 NULL NULL NULL explain extended select log2(8),log2(15),log2(-2),log2(0),log2(NULL); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used @@ -68,7 +68,7 @@ Warnings: Note 1003 select log2(8) AS `log2(8)`,log2(15) AS `log2(15)`,log2(-(2)) AS `log2(-2)`,log2(0) AS `log2(0)`,log2(NULL) AS `log2(NULL)` select log10(100),log10(18),log10(-4),log10(0),log10(NULL); log10(100) log10(18) log10(-4) log10(0) log10(NULL) -2 1.2552725051033 NULL NULL NULL +2 1.25527250510331 NULL NULL NULL explain extended select log10(100),log10(18),log10(-4),log10(0),log10(NULL); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used @@ -85,7 +85,7 @@ Note 1003 select pow(10,log10(10)) AS `pow(10,log10(10))`,pow(2,4) AS `power(2,4 set @@rand_seed1=10000000,@@rand_seed2=1000000; select rand(999999),rand(); rand(999999) rand() -0.014231365187309 0.028870999839968 +0.0142313651873091 0.028870999839968 explain extended select rand(999999),rand(); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used @@ -101,7 +101,7 @@ Warnings: Note 1003 select pi() AS `pi()`,format(sin((pi() / 2)),6) AS `format(sin(pi()/2),6)`,format(cos((pi() / 2)),6) AS `format(cos(pi()/2),6)`,format(abs(tan(pi())),6) AS `format(abs(tan(pi())),6)`,format((1 / tan(1)),6) AS `format(cot(1),6)`,format(asin(1),6) AS `format(asin(1),6)`,format(acos(0),6) AS `format(acos(0),6)`,format(atan(1),6) AS `format(atan(1),6)` select degrees(pi()),radians(360); degrees(pi()) radians(360) -180 6.2831853071796 +180 6.28318530717959 SELECT ACOS(1.0); ACOS(1.0) 0 @@ -321,7 +321,7 @@ mod(5, cast(-2 as unsigned)) mod(5, 18446744073709551614) mod(5, -2) 5 5 1 select pow(cast(-2 as unsigned), 5), pow(18446744073709551614, 5), pow(-2, 5); pow(cast(-2 as unsigned), 5) pow(18446744073709551614, 5) pow(-2, 5) -2.1359870359209e+96 2.1359870359209e+96 -32 +2.13598703592091e+96 2.13598703592091e+96 -32 CREATE TABLE t1 (a timestamp, b varchar(20), c bit(1)); INSERT INTO t1 VALUES('1998-09-23', 'str1', 1), ('2003-03-25', 'str2', 0); SELECT a DIV 900 y FROM t1 GROUP BY y; diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index c121c8937d7..b8d915d0c4f 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1131,10 +1131,10 @@ cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2)) 20.06 select conv("18383815659218730760",10,10) + 0; conv("18383815659218730760",10,10) + 0 -1.8383815659219e+19 +1.83838156592187e+19 select "18383815659218730760" + 0; "18383815659218730760" + 0 -1.8383815659219e+19 +1.83838156592187e+19 CREATE TABLE t1 (code varchar(10)); INSERT INTO t1 VALUES ('a12'), ('A12'), ('a13'); SELECT ASCII(code), code FROM t1 WHERE code='A12'; diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index ac6356f8203..e3b2ea751d9 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -284,7 +284,7 @@ Note 1003 select astext(startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint SELECT fid, AsText(Centroid(g)) FROM gis_polygon; fid AsText(Centroid(g)) 108 POINT(15 15) -109 POINT(25.416666666667 25.416666666667) +109 POINT(25.4166666666667 25.4166666666667) 110 POINT(20 10) SELECT fid, Area(g) FROM gis_polygon; fid Area(g) @@ -318,8 +318,8 @@ fid IsClosed(g) 116 0 SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon; fid AsText(Centroid(g)) -117 POINT(55.588527753042 17.426536064114) -118 POINT(55.588527753042 17.426536064114) +117 POINT(55.5885277530424 17.426536064114) +118 POINT(55.5885277530424 17.426536064114) 119 POINT(2 2) SELECT fid, Area(g) FROM gis_multi_polygon; fid Area(g) @@ -651,11 +651,11 @@ insert into t1 values ('85984',GeomFromText('MULTIPOLYGON(((-115.006363 select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from t1 where object_id=85998; object_id geometrytype(geo) ISSIMPLE(GEO) ASTEXT(centroid(geo)) -85998 MULTIPOLYGON 0 POINT(115.31877315203 -36.237472821022) +85998 MULTIPOLYGON 0 POINT(115.318773152032 -36.2374728210215) select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from t1 where object_id=85984; object_id geometrytype(geo) ISSIMPLE(GEO) ASTEXT(centroid(geo)) -85984 MULTIPOLYGON 0 POINT(-114.87787186923 36.33101763469) +85984 MULTIPOLYGON 0 POINT(-114.877871869233 36.3310176346905) drop table t1; create table t1 (fl geometry not null); insert into t1 values (1); diff --git a/mysql-test/r/innodb_gis.result b/mysql-test/r/innodb_gis.result index bfe8c984b7b..0f2607e9787 100644 --- a/mysql-test/r/innodb_gis.result +++ b/mysql-test/r/innodb_gis.result @@ -291,7 +291,7 @@ Note 1003 select astext(startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint SELECT fid, AsText(Centroid(g)) FROM gis_polygon ORDER by fid; fid AsText(Centroid(g)) 108 POINT(15 15) -109 POINT(25.416666666667 25.416666666667) +109 POINT(25.4166666666667 25.4166666666667) 110 POINT(20 10) SELECT fid, Area(g) FROM gis_polygon ORDER by fid; fid Area(g) @@ -325,8 +325,8 @@ fid IsClosed(g) 116 0 SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid; fid AsText(Centroid(g)) -117 POINT(55.588527753042 17.426536064114) -118 POINT(55.588527753042 17.426536064114) +117 POINT(55.5885277530424 17.426536064114) +118 POINT(55.5885277530424 17.426536064114) 119 POINT(2 2) SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid; fid Area(g) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 67ce231a157..9558b0533ad 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2790,26 +2790,26 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away select max(key1) from t1 where key1 <= 0.6158; max(key1) -0.61580002307892 +0.615800023078918 select max(key2) from t2 where key2 <= 1.6158; max(key2) -1.6158000230789 +1.61580002307892 select min(key1) from t1 where key1 >= 0.3762; min(key1) -0.37619999051094 +0.376199990510941 select min(key2) from t2 where key2 >= 1.3762; min(key2) -1.3761999607086 +1.37619996070862 select max(key1), min(key2) from t1, t2 where key1 <= 0.6158 and key2 >= 1.3762; max(key1) min(key2) -0.61580002307892 1.3761999607086 +0.615800023078918 1.37619996070862 select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; max(key1) -0.61580002307892 +0.615800023078918 select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; min(key1) -0.37619999051094 +0.376199990510941 DROP TABLE t1,t2; create table t1(a bigint unsigned, b bigint); insert into t1 values (0xfffffffffffffffff, 0xfffffffffffffffff), diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index ec00435548c..bfa2f51e4fc 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -581,7 +581,7 @@ return 2.7182818284590452354| set @e = e()| select e(), @e| e() @e -2.718281828459 2.718281828459 +2.71828182845905 2.71828182845905 drop function if exists inc| create function inc(i int) returns int return i+1| @@ -618,7 +618,7 @@ create function fun(d double, i int, u int unsigned) returns double return mul(inc(i), fac(u)) / e()| select fun(2.3, 3, 5)| fun(2.3, 3, 5) -176.58213176229 +176.582131762292 insert into t2 values (append("xxx", "yyy"), mul(4,3), e())| insert into t2 values (append("a", "b"), mul(2,mul(3,4)), fun(1.7, 4, 6))| select * from t2 where s = append("a", "b")| @@ -5972,9 +5972,9 @@ CREATE TABLE t3 (f1 INT, f2 FLOAT)| INSERT INTO t3 VALUES (1, 3.4), (1, 2), (1, 0.9), (2, 8), (2, 7)| SELECT SUM(f2), bug25373(f1) FROM t3 GROUP BY bug25373(f1) WITH ROLLUP| SUM(f2) bug25373(f1) -6.3000000715256 1 +6.30000007152557 1 15 2 -21.300000071526 NULL +21.3000000715256 NULL DROP FUNCTION bug25373| DROP TABLE t3| DROP DATABASE IF EXISTS mysqltest1| diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 8caabbff047..757cd6f5d71 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -385,12 +385,12 @@ Warning 1264 Out of range value adjusted for column 'f1' at row 1 Warning 1264 Out of range value adjusted for column 'f1' at row 2 select f1 + 0e0 from t1; f1 + 0e0 -1.0000000150475e+29 --1.0000000150475e+29 -1.0000000150475e+30 --1.0000000150475e+30 -1.0000000150475e+30 --1.0000000150475e+30 +1.00000001504747e+29 +-1.00000001504747e+29 +1.00000001504747e+30 +-1.00000001504747e+30 +1.00000001504747e+30 +-1.00000001504747e+30 drop table t1; create table t1(d double, u bigint unsigned); insert into t1(d) values (9.22337203685479e18), @@ -401,4 +401,9 @@ u 9223372036854790144 18400000000000000000 drop table t1; +CREATE TABLE t1 (f1 DOUBLE); +INSERT INTO t1 VALUES(-1.79769313486231e+308); +SELECT f1 FROM t1; +f1 +-1.79769313486231e+308 End of 5.0 tests diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 53bcf44061d..42703e11863 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -267,4 +267,12 @@ select u from t1; drop table t1; +# +# Bug #21205: Different number of digits for float/doble/real in --ps-protocol +# + +CREATE TABLE t1 (f1 DOUBLE); +INSERT INTO t1 VALUES(-1.79769313486231e+308); +SELECT f1 FROM t1; + --echo End of 5.0 tests diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 75e47dd0c8e..a7d6d5db411 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -125,7 +125,7 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs) str_charset=cs; if (decimals >= NOT_FIXED_DEC) { - uint32 len= my_sprintf(buff,(buff, "%.14g",num));// Enough for a DATETIME + uint32 len= my_sprintf(buff,(buff, "%.15g",num));// Enough for a DATETIME return copy(buff, len, &my_charset_latin1, cs, &dummy_errors); } #ifdef HAVE_FCONVERT @@ -677,7 +677,7 @@ void String::qs_append(const char *str, uint32 len) void String::qs_append(double d) { char *buff = Ptr + str_length; - str_length+= my_sprintf(buff, (buff, "%.14g", d)); + str_length+= my_sprintf(buff, (buff, "%.15g", d)); } void String::qs_append(double *d) -- cgit v1.2.1 From 39f8dd37216f78e86fdefc864f7f7227a563306a Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Wed, 28 Jan 2009 22:46:45 +0400 Subject: Bug #39069: IN seriously messed up "ROW(...) IN (SELECT ... FROM DUAL)" always returned TRUE. Item_in_subselect::row_value_transformer rewrites "ROW(...) IN SELECT" conditions into the "EXISTS (SELECT ... HAVING ...)" form. For a subquery from the DUAL pseudotable resulting HAVING condition is an expression on constant values, so further transformation with optimize_cond() eliminates this HAVING condition and resets JOIN::having to NULL. Then JOIN::exec treated that NULL as an always-true-HAVING and that caused a bug. To distinguish an optimized out "HAVING TRUE" clause from "HAVING FALSE" we already have the JOIN::having_value flag. However, JOIN::exec() ignored JOIN::having_value as described above as if it always set to COND_TRUE. The JOIN::exec method has been modified to take into account the value of the JOIN::having_value field. mysql-test/r/subselect3.result: Added test case for bug #39069. mysql-test/t/subselect3.test: Added test case for bug #39069. sql/sql_select.cc: Bug #39069: IN seriously messed up The JOIN::exec method has been modified to take into account the value of the JOIN::having_value field. --- mysql-test/r/subselect3.result | 54 ++++++++++++++++++++++++++++++++++++++++++ mysql-test/t/subselect3.test | 29 +++++++++++++++++++++++ sql/sql_select.cc | 5 ++++ 3 files changed, 88 insertions(+) diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index 97479418bec..9a6f4436ff0 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -795,4 +795,58 @@ WHERE INNR.varchar_key > 'n{' ); varchar_nokey DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1), (2), (11); +# 2nd and 3rd columns should be same +SELECT a, ROW(11, 12) = (SELECT a, 22), ROW(11, 12) IN (SELECT a, 22) FROM t1 GROUP BY t1.a; +a ROW(11, 12) = (SELECT a, 22) ROW(11, 12) IN (SELECT a, 22) +1 0 0 +2 0 0 +11 0 0 +SELECT a, ROW(11, 12) = (SELECT a, 12), ROW(11, 12) IN (SELECT a, 12) FROM t1 GROUP BY t1.a; +a ROW(11, 12) = (SELECT a, 12) ROW(11, 12) IN (SELECT a, 12) +1 0 0 +2 0 0 +11 1 1 +SELECT a, ROW(11, 12) = (SELECT a, 22), ROW(11, 12) IN (SELECT a, 22) FROM t1; +a ROW(11, 12) = (SELECT a, 22) ROW(11, 12) IN (SELECT a, 22) +1 0 0 +2 0 0 +11 0 0 +SELECT a, ROW(11, 12) = (SELECT a, 12), ROW(11, 12) IN (SELECT a, 12) FROM t1; +a ROW(11, 12) = (SELECT a, 12) ROW(11, 12) IN (SELECT a, 12) +1 0 0 +2 0 0 +11 1 1 +SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 22), ROW(11, 12) IN (SELECT MAX(x), 22) FROM t1; +x ROW(11, 12) = (SELECT MAX(x), 22) ROW(11, 12) IN (SELECT MAX(x), 22) +1 0 0 +2 0 0 +11 0 0 +# 2nd and 3rd columns should be same for x == 11 only +SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 12), ROW(11, 12) IN (SELECT MAX(x), 12) FROM t1; +x ROW(11, 12) = (SELECT MAX(x), 12) ROW(11, 12) IN (SELECT MAX(x), 12) +1 0 1 +2 0 1 +11 1 1 +DROP TABLE t1; +# both columns should be same +SELECT ROW(1,2) = (SELECT NULL, NULL), ROW(1,2) IN (SELECT NULL, NULL); +ROW(1,2) = (SELECT NULL, NULL) ROW(1,2) IN (SELECT NULL, NULL) +NULL NULL +SELECT ROW(1,2) = (SELECT 1, NULL), ROW(1,2) IN (SELECT 1, NULL); +ROW(1,2) = (SELECT 1, NULL) ROW(1,2) IN (SELECT 1, NULL) +NULL NULL +SELECT ROW(1,2) = (SELECT NULL, 2), ROW(1,2) IN (SELECT NULL, 2); +ROW(1,2) = (SELECT NULL, 2) ROW(1,2) IN (SELECT NULL, 2) +NULL NULL +SELECT ROW(1,2) = (SELECT NULL, 1), ROW(1,2) IN (SELECT NULL, 1); +ROW(1,2) = (SELECT NULL, 1) ROW(1,2) IN (SELECT NULL, 1) +0 0 +SELECT ROW(1,2) = (SELECT 1, 1), ROW(1,2) IN (SELECT 1, 1); +ROW(1,2) = (SELECT 1, 1) ROW(1,2) IN (SELECT 1, 1) +0 0 +SELECT ROW(1,2) = (SELECT 1, 2), ROW(1,2) IN (SELECT 1, 2); +ROW(1,2) = (SELECT 1, 2) ROW(1,2) IN (SELECT 1, 2) +1 1 End of 5.0 tests diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test index 7e9aa1554c0..2d88d1660b0 100644 --- a/mysql-test/t/subselect3.test +++ b/mysql-test/t/subselect3.test @@ -640,4 +640,33 @@ WHERE NULL NOT IN ( DROP TABLE t1; +# +# Bug #39069: IN seriously messed up +# + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1), (2), (11); + +--echo # 2nd and 3rd columns should be same +SELECT a, ROW(11, 12) = (SELECT a, 22), ROW(11, 12) IN (SELECT a, 22) FROM t1 GROUP BY t1.a; +SELECT a, ROW(11, 12) = (SELECT a, 12), ROW(11, 12) IN (SELECT a, 12) FROM t1 GROUP BY t1.a; +SELECT a, ROW(11, 12) = (SELECT a, 22), ROW(11, 12) IN (SELECT a, 22) FROM t1; +SELECT a, ROW(11, 12) = (SELECT a, 12), ROW(11, 12) IN (SELECT a, 12) FROM t1; + +# The x alias is used below to workaround bug #40674. +# Regression tests for sum function on outer column in subselect from dual: +SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 22), ROW(11, 12) IN (SELECT MAX(x), 22) FROM t1; +--echo # 2nd and 3rd columns should be same for x == 11 only +SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 12), ROW(11, 12) IN (SELECT MAX(x), 12) FROM t1; + +DROP TABLE t1; + +--echo # both columns should be same +SELECT ROW(1,2) = (SELECT NULL, NULL), ROW(1,2) IN (SELECT NULL, NULL); +SELECT ROW(1,2) = (SELECT 1, NULL), ROW(1,2) IN (SELECT 1, NULL); +SELECT ROW(1,2) = (SELECT NULL, 2), ROW(1,2) IN (SELECT NULL, 2); +SELECT ROW(1,2) = (SELECT NULL, 1), ROW(1,2) IN (SELECT NULL, 1); +SELECT ROW(1,2) = (SELECT 1, 1), ROW(1,2) IN (SELECT 1, 1); +SELECT ROW(1,2) = (SELECT 1, 2), ROW(1,2) IN (SELECT 1, 2); + --echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 53e24414f01..74d1158d8b7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1608,8 +1608,13 @@ JOIN::exec() We have to test for 'conds' here as the WHERE may not be constant even if we don't have any tables for prepared statements or if conds uses something like 'rand()'. + If the HAVING clause is either impossible or always true, then + JOIN::having is set to NULL by optimize_cond. + In this case JOIN::exec must check for JOIN::having_value, in the + same way it checks for JOIN::cond_value. */ if (cond_value != Item::COND_FALSE && + having_value != Item::COND_FALSE && (!conds || conds->val_int()) && (!having || having->val_int())) { -- cgit v1.2.1 From 2206b2dfb8ab8ba5a09500e70cd8f1a5e11c745f Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 29 Jan 2009 14:40:48 +0200 Subject: Bug #35396: Abnormal query times in slow query log If the system time is adjusted back during a query execution (resulting in the end time being earlier than the start time) the code that prints to the slow query log gets confused and prints unsigned negative numbers. Fixed by not logging the statements that would have negative execution time due to time shifts. No test case since this would involve changing the system time. sql/sql_parse.cc: Bug #35396: don't log queries with negative execution times (due to shifts in system time). --- sql/sql_parse.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 91c5cacc4d0..1d3632fd468 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2333,8 +2333,9 @@ void log_slow_statement(THD *thd) { thd->proc_info="logging slow query"; - if ((ulong) (thd->start_time - thd->time_after_lock) > - thd->variables.long_query_time || + if ((thd->start_time > thd->time_after_lock && + (ulong) (thd->start_time - thd->time_after_lock) > + thd->variables.long_query_time) || (thd->server_status & (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && opt_log_queries_not_using_indexes && -- cgit v1.2.1 From 3768150234ded41e995dffd559241b158d477141 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Thu, 29 Jan 2009 22:43:52 +0100 Subject: Raise the version number in this (enterprise) tree, 5.0.77 will be a community build. --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index ff0e9de9ec2..12c31b33d1b 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.77) +AM_INIT_AUTOMAKE(mysql, 5.0.78) 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=77 +NDB_VERSION_BUILD=78 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? -- cgit v1.2.1 From 5fa806caaadaf92633f7398a08395f3d8c56eaf0 Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Fri, 30 Jan 2009 17:12:24 +0100 Subject: Bug#41370: TIMESTAMP field does not accepts NULL from FROM_UNIXTIME() When storing a NULL to a TIMESTAMP NOT NULL DEFAULT ..., NULL returned from some functions threw a 'cannot be NULL error.' NULL-returns now correctly result in the timestamp-field being assigned its default value. mysql-test/r/type_timestamp.result: Show that for TIMESTAMP NOT NULL DEFAULT, NULL function returns set default now. mysql-test/t/type_timestamp.test: Show that for TIMESTAMP NOT NULL DEFAULT, NULL function returns set default now. sql/item.cc: When storing a returned NULL (from a time- or date-related function), make sure to apply NULL-means-DEFAULT magic where applicable. --- mysql-test/r/type_timestamp.result | 19 +++++++++++++++++++ mysql-test/t/type_timestamp.test | 20 +++++++++++++++++++- sql/item.cc | 4 ++-- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index 445ada578d0..59900fe4a77 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -492,6 +492,7 @@ a b c 5 NULL 2001-09-09 04:46:59 6 NULL 2006-06-06 06:06:06 drop table t1; +End of 4.1 tests set time_zone= @@global.time_zone; CREATE TABLE t1 ( `id` int(11) NOT NULL auto_increment, @@ -508,3 +509,21 @@ select is_nullable from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='t1' and COL is_nullable NO drop table t1; +CREATE TABLE t1 ( f1 INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, +f2 TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, +f3 TIMESTAMP); +INSERT INTO t1 (f2,f3) VALUES (NOW(), "0000-00-00 00:00:00"); +INSERT INTO t1 (f2,f3) VALUES (NOW(), NULL); +INSERT INTO t1 (f2,f3) VALUES (NOW(), ASCII(NULL)); +INSERT INTO t1 (f2,f3) VALUES (NOW(), FROM_UNIXTIME('9999999999')); +INSERT INTO t1 (f2,f3) VALUES (NOW(), TIME(NULL)); +UPDATE t1 SET f2=NOW(), f3=FROM_UNIXTIME('9999999999') WHERE f1=1; +SELECT f1,f2-f3 FROM t1; +f1 f2-f3 +1 0 +2 0 +3 0 +4 0 +5 0 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index 7b4af9e0c69..ce1d3f21ff5 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -324,7 +324,7 @@ insert into t1 (a, c) values (4, '2004-04-04 00:00:00'), select * from t1; drop table t1; -# End of 4.1 tests +--echo End of 4.1 tests # Restore timezone to default set time_zone= @@global.time_zone; @@ -339,3 +339,21 @@ PRIMARY KEY (`id`) show fields from t1; select is_nullable from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='t1' and COLUMN_NAME='posted_on'; drop table t1; + +# +# Bug#41370: TIMESTAMP field does not accepts NULL from FROM_UNIXTIME() +# + +CREATE TABLE t1 ( f1 INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + f2 TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + f3 TIMESTAMP); +INSERT INTO t1 (f2,f3) VALUES (NOW(), "0000-00-00 00:00:00"); +INSERT INTO t1 (f2,f3) VALUES (NOW(), NULL); +INSERT INTO t1 (f2,f3) VALUES (NOW(), ASCII(NULL)); +INSERT INTO t1 (f2,f3) VALUES (NOW(), FROM_UNIXTIME('9999999999')); +INSERT INTO t1 (f2,f3) VALUES (NOW(), TIME(NULL)); +UPDATE t1 SET f2=NOW(), f3=FROM_UNIXTIME('9999999999') WHERE f1=1; +SELECT f1,f2-f3 FROM t1; +DROP TABLE t1; + +--echo End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index 2a89c86cd88..977c5f0b7c0 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -321,7 +321,7 @@ int Item::save_time_in_field(Field *field) { MYSQL_TIME ltime; if (get_time(<ime)) - return set_field_to_null(field); + return set_field_to_null_with_conversions(field, 0); field->set_notnull(); return field->store_time(<ime, MYSQL_TIMESTAMP_TIME); } @@ -331,7 +331,7 @@ int Item::save_date_in_field(Field *field) { MYSQL_TIME ltime; if (get_date(<ime, TIME_FUZZY_DATE)) - return set_field_to_null(field); + return set_field_to_null_with_conversions(field, 0); field->set_notnull(); return field->store_time(<ime, MYSQL_TIMESTAMP_DATETIME); } -- cgit v1.2.1 From 3913a257bfabe2873fbd0eed1180b76f4f512587 Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Mon, 2 Feb 2009 18:19:07 +0100 Subject: Bug#33550: mysqldump 4.0 compatibility broken mysqldump included character_set_client magic that is unknown before 4.1 even when asked for an appropriate compatibility mode. In compatibility (3.23, 4.0) mode, we do not output charset statements (not even in a "comment conditional"), nor do we do magic on the server, even if the server is sufficient new (4.1+). Table-names will be output converted to the charset requested by mysqldump; if such a conversion is not possible (Ivrit -> Latin), mysqldump will fail. client/mysqldump.c: in 3.23/4.0 compat mode, don't do charset magic, period. not in output, but not on the server, either! mysql-test/r/mysqldump-max.result: character_set_client magic lives in version-conditional now (except in compat 3.23/4.0 mode, in which case we don't output any at all!). mysql-test/r/mysqldump.result: character_set_client magic lives in version-conditional now (except in compat 3.23/4.0 mode, in which case we don't output any at all!). mysql-test/r/openssl_1.result: character_set_client magic lives in version-conditional now (except in compat 3.23/4.0 mode, in which case we don't output any at all!). mysql-test/t/mysqldump.test: character_set_client magic lives in version-conditional now (except in compat 3.23/4.0 mode, in which case we don't output any at all!). --- client/mysqldump.c | 11 +- mysql-test/r/mysqldump-max.result | 72 +++---- mysql-test/r/mysqldump.result | 422 ++++++++++++++++++++++---------------- mysql-test/r/openssl_1.result | 18 +- mysql-test/t/mysqldump.test | 18 ++ 5 files changed, 311 insertions(+), 230 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index ced34f16212..97e8d6ed5ef 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1129,7 +1129,8 @@ static int connect_to_db(char *host, char *user,char *passwd) DB_error(&mysql_connection, "when trying to connect"); DBUG_RETURN(1); } - if (mysql_get_server_version(&mysql_connection) < 40100) + if ((mysql_get_server_version(&mysql_connection) < 40100) || + (opt_compatible_mode & 3)) { /* Don't dump SET NAMES with a pre-4.1 server (bug#7997). */ opt_set_charset= 0; @@ -1857,11 +1858,11 @@ static uint get_table_structure(char *table, char *db, char *table_type, row= mysql_fetch_row(result); - fprintf(sql_file, - "SET @saved_cs_client = @@character_set_client;\n" - "SET character_set_client = utf8;\n" + fprintf(sql_file, (opt_compatible_mode & 3) ? "%s;\n" : + "/*!40101 SET @saved_cs_client = @@character_set_client */;\n" + "/*!40101 SET character_set_client = utf8 */;\n" "%s;\n" - "SET character_set_client = @saved_cs_client;\n", + "/*!40101 SET character_set_client = @saved_cs_client */;\n", row[1]); check_io(sql_file); diff --git a/mysql-test/r/mysqldump-max.result b/mysql-test/r/mysqldump-max.result index 261c7a7f197..b3a966b9b39 100644 --- a/mysql-test/r/mysqldump-max.result +++ b/mysql-test/r/mysqldump-max.result @@ -93,73 +93,73 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `id` int(8) default NULL, `name` varchar(32) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; INSERT DELAYED IGNORE INTO `t1` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value'); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; DROP TABLE IF EXISTS `t2`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t2` ( `id` int(8) default NULL, `name` varchar(32) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; INSERT DELAYED IGNORE INTO `t2` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value'); /*!40000 ALTER TABLE `t2` ENABLE KEYS */; DROP TABLE IF EXISTS `t3`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t3` ( `id` int(8) default NULL, `name` varchar(32) default NULL ) ENGINE=MEMORY DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t3` DISABLE KEYS */; INSERT DELAYED IGNORE INTO `t3` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value'); /*!40000 ALTER TABLE `t3` ENABLE KEYS */; DROP TABLE IF EXISTS `t4`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t4` ( `id` int(8) default NULL, `name` varchar(32) default NULL ) ENGINE=MEMORY DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t4` DISABLE KEYS */; INSERT DELAYED IGNORE INTO `t4` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value'); /*!40000 ALTER TABLE `t4` ENABLE KEYS */; DROP TABLE IF EXISTS `t5`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t5` ( `id` int(8) default NULL, `name` varchar(32) default NULL ) ENGINE=ARCHIVE DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t5` DISABLE KEYS */; INSERT DELAYED IGNORE INTO `t5` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value'); /*!40000 ALTER TABLE `t5` ENABLE KEYS */; DROP TABLE IF EXISTS `t6`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t6` ( `id` int(8) default NULL, `name` varchar(32) default NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t6` DISABLE KEYS */; INSERT IGNORE INTO `t6` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value'); @@ -190,73 +190,73 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `id` int(8) default NULL, `name` varchar(32) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; INSERT DELAYED INTO `t1` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value'); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; DROP TABLE IF EXISTS `t2`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t2` ( `id` int(8) default NULL, `name` varchar(32) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; INSERT DELAYED INTO `t2` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value'); /*!40000 ALTER TABLE `t2` ENABLE KEYS */; DROP TABLE IF EXISTS `t3`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t3` ( `id` int(8) default NULL, `name` varchar(32) default NULL ) ENGINE=MEMORY DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t3` DISABLE KEYS */; INSERT DELAYED INTO `t3` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value'); /*!40000 ALTER TABLE `t3` ENABLE KEYS */; DROP TABLE IF EXISTS `t4`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t4` ( `id` int(8) default NULL, `name` varchar(32) default NULL ) ENGINE=MEMORY DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t4` DISABLE KEYS */; INSERT DELAYED INTO `t4` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value'); /*!40000 ALTER TABLE `t4` ENABLE KEYS */; DROP TABLE IF EXISTS `t5`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t5` ( `id` int(8) default NULL, `name` varchar(32) default NULL ) ENGINE=ARCHIVE DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t5` DISABLE KEYS */; INSERT DELAYED INTO `t5` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value'); /*!40000 ALTER TABLE `t5` ENABLE KEYS */; DROP TABLE IF EXISTS `t6`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t6` ( `id` int(8) default NULL, `name` varchar(32) default NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t6` DISABLE KEYS */; INSERT INTO `t6` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value'); diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 08a18d8de75..8b7e8f4430f 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -33,12 +33,12 @@ DROP TABLE t1; CREATE TABLE t1 (a decimal(64, 20)); INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), ("0987654321098765432109876543210987654321"); -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` decimal(64,20) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t1` VALUES ('1234567890123456789012345678901234567890.00000000000000000000'),('987654321098765432109876543210987654321.00000000000000000000'); DROP TABLE t1; # @@ -48,12 +48,12 @@ CREATE TABLE t1 (a double); INSERT INTO t1 VALUES ('-9e999999'); Warnings: Warning 1264 Out of range value adjusted for column 'a' at row 1 -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` double default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t1` VALUES (RES); DROP TABLE t1; # @@ -69,21 +69,21 @@ INSERT INTO t1 VALUES ('1.2345', 2.3456); INSERT INTO t1 VALUES ("1.2345", 2.3456); ERROR 42S22: Unknown column '1.2345' in 'field list' SET SQL_MODE=@OLD_SQL_MODE; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` decimal(10,5) default NULL, `b` float default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t1` VALUES ('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456); -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` decimal(10,5) default NULL, `b` float default NULL ); -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t1` VALUES ('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456); /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; @@ -97,13 +97,13 @@ INSERT INTO `t1` VALUES ('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456) /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` decimal(10,5) default NULL, `b` float default NULL ); -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -126,13 +126,13 @@ UNLOCK TABLES; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` decimal(10,5) default NULL, `b` float default NULL ); -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t1` VALUES ('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456); /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; @@ -208,12 +208,12 @@ INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'), (NULL); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` varchar(255) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=koi8r; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -244,12 +244,9 @@ INSERT INTO t1 VALUES (1), (2); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL40' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; CREATE TABLE `t1` ( `a` int(11) default NULL ) TYPE=MyISAM; -SET character_set_client = @saved_cs_client; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -270,12 +267,9 @@ UNLOCK TABLES; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; CREATE TABLE `t1` ( `a` int(11) default NULL ) TYPE=MyISAM; -SET character_set_client = @saved_cs_client; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -294,12 +288,12 @@ DROP TABLE t1; # Bug #2592 'mysqldump doesn't quote "tricky" names correctly' # create table ```a` (i int); -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE ```a` ( `i` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; drop table ```a`; # # Bug #2591 "mysqldump quotes names inconsistently" @@ -317,12 +311,12 @@ create table t1(a int); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -345,12 +339,12 @@ UNLOCK TABLES; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS "t1"; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE "t1" ( "a" int(11) default NULL ); -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES "t1" WRITE; /*!40000 ALTER TABLE "t1" DISABLE KEYS */; @@ -376,12 +370,12 @@ set global sql_mode='ANSI_QUOTES'; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -404,12 +398,12 @@ UNLOCK TABLES; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS "t1"; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE "t1" ( "a" int(11) default NULL ); -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES "t1" WRITE; /*!40000 ALTER TABLE "t1" DISABLE KEYS */; @@ -439,12 +433,12 @@ insert into t1 values (1),(2),(3); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; @@ -533,12 +527,12 @@ INSERT INTO t1 VALUES (_latin1 ' /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` char(10) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -569,12 +563,9 @@ UNLOCK TABLES; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; CREATE TABLE `t1` ( `a` char(10) default NULL ) TYPE=MyISAM; -SET character_set_client = @saved_cs_client; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -595,12 +586,9 @@ UNLOCK TABLES; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; CREATE TABLE `t1` ( `a` char(10) default NULL ) TYPE=MyISAM; -SET character_set_client = @saved_cs_client; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -621,12 +609,9 @@ UNLOCK TABLES; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; CREATE TABLE `t1` ( `a` char(10) default NULL ) TYPE=MyISAM; -SET character_set_client = @saved_cs_client; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -660,12 +645,12 @@ INSERT INTO t2 VALUES (4),(5),(6); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t2`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t2` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; @@ -701,12 +686,12 @@ INSERT INTO `t1` VALUES (0x602010000280100005E71A); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `b` blob ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -742,12 +727,12 @@ INSERT INTO t1 VALUES (4),(5),(6); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -776,12 +761,12 @@ UNLOCK TABLES; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; INSERT DELAYED IGNORE INTO `t1` VALUES (1),(2),(3),(4),(5),(6); @@ -1145,8 +1130,8 @@ insert into t1 (F_8d3bba7425e7c98c50f52ca1b52d3735) values (1); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `F_c4ca4238a0b923820dcc509a6f75849b` int(11) default NULL, `F_c81e728d9d4c2f636f067f89cc14862c` int(11) default NULL, @@ -1479,7 +1464,7 @@ CREATE TABLE `t1` ( `F_6faa8040da20ef399b63a72d0e4ab575` int(11) default NULL, `F_fe73f687e5bc5280214e0486b273a5f9` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -1520,12 +1505,12 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -1564,19 +1549,19 @@ INSERT INTO t2 VALUES (1), (2); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `t2`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t2` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -1599,19 +1584,19 @@ SET character_set_client = @saved_cs_client; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `t2`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t2` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -1811,26 +1796,26 @@ create table t3(a int); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t3`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t3` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `t2`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t2` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -1860,12 +1845,12 @@ mysqldump: Got error: 1064: You have an error in your SQL syntax; check the manu /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; @@ -1896,15 +1881,15 @@ insert into t1 values (0815, 4711, 2006); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS "t1"; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE "t1" ( "a b" int(11) NOT NULL default '0', "c""d" int(11) NOT NULL default '0', "e`f" int(11) NOT NULL default '0', PRIMARY KEY ("a b","c""d","e`f") ); -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES "t1" WRITE; /*!40000 ALTER TABLE "t1" DISABLE KEYS */; @@ -1930,15 +1915,15 @@ UNLOCK TABLES; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a b` int(11) NOT NULL default '0', `c"d` int(11) NOT NULL default '0', `e``f` int(11) NOT NULL default '0', PRIMARY KEY (`a b`,`c"d`,`e``f`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -1984,13 +1969,13 @@ create view v2 as select * from t2 where a like 'a%' with check option; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t2`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t2` ( `a` varchar(30) default NULL, KEY `a` (`a`(5)) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; @@ -2068,12 +2053,12 @@ create view v1 as select * from t1; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -2128,13 +2113,13 @@ create view v2 as select * from t2 where a like 'a%' with check option; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t2`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t2` ( `a` varchar(30) default NULL, KEY `a` (`a`(5)) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; @@ -2183,12 +2168,12 @@ INSERT INTO t1 VALUES ('\''); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` char(10) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -2229,14 +2214,14 @@ select v3.a from v3, v1 where v1.a=v3.a and v3.b=3 limit 1; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL, `b` int(11) default NULL, `c` varchar(30) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -2352,13 +2337,13 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL, `b` bigint(20) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -2392,12 +2377,12 @@ end */;; DELIMITER ; /*!50003 SET SESSION SQL_MODE=@SAVE_SQL_MODE*/; DROP TABLE IF EXISTS `t2`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t2` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; @@ -2442,13 +2427,13 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL, `b` bigint(20) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -2456,12 +2441,12 @@ INSERT INTO `t1` VALUES (1,NULL),(2,NULL),(4,NULL),(11,NULL); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; DROP TABLE IF EXISTS `t2`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t2` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; @@ -2585,12 +2570,12 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `id` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -2678,13 +2663,13 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `d` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, UNIQUE KEY `d` (`d`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -2715,13 +2700,13 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `d` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, UNIQUE KEY `d` (`d`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -2768,12 +2753,12 @@ a2 /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS "t1 test"; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE "t1 test" ( "a1" int(11) default NULL ); -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES "t1 test" WRITE; /*!40000 ALTER TABLE "t1 test" DISABLE KEYS */; @@ -2791,12 +2776,12 @@ INSERT INTO `t2 test` SET a2 = NEW.a1; END */;; DELIMITER ; /*!50003 SET SESSION SQL_MODE=@SAVE_SQL_MODE*/; DROP TABLE IF EXISTS "t2 test"; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE "t2 test" ( "a2" int(11) default NULL ); -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES "t2 test" WRITE; /*!40000 ALTER TABLE "t2 test" DISABLE KEYS */; @@ -2845,14 +2830,14 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL, `b` varchar(32) default NULL, `c` varchar(32) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -2940,12 +2925,12 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -2991,13 +2976,13 @@ insert into t1 values ('',''); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` binary(1) default NULL, `b` blob ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -3026,13 +3011,13 @@ UNLOCK TABLES; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` binary(1) default NULL, `b` blob ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -3187,12 +3172,12 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_test_db` /*!40100 DEFAULT CH USE `mysqldump_test_db`; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `id` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -3237,14 +3222,14 @@ create view nasishnasifu as select mysqldump_tables.basetable.id from mysqldump_ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_tables` /*!40100 DEFAULT CHARACTER SET latin1 */; USE `mysqldump_tables`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `basetable` ( `id` bigint(20) unsigned NOT NULL auto_increment, `tag` varchar(64) default NULL, UNIQUE KEY `id` (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_views` /*!40100 DEFAULT CHARACTER SET latin1 */; @@ -3312,13 +3297,13 @@ mysqldump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need the SU mysqldump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need the SUPER,REPLICATION CLIENT privilege for this operation (1227) grant REPLICATION CLIENT on *.* to mysqltest_1@localhost; CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=#; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL, `b` varchar(34) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; drop table t1; drop user mysqltest_1@localhost; # @@ -3407,31 +3392,31 @@ CREATE TABLE t1 (a int) ENGINE=merge UNION=(t2, t3); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=(`t2`,`t3`); -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `t2`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t2` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; /*!40000 ALTER TABLE `t2` ENABLE KEYS */; UNLOCK TABLES; DROP TABLE IF EXISTS `t3`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t3` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t3` WRITE; /*!40000 ALTER TABLE `t3` DISABLE KEYS */; @@ -3507,13 +3492,13 @@ drop database mysqldump_test_db; # CREATE TABLE t1 (c1 INT, c2 LONGBLOB); INSERT INTO t1 SET c1=11, c2=REPEAT('q',509); -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `c1` int(11) default NULL, `c2` longblob ); -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t1` VALUES (11,0x7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171); DROP TABLE t1; # @@ -3571,6 +3556,83 @@ DROP TABLE t1,t2; -- Dump completed on DATE SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT; +SET NAMES utf8; +CREATE TABLE `straße` ( f1 INT ); +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `straße`; +CREATE TABLE `straße` ( + `f1` int(11) default NULL +) TYPE=MyISAM; + +LOCK TABLES `straße` WRITE; +/*!40000 ALTER TABLE `straße` DISABLE KEYS */; +/*!40000 ALTER TABLE `straße` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `straße`; +CREATE TABLE `straße` ( + `f1` int(11) default NULL +) TYPE=MyISAM; + +LOCK TABLES `straße` WRITE; +/*!40000 ALTER TABLE `straße` DISABLE KEYS */; +/*!40000 ALTER TABLE `straße` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +DROP TABLE `straße`; +CREATE TABLE `כדשגכחךלדגכחשךדגחכךלדגכ` ( f1 INT ); +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `כדשגכחךלדגכחשךדגחכךלדגכ`; +CREATE TABLE `כדשגכחךלדגכחשךדגחכךלדגכ` ( + `f1` int(11) default NULL +) TYPE=MyISAM; + +LOCK TABLES `כדשגכחךלדגכחשךדגחכךלדגכ` WRITE; +/*!40000 ALTER TABLE `כדשגכחךלדגכחשךדגחכךלדגכ` DISABLE KEYS */; +/*!40000 ALTER TABLE `כדשגכחךלדגכחשךדגחכךלדגכ` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE `כדשגכחךלדגכחשךדגחכךלדגכ`; # # End of 5.0 tests # diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result index 9c6c29eea47..32c8dfeac1c 100644 --- a/mysql-test/r/openssl_1.result +++ b/mysql-test/r/openssl_1.result @@ -77,12 +77,12 @@ INSERT INTO t1 VALUES (1), (2); /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ); -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -111,12 +111,12 @@ UNLOCK TABLES; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ); -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; @@ -145,12 +145,12 @@ UNLOCK TABLES; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( `a` int(11) default NULL ); -SET character_set_client = @saved_cs_client; +/*!40101 SET character_set_client = @saved_cs_client */; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 2f11685385f..5b2af21c691 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1606,6 +1606,24 @@ DROP TABLE t1,t2; SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT; +# +# Bug #33550 - mysqldump 4.0 compatibility broken +# + +SET NAMES utf8; +CREATE TABLE `straße` ( f1 INT ); +--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=utf8 --compatible=mysql323 test +--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=latin1 --compatible=mysql323 test +DROP TABLE `straße`; + +CREATE TABLE `כדשגכחךלדגכחשךדגחכךלדגכ` ( f1 INT ); +--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=utf8 --compatible=mysql323 test +--error 2 +--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=latin1 --compatible=mysql323 test +DROP TABLE `כדשגכחךלדגכחשךדגחכךלדגכ`; + + --echo # --echo # End of 5.0 tests --echo # + -- cgit v1.2.1 From 400900bdc16d55c629e046b806cd9565b8689821 Mon Sep 17 00:00:00 2001 From: Matthias Leich Date: Mon, 2 Feb 2009 22:20:25 +0100 Subject: 1. Slice of fix for Bug#42003 tests missing the disconnect of connections <> default - If missing: add "disconnect " - If physical disconnect of non "default" sessions is not finished at test end: add routine which waits till this happened + additional improvements like - remove superfluous files created by the test - replace error numbers by error names - remove trailing spaces, replace tabs by spaces - unify writing of bugs within comments - correct comments - minor changes of formatting Modifications according to the code review are included. Fixed tests: grant2 grant3 lock_tables_lost_commit mysqldump openssl_1 outfile --- mysql-test/include/count_sessions.inc | 21 +++ mysql-test/include/wait_until_count_sessions.inc | 112 ++++++++++++ mysql-test/r/grant2.result | 23 +-- mysql-test/r/lock_tables_lost_commit.result | 12 +- mysql-test/r/mysqldump.result | 166 ++++++++--------- mysql-test/r/outfile.result | Bin 2135 -> 2134 bytes mysql-test/t/grant2.test | 123 +++++++------ mysql-test/t/grant3.test | 16 +- mysql-test/t/lock_tables_lost_commit.test | 27 ++- mysql-test/t/mysqldump.test | 223 ++++++++++++++--------- mysql-test/t/openssl_1.test | 26 ++- mysql-test/t/outfile.test | 16 +- 12 files changed, 499 insertions(+), 266 deletions(-) create mode 100644 mysql-test/include/count_sessions.inc create mode 100644 mysql-test/include/wait_until_count_sessions.inc diff --git a/mysql-test/include/count_sessions.inc b/mysql-test/include/count_sessions.inc new file mode 100644 index 00000000000..4728e39ce74 --- /dev/null +++ b/mysql-test/include/count_sessions.inc @@ -0,0 +1,21 @@ +# include/count_sessions.inc +# +# SUMMARY +# +# Stores the number of current sessions in $count_sessions. +# +# +# USAGE +# +# Please look into include/wait_until_count_sessions.inc +# for examples of typical usage. +# +# +# EXAMPLE +# backup.test, grant3.test +# +# +# Created: 2009-01-14 mleich +# + +let $count_sessions= query_get_value(SHOW STATUS LIKE 'Threads_connected', Value, 1); diff --git a/mysql-test/include/wait_until_count_sessions.inc b/mysql-test/include/wait_until_count_sessions.inc new file mode 100644 index 00000000000..36fa9accafe --- /dev/null +++ b/mysql-test/include/wait_until_count_sessions.inc @@ -0,0 +1,112 @@ +# include/wait_until_count_sessions.inc +# +# SUMMARY +# +# Waits until the passed number ($count_sessions) of concurrent sessions was +# observed via +# SHOW STATUS LIKE 'Threads_connected' +# or the operation times out. +# Note: Starting with 5.1 we could also use +# SELECT COUNT(*) FROM information_schema.processlist +# I stay with "SHOW STATUS LIKE 'Threads_connected'" because this +# runs in all versions 5.0+ +# +# +# USAGE +# +# let $count_sessions= 3; +# --source include/wait_until_count_sessions.inc +# +# OR typical example of a test which uses more than one session +# Such a test could harm successing tests if there is no server shutdown +# and start between.cw +# +# If the testing box is slow than the disconnect of sessions belonging to +# the current test might happen when the successing test gets executed. +# This means the successing test might see activities like unexpected +# rows within the general log or the PROCESSLIST. +# Example from bug http://bugs.mysql.com/bug.php?id=40377 +# --- bzr_mysql-6.0-rpl/.../r/log_state.result +# +++ bzr_mysql-6.0-rpl/.../r/log_state.reject +# @@ -25,6 +25,7 @@ +# event_time user_host ... command_type argument +# TIMESTAMP USER_HOST ... Query create table t1(f1 int) +# TIMESTAMP USER_HOST ... Query select * from mysql.general_log +# +TIMESTAMP USER_HOST ... Quit +# .... +# +# What to do? +# ----------- +# +# # Determine initial number of connections (set $count_sessions) +# --source include/count_sessions.inc +# ... +# connect (con1,.....) +# ... +# connection default; +# ... +# disconnect con1; +# ... +# # Wait until we have reached the initial number of connections +# # or more than the sleep time above (10 seconds) has passed. +# # $count_sessions +# --source include/wait_until_count_sessions.inc +# +# +# Important note about tests with unfortunate (= not cooperative +# to successing tests) architecture: +# connection con1; +# send SELECT ..., sleep(10) +# connection default; +# ... +# disconnect con1; +# +# should be fixed by +# connection con1; +# send SELECT ..., sleep(10) +# connection default; +# ... +# connect con1; +# reap; +# connection default; +# disconnect con1; +# +# and not only by appending include/wait_until_count_sessions.inc etc. +# +# +# EXAMPLE +# +# backup.test, grant3.test +# +# +# Created: 2009-01-14 mleich +# + +let $wait_counter= 50; +if ($wait_timeout) +{ + let $wait_counter= `SELECT $wait_timeout * 10`; +} +# Reset $wait_timeout so that its value won't be used on subsequent +# calls, and default will be used instead. +let $wait_timeout= 0; +while ($wait_counter) +{ + let $current_sessions= query_get_value(SHOW STATUS LIKE 'Threads_connected', Value, 1); + let $success= `SELECT $current_sessions = $count_sessions`; + if ($success) + { + let $wait_counter= 0; + } + if (!$success) + { + real_sleep 0.1; + dec $wait_counter; + } +} +if (!$success) +{ + --echo # Timeout in wait_until_count_sessions.inc + --echo # Number of sessions expected: $count_sessions found: $current_sessions +} + diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index e3c92ecc7c8..95748c89103 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -366,20 +366,20 @@ insert into mysql.user select * from t1; drop table t1, t2; drop database TESTDB; flush privileges; -grant all privileges on test.* to `a@`@localhost; -grant execute on * to `a@`@localhost; -create table t2 (s1 int); -insert into t2 values (1); -drop function if exists f2; -create function f2 () returns int begin declare v int; select s1 from t2 -into v; return v; end// -select f2(); +GRANT ALL PRIVILEGES ON test.* TO `a@`@localhost; +GRANT EXECUTE ON * TO `a@`@localhost; +CREATE TABLE t2 (s1 INT); +INSERT INTO t2 VALUES (1); +DROP FUNCTION IF EXISTS f2; +CREATE FUNCTION f2 () RETURNS INT +BEGIN DECLARE v INT; SELECT s1 FROM t2 INTO v; RETURN v; END// +SELECT f2(); f2() 1 -drop function f2; -drop table t2; +DROP FUNCTION f2; +DROP TABLE t2; REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost; -drop user `a@`@localhost; +DROP USER `a@`@localhost; drop database if exists mysqltest_1; drop database if exists mysqltest_2; drop user mysqltest_u1@localhost; @@ -436,6 +436,7 @@ SELECT * FROM t2; ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2' SELECT * FROM t1 JOIN t2 USING (b); ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2' +USE test; DROP TABLE db1.t1, db1.t2; DROP USER mysqltest1@localhost; DROP DATABASE db1; diff --git a/mysql-test/r/lock_tables_lost_commit.result b/mysql-test/r/lock_tables_lost_commit.result index 22885d93d40..df4b6eff5cf 100644 --- a/mysql-test/r/lock_tables_lost_commit.result +++ b/mysql-test/r/lock_tables_lost_commit.result @@ -1,8 +1,8 @@ -drop table if exists t1; -create table t1(a int) engine=innodb; -lock tables t1 write; -insert into t1 values(10); -select * from t1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(a INT) ENGINE=innodb; +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES(10); +SELECT * FROM t1; a 10 -drop table t1; +DROP TABLE t1; diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 08a18d8de75..76e553dea42 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1,6 +1,6 @@ -Bug#37938 - Test "mysqldump" lacks various insert statements -Turn off concurrent inserts to avoid random errors -NOTE: We reset the variable back to saved value at the end of test +# Bug#37938 Test "mysqldump" lacks various insert statements +# Turn off concurrent inserts to avoid random errors +# NOTE: We reset the variable back to saved value at the end of test SET @OLD_CONCURRENT_INSERT = @@GLOBAL.CONCURRENT_INSERT; SET @@GLOBAL.CONCURRENT_INSERT = 0; DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa, t3; @@ -8,7 +8,7 @@ drop database if exists mysqldump_test_db; drop database if exists db1; drop database if exists db2; drop view if exists v1, v2, v3; -CREATE TABLE t1(a int); +CREATE TABLE t1(a INT); INSERT INTO t1 VALUES (1), (2); @@ -28,7 +28,7 @@ INSERT INTO t1 VALUES (1), (2); DROP TABLE t1; # -# Bug #2005 +# Bug#2005 Long decimal comparison bug. # CREATE TABLE t1 (a decimal(64, 20)); INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), @@ -42,7 +42,7 @@ SET character_set_client = @saved_cs_client; INSERT INTO `t1` VALUES ('1234567890123456789012345678901234567890.00000000000000000000'),('987654321098765432109876543210987654321.00000000000000000000'); DROP TABLE t1; # -# Bug #2055 +# Bug#2055 mysqldump should replace "-inf" numeric field values with "NULL" # CREATE TABLE t1 (a double); INSERT INTO t1 VALUES ('-9e999999'); @@ -57,7 +57,7 @@ SET character_set_client = @saved_cs_client; INSERT INTO `t1` VALUES (RES); DROP TABLE t1; # -# Bug #3361 mysqldump quotes DECIMAL values inconsistently +# Bug#3361 mysqldump quotes DECIMAL values inconsistently # CREATE TABLE t1 (a DECIMAL(10,5), b FLOAT); INSERT INTO t1 VALUES (1.2345, 2.3456); @@ -169,7 +169,7 @@ INSERT INTO t1 VALUES (1, "test", "tes"), (2, "TEST", "TES"); DROP TABLE t1; # -# Bug #1707 +# Bug#1707 mysqldump -X does't quote field and table names # CREATE TABLE t1 (`a"b"` char(2)); INSERT INTO t1 VALUES ("1\""), ("\"2"); @@ -191,8 +191,8 @@ INSERT INTO t1 VALUES ("1\""), ("\"2"); DROP TABLE t1; # -# Bug #1994 -# Bug #4261 +# Bug#1994 mysqldump does not correctly dump UCS2 data +# Bug#4261 mysqldump 10.7 (mysql 4.1.2) --skip-extended-insert drops NULL from inserts # CREATE TABLE t1 (a VARCHAR(255)) DEFAULT CHARSET koi8r; INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'), (NULL); @@ -233,7 +233,7 @@ UNLOCK TABLES; DROP TABLE t1; # -# Bug #2634 +# Bug#2634 mysqldump in --compatible=mysql4 # CREATE TABLE t1 (a int) ENGINE=MYISAM; INSERT INTO t1 VALUES (1), (2); @@ -291,7 +291,7 @@ UNLOCK TABLES; DROP TABLE t1; # -# Bug #2592 'mysqldump doesn't quote "tricky" names correctly' +# Bug#2592 mysqldump doesn't quote "tricky" names correctly # create table ```a` (i int); SET @saved_cs_client = @@character_set_client; @@ -302,7 +302,7 @@ CREATE TABLE ```a` ( SET character_set_client = @saved_cs_client; drop table ```a`; # -# Bug #2591 "mysqldump quotes names inconsistently" +# Bug#2591 mysqldump quotes names inconsistently # create table t1(a int); @@ -425,7 +425,7 @@ UNLOCK TABLES; set global sql_mode=''; drop table t1; # -# Bug #2705 'mysqldump --tab extra output' +# Bug#2705 mysqldump --tab extra output # create table t1(a int); insert into t1 values (1),(2),(3); @@ -459,7 +459,7 @@ SET character_set_client = @saved_cs_client; 3 drop table t1; # -# Bug #6101: create database problem +# Bug#6101 create database problem # /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; @@ -514,7 +514,7 @@ USE `mysqldump_test_db`; drop database mysqldump_test_db; # -# Bug #7020 +# Bug#7020 mysqldump --compatible=mysql40 should set --skip-set-charset --default-char... # Check that we don't dump in UTF8 in compatible mode by default, # but use the default compiled values, or the values given in # --default-character-set=xxx. However, we should dump in UTF8 @@ -556,8 +556,8 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; # -# Bug#8063: make test mysqldump [ fail ] -# We cannot tes this command because its output depends +# Bug#8063 make test mysqldump [ fail ] +# We cannot test this command because its output depends # on --default-character-set incompiled into "mysqldump" program. # If the future we can move this command into a separate test with # checking that "mysqldump" is compiled with "latin1" @@ -642,7 +642,7 @@ UNLOCK TABLES; DROP TABLE t1; # -# WL #2319: Exclude Tables from dump +# WL#2319 Exclude Tables from dump # CREATE TABLE t1 (a int); CREATE TABLE t2 (a int); @@ -685,7 +685,7 @@ UNLOCK TABLES; DROP TABLE t1; DROP TABLE t2; # -# Bug #8830 +# Bug#8830 mysqldump --skip-extended-insert causes --hex-blob to dump wrong values # CREATE TABLE t1 (`b` blob); INSERT INTO `t1` VALUES (0x602010000280100005E71A); @@ -727,7 +727,7 @@ DROP TABLE t1; # # Test for --insert-ignore # -CREATE TABLE t1 (a int); +CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2),(3); INSERT INTO t1 VALUES (4),(5),(6); @@ -798,9 +798,9 @@ INSERT DELAYED IGNORE INTO `t1` VALUES (1),(2),(3),(4),(5),(6); DROP TABLE t1; # -# Bug #10286: mysqldump -c crashes on table that has many fields with long -# names -# +# Bug#10286 mysqldump -c crashes on table that has many fields with long +# names +# create table t1 ( F_c4ca4238a0b923820dcc509a6f75849b int, F_c81e728d9d4c2f636f067f89cc14862c int, @@ -1544,7 +1544,7 @@ UNLOCK TABLES; DROP TABLE t1; # -# Bug #9558 mysqldump --no-data db t1 t2 format still dumps data +# Bug#9558 mysqldump --no-data db t1 t2 format still dumps data # CREATE DATABASE mysqldump_test_db; USE mysqldump_test_db; @@ -1649,7 +1649,7 @@ DROP DATABASE mysqldump_test_db; # # Testing with tables and databases that don't exists # or contains illegal characters -# (Bug #9358 mysqldump crashes if tablename starts with \) +# (Bug#9358 mysqldump crashes if tablename starts with \) # create database mysqldump_test_db; use mysqldump_test_db; @@ -1678,7 +1678,7 @@ drop table t1, t2, t3; drop database mysqldump_test_db; use test; # -# Bug #9657 mysqldump xml ( -x ) does not format NULL fields correctly +# Bug#9657 mysqldump xml ( -x ) does not format NULL fields correctly # create table t1 (a int(10)); create table t2 (pk int primary key auto_increment, @@ -1737,7 +1737,7 @@ insert into t2 (a, b) values (NULL, NULL),(10, NULL),(NULL, "twenty"),(30, "thir drop table t1, t2; # -# BUG #12123 +# Bug#12123 mysqldump --tab results in text file which can't be imported # create table t1 (a text character set utf8, b text character set latin1); insert t1 values (0x4F736E616272C3BC636B, 0x4BF66C6E); @@ -1750,11 +1750,11 @@ a b Osnabrück Köln drop table t1; # -# BUG#15328 Segmentation fault occured if my.cnf is invalid for escape sequence +# Bug#15328 Segmentation fault occured if my.cnf is invalid for escape sequence # --fields-optionally-enclosed-by=" # -# BUG #19025 mysqldump doesn't correctly dump "auto_increment = [int]" +# Bug#19025 mysqldump doesn't correctly dump "auto_increment = [int]" # create table `t1` ( t1_name varchar(255) default null, @@ -1794,7 +1794,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1 drop table `t1`; # -# Bug #18536: wrong table order +# Bug#18536 wrong table order # create table t1(a int); create table t2(a int); @@ -1843,7 +1843,7 @@ SET character_set_client = @saved_cs_client; drop table t1, t2, t3; # -# Bug #21288: mysqldump segmentation fault when using --where +# Bug#21288 mysqldump segmentation fault when using --where # create table t1 (a int); mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ * FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': 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 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064) @@ -1879,7 +1879,7 @@ SET character_set_client = @saved_cs_client; drop table t1; # -# BUG#13926: --order-by-primary fails if PKEY contains quote character +# Bug#13926 --order-by-primary fails if PKEY contains quote character # DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( @@ -1958,7 +1958,7 @@ UNLOCK TABLES; DROP TABLE `t1`; End of 4.1 tests # -# Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) +# Bug#10213 mysqldump crashes when dumping VIEWs(on MacOS X) # create database db1; use db1; @@ -2023,7 +2023,7 @@ drop view v2; drop database db1; use test; # -# Bug 10713 mysqldump includes database in create view and referenced tables +# Bug#10713 mysqldump includes database in create view and referenced tables # create database db2; use db2; @@ -2102,7 +2102,7 @@ DROP TABLE IF EXISTS `v1`; drop view v1; drop table t1; # -# Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) +# Bug#10213 mysqldump crashes when dumping VIEWs(on MacOS X) # create database mysqldump_test_db; use mysqldump_test_db; @@ -2167,7 +2167,7 @@ drop view v2; drop database mysqldump_test_db; use test; # -# Bug #9756 +# Bug#9756 mysql client failing on dumps containing certain \ sequences # CREATE TABLE t1 (a char(10)); INSERT INTO t1 VALUES ('\''); @@ -2207,7 +2207,7 @@ UNLOCK TABLES; DROP TABLE t1; # -# Bug #10927 mysqldump: Can't reload dump with view that consist of other view +# Bug#10927 mysqldump: Can't reload dump with view that consist of other view # create table t1(a int, b int, c varchar(30)); insert into t1 values(1, 2, "one"), (2, 4, "two"), (3, 6, "three"); @@ -2505,12 +2505,14 @@ end if; end BEFORE # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER root@localhost DROP TABLE t1, t2; # -# Bugs #9136, #12917: problems with --defaults-extra-file option +# Bug#9136 my_print_defaults changed behaviour between 4.1.7 and 4.1.10a +# Bug#12917 The --defaults-extra-file option is ignored by the 5.0 client binaries +# (Problems with --defaults-extra-file option) # --port=1234 --port=1234 # -# Test of fix to BUG 12597 +# Test of fix to Bug#12597 mysqldump dumps triggers wrongly # DROP TABLE IF EXISTS `test1`; Warnings: @@ -2544,7 +2546,7 @@ DROP TRIGGER testref; DROP TABLE test1; DROP TABLE test2; # -# BUG#9056 - mysqldump does not dump routines +# Bug#9056 mysqldump does not dump routines # DROP TABLE IF EXISTS t1; DROP FUNCTION IF EXISTS bug9056_func1; @@ -2562,9 +2564,9 @@ begin set f1= concat( 'hello', f1 ); return f1; end // -CREATE PROCEDURE bug9056_proc2(OUT a INT) -BEGIN -select sum(id) from t1 into a; +CREATE PROCEDURE bug9056_proc2(OUT a INT) +BEGIN +select sum(id) from t1 into a; END // set sql_mode='ansi'; create procedure `a'b` () select 1; @@ -2624,8 +2626,8 @@ BEGIN SELECT a+b INTO c; end */;; /*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc2` */;; /*!50003 SET SESSION SQL_MODE=""*/;; /*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `bug9056_proc2`(OUT a INT) -BEGIN -select sum(id) from t1 into a; +BEGIN +select sum(id) from t1 into a; END */;; /*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;; DELIMITER ; @@ -2646,7 +2648,7 @@ DROP PROCEDURE bug9056_proc2; DROP PROCEDURE `a'b`; drop table t1; # -# BUG# 13052 - mysqldump timestamp reloads broken +# Bug#13052 mysqldump timestamp reloads broken # drop table if exists t1; create table t1 (`d` timestamp, unique (`d`)); @@ -2741,7 +2743,7 @@ drop table t1; set global time_zone=default; set time_zone=default; # -# Test of fix to BUG 13146 - ansi quotes break loading of triggers +# Test of fix to Bug#13146 ansi quotes break loading of triggers # DROP TABLE IF EXISTS `t1 test`; DROP TABLE IF EXISTS `t2 test`; @@ -2814,7 +2816,7 @@ DROP TRIGGER `test trig`; DROP TABLE `t1 test`; DROP TABLE `t2 test`; # -# BUG# 12838 mysqldump -x with views exits with error +# Bug#12838 mysqldump -x with views exits with error # drop table if exists t1; create table t1 (a int, b varchar(32), c varchar(32)); @@ -2912,7 +2914,7 @@ drop view v0; drop view v1; drop table t1; # -# BUG#14554 - mysqldump does not separate words "ROW" and "BEGIN" +# Bug#14554 mysqldump does not separate words "ROW" and "BEGIN" # for tables with trigger created in the IGNORE_SPACE sql mode. # SET @old_sql_mode = @@SQL_MODE; @@ -2975,8 +2977,8 @@ DELIMITER ; DROP TRIGGER tr1; DROP TABLE t1; # -# Bug #13318: Bad result with empty field and --hex-blob -# +# Bug#13318 Bad result with empty field and --hex-blob +# create table t1 (a binary(1), b blob); insert into t1 values ('',''); @@ -3051,7 +3053,7 @@ UNLOCK TABLES; drop table t1; # -# Bug 14871 Invalid view dump output +# Bug#14871 Invalid view dump output # create table t1 (a int); insert into t1 values (289), (298), (234), (456), (789); @@ -3080,7 +3082,7 @@ a drop table t1; drop view v1, v2, v3, v4, v5; # -# Bug #16878 dump of trigger +# Bug#16878 dump of trigger # create table t1 (a int, created datetime); create table t2 (b int, created datetime); @@ -3130,7 +3132,7 @@ drop view v2; drop table t; # # Bug#14857 Reading dump files with single statement stored routines fails. -# fixed by patch for bug#16878 +# fixed by patch for Bug#16878 # /*!50003 CREATE FUNCTION `f`() RETURNS bigint(20) return 42 */| @@ -3147,7 +3149,7 @@ select 42 drop function f; drop procedure p; # -# Bug #17371 Unable to dump a schema with invalid views +# Bug#17371 Unable to dump a schema with invalid views # create table t1 ( id serial ); create view v1 as select * from t1; @@ -3158,7 +3160,7 @@ mysqldump { } mysqldump drop view v1; -# BUG#17201 Spurious 'DROP DATABASE' in output, +# Bug#17201 Spurious 'DROP DATABASE' in output, # also confusion between tables and views. # Example code from Markus Popp create database mysqldump_test_db; @@ -3225,7 +3227,7 @@ drop view v1; drop table t1; drop database mysqldump_test_db; # -# Bug21014 Segmentation fault of mysqldump on view +# Bug#21014 Segmentation fault of mysqldump on view # create database mysqldump_tables; use mysqldump_tables; @@ -3265,7 +3267,7 @@ drop database mysqldump_views; drop table mysqldump_tables.basetable; drop database mysqldump_tables; # -# Bug20221 Dumping of multiple databases containing view(s) yields maleformed dumps +# Bug#20221 Dumping of multiple databases containing view(s) yields maleformed dumps # create database mysqldump_dba; use mysqldump_dba; @@ -3322,10 +3324,10 @@ SET character_set_client = @saved_cs_client; drop table t1; drop user mysqltest_1@localhost; # -# Bug #21527 mysqldump incorrectly tries to LOCK TABLES on the -# information_schema database. +# Bug#21527 mysqldump incorrectly tries to LOCK TABLES on the +# information_schema database. # -# Bug #21424 mysqldump failing to export/import views +# Bug#21424 mysqldump failing to export/import views # create database mysqldump_myDB; use mysqldump_myDB; @@ -3345,8 +3347,8 @@ revoke all privileges on mysqldump_myDB.* from myDB_User@localhost; drop user myDB_User@localhost; drop database mysqldump_myDB; flush privileges; -# Bug #21424 continues from here. -# Restore. Flush Privileges test ends. +# Bug#21424 continues from here. +# Restore. Flush Privileges test ends. # use mysqldump_myDB; select * from mysqldump_myDB.v1; @@ -3364,7 +3366,7 @@ drop user myDB_User@localhost; drop database mysqldump_myDB; use test; # -# Bug #19745: mysqldump --xml produces invalid xml +# Bug#19745 mysqldump --xml produces invalid xml # DROP TABLE IF EXISTS t1; CREATE TABLE t1 (f1 int(10), data MEDIUMBLOB); @@ -3386,15 +3388,15 @@ INSERT INTO t1 VALUES(1,0xff00fef0); DROP TABLE t1; # -# Bug#26346: stack + buffer overrun in mysqldump +# Bug#26346 stack + buffer overrun in mysqldump # CREATE TABLE t1(a int); INSERT INTO t1 VALUES (1), (2); mysqldump: Input filename too long: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa DROP TABLE t1; -CREATE TABLE t2 (a int); -CREATE TABLE t3 (a int); -CREATE TABLE t1 (a int) ENGINE=merge UNION=(t2, t3); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT); +CREATE TABLE t1 (a INT) ENGINE=merge UNION=(t2, t3); /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -3449,7 +3451,7 @@ UNLOCK TABLES; DROP TABLE t1, t2, t3; # -# Bug #23491: MySQLDump prefix function call in a view by database name +# Bug#23491 MySQLDump prefix function call in a view by database name # create database bug23491_original; create database bug23491_restore; @@ -3471,12 +3473,12 @@ v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VI drop database bug23491_original; drop database bug23491_restore; use test; -# -# Bug 27293: mysqldump crashes when dumping routines -# defined by a different user # -# Bug #22761: mysqldump reports no errors when using -# --routines without mysql.proc privileges +# Bug#27293 mysqldump crashes when dumping routines +# defined by a different user +# +# Bug#22761 mysqldump reports no errors when using +# --routines without mysql.proc privileges # create database mysqldump_test_db; grant all privileges on mysqldump_test_db.* to user1; @@ -3503,7 +3505,7 @@ drop user user1; drop user user2; drop database mysqldump_test_db; # -# Bug #28522: buffer overrun by '\0' byte using --hex-blob. +# Bug#28522 buffer overrun by '\0' byte using --hex-blob. # CREATE TABLE t1 (c1 INT, c2 LONGBLOB); INSERT INTO t1 SET c1=11, c2=REPEAT('q',509); @@ -3517,8 +3519,8 @@ SET character_set_client = @saved_cs_client; INSERT INTO `t1` VALUES (11,0x7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171); DROP TABLE t1; # -# Bug #28524: mysqldump --skip-add-drop-table is not -# compatible with views +# Bug#28524 mysqldump --skip-add-drop-table is not +# compatible with views # CREATE VIEW v1 AS SELECT 1; DROP VIEW v1; @@ -3527,8 +3529,8 @@ SELECT * FROM v1; 1 DROP VIEW v1; # -# Bug #29788: mysqldump discards the NO_AUTO_VALUE_ON_ZERO value of -# the SQL_MODE variable after the dumping of triggers. +# Bug#29788 mysqldump discards the NO_AUTO_VALUE_ON_ZERO value of +# the SQL_MODE variable after the dumping of triggers. # CREATE TABLE t1 (c1 INT); CREATE TRIGGER t1bd BEFORE DELETE ON t1 FOR EACH ROW BEGIN END; @@ -3549,8 +3551,8 @@ c1 2 DROP TABLE t1,t2; # -# Bug#29815: new option for suppressing last line of mysqldump: -# "Dump completed on" +# Bug#29815 new option for suppressing last line of mysqldump: +# "Dump completed on" # # --skip-dump-date: -- diff --git a/mysql-test/r/outfile.result b/mysql-test/r/outfile.result index 8503df545d2..e8c62098f95 100644 Binary files a/mysql-test/r/outfile.result and b/mysql-test/r/outfile.result differ diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index e2d92ee58d4..8f83c365170 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -1,6 +1,10 @@ # Grant tests not performed with embedded server -- source include/not_embedded.inc +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + + SET NAMES binary; # @@ -27,7 +31,7 @@ create user mysqltest_2@localhost; connect (user_a,localhost,mysqltest_1,,); connection user_a; grant select on `my\_1`.* to mysqltest_2@localhost; ---error 1132 +--error ER_PASSWORD_NOT_ALLOWED grant select on `my\_1`.* to mysqltest_2@localhost identified by 'pass'; disconnect user_a; connection default; @@ -61,7 +65,7 @@ connect (user1,localhost,mysqltest_1,,); connection user1; select current_user(); grant all privileges on `my\_1`.* to mysqltest_2@localhost with grant option; ---error 1044 +--error ER_DBACCESS_DENIED_ERROR grant all privileges on `my_%`.* to mysqltest_3@localhost with grant option; # @@ -72,7 +76,7 @@ select @@sql_mode; # # GRANT without IDENTIFIED BY does not create new users # ---error 1133 +--error ER_PASSWORD_NO_MATCH grant select on `my\_1`.* to mysqltest_4@localhost with grant option; grant select on `my\_1`.* to mysqltest_4@localhost identified by 'mypass' with grant option; @@ -80,7 +84,7 @@ disconnect user1; connection default; show grants for mysqltest_1@localhost; show grants for mysqltest_2@localhost; ---error 1141 +--error ER_NONEXISTING_GRANT show grants for mysqltest_3@localhost; delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; @@ -95,7 +99,7 @@ connect (user2,localhost,mysqltest_1,,); connection user2; select current_user(); show databases; ---error 1044 +--error ER_DBACCESS_DENIED_ERROR grant all privileges on `mysqltest_1`.* to mysqltest_1@localhost with grant option; disconnect user2; connection default; @@ -106,8 +110,8 @@ drop database mysqltest_1; flush privileges; # -# Bug #6173: One can circumvent missing UPDATE privilege if he has SELECT -# and INSERT privilege for table with primary key +# Bug#6173 One can circumvent missing UPDATE privilege if he has SELECT and +# INSERT privilege for table with primary key # create database mysqltest; grant INSERT, SELECT on mysqltest.* to mysqltest_1@localhost; @@ -119,10 +123,10 @@ connect (mrbad, localhost, mysqltest_1,,mysqltest); connection mrbad; show grants for current_user(); insert into t1 values (1, 'I can''t change it!'); ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR update t1 set data='I can change it!' where id = 1; # This should not be allowed since it too require UPDATE privilege. ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR insert into t1 values (1, 'XXX') on duplicate key update data= 'I can change it!'; select * from t1; disconnect mrbad; @@ -138,9 +142,9 @@ create table t1 (a int, b int); grant select (a) on t1 to mysqltest_1@localhost with grant option; connect (mrugly, localhost, mysqltest_1,,mysqltest); connection mrugly; ---error 1143 +--error ER_COLUMNACCESS_DENIED_ERROR grant select (a,b) on t1 to mysqltest_2@localhost; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR grant select on t1 to mysqltest_3@localhost; disconnect mrugly; @@ -157,7 +161,7 @@ use test; # -# Bug #15775: "drop user" command does not refresh acl_check_hosts +# Bug#15775 "drop user" command does not refresh acl_check_hosts # # Create some test users @@ -188,15 +192,15 @@ disconnect con9; connection default; # -# Bug# 16180 - Setting SQL_LOG_OFF without SUPER privilege is silently ignored +# Bug#16180 Setting SQL_LOG_OFF without SUPER privilege is silently ignored # create database mysqltest_1; grant select, insert, update on `mysqltest\_1`.* to mysqltest_1@localhost; connect (con10,localhost,mysqltest_1,,); connection con10; ---error 1227 +--error ER_SPECIFIC_ACCESS_DENIED_ERROR set sql_log_off = 1; ---error 1227 +--error ER_SPECIFIC_ACCESS_DENIED_ERROR set sql_log_bin = 0; disconnect con10; connection default; @@ -217,7 +221,7 @@ create table t2(c1 int, c2 int); # # Three forms of CREATE USER create user 'mysqltest_1'; ---error 1396 +--error ER_CANNOT_USER create user 'mysqltest_1'; create user 'mysqltest_2' identified by 'Mysqltest-2'; create user 'mysqltest_3' identified by password 'fffffffffffffffffffffffffffffffffffffffff'; @@ -238,7 +242,7 @@ select host,user,password from mysql.user where user like 'mysqltest_%' order by select host,db,user from mysql.db where user like 'mysqltest_%' order by host,db,user; select host,db,user,table_name from mysql.tables_priv where user like 'mysqltest_%' order by host,db,user,table_name; select host,db,user,table_name,column_name from mysql.columns_priv where user like 'mysqltest_%' order by host,db,user,table_name,column_name; ---error 1141 +--error ER_NONEXISTING_GRANT show grants for 'mysqltest_1'; # # Rename @@ -249,7 +253,7 @@ select host,db,user,table_name from mysql.tables_priv where user like 'mysqltest select host,db,user,table_name,column_name from mysql.columns_priv where user like 'mysqltest_%' order by host,db,user,table_name,column_name; show grants for 'mysqltest_1'; drop user 'mysqltest_1', 'mysqltest_3'; ---error 1396 +--error ER_CANNOT_USER drop user 'mysqltest_1'; # # Cleanup @@ -258,9 +262,9 @@ drop table t1, t2; # Add a stray record insert into mysql.db set user='mysqltest_1', db='%', host='%'; flush privileges; ---error 1141 +--error ER_NONEXISTING_GRANT show grants for 'mysqltest_1'; ---error 1269 +--error ER_REVOKE_GRANTS revoke all privileges, grant option from 'mysqltest_1'; drop user 'mysqltest_1'; select host,db,user from mysql.db where user = 'mysqltest_1' order by host,db,user; @@ -268,7 +272,7 @@ select host,db,user from mysql.db where user = 'mysqltest_1' order by host,db,us # Add a stray record insert into mysql.tables_priv set host='%', db='test', user='mysqltest_1', table_name='t1'; flush privileges; ---error 1141 +--error ER_NONEXISTING_GRANT show grants for 'mysqltest_1'; drop user 'mysqltest_1'; select host,db,user,table_name from mysql.tables_priv where user = 'mysqltest_1' order by host,db,user,table_name; @@ -276,7 +280,7 @@ select host,db,user,table_name from mysql.tables_priv where user = 'mysqltest_1' # Add a stray record insert into mysql.columns_priv set host='%', db='test', user='mysqltest_1', table_name='t1', column_name='c1'; flush privileges; ---error 1141 +--error ER_NONEXISTING_GRANT show grants for 'mysqltest_1'; drop user 'mysqltest_1'; select host,db,user,table_name,column_name from mysql.columns_priv where user = 'mysqltest_1' order by host,db,user,table_name,column_name; @@ -286,23 +290,23 @@ create user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; create user 'mysqltest_1', 'mysqltest_2' identified by 'Mysqltest-2', 'mysqltest_3' identified by password 'fffffffffffffffffffffffffffffffffffffffff'; rename user 'mysqltest_1' to 'mysqltest_1a', 'mysqltest_2' TO 'mysqltest_2a', 'mysqltest_3' TO 'mysqltest_3a'; ---error 1396 +--error ER_CANNOT_USER drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; drop user 'mysqltest_1a', 'mysqltest_2a', 'mysqltest_3a'; # # Let one of multiple users fail create user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; ---error 1396 +--error ER_CANNOT_USER create user 'mysqltest_1a', 'mysqltest_2', 'mysqltest_3a'; ---error 1396 +--error ER_CANNOT_USER rename user 'mysqltest_1a' to 'mysqltest_1b', 'mysqltest_2a' TO 'mysqltest_2b', 'mysqltest_3a' TO 'mysqltest_3b'; drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; ---error 1396 +--error ER_CANNOT_USER drop user 'mysqltest_1b', 'mysqltest_2b', 'mysqltest_3b'; # # Obsolete syntax has been dropped create user 'mysqltest_2' identified by 'Mysqltest-2'; ---error 1064 +--error ER_PARSE_ERROR drop user 'mysqltest_2' identified by 'Mysqltest-2'; drop user 'mysqltest_2'; # @@ -312,7 +316,7 @@ show grants for '%@b'@'b'; grant select on mysql.* to '%@b'@'b'; show grants for '%@b'@'b'; rename user '%@b'@'b' to '%@a'@'a'; ---error 1141 +--error ER_NONEXISTING_GRANT show grants for '%@b'@'b'; show grants for '%@a'@'a'; drop user '%@a'@'a'; @@ -323,7 +327,7 @@ create user mysqltest_2@localhost; grant create user on *.* to mysqltest_2@localhost; connect (user3,localhost,mysqltest_2,,); connection user3; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password; create user mysqltest_A@'%'; rename user mysqltest_A@'%' to mysqltest_B@'%'; @@ -338,7 +342,7 @@ grant INSERT,DELETE,UPDATE on mysql.* to mysqltest_3@localhost; connect (user4,localhost,mysqltest_3,,); connection user4; show grants; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password; insert into mysql.user set host='%', user='mysqltest_B'; create user mysqltest_A@'%'; @@ -349,7 +353,7 @@ disconnect user4; connection default; drop user mysqltest_3@localhost; # -# Bug #3309: Test IP addresses with netmask +# Bug#3309 Test IP addresses with netmask set @@sql_mode=''; create database mysqltest_1; create table mysqltest_1.t1 (i int); @@ -367,7 +371,8 @@ flush privileges; drop table mysqltest_1.t1; # -# Bug #12302: 'SET PASSWORD = ...' didn't work if connecting hostname != +# Bug#12302 Hostname resolution preventing password changes +# 'SET PASSWORD = ...' didn't work if connecting hostname != # hostname the current user is authenticated as. Note that a test for this # was also added to the test above. # @@ -400,7 +405,7 @@ drop database mysqltest_1; # But anonymous users can't change their password connect (n5,localhost,test,,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection n5; ---error 1044 +--error ER_DBACCESS_DENIED_ERROR set password = password("changed"); disconnect n5; connection default; @@ -408,7 +413,7 @@ connection default; --source include/delete_anonymous_users.inc -# Bug #12423 "Deadlock when doing FLUSH PRIVILEGES and GRANT in +# Bug#12423 "Deadlock when doing FLUSH PRIVILEGES and GRANT in # multi-threaded environment". We should be able to execute FLUSH # PRIVILEGES and SET PASSWORD simultaneously with other account # management commands (such as GRANT and REVOKE) without causing @@ -474,12 +479,13 @@ connect (con1,localhost,mysqltest_1,password,TESTDB); # The user mysqltest_1 should only be allowed access to # database TESTDB, not TEStdb -# On system with "lowercase names" we get error "1007: Can't create db..." ---error 1044, 1007 +# On system with "lowercase names" we get error "ER_DB_CREATE_EXISTS: Can't create db..." +--error ER_DBACCESS_DENIED_ERROR, ER_DB_CREATE_EXISTS create database TEStdb; # Clean-up connection default; +disconnect con1; delete from mysql.user; delete from mysql.db where host='%' and user='mysqltest_1' and db='TESTDB'; insert into mysql.user select * from t1; @@ -488,35 +494,34 @@ drop database TESTDB; flush privileges; # -# BUG#13310 incorrect user parsing by SP +# Bug#13310 incorrect user parsing by SP # -grant all privileges on test.* to `a@`@localhost; -grant execute on * to `a@`@localhost; +GRANT ALL PRIVILEGES ON test.* TO `a@`@localhost; +GRANT EXECUTE ON * TO `a@`@localhost; connect (bug13310,localhost,'a@',,test); connection bug13310; -create table t2 (s1 int); -insert into t2 values (1); +CREATE TABLE t2 (s1 INT); +INSERT INTO t2 VALUES (1); --disable_warnings -drop function if exists f2; +DROP FUNCTION IF EXISTS f2; --enable_warnings delimiter //; -create function f2 () returns int begin declare v int; select s1 from t2 -into v; return v; end// +CREATE FUNCTION f2 () RETURNS INT +BEGIN DECLARE v INT; SELECT s1 FROM t2 INTO v; RETURN v; END// delimiter ;// -select f2(); +SELECT f2(); -drop function f2; -drop table t2; +DROP FUNCTION f2; +DROP TABLE t2; disconnect bug13310; - connection default; REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost; -drop user `a@`@localhost; +DROP USER `a@`@localhost; # -# Bug#25578 "CREATE TABLE LIKE does not require any privileges on source table" +# Bug#25578 CREATE TABLE LIKE does not require any privileges on source table # --disable_warnings drop database if exists mysqltest_1; @@ -535,7 +540,7 @@ create table t1 (i int); connect (user1,localhost,mysqltest_u1,,mysqltest_1); connection user1; # As expected error is emitted ---error ER_TABLEACCESS_DENIED_ERROR +--error ER_TABLEACCESS_DENIED_ERROR show create table mysqltest_2.t1; # This should emit error as well --error ER_TABLEACCESS_DENIED_ERROR @@ -550,14 +555,16 @@ create table t1 like mysqltest_2.t1; # Clean-up connection default; +disconnect user1; use test; drop database mysqltest_1; drop database mysqltest_2; drop user mysqltest_u1@localhost; + # # Bug#18660 Can't grant any privileges on single table in database -# with underscore char +# with underscore char # grant all on `mysqltest\_%`.* to mysqltest_1@localhost with grant option; grant usage on *.* to mysqltest_2@localhost; @@ -571,7 +578,7 @@ grant create on `mysqltest\_1`.* to mysqltest_2@localhost; grant select on mysqltest_1.t1 to mysqltest_2@localhost; connect (con3,localhost,mysqltest_2,,); connection con3; ---error 1044 +--error ER_DBACCESS_DENIED_ERROR create database mysqltest_3; use mysqltest_1; create table t2(f1 int); @@ -579,6 +586,9 @@ select * from t1; connection default; drop database mysqltest_1; +connection default; +disconnect con3; +disconnect con18600_1; revoke all privileges, grant option from mysqltest_1@localhost; revoke all privileges, grant option from mysqltest_2@localhost; drop user mysqltest_1@localhost; @@ -586,7 +596,7 @@ drop user mysqltest_2@localhost; # -# Bug #30468: column level privileges not respected when joining tables +# Bug#30468 column level privileges not respected when joining tables # CREATE DATABASE db1; @@ -597,7 +607,7 @@ INSERT INTO t1 VALUES (1,1),(2,2); CREATE TABLE t2 (b INT, c INT); INSERT INTO t2 VALUES (1,100),(2,200); -GRANT SELECT ON t1 TO mysqltest1@localhost; +GRANT SELECT ON t1 TO mysqltest1@localhost; GRANT SELECT (b) ON t2 TO mysqltest1@localhost; connect (conn1,localhost,mysqltest1,,); @@ -612,6 +622,7 @@ SELECT * FROM t1 JOIN t2 USING (b); connection default; disconnect conn1; +USE test; DROP TABLE db1.t1, db1.t2; DROP USER mysqltest1@localhost; DROP DATABASE db1; @@ -619,3 +630,5 @@ DROP DATABASE db1; --echo End of 5.0 tests +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/grant3.test b/mysql-test/t/grant3.test index 8eceb851c29..9a635048774 100644 --- a/mysql-test/t/grant3.test +++ b/mysql-test/t/grant3.test @@ -1,6 +1,10 @@ -# Can't run with embedded server +# Can't run with embedded server because we use GRANT -- source include/not_embedded.inc +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + + # Test of GRANT commands SET NAMES binary; @@ -23,10 +27,11 @@ grant create user on *.* to mysqltest_1@localhost; grant select on `my\_1`.* to mysqltest_1@localhost with grant option; connect (user_a,localhost,mysqltest_1,,); connection user_a; ---error 1410 +--error ER_CANT_CREATE_USER_WITH_GRANT grant select on `my\_1`.* to mysqltest_2@localhost; create user mysqltest_2@localhost; disconnect user_a; +disconnect master; connection default; delete from mysql.user where user like 'mysqltest\_%'; @@ -36,7 +41,7 @@ delete from mysql.columns_priv where user like 'mysqltest\_%'; flush privileges; # -# Bug: #19828 Case sensitivity in Grant/Revoke +# Bug#19828 Case sensitivity in Grant/Revoke # grant select on test.* to CUser@localhost; @@ -137,7 +142,7 @@ DROP USER CUser2@LOCALHOST; # -# Bug#31194: Privilege ordering does not order properly for wildcard values +# Bug#31194 Privilege ordering does not order properly for wildcard values # CREATE DATABASE mysqltest_1; @@ -160,3 +165,6 @@ DROP DATABASE mysqltest_1; --echo End of 5.0 tests + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/lock_tables_lost_commit.test b/mysql-test/t/lock_tables_lost_commit.test index d31b4b7dfb5..754c8f3c378 100644 --- a/mysql-test/t/lock_tables_lost_commit.test +++ b/mysql-test/t/lock_tables_lost_commit.test @@ -1,24 +1,33 @@ -# This is a test for bug 578 +# Test for Bug#578 mysqlimport -l silently fails when binlog-ignore-db is set --- source include/have_innodb.inc +--source include/have_innodb.inc + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc connect (con1,localhost,root,,); connect (con2,localhost,root,,); connection con1; --disable_warnings -drop table if exists t1; -create table t1(a int) engine=innodb; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(a INT) ENGINE=innodb; --enable_warnings -lock tables t1 write; -insert into t1 values(10); +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES(10); disconnect con1; connection con2; # The bug was that, because of the LOCK TABLES, the handler "forgot" to commit, # and the other commit when we write to the binlog was not done because of -# binlog-ignore-db -select * from t1; -drop table t1; +# binlog-ignore-db +SELECT * FROM t1; +DROP TABLE t1; + +connection default; +disconnect con2; # End of 4.1 tests + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 2f11685385f..5cd9c17e2ac 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -5,10 +5,13 @@ # Binlog is required --source include/have_log_bin.inc +# Save the initial number of concurrent sessions +--source include/count_sessions.inc ---echo Bug#37938 - Test "mysqldump" lacks various insert statements ---echo Turn off concurrent inserts to avoid random errors ---echo NOTE: We reset the variable back to saved value at the end of test + +--echo # Bug#37938 Test "mysqldump" lacks various insert statements +--echo # Turn off concurrent inserts to avoid random errors +--echo # NOTE: We reset the variable back to saved value at the end of test SET @OLD_CONCURRENT_INSERT = @@GLOBAL.CONCURRENT_INSERT; SET @@GLOBAL.CONCURRENT_INSERT = 0; @@ -23,13 +26,13 @@ drop view if exists v1, v2, v3; # XML output -CREATE TABLE t1(a int); +CREATE TABLE t1(a INT); INSERT INTO t1 VALUES (1), (2); --exec $MYSQL_DUMP --skip-create --skip-comments -X test t1 DROP TABLE t1; --echo # ---echo # Bug #2005 +--echo # Bug#2005 Long decimal comparison bug. --echo # CREATE TABLE t1 (a decimal(64, 20)); @@ -39,7 +42,7 @@ INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), DROP TABLE t1; --echo # ---echo # Bug #2055 +--echo # Bug#2055 mysqldump should replace "-inf" numeric field values with "NULL" --echo # CREATE TABLE t1 (a double); @@ -51,7 +54,7 @@ INSERT INTO t1 VALUES ('-9e999999'); DROP TABLE t1; --echo # ---echo # Bug #3361 mysqldump quotes DECIMAL values inconsistently +--echo # Bug#3361 mysqldump quotes DECIMAL values inconsistently --echo # CREATE TABLE t1 (a DECIMAL(10,5), b FLOAT); @@ -65,7 +68,7 @@ INSERT INTO t1 VALUES ("1.2345", 2.3456); SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI_QUOTES'; INSERT INTO t1 VALUES (1.2345, 2.3456); INSERT INTO t1 VALUES ('1.2345', 2.3456); ---error 1054 +--error ER_BAD_FIELD_ERROR INSERT INTO t1 VALUES ("1.2345", 2.3456); SET SQL_MODE=@OLD_SQL_MODE; @@ -82,7 +85,7 @@ INSERT INTO t1 VALUES (1, "test", "tes"), (2, "TEST", "TES"); DROP TABLE t1; --echo # ---echo # Bug #1707 +--echo # Bug#1707 mysqldump -X does't quote field and table names --echo # CREATE TABLE t1 (`a"b"` char(2)); @@ -91,8 +94,8 @@ INSERT INTO t1 VALUES ("1\""), ("\"2"); DROP TABLE t1; --echo # ---echo # Bug #1994 ---echo # Bug #4261 +--echo # Bug#1994 mysqldump does not correctly dump UCS2 data +--echo # Bug#4261 mysqldump 10.7 (mysql 4.1.2) --skip-extended-insert drops NULL from inserts --echo # CREATE TABLE t1 (a VARCHAR(255)) DEFAULT CHARSET koi8r; @@ -101,7 +104,7 @@ INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'), (NULL); DROP TABLE t1; --echo # ---echo # Bug #2634 +--echo # Bug#2634 mysqldump in --compatible=mysql4 --echo # CREATE TABLE t1 (a int) ENGINE=MYISAM; @@ -111,7 +114,7 @@ INSERT INTO t1 VALUES (1), (2); DROP TABLE t1; --echo # ---echo # Bug #2592 'mysqldump doesn't quote "tricky" names correctly' +--echo # Bug#2592 mysqldump doesn't quote "tricky" names correctly --echo # create table ```a` (i int); @@ -119,7 +122,7 @@ create table ```a` (i int); drop table ```a`; --echo # ---echo # Bug #2591 "mysqldump quotes names inconsistently" +--echo # Bug#2591 mysqldump quotes names inconsistently --echo # create table t1(a int); @@ -132,7 +135,7 @@ set global sql_mode=''; drop table t1; --echo # ---echo # Bug #2705 'mysqldump --tab extra output' +--echo # Bug#2705 mysqldump --tab extra output --echo # create table t1(a int); @@ -148,7 +151,7 @@ insert into t1 values (1),(2),(3); drop table t1; --echo # ---echo # Bug #6101: create database problem +--echo # Bug#6101 create database problem --echo # --exec $MYSQL_DUMP --skip-comments --databases test @@ -158,7 +161,7 @@ create database mysqldump_test_db character set latin2 collate latin2_bin; drop database mysqldump_test_db; --echo # ---echo # Bug #7020 +--echo # Bug#7020 mysqldump --compatible=mysql40 should set --skip-set-charset --default-char... --echo # Check that we don't dump in UTF8 in compatible mode by default, --echo # but use the default compiled values, or the values given in --echo # --default-character-set=xxx. However, we should dump in UTF8 @@ -169,8 +172,8 @@ INSERT INTO t1 VALUES (_latin1 ' --exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments test t1 --echo # ---echo # Bug#8063: make test mysqldump [ fail ] ---echo # We cannot tes this command because its output depends +--echo # Bug#8063 make test mysqldump [ fail ] +--echo # We cannot test this command because its output depends --echo # on --default-character-set incompiled into "mysqldump" program. --echo # If the future we can move this command into a separate test with --echo # checking that "mysqldump" is compiled with "latin1" @@ -183,7 +186,7 @@ INSERT INTO t1 VALUES (_latin1 ' DROP TABLE t1; --echo # ---echo # WL #2319: Exclude Tables from dump +--echo # WL#2319 Exclude Tables from dump --echo # CREATE TABLE t1 (a int); @@ -195,7 +198,7 @@ DROP TABLE t1; DROP TABLE t2; --echo # ---echo # Bug #8830 +--echo # Bug#8830 mysqldump --skip-extended-insert causes --hex-blob to dump wrong values --echo # CREATE TABLE t1 (`b` blob); @@ -207,7 +210,7 @@ DROP TABLE t1; --echo # Test for --insert-ignore --echo # -CREATE TABLE t1 (a int); +CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2),(3); INSERT INTO t1 VALUES (4),(5),(6); --exec $MYSQL_DUMP --skip-comments --insert-ignore test t1 @@ -215,9 +218,9 @@ INSERT INTO t1 VALUES (4),(5),(6); DROP TABLE t1; --echo # ---echo # Bug #10286: mysqldump -c crashes on table that has many fields with long ---echo # names ---echo # +--echo # Bug#10286 mysqldump -c crashes on table that has many fields with long +--echo # names +--echo # create table t1 ( F_c4ca4238a0b923820dcc509a6f75849b int, F_c81e728d9d4c2f636f067f89cc14862c int, @@ -563,7 +566,7 @@ INSERT INTO t1 VALUES (1),(2),(3); DROP TABLE t1; --echo # ---echo # Bug #9558 mysqldump --no-data db t1 t2 format still dumps data +--echo # Bug#9558 mysqldump --no-data db t1 t2 format still dumps data --echo # CREATE DATABASE mysqldump_test_db; @@ -582,7 +585,7 @@ DROP DATABASE mysqldump_test_db; --echo # --echo # Testing with tables and databases that don't exists --echo # or contains illegal characters ---echo # (Bug #9358 mysqldump crashes if tablename starts with \) +--echo # (Bug#9358 mysqldump crashes if tablename starts with \) --echo # create database mysqldump_test_db; use mysqldump_test_db; @@ -601,7 +604,7 @@ select '------ Testing with illegal table names ------' as test_sequence ; --error 6 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "\\t1" 2>&1 - + --error 6 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "\\\\t1" 2>&1 @@ -644,7 +647,7 @@ use test; --echo # ---echo # Bug #9657 mysqldump xml ( -x ) does not format NULL fields correctly +--echo # Bug#9657 mysqldump xml ( -x ) does not format NULL fields correctly --echo # create table t1 (a int(10)); @@ -655,8 +658,9 @@ insert into t2 (a, b) values (NULL, NULL),(10, NULL),(NULL, "twenty"),(30, "thir --exec $MYSQL_DUMP --skip-comments --xml --no-create-info test drop table t1, t2; + --echo # ---echo # BUG #12123 +--echo # Bug#12123 mysqldump --tab results in text file which can't be imported --echo # create table t1 (a text character set utf8, b text character set latin1); @@ -669,14 +673,15 @@ select * from t1; drop table t1; + --echo # ---echo # BUG#15328 Segmentation fault occured if my.cnf is invalid for escape sequence +--echo # Bug#15328 Segmentation fault occured if my.cnf is invalid for escape sequence --echo # --exec $MYSQL_MY_PRINT_DEFAULTS --config-file=$MYSQL_TEST_DIR/std_data/bug15328.cnf mysqldump --echo # ---echo # BUG #19025 mysqldump doesn't correctly dump "auto_increment = [int]" +--echo # Bug#19025 mysqldump doesn't correctly dump "auto_increment = [int]" --echo # create table `t1` ( @@ -704,9 +709,11 @@ select * from t1; show create table `t1`; drop table `t1`; +--remove_file $MYSQLTEST_VARDIR/tmp/bug19025.sql + --echo # ---echo # Bug #18536: wrong table order +--echo # Bug#18536 wrong table order --echo # create table t1(a int); @@ -716,8 +723,9 @@ create table t3(a int); --exec $MYSQL_DUMP --skip-comments --force --no-data test t3 t1 non_existing t2 drop table t1, t2, t3; + --echo # ---echo # Bug #21288: mysqldump segmentation fault when using --where +--echo # Bug#21288 mysqldump segmentation fault when using --where --echo # create table t1 (a int); @@ -725,8 +733,9 @@ create table t1 (a int); --exec $MYSQL_DUMP --skip-comments --force test t1 --where="xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 2>&1 drop table t1; + --echo # ---echo # BUG#13926: --order-by-primary fails if PKEY contains quote character +--echo # Bug#13926 --order-by-primary fails if PKEY contains quote character --echo # --disable_warnings @@ -746,8 +755,9 @@ DROP TABLE `t1`; --echo End of 4.1 tests + --echo # ---echo # Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) +--echo # Bug#10213 mysqldump crashes when dumping VIEWs(on MacOS X) --echo # create database db1; @@ -770,8 +780,9 @@ drop view v2; drop database db1; use test; + --echo # ---echo # Bug 10713 mysqldump includes database in create view and referenced tables +--echo # Bug#10713 mysqldump includes database in create view and referenced tables --echo # # create table and views in db2 @@ -805,18 +816,21 @@ select * from t2 order by a; drop table t1, t2; drop database db1; use test; +--remove_file $MYSQLTEST_VARDIR/tmp/bug10713.sql # # dump of view # + create table t1(a int); create view v1 as select * from t1; --exec $MYSQL_DUMP --skip-comments test drop view v1; drop table t1; + --echo # ---echo # Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) +--echo # Bug#10213 mysqldump crashes when dumping VIEWs(on MacOS X) --echo # create database mysqldump_test_db; @@ -840,7 +854,7 @@ drop database mysqldump_test_db; use test; --echo # ---echo # Bug #9756 +--echo # Bug#9756 mysql client failing on dumps containing certain \ sequences --echo # CREATE TABLE t1 (a char(10)); @@ -849,7 +863,7 @@ INSERT INTO t1 VALUES ('\''); DROP TABLE t1; --echo # ---echo # Bug #10927 mysqldump: Can't reload dump with view that consist of other view +--echo # Bug#10927 mysqldump: Can't reload dump with view that consist of other view --echo # create table t1(a int, b int, c varchar(30)); @@ -921,7 +935,9 @@ show triggers; DROP TABLE t1, t2; --echo # ---echo # Bugs #9136, #12917: problems with --defaults-extra-file option +--echo # Bug#9136 my_print_defaults changed behaviour between 4.1.7 and 4.1.10a +--echo # Bug#12917 The --defaults-extra-file option is ignored by the 5.0 client binaries +--echo # (Problems with --defaults-extra-file option) --echo # --write_file $MYSQLTEST_VARDIR/tmp/tmp.cnf @@ -933,7 +949,7 @@ EOF --remove_file $MYSQLTEST_VARDIR/tmp/tmp.cnf --echo # ---echo # Test of fix to BUG 12597 +--echo # Test of fix to Bug#12597 mysqldump dumps triggers wrongly --echo # DROP TABLE IF EXISTS `test1`; @@ -969,9 +985,11 @@ SELECT * FROM `test2`; DROP TRIGGER testref; DROP TABLE test1; DROP TABLE test2; +--remove_file $MYSQLTEST_VARDIR/tmp/mysqldump.sql + --echo # ---echo # BUG#9056 - mysqldump does not dump routines +--echo # Bug#9056 mysqldump does not dump routines --echo # --disable_warnings @@ -997,9 +1015,9 @@ begin return f1; end // -CREATE PROCEDURE bug9056_proc2(OUT a INT) -BEGIN - select sum(id) from t1 into a; +CREATE PROCEDURE bug9056_proc2(OUT a INT) +BEGIN + select sum(id) from t1 into a; END // DELIMITER ;// @@ -1008,7 +1026,7 @@ set sql_mode='ansi'; create procedure `a'b` () select 1; # to fix syntax highlighting :') set sql_mode=''; -# Dump the DB and ROUTINES +# Dump the DB and ROUTINES --exec $MYSQL_DUMP --skip-comments --routines --databases test # ok, now blow it all away @@ -1019,8 +1037,9 @@ DROP PROCEDURE bug9056_proc2; DROP PROCEDURE `a'b`; drop table t1; + --echo # ---echo # BUG# 13052 - mysqldump timestamp reloads broken +--echo # Bug#13052 mysqldump timestamp reloads broken --echo # --disable_warnings @@ -1043,7 +1062,7 @@ set global time_zone=default; set time_zone=default; --echo # ---echo # Test of fix to BUG 13146 - ansi quotes break loading of triggers +--echo # Test of fix to Bug#13146 ansi quotes break loading of triggers --echo # --disable_warnings @@ -1068,7 +1087,7 @@ INSERT INTO `t1 test` VALUES (1); INSERT INTO `t1 test` VALUES (2); INSERT INTO `t1 test` VALUES (3); SELECT * FROM `t2 test`; -# dump with compatible=ansi. Everything except triggers should be double +# dump with compatible=ansi. Everything except triggers should be double # quoted --exec $MYSQL_DUMP --skip-comments --compatible=ansi --triggers test @@ -1077,7 +1096,7 @@ DROP TABLE `t1 test`; DROP TABLE `t2 test`; --echo # ---echo # BUG# 12838 mysqldump -x with views exits with error +--echo # Bug#12838 mysqldump -x with views exits with error --echo # --disable_warnings @@ -1101,7 +1120,7 @@ drop view v1; drop table t1; --echo # ---echo # BUG#14554 - mysqldump does not separate words "ROW" and "BEGIN" +--echo # Bug#14554 mysqldump does not separate words "ROW" and "BEGIN" --echo # for tables with trigger created in the IGNORE_SPACE sql mode. --echo # @@ -1125,8 +1144,8 @@ DROP TRIGGER tr1; DROP TABLE t1; --echo # ---echo # Bug #13318: Bad result with empty field and --hex-blob ---echo # +--echo # Bug#13318 Bad result with empty field and --hex-blob +--echo # create table t1 (a binary(1), b blob); insert into t1 values ('',''); @@ -1135,7 +1154,7 @@ insert into t1 values ('',''); drop table t1; --echo # ---echo # Bug 14871 Invalid view dump output +--echo # Bug#14871 Invalid view dump output --echo # create table t1 (a int); @@ -1162,9 +1181,11 @@ select * from v3 order by a; drop table t1; drop view v1, v2, v3, v4, v5; +--remove_file $MYSQLTEST_VARDIR/tmp/bug14871.sql + --echo # ---echo # Bug #16878 dump of trigger +--echo # Bug#16878 dump of trigger --echo # create table t1 (a int, created datetime); @@ -1192,6 +1213,8 @@ show triggers; drop trigger tr1; drop trigger tr2; drop table t1, t2; +--remove_file $MYSQLTEST_VARDIR/tmp/bug16878.sql + --echo # --echo # Bug#18462 mysqldump does not dump view structures correctly @@ -1211,11 +1234,15 @@ create view v2 as select qty from v1; drop view v1; drop view v2; drop table t; +--remove_file $MYSQLTEST_VARDIR/tmp/v1.sql +--remove_file $MYSQLTEST_VARDIR/tmp/v2.sql +--remove_file $MYSQLTEST_VARDIR/tmp/t.sql +--remove_file $MYSQLTEST_VARDIR/tmp/t.txt --echo # --echo # Bug#14857 Reading dump files with single statement stored routines fails. ---echo # fixed by patch for bug#16878 +--echo # fixed by patch for Bug#16878 --echo # DELIMITER |; @@ -1230,7 +1257,7 @@ drop function f; drop procedure p; --echo # ---echo # Bug #17371 Unable to dump a schema with invalid views +--echo # Bug#17371 Unable to dump a schema with invalid views --echo # create table t1 ( id serial ); @@ -1243,7 +1270,8 @@ drop table t1; --echo } mysqldump drop view v1; ---echo # BUG#17201 Spurious 'DROP DATABASE' in output, + +--echo # Bug#17201 Spurious 'DROP DATABASE' in output, --echo # also confusion between tables and views. --echo # Example code from Markus Popp @@ -1260,8 +1288,9 @@ drop view v1; drop table t1; drop database mysqldump_test_db; + --echo # ---echo # Bug21014 Segmentation fault of mysqldump on view +--echo # Bug#21014 Segmentation fault of mysqldump on view --echo # create database mysqldump_tables; @@ -1280,7 +1309,7 @@ drop table mysqldump_tables.basetable; drop database mysqldump_tables; --echo # ---echo # Bug20221 Dumping of multiple databases containing view(s) yields maleformed dumps +--echo # Bug#20221 Dumping of multiple databases containing view(s) yields maleformed dumps --echo # create database mysqldump_dba; @@ -1318,6 +1347,7 @@ use mysqldump_dbb; drop view v1; drop table t1; drop database mysqldump_dbb; +--remove_file $MYSQLTEST_VARDIR/tmp/bug20221_backup use test; --echo # @@ -1363,11 +1393,12 @@ grant REPLICATION CLIENT on *.* to mysqltest_1@localhost; drop table t1; drop user mysqltest_1@localhost; + --echo # ---echo # Bug #21527 mysqldump incorrectly tries to LOCK TABLES on the ---echo # information_schema database. +--echo # Bug#21527 mysqldump incorrectly tries to LOCK TABLES on the +--echo # information_schema database. --echo # ---echo # Bug #21424 mysqldump failing to export/import views +--echo # Bug#21424 mysqldump failing to export/import views --echo # # Do as root @@ -1388,7 +1419,7 @@ create table u1 (f1 int); insert into u1 values (4); create view v1 (c1) as select * from t1; -# Backup should not fail for Bug #21527. Flush priviliges test begins. +# Backup should not fail for Bug#21527. Flush priviliges test begins. --exec $MYSQL_DUMP --skip-comments --add-drop-table --flush-privileges --ignore-table=mysql.general_log --ignore-table=mysql.slow_log --databases mysqldump_myDB mysql > $MYSQLTEST_VARDIR/tmp/bug21527.sql # Clean up @@ -1402,8 +1433,9 @@ drop user myDB_User@localhost; drop database mysqldump_myDB; flush privileges; ---echo # Bug #21424 continues from here. ---echo # Restore. Flush Privileges test ends. + +--echo # Bug#21424 continues from here. +--echo # Restore. Flush Privileges test ends. --echo # --exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug21527.sql @@ -1416,8 +1448,9 @@ use mysqldump_myDB; select * from mysqldump_myDB.v1; select * from mysqldump_myDB.u1; -#Final cleanup. +# Final cleanup. connection root; +disconnect user1; use mysqldump_myDB; drop view v1; drop table t1; @@ -1425,10 +1458,14 @@ drop table u1; revoke all privileges on mysqldump_myDB.* from myDB_User@localhost; drop user myDB_User@localhost; drop database mysqldump_myDB; +connection default; +disconnect root; +--remove_file $MYSQLTEST_VARDIR/tmp/bug21527.sql use test; + --echo # ---echo # Bug #19745: mysqldump --xml produces invalid xml +--echo # Bug#19745 mysqldump --xml produces invalid xml --echo # --disable_warnings @@ -1443,9 +1480,8 @@ INSERT INTO t1 VALUES(1,0xff00fef0); DROP TABLE t1; - --echo # ---echo # Bug#26346: stack + buffer overrun in mysqldump +--echo # Bug#26346 stack + buffer overrun in mysqldump --echo # CREATE TABLE t1(a int); @@ -1466,18 +1502,20 @@ INSERT INTO t1 VALUES (1), (2); DROP TABLE t1; + # -# Bug #25993: crashe with a merge table and -c +# Bug#25993 crashes with a merge table and -c # -CREATE TABLE t2 (a int); -CREATE TABLE t3 (a int); -CREATE TABLE t1 (a int) ENGINE=merge UNION=(t2, t3); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT); +CREATE TABLE t1 (a INT) ENGINE=merge UNION=(t2, t3); --exec $MYSQL_DUMP --skip-comments -c test DROP TABLE t1, t2, t3; + --echo # ---echo # Bug #23491: MySQLDump prefix function call in a view by database name +--echo # Bug#23491 MySQLDump prefix function call in a view by database name --echo # # Setup @@ -1507,15 +1545,16 @@ show create view bug23491_restore.v3; drop database bug23491_original; drop database bug23491_restore; use test; +--remove_file $MYSQLTEST_VARDIR/tmp/bug23491_backup.sql ---echo # ---echo # Bug 27293: mysqldump crashes when dumping routines ---echo # defined by a different user --echo # ---echo # Bug #22761: mysqldump reports no errors when using ---echo # --routines without mysql.proc privileges +--echo # Bug#27293 mysqldump crashes when dumping routines +--echo # defined by a different user +--echo # +--echo # Bug#22761 mysqldump reports no errors when using +--echo # --routines without mysql.proc privileges --echo # create database mysqldump_test_db; @@ -1536,13 +1575,14 @@ create procedure mysqldump_test_db.sp1() select 'hello'; drop procedure sp1; connection default; +disconnect user27293; drop user user1; drop user user2; drop database mysqldump_test_db; --echo # ---echo # Bug #28522: buffer overrun by '\0' byte using --hex-blob. +--echo # Bug#28522 buffer overrun by '\0' byte using --hex-blob. --echo # CREATE TABLE t1 (c1 INT, c2 LONGBLOB); @@ -1551,8 +1591,8 @@ INSERT INTO t1 SET c1=11, c2=REPEAT('q',509); DROP TABLE t1; --echo # ---echo # Bug #28524: mysqldump --skip-add-drop-table is not ---echo # compatible with views +--echo # Bug#28524 mysqldump --skip-add-drop-table is not +--echo # compatible with views --echo # CREATE VIEW v1 AS SELECT 1; @@ -1562,10 +1602,12 @@ DROP VIEW v1; --exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug28524.sql SELECT * FROM v1; DROP VIEW v1; +--remove_file $MYSQLTEST_VARDIR/tmp/bug28524.sql + --echo # ---echo # Bug #29788: mysqldump discards the NO_AUTO_VALUE_ON_ZERO value of ---echo # the SQL_MODE variable after the dumping of triggers. +--echo # Bug#29788 mysqldump discards the NO_AUTO_VALUE_ON_ZERO value of +--echo # the SQL_MODE variable after the dumping of triggers. --echo # CREATE TABLE t1 (c1 INT); @@ -1584,10 +1626,12 @@ SELECT * FROM t2; SELECT * FROM t2; DROP TABLE t1,t2; +--remove_file $MYSQLTEST_VARDIR/tmp/bug29788.sql + --echo # ---echo # Bug#29815: new option for suppressing last line of mysqldump: ---echo # "Dump completed on" +--echo # Bug#29815 new option for suppressing last line of mysqldump: +--echo # "Dump completed on" --echo # --echo # --skip-dump-date: @@ -1609,3 +1653,6 @@ SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT; --echo # --echo # End of 5.0 tests --echo # + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test index 14c14fca0c6..ad051503fd6 100644 --- a/mysql-test/t/openssl_1.test +++ b/mysql-test/t/openssl_1.test @@ -3,6 +3,10 @@ -- source include/have_ssl.inc +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + + --disable_warnings drop table if exists t1; --enable_warnings @@ -21,38 +25,42 @@ connect (con2,localhost,ssl_user2,,,,,SSL); connect (con3,localhost,ssl_user3,,,,,SSL); connect (con4,localhost,ssl_user4,,,,,SSL); --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT ---error 1045 +--error ER_ACCESS_DENIED_ERROR connect (con5,localhost,ssl_user5,,,,,SSL); connection con1; # Check ssl turned on SHOW STATUS LIKE 'Ssl_cipher'; select * from t1; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR delete from t1; connection con2; # Check ssl turned on SHOW STATUS LIKE 'Ssl_cipher'; select * from t1; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR delete from t1; connection con3; # Check ssl turned on SHOW STATUS LIKE 'Ssl_cipher'; select * from t1; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR delete from t1; connection con4; # Check ssl turned on SHOW STATUS LIKE 'Ssl_cipher'; select * from t1; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR delete from t1; connection default; +disconnect con1; +disconnect con2; +disconnect con3; +disconnect con4; drop user ssl_user1@localhost, ssl_user2@localhost, ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost; @@ -97,7 +105,7 @@ drop table t1; --exec $MYSQL_TEST --ssl-cert= --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 # -# BUG#21611 Slave can't connect when master-ssl-cipher specified +# Bug#21611 Slave can't connect when master-ssl-cipher specified # - Apparently selecting a cipher doesn't work at all # - Usa a cipher that both yaSSL and OpenSSL supports # @@ -133,7 +141,7 @@ drop table t1; --exec $MYSQL_TEST --ssl-cipher=UNKNOWN-CIPHER < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 # -# Bug #27669 mysqldump: SSL connection error when trying to connect +# Bug#27669 mysqldump: SSL connection error when trying to connect # CREATE TABLE t1(a int); @@ -152,3 +160,7 @@ INSERT INTO t1 VALUES (1), (2); --exec $MYSQL_DUMP --skip-create --skip-comments --ssl --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test 2>&1 DROP TABLE t1; +--remove_file $MYSQLTEST_VARDIR/tmp/test.sql + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/outfile.test b/mysql-test/t/outfile.test index 527a4d398d8..4398f9fa741 100644 --- a/mysql-test/t/outfile.test +++ b/mysql-test/t/outfile.test @@ -5,6 +5,10 @@ eval set @tmpdir="../tmp"; enable_query_log; -- source include/have_outfile.inc +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + + # # test of into outfile|dumpfile # @@ -46,7 +50,7 @@ select load_file(concat(@tmpdir,"/outfile-test.not-exist")); --remove_file $MYSQLTEST_VARDIR/tmp/outfile-test.3 drop table t1; -# Bug#8191 +# Bug#8191 SELECT INTO OUTFILE insists on FROM clause disable_query_log; eval select 1 into outfile "../tmp/outfile-test.4"; enable_query_log; @@ -54,11 +58,11 @@ select load_file(concat(@tmpdir,"/outfile-test.4")); --remove_file $MYSQLTEST_VARDIR/tmp/outfile-test.4 # -# Bug #5382: 'explain select into outfile' crashes the server +# Bug#5382 'explain select into outfile' crashes the server # CREATE TABLE t1 (a INT); -EXPLAIN +EXPLAIN SELECT * INTO OUTFILE '/tmp/t1.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\r\n' @@ -68,7 +72,7 @@ DROP TABLE t1; # End of 4.1 tests # -# Bug#13202 SELECT * INTO OUTFILE ... FROM information_schema.schemata now fails +# Bug#13202 SELECT * INTO OUTFILE ... FROM information_schema.schemata now fails # disable_query_log; eval SELECT * INTO OUTFILE "../tmp/outfile-test.4" @@ -114,6 +118,7 @@ from information_schema.schemata where schema_name like 'mysqltest'; connection default; +disconnect con28181_1; grant file on *.* to user_1@localhost; connect (con28181_2,localhost,user_1,,mysqltest); @@ -125,9 +130,12 @@ from information_schema.schemata where schema_name like 'mysqltest'; connection default; +disconnect con28181_2; --remove_file $MYSQLTEST_VARDIR/tmp/outfile-test.4 use test; revoke all privileges on *.* from user_1@localhost; drop user user_1@localhost; drop database mysqltest; +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc -- cgit v1.2.1 From 039f51a047987dd7d353dac658ca907bc64ca327 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Mon, 2 Feb 2009 17:30:02 -0500 Subject: Bug#39369: execution of "variables.test" with "check-testcases" show differences. The original symptoms of this bug have been fixed as a consequence of other bug fixes. Taking this time to correct some formatting, such as replacing error numbers with names. Beginning this with 5.0 --- mysql-test/t/variables.test | 92 ++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 1748b63ceb9..60254ad9a1d 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -6,7 +6,7 @@ drop table if exists t1,t2; --enable_warnings # -# Bug #19263: variables.test doesn't clean up after itself (I/II -- save) +# Bug#19263: variables.test doesn't clean up after itself (I/II -- save) # set @my_binlog_cache_size =@@global.binlog_cache_size; set @my_connect_timeout =@@global.connect_timeout; @@ -172,46 +172,46 @@ SELECT @@version_compile_os LIKE 'non-existent'; # The following should give errors ---error 1231 +--error ER_WRONG_VALUE_FOR_VAR set big_tables=OFFF; ---error 1231 +--error ER_WRONG_VALUE_FOR_VAR set big_tables="OFFF"; ---error 1193 +--error ER_UNKNOWN_SYSTEM_VARIABLE set unknown_variable=1; ---error 1232 +--error ER_WRONG_TYPE_FOR_VAR set max_join_size="hello"; ---error 1286 +--error ER_UNKNOWN_STORAGE_ENGINE set storage_engine=UNKNOWN_TABLE_TYPE; ---error 1231 +--error ER_WRONG_VALUE_FOR_VAR set storage_engine=MERGE, big_tables=2; show local variables like 'storage_engine'; ---error 1229 +--error ER_GLOBAL_VARIABLE set SESSION query_cache_size=10000; ---error 1230 +--error ER_NO_DEFAULT set GLOBAL storage_engine=DEFAULT; ---error 1115 +--error ER_UNKNOWN_CHARACTER_SET set character_set_client=UNKNOWN_CHARACTER_SET; ---error 1273 +--error ER_UNKNOWN_COLLATION set collation_connection=UNKNOWN_COLLATION; ---error 1231 +--error ER_WRONG_VALUE_FOR_VAR set character_set_client=NULL; ---error 1231 +--error ER_WRONG_VALUE_FOR_VAR set collation_connection=NULL; ---error 1228 +--error ER_LOCAL_VARIABLE set global autocommit=1; ---error 1238 +--error ER_INCORRECT_GLOBAL_LOCAL_VAR select @@global.timestamp; ---error 1238 +--error ER_INCORRECT_GLOBAL_LOCAL_VAR set @@version=''; ---error 1229 +--error ER_GLOBAL_VARIABLE set @@concurrent_insert=1; ---error 1228 +--error ER_LOCAL_VARIABLE set @@global.sql_auto_is_null=1; ---error 1238 +--error ER_INCORRECT_GLOBAL_LOCAL_VAR select @@global.sql_auto_is_null; ---error 1229 +--error ER_GLOBAL_VARIABLE set myisam_max_sort_file_size=100; ---error 1231 +--error ER_WRONG_VALUE_FOR_VAR set @@SQL_WARNINGS=NULL; # Test setting all variables @@ -338,23 +338,23 @@ drop table t1,t2; # error conditions # ---error 1193 +--error ER_UNKNOWN_SYSTEM_VARIABLE select @@xxxxxxxxxx; select 1; ---error 1238 +--error ER_INCORRECT_GLOBAL_LOCAL_VAR select @@session.key_buffer_size; ---error 1229 +--error ER_GLOBAL_VARIABLE set ft_boolean_syntax = @@init_connect; ---error 1231 +--error ER_WRONG_VALUE_FOR_VAR set global ft_boolean_syntax = @@init_connect; ---error 1229 +--error ER_GLOBAL_VARIABLE set init_connect = NULL; set global init_connect = NULL; ---error 1229 +--error ER_GLOBAL_VARIABLE set ft_boolean_syntax = @@init_connect; ---error 1231 +--error ER_WRONG_VALUE_FOR_VAR set global ft_boolean_syntax = @@init_connect; # Bug#3754 SET GLOBAL myisam_max_sort_file_size doesn't work as @@ -385,15 +385,15 @@ select @a, @b; # # Bug#2586:Disallow global/session/local as structured var. instance names # ---error 1064 +--error ER_PARSE_ERROR set @@global.global.key_buffer_size= 1; ---error 1064 +--error ER_PARSE_ERROR set GLOBAL global.key_buffer_size= 1; ---error 1064 +--error ER_PARSE_ERROR SELECT @@global.global.key_buffer_size; ---error 1064 +--error ER_PARSE_ERROR SELECT @@global.session.key_buffer_size; ---error 1064 +--error ER_PARSE_ERROR SELECT @@global.local.key_buffer_size; # BUG#5135: cannot turn on log_warnings with SET in 4.1 (and 4.0) @@ -478,27 +478,27 @@ select @@lc_time_names; --echo *** LC_TIME_NAMES: testing with string expressions set lc_time_names=concat('de','_','DE'); select @@lc_time_names; ---error 1105 +--error ER_UNKNOWN_ERROR set lc_time_names=concat('de','+','DE'); select @@lc_time_names; --echo LC_TIME_NAMES: testing with numeric expressions set @@lc_time_names=1+2; select @@lc_time_names; ---error 1232 +--error ER_WRONG_TYPE_FOR_VAR set @@lc_time_names=1/0; select @@lc_time_names; set lc_time_names=en_US; --echo LC_TIME_NAMES: testing NULL and a negative number: ---error 1231 +--error ER_WRONG_VALUE_FOR_VAR set lc_time_names=NULL; ---error 1105 +--error ER_UNKNOWN_ERROR set lc_time_names=-1; select @@lc_time_names; --echo LC_TIME_NAMES: testing locale with the last ID: set lc_time_names=108; select @@lc_time_names; --echo LC_TIME_NAMES: testing a number beyond the valid ID range: ---error 1105 +--error ER_UNKNOWN_ERROR set lc_time_names=109; select @@lc_time_names; --echo LC_TIME_NAMES: testing that 0 is en_US: @@ -540,7 +540,7 @@ select @@query_prealloc_size = @test; # Bug#31588 buffer overrun when setting variables # # Buffer-size Off By One. Should throw valgrind-warning without fix #31588. ---error 1231 +--error ER_WRONG_VALUE_FOR_VAR set global sql_mode=repeat('a',80); --echo End of 4.1 tests @@ -558,9 +558,9 @@ drop table t1; # Bug #10339: read only variables. # ---error 1238 +--error ER_INCORRECT_GLOBAL_LOCAL_VAR set @@warning_count=1; ---error 1238 +--error ER_INCORRECT_GLOBAL_LOCAL_VAR set @@global.error_count=1; # @@ -578,9 +578,9 @@ select @@max_heap_table_size > 0; # Bug #11775 Variable character_set_system does not exist (sometimes) # select @@character_set_system; ---error 1238 +--error ER_INCORRECT_GLOBAL_LOCAL_VAR set global character_set_system = latin1; ---error 1238 +--error ER_INCORRECT_GLOBAL_LOCAL_VAR set @@global.version_compile_os='234'; # @@ -677,7 +677,7 @@ select @@@; # Don't actually output, since it depends on the system --replace_column 1 # select @@hostname; ---error 1238 +--error ER_INCORRECT_GLOBAL_LOCAL_VAR set @@hostname= "anothername"; --replace_column 2 # show variables like 'hostname'; @@ -688,12 +688,12 @@ show variables like 'hostname'; SHOW VARIABLES LIKE 'log'; SELECT @@log; ---error 1238 +--error ER_INCORRECT_GLOBAL_LOCAL_VAR SET GLOBAL log=0; SHOW VARIABLES LIKE 'log_slow_queries'; SELECT @@log_slow_queries; ---error 1238 +--error ER_INCORRECT_GLOBAL_LOCAL_VAR SET GLOBAL log_slow_queries=0; --echo End of 5.0 tests -- cgit v1.2.1 From 5fa093f1b02ff84a97c82d633e9a12e64f4cdf07 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 3 Feb 2009 11:04:22 +0200 Subject: changed the version in .bzr-mysql/default.conf --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..f79c1cd6319 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.0-bugteam" +tree_name = "mysql-5.0" -- cgit v1.2.1 From d70c448e157bdb1c88394a7ecafd4a287c54d4c7 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Tue, 3 Feb 2009 20:19:01 +0300 Subject: Fix for bug #41868: crash or memory overrun with concat + upper, date_format functions String::realloc() did not check whether the existing string data fits in the newly allocated buffer for cases when reallocating a String object with external buffer (i.e.alloced == FALSE). This could lead to memory overruns in some cases. mysql-test/r/func_str.result: Added a test case for bug #41868. mysql-test/t/func_str.test: Added a test case for bug #41868. sql/sql_class.cc: After each call to Item::send() in select_send::send_data() reset buffer to its original state to reduce unnecessary malloc() calls. See comments for bug #41868 for detailed analysis. sql/sql_string.cc: Fixed String::realloc() to check whether the existing string data fits in the newly allocated buffer for cases when reallocating a String object with external buffer. --- client/sql_string.cc | 20 ++++++++++---------- mysql-test/r/func_str.result | 6 ++++++ mysql-test/t/func_str.test | 9 +++++++++ sql/sql_class.cc | 5 +++++ sql/sql_string.cc | 20 ++++++++++---------- 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/client/sql_string.cc b/client/sql_string.cc index 9d887ff031c..eb80e29ed49 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -72,26 +72,26 @@ bool String::realloc(uint32 alloc_length) if (alloced) { if ((new_ptr= (char*) my_realloc(Ptr,len,MYF(MY_WME)))) - { - Ptr=new_ptr; - Alloced_length=len; - } + new_ptr[alloc_length]= 0; else - return TRUE; // Signal error + return TRUE; // Signal error } else if ((new_ptr= (char*) my_malloc(len,MYF(MY_WME)))) { + if (str_length > len - 1) + str_length= 0; if (str_length) // Avoid bugs in memcpy on AIX - memcpy(new_ptr,Ptr,str_length); - new_ptr[str_length]=0; - Ptr=new_ptr; - Alloced_length=len; + memcpy(new_ptr, Ptr, str_length); + new_ptr[str_length]= 0; alloced=1; } else return TRUE; // Signal error + Ptr= new_ptr; + Alloced_length= len; } - Ptr[alloc_length]=0; // This make other funcs shorter + else + Ptr[alloc_length]= 0; return FALSE; } diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index c121c8937d7..d7fd8c5c887 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -2181,4 +2181,10 @@ def format(a, 2) 253 20 4 Y 0 2 8 format(a, 2) 1.33 drop table t1; +CREATE TABLE t1 (c DATE, aa VARCHAR(30)); +INSERT INTO t1 VALUES ('2008-12-31','aaaaaa'); +SELECT DATE_FORMAT(c, GET_FORMAT(DATE, 'eur')) h, CONCAT(UPPER(aa),', ', aa) i FROM t1; +h i +31.12.2008 AAAAAA, aaaaaa +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 8298a50c277..389538c4cc0 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1159,4 +1159,13 @@ select format(a, 2) from t1; --disable_metadata drop table t1; +# +# Bug #41868: crash or memory overrun with concat + upper, date_format functions +# + +CREATE TABLE t1 (c DATE, aa VARCHAR(30)); +INSERT INTO t1 VALUES ('2008-12-31','aaaaaa'); +SELECT DATE_FORMAT(c, GET_FORMAT(DATE, 'eur')) h, CONCAT(UPPER(aa),', ', aa) i FROM t1; +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 91c0aa66761..9ff602bb62e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1047,6 +1047,11 @@ bool select_send::send_data(List &items) my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); break; } + /* + Reset buffer to its original state, as it may have been altered in + Item::send(). + */ + buffer.set(buff, sizeof(buff), &my_charset_bin); } thd->sent_row_count++; if (!thd->vio_ok()) diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 75e47dd0c8e..b6ce4d8dc8d 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -72,26 +72,26 @@ bool String::realloc(uint32 alloc_length) if (alloced) { if ((new_ptr= (char*) my_realloc(Ptr,len,MYF(MY_WME)))) - { - Ptr=new_ptr; - Alloced_length=len; - } + new_ptr[alloc_length]= 0; else - return TRUE; // Signal error + return TRUE; // Signal error } else if ((new_ptr= (char*) my_malloc(len,MYF(MY_WME)))) { + if (str_length > len - 1) + str_length= 0; if (str_length) // Avoid bugs in memcpy on AIX - memcpy(new_ptr,Ptr,str_length); - new_ptr[str_length]=0; - Ptr=new_ptr; - Alloced_length=len; + memcpy(new_ptr, Ptr, str_length); + new_ptr[str_length]= 0; alloced=1; } else return TRUE; // Signal error + Ptr= new_ptr; + Alloced_length= len; } - Ptr[alloc_length]=0; // This make other funcs shorter + else + Ptr[alloc_length]= 0; return FALSE; } -- cgit v1.2.1 From ed9e030abb6b233878554355fbff65ad597af0c8 Mon Sep 17 00:00:00 2001 From: Timothy Smith Date: Wed, 4 Feb 2009 04:20:42 +0100 Subject: The nwbootstrap script depended on BitKeeper, and was fairly complicated. It's much simpler to just use the source .tar.gz to do a build. So the script has been renamed to nwbuild, and simplified. --- netware/BUILD/nwbootstrap | 191 ---------------------------------------------- netware/BUILD/nwbuild | 86 +++++++++++++++++++++ 2 files changed, 86 insertions(+), 191 deletions(-) delete mode 100755 netware/BUILD/nwbootstrap create mode 100755 netware/BUILD/nwbuild diff --git a/netware/BUILD/nwbootstrap b/netware/BUILD/nwbootstrap deleted file mode 100755 index 7ea8b9fc4b8..00000000000 --- a/netware/BUILD/nwbootstrap +++ /dev/null @@ -1,191 +0,0 @@ -#! /bin/sh - -# debug -#set -x - -# stop on errors -set -e - -path=`dirname $0` - -# repository direcotry -repo_dir=`pwd` - -# build directory -build_dir="$HOME/mydev" -wine_build_dir="F:/mydev" - -# doc directory -doc_dir="$repo_dir/../mysqldoc" - -# init -target_dir="" -temp_dir="" -revision="" -rev="" -build="" -suffix="" -#obsolete mwenv="" - -# show usage -show_usage() -{ - cat << EOF - -usage: nwbootstrap [options] - -Exports a revision of the BitKeeper tree (nwbootstrap must be run inside a -directory of the BitKeeper tree to be used). Creates the ChangeLog file. -Adds the latest manual.texi from the mysqldoc BitKeeper tree. Builds the -Linux tools required for cross-platform builds. Optionally, builds the -binary distributions for NetWare. - -options: - ---build= Build the binary distributions for NetWare, - where is "standard", "debug", or "all" - (default is to not build a binary distribution) - ---build-dir= Export the BitKeeper tree to the directroy - (default is "$build_dir") - ---doc-dir= Use the mysqldoc BitKeeper tree located in the - directory - (default is parallel to current BitKeeper tree) - ---help Show this help information - ---revision= Export the BitKeeper tree as of revision - (default is the latest revision) - ---wine-build-dir= Use the WINE directory , which should - correspond to the --build-dir directory - (default is "$wine_build_dir") - -examples: - - nwbootstrap - - nwbootstrap --revision=1.1594 --build=all - - nwbootstrap --build-dir=/home/jdoe/dev --wine-build-dir=F:/dev - - -EOF - exit 0; -} - -# parse arguments -for arg do - case "$arg" in - --build-dir=*) build_dir=`echo "$arg" | sed -e "s;--build-dir=;;"` ;; - --wine-build-dir=*) wine_build_dir=`echo "$arg" | sed -e "s;--wine-build-dir=;;"` ;; - --revision=*) revision=`echo "$arg" | sed -e "s;--revision=;;"` ;; - --build=*) build=`echo "$arg" | sed -e "s;--build=;;"` ;; - --suffix=*) suffix=`echo "$arg" | sed -e "s;--suffix=;;"` ;; - --doc-dir=*) doc_dir=`echo "$arg" | sed -e "s;--doc-dir=;;"` ;; - *) show_usage ;; - esac -done - -echo "starting build..." - -# check for bk and repo_dir -bzr help > /dev/null -repo_dir=`bzr root $repo_dir` -cd $repo_dir -doc_dir="$repo_dir/../mysqldoc" - -# build temporary directory -temp_dir="$build_dir/mysql-$$.tmp" - -# export the bk tree -command="bzr export"; -if test $revision; then command="$command -r$revision"; fi -command="$command $temp_dir" -echo "exporting $repo_dir..." -$command - -# determine version -version=`grep -e "AM_INIT_AUTOMAKE(mysql, .*)" < $temp_dir/configure.in | sed -e "s/AM_INIT_AUTOMAKE(mysql, \(.*\))/\1/"` -echo "version: $version" - -# build target directory -target_dir="$build_dir/mysql-$version" - -# add suffix -if test $suffix -then - target_dir="$target_dir-$suffix" -fi - -# delete any old target -if test -d $target_dir.old; then rm -rf $target_dir.old; fi - -# rename old target -if test -d $target_dir; then mv -f $target_dir $target_dir.old; fi - -# rename directory to use version -mv $temp_dir $target_dir - -# create ChangeLog -if test $revision -then - rev=`bk changes -r..$revision -t -d':REV:' -n | head -2 | tail -1` -else - rev=`bk changes -t -d':REV:' -n | head -1` -fi - -echo "creating ChangeLog..." -bk changes -v -r$rev..$revision > $target_dir/ChangeLog - -# add the latest manual -if test -d $doc_dir -then - echo "adding the latest manual..." - install -m 644 $doc_dir/Docs/{manual,reservedwords}.texi $target_dir/Docs/ -fi - -# make files writeable -echo "making files writable..." -cd $target_dir -chmod -R u+rw,g+rw . - -#obsolete # edit the mvenv file -#obsolete echo "updating the mwenv environment file..." -#obsolete mwenv="./netware/BUILD/mwenv" -#obsolete mv -f $mwenv $mwenv.org -#obsolete sed -e "s;WINE_BUILD_DIR;$wine_build_dir;g" \ -#obsolete -e "s;BUILD_DIR;$build_dir;g" \ -#obsolete -e "s;VERSION;$version;g" $mwenv.org > $mwenv -#obsolete chmod +rwx $mwenv - -# edit the def file versions -echo "updating *.def file versions..." -nlm_version=`echo "$version" | sed -e "s;\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*;\1, \2, \3;"` - -for file in ./netware/*.def -do - mv -f $file $file.org - sed -e "s;VERSION.*;VERSION $nlm_version;g" $file.org > $file - rm $file.org -done - -# create the libmysql.imp file in netware folder from libmysql/libmysql.def -# file -echo "generating llibmysql.imp file..." -awk 'BEGIN{x=0;} END{printf("\n");} x==1 {printf(" %s",$1); x++; next} x>1 {printf(",\n %s", $1);next} /EXPORTS/{x=1}' libmysql/libmysql.def > netware/libmysql.imp -# build linux tools -echo "compiling linux tools..." -./netware/BUILD/compile-linux-tools -test -f ./netware/init_db.sql # this must exist -test -f ./netware/test_db.sql # this must exist - -# compile -if test $build -then - echo "compiling $build..." - ./netware/BUILD/compile-netware-$build -fi - -echo "done" diff --git a/netware/BUILD/nwbuild b/netware/BUILD/nwbuild new file mode 100755 index 00000000000..d431f70add8 --- /dev/null +++ b/netware/BUILD/nwbuild @@ -0,0 +1,86 @@ +#! /bin/sh + +# This script builds a Netware binary from a MySQL source tarball + +# debug +#set -x + +# stop on errors +set -e + +# init +build="" + +# show usage +show_usage() +{ + cat << EOF + +usage: nwbuild [options] + +Build Netware binary from source .tar.gz + +options: + +--build= Build the binary distributions for NetWare, + where is "standard", "debug", or "all" + (default is to not build a binary distribution) + +--help Show this help information + +Examples: + + ./netware/BUILD/nwbuild --build=debug + ./netware/BUILD/nwbuild --build=standard + +EOF +} + +# parse arguments +for arg do + case "$arg" in + --build=*) build=`echo "$arg" | sed -e "s;--build=;;"` ;; + --help) show_usage; exit 0 ;; + *) show_usage >&2; exit 1 ;; + esac +done + +# determine version +version=`grep -e "AM_INIT_AUTOMAKE(mysql, .*)" < configure.in | sed -e "s/AM_INIT_AUTOMAKE(mysql, \(.*\))/\1/"` +echo "version: $version" + +# make files writeable +echo "making files writable..." +chmod -R u+rw,g+rw . + +# edit the def file versions +nlm_version=`echo "$version" | sed -e "s;\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*;\1, \2, \3;"` +echo "updating *.def file versions to $nlm_version..." + +for file in ./netware/*.def +do + mv -f $file $file.org + sed -e "s;VERSION.*;VERSION $nlm_version;g" $file.org > $file + rm $file.org +done + +# create the libmysql.imp file in netware folder from libmysql/libmysql.def +# file +echo "generating libmysql.imp file..." +awk 'BEGIN{x=0;} END{printf("\n");} x==1 {printf(" %s",$1); x++; next} x>1 {printf(",\n %s", $1);next} /EXPORTS/{x=1}' libmysql/libmysql.def > netware/libmysql.imp +# build linux tools +echo "compiling linux tools..." +./netware/BUILD/compile-linux-tools +test -f ./netware/init_db.sql # this must exist +test -f ./netware/test_db.sql # this must exist + +# compile +if test $build +then + echo "compiling $build..." + ./netware/BUILD/compile-netware-$build +else + echo "Preparation complete. Use ./netware/BUILD/compile-netware-* to build MySQL." +fi + +echo "done" -- cgit v1.2.1 From 8819e71c2799c0ad50bc5c05d2806610c658fbeb Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 4 Feb 2009 15:46:23 +0400 Subject: BUG#32047 - 'Spurious' errors while opening MERGE tables Accessing well defined MERGE table may return an error stating that the merge table is incorrectly defined. This happens if MERGE child tables were accessed before and we failed to open another incorrectly defined MERGE table in this connection. myrg_open() internally used my_errno as a variable for determining failure, and thus could be tricked into a wrong decision by other uses of my_errno. With this fix we use function local boolean flag instead of my_errno to determine failure. myisammrg/myrg_open.c: There are two requirement for accessing/setting my_errno variable, which were not followed by myrg_open(): - it must be checked immediately after a function returned an error. There must be no calls to other functions that may change it's value between. - my_errno value must be set right before a function is going to return an error. There must be no calls to other functions that may change it's value between (that's why we have these tricks with save_errno at the bottom of myrg_open()). myrg_open() internally used my_errno as a variable for determining failure, and thus could be tricked into a wrong decision by other uses of my_errno. mysql-test/r/merge.result: A test case for BUG#32047. mysql-test/t/merge.test: A test case for BUG#32047. --- myisammrg/myrg_open.c | 17 ++++++++++------- mysql-test/r/merge.result | 11 +++++++++++ mysql-test/t/merge.test | 13 +++++++++++++ 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c index 0e82e429afd..4e61f42efce 100644 --- a/myisammrg/myrg_open.c +++ b/myisammrg/myrg_open.c @@ -40,6 +40,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) IO_CACHE file; MI_INFO *isam=0; uint found_merge_insert_method= 0; + my_bool bad_children= FALSE; DBUG_ENTER("myrg_open"); LINT_INIT(key_parts); @@ -89,13 +90,13 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) fn_format(buff, buff, "", "", 0); if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0)))) { - my_errno= HA_ERR_WRONG_MRG_TABLE_DEF; if (handle_locking & HA_OPEN_FOR_REPAIR) { myrg_print_wrong_table(buff); + bad_children= TRUE; continue; } - goto err; + goto bad_children; } if (!m_info) /* First file */ { @@ -122,13 +123,13 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) files++; if (m_info->reclength != isam->s->base.reclength) { - my_errno=HA_ERR_WRONG_MRG_TABLE_DEF; if (handle_locking & HA_OPEN_FOR_REPAIR) { myrg_print_wrong_table(buff); + bad_children= TRUE; continue; } - goto err; + goto bad_children; } m_info->options|= isam->s->options; m_info->records+= isam->state->records; @@ -141,8 +142,8 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) m_info->tables); } - if (my_errno == HA_ERR_WRONG_MRG_TABLE_DEF) - goto err; + if (bad_children) + goto bad_children; if (!m_info && !(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO), MYF(MY_WME | MY_ZEROFILL)))) goto err; @@ -170,12 +171,14 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) pthread_mutex_unlock(&THR_LOCK_open); DBUG_RETURN(m_info); +bad_children: + my_errno= HA_ERR_WRONG_MRG_TABLE_DEF; err: save_errno=my_errno; switch (errpos) { case 3: while (files) - mi_close(m_info->open_tables[--files].table); + (void) mi_close(m_info->open_tables[--files].table); my_free((char*) m_info,MYF(0)); /* Fall through */ case 2: diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index f8ef4f23180..3f2ac3e08ec 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -940,4 +940,15 @@ m1 CREATE TABLE `m1` ( `a` int(11) default NULL ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1, m1; +CREATE TABLE t1(a INT); +CREATE TABLE t2(a VARCHAR(10)); +CREATE TABLE m1(a INT) ENGINE=MERGE UNION=(t1, t2); +CREATE TABLE m2(a INT) ENGINE=MERGE UNION=(t1); +SELECT * FROM t1; +a +SELECT * FROM m1; +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +SELECT * FROM m2; +a +DROP TABLE t1, t2, m1, m2; End of 5.0 tests diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index e5cc4d703f2..341296dbe8e 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -556,4 +556,17 @@ ALTER TABLE m1 UNION=(); SHOW CREATE TABLE m1; DROP TABLE t1, m1; +# +# BUG#32047 - 'Spurious' errors while opening MERGE tables +# +CREATE TABLE t1(a INT); +CREATE TABLE t2(a VARCHAR(10)); +CREATE TABLE m1(a INT) ENGINE=MERGE UNION=(t1, t2); +CREATE TABLE m2(a INT) ENGINE=MERGE UNION=(t1); +SELECT * FROM t1; +--error ER_WRONG_MRG_TABLE +SELECT * FROM m1; +SELECT * FROM m2; +DROP TABLE t1, t2, m1, m2; + --echo End of 5.0 tests -- cgit v1.2.1 From 91d23568edbe67a9658f6a78093f9d3c12d23499 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Thu, 5 Feb 2009 11:43:39 +0400 Subject: Fix for bug#42014: Crash, name_const with collate Problem: some queries using NAME_CONST(.. COLLATE ...) lead to server crash due to failed type cast. Fix: return the underlying item's type in case of NAME_CONST(.. COLLATE ...) to avoid wrong casting. mysql-test/r/func_misc.result: Fix for bug#42014: Crash, name_const with coll - test result. mysql-test/t/func_misc.test: Fix for bug#42014: Crash, name_const with coll - test case. sql/item.cc: Fix for bug#42014: Crash, name_const with coll - in case of NAME_CONST('name', 'value' COLLATE collation) Item_name_const::type() returns type of 'value' argument to awoid wrong type casting of the Item_name_const items. --- mysql-test/r/func_misc.result | 5 +++++ mysql-test/t/func_misc.test | 9 +++++++++ sql/item.cc | 25 +++++++++++++++++++------ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index ce177b511b9..e57d46c006a 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -319,4 +319,9 @@ select @my_uuid_date - @my_uuid_synthetic; @my_uuid_date - @my_uuid_synthetic 0 set @@session.time_zone=@save_tz; +CREATE TABLE t1 (a DATE); +SELECT * FROM t1 WHERE a = NAME_CONST('reportDate', +_binary'2009-01-09' COLLATE 'binary'); +a +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 93fe94ec94f..c8075c42fc7 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -436,5 +436,14 @@ select @my_uuid_date - @my_uuid_synthetic; set @@session.time_zone=@save_tz; + +# +# Bug#42014: Crash, name_const with collate +# +CREATE TABLE t1 (a DATE); +SELECT * FROM t1 WHERE a = NAME_CONST('reportDate', + _binary'2009-01-09' COLLATE 'binary'); +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index fc5ee3d4d6a..bc1ae683e93 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1243,13 +1243,26 @@ Item::Type Item_name_const::type() const valid_args guarantees value_item->basic_const_item(); if type is FUNC_ITEM, then we have a fudged item_func_neg() on our hands and return the underlying type. + For Item_func_set_collation() + e.g. NAME_CONST('name', 'value' COLLATE collation) we return its + 'value' argument type. */ - return valid_args ? - (((value_item->type() == FUNC_ITEM) && - (((Item_func *) value_item)->functype() == Item_func::NEG_FUNC)) ? - ((Item_func *) value_item)->key_item()->type() : - value_item->type()) : - NULL_ITEM; + if (!valid_args) + return NULL_ITEM; + Item::Type value_type= value_item->type(); + if (value_type == FUNC_ITEM) + { + /* + The second argument of NAME_CONST('name', 'value') must be + a simple constant item or a NEG_FUNC/COLLATE_FUNC. + */ + DBUG_ASSERT(((Item_func *) value_item)->functype() == + Item_func::NEG_FUNC || + ((Item_func *) value_item)->functype() == + Item_func::COLLATE_FUNC); + return ((Item_func *) value_item)->key_item()->type(); + } + return value_type; } -- cgit v1.2.1 From 31f748313a5b7af30440d04881d09743d49107c7 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Thu, 5 Feb 2009 13:30:39 +0400 Subject: Bug #42037: Queries containing a subquery with DISTINCT and ORDER BY could cause a server crash Dependent subqueries like SELECT COUNT(*) FROM t1, t2 WHERE t2.b IN (SELECT DISTINCT t2.b FROM t2 WHERE t2.b = t1.a) caused a memory leak proportional to the number of outer rows. The make_simple_join() function has been modified to JOIN class method to store join_tab_reexec and table_reexec values in the parent join only (make_simple_join of tmp_join may access these values via 'this' pointer of the parent JOIN). NOTE: this patch doesn't include standard test case (this is "out of memory" bug). See bug #42037 page for test cases. sql/sql_select.cc: Bug #42037: Queries containing a subquery with DISTINCT and ORDER BY could cause a server crash The make_simple_join() function has been modified to JOIN class method to store join_tab_reexec and table_reexec values in the parent join only. sql/sql_select.h: Bug #42037: Queries containing a subquery with DISTINCT and ORDER BY could cause a server crash 1. The make_simple_join() function has been modified to JOIN class method. 2. Type of JOIN::table_reexec field has been changed from TABLE** to TABLE *table_reexec[1]: this field always was NULL or a pointer to one-element array of pointers, so a pointer to a pointer has been replaced with one pointer and unnecessary memory allocation has been eliminated. --- sql/sql_select.cc | 73 +++++++++++++++++++++++++------------------------------ sql/sql_select.h | 9 +++++-- 2 files changed, 40 insertions(+), 42 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 74d1158d8b7..a341cf5e0e9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -78,7 +78,6 @@ static store_key *get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables, KEY_PART_INFO *key_part, char *key_buff, uint maybe_null); -static bool make_simple_join(JOIN *join,TABLE *tmp_table); static void make_outerjoin_info(JOIN *join); static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item); static void make_join_readinfo(JOIN *join, ulonglong options); @@ -1809,7 +1808,7 @@ JOIN::exec() /* Free first data from old join */ curr_join->join_free(); - if (make_simple_join(curr_join, curr_tmp_table)) + if (curr_join->make_simple_join(this, curr_tmp_table)) DBUG_VOID_RETURN; calc_group_buffer(curr_join, group_list); count_field_types(select_lex, &curr_join->tmp_table_param, @@ -1929,7 +1928,7 @@ JOIN::exec() curr_join->select_distinct=0; } curr_tmp_table->reginfo.lock_type= TL_UNLOCK; - if (make_simple_join(curr_join, curr_tmp_table)) + if (curr_join->make_simple_join(this, curr_tmp_table)) DBUG_VOID_RETURN; calc_group_buffer(curr_join, curr_join->group_list); count_field_types(select_lex, &curr_join->tmp_table_param, @@ -5431,48 +5430,42 @@ store_val_in_field(Field *field, Item *item, enum_check_fields check_flag) } -static bool -make_simple_join(JOIN *join,TABLE *tmp_table) +/** + @details Initialize a JOIN as a query execution plan + that accesses a single table via a table scan. + + @param parent contains JOIN_TAB and TABLE object buffers for this join + @param tmp_table temporary table + + @retval FALSE success + @retval TRUE error occurred +*/ +bool +JOIN::make_simple_join(JOIN *parent, TABLE *tmp_table) { - TABLE **tableptr; - JOIN_TAB *join_tab; - DBUG_ENTER("make_simple_join"); + DBUG_ENTER("JOIN::make_simple_join"); /* Reuse TABLE * and JOIN_TAB if already allocated by a previous call to this function through JOIN::exec (may happen for sub-queries). */ - if (!join->table_reexec) - { - if (!(join->table_reexec= (TABLE**) join->thd->alloc(sizeof(TABLE*)))) - DBUG_RETURN(TRUE); /* purecov: inspected */ - if (join->tmp_join) - join->tmp_join->table_reexec= join->table_reexec; - } - if (!join->join_tab_reexec) - { - if (!(join->join_tab_reexec= - (JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB)))) - DBUG_RETURN(TRUE); /* purecov: inspected */ - if (join->tmp_join) - join->tmp_join->join_tab_reexec= join->join_tab_reexec; - } - tableptr= join->table_reexec; - join_tab= join->join_tab_reexec; - - join->join_tab=join_tab; - join->table=tableptr; tableptr[0]=tmp_table; - join->tables=1; - join->const_tables=0; - join->const_table_map=0; - join->tmp_table_param.field_count= join->tmp_table_param.sum_func_count= - join->tmp_table_param.func_count=0; - join->tmp_table_param.copy_field=join->tmp_table_param.copy_field_end=0; - join->first_record=join->sort_and_group=0; - join->send_records=(ha_rows) 0; - join->group=0; - join->row_limit=join->unit->select_limit_cnt; - join->do_send_rows = (join->row_limit) ? 1 : 0; + if (!parent->join_tab_reexec && + !(parent->join_tab_reexec= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)))) + DBUG_RETURN(TRUE); /* purecov: inspected */ + + join_tab= parent->join_tab_reexec; + table= &parent->table_reexec[0]; parent->table_reexec[0]= tmp_table; + tables= 1; + const_tables= 0; + const_table_map= 0; + tmp_table_param.field_count= tmp_table_param.sum_func_count= + tmp_table_param.func_count= 0; + tmp_table_param.copy_field= tmp_table_param.copy_field_end=0; + first_record= sort_and_group=0; + send_records= (ha_rows) 0; + group= 0; + row_limit= unit->select_limit_cnt; + do_send_rows= row_limit ? 1 : 0; join_tab->cache.buff=0; /* No caching */ join_tab->table=tmp_table; @@ -5489,7 +5482,7 @@ make_simple_join(JOIN *join,TABLE *tmp_table) join_tab->ref.key = -1; join_tab->not_used_in_distinct=0; join_tab->read_first_record= join_init_read_record; - join_tab->join=join; + join_tab->join= this; join_tab->ref.key_parts= 0; bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record)); tmp_table->status=0; diff --git a/sql/sql_select.h b/sql/sql_select.h index 8ece01d3286..75a905043d2 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -352,9 +352,12 @@ public: cleared only at the end of the execution of the whole query and not caching allocations that occur in repetition at execution time will result in excessive memory usage. + Note: make_simple_join always creates an execution plan that accesses + a single table, thus it is sufficient to have a one-element array for + table_reexec. */ SORT_FIELD *sortorder; // make_unireg_sortorder() - TABLE **table_reexec; // make_simple_join() + TABLE *table_reexec[1]; // make_simple_join() JOIN_TAB *join_tab_reexec; // make_simple_join() /* end of allocation caching storage */ @@ -384,7 +387,7 @@ public: exec_tmp_table1= 0; exec_tmp_table2= 0; sortorder= 0; - table_reexec= 0; + table_reexec[0]= 0; join_tab_reexec= 0; thd= thd_arg; sum_funcs= sum_funcs2= 0; @@ -476,6 +479,8 @@ public: return (unit == &thd->lex->unit && (unit->fake_select_lex == 0 || select_lex == unit->fake_select_lex)); } +private: + bool make_simple_join(JOIN *join, TABLE *tmp_table); }; -- cgit v1.2.1 From ddb4aa5d3ec992851aa8cb09a75e82ded60308e1 Mon Sep 17 00:00:00 2001 From: Matthias Leich Date: Thu, 5 Feb 2009 21:47:23 +0100 Subject: 2. Slice of fix for Bug#42003 tests missing the disconnect of connections <> default - If missing: add "disconnect " - If physical disconnect of non "default" sessions is not finished at test end: add routine which waits till this happened + additional improvements - remove superfluous files created by the test - replace error numbers by error names - remove trailing spaces, replace tabs by spaces - unify writing of bugs within comments - correct comments - minor changes of formatting Fixed tests: backup check compress grant information_schema multi_update overflow packet query_cache_not_embedded sp-threads subselect synchronization timezone_grant --- mysql-test/r/backup.result | 2 +- mysql-test/r/check.result | 3 +- mysql-test/r/grant.result | 32 +- mysql-test/r/information_schema.result | 22 +- mysql-test/r/multi_update.result | 10 +- mysql-test/r/packet.result | 4 + mysql-test/r/query_cache_notembedded.result | 16 + mysql-test/r/subselect.result | 218 +++++------ mysql-test/r/synchronization.result | 44 +-- mysql-test/t/backup.test | 15 +- mysql-test/t/check.test | 24 +- mysql-test/t/compress.test | 11 + mysql-test/t/grant.test | 179 +++++---- mysql-test/t/information_schema.test | 144 ++++---- mysql-test/t/multi_update.test | 55 +-- mysql-test/t/overflow.test | 10 +- mysql-test/t/packet.test | 20 +- mysql-test/t/query_cache_notembedded.test | 47 ++- mysql-test/t/sp-threads.test | 29 +- mysql-test/t/subselect.test | 549 ++++++++++++++++------------ mysql-test/t/synchronization.test | 22 +- mysql-test/t/timezone_grant.test | 41 ++- 22 files changed, 864 insertions(+), 633 deletions(-) diff --git a/mysql-test/r/backup.result b/mysql-test/r/backup.result index 14313ba490f..f5a649d27a5 100644 --- a/mysql-test/r/backup.result +++ b/mysql-test/r/backup.result @@ -1,5 +1,5 @@ set SQL_LOG_BIN=0; -drop table if exists t1, t2, t3; +drop table if exists t1, t2, t3, t4; create table t4(n int); backup table t4 to '../bogus'; Table Op Msg_type Msg_text diff --git a/mysql-test/r/check.result b/mysql-test/r/check.result index 03219d0977e..0bff34dba20 100644 --- a/mysql-test/r/check.result +++ b/mysql-test/r/check.result @@ -1,4 +1,5 @@ -drop table if exists t1; +drop table if exists t1,t2; +drop view if exists v1; create table t1(n int not null, key(n), key(n), key(n), key(n)); check table t1 extended; insert into t1 values (200000); diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index ee328d461ac..97945a702d8 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -162,7 +162,7 @@ Warnings: Warning 1364 Field 'ssl_cipher' doesn't have a default value Warning 1364 Field 'x509_issuer' doesn't have a default value Warning 1364 Field 'x509_subject' doesn't have a default value -insert into mysql.db (host, db, user, select_priv) values +insert into mysql.db (host, db, user, select_priv) values ('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y'); alter table mysql.db order by db asc; flush privileges; @@ -262,7 +262,7 @@ drop user mysqltest_1@localhost; SET NAMES koi8r; CREATE DATABASE ÂÄ; USE ÂÄ; -CREATE TABLE ÔÁ (ËÏÌ int); +CREATE TABLE ÔÁ (ËÏÌ INT); GRANT SELECT ON ÂÄ.* TO ÀÚÅÒ@localhost; SHOW GRANTS FOR ÀÚÅÒ@localhost; Grants for ÀÚÅÒ@localhost @@ -381,21 +381,21 @@ grant update (a) on mysqltest_1.t1 to mysqltest_3@localhost; grant select (b) on mysqltest_1.t2 to mysqltest_3@localhost; grant select (c) on mysqltest_2.t1 to mysqltest_3@localhost; grant update (d) on mysqltest_2.t2 to mysqltest_3@localhost; -SELECT * FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES -WHERE GRANTEE = '''mysqltest_3''@''localhost''' -ORDER BY TABLE_NAME,COLUMN_NAME,PRIVILEGE_TYPE; +SELECT * FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES +WHERE GRANTEE = '''mysqltest_3''@''localhost''' + ORDER BY TABLE_NAME,COLUMN_NAME,PRIVILEGE_TYPE; GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE 'mysqltest_3'@'localhost' NULL mysqltest_1 t1 a UPDATE NO 'mysqltest_3'@'localhost' NULL mysqltest_2 t1 c SELECT NO 'mysqltest_3'@'localhost' NULL mysqltest_1 t2 b SELECT NO 'mysqltest_3'@'localhost' NULL mysqltest_2 t2 d UPDATE NO SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES -WHERE GRANTEE = '''mysqltest_3''@''localhost''' -ORDER BY TABLE_NAME,PRIVILEGE_TYPE; +WHERE GRANTEE = '''mysqltest_3''@''localhost''' + ORDER BY TABLE_NAME,PRIVILEGE_TYPE; GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE SELECT * from INFORMATION_SCHEMA.SCHEMA_PRIVILEGES -WHERE GRANTEE = '''mysqltest_3''@''localhost''' -ORDER BY TABLE_SCHEMA,PRIVILEGE_TYPE; +WHERE GRANTEE = '''mysqltest_3''@''localhost''' + ORDER BY TABLE_SCHEMA,PRIVILEGE_TYPE; GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE SELECT * from INFORMATION_SCHEMA.USER_PRIVILEGES WHERE GRANTEE = '''mysqltest_3''@''localhost''' @@ -880,11 +880,11 @@ flush privileges; drop table t2; drop table t1; CREATE DATABASE mysqltest3; -use mysqltest3; +USE mysqltest3; CREATE TABLE t_nn (c1 INT); CREATE VIEW v_nn AS SELECT * FROM t_nn; CREATE DATABASE mysqltest2; -use mysqltest2; +USE mysqltest2; CREATE TABLE t_nn (c1 INT); CREATE VIEW v_nn AS SELECT * FROM t_nn; CREATE VIEW v_yn AS SELECT * FROM t_nn; @@ -954,7 +954,7 @@ DROP TABLE mysqltest3.t_nn; DROP DATABASE mysqltest3; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'mysqltest_1'@'localhost'; DROP USER 'mysqltest_1'@'localhost'; -use test; +USE test; create user mysqltest1_thisisreallytoolong; ERROR HY000: String 'mysqltest1_thisisreallytoolong' is too long for user name (should be no longer than 16) GRANT CREATE ON mysqltest.* TO 1234567890abcdefGHIKL@localhost; @@ -1106,16 +1106,16 @@ DROP DATABASE mysqltest1; DROP DATABASE mysqltest2; DROP USER mysqltest_1@localhost; DROP USER mysqltest_2@localhost; -use test; +USE test; CREATE TABLE t1 (f1 int, f2 int); INSERT INTO t1 VALUES(1,1), (2,2); CREATE DATABASE db27878; GRANT UPDATE(f1) ON t1 TO 'mysqltest_1'@'localhost'; GRANT SELECT ON `test`.* TO 'mysqltest_1'@'localhost'; GRANT ALL ON db27878.* TO 'mysqltest_1'@'localhost'; -use db27878; +USE db27878; CREATE SQL SECURITY INVOKER VIEW db27878.v1 AS SELECT * FROM test.t1; -use db27878; +USE db27878; UPDATE v1 SET f2 = 4; ERROR HY000: View 'db27878.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them SELECT * FROM test.t1; @@ -1127,7 +1127,7 @@ REVOKE SELECT ON `test`.* FROM 'mysqltest_1'@'localhost'; REVOKE ALL ON db27878.* FROM 'mysqltest_1'@'localhost'; DROP USER mysqltest_1@localhost; DROP DATABASE db27878; -use test; +USE test; DROP TABLE t1; drop table if exists test; Warnings: diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index d7ff87bd1eb..38c8d748870 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -75,7 +75,7 @@ t2 t3 t5 v1 -select c,table_name from v1 +select c,table_name from v1 inner join information_schema.TABLES v2 on (v1.c=v2.table_name) where v1.c like "t%"; c table_name @@ -94,7 +94,7 @@ t4 t4 t2 t2 t3 t3 t5 t5 -select c,table_name from v1 +select c,table_name from v1 left join information_schema.TABLES v2 on (v1.c=v2.table_name) where v1.c like "t%"; c table_name @@ -173,7 +173,7 @@ a int(11) YES NULL create view mysqltest.v1 (c) as select a from mysqltest.t1; grant select (a) on mysqltest.t1 to mysqltest_2@localhost; grant select on mysqltest.v1 to mysqltest_3; -select table_name, column_name, privileges from information_schema.columns +select table_name, column_name, privileges from information_schema.columns where table_schema = 'mysqltest' and table_name = 't1'; table_name column_name privileges t1 a select @@ -249,7 +249,7 @@ begin select * from t1; select * from t2; end| -select parameter_style, sql_data_access, dtd_identifier +select parameter_style, sql_data_access, dtd_identifier from information_schema.routines; parameter_style sql_data_access dtd_identifier SQL CONTAINS SQL NULL @@ -280,7 +280,7 @@ sub1 sub1 select count(*) from information_schema.ROUTINES; count(*) 2 -create view v1 as select routine_schema, routine_name from information_schema.routines +create view v1 as select routine_schema, routine_name from information_schema.routines order by routine_schema, routine_name; select * from v1; routine_schema routine_name @@ -532,7 +532,7 @@ drop view v1; create table t1(a NUMERIC(5,3), b NUMERIC(5,1), c float(5,2), d NUMERIC(6,4), e float, f DECIMAL(6,3), g int(11), h DOUBLE(10,3), i DOUBLE); -select COLUMN_NAME,COLUMN_TYPE, CHARACTER_MAXIMUM_LENGTH, +select COLUMN_NAME,COLUMN_TYPE, CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE from information_schema.columns where table_name= 't1'; COLUMN_NAME COLUMN_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE @@ -589,7 +589,7 @@ TABLE_NAME= "vo"; CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION POSITION_IN_UNIQUE_CONSTRAINT REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME drop view vo; select TABLE_NAME,TABLE_TYPE,ENGINE -from information_schema.tables +from information_schema.tables where table_schema='information_schema' limit 2; TABLE_NAME TABLE_TYPE ENGINE CHARACTER_SETS SYSTEM VIEW MEMORY @@ -700,7 +700,7 @@ where table_schema="information_schema" and table_name="COLUMNS" and column_type varchar(64) varchar(64) -select TABLE_ROWS from information_schema.tables where +select TABLE_ROWS from information_schema.tables where table_schema="information_schema" and table_name="COLUMNS"; TABLE_ROWS NULL @@ -733,7 +733,7 @@ count(*) drop view a2, a1; drop table t_crashme; select table_schema,table_name, column_name from -information_schema.columns +information_schema.columns where data_type = 'longtext'; table_schema table_name column_name information_schema COLUMNS COLUMN_DEFAULT @@ -755,7 +755,7 @@ TABLES UPDATE_TIME datetime TABLES CHECK_TIME datetime TRIGGERS CREATED datetime SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES A -WHERE NOT EXISTS +WHERE NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS B WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA AND A.TABLE_NAME = B.TABLE_NAME); @@ -784,7 +784,7 @@ x_float NULL NULL x_double_precision NULL NULL drop table t1; grant select on test.* to mysqltest_4@localhost; -SELECT TABLE_NAME, COLUMN_NAME, PRIVILEGES FROM INFORMATION_SCHEMA.COLUMNS +SELECT TABLE_NAME, COLUMN_NAME, PRIVILEGES FROM INFORMATION_SCHEMA.COLUMNS where COLUMN_NAME='TABLE_NAME'; TABLE_NAME COLUMN_NAME PRIVILEGES COLUMNS TABLE_NAME select diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index b85fb559e8c..f6dbac31c2a 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -375,7 +375,7 @@ update t2, t1 set t2.field=t1.field where t1.id1=t2.id2 and 0=1; delete t1, t2 from t2 inner join t1 on t1.id1=t2.id2 where 0=1; -delete t1, t2 from t2,t1 +delete t1, t2 from t2,t1 where t1.id1=t2.id2 and 0=1; drop table t1,t2; CREATE TABLE t1 ( a int ); @@ -443,12 +443,12 @@ delete t1 from t1,t2 where t1.col1 < (select max(col1) from t1) and t1.col1 = t2 ERROR HY000: You can't specify target table 't1' for update in FROM clause drop table t1,t2; create table t1 ( -aclid bigint not null primary key, -status tinyint(1) not null +aclid bigint not null primary key, +status tinyint(1) not null ) engine = innodb; create table t2 ( -refid bigint not null primary key, -aclid bigint, index idx_acl(aclid) +refid bigint not null primary key, +aclid bigint, index idx_acl(aclid) ) engine = innodb; insert into t2 values(1,null); delete t2, t1 from t2 left join t1 on (t2.aclid=t1.aclid) where t2.refid='1'; diff --git a/mysql-test/r/packet.result b/mysql-test/r/packet.result index df0d9ff9adc..5cc63c4690d 100644 --- a/mysql-test/r/packet.result +++ b/mysql-test/r/packet.result @@ -1,3 +1,5 @@ +set @max_allowed_packet=@@global.max_allowed_packet; +set @net_buffer_length=@@global.net_buffer_length; set global max_allowed_packet=100; Warnings: Warning 1292 Truncated incorrect max_allowed_packet value: '100' @@ -33,3 +35,5 @@ len select length(repeat('a',2000)); length(repeat('a',2000)) 2000 +set global max_allowed_packet=@max_allowed_packet; +set global net_buffer_length=@net_buffer_length; diff --git a/mysql-test/r/query_cache_notembedded.result b/mysql-test/r/query_cache_notembedded.result index 8e5df012cfb..bf582bfaec6 100644 --- a/mysql-test/r/query_cache_notembedded.result +++ b/mysql-test/r/query_cache_notembedded.result @@ -345,3 +345,19 @@ id drop table t1; drop function f1; set GLOBAL query_cache_size=0; +DROP TABLE IF EXISTS t1; +FLUSH STATUS; +SET GLOBAL query_cache_size=1048576; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +SHOW STATUS LIKE 'Qcache_queries_in_cache'; +Variable_name Value +Qcache_queries_in_cache 0 +LOCK TABLES t1 WRITE; +SELECT * FROM t1; +UNLOCK TABLES; +SHOW STATUS LIKE 'Qcache_queries_in_cache'; +Variable_name Value +Qcache_queries_in_cache 0 +DROP TABLE t1; +SET GLOBAL query_cache_size= default; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 8830ea11f97..671e5d8f532 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -192,11 +192,11 @@ select (select a from t3 where a1) as tt; (select t3.a from t3 where a<8 order by 1 desc limit 1) a 7 2 -explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from +explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from (select * from t2 where a>1) as tt; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 @@ -2303,20 +2303,20 @@ drop table t1,t2; CREATE TABLE t1 ( a int, b int ); CREATE TABLE t2 ( c int, d int ); INSERT INTO t1 VALUES (1,2), (2,3), (3,4); -SELECT a AS abc, b FROM t1 outr WHERE b = +SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a); abc b 1 2 2 3 3 4 -INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = +INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a); select * from t2; c d 1 2 2 3 3 4 -CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = +CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a); select * from t3; abc b @@ -2517,8 +2517,8 @@ INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,680 INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF'); INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM'); /*!40000 ALTER TABLE t1 ENABLE KEYS */; -SELECT DISTINCT Continent AS c FROM t1 outr WHERE -Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND +SELECT DISTINCT Continent AS c FROM t1 outr WHERE +Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND Population < 200); c Oceania @@ -2628,32 +2628,32 @@ select count(distinct t2.userid) pass, groupstuff.*, count(t2.courseid) crse, -t1.categoryid, +t1.categoryid, t2.courseid, date_format(date, '%b%y') as colhead -from t2 -join t1 on t2.courseid=t1.courseid +from t2 +join t1 on t2.courseid=t1.courseid join ( -select -t5.userid, -parentid, -parentgroup, -childid, -groupname, -grouptypeid -from t5 -join +select +t5.userid, +parentid, +parentgroup, +childid, +groupname, +grouptypeid +from t5 +join ( -select t4.id as parentid, -t4.name as parentgroup, -t4.id as childid, -t4.name as groupname, -t4.grouptypeid -from t4 -) as gin on t5.groupid=gin.childid -) as groupstuff on t2.userid = groupstuff.userid -group by +select t4.id as parentid, +t4.name as parentgroup, +t4.id as childid, +t4.name as groupname, +t4.grouptypeid +from t4 +) as gin on t5.groupid=gin.childid +) as groupstuff on t2.userid = groupstuff.userid +group by groupstuff.groupname, colhead , t2.courseid; pass userid parentid parentgroup childid groupname grouptypeid crse categoryid courseid colhead 1 5141 12 group2 12 group2 5 1 5 12 Aug04 @@ -2929,9 +2929,9 @@ INSERT INTO t1 VALUES("0037", "1", "2005-12-06 12:18:56"); INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53"); INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50"); INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50"); -select * from t1 r1 -where (r1.retailerID,(r1.changed)) in -(SELECT r2.retailerId,(max(changed)) from t1 r2 +select * from t1 r1 +where (r1.retailerID,(r1.changed)) in +(SELECT r2.retailerId,(max(changed)) from t1 r2 group by r2.retailerId); retailerID statusID changed 0026 2 2006-01-06 12:25:53 @@ -2943,41 +2943,41 @@ create table t1(a int, primary key (a)); insert into t1 values (10); create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); -explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r -ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' -ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; +explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r +ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' + ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using where -SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r -ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' -ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; +SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r +ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' + ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; a a b 10 3 35989 -explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r -ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' -ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; +explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r +ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' + ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using where -SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r -ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' -ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; +SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r +ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' + ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; a a b 10 1 359 drop table t1,t2; -CREATE TABLE t1 ( -field1 int NOT NULL, -field2 int NOT NULL, -field3 int NOT NULL, -PRIMARY KEY (field1,field2,field3) +CREATE TABLE t1 ( +field1 int NOT NULL, +field2 int NOT NULL, +field3 int NOT NULL, +PRIMARY KEY (field1,field2,field3) ); -CREATE TABLE t2 ( -fieldA int NOT NULL, -fieldB int NOT NULL, -PRIMARY KEY (fieldA,fieldB) +CREATE TABLE t2 ( +fieldA int NOT NULL, +fieldB int NOT NULL, +PRIMARY KEY (fieldA,fieldB) ); INSERT INTO t1 VALUES (1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1); @@ -2991,14 +2991,14 @@ field1 field2 COUNT(*) SELECT field1, field2 FROM t1 GROUP BY field1, field2 -HAVING COUNT(*) >= ALL (SELECT fieldB +HAVING COUNT(*) >= ALL (SELECT fieldB FROM t2 WHERE fieldA = field1); field1 field2 1 2 SELECT field1, field2 FROM t1 GROUP BY field1, field2 -HAVING COUNT(*) < ANY (SELECT fieldB +HAVING COUNT(*) < ANY (SELECT fieldB FROM t2 WHERE fieldA = field1); field1 field2 1 1 @@ -3021,8 +3021,8 @@ a a IN (SELECT a FROM t1) DROP TABLE t1,t2; CREATE TABLE t1 (a DATETIME); INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25'); -CREATE TABLE t2 AS SELECT -(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a +CREATE TABLE t2 AS SELECT +(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a FROM t1 WHERE a > '2000-01-01'; SHOW CREATE TABLE t2; Table Create Table @@ -3188,7 +3188,7 @@ INSERT INTO t2 VALUES ( 6 ); CREATE TABLE t3 ( c3 integer ); INSERT INTO t3 VALUES ( 7 ); INSERT INTO t3 VALUES ( 8 ); -SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2 +SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2 WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL ); c1 c2 2 NULL @@ -3231,20 +3231,20 @@ E1 DROP TABLE t1,t2; CREATE TABLE t1(select_id BIGINT, values_id BIGINT); INSERT INTO t1 VALUES (1, 1); -CREATE TABLE t2 (select_id BIGINT, values_id BIGINT, +CREATE TABLE t2 (select_id BIGINT, values_id BIGINT, PRIMARY KEY(select_id,values_id)); INSERT INTO t2 VALUES (0, 1), (0, 2), (0, 3), (1, 5); -SELECT values_id FROM t1 +SELECT values_id FROM t1 WHERE values_id IN (SELECT values_id FROM t2 WHERE select_id IN (1, 0)); values_id 1 -SELECT values_id FROM t1 +SELECT values_id FROM t1 WHERE values_id IN (SELECT values_id FROM t2 WHERE select_id BETWEEN 0 AND 1); values_id 1 -SELECT values_id FROM t1 +SELECT values_id FROM t1 WHERE values_id IN (SELECT values_id FROM t2 WHERE select_id = 0 OR select_id = 1); values_id @@ -3259,7 +3259,7 @@ drop table t1; CREATE TABLE t1 (a int, b int); CREATE TABLE t2 (c int, d int); CREATE TABLE t3 (e int); -INSERT INTO t1 VALUES +INSERT INTO t1 VALUES (1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40); INSERT INTO t2 VALUES (2,10), (2,20), (4,10), (5,10), (3,20), (2,40); @@ -3322,7 +3322,7 @@ a 2 SELECT a FROM t1 GROUP BY a HAVING a IN (SELECT c FROM t2 -WHERE MIN(b) < d AND +WHERE MIN(b) < d AND EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d)); a 2 @@ -3373,7 +3373,7 @@ a 4 SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a > ALL(SELECT t2.c FROM t2 -WHERE EXISTS(SELECT t3.e FROM t3 +WHERE EXISTS(SELECT t3.e FROM t3 WHERE SUM(t1.a+t2.c) < t3.e/4)); ERROR HY000: Invalid use of group function SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20; @@ -3486,7 +3486,7 @@ mid bigint(20) unsigned NOT NULL, date date NOT NULL, PRIMARY KEY (id) ); -INSERT INTO t2 VALUES +INSERT INTO t2 VALUES (1, 1, '2006-03-30'), (2, 2, '2006-04-06'), (3, 3, '2006-04-13'), (4, 2, '2006-04-20'), (5, 1, '2006-05-01'); SELECT *, @@ -3524,7 +3524,7 @@ i2 int(11) NOT NULL default '0', t datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (i1,i2,t) ); -INSERT INTO t1 VALUES +INSERT INTO t1 VALUES (24,1,'2005-03-03 16:31:31'),(24,1,'2005-05-27 12:40:07'), (24,1,'2005-05-27 12:40:08'),(24,1,'2005-05-27 12:40:10'), (24,1,'2005-05-27 12:40:25'),(24,1,'2005-05-27 12:40:30'), @@ -3540,7 +3540,7 @@ PRIMARY KEY (i1) INSERT INTO t2 VALUES (24,1,'2006-06-20 12:29:40'); EXPLAIN SELECT * FROM t1,t2 -WHERE t1.t = (SELECT t1.t FROM t1 +WHERE t1.t = (SELECT t1.t FROM t1 WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1 ORDER BY t1.t DESC LIMIT 1); id select_type table type possible_keys key key_len ref rows Extra @@ -3548,7 +3548,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index 2 DEPENDENT SUBQUERY t1 range PRIMARY PRIMARY 16 NULL 5 Using where; Using index SELECT * FROM t1,t2 -WHERE t1.t = (SELECT t1.t FROM t1 +WHERE t1.t = (SELECT t1.t FROM t1 WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1 ORDER BY t1.t DESC LIMIT 1); i1 i2 t i1 i2 t @@ -3557,22 +3557,22 @@ DROP TABLE t1, t2; CREATE TABLE t1 (i INT); (SELECT i FROM t1) UNION (SELECT i FROM t1); i -SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS +SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS ( -(SELECT i FROM t1) UNION +(SELECT i FROM t1) UNION (SELECT i FROM t1) ); -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 'UNION +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 'UNION (SELECT i FROM t1) )' at line 3 -SELECT * FROM t1 +SELECT * FROM t1 WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); 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 'UNION (SELECT i FROM t1)))' at line 2 explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12)) from t1; 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 'union (select t12.i from t1 t12)) from t1' at line 1 -explain select * from t1 where not exists +explain select * from t1 where not exists ((select t11.i from t1 t11) union (select t12.i from t1 t12)); 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 'union (select t12.i from t1 t12))' at line 2 DROP TABLE t1; @@ -3591,9 +3591,9 @@ insert into t1 (a) select FLOOR(rand() * 100) from t1; insert into t1 (a) select FLOOR(rand() * 100) from t1; insert into t1 (a) select FLOOR(rand() * 100) from t1; insert into t1 (a) select FLOOR(rand() * 100) from t1; -SELECT a, -(SELECT REPEAT(' ',250) FROM t1 i1 -WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a +SELECT a, +(SELECT REPEAT(' ',250) FROM t1 i1 +WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a FROM t1 ORDER BY a LIMIT 5; a a 0 NULL @@ -3622,7 +3622,7 @@ COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b)) 2 2 1 1 1 1 -SELECT COUNT(DISTINCT t1.b), +SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3) FROM t1 GROUP BY t1.a; COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3) @@ -3633,7 +3633,7 @@ SELECT ( SELECT ( SELECT COUNT(DISTINCT t1.b) ) -) +) FROM t1 GROUP BY t1.a; ( SELECT ( @@ -3648,8 +3648,8 @@ SELECT ( SELECT ( SELECT COUNT(DISTINCT t1.b) ) -) -FROM t1 GROUP BY t1.a LIMIT 1) +) +FROM t1 GROUP BY t1.a LIMIT 1) FROM t1 t2 GROUP BY t2.a; ( @@ -3657,7 +3657,7 @@ SELECT ( SELECT ( SELECT COUNT(DISTINCT t1.b) ) -) +) FROM t1 GROUP BY t1.a LIMIT 1) 2 2 @@ -3669,13 +3669,13 @@ PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b)); SET SESSION sort_buffer_size = 32 * 1024; Warnings: Warning 1292 Truncated incorrect sort_buffer_size value: '32768' -SELECT SQL_NO_CACHE COUNT(*) +SELECT SQL_NO_CACHE COUNT(*) FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c FROM t1) t; COUNT(*) 3000 SET SESSION sort_buffer_size = 8 * 1024 * 1024; -SELECT SQL_NO_CACHE COUNT(*) +SELECT SQL_NO_CACHE COUNT(*) FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c FROM t1) t; COUNT(*) @@ -3736,7 +3736,7 @@ sq 2 4 DEALLOCATE PREPARE stmt1; -SELECT f2, AVG(f21), +SELECT f2, AVG(f21), (SELECT t.f3 FROM t2 AS t WHERE t2.f2=t.f2 AND t.f3=MAX(t2.f3)) AS test FROM t2 GROUP BY f2; f2 AVG(f21) test @@ -3744,12 +3744,12 @@ f2 AVG(f21) test 2 2.0000 2004-02-29 11:11:11 DROP TABLE t1,t2; CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL); -INSERT INTO t1 VALUES -(1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'), -(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'), +INSERT INTO t1 VALUES +(1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'), +(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'), (3,2,'k'), (3,1,'l'), (1,9,'m'); -SELECT a, MAX(b), -(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test +SELECT a, MAX(b), +(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test FROM t1 GROUP BY a; a MAX(b) test 1 9 m @@ -3900,7 +3900,7 @@ COUNT(*) a (SELECT MIN(m) FROM t2 WHERE m = count(*)) 2 2 2 3 3 3 1 4 1 -SELECT COUNT(*), a +SELECT COUNT(*), a FROM t1 GROUP BY a HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1; COUNT(*) a @@ -3931,7 +3931,7 @@ INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'), (1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'), (3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p'); SELECT a, MAX(b), -(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test +(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test FROM t1 GROUP BY a; a MAX(b) test 1 9 m @@ -3953,7 +3953,7 @@ a AVG(b) test 3 2.5000 NULL SELECT tt.a, (SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) -LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test +LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test FROM t1 as tt; a test 1 n @@ -3975,7 +3975,7 @@ a test SELECT tt.a, (SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) LIMIT 1) -FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test +FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test FROM t1 as tt GROUP BY tt.a; a test 1 n @@ -3984,7 +3984,7 @@ a test SELECT tt.a, MAX( (SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) LIMIT 1) -FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test +FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test FROM t1 as tt GROUP BY tt.a; a test 1 n @@ -4027,11 +4027,11 @@ COUNT(1) 1 SELECT SUM( (SELECT AVG( (SELECT t1.a FROM t2) ) FROM DUAL) ) FROM t1; ERROR HY000: Invalid use of group function -SELECT +SELECT SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING t1.a < 12) ) FROM t2) ) FROM t1; ERROR HY000: Invalid use of group function -SELECT t1.a as XXA, +SELECT t1.a as XXA, SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) ) FROM t1; ERROR HY000: Invalid use of group function @@ -4048,25 +4048,25 @@ INSERT INTO t1 VALUES (3,'FL'), (2,'GA'), (4,'FL'), (1,'GA'), (5,'NY'), (7,'FL'), (6,'NY'); CREATE TABLE t2 (id int NOT NULL, INDEX idx(id)); INSERT INTO t2 VALUES (7), (5), (1), (3); -SELECT id, st FROM t1 +SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id); id st 3 FL 1 GA 7 FL -SELECT id, st FROM t1 +SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id) GROUP BY id; id st 1 GA 3 FL 7 FL -SELECT id, st FROM t1 +SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id); id st 2 GA 4 FL -SELECT id, st FROM t1 +SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id) GROUP BY id; id st @@ -4272,7 +4272,7 @@ a b DROP TABLE t1,t2; CREATE TABLE t1(a INT, b INT); INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4); -EXPLAIN +EXPLAIN SELECT a AS out_a, MIN(b) FROM t1 WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a) GROUP BY a; @@ -4281,7 +4281,7 @@ SELECT a AS out_a, MIN(b) FROM t1 WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a) GROUP BY a; ERROR 42S22: Unknown column 'out_a' in 'where clause' -EXPLAIN +EXPLAIN SELECT a AS out_a, MIN(b) FROM t1 t1_outer WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a) GROUP BY a; @@ -4312,16 +4312,16 @@ Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 Note 1003 select 2 AS `2` from `test`.`t1` where exists(select 1 AS `1` from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) EXPLAIN EXTENDED -SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION +SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION (SELECT 1 FROM t2 WHERE t1.a = t2.a)); -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 'UNION +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 'UNION (SELECT 1 FROM t2 WHERE t1.a = t2.a))' at line 2 DROP TABLE t1,t2; create table t1(f11 int, f12 int); create table t2(f21 int unsigned not null, f22 int, f23 varchar(10)); insert into t1 values(1,1),(2,2), (3, 3); set session sort_buffer_size= 33*1024; -select count(*) from t1 where f12 = +select count(*) from t1 where f12 = (select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1); count(*) 3 @@ -4362,12 +4362,12 @@ IF( FROM t2 VPC, t4 a2, t2 a3 WHERE VPC.f4 = a2.f10 AND a3.f2 = a4 -LIMIT 1) IS NULL, -0, +LIMIT 1) IS NULL, +0, t3.f5 ) ) AS a6 -FROM +FROM t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4 GROUP BY a4; a4 f3 a6 @@ -4376,7 +4376,7 @@ a4 f3 a6 DROP TABLE t1, t2, t3, t4; create table t1 (a float(5,4) zerofill); create table t2 (a float(5,4),b float(2,0)); -select t1.a from t1 where +select t1.a from t1 where t1.a= (select b from t2 limit 1) and not t1.a= (select a from t2 limit 1) ; a diff --git a/mysql-test/r/synchronization.result b/mysql-test/r/synchronization.result index 29557b6cfd4..44edfb1e535 100644 --- a/mysql-test/r/synchronization.result +++ b/mysql-test/r/synchronization.result @@ -1,6 +1,6 @@ -drop table if exists t1; -CREATE TABLE t1 (x1 int); -ALTER TABLE t1 CHANGE x1 x2 int; +DROP TABLE IF EXISTS t1,t2; +CREATE TABLE t1 (x1 INT); +ALTER TABLE t1 CHANGE x1 x2 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -8,7 +8,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -16,7 +16,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -24,7 +24,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -32,7 +32,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -40,7 +40,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -48,7 +48,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -56,7 +56,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -64,7 +64,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -72,7 +72,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -80,7 +80,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -88,7 +88,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -96,7 +96,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -104,7 +104,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -112,7 +112,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -120,7 +120,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -128,7 +128,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -136,7 +136,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -144,7 +144,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -152,7 +152,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; -ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 INT; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table diff --git a/mysql-test/t/backup.test b/mysql-test/t/backup.test index b05eef6a3ad..34982b391ac 100644 --- a/mysql-test/t/backup.test +++ b/mysql-test/t/backup.test @@ -1,7 +1,10 @@ # The server need to be started in $MYSQLTEST_VARDIR since it # uses ../std_data_ln/ --- source include/uses_vardir.inc +--source include/uses_vardir.inc + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc # # This test is a bit tricky as we can't use backup table to overwrite an old @@ -12,7 +15,7 @@ connect (con2,localhost,root,,); connection con1; set SQL_LOG_BIN=0; --disable_warnings -drop table if exists t1, t2, t3; +drop table if exists t1, t2, t3, t4; --enable_warnings create table t4(n int); --replace_result ": 1" ": X" ": 2" ": X" ": 22" ": X" ": 23" ": X" $MYSQLTEST_VARDIR MYSQLTEST_VARDIR @@ -57,6 +60,9 @@ unlock tables; connection con1; reap; drop table t5; +connection default; +disconnect con1; +disconnect con2; remove_file $MYSQLTEST_VARDIR/tmp/t1.MYD; remove_file $MYSQLTEST_VARDIR/tmp/t2.MYD; remove_file $MYSQLTEST_VARDIR/tmp/t3.MYD; @@ -68,4 +74,9 @@ remove_file $MYSQLTEST_VARDIR/tmp/t3.frm; remove_file $MYSQLTEST_VARDIR/tmp/t4.frm; remove_file $MYSQLTEST_VARDIR/tmp/t5.frm; + # End of 4.1 tests + +# Wait till all disconnects are completed +--source include/wait_until_count_sessions.inc + diff --git a/mysql-test/t/check.test b/mysql-test/t/check.test index 698f6538529..ff23b352b5a 100644 --- a/mysql-test/t/check.test +++ b/mysql-test/t/check.test @@ -1,8 +1,12 @@ +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + connect (con1,localhost,root,,); connect (con2,localhost,root,,); connection con1; --disable_warnings -drop table if exists t1; +drop table if exists t1,t2; +drop view if exists v1; --enable_warnings # Add a lot of keys to slow down check @@ -20,16 +24,18 @@ connection con2; insert into t1 values (200000); connection con1; reap; +connection default; +disconnect con1; +disconnect con2; drop table t1; + # End of 4.1 tests # -# Bug #9897 Views: 'Check Table' crashes MySQL, with a view and a table -# in the statement +# Bug#9897 Views: 'Check Table' crashes MySQL, with a view and a table +# in the statement # - -connection default; Create table t1(f1 int); Create table t2(f1 int); Create view v1 as Select * from t1; @@ -37,11 +43,15 @@ Check Table v1,t2; drop view v1; drop table t1, t2; + # -# BUG#26325 - TEMPORARY TABLE "corrupt" after first read, according to CHECK -# TABLE +# Bug#26325 TEMPORARY TABLE "corrupt" after first read, according to CHECK TABLE # CREATE TEMPORARY TABLE t1(a INT); CHECK TABLE t1; REPAIR TABLE t1; DROP TABLE t1; + + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/compress.test b/mysql-test/t/compress.test index 3f1892b5dec..8e12ab46f06 100644 --- a/mysql-test/t/compress.test +++ b/mysql-test/t/compress.test @@ -6,6 +6,10 @@ -- source include/have_compress.inc +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + + connect (comp_con,localhost,root,,,,,COMPRESS); # Check compression turned on @@ -16,3 +20,10 @@ SHOW STATUS LIKE 'Compression'; # Check compression turned on SHOW STATUS LIKE 'Compression'; + +connection default; +disconnect comp_con; + +# Wait till all disconnects are completed +--source include/wait_until_count_sessions.inc + diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index 14c5879d007..6f6e8753004 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -3,6 +3,9 @@ # Grant tests not performed with embedded server -- source include/not_embedded.inc +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + # Cleanup --disable_warnings drop table if exists t1; @@ -78,7 +81,7 @@ delete from mysql.db where user='mysqltest_1'; delete from mysql.tables_priv where user='mysqltest_1'; delete from mysql.columns_priv where user='mysqltest_1'; flush privileges; ---error 1141 +--error ER_NONEXISTING_GRANT show grants for mysqltest_1@localhost; # @@ -116,15 +119,15 @@ drop table t1; # # Test some error conditions # ---error 1221 +--error ER_WRONG_USAGE GRANT FILE on mysqltest.* to mysqltest_1@localhost; -select 1; # To test that the previous command didn't cause problems +select 1; # To test that the previous command didn't cause problems # -# Bug #4898: User privileges depending on ORDER BY Settings of table db +# Bug#4898 User privileges depending on ORDER BY Settings of table db # insert into mysql.user (host, user) values ('localhost', 'test11'); -insert into mysql.db (host, db, user, select_priv) values +insert into mysql.db (host, db, user, select_priv) values ('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y'); alter table mysql.db order by db asc; flush privileges; @@ -136,7 +139,7 @@ delete from mysql.user where user='test11'; delete from mysql.db where user='test11'; # -# Bug#6123: GRANT USAGE inserts useless Db row +# Bug#6123 GRANT USAGE inserts useless Db row # create database mysqltest1; grant usage on mysqltest1.* to test6123 identified by 'magic123'; @@ -145,7 +148,7 @@ delete from mysql.user where user='test6123'; drop database mysqltest1; # -# Test for 'drop user', 'revoke privileges, grant' +# Test for 'drop user', 'revoke privileges, grant' # create table t1 (a int); @@ -160,7 +163,7 @@ grant select(a) on test.t1 to drop_user@localhost; show grants for drop_user@localhost; # -# Bug3086 +# Bug#3086 SHOW GRANTS doesn't follow ANSI_QUOTES # set sql_mode=ansi_quotes; show grants for drop_user@localhost; @@ -178,7 +181,7 @@ show grants for drop_user@localhost; revoke all privileges, grant option from drop_user@localhost; show grants for drop_user@localhost; drop user drop_user@localhost; ---error 1269 +--error ER_REVOKE_GRANTS revoke all privileges, grant option from drop_user@localhost; grant select(a) on test.t1 to drop_user1@localhost; @@ -188,10 +191,10 @@ grant select on *.* to drop_user4@localhost; # Drop user now implicitly revokes all privileges. drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; ---error 1269 +--error ER_REVOKE_GRANTS revoke all privileges, grant option from drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; ---error 1396 +--error ER_CANNOT_USER drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; drop table t1; @@ -201,12 +204,12 @@ show grants for mysqltest_1@localhost; drop user mysqltest_1@localhost; # -# Bug #3403 Wrong encodin in SHOW GRANTS output +# Bug#3403 Wrong encoding in SHOW GRANTS, EPLAIN SELECT output # SET NAMES koi8r; CREATE DATABASE ÂÄ; USE ÂÄ; -CREATE TABLE ÔÁ (ËÏÌ int); +CREATE TABLE ÔÁ (ËÏÌ INT); GRANT SELECT ON ÂÄ.* TO ÀÚÅÒ@localhost; SHOW GRANTS FOR ÀÚÅÒ@localhost; @@ -227,7 +230,7 @@ DROP DATABASE SET NAMES latin1; # -# Bug #5831: REVOKE ALL PRIVILEGES, GRANT OPTION does not revoke everything +# Bug#5831 REVOKE ALL PRIVILEGES, GRANT OPTION does not revoke everything # USE test; CREATE TABLE t1 (a int ); @@ -296,7 +299,7 @@ DROP DATABASE testdb9; DROP DATABASE testdb10; # -# Bug #6932: a problem with 'revoke ALL PRIVILEGES' +# Bug#6932 a problem with 'revoke ALL PRIVILEGES' # create table t1(a int, b int, c int, d int); @@ -310,7 +313,7 @@ drop user grant_user@localhost; drop table t1; # -# Bug#7391: Cross-database multi-table UPDATE security problem +# Bug#7391 Cross-database multi-table UPDATE security problem # create database mysqltest_1; create database mysqltest_2; @@ -319,36 +322,36 @@ create table mysqltest_1.t2 select 1 b, 2 r; create table mysqltest_2.t1 select 1 c, 2 s; create table mysqltest_2.t2 select 1 d, 2 t; -#test the column privileges +# test the column privileges grant update (a) on mysqltest_1.t1 to mysqltest_3@localhost; grant select (b) on mysqltest_1.t2 to mysqltest_3@localhost; grant select (c) on mysqltest_2.t1 to mysqltest_3@localhost; grant update (d) on mysqltest_2.t2 to mysqltest_3@localhost; connect (conn1,localhost,mysqltest_3,,); connection conn1; -SELECT * FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES - WHERE GRANTEE = '''mysqltest_3''@''localhost''' +SELECT * FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES + WHERE GRANTEE = '''mysqltest_3''@''localhost''' ORDER BY TABLE_NAME,COLUMN_NAME,PRIVILEGE_TYPE; SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES - WHERE GRANTEE = '''mysqltest_3''@''localhost''' + WHERE GRANTEE = '''mysqltest_3''@''localhost''' ORDER BY TABLE_NAME,PRIVILEGE_TYPE; SELECT * from INFORMATION_SCHEMA.SCHEMA_PRIVILEGES - WHERE GRANTEE = '''mysqltest_3''@''localhost''' + WHERE GRANTEE = '''mysqltest_3''@''localhost''' ORDER BY TABLE_SCHEMA,PRIVILEGE_TYPE; SELECT * from INFORMATION_SCHEMA.USER_PRIVILEGES WHERE GRANTEE = '''mysqltest_3''@''localhost''' ORDER BY TABLE_CATALOG,PRIVILEGE_TYPE; ---error 1143 +--error ER_COLUMNACCESS_DENIED_ERROR update mysqltest_1.t1, mysqltest_1.t2 set q=10 where b=1; ---error 1143 +--error ER_COLUMNACCESS_DENIED_ERROR update mysqltest_1.t2, mysqltest_2.t2 set d=20 where d=1; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR update mysqltest_1.t1, mysqltest_2.t2 set d=20 where d=1; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR update mysqltest_2.t1, mysqltest_1.t2 set c=20 where b=1; ---error 1143 +--error ER_COLUMNACCESS_DENIED_ERROR update mysqltest_2.t1, mysqltest_2.t2 set d=10 where s=2; -#the following two should work +# the following two should work update mysqltest_1.t1, mysqltest_2.t2 set a=10,d=10; update mysqltest_1.t1, mysqltest_2.t1 set a=20 where c=20; connection master; @@ -359,7 +362,7 @@ revoke all on mysqltest_1.t2 from mysqltest_3@localhost; revoke all on mysqltest_2.t1 from mysqltest_3@localhost; revoke all on mysqltest_2.t2 from mysqltest_3@localhost; -#test the db/table level privileges +# test the db/table level privileges grant all on mysqltest_2.* to mysqltest_3@localhost; grant select on *.* to mysqltest_3@localhost; # Next grant is needed to trigger bug#7391. Do not optimize! @@ -371,15 +374,15 @@ connection conn2; use mysqltest_1; update mysqltest_2.t1, mysqltest_2.t2 set c=500,d=600; # the following failed before, should fail now. ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR update mysqltest_1.t1, mysqltest_1.t2 set a=100,b=200; use mysqltest_2; -#the following used to succeed, it must fail now. ---error 1142 +# the following used to succeed, it must fail now. +--error ER_TABLEACCESS_DENIED_ERROR update mysqltest_1.t1, mysqltest_1.t2 set a=100,b=200; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR update mysqltest_2.t1, mysqltest_1.t2 set c=100,b=200; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR update mysqltest_1.t1, mysqltest_2.t2 set a=100,d=200; #lets see the result connection master; @@ -393,6 +396,7 @@ delete from mysql.columns_priv where user="mysqltest_3"; flush privileges; drop database mysqltest_1; drop database mysqltest_2; +disconnect conn2; # # just SHOW PRIVILEGES test @@ -400,7 +404,7 @@ drop database mysqltest_2; SHOW PRIVILEGES; # -# Rights for renaming test (Bug #3270) +# Rights for renaming test (Bug#3270) # connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection root; @@ -411,16 +415,18 @@ create table mysqltest.t1 (a int,b int,c int); grant all on mysqltest.t1 to mysqltest_1@localhost; connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK); connection user1; --- error 1142 +-- error ER_TABLEACCESS_DENIED_ERROR alter table t1 rename t2; disconnect user1; connection root; revoke all privileges on mysqltest.t1 from mysqltest_1@localhost; delete from mysql.user where user=_binary'mysqltest_1'; drop database mysqltest; +connection default; +disconnect root; # -# check all new table priveleges +# check all new table privileges # CREATE USER dummy@localhost; CREATE DATABASE mysqltest; @@ -485,7 +491,7 @@ REVOKE ALL PRIVILEGES, GRANT OPTION FROM dummy@localhost; DROP USER dummy@localhost; DROP DATABASE mysqltest; # -# Bug #11330: Entry in tables_priv with host = '' causes crash +# Bug#11330 Entry in tables_priv with host = '' causes crash # connection default; use mysql; @@ -496,7 +502,7 @@ flush privileges; use test; # -# Bug #10892 user variables not auto cast for comparisons +# Bug#10892 user variables not auto cast for comparisons # Check that we don't get illegal mix of collations # set @user123="non-existent"; @@ -515,18 +521,18 @@ show grants for root@localhost; set names latin1; # -# Bug #15598 Server crashes in specific case during setting new password +# Bug#15598 Server crashes in specific case during setting new password # - Caused by a user with host '' # create user mysqltest_7@; set password for mysqltest_7@ = password('systpass'); show grants for mysqltest_7@; drop user mysqltest_7@; ---error 1141 +--error ER_NONEXISTING_GRANT show grants for mysqltest_7@; # -# Bug#14385: GRANT and mapping to correct user account problems +# Bug#14385 GRANT and mapping to correct user account problems # create database mysqltest; use mysqltest; @@ -542,7 +548,7 @@ flush privileges; drop database mysqltest; # -# Bug #27515: DROP previlege is not required for RENAME TABLE +# Bug#27515 DROP previlege is not required for RENAME TABLE # connection master; create database db27515; @@ -553,7 +559,7 @@ grant insert, create on db27515.t2 to user27515@localhost; connect (conn27515, localhost, user27515, , db27515); connection conn27515; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR rename table t1 to t2; disconnect conn27515; @@ -565,7 +571,7 @@ drop database db27515; --echo End of 4.1 tests # -# Bug #16297 In memory grant tables not flushed when users's hostname is "" +# Bug#16297 In memory grant tables not flushed when users's hostname is "" # use test; create table t1 (a int); @@ -582,11 +588,11 @@ create user mysqltest_8; create user mysqltest_8@host8; # Try to create them again ---error 1396 +--error ER_CANNOT_USER create user mysqltest_8@''; ---error 1396 +--error ER_CANNOT_USER create user mysqltest_8; ---error 1396 +--error ER_CANNOT_USER create user mysqltest_8@host8; select user, QUOTE(host) from mysql.user where user="mysqltest_8"; @@ -681,44 +687,43 @@ flush privileges; show grants for mysqltest_8@''; show grants for mysqltest_8; drop user mysqltest_8@''; ---error 1141 +--error ER_NONEXISTING_GRANT show grants for mysqltest_8@''; show grants for mysqltest_8; select * from information_schema.user_privileges where grantee like "'mysqltest_8'%"; drop user mysqltest_8; --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT ---error 1045 +--error ER_ACCESS_DENIED_ERROR connect (conn6,localhost,mysqltest_8,,); connection master; ---error 1141 +--error ER_NONEXISTING_GRANT show grants for mysqltest_8; drop user mysqltest_8@host8; ---error 1141 +--error ER_NONEXISTING_GRANT show grants for mysqltest_8@host8; # Restore the anonymous users. insert into mysql.user select * from t2; flush privileges; drop table t2; - drop table t1; # -# Bug#20214: Incorrect error when user calls SHOW CREATE VIEW on non -# privileged view +# Bug#20214 Incorrect error when user calls SHOW CREATE VIEW on non +# privileged view # connection master; CREATE DATABASE mysqltest3; -use mysqltest3; +USE mysqltest3; CREATE TABLE t_nn (c1 INT); CREATE VIEW v_nn AS SELECT * FROM t_nn; CREATE DATABASE mysqltest2; -use mysqltest2; +USE mysqltest2; CREATE TABLE t_nn (c1 INT); CREATE VIEW v_nn AS SELECT * FROM t_nn; @@ -740,24 +745,18 @@ SHOW CREATE VIEW mysqltest2.v_nn; --error ER_TABLEACCESS_DENIED_ERROR SHOW CREATE TABLE mysqltest2.v_nn; - - # fail because of missing SHOW VIEW --error ER_TABLEACCESS_DENIED_ERROR SHOW CREATE VIEW mysqltest2.v_yn; --error ER_TABLEACCESS_DENIED_ERROR SHOW CREATE TABLE mysqltest2.v_yn; - - # succeed (despite of missing SELECT, having SHOW VIEW bails us out) SHOW CREATE TABLE mysqltest2.v_ny; # succeed (despite of missing SELECT, having SHOW VIEW bails us out) SHOW CREATE VIEW mysqltest2.v_ny; - - # fail because of missing (specific or generic) SELECT --error ER_TABLEACCESS_DENIED_ERROR SHOW CREATE TABLE mysqltest3.t_nn; @@ -766,16 +765,12 @@ SHOW CREATE TABLE mysqltest3.t_nn; --error ER_TABLEACCESS_DENIED_ERROR SHOW CREATE VIEW mysqltest3.t_nn; - - # fail because of missing missing (specific or generic) SELECT (and SHOW VIEW) --error ER_TABLEACCESS_DENIED_ERROR SHOW CREATE VIEW mysqltest3.v_nn; --error ER_TABLEACCESS_DENIED_ERROR SHOW CREATE TABLE mysqltest3.v_nn; - - # succeed thanks to generic SELECT SHOW CREATE TABLE mysqltest2.t_nn; @@ -783,8 +778,6 @@ SHOW CREATE TABLE mysqltest2.t_nn; --error ER_WRONG_OBJECT SHOW CREATE VIEW mysqltest2.t_nn; - - # succeed, have SELECT and SHOW VIEW SHOW CREATE VIEW mysqltest2.v_yy; @@ -792,8 +785,7 @@ SHOW CREATE VIEW mysqltest2.v_yy; SHOW CREATE TABLE mysqltest2.v_yy; - -#clean-up +# clean-up connection master; # succeed, we're root @@ -806,38 +798,30 @@ SHOW CREATE TABLE mysqltest2.t_nn; --error ER_WRONG_OBJECT SHOW CREATE VIEW mysqltest2.t_nn; - - DROP VIEW mysqltest2.v_nn; DROP VIEW mysqltest2.v_yn; DROP VIEW mysqltest2.v_ny; DROP VIEW mysqltest2.v_yy; - DROP TABLE mysqltest2.t_nn; - DROP DATABASE mysqltest2; - - - DROP VIEW mysqltest3.v_nn; DROP TABLE mysqltest3.t_nn; - DROP DATABASE mysqltest3; - +disconnect mysqltest_1; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'mysqltest_1'@'localhost'; DROP USER 'mysqltest_1'@'localhost'; # restore the original database -use test; +USE test; # -# Bug #10668: CREATE USER does not enforce username length limit +# Bug#10668 CREATE USER does not enforce username length limit # --error ER_WRONG_STRING_LENGTH create user mysqltest1_thisisreallytoolong; # -# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause. +# Test for Bug#16899 Possible buffer overflow in handling of DEFINER-clause. # # These checks are intended to ensure that appropriate errors are risen when # illegal user name or hostname is specified in user-clause of GRANT/REVOKE @@ -887,7 +871,7 @@ REVOKE EXECUTE ON PROCEDURE p1 FROM 1234567890abcdefGHIKL@localhost; REVOKE EXECUTE ON PROCEDURE t1 FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY; # -# Bug #6774: Replication fails with Wrong usage of DB GRANT and GLOBAL PRIVILEGES +# Bug#6774 Replication fails with Wrong usage of DB GRANT and GLOBAL PRIVILEGES # # Check if GRANT ... ON * ... fails when no database is selected connect (con1, localhost, root,,*NO-ONE*); @@ -899,7 +883,7 @@ connection default; # -# BUG#9504: Stored procedures: execute privilege doesn't make 'use database' +# Bug#9504 Stored procedures: execute privilege doesn't make 'use database' # okay. # @@ -924,8 +908,8 @@ CREATE PROCEDURE mysqltest2.p_inv() SQL SECURITY INVOKER SELECT 1; CREATE FUNCTION mysqltest3.f_def() RETURNS INT SQL SECURITY DEFINER - RETURN 1; - + RETURN 1; + CREATE FUNCTION mysqltest4.f_inv() RETURNS INT SQL SECURITY INVOKER RETURN 1; @@ -981,7 +965,7 @@ DROP USER mysqltest_1@localhost; # -# BUG#27337: Privileges are not restored properly. +# Bug#27337 Privileges are not restored properly. # # Actually, the patch for this bugs fixes two problems. So, here are two test # cases. @@ -1043,7 +1027,7 @@ DROP DATABASE mysqltest2; DROP USER mysqltest_1@localhost; -# Test case 2: priveleges are not checked properly for prepared statements. +# Test case 2: privileges are not checked properly for prepared statements. # Prepare. @@ -1116,6 +1100,7 @@ EXECUTE stmt2; --echo --echo ---> connection: default +--disconnect bug27337_con1 --disconnect bug27337_con2 DROP DATABASE mysqltest1; @@ -1125,21 +1110,21 @@ DROP USER mysqltest_1@localhost; DROP USER mysqltest_2@localhost; # -# Bug#27878: Unchecked privileges on a view referring to a table from another -# database. +# Bug#27878 Unchecked privileges on a view referring to a table from another +# database. # -use test; +USE test; CREATE TABLE t1 (f1 int, f2 int); INSERT INTO t1 VALUES(1,1), (2,2); CREATE DATABASE db27878; GRANT UPDATE(f1) ON t1 TO 'mysqltest_1'@'localhost'; GRANT SELECT ON `test`.* TO 'mysqltest_1'@'localhost'; GRANT ALL ON db27878.* TO 'mysqltest_1'@'localhost'; -use db27878; +USE db27878; CREATE SQL SECURITY INVOKER VIEW db27878.v1 AS SELECT * FROM test.t1; connect (user1,localhost,mysqltest_1,,test); connection user1; -use db27878; +USE db27878; --error 1356 UPDATE v1 SET f2 = 4; SELECT * FROM test.t1; @@ -1150,11 +1135,11 @@ REVOKE SELECT ON `test`.* FROM 'mysqltest_1'@'localhost'; REVOKE ALL ON db27878.* FROM 'mysqltest_1'@'localhost'; DROP USER mysqltest_1@localhost; DROP DATABASE db27878; -use test; +USE test; DROP TABLE t1; # -# Bug #33201 Crash occurs when granting update privilege on one column of a view +# Bug#33201 Crash occurs when granting update privilege on one column of a view # drop table if exists test; drop function if exists test_function; @@ -1183,3 +1168,7 @@ SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin"); SET PASSWORD FOR CURRENT_USER() = PASSWORD(""); --echo End of 5.0 tests + +disconnect master; +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index caf38945cbc..5873347eae0 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -36,11 +36,11 @@ insert into t5 values (10); create view v1 (c) as select table_name from information_schema.TABLES; select * from v1; -select c,table_name from v1 +select c,table_name from v1 inner join information_schema.TABLES v2 on (v1.c=v2.table_name) where v1.c like "t%"; -select c,table_name from v1 +select c,table_name from v1 left join information_schema.TABLES v2 on (v1.c=v2.table_name) where v1.c like "t%"; @@ -69,7 +69,7 @@ grant select (a) on mysqltest.t1 to mysqltest_2@localhost; grant select on mysqltest.v1 to mysqltest_3; connect (user3,localhost,mysqltest_2,,); connection user3; -select table_name, column_name, privileges from information_schema.columns +select table_name, column_name, privileges from information_schema.columns where table_schema = 'mysqltest' and table_name = 't1'; show columns from mysqltest.t1; connect (user4,localhost,mysqltest_3,,mysqltest); @@ -77,6 +77,7 @@ connection user4; select table_name, column_name, privileges from information_schema.columns where table_schema = 'mysqltest' and table_name = 'v1'; connection default; +disconnect user4; drop view v1, mysqltest.v1; drop tables mysqltest.t4, mysqltest.t1, t2, t3, t5; @@ -126,7 +127,7 @@ delimiter ;| # # Bug#7222 information_schema: errors in "routines" # -select parameter_style, sql_data_access, dtd_identifier +select parameter_style, sql_data_access, dtd_identifier from information_schema.routines; --replace_column 5 # 6 # @@ -145,7 +146,7 @@ select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a, mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8) order by 1; select count(*) from information_schema.ROUTINES; -create view v1 as select routine_schema, routine_name from information_schema.routines +create view v1 as select routine_schema, routine_name from information_schema.routines order by routine_schema, routine_name; select * from v1; drop view v1; @@ -153,7 +154,7 @@ drop view v1; connect (user1,localhost,mysqltest_1,,); connection user1; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; ---error 1305 +--error ER_SP_DOES_NOT_EXIST show create function sub1; connection user3; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; @@ -172,6 +173,7 @@ show create function sub2; show function status like "sub2"; connection default; disconnect user1; +disconnect user3; drop function sub2; show create procedure sel2; @@ -311,7 +313,7 @@ drop view v1; create table t1(a NUMERIC(5,3), b NUMERIC(5,1), c float(5,2), d NUMERIC(6,4), e float, f DECIMAL(6,3), g int(11), h DOUBLE(10,3), i DOUBLE); -select COLUMN_NAME,COLUMN_TYPE, CHARACTER_MAXIMUM_LENGTH, +select COLUMN_NAME,COLUMN_TYPE, CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE from information_schema.columns where table_name= 't1'; drop table t1; @@ -324,7 +326,7 @@ drop table t115; delimiter //; create procedure p108 () begin declare c cursor for select data_type from information_schema.columns; open c; open c; end;// ---error 1325 +--error ER_SP_CURSOR_ALREADY_OPEN call p108()// delimiter ;// drop procedure p108; @@ -334,24 +336,24 @@ where table_name= "user"; select * from v1; drop view v1; -create view vo as select 'a' union select 'a'; +create view vo as select 'a' union select 'a'; show index from vo; select * from information_schema.TABLE_CONSTRAINTS where TABLE_NAME= "vo"; select * from information_schema.KEY_COLUMN_USAGE where -TABLE_NAME= "vo"; +TABLE_NAME= "vo"; drop view vo; select TABLE_NAME,TABLE_TYPE,ENGINE -from information_schema.tables +from information_schema.tables where table_schema='information_schema' limit 2; show tables from information_schema like "T%"; ---error 1044 +--error ER_DBACCESS_DENIED_ERROR create database information_schema; use information_schema; show full tables like "T%"; ---error 1109 +--error ER_UNKNOWN_TABLE create table t1(a int); use test; show tables; @@ -359,15 +361,15 @@ use information_schema; show tables like "T%"; # -# Bug#7210: information_schema: can't access when table-name = reserved word +# Bug#7210 information_schema: can't access when table-name = reserved word # select table_name from tables where table_name='user'; select column_name, privileges from columns where table_name='user' and column_name like '%o%'; # -# Bug#7212: information_schema: "Can't find file" errors if storage engine gone -# Bug#7211: information_schema: crash if bad view +# Bug#7212 information_schema: "Can't find file" errors if storage engine gone +# Bug#7211 information_schema: crash if bad view # use test; create function sub1(i int) returns int @@ -394,9 +396,9 @@ drop view v3; drop table t4; # -# Bug#7213: information_schema: redundant non-standard TABLE_NAMES table +# Bug#7213 information_schema: redundant non-standard TABLE_NAMES table # ---error 1109 +--error ER_UNKNOWN_TABLE select * from information_schema.table_names; # @@ -409,7 +411,7 @@ where table_schema="information_schema" and table_name="COLUMNS" and # # Bug#2718 information_schema: errors in "tables" # -select TABLE_ROWS from information_schema.tables where +select TABLE_ROWS from information_schema.tables where table_schema="information_schema" and table_name="COLUMNS"; select table_type from information_schema.tables where table_schema="mysql" and table_name="user"; @@ -422,14 +424,14 @@ show status where variable_name like "%database%"; show variables where variable_name like "skip_show_databas"; # -# Bug #7981:SHOW GLOBAL STATUS crashes server +# Bug#7981 SHOW GLOBAL STATUS crashes server # # We don't actually care about the value, just that it doesn't crash. --replace_column 2 # show global status like "Threads_running"; # -# Bug #7915 crash,JOIN VIEW, subquery, +# Bug#7915 crash,JOIN VIEW, subquery, # SELECT .. FROM INFORMATION_SCHEMA.COLUMNS # create table t1(f1 int); @@ -440,7 +442,7 @@ drop view v1; drop table t1, t2; # -# Bug #7476: crash on SELECT * FROM INFORMATION_SCHEMA.TABLES +# Bug#7476 crash on SELECT * FROM INFORMATION_SCHEMA.TABLES # CREATE TABLE t_crashme ( f1 BIGINT); @@ -468,26 +470,26 @@ drop view a2, a1; drop table t_crashme; # -# Bug #7215 information_schema: columns are longtext instead of varchar -# Bug #7217 information_schema: columns are varbinary() instead of timestamp +# Bug#7215 information_schema: columns are longtext instead of varchar +# Bug#7217 information_schema: columns are varbinary() instead of timestamp # select table_schema,table_name, column_name from -information_schema.columns +information_schema.columns where data_type = 'longtext'; select table_name, column_name, data_type from information_schema.columns where data_type = 'datetime'; # -# Bug #8164 subquery with INFORMATION_SCHEMA.COLUMNS, 100 % CPU +# Bug#8164 subquery with INFORMATION_SCHEMA.COLUMNS, 100 % CPU # SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES A -WHERE NOT EXISTS +WHERE NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS B WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA AND A.TABLE_NAME = B.TABLE_NAME); # -# Bug #9344 INFORMATION_SCHEMA, wrong content, numeric columns +# Bug#9344 INFORMATION_SCHEMA, wrong content, numeric columns # create table t1 @@ -505,21 +507,22 @@ WHERE TABLE_NAME= 't1'; drop table t1; # -# Bug#10261 INFORMATION_SCHEMA.COLUMNS, incomplete result for non root user +# Bug#10261 INFORMATION_SCHEMA.COLUMNS, incomplete result for non root user # grant select on test.* to mysqltest_4@localhost; connect (user10261,localhost,mysqltest_4,,); connection user10261; -SELECT TABLE_NAME, COLUMN_NAME, PRIVILEGES FROM INFORMATION_SCHEMA.COLUMNS +SELECT TABLE_NAME, COLUMN_NAME, PRIVILEGES FROM INFORMATION_SCHEMA.COLUMNS where COLUMN_NAME='TABLE_NAME'; connection default; +disconnect user10261; delete from mysql.user where user='mysqltest_4'; delete from mysql.db where user='mysqltest_4'; flush privileges; # -# Bug #9404 information_schema: Weird error messages +# Bug#9404 information_schema: Weird error messages # with SELECT SUM() ... GROUP BY queries # SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA; @@ -560,7 +563,7 @@ drop table t1; # -# Bug #10964 Information Schema:Authorization check on privilege tables is improper +# Bug#10964 Information Schema:Authorization check on privilege tables is improper # create database mysqltest; @@ -604,12 +607,16 @@ select * from information_schema.user_privileges where grantee like '%user%' order by grantee; show grants; connection default; +disconnect con1; +disconnect con2; +disconnect con3; +disconnect con4; drop user user1@localhost, user2@localhost, user3@localhost, user4@localhost; use test; drop database mysqltest; # -# Bug #11055 information_schema: routines.sql_data_access has wrong value +# Bug#11055 information_schema: routines.sql_data_access has wrong value # --disable_warnings drop procedure if exists p1; @@ -624,13 +631,13 @@ drop procedure p1; drop procedure p2; # -# Bug #9434 SHOW CREATE DATABASE information_schema; +# Bug#9434 SHOW CREATE DATABASE information_schema; # show create database information_schema; # -# Bug #11057 information_schema: columns table has some questionable contents -# Bug #12301 information_schema: NUMERIC_SCALE must be 0 for integer columns +# Bug#11057 information_schema: columns table has some questionable contents +# Bug#12301 information_schema: NUMERIC_SCALE must be 0 for integer columns # create table t1(f1 LONGBLOB, f2 LONGTEXT); select column_name,data_type,CHARACTER_OCTET_LENGTH, @@ -646,7 +653,7 @@ where table_name='t1'; drop table t1; # -# Bug #12127 triggers do not show in info_schema before they are used if set to the database +# Bug#12127 triggers do not show in info_schema before they are used if set to the database # create table t1 (f1 integer); create trigger tr1 after insert on t1 for each row set @test_var=42; @@ -668,7 +675,7 @@ show columns from t1; drop table t1; # -# Bug #12636: SHOW TABLE STATUS with where condition containing a subquery +# Bug#12636 SHOW TABLE STATUS with where condition containing a subquery # over information schema # @@ -683,7 +690,7 @@ SHOW TABLE STATUS FROM test DROP TABLE t1,t2; # -# Bug #12905 show fields from view behaving erratically with current database +# Bug#12905 show fields from view behaving erratically with current database # create table t1(f1 int); create view v1 (c) as select f1 from t1; @@ -691,28 +698,29 @@ connect (con5,localhost,root,,*NO-ONE*); select database(); show fields from test.v1; connection default; +disconnect con5; drop view v1; drop table t1; # -# Bug #9846 Inappropriate error displayed while dropping table from 'INFORMATION_SCHEMA' +# Bug#9846 Inappropriate error displayed while dropping table from 'INFORMATION_SCHEMA' # --error ER_PARSE_ERROR alter database information_schema; ---error 1044 +--error ER_DBACCESS_DENIED_ERROR drop database information_schema; ---error 1044 +--error ER_DBACCESS_DENIED_ERROR drop table information_schema.tables; ---error 1044 +--error ER_DBACCESS_DENIED_ERROR alter table information_schema.tables; # -# Bug #9683 INFORMATION_SCH: Creation of temporary table allowed in Information_schema DB +# Bug#9683 INFORMATION_SCH: Creation of temporary table allowed in Information_schema DB # use information_schema; ---error 1044 +--error ER_DBACCESS_DENIED_ERROR create temporary table schemata(f1 char(10)); # -# Bug #10708 SP's can use INFORMATION_SCHEMA as ROUTINE_SCHEMA +# Bug#10708 SP's can use INFORMATION_SCHEMA as ROUTINE_SCHEMA # delimiter |; --error ER_BAD_DB_ERROR @@ -723,11 +731,11 @@ END | delimiter ;| select ROUTINE_NAME from routines; # -# Bug #10734 Grant of privileges other than 'select' and 'create view' should fail on schema +# Bug#10734 Grant of privileges other than 'select' and 'create view' should fail on schema # ---error 1044 +--error ER_DBACCESS_DENIED_ERROR grant all on information_schema.* to 'user1'@'localhost'; ---error 1044 +--error ER_DBACCESS_DENIED_ERROR grant select on information_schema.* to 'user1'@'localhost'; # @@ -753,9 +761,9 @@ where table_name="v1"; drop view v1; # -# Bug #14387 SHOW COLUMNS doesn't work on temporary tables -# Bug #15224 SHOW INDEX from temporary table doesn't work -# Bug #12770 DESC cannot display the info. about temporary table +# Bug#14387 SHOW COLUMNS doesn't work on temporary tables +# Bug#15224 SHOW INDEX from temporary table doesn't work +# Bug#12770 DESC cannot display the info. about temporary table # create temporary table t1(f1 int, index(f1)); show columns from t1; @@ -839,6 +847,7 @@ connection con16681; select * from information_schema.views where table_name='v1' or table_name='v2'; connection default; +disconnect con16681; drop view v1, v2; drop table t1; drop user mysqltest_1@localhost; @@ -855,7 +864,7 @@ drop table t1,t2; # -# Bug#20230: routine_definition is not null +# Bug#20230 routine_definition is not null # --disable_warnings DROP PROCEDURE IF EXISTS p1; @@ -888,7 +897,7 @@ DROP PROCEDURE p1; DROP USER mysql_bug20230@localhost; # -# Bug#18925: subqueries with MIN/MAX functions on INFORMARTION_SCHEMA +# Bug#18925 subqueries with MIN/MAX functions on INFORMARTION_SCHEMA # SELECT t.table_name, c1.column_name @@ -921,8 +930,8 @@ SELECT t.table_name, c1.column_name ); # -# Bug#21231: query with a simple non-correlated subquery over -# INFORMARTION_SCHEMA.TABLES +# Bug#2123 query with a simple non-correlated subquery over +# INFORMARTION_SCHEMA.TABLES # SELECT MAX(table_name) FROM information_schema.tables; @@ -931,7 +940,7 @@ SELECT table_name from information_schema.tables FROM information_schema.tables); # -# Bug #23037: Bug in field "Default" of query "SHOW COLUMNS FROM table" +# Bug#23037 Bug in field "Default" of query "SHOW COLUMNS FROM table" # # Note, MyISAM/InnoDB can't take more that 65532 chars, because the row # size is limited to 65535 bytes (BLOBs not counted) @@ -975,7 +984,7 @@ DROP FUNCTION get_value; # -# Bug#22413: EXPLAIN SELECT FROM view with ORDER BY yield server crash +# Bug#22413 EXPLAIN SELECT FROM view with ORDER BY yield server crash # create view v1 as select table_schema as object_schema, @@ -1001,7 +1010,7 @@ drop table t1,t2; # -# Bug#24630 Subselect query crashes mysqld +# Bug#24630 Subselect query crashes mysqld # select 1 as f1 from information_schema.tables where "CHARACTER_SETS"= (select cast(table_name as char) from information_schema.tables @@ -1028,8 +1037,8 @@ group by t.table_name order by num1, t.table_name; # create table t1(f1 int); create view v1 as select f1+1 as a from t1; -create table t2 (f1 int, f2 int); -create view v2 as select f1+1 as a, f2 as b from t2; +create table t2 (f1 int, f2 int); +create view v2 as select f1+1 as a, f2 as b from t2; select table_name, is_updatable from information_schema.views; # # Note: we can perform 'delete' for non updatable view. @@ -1039,7 +1048,7 @@ drop view v1,v2; drop table t1,t2; # -# Bug#25859 ALTER DATABASE works w/o parameters +# Bug#25859 ALTER DATABASE works w/o parameters # --error ER_PARSE_ERROR alter database; @@ -1068,6 +1077,7 @@ show triggers; select trigger_name from information_schema.triggers where event_object_table='t1'; connection default; +disconnect con27629; drop user mysqltest_1@localhost; drop database mysqltest; @@ -1111,13 +1121,13 @@ select * from `information_schema`.`VIEWS` where `TABLE_NAME` = NULL; # # Bug#30079 A check for "hidden" I_S tables is flawed # ---error 1109 +--error ER_UNKNOWN_TABLE show fields from information_schema.table_names; ---error 1109 +--error ER_UNKNOWN_TABLE show keys from information_schema.table_names; # -# Bug#34529: Crash on complex Falcon I_S select after ALTER .. PARTITION BY +# Bug#34529 Crash on complex Falcon I_S select after ALTER .. PARTITION BY # USE information_schema; SET max_heap_table_size = 16384; @@ -1126,9 +1136,9 @@ CREATE TABLE test.t1( a INT ); # What we need to create here is a bit of a corner case: # We need a star query with information_schema tables, where the first -# branch of the star join produces zero rows, so that reading of the +# branch of the star join produces zero rows, so that reading of the # second branch never happens. At the same time we have to make sure -# that data for at least the last table is swapped from MEMORY/HEAP to +# that data for at least the last table is swapped from MEMORY/HEAP to # MyISAM. This and only this triggers the bug. SELECT * FROM tables ta diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 2bb3b17340c..9f493189e6d 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -24,17 +24,17 @@ let $1 = 100; while ($1) { let $2 = 5; - eval insert into t1(t) values ('$1'); + eval insert into t1(t) values ('$1'); while ($2) { - eval insert into t2(id2,t) values ($1,'$2'); + eval insert into t2(id2,t) values ($1,'$2'); let $3 = 10; while ($3) { - eval insert into t3(id3,t) values ($1,'$2'); + eval insert into t3(id3,t) values ($1,'$2'); dec $3; } - dec $2; + dec $2; } dec $1; } @@ -79,11 +79,11 @@ let $1 = 1000; while ($1) { let $2 = 5; - eval insert into t1 values ($1,'aaaaaaaaaaaaaaaaaaaa'); + eval insert into t1 values ($1,'aaaaaaaaaaaaaaaaaaaa'); while ($2) { - eval insert into t2(id2,t) values ($1,'bbbbbbbbbbbbbbbbb'); - dec $2; + eval insert into t2(id2,t) values ($1,'bbbbbbbbbbbbbbbbb'); + dec $2; } dec $1; } @@ -317,7 +317,7 @@ update t2, t1 set t2.field=t1.field delete t1, t2 from t2 inner join t1 on t1.id1=t2.id2 where 0=1; -delete t1, t2 from t2,t1 +delete t1, t2 from t2,t1 where t1.id1=t2.id2 and 0=1; drop table t1,t2; @@ -351,7 +351,7 @@ create table `t2` (`c2_id` int(10) unsigned NULL auto_increment, `c2_p_id` int(1 insert into t1 values (0,'A01-Comp',1); insert into t1 values (0,'B01-Comp',1); insert into t2 values (0,1,'A Note',1); -update t1 left join t2 on p_id = c2_p_id set c2_note = 'asdf-1' where p_id = 2; +update t1 left join t2 on p_id = c2_p_id set c2_note = 'asdf-1' where p_id = 2; select * from t1; select * from t2; drop table t1, t2; @@ -379,6 +379,9 @@ revoke all privileges on mysqltest.t1 from mysqltest_1@localhost; revoke all privileges on mysqltest.* from mysqltest_1@localhost; delete from mysql.user where user=_binary'mysqltest_1'; drop database mysqltest; +connection default; +disconnect user1; +disconnect root; # # multi delete wrong table check @@ -393,7 +396,7 @@ drop table t1, t2, t3; # # multi* unique updating table check # -create table t1 (col1 int); +create table t1 (col1 int); create table t2 (col1 int); -- error ER_UPDATE_TABLE_USED update t1,t2 set t1.col1 = (select max(col1) from t1) where t1.col1 = t2.col1; @@ -401,16 +404,16 @@ update t1,t2 set t1.col1 = (select max(col1) from t1) where t1.col1 = t2.col1; delete t1 from t1,t2 where t1.col1 < (select max(col1) from t1) and t1.col1 = t2.col1; drop table t1,t2; -# Test for BUG#5837 - delete with outer join and const tables +# Test for Bug#5837 delete with outer join and const tables --disable_warnings create table t1 ( - aclid bigint not null primary key, - status tinyint(1) not null + aclid bigint not null primary key, + status tinyint(1) not null ) engine = innodb; create table t2 ( - refid bigint not null primary key, - aclid bigint, index idx_acl(aclid) + refid bigint not null primary key, + aclid bigint, index idx_acl(aclid) ) engine = innodb; --enable_warnings insert into t2 values(1,null); @@ -418,7 +421,7 @@ delete t2, t1 from t2 left join t1 on (t2.aclid=t1.aclid) where t2.refid='1'; drop table t1, t2; # -# Bug#19225: unchecked error leads to server crash +# Bug#19225 unchecked error leads to server crash # create table t1(a int); create table t2(a int); @@ -428,7 +431,7 @@ drop table t1, t2; # End of 4.1 tests # -# Test for bug #1980. +# Test for Bug#1980. # --disable_warnings create table t1 ( c char(8) not null ) engine=innodb; @@ -484,9 +487,12 @@ send alter table t1 add column c int default 100 after a; connect (updater,localhost,root,,test); connection updater; +# Wait till "alter table t1 ..." is in work. +sleep 2; send update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a; connection locker; +# Wait till "update t1, v1 ..." is in work. sleep 2; unlock tables; @@ -500,8 +506,14 @@ select * from t2; drop view v1; drop table t1, t2; +connection default; +disconnect locker; +disconnect changer; +disconnect updater; + + # -# Bug#27716 multi-update did partially and has not binlogged +# Bug#27716 multi-update did partially and has not binlogged # CREATE TABLE `t1` ( @@ -536,11 +548,12 @@ reset master; UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a; show master status /* there must be the UPDATE query event */; -# cleanup bug#27716 +# cleanup drop table t1, t2; + # -# Bug #29136 erred multi-delete on trans table does not rollback +# Bug#29136 erred multi-delete on trans table does not rollback # # prepare @@ -569,7 +582,7 @@ select count(*) from t3 /* must be 1 */; # the query must be in binlog (no surprise though) source include/show_binlog_events.inc; -# cleanup bug#29136 +# cleanup drop table t1, t2, t3; diff --git a/mysql-test/t/overflow.test b/mysql-test/t/overflow.test index a62ef9c4cd2..774c43be658 100644 --- a/mysql-test/t/overflow.test +++ b/mysql-test/t/overflow.test @@ -1,6 +1,14 @@ +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + connect (con1,localhost,root,,); connection con1; --- error 1064,1102,1280 +--error ER_PARSE_ERROR,ER_WRONG_DB_NAME,ER_WRONG_NAME_FOR_INDEX drop database AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; +connection default; +disconnect con1; # End of 4.1 tests + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/packet.test b/mysql-test/t/packet.test index 4de284b7824..6210e9986ad 100644 --- a/mysql-test/t/packet.test +++ b/mysql-test/t/packet.test @@ -4,12 +4,18 @@ # swallowing them and returning an error --source include/not_windows.inc +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + + # # Check protocol handling # -connect (con1,localhost,root,,); +set @max_allowed_packet=@@global.max_allowed_packet; +set @net_buffer_length=@@global.net_buffer_length; +connect (con1,localhost,root,,); connection con1; set global max_allowed_packet=100; set max_allowed_packet=100; @@ -19,6 +25,8 @@ set net_buffer_length=100; SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; # Should return NULL as 2000 is bigger than max_allowed_packet select repeat('a',2000); +connection default; +disconnect con1; # # Connection 2 should get error for too big packets @@ -26,7 +34,7 @@ select repeat('a',2000); connect (con2,localhost,root,,); connection con2; select @@net_buffer_length, @@max_allowed_packet; ---error 1153 +--error ER_NET_PACKET_TOO_LARGE SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; set global max_allowed_packet=default; set max_allowed_packet=default; @@ -34,5 +42,13 @@ set global net_buffer_length=default; set net_buffer_length=default; SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; select length(repeat('a',2000)); +connection default; +disconnect con2; + +set global max_allowed_packet=@max_allowed_packet; +set global net_buffer_length=@net_buffer_length; # End of 4.1 tests + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/query_cache_notembedded.test b/mysql-test/t/query_cache_notembedded.test index 421ec913e5d..b8b223ecd8c 100644 --- a/mysql-test/t/query_cache_notembedded.test +++ b/mysql-test/t/query_cache_notembedded.test @@ -1,6 +1,10 @@ -- source include/have_query_cache.inc -- source include/not_embedded.inc +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + + # # Tests with query cache # @@ -79,7 +83,7 @@ show status like "Qcache_free_blocks"; drop table t1, t2, t3, t11, t21; # -# do not use QC if tables locked (BUG#12385) +# do not use QC if tables locked (Bug#12385) # connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection root; @@ -96,10 +100,13 @@ SELECT * FROM t1; connection root; SELECT * FROM t1; drop table t1; +connection default; +disconnect root; +disconnect root2; # -# query in QC from normal execution and SP (BUG#6897) -# improved to also test BUG#3583 and BUG#12990 +# query in QC from normal execution and SP (Bug#6897) +# improved to also test Bug#3583 and Bug#12990 # flush query cache; reset query cache; @@ -181,7 +188,7 @@ drop procedure f4; drop table t1; # -# bug#14767: INSERT in SF + concurrent SELECT with query cache +# Bug#14767 INSERT in SF + concurrent SELECT with query cache # reset query cache; --disable_warnings @@ -223,4 +230,36 @@ connection default; set GLOBAL query_cache_size=0; +# +# Bug#40264: Aborted cached query causes query to hang indefinitely on next cache hit +# + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +FLUSH STATUS; +SET GLOBAL query_cache_size=1048576; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +SHOW STATUS LIKE 'Qcache_queries_in_cache'; +LOCK TABLES t1 WRITE; +connect(con1,localhost,root,,); +--send SELECT * FROM t1 +connection default; +let $show_type= open tables where `table`='t1' and in_use=2; +let $show_pattern= '%t1%2%'; +--source include/wait_show_pattern.inc +dirty_close con1; +UNLOCK TABLES; +let $show_type= open tables where `table`='t1' and in_use=0; +let $show_pattern= '%t1%0%'; +--source include/wait_show_pattern.inc +SHOW STATUS LIKE 'Qcache_queries_in_cache'; +DROP TABLE t1; +SET GLOBAL query_cache_size= default; + # End of 5.0 tests + +# Wait till we reached the initial number of concurrent sessions +#--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/sp-threads.test b/mysql-test/t/sp-threads.test index d8a8ce5dae7..e1012e2b72d 100644 --- a/mysql-test/t/sp-threads.test +++ b/mysql-test/t/sp-threads.test @@ -5,6 +5,9 @@ # except security/privilege tests, they go to sp-security.test # +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + connect (con1root,localhost,root,,); connect (con2root,localhost,root,,); connect (con3root,localhost,root,,); @@ -17,7 +20,7 @@ drop table if exists t1; --enable_warnings create table t1 (s1 int, s2 int, s3 int); -delimiter //; +delimiter //; create procedure bug4934() begin insert into t1 values (1,0,1); @@ -38,7 +41,7 @@ drop table t1; create table t1 (s1 int, s2 int, s3 int); drop procedure bug4934; -delimiter //; +delimiter //; create procedure bug4934() begin end// @@ -58,7 +61,7 @@ drop procedure bug4934; # -# BUG #9486 "Can't perform multi-update in stored procedure" +# Bug#9486 Can't perform multi-update in stored procedure # --disable_warnings drop procedure if exists bug9486; @@ -87,8 +90,9 @@ reap; drop procedure bug9486; drop table t1, t2; + # -# BUG#11158: Can't perform multi-delete in stored procedure +# Bug#11158 Can't perform multi-delete in stored procedure # --disable_warnings drop procedure if exists bug11158; @@ -114,8 +118,9 @@ connection con1root; drop procedure bug11158; drop table t1, t2; + # -# BUG#11554: Server crashes on statement indirectly using non-cached function +# Bug#11554 Server crashes on statement indirectly using non-cached function # --disable_warnings drop function if exists bug11554; @@ -134,7 +139,7 @@ drop table t1; drop view v1; -# BUG#12228 +# Bug#12228 Crash happens during calling specific SP in multithread environment --disable_warnings drop procedure if exists p1; drop procedure if exists p2; @@ -168,18 +173,26 @@ connection con2root; unlock tables; connection con1root; -# Crash will be here if we hit BUG#12228 +# Crash will be here if we hit Bug#12228 reap; drop procedure p1; drop procedure p2; drop table t1; + # -# BUG#NNNN: New bug synopsis +# Bug#NNNN New bug synopsis # #--disable_warnings #drop procedure if exists bugNNNN; #--enable_warnings #create procedure bugNNNN... +connection default; +disconnect con1root; +disconnect con2root; +disconnect con3root; + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index ea911e4912d..57aaa00e643 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -78,9 +78,9 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1); (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a); explain extended (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a); select (select a from t3 where a1) as tt; -explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from +explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from (select * from t2 where a>1) as tt; select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1); select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a > t1.a) order by 1 desc limit 1); @@ -536,7 +536,7 @@ do (SELECT a from t1); -- error ER_NO_SUCH_TABLE set @a:=(SELECT a from t1); -CREATE TABLE t1 (a int, KEY(a)); +CREATE TABLE t1 (a int, KEY(a)); HANDLER t1 OPEN; -- error ER_PARSE_ERROR HANDLER t1 READ a=((SELECT 1)); @@ -678,7 +678,7 @@ CREATE TABLE t2 ( INSERT INTO t2 VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU'); INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ'); -select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent); +select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent); drop table t1, t2; @@ -732,9 +732,9 @@ drop table t1,t2; # # correct NULL in IN (SELECT ...) # -create table t1 (a int, unique index indexa (a)); -insert into t1 values (-1), (-4), (-2), (NULL); -select -10 IN (select a from t1 FORCE INDEX (indexa)); +create table t1 (a int, unique index indexa (a)); +insert into t1 values (-1), (-4), (-2), (NULL); +select -10 IN (select a from t1 FORCE INDEX (indexa)); drop table t1; # @@ -816,7 +816,7 @@ disable_query_log; let $1 = 10000; while ($1) { - eval insert into t1 values (rand()*100000+200,rand()*100000); + eval insert into t1 values (rand()*100000+200,rand()*100000); dec $1; } enable_query_log; @@ -842,7 +842,7 @@ create table t2 (a int, b int); create table t3 (a int, b int); insert into t1 values (0,100),(1,2), (1,3), (2,2), (2,7), (2,-1), (3,10); insert into t2 values (0,0), (1,1), (2,1), (3,1), (4,1); -insert into t3 values (3,3), (2,2), (1,1); +insert into t3 values (3,3), (2,2), (1,1); select a,(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3; drop table t1,t2,t3; @@ -1010,7 +1010,7 @@ drop table t1, t2; # # unresolved field error # -create table t1 (s1 int); +create table t1 (s1 int); create table t2 (s1 int); -- error ER_BAD_FIELD_ERROR select * from t1 where (select count(*) from t2 where t1.s2) = 1; @@ -1035,11 +1035,12 @@ INSERT INTO t1 VALUES (1),(1),(1),(1),(1),(2),(3),(4),(5); SELECT DISTINCT (SELECT a) FROM t1 LIMIT 100; DROP TABLE t1; + # -# Bug 2198 +# Bug#2198 SELECT INTO OUTFILE (with Sub-Select) Problem # -create table t1 (a int, b decimal(13, 3)); +create table t1 (a int, b decimal(13, 3)); insert into t1 values (1, 0.123); let $outfile = $MYSQLTEST_VARDIR/master-data/test/subselect.out.file.1; --error 0,1 @@ -1051,8 +1052,9 @@ load data infile "subselect.out.file.1" into table t1; select * from t1; drop table t1; + # -# Bug 2479 +# Bug#2479 dependant subquery with limit crash # CREATE TABLE `t1` ( @@ -1090,8 +1092,9 @@ select 2 in (select * from t1); SET SQL_SELECT_LIMIT=default; drop table t1; + # -# Bug #3118: subselect + order by +# Bug#3118 subselect + order by # CREATE TABLE t1 (a int, b int, INDEX (a)); @@ -1130,8 +1133,9 @@ insert into t1 values (1); explain select benchmark(1000, (select a from t1 where a=sha(rand()))); drop table t1; + # -# bug 3188 +# Bug#3188 Ambiguous Column in Subselect crashes server # create table t1(id int); create table t2(id int); @@ -1140,8 +1144,9 @@ create table t3(flag int); select (select * from t3 where id not null) from t1, t2; drop table t1,t2,t3; + # -# aggregate functions (Bug #3505) +# aggregate functions (Bug#3505 Wrong results on use of ORDER BY with subqueries) # CREATE TABLE t1 (id INT); CREATE TABLE t2 (id INT); @@ -1332,8 +1337,9 @@ select * from t1 up where exists (select * from t1 where t1.a=up.a); explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a); drop table t1; + # -# Bug #4102: subselect in HAVING +# Bug#4102 subselect in HAVING # CREATE TABLE t1 (t1_a int); @@ -1344,8 +1350,10 @@ SELECT * FROM t1, t2 table2 WHERE t1_a = 1 AND table2.t2_a = 1 HAVING table2.t2_b = (SELECT MAX(t2_b) FROM t2 WHERE t2_a = table2.t2_a); DROP TABLE t1, t2; + # -# Test problem with NULL and derived tables (Bug #4097) +# Test problem with NULL and derived tables +# (Bug#4097 JOIN with subquery causes entire column to report NULL) # CREATE TABLE t1 (id int(11) default NULL,name varchar(10) default NULL); @@ -1355,18 +1363,19 @@ INSERT INTO t2 VALUES (1,'Fido'),(2,'Spot'),(3,'Felix'); SELECT a.*, b.* FROM (SELECT * FROM t1) AS a JOIN t2 as b on a.id=b.id; drop table t1,t2; + # # outer fields resolving in INSERT/REPLACE and CRETE with SELECT # CREATE TABLE t1 ( a int, b int ); CREATE TABLE t2 ( c int, d int ); INSERT INTO t1 VALUES (1,2), (2,3), (3,4); -SELECT a AS abc, b FROM t1 outr WHERE b = +SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a); -INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = +INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a); select * from t2; -CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = +CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a); select * from t3; prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);"; @@ -1390,19 +1399,21 @@ insert into t2 values (1,2); select t000.a, count(*) `C` FROM t1 t000 GROUP BY t000.a HAVING count(*) > ALL (SELECT count(*) FROM t2 t001 WHERE t001.a=1); drop table t1,t2; + # -# BUG#4769 - fulltext in subselect +# Bug#4769 - fulltext in subselect # -create table t1 (a int not null auto_increment primary key, b varchar(40), fulltext(b)); -insert into t1 (b) values ('ball'),('ball games'), ('games'), ('foo'), ('foobar'), ('Serg'), ('Sergei'),('Georg'), ('Patrik'),('Hakan'); -create table t2 (a int); -insert into t2 values (1),(3),(2),(7); -select a,b from t1 where match(b) against ('Ball') > 0; -select a from t2 where a in (select a from t1 where match(b) against ('Ball') > 0); +create table t1 (a int not null auto_increment primary key, b varchar(40), fulltext(b)); +insert into t1 (b) values ('ball'),('ball games'), ('games'), ('foo'), ('foobar'), ('Serg'), ('Sergei'),('Georg'), ('Patrik'),('Hakan'); +create table t2 (a int); +insert into t2 values (1),(3),(2),(7); +select a,b from t1 where match(b) against ('Ball') > 0; +select a from t2 where a in (select a from t1 where match(b) against ('Ball') > 0); drop table t1,t2; + # -# BUG#5003 - like in subselect +# Bug#5003 - like in subselect # CREATE TABLE t1(`IZAVORGANG_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`KUERZEL` VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_bin,`IZAANALYSEART_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`IZAPMKZ_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin); CREATE INDEX AK01IZAVORGANG ON t1(izaAnalyseart_id,Kuerzel); @@ -1459,10 +1470,10 @@ SELECT b.sc FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.s SELECT b.ac FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b; drop tables t1,t2; + # -# Test for bug #6462. "Same request on same data returns different -# results." a.k.a. "Proper cleanup of subqueries is missing for -# SET and DO statements". +# Test for Bug#6462 Same request on same data returns different results +# a.k.a. "Proper cleanup of subqueries is missing for SET and DO statements". # create table t1 (a int not null, b int not null, c int, primary key (a,b)); insert into t1 values (1,1,1), (2,2,2), (3,3,3); @@ -1484,9 +1495,11 @@ drop table t1; connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection root; set @got_val= (SELECT 1 FROM (SELECT 'A' as my_col) as T1 ) ; +connection default; +disconnect root; # -# primary query with temporary table and subquery with groupping +# primary query with temporary table and subquery with grouping # create table t1 (a int, b int); create table t2 (a int, b int); @@ -1547,14 +1560,15 @@ INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,680 INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF'); INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM'); /*!40000 ALTER TABLE t1 ENABLE KEYS */; -SELECT DISTINCT Continent AS c FROM t1 outr WHERE - Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND +SELECT DISTINCT Continent AS c FROM t1 outr WHERE + Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND Population < 200); drop table t1; + # -# Test for BUG#7885: Server crash when 'any' subselect compared to -# non-existant field. +# Test for Bug#7885 Server crash when 'any' subselect compared to +# non-existant field. # create table t1 (a1 int); create table t2 (b1 int); @@ -1603,8 +1617,9 @@ select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx; select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL; drop table t1; + # -# Test for BUG#8218 +# Test for Bug#8218 Join does not pass string from right table # CREATE TABLE t1 ( categoryId int(11) NOT NULL, @@ -1674,38 +1689,39 @@ select count(distinct t2.userid) pass, groupstuff.*, count(t2.courseid) crse, - t1.categoryid, + t1.categoryid, t2.courseid, date_format(date, '%b%y') as colhead -from t2 -join t1 on t2.courseid=t1.courseid +from t2 +join t1 on t2.courseid=t1.courseid join ( - select - t5.userid, - parentid, - parentgroup, - childid, - groupname, - grouptypeid - from t5 - join + select + t5.userid, + parentid, + parentgroup, + childid, + groupname, + grouptypeid + from t5 + join ( - select t4.id as parentid, - t4.name as parentgroup, - t4.id as childid, - t4.name as groupname, - t4.grouptypeid - from t4 - ) as gin on t5.groupid=gin.childid -) as groupstuff on t2.userid = groupstuff.userid -group by + select t4.id as parentid, + t4.name as parentgroup, + t4.id as childid, + t4.name as groupname, + t4.grouptypeid + from t4 + ) as gin on t5.groupid=gin.childid +) as groupstuff on t2.userid = groupstuff.userid +group by groupstuff.groupname, colhead , t2.courseid; drop table t1, t2, t3, t4, t5; + # -# Transformation in left expression of subquery (BUG#8888) +# Transformation in left expression of subquery (Bug#8888) # create table t1 (a int); insert into t1 values (1), (2), (3); @@ -1750,8 +1766,9 @@ select (1,2,3) = (select * from t1); select (select * from t1) = (1,2,3); drop table t1; + # -# Item_int_with_ref check (BUG#10020) +# Item_int_with_ref check (Bug#10020) # CREATE TABLE `t1` ( `itemid` bigint(20) unsigned NOT NULL auto_increment, @@ -1774,15 +1791,16 @@ INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1'); SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30; drop tables t1,t2; -# BUG#11821 : Select from subselect using aggregate function on an enum -# segfaults: + +# Bug#11821 Select from subselect using aggregate function on an enum segfaults create table t1 (fld enum('0','1')); insert into t1 values ('1'); select * from (select max(fld) from t1) as foo; drop table t1; + # -# Bug #11867: queries with ROW(,elems>) IN (SELECT DISTINCT FROM ...) +# Bug#11867 queries with ROW(,elems>) IN (SELECT DISTINCT FROM ...) # CREATE TABLE t1 (one int, two int, flag char(1)); @@ -1812,8 +1830,9 @@ explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FR explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1; DROP TABLE t1,t2; + # -# Bug #12392: where cond with IN predicate for rows and NULL values in table +# Bug#12392 where cond with IN predicate for rows and NULL values in table # CREATE TABLE t1 (a char(5), b char(5)); @@ -1823,8 +1842,9 @@ SELECT * FROM t1 WHERE (a,b) IN (('aaa','aaa'), ('aaa','bbb')); DROP TABLE t1; + # -# Bug #11479: subquery over left join with an empty inner table +# Bug#11479 subquery over left join with an empty inner table # CREATE TABLE t1 (a int); @@ -1841,9 +1861,10 @@ SELECT * FROM t1 DROP TABLE t1,t2,t3; + # -# Bug#18503: Queries with a quantified subquery returning empty set may -# return a wrong result. +# Bug#18503 Queries with a quantified subquery returning empty set may +# return a wrong result. # CREATE TABLE t1 (f1 INT); CREATE TABLE t2 (f2 INT); @@ -1855,8 +1876,9 @@ INSERT INTO t2 VALUES (2); SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE f2=0); DROP TABLE t1, t2; + # -# Bug#16302: Quantified subquery without any tables gives wrong results +# Bug#16302 Quantified subquery without any tables gives wrong results # select 1 from dual where 1 < any (select 2); select 1 from dual where 1 < all (select 2); @@ -1865,7 +1887,8 @@ select 1 from dual where 2 > all (select 1); select 1 from dual where 1 < any (select 2 from dual); select 1 from dual where 1 < all (select 2 from dual where 1!=1); -# BUG#20975 Wrong query results for subqueries within NOT + +# Bug#20975 Wrong query results for subqueries within NOT create table t1 (s1 char); insert into t1 values (1),(2); @@ -1882,8 +1905,9 @@ select * from t1 where (s1 = ALL (select s1/s1 from t1)); select * from t1 where NOT(s1 = ALL (select s1/s1 from t1)); drop table t1; + # -# Bug #16255: Subquery in where +# Bug#16255 Subquery in where # create table t1 ( retailerID varchar(8) NOT NULL, @@ -1899,15 +1923,16 @@ INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53"); INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50"); INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50"); -select * from t1 r1 - where (r1.retailerID,(r1.changed)) in - (SELECT r2.retailerId,(max(changed)) from t1 r2 +select * from t1 r1 + where (r1.retailerID,(r1.changed)) in + (SELECT r2.retailerId,(max(changed)) from t1 r2 group by r2.retailerId); drop table t1; + # -# Bug #21180: Subselect with index for both WHERE and ORDER BY -# produces empty result +# Bug#21180 Subselect with index for both WHERE and ORDER BY +# produces empty result # create table t1(a int, primary key (a)); insert into t1 values (10); @@ -1915,38 +1940,39 @@ insert into t1 values (10); create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); -explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r - ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' +explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r + ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; -SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r - ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' +SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r + ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; -explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r - ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' +explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r + ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; -SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r - ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' +SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r + ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; drop table t1,t2; + # -# Bug #21853: assert failure for a grouping query with -# an ALL/ANY quantified subquery in HAVING +# Bug#21853 assert failure for a grouping query with +# an ALL/ANY quantified subquery in HAVING # -CREATE TABLE t1 ( - field1 int NOT NULL, - field2 int NOT NULL, - field3 int NOT NULL, - PRIMARY KEY (field1,field2,field3) +CREATE TABLE t1 ( + field1 int NOT NULL, + field2 int NOT NULL, + field3 int NOT NULL, + PRIMARY KEY (field1,field2,field3) +); +CREATE TABLE t2 ( + fieldA int NOT NULL, + fieldB int NOT NULL, + PRIMARY KEY (fieldA,fieldB) ); -CREATE TABLE t2 ( - fieldA int NOT NULL, - fieldB int NOT NULL, - PRIMARY KEY (fieldA,fieldB) -); INSERT INTO t1 VALUES (1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1); @@ -1958,19 +1984,20 @@ SELECT field1, field2, COUNT(*) SELECT field1, field2 FROM t1 GROUP BY field1, field2 - HAVING COUNT(*) >= ALL (SELECT fieldB + HAVING COUNT(*) >= ALL (SELECT fieldB FROM t2 WHERE fieldA = field1); SELECT field1, field2 FROM t1 GROUP BY field1, field2 - HAVING COUNT(*) < ANY (SELECT fieldB + HAVING COUNT(*) < ANY (SELECT fieldB FROM t2 WHERE fieldA = field1); DROP TABLE t1, t2; + # -# Bug #23478: not top-level IN subquery returning a non-empty result set -# with possible NULL values by index access from the outer query +# Bug#23478 not top-level IN subquery returning a non-empty result set +# with possible NULL values by index access from the outer query # CREATE TABLE t1(a int, INDEX (a)); @@ -1985,24 +2012,26 @@ SELECT a, a IN (SELECT a FROM t1) FROM t2; DROP TABLE t1,t2; + # -# Bug #11302: getObject() returns a String for a sub-query of type datetime +# Bug#11302 getObject() returns a String for a sub-query of type datetime # CREATE TABLE t1 (a DATETIME); INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25'); -CREATE TABLE t2 AS SELECT - (SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a +CREATE TABLE t2 AS SELECT + (SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a FROM t1 WHERE a > '2000-01-01'; SHOW CREATE TABLE t2; -CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01'); +CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01'); SHOW CREATE TABLE t3; DROP TABLE t1,t2,t3; + # -# Bug 24670: subquery witout tables but with a WHERE clause +# Bug24670 subquery witout tables but with a WHERE clause # CREATE TABLE t1 (a int); @@ -2014,9 +2043,10 @@ EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL; DROP TABLE t1; + # -# Bug 24653: sorting by expressions containing subselects -# that return more than one row +# Bug#24653 sorting by expressions containing subselects +# that return more than one row # CREATE TABLE t1 (a int); @@ -2099,8 +2129,9 @@ select * from t1; select min(a) from t1 group by grp; drop table t1; + # -# Test for bug #9338: lame substitution of c1 instead of c2 +# Test for Bug#9338 lame substitution of c1 instead of c2 # CREATE table t1 ( c1 integer ); @@ -2120,15 +2151,16 @@ SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2 DROP TABLE t1,t2; + # -# Test for bug #9516: wrong evaluation of not_null_tables attribute in SQ +# Test for Bug#9516 wrong evaluation of not_null_tables attribute in SQ # CREATE TABLE t1 ( c1 integer ); INSERT INTO t1 VALUES ( 1 ); INSERT INTO t1 VALUES ( 2 ); INSERT INTO t1 VALUES ( 3 ); -INSERT INTO t1 VALUES ( 6 ); - +INSERT INTO t1 VALUES ( 6 ); + CREATE TABLE t2 ( c2 integer ); INSERT INTO t2 VALUES ( 1 ); INSERT INTO t2 VALUES ( 4 ); @@ -2139,13 +2171,14 @@ CREATE TABLE t3 ( c3 integer ); INSERT INTO t3 VALUES ( 7 ); INSERT INTO t3 VALUES ( 8 ); -SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2 +SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2 WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL ); DROP TABLE t1,t2,t3; + # -# Item_int_with_ref check (BUG#10020) +# Item_int_with_ref check (Bug#10020) # CREATE TABLE `t1` ( `itemid` bigint(20) unsigned NOT NULL auto_increment, @@ -2168,9 +2201,10 @@ INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1'); SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30; drop tables t1,t2; + # # Correct building of equal fields list (do not include outer -# fields) (BUG#6384) +# fields) (Bug#6384) # CREATE TABLE t1 (EMPNUM CHAR(3)); CREATE TABLE t2 (EMPNUM CHAR(3) ); @@ -2184,44 +2218,46 @@ WHERE t1.EMPNUM NOT IN select * from t1; DROP TABLE t1,t2; + # -# Test for bug #11487: range access in a subquery +# Test for Bug#11487 range access in a subquery # CREATE TABLE t1(select_id BIGINT, values_id BIGINT); INSERT INTO t1 VALUES (1, 1); -CREATE TABLE t2 (select_id BIGINT, values_id BIGINT, +CREATE TABLE t2 (select_id BIGINT, values_id BIGINT, PRIMARY KEY(select_id,values_id)); INSERT INTO t2 VALUES (0, 1), (0, 2), (0, 3), (1, 5); -SELECT values_id FROM t1 +SELECT values_id FROM t1 WHERE values_id IN (SELECT values_id FROM t2 WHERE select_id IN (1, 0)); -SELECT values_id FROM t1 +SELECT values_id FROM t1 WHERE values_id IN (SELECT values_id FROM t2 WHERE select_id BETWEEN 0 AND 1); -SELECT values_id FROM t1 +SELECT values_id FROM t1 WHERE values_id IN (SELECT values_id FROM t2 WHERE select_id = 0 OR select_id = 1); DROP TABLE t1, t2; -# BUG#11821 : Select from subselect using aggregate function on an enum -# segfaults: + +# Bug#11821 Select from subselect using aggregate function on an enum segfaults create table t1 (fld enum('0','1')); insert into t1 values ('1'); select * from (select max(fld) from t1) as foo; drop table t1; + # -# Test for bug #11762: subquery with an aggregate function in HAVING +# Test for Bug#11762 subquery with an aggregate function in HAVING # CREATE TABLE t1 (a int, b int); CREATE TABLE t2 (c int, d int); CREATE TABLE t3 (e int); -INSERT INTO t1 VALUES +INSERT INTO t1 VALUES (1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40); INSERT INTO t2 VALUES (2,10), (2,20), (4,10), (5,10), (3,20), (2,40); @@ -2251,7 +2287,7 @@ SELECT a FROM t1 GROUP BY a WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e < d)); SELECT a FROM t1 GROUP BY a HAVING a IN (SELECT c FROM t2 - WHERE MIN(b) < d AND + WHERE MIN(b) < d AND EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d)); SELECT a, SUM(a) FROM t1 GROUP BY a; @@ -2279,9 +2315,9 @@ SELECT t1.a FROM t1 GROUP BY t1.a -- error ER_INVALID_GROUP_FUNC_USE SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a > ALL(SELECT t2.c FROM t2 - WHERE EXISTS(SELECT t3.e FROM t3 + WHERE EXISTS(SELECT t3.e FROM t3 WHERE SUM(t1.a+t2.c) < t3.e/4)); --- error ER_INVALID_GROUP_FUNC_USE +-- error ER_INVALID_GROUP_FUNC_USE SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20; SELECT t1.a FROM t1 GROUP BY t1.a @@ -2297,9 +2333,10 @@ SELECT t1.a, SUM(b) AS sum FROM t1 GROUP BY t1.a DROP TABLE t1,t2,t3; + # -# Test for bug #16603: GROUP BY in a row subquery with a quantifier -# when an index is defined on the grouping field +# Test for Bug#16603 GROUP BY in a row subquery with a quantifier +# when an index is defined on the grouping field CREATE TABLE t1 (a varchar(5), b varchar(10)); INSERT INTO t1 VALUES @@ -2318,27 +2355,30 @@ SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a); DROP TABLE t1; + # -# Bug#17366: Unchecked Item_int results in server crash +# Bug#17366 Unchecked Item_int results in server crash # create table t1( f1 int,f2 int); insert into t1 values (1,1),(2,2); select tt.t from (select 'crash1' as t, f2 from t1) as tt left join t1 on tt.t = 'crash2' and tt.f2 = t1.f2 where tt.t = 'crash1'; drop table t1; + # -# Bug #18306: server crash on delete using subquery. +# Bug#18306 server crash on delete using subquery. # -create table t1 (c int, key(c)); +create table t1 (c int, key(c)); insert into t1 values (1142477582), (1142455969); create table t2 (a int, b int); insert into t2 values (2, 1), (1, 0); delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1; drop table t1, t2; + # -# Bug #7549: Missing error message for invalid view selection with subquery +# Bug#7549 Missing error message for invalid view selection with subquery # CREATE TABLE t1 (a INT); @@ -2352,16 +2392,18 @@ SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1); DROP TABLE t1; + # -# Bug#19077: A nested materialized derived table is used before being populated. +# Bug#19077 A nested materialized derived table is used before being populated. # create table t1 (i int, j bigint); insert into t1 values (1, 2), (2, 2), (3, 2); select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3; drop table t1; -# -# Bug#19700: subselect returning BIGINT always returned it as SIGNED + +# +# Bug#19700 subselect returning BIGINT always returned it as SIGNED # CREATE TABLE t1 (i BIGINT UNSIGNED); INSERT INTO t1 VALUES (10000000000000000000); # > MAX SIGNED BIGINT 9323372036854775807 @@ -2383,8 +2425,9 @@ SELECT t1.i FROM t1 WHERE t1.i = CAST((SELECT MAX(i) FROM t2) AS UNSIGNED); DROP TABLE t1; DROP TABLE t2; -# -# Bug#20519: subselect with LIMIT M, N + +# +# Bug#20519 subselect with LIMIT M, N # CREATE TABLE t1 ( @@ -2401,7 +2444,7 @@ CREATE TABLE t2 ( date date NOT NULL, PRIMARY KEY (id) ); -INSERT INTO t2 VALUES +INSERT INTO t2 VALUES (1, 1, '2006-03-30'), (2, 2, '2006-04-06'), (3, 3, '2006-04-13'), (4, 2, '2006-04-20'), (5, 1, '2006-05-01'); @@ -2423,8 +2466,9 @@ SELECT *, FROM t1; DROP TABLE t1,t2; + # -# Bug#20869: subselect with range access by DESC +# Bug#20869 subselect with range access by DESC # CREATE TABLE t1 ( @@ -2433,7 +2477,7 @@ CREATE TABLE t1 ( t datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (i1,i2,t) ); -INSERT INTO t1 VALUES +INSERT INTO t1 VALUES (24,1,'2005-03-03 16:31:31'),(24,1,'2005-05-27 12:40:07'), (24,1,'2005-05-27 12:40:08'),(24,1,'2005-05-27 12:40:10'), (24,1,'2005-05-27 12:40:25'),(24,1,'2005-05-27 12:40:30'), @@ -2451,34 +2495,34 @@ INSERT INTO t2 VALUES (24,1,'2006-06-20 12:29:40'); EXPLAIN SELECT * FROM t1,t2 - WHERE t1.t = (SELECT t1.t FROM t1 + WHERE t1.t = (SELECT t1.t FROM t1 WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1 ORDER BY t1.t DESC LIMIT 1); SELECT * FROM t1,t2 - WHERE t1.t = (SELECT t1.t FROM t1 + WHERE t1.t = (SELECT t1.t FROM t1 WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1 ORDER BY t1.t DESC LIMIT 1); DROP TABLE t1, t2; + # -# Bug#14654 : Cannot select from the same table twice within a UNION -# statement +# Bug#14654 Cannot select from the same table twice within a UNION statement # CREATE TABLE t1 (i INT); (SELECT i FROM t1) UNION (SELECT i FROM t1); #TODO:not supported --error ER_PARSE_ERROR -SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS +SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS ( - (SELECT i FROM t1) UNION + (SELECT i FROM t1) UNION (SELECT i FROM t1) ); #TODO:not supported --error ER_PARSE_ERROR -SELECT * FROM t1 +SELECT * FROM t1 WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); #TODO:not supported @@ -2488,14 +2532,15 @@ explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12)) #TODO:not supported --error ER_PARSE_ERROR -explain select * from t1 where not exists +explain select * from t1 where not exists ((select t11.i from t1 t11) union (select t12.i from t1 t12)); DROP TABLE t1; + # -# Bug#21798: memory leak during query execution with subquery in column -# list using a function +# Bug#21798 memory leak during query execution with subquery in column +# list using a function # CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b)); insert into t1 (a) values (FLOOR(rand() * 100)); @@ -2513,14 +2558,15 @@ insert into t1 (a) select FLOOR(rand() * 100) from t1; insert into t1 (a) select FLOOR(rand() * 100) from t1; insert into t1 (a) select FLOOR(rand() * 100) from t1; -SELECT a, - (SELECT REPEAT(' ',250) FROM t1 i1 - WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a +SELECT a, + (SELECT REPEAT(' ',250) FROM t1 i1 + WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a FROM t1 ORDER BY a LIMIT 5; DROP TABLE t1; + # -# Bug #21540: Subqueries with no from and aggregate functions return +# Bug#21540 Subqueries with no from and aggregate functions return # wrong results CREATE TABLE t1 (a INT, b INT); CREATE TABLE t2 (a INT); @@ -2530,29 +2576,30 @@ SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a; SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3) FROM t1 GROUP BY t1.a; SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a; -SELECT COUNT(DISTINCT t1.b), +SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3) FROM t1 GROUP BY t1.a; SELECT ( SELECT ( SELECT COUNT(DISTINCT t1.b) ) -) +) FROM t1 GROUP BY t1.a; SELECT ( SELECT ( SELECT ( SELECT COUNT(DISTINCT t1.b) ) - ) - FROM t1 GROUP BY t1.a LIMIT 1) + ) + FROM t1 GROUP BY t1.a LIMIT 1) FROM t1 t2 GROUP BY t2.a; -DROP TABLE t1,t2; +DROP TABLE t1,t2; + # -# Bug #21727: Correlated subquery that requires filesort: -# slow with big sort_buffer_size +# Bug#21727 Correlated subquery that requires filesort: +# slow with big sort_buffer_size # CREATE TABLE t1 (a int, b int auto_increment, PRIMARY KEY (b)); @@ -2570,26 +2617,27 @@ while ($1) { eval INSERT INTO t2(y,z) VALUES(@id,RAND()*1000); dec $2; - } + } dec $1; } enable_query_log; SET SESSION sort_buffer_size = 32 * 1024; -SELECT SQL_NO_CACHE COUNT(*) +SELECT SQL_NO_CACHE COUNT(*) FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c FROM t1) t; SET SESSION sort_buffer_size = 8 * 1024 * 1024; -SELECT SQL_NO_CACHE COUNT(*) +SELECT SQL_NO_CACHE COUNT(*) FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c FROM t1) t; DROP TABLE t1,t2; + # -# Bug #25219: EXIST subquery with UNION over a mix of -# correlated and uncorrelated selects +# Bug#25219 EXIST subquery with UNION over a mix of +# correlated and uncorrelated selects # CREATE TABLE t1 (id char(4) PRIMARY KEY, c int); @@ -2621,10 +2669,11 @@ SELECT * FROM t1 DROP TABLE t1,t2,t3; -# -# Bug#23800: Outer fields in correlated subqueries is used in a temporary -# table created for sorting. -# + +# +# Bug#23800 Outer fields in correlated subqueries is used in a temporary +# table created for sorting. +# CREATE TABLE t1(f1 int); CREATE TABLE t2(f2 int, f21 int, f3 timestamp); INSERT INTO t1 VALUES (1),(1),(2),(2); @@ -2635,19 +2684,20 @@ PREPARE stmt1 FROM 'SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1) EXECUTE stmt1; EXECUTE stmt1; DEALLOCATE PREPARE stmt1; -SELECT f2, AVG(f21), +SELECT f2, AVG(f21), (SELECT t.f3 FROM t2 AS t WHERE t2.f2=t.f2 AND t.f3=MAX(t2.f3)) AS test FROM t2 GROUP BY f2; -DROP TABLE t1,t2; -CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL); -INSERT INTO t1 VALUES - (1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'), - (2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'), - (3,2,'k'), (3,1,'l'), (1,9,'m'); -SELECT a, MAX(b), - (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test - FROM t1 GROUP BY a; -DROP TABLE t1; +DROP TABLE t1,t2; +CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL); +INSERT INTO t1 VALUES + (1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'), + (2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'), + (3,2,'k'), (3,1,'l'), (1,9,'m'); +SELECT a, MAX(b), + (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test + FROM t1 GROUP BY a; +DROP TABLE t1; + # # Bug#21904 (parser problem when using IN with a double "(())") @@ -2748,21 +2798,23 @@ DROP TABLE t1; DROP TABLE t2; DROP TABLE t1xt2; + +# +# Bug#26728 derived table with concatanation of literals in select list # -# Bug #26728: derived table with concatanation of literals in select list -# CREATE TABLE t1 (a int); -INSERT INTO t1 VALUES (3), (1), (2); +INSERT INTO t1 VALUES (3), (1), (2); SELECT 'this is ' 'a test.' AS col1, a AS col2 FROM t1; SELECT * FROM (SELECT 'this is ' 'a test.' AS col1, a AS t2 FROM t1) t; DROP table t1; + +# +# Bug#27257 COUNT(*) aggregated in outer query # -# Bug #27257: COUNT(*) aggregated in outer query -# CREATE TABLE t1 (a int, b int); CREATE TABLE t2 (m int, n int); @@ -2777,15 +2829,16 @@ SELECT COUNT(*), a, (SELECT MIN(m) FROM t2 WHERE m = count(*)) FROM t1 GROUP BY a; -SELECT COUNT(*), a +SELECT COUNT(*), a FROM t1 GROUP BY a HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1; DROP TABLE t1,t2; + +# +# Bug#27229 GROUP_CONCAT in subselect with COUNT() as an argument # -# Bug #27229: GROUP_CONCAT in subselect with COUNT() as an argument -# CREATE TABLE t1 (a int, b int); CREATE TABLE t2 (m int, n int); @@ -2802,8 +2855,9 @@ SELECT COUNT(*) c, a, DROP table t1,t2; + # -# Bug#27321: Wrong subquery result in a grouping select +# Bug#27321 Wrong subquery result in a grouping select # CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b)); INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'), @@ -2811,7 +2865,7 @@ INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'), (3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p'); SELECT a, MAX(b), - (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test + (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test FROM t1 GROUP BY a; SELECT a x, MAX(b), (SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test @@ -2822,25 +2876,27 @@ SELECT a, AVG(b), SELECT tt.a, (SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) - LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test + LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test FROM t1 as tt; SELECT tt.a, (SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) LIMIT 1) - FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test + FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test FROM t1 as tt GROUP BY tt.a; SELECT tt.a, MAX( (SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) LIMIT 1) - FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test + FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test FROM t1 as tt GROUP BY tt.a; DROP TABLE t1; + + +# +# Bug#27348 SET FUNCTION used in a subquery from WHERE condition # -# Bug #27348: SET FUNCTION used in a subquery from WHERE condition -# CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (2,22),(1,11),(2,22); @@ -2865,9 +2921,9 @@ SET @@sql_mode=default; DROP TABLE t1; + # -# Bug #27363: nested aggregates in outer, subquery / sum(select -# count(outer)) +# Bug#27363 nested aggregates in outer, subquery / sum(select count(outer)) # CREATE TABLE t1 (a INT); INSERT INTO t1 values (1),(1),(1),(1); CREATE TABLE t2 (x INT); INSERT INTO t1 values (1000),(1001),(1002); @@ -2882,28 +2938,30 @@ SELECT COUNT(1) FROM DUAL; SELECT SUM( (SELECT AVG( (SELECT t1.a FROM t2) ) FROM DUAL) ) FROM t1; --error ER_INVALID_GROUP_FUNC_USE -SELECT +SELECT SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING t1.a < 12) ) FROM t2) ) FROM t1; --error ER_INVALID_GROUP_FUNC_USE -SELECT t1.a as XXA, +SELECT t1.a as XXA, SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) ) FROM t1; DROP TABLE t1,t2; + +# +# Bug#27807 Server crash when executing subquery with EXPLAIN # -# Bug #27807: Server crash when executing subquery with EXPLAIN -# -CREATE TABLE t1 (a int, b int, KEY (a)); +CREATE TABLE t1 (a int, b int, KEY (a)); INSERT INTO t1 VALUES (1,1),(2,1); EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b); DROP TABLE t1; + +# +# Bug#28377 grouping query with a correlated subquery in WHERE condition # -# Bug #28377: grouping query with a correlated subquery in WHERE condition -# CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id)); INSERT INTO t1 VALUES @@ -2911,24 +2969,25 @@ INSERT INTO t1 VALUES CREATE TABLE t2 (id int NOT NULL, INDEX idx(id)); INSERT INTO t2 VALUES (7), (5), (1), (3); -SELECT id, st FROM t1 +SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id); -SELECT id, st FROM t1 +SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id) GROUP BY id; -SELECT id, st FROM t1 +SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id); -SELECT id, st FROM t1 +SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id) GROUP BY id; DROP TABLE t1,t2; + +# +# Bug#28728 crash with EXPLAIN EXTENDED for a query with a derived table +# over a grouping subselect # -# Bug #28728: crash with EXPLAIN EXTENDED for a query with a derived table -# over a grouping subselect -# CREATE TABLE t1 (a int); @@ -2939,10 +2998,11 @@ SELECT * FROM (SELECT count(*) FROM t1 GROUP BY a) as res; DROP TABLE t1; + # -# Bug #28811: crash for query containing subquery with ORDER BY and LIMIT 1 +# Bug#28811 crash for query containing subquery with ORDER BY and LIMIT 1 # - + CREATE TABLE t1 ( a varchar(255) default NULL, b timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, @@ -2973,8 +3033,8 @@ DROP TABLE t1,t2; # -# Bug #27333: subquery grouped for aggregate of outer query / no aggregate -# of subquery +# Bug#27333 subquery grouped for aggregate of outer query / no aggregate +# of subquery # CREATE TABLE t1 (a INTEGER, b INTEGER); CREATE TABLE t2 (x INTEGER); @@ -3013,8 +3073,9 @@ SELECT (SELECT SUM(t1.a) FROM t2 WHERE a!=0) FROM t1; SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=1) FROM t1; DROP TABLE t1,t2; + # -# Bug31048: Many nested subqueries may cause server crash. +# Bug31048 Many nested subqueries may cause server crash. # create table t1(a int,b int,key(a),key(b)); insert into t1(a,b) values (1,2),(2,1),(2,3),(3,4),(5,4),(5,5), @@ -3059,8 +3120,9 @@ while ($nesting) --enable_query_log drop table t1; + # -# Bug #31884: Assertion + crash in subquery in the SELECT clause. +# Bug#31884 Assertion + crash in subquery in the SELECT clause. # CREATE TABLE t1 (a1 INT, a2 INT); @@ -3075,7 +3137,7 @@ SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1; DROP TABLE t1, t2; # -# Bug #28076: inconsistent binary/varbinary comparison +# Bug#28076 inconsistent binary/varbinary comparison # CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5)); @@ -3116,8 +3178,9 @@ SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3; SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3); DROP TABLE t1, t2, t3; + # -# Bug #30788: Inconsistent retrieval of char/varchar +# Bug#30788 Inconsistent retrieval of char/varchar # CREATE TABLE t1 (a CHAR(1), b VARCHAR(10)); @@ -3141,16 +3204,16 @@ SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); DROP TABLE t1,t2; + # -# Bug #32400: Complex SELECT query returns correct result only on some -# occasions +# Bug#32400 Complex SELECT query returns correct result only on some occasions # CREATE TABLE t1(a INT, b INT); INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4); --error ER_BAD_FIELD_ERROR -EXPLAIN +EXPLAIN SELECT a AS out_a, MIN(b) FROM t1 WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a) GROUP BY a; @@ -3160,7 +3223,7 @@ SELECT a AS out_a, MIN(b) FROM t1 WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a) GROUP BY a; -EXPLAIN +EXPLAIN SELECT a AS out_a, MIN(b) FROM t1 t1_outer WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a) GROUP BY a; @@ -3171,8 +3234,9 @@ GROUP BY a; DROP TABLE t1; + # -# Bug #32036: EXISTS within a WHERE clause with a UNION crashes MySQL 5.122 +# Bug#32036 EXISTS within a WHERE clause with a UNION crashes MySQL 5.122 # CREATE TABLE t1 (a INT); @@ -3189,15 +3253,15 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); #TODO:not supported --error ER_PARSE_ERROR EXPLAIN EXTENDED -SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION +SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION (SELECT 1 FROM t2 WHERE t1.a = t2.a)); DROP TABLE t1,t2; # -# Bug#33675: Usage of an uninitialized memory by filesort in a subquery -# caused server crash. +# Bug#33675 Usage of an uninitialized memory by filesort in a subquery +# caused server crash. # create table t1(f11 int, f12 int); create table t2(f21 int unsigned not null, f22 int, f23 varchar(10)); @@ -3213,13 +3277,14 @@ while ($i) --enable_warnings --enable_query_log set session sort_buffer_size= 33*1024; -select count(*) from t1 where f12 = +select count(*) from t1 where f12 = (select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1); drop table t1,t2; + # -# BUG#33794 "MySQL crashes executing specific query on specific dump" +# Bug#33794 "MySQL crashes executing specific query on specific dump" # CREATE TABLE t4 ( f7 varchar(32) collate utf8_bin NOT NULL default '', @@ -3261,32 +3326,34 @@ SELECT FROM t2 VPC, t4 a2, t2 a3 WHERE VPC.f4 = a2.f10 AND a3.f2 = a4 - LIMIT 1) IS NULL, - 0, + LIMIT 1) IS NULL, + 0, t3.f5 ) ) AS a6 -FROM +FROM t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4 GROUP BY a4; DROP TABLE t1, t2, t3, t4; + # -# BUG#36139 "float, zerofill, crash with subquery" +# Bug#36139 "float, zerofill, crash with subquery" # create table t1 (a float(5,4) zerofill); create table t2 (a float(5,4),b float(2,0)); -select t1.a from t1 where +select t1.a from t1 where t1.a= (select b from t2 limit 1) and not t1.a= (select a from t2 limit 1) ; drop table t1, t2; + # -# Bug #36011: Server crash with explain extended on query with dependent -# subqueries +# Bug#36011 Server crash with explain extended on query with dependent +# subqueries # CREATE TABLE t1 (a INT); @@ -3295,8 +3362,9 @@ EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 GROUP BY a); EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a); DROP TABLE t1; + # -# Bug #38191: Server crash with subquery containing DISTINCT and ORDER BY +# Bug#38191 Server crash with subquery containing DISTINCT and ORDER BY # CREATE TABLE t1(pk int PRIMARY KEY, a int, INDEX idx(a)); @@ -3307,6 +3375,7 @@ SELECT * FROM t1 WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b); DROP TABLE t1,t2; + # # Bug#20835 (literal string with =any values) # @@ -3315,6 +3384,7 @@ INSERT INTO t1 VALUES ('a'); SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1); DROP TABLE t1; + # # Bug#40519 Subselect query using bigint fails # @@ -3325,6 +3395,7 @@ INSERT INTO t2 VALUES (2,1),(3,1); SELECT * FROM t1 i WHERE 1 IN (SELECT l.id2 FROM t2 l WHERE i.id=l.id1); DROP TABLE t1, t2; + # # Bug#37460 Assertion failed: # !table->file || table->file->inited == handler::NONE @@ -3346,7 +3417,7 @@ CREATE VIEW v2 (a,b) AS SELECT t2.id, t2.c AS c FROM t1, t2 WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION; ---error 1369 +--error ER_VIEW_CHECK_FAILED INSERT INTO v2(a,b) VALUES (2,2); INSERT INTO v2(a,b) VALUES (1,2); SELECT * FROM v1; diff --git a/mysql-test/t/synchronization.test b/mysql-test/t/synchronization.test index c7696195ee0..aef06245717 100644 --- a/mysql-test/t/synchronization.test +++ b/mysql-test/t/synchronization.test @@ -1,10 +1,13 @@ +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + # -# Test for Bug #2385 CREATE TABLE LIKE lacks locking on source and destination -# table +# Test for Bug#2385 CREATE TABLE LIKE lacks locking on source and destination +# table # --disable_warnings -drop table if exists t1; +DROP TABLE IF EXISTS t1,t2; --enable_warnings connect (con1,localhost,root,,); @@ -12,12 +15,12 @@ connect (con2,localhost,root,,); # locking of source: -CREATE TABLE t1 (x1 int); +CREATE TABLE t1 (x1 INT); let $1= 10; while ($1) { connection con1; - send ALTER TABLE t1 CHANGE x1 x2 int; + send ALTER TABLE t1 CHANGE x1 x2 INT; connection con2; CREATE TABLE t2 LIKE t1; replace_result x1 xx x2 xx; @@ -25,7 +28,7 @@ while ($1) DROP TABLE t2; connection con1; reap; - send ALTER TABLE t1 CHANGE x2 x1 int; + send ALTER TABLE t1 CHANGE x2 x1 INT; connection con2; CREATE TABLE t2 LIKE t1; replace_result x1 xx x2 xx; @@ -37,4 +40,11 @@ while ($1) } DROP TABLE t1; +connection default; +disconnect con1; +disconnect con2; + # End of 4.1 tests + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/timezone_grant.test b/mysql-test/t/timezone_grant.test index 450c1edc47e..8013f2b04ce 100644 --- a/mysql-test/t/timezone_grant.test +++ b/mysql-test/t/timezone_grant.test @@ -1,15 +1,18 @@ # Embedded server testing does not support grants -- source include/not_embedded.inc +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + --disable_warnings drop tables if exists t1, t2; drop view if exists v1; --enable_warnings # -# Test for bug #6116 "SET time_zone := ... requires access to mysql.time_zone -# tables". We should allow implicit access to time zone description tables -# even for unprivileged users. +# Test for Bug#6116 SET time_zone := ... requires access to mysql.time_zone tables +# We should allow implicit access to time zone description tables even for +# unprivileged users. # # Let us prepare playground @@ -33,18 +36,20 @@ select convert_tz(b, 'Europe/Moscow', 'UTC') from t1; update t1, t2 set t1.b = convert_tz('2004-10-21 19:00:00', 'Europe/Moscow', 'UTC') where t1.a = t2.c and t2.d = (select max(d) from t2); # But still these two statements should not work: ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR select * from mysql.time_zone_name; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR select Name, convert_tz('2004-10-21 19:00:00', Name, 'UTC') from mysql.time_zone_name; +connection default; +disconnect tzuser; + # -# Test for bug #6765 "Implicit access to time zone description tables -# requires privileges for them if some table or column level grants -# present" +# Bug#6765 Implicit access to time zone description tables requires privileges +# for them if some table or column level grants present # connection default; -# Let use some table-level grants instead of db-level +# Let use some table-level grants instead of db-level # to make life more interesting delete from mysql.db where user like 'mysqltest\_%'; flush privileges; @@ -61,14 +66,14 @@ select convert_tz(b, 'Europe/Moscow', 'UTC') from t1; update t1, t2 set t1.b = convert_tz('2004-11-30 12:00:00', 'Europe/Moscow', 'UTC') where t1.a = t2.c and t2.d = (select max(d) from t2); # Again these two statements should not work (but with different errors): ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR select * from mysql.time_zone_name; ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR select Name, convert_tz('2004-11-30 12:00:00', Name, 'UTC') from mysql.time_zone_name; # -# Bug #9979: Use of CONVERT_TZ in multiple-table UPDATE causes bogus -# privilege error +# Bug#9979 Use of CONVERT_TZ in multiple-table UPDATE causes bogus +# privilege error # drop table t1, t2; create table t1 (a int, b datetime); @@ -80,6 +85,7 @@ update t1 join t2 on (t1.a = t2.a) set t1.b = convert_tz('2005-01-01 10:00','UTC # Clean-up connection default; +disconnect tzuser2; delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%'; @@ -89,10 +95,9 @@ drop table t1, t2; # End of 4.1 tests # -# Additional test for bug #15153: CONVERT_TZ() is not allowed in all -# places in views. +# Additional test for Bug#15153 CONVERT_TZ() is not allowed in all places in views. # -# Let us check that usage of CONVERT_TZ() function in view does not +# Let us check that usage of CONVERT_TZ() function in view does not # require additional privileges. # Let us rely on that previous tests done proper cleanups @@ -109,7 +114,11 @@ drop view v1; --error ER_TABLEACCESS_DENIED_ERROR create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1, mysql.time_zone; connection default; +disconnect tzuser3; drop table t1; drop user mysqltest_1@localhost; # End of 5.0 tests + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc -- cgit v1.2.1 From d502f4905c51210554a745b41b7e16b7ac23e563 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Fri, 6 Feb 2009 12:51:11 +0300 Subject: Temporarily reverted patch for bug #41868 as it was causing problems in PB. --- client/sql_string.cc | 20 ++++++++++---------- mysql-test/r/func_str.result | 6 ------ mysql-test/t/func_str.test | 9 --------- sql/sql_class.cc | 5 ----- sql/sql_string.cc | 20 ++++++++++---------- 5 files changed, 20 insertions(+), 40 deletions(-) diff --git a/client/sql_string.cc b/client/sql_string.cc index eb80e29ed49..9d887ff031c 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -72,26 +72,26 @@ bool String::realloc(uint32 alloc_length) if (alloced) { if ((new_ptr= (char*) my_realloc(Ptr,len,MYF(MY_WME)))) - new_ptr[alloc_length]= 0; + { + Ptr=new_ptr; + Alloced_length=len; + } else - return TRUE; // Signal error + return TRUE; // Signal error } else if ((new_ptr= (char*) my_malloc(len,MYF(MY_WME)))) { - if (str_length > len - 1) - str_length= 0; if (str_length) // Avoid bugs in memcpy on AIX - memcpy(new_ptr, Ptr, str_length); - new_ptr[str_length]= 0; + memcpy(new_ptr,Ptr,str_length); + new_ptr[str_length]=0; + Ptr=new_ptr; + Alloced_length=len; alloced=1; } else return TRUE; // Signal error - Ptr= new_ptr; - Alloced_length= len; } - else - Ptr[alloc_length]= 0; + Ptr[alloc_length]=0; // This make other funcs shorter return FALSE; } diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index d7fd8c5c887..c121c8937d7 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -2181,10 +2181,4 @@ def format(a, 2) 253 20 4 Y 0 2 8 format(a, 2) 1.33 drop table t1; -CREATE TABLE t1 (c DATE, aa VARCHAR(30)); -INSERT INTO t1 VALUES ('2008-12-31','aaaaaa'); -SELECT DATE_FORMAT(c, GET_FORMAT(DATE, 'eur')) h, CONCAT(UPPER(aa),', ', aa) i FROM t1; -h i -31.12.2008 AAAAAA, aaaaaa -DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 389538c4cc0..8298a50c277 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1159,13 +1159,4 @@ select format(a, 2) from t1; --disable_metadata drop table t1; -# -# Bug #41868: crash or memory overrun with concat + upper, date_format functions -# - -CREATE TABLE t1 (c DATE, aa VARCHAR(30)); -INSERT INTO t1 VALUES ('2008-12-31','aaaaaa'); -SELECT DATE_FORMAT(c, GET_FORMAT(DATE, 'eur')) h, CONCAT(UPPER(aa),', ', aa) i FROM t1; -DROP TABLE t1; - --echo End of 5.0 tests diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9ff602bb62e..91c0aa66761 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1047,11 +1047,6 @@ bool select_send::send_data(List &items) my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); break; } - /* - Reset buffer to its original state, as it may have been altered in - Item::send(). - */ - buffer.set(buff, sizeof(buff), &my_charset_bin); } thd->sent_row_count++; if (!thd->vio_ok()) diff --git a/sql/sql_string.cc b/sql/sql_string.cc index b6ce4d8dc8d..75e47dd0c8e 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -72,26 +72,26 @@ bool String::realloc(uint32 alloc_length) if (alloced) { if ((new_ptr= (char*) my_realloc(Ptr,len,MYF(MY_WME)))) - new_ptr[alloc_length]= 0; + { + Ptr=new_ptr; + Alloced_length=len; + } else - return TRUE; // Signal error + return TRUE; // Signal error } else if ((new_ptr= (char*) my_malloc(len,MYF(MY_WME)))) { - if (str_length > len - 1) - str_length= 0; if (str_length) // Avoid bugs in memcpy on AIX - memcpy(new_ptr, Ptr, str_length); - new_ptr[str_length]= 0; + memcpy(new_ptr,Ptr,str_length); + new_ptr[str_length]=0; + Ptr=new_ptr; + Alloced_length=len; alloced=1; } else return TRUE; // Signal error - Ptr= new_ptr; - Alloced_length= len; } - else - Ptr[alloc_length]= 0; + Ptr[alloc_length]=0; // This make other funcs shorter return FALSE; } -- cgit v1.2.1 From fde1dc7c3d356eb3e53759ce9b7ecd1140605c67 Mon Sep 17 00:00:00 2001 From: Timothy Smith Date: Fri, 6 Feb 2009 15:07:45 +0100 Subject: Handle renamed nwbootstrap -> nwbuild --- netware/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netware/Makefile.am b/netware/Makefile.am index 7ad045d433d..0f11ee85eb0 100644 --- a/netware/Makefile.am +++ b/netware/Makefile.am @@ -90,7 +90,7 @@ EXTRA_DIST= $(BUILT_SOURCES) comp_err.def install_test_db.ncf \ BUILD/compile-netware-standard BUILD/create-patch \ BUILD/cron-build BUILD/crontab BUILD/knetware.imp \ BUILD/mwasmnlm BUILD/mwccnlm BUILD/mwenv BUILD/mwldnlm \ - BUILD/nwbootstrap BUILD/openssl.imp BUILD/save-patch + BUILD/nwbuild BUILD/openssl.imp BUILD/save-patch endif -- cgit v1.2.1 From d7b158e7eabe0458b99c483e306845a6d234d756 Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Fri, 6 Feb 2009 18:25:08 +0100 Subject: Bug#42525: TIMEDIFF function In 37553 we declared longlong results for class Item_str_timefunc as per comments/docs, but didn't add a method for that. And the default just wasn't good enough for some cases. Changeset adds dedicated val_int() to class. mysql-test/r/func_sapdb.result: More tests for casts of TIME() / TIMEDIFF() with negative results. mysql-test/t/func_sapdb.test: More tests for casts of TIME() / TIMEDIFF() with negative results. sql/item_timefunc.h: Since we claim to provide longlong results, we should have a suitable function to provide them (the default won't do). This one matches the val_real() variant. --- mysql-test/r/func_sapdb.result | 14 ++++++++++++++ mysql-test/t/func_sapdb.test | 18 ++++++++++++++++++ sql/item_timefunc.h | 1 + 3 files changed, 33 insertions(+) diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index a06d7004908..3a8515c8831 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -268,3 +268,17 @@ timediff('2008-09-29 20:10:10','2008-09-30 20:10:10') Date: Sat, 7 Feb 2009 05:47:21 +0100 Subject: Raise version number after cloning 5.0.78 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 12c31b33d1b..9591b5bbc5a 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.78) +AM_INIT_AUTOMAKE(mysql, 5.0.79) 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=78 +NDB_VERSION_BUILD=79 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? -- cgit v1.2.1 From 4c07b1e723380354fa6f00f1eb4bbc75805b5fc3 Mon Sep 17 00:00:00 2001 From: Matthias Leich Date: Mon, 9 Feb 2009 21:52:40 +0100 Subject: This belongs to the fix for Bug#42003 tests missing the disconnect of connections <> default second slice Content: 1. wait_until_count_sessions.inc - One PB run of a test using this routine failed because 5 seconds timeout were exceeded. Although I have some doubts if the assigned timeout was really too small, I increase the value to 10. We waste the additional 5 seconds only if the tests fails anyway. - Print the content of the PROCESSLIST if the poll routine fails 2. minor improvements of formatting 3. query_cache_notembedded: Activate the wait_until_count_sessions.inc routine which was unfortunately forgotten in the changeset before. --- mysql-test/include/wait_until_count_sessions.inc | 3 ++- mysql-test/r/information_schema.result | 2 +- mysql-test/r/subselect.result | 2 +- mysql-test/t/grant.test | 5 ++--- mysql-test/t/information_schema.test | 7 ++----- mysql-test/t/query_cache_notembedded.test | 2 +- mysql-test/t/subselect.test | 20 ++++++++++---------- 7 files changed, 19 insertions(+), 22 deletions(-) diff --git a/mysql-test/include/wait_until_count_sessions.inc b/mysql-test/include/wait_until_count_sessions.inc index 36fa9accafe..41348bee129 100644 --- a/mysql-test/include/wait_until_count_sessions.inc +++ b/mysql-test/include/wait_until_count_sessions.inc @@ -82,7 +82,7 @@ # Created: 2009-01-14 mleich # -let $wait_counter= 50; +let $wait_counter= 100; if ($wait_timeout) { let $wait_counter= `SELECT $wait_timeout * 10`; @@ -108,5 +108,6 @@ if (!$success) { --echo # Timeout in wait_until_count_sessions.inc --echo # Number of sessions expected: $count_sessions found: $current_sessions + SHOW PROCESSLIST; } diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 38c8d748870..6ced6bb373a 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1027,7 +1027,7 @@ BEGIN SELECT 'foo' FROM DUAL; END | ERROR 42000: Unknown database 'information_schema' -select ROUTINE_NAME from routines; +select ROUTINE_NAME from routines; ROUTINE_NAME grant all on information_schema.* to 'user1'@'localhost'; ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema' diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 671e5d8f532..0c7f9ae959c 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4407,7 +4407,7 @@ pk a 3 30 2 20 DROP TABLE t1,t2; -CREATE TABLE t1 (s1 char(1)); +CREATE TABLE t1 (s1 CHAR(1)); INSERT INTO t1 VALUES ('a'); SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1); s1 diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index 6f6e8753004..1b2b8465c83 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -204,7 +204,7 @@ show grants for mysqltest_1@localhost; drop user mysqltest_1@localhost; # -# Bug#3403 Wrong encoding in SHOW GRANTS, EPLAIN SELECT output +# Bug#3403 Wrong encoding in SHOW GRANTS, EXPLAIN SELECT output # SET NAMES koi8r; CREATE DATABASE ÂÄ; @@ -384,7 +384,7 @@ update mysqltest_1.t1, mysqltest_1.t2 set a=100,b=200; update mysqltest_2.t1, mysqltest_1.t2 set c=100,b=200; --error ER_TABLEACCESS_DENIED_ERROR update mysqltest_1.t1, mysqltest_2.t2 set a=100,d=200; -#lets see the result +# lets see the result connection master; select t1.*,t2.* from mysqltest_1.t1,mysqltest_1.t2; select t1.*,t2.* from mysqltest_2.t1,mysqltest_2.t2; @@ -784,7 +784,6 @@ SHOW CREATE VIEW mysqltest2.v_yy; # succeed, have SELECT and SHOW VIEW SHOW CREATE TABLE mysqltest2.v_yy; - # clean-up connection master; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 5873347eae0..079f96777bf 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -676,7 +676,7 @@ drop table t1; # # Bug#12636 SHOW TABLE STATUS with where condition containing a subquery -# over information schema +# over information schema # CREATE TABLE t1 (a int); @@ -729,7 +729,7 @@ BEGIN SELECT 'foo' FROM DUAL; END | delimiter ;| -select ROUTINE_NAME from routines; +select ROUTINE_NAME from routines; # # Bug#10734 Grant of privileges other than 'select' and 'create view' should fail on schema # @@ -980,9 +980,6 @@ SELECT COLUMN_NAME, MD5(COLUMN_DEFAULT), LENGTH(COLUMN_DEFAULT), COLUMN_DEFAULT= DROP TABLE bug23037; DROP FUNCTION get_value; - - - # # Bug#22413 EXPLAIN SELECT FROM view with ORDER BY yield server crash # diff --git a/mysql-test/t/query_cache_notembedded.test b/mysql-test/t/query_cache_notembedded.test index b8b223ecd8c..d98ed691c7b 100644 --- a/mysql-test/t/query_cache_notembedded.test +++ b/mysql-test/t/query_cache_notembedded.test @@ -262,4 +262,4 @@ SET GLOBAL query_cache_size= default; # End of 5.0 tests # Wait till we reached the initial number of concurrent sessions -#--source include/wait_until_count_sessions.inc +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 57aaa00e643..26bd7c9e8dd 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -367,7 +367,7 @@ let $wait_condition= SELECT COUNT(*) <> $row_count_before FROM t1; --source include/wait_condition.inc select * from t1; # -#TODO: should be uncommented after bug 380 fix pushed +#TODO: should be uncommented after Bug#380 fix pushed #INSERT INTO t1 (x) SELECT (SELECT SUM(a)+b FROM t2) from t3; #select * from t1; drop table t1, t2, t3; @@ -2031,7 +2031,7 @@ DROP TABLE t1,t2,t3; # -# Bug24670 subquery witout tables but with a WHERE clause +# Bug#24670 subquery witout tables but with a WHERE clause # CREATE TABLE t1 (a int); @@ -2567,7 +2567,7 @@ DROP TABLE t1; # # Bug#21540 Subqueries with no from and aggregate functions return -# wrong results +# wrong results CREATE TABLE t1 (a INT, b INT); CREATE TABLE t2 (a INT); INSERT INTO t2 values (1); @@ -3379,7 +3379,7 @@ DROP TABLE t1,t2; # # Bug#20835 (literal string with =any values) # -CREATE TABLE t1 (s1 char(1)); +CREATE TABLE t1 (s1 CHAR(1)); INSERT INTO t1 VALUES ('a'); SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1); DROP TABLE t1; @@ -3409,13 +3409,13 @@ INSERT INTO t1 (id) VALUES (1); INSERT INTO t2 (id) VALUES (1); CREATE VIEW v1 AS - SELECT t2.c AS c FROM t1, t2 - WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION; +SELECT t2.c AS c FROM t1, t2 +WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION; UPDATE v1 SET c=1; CREATE VIEW v2 (a,b) AS - SELECT t2.id, t2.c AS c FROM t1, t2 - WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION; +SELECT t2.id, t2.c AS c FROM t1, t2 +WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION; --error ER_VIEW_CHECK_FAILED INSERT INTO v2(a,b) VALUES (2,2); @@ -3423,8 +3423,8 @@ INSERT INTO v2(a,b) VALUES (1,2); SELECT * FROM v1; CREATE VIEW v3 AS - SELECT t2.c AS c FROM t2 - WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION; +SELECT t2.c AS c FROM t2 +WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION; DELETE FROM v3; -- cgit v1.2.1 From 574b1e25549a27765e3537e711a38acac47e1d91 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 10 Feb 2009 11:58:19 +0200 Subject: Bug #33813: Schema names are case-sensitive in DROP FUNCTION The parser was not using the correct fully-qualified-name production for DROP FUNCTION. Fixed by copying the production from DROP PROCEDURE. Tested in the windows specific suite to make sure it's tested on a case-insensitive file system. mysql-test/r/windows.result: Bug #33813: test case mysql-test/t/windows.test: Bug #33813: test case sql/sql_yacc.yy: Bug #33813: use the correct production for the name in DROP PROCEDURE --- mysql-test/r/windows.result | 18 ++++++++++++++++++ mysql-test/t/windows.test | 31 +++++++++++++++++++++++++++++++ sql/sql_yacc.yy | 33 +++------------------------------ 3 files changed, 52 insertions(+), 30 deletions(-) diff --git a/mysql-test/r/windows.result b/mysql-test/r/windows.result index 5a54db8bb84..43ba878b9a5 100644 --- a/mysql-test/r/windows.result +++ b/mysql-test/r/windows.result @@ -19,4 +19,22 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used DROP TABLE t1; +CREATE DATABASE `TESTDB`; +USE `TESTDB`; +CREATE FUNCTION test_fn() RETURNS INTEGER +BEGIN +DECLARE rId bigint; +RETURN rId; +END +// +CREATE FUNCTION test_fn2() RETURNS INTEGER +BEGIN +DECLARE rId bigint; +RETURN rId; +END +// +DROP FUNCTION `TESTDB`.`test_fn`; +DROP FUNCTION `testdb`.`test_fn2`; +USE test; +DROP DATABASE `TESTDB`; End of 5.0 tests. diff --git a/mysql-test/t/windows.test b/mysql-test/t/windows.test index 6e6a7ec93a3..adaf8d3ea17 100755 --- a/mysql-test/t/windows.test +++ b/mysql-test/t/windows.test @@ -35,4 +35,35 @@ CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (1,1); EXPLAIN SELECT * FROM t1 WHERE b = (SELECT max(2)); DROP TABLE t1; +# +# Bug #33813: Schema names are case-sensitive in DROP FUNCTION +# + +CREATE DATABASE `TESTDB`; + +USE `TESTDB`; +DELIMITER //; + +CREATE FUNCTION test_fn() RETURNS INTEGER +BEGIN +DECLARE rId bigint; +RETURN rId; +END +// + +CREATE FUNCTION test_fn2() RETURNS INTEGER +BEGIN +DECLARE rId bigint; +RETURN rId; +END +// + +DELIMITER ;// + +DROP FUNCTION `TESTDB`.`test_fn`; +DROP FUNCTION `testdb`.`test_fn2`; + +USE test; +DROP DATABASE `TESTDB`; + --echo End of 5.0 tests. diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0eefe782354..fbaf761cc33 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7507,44 +7507,17 @@ drop: lex->drop_if_exists=$3; lex->name=$4.str; } - | DROP FUNCTION_SYM if_exists ident '.' ident + | DROP FUNCTION_SYM if_exists sp_name { - THD *thd= YYTHD; - LEX *lex= thd->lex; - sp_name *spname; - if (lex->sphead) - { - my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION"); - MYSQL_YYABORT; - } - lex->sql_command = SQLCOM_DROP_FUNCTION; - lex->drop_if_exists= $3; - spname= new sp_name($4, $6, true); - if (spname == NULL) - MYSQL_YYABORT; - spname->init_qname(thd); - lex->spname= spname; - } - | DROP FUNCTION_SYM if_exists ident - { - THD *thd= YYTHD; - LEX *lex= thd->lex; - LEX_STRING db= {0, 0}; - sp_name *spname; + LEX *lex= Lex; if (lex->sphead) { my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION"); MYSQL_YYABORT; } - if (thd->db && lex->copy_db_to(&db.str, &db.length)) - MYSQL_YYABORT; lex->sql_command = SQLCOM_DROP_FUNCTION; lex->drop_if_exists= $3; - spname= new sp_name(db, $4, false); - if (spname == NULL) - MYSQL_YYABORT; - spname->init_qname(thd); - lex->spname= spname; + lex->spname= $4; } | DROP PROCEDURE if_exists sp_name { -- cgit v1.2.1 From 59782a4f0eaed3ebc3e3c3921410239544281ac0 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Tue, 10 Feb 2009 15:38:56 +0300 Subject: Fix for bug #41868: crash or memory overrun with concat + upper, date_format functions String::realloc() did not check whether the existing string data fits in the newly allocated buffer for cases when reallocating a String object with external buffer (i.e.alloced == FALSE). This could lead to memory overruns in some cases. client/sql_string.cc: Fixed String::realloc() to check whether the existing string data fits in the newly allocated buffer for cases when reallocating a String object with external buffer. mysql-test/r/func_str.result: Added a test case for bug #41868. mysql-test/t/func_str.test: Added a test case for bug #41868. sql/sql_class.cc: After each call to Item::send() in select_send::send_data() reset buffer to its original state to reduce unnecessary malloc() calls. See comments for bug #41868 for detailed analysis. sql/sql_string.cc: Fixed String::realloc() to check whether the existing string data fits in the newly allocated buffer for cases when reallocating a String object with external buffer. --- client/sql_string.cc | 15 ++++++--------- mysql-test/r/func_str.result | 6 ++++++ mysql-test/t/func_str.test | 9 +++++++++ sql/sql_class.cc | 5 +++++ sql/sql_string.cc | 15 ++++++--------- 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/client/sql_string.cc b/client/sql_string.cc index 9d887ff031c..fe1fd83a6f6 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -71,25 +71,22 @@ bool String::realloc(uint32 alloc_length) char *new_ptr; if (alloced) { - if ((new_ptr= (char*) my_realloc(Ptr,len,MYF(MY_WME)))) - { - Ptr=new_ptr; - Alloced_length=len; - } - else - return TRUE; // Signal error + if (!(new_ptr= (char*) my_realloc(Ptr,len,MYF(MY_WME)))) + return TRUE; // Signal error } else if ((new_ptr= (char*) my_malloc(len,MYF(MY_WME)))) { + if (str_length > len - 1) + str_length= 0; if (str_length) // Avoid bugs in memcpy on AIX memcpy(new_ptr,Ptr,str_length); new_ptr[str_length]=0; - Ptr=new_ptr; - Alloced_length=len; alloced=1; } else return TRUE; // Signal error + Ptr= new_ptr; + Alloced_length= len; } Ptr[alloc_length]=0; // This make other funcs shorter return FALSE; diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index c121c8937d7..d7fd8c5c887 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -2181,4 +2181,10 @@ def format(a, 2) 253 20 4 Y 0 2 8 format(a, 2) 1.33 drop table t1; +CREATE TABLE t1 (c DATE, aa VARCHAR(30)); +INSERT INTO t1 VALUES ('2008-12-31','aaaaaa'); +SELECT DATE_FORMAT(c, GET_FORMAT(DATE, 'eur')) h, CONCAT(UPPER(aa),', ', aa) i FROM t1; +h i +31.12.2008 AAAAAA, aaaaaa +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 8298a50c277..389538c4cc0 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1159,4 +1159,13 @@ select format(a, 2) from t1; --disable_metadata drop table t1; +# +# Bug #41868: crash or memory overrun with concat + upper, date_format functions +# + +CREATE TABLE t1 (c DATE, aa VARCHAR(30)); +INSERT INTO t1 VALUES ('2008-12-31','aaaaaa'); +SELECT DATE_FORMAT(c, GET_FORMAT(DATE, 'eur')) h, CONCAT(UPPER(aa),', ', aa) i FROM t1; +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 91c0aa66761..9ff602bb62e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1047,6 +1047,11 @@ bool select_send::send_data(List &items) my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); break; } + /* + Reset buffer to its original state, as it may have been altered in + Item::send(). + */ + buffer.set(buff, sizeof(buff), &my_charset_bin); } thd->sent_row_count++; if (!thd->vio_ok()) diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 75e47dd0c8e..ed1dc9eac77 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -71,25 +71,22 @@ bool String::realloc(uint32 alloc_length) char *new_ptr; if (alloced) { - if ((new_ptr= (char*) my_realloc(Ptr,len,MYF(MY_WME)))) - { - Ptr=new_ptr; - Alloced_length=len; - } - else - return TRUE; // Signal error + if (!(new_ptr= (char*) my_realloc(Ptr,len,MYF(MY_WME)))) + return TRUE; // Signal error } else if ((new_ptr= (char*) my_malloc(len,MYF(MY_WME)))) { + if (str_length > len - 1) + str_length= 0; if (str_length) // Avoid bugs in memcpy on AIX memcpy(new_ptr,Ptr,str_length); new_ptr[str_length]=0; - Ptr=new_ptr; - Alloced_length=len; alloced=1; } else return TRUE; // Signal error + Ptr= new_ptr; + Alloced_length= len; } Ptr[alloc_length]=0; // This make other funcs shorter return FALSE; -- cgit v1.2.1 From da2e124ffd342f6f80639b58f86449ee9025c891 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 10 Feb 2009 14:39:14 +0200 Subject: From jperkin : Merge libedit 2.11 and related files, based on NetBSD CVS as of 2009/02/06 20:09:00. --- client/mysql.cc | 4 +- cmd-line-utils/libedit/Makefile.am | 28 +- cmd-line-utils/libedit/README | 50 ++ cmd-line-utils/libedit/TEST/test.c | 269 --------- cmd-line-utils/libedit/chared.c | 45 +- cmd-line-utils/libedit/chared.h | 9 +- cmd-line-utils/libedit/common.c | 27 +- cmd-line-utils/libedit/compat.h | 43 -- cmd-line-utils/libedit/compat_conf.h | 2 - cmd-line-utils/libedit/config.h | 14 - cmd-line-utils/libedit/editline.3 | 619 --------------------- cmd-line-utils/libedit/editrc.5 | 491 ----------------- cmd-line-utils/libedit/el.c | 204 ++++--- cmd-line-utils/libedit/el.h | 6 +- cmd-line-utils/libedit/el_term.h | 28 +- cmd-line-utils/libedit/emacs.c | 15 +- cmd-line-utils/libedit/fgetln.c | 88 --- cmd-line-utils/libedit/fgetln.h | 3 - cmd-line-utils/libedit/filecomplete.c | 558 +++++++++++++++++++ cmd-line-utils/libedit/filecomplete.h | 44 ++ cmd-line-utils/libedit/hist.c | 8 +- cmd-line-utils/libedit/histedit.h | 24 +- cmd-line-utils/libedit/history.c | 62 ++- cmd-line-utils/libedit/key.c | 148 +++-- cmd-line-utils/libedit/key.h | 6 +- cmd-line-utils/libedit/libedit_term.h | 124 ----- cmd-line-utils/libedit/makelist.sh | 20 +- cmd-line-utils/libedit/map.c | 64 ++- cmd-line-utils/libedit/np/fgetln.c | 50 +- cmd-line-utils/libedit/np/strlcat.c | 80 +-- cmd-line-utils/libedit/np/strlcpy.c | 77 +-- cmd-line-utils/libedit/np/unvis.c | 99 ++-- cmd-line-utils/libedit/np/vis.c | 409 +++++++------- cmd-line-utils/libedit/np/vis.h | 19 +- cmd-line-utils/libedit/parse.c | 12 +- cmd-line-utils/libedit/parse.h | 4 +- cmd-line-utils/libedit/prompt.c | 8 +- cmd-line-utils/libedit/read.c | 60 +- cmd-line-utils/libedit/read.h | 9 +- cmd-line-utils/libedit/readline.c | 843 +++++++++++------------------ cmd-line-utils/libedit/readline/readline.h | 38 +- cmd-line-utils/libedit/refresh.c | 76 ++- cmd-line-utils/libedit/search.c | 9 +- cmd-line-utils/libedit/sig.c | 20 +- cmd-line-utils/libedit/sig.h | 3 +- cmd-line-utils/libedit/strlcpy.c | 73 --- cmd-line-utils/libedit/strlcpy.h | 2 - cmd-line-utils/libedit/sys.h | 27 +- cmd-line-utils/libedit/term.c | 334 ++++++++---- cmd-line-utils/libedit/tokenizer.c | 8 +- cmd-line-utils/libedit/tokenizer.h | 54 -- cmd-line-utils/libedit/tty.c | 89 ++- cmd-line-utils/libedit/tty.h | 6 +- cmd-line-utils/libedit/unvis.c | 311 ----------- cmd-line-utils/libedit/vi.c | 39 +- cmd-line-utils/libedit/vis.c | 392 -------------- cmd-line-utils/libedit/vis.h | 92 ---- 57 files changed, 2298 insertions(+), 3948 deletions(-) create mode 100644 cmd-line-utils/libedit/README delete mode 100644 cmd-line-utils/libedit/TEST/test.c delete mode 100644 cmd-line-utils/libedit/compat.h delete mode 100644 cmd-line-utils/libedit/compat_conf.h delete mode 100644 cmd-line-utils/libedit/editline.3 delete mode 100644 cmd-line-utils/libedit/editrc.5 delete mode 100644 cmd-line-utils/libedit/fgetln.c delete mode 100644 cmd-line-utils/libedit/fgetln.h create mode 100644 cmd-line-utils/libedit/filecomplete.c create mode 100644 cmd-line-utils/libedit/filecomplete.h delete mode 100644 cmd-line-utils/libedit/libedit_term.h delete mode 100644 cmd-line-utils/libedit/strlcpy.c delete mode 100644 cmd-line-utils/libedit/strlcpy.h delete mode 100644 cmd-line-utils/libedit/tokenizer.h delete mode 100644 cmd-line-utils/libedit/unvis.c delete mode 100644 cmd-line-utils/libedit/vis.c delete mode 100644 cmd-line-utils/libedit/vis.h diff --git a/client/mysql.cc b/client/mysql.cc index 20f87d5cdcd..88ddd40fa68 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2247,8 +2247,10 @@ static char **new_mysql_completion (const char *text, int start, int end); if not. */ -#if defined(USE_NEW_READLINE_INTERFACE) || defined(USE_LIBEDIT_INTERFACE) +#if defined(USE_NEW_READLINE_INTERFACE) char *no_completion(const char*,int) +#elif defined(USE_LIBEDIT_INTERFACE) +int no_completion(const char*,int) #else char *no_completion() #endif diff --git a/cmd-line-utils/libedit/Makefile.am b/cmd-line-utils/libedit/Makefile.am index bb4b40180d1..5a01a746963 100644 --- a/cmd-line-utils/libedit/Makefile.am +++ b/cmd-line-utils/libedit/Makefile.am @@ -1,6 +1,4 @@ ## Process this file with automake to create Makefile.in -# Makefile for the GNU readline library. -# Copyright (C) 1994,1996,1997 Free Software Foundation, Inc. ASRC = $(srcdir)/vi.c $(srcdir)/emacs.c $(srcdir)/common.c AHDR = vi.h emacs.h common.h @@ -12,10 +10,9 @@ noinst_LIBRARIES = libedit.a libedit_a_SOURCES = chared.c el.c history.c map.c prompt.c readline.c \ search.c tokenizer.c vi.c common.c emacs.c \ hist.c key.c parse.c read.c refresh.c sig.c term.c \ - tty.c help.c fcns.c - -EXTRA_libedit_a_SOURCES = np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c \ - np/fgetln.c + tty.c help.c fcns.c filecomplete.c \ + np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c \ + np/fgetln.c libedit_a_LIBADD = @LIBEDIT_LOBJECTS@ libedit_a_DEPENDENCIES = @LIBEDIT_LOBJECTS@ @@ -23,22 +20,13 @@ libedit_a_DEPENDENCIES = @LIBEDIT_LOBJECTS@ pkginclude_HEADERS = readline/readline.h noinst_HEADERS = chared.h el.h el_term.h histedit.h key.h parse.h refresh.h sig.h \ - sys.h tokenizer.h config.h hist.h map.h prompt.h read.h \ - search.h tty.h libedit_term.h vis.h + sys.h config.h hist.h map.h prompt.h read.h \ + search.h tty.h filecomplete.h -EXTRA_DIST = makelist.sh np/unvis.c np/strlcpy.c np/vis.c np/vis.h np/strlcat.c np/fgetln.c +EXTRA_DIST = makelist.sh CLEANFILES = makelist common.h emacs.h vi.h fcns.h help.h fcns.c help.c -# Make sure to include stuff from this directory first, to get right "config.h" -# Automake puts into DEFAULT_INCLUDES this source and corresponding -# build directory together with ../../include to let all make files -# find the central "config.h". This variable is used before INCLUDES -# above. But in automake 1.10 the order of these are changed. Put the -# includes of this directory into DEFS to always be sure it is first -# before DEFAULT_INCLUDES on the compile line. -DEFS = -DUNDEF_THREADS_HACK -DHAVE_CONFIG_H -DNO_KILL_INTR -I. -I$(srcdir) - SUFFIXES = .sh .sh: @@ -101,6 +89,4 @@ term.o: vi.h emacs.h common.h help.h fcns.h tty.o: vi.h emacs.h common.h help.h fcns.h help.o: vi.h emacs.h common.h help.h fcns.h fcns.o: vi.h emacs.h common.h help.h fcns.h - -# Don't update the files from bitkeeper -%::SCCS/s.% +filecomplete.o: vi.h emacs.h common.h help.h fcns.h diff --git a/cmd-line-utils/libedit/README b/cmd-line-utils/libedit/README new file mode 100644 index 00000000000..0b698a6150d --- /dev/null +++ b/cmd-line-utils/libedit/README @@ -0,0 +1,50 @@ +An approximate method to merge from upstream is: + + # Fetch latest from upstream (we also include some compat stuff) + $ CVS_RSH=ssh; export CVS_RSH + $ CVSROOT="anoncvs@stripped:/cvsroot" + $ cvs co -d libedit -P src/lib/libedit + $ mkdir libedit/np + $ for f in src/common/lib/libc/string/strlcat.c \ + > src/common/lib/libc/string/strlcpy.c \ + > src/include/vis.h \ + > src/lib/libc/gen/unvis.c \ + > src/lib/libc/gen/vis.c \ + > src/tools/compat/fgetln.c + > do + > cvs co -P ${f} + > mv ${f} libedit/np + > done + $ rm -rf src + $ cd libedit + + # Remove files we don't need/use + $ rm -rf CVS TEST Makefile shlib_version *.[0-9] + $ (cd readline; rm -rf CVS Makefile) + + # Rename files to match our naming + $ mv makelist makelist.sh + $ mv term.h el_term.h + + # Remove NetBSD-specific bits + $ for file in $(find . -type f) + > do + > cp ${file} ${file}.orig + > sed -e 's/#include "term.h"/#include "el_term.h"/g' \ + > -e 's/sig_handler/el_sig_handler/g' \ + > -e 's/isprint/el_isprint/g' \ + > -e '/^__RCSID/d' \ + > ${file}.orig >${file} + > rm ${file}.orig + > done + +then merge remaining bits by hand. All MySQL-specific changes should be +marked with XXXMYSQL to make them easier to identify and merge. To generate +a 'clean' diff against upstream you can use the above commands but use + + cvs co -D "2009/02/06 20:09:00" [..] + +to fetch the baseline of most recent merge. + +Please feed any fixes to Jonathan Perkin who will endeavour +to merge them upstream and keep diffs minimal. diff --git a/cmd-line-utils/libedit/TEST/test.c b/cmd-line-utils/libedit/TEST/test.c deleted file mode 100644 index 605341eac62..00000000000 --- a/cmd-line-utils/libedit/TEST/test.c +++ /dev/null @@ -1,269 +0,0 @@ -/* $NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include "compat.h" -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\ - The Regents of the University of California. All rights reserved.\n"); -#endif /* not lint */ - -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * test.c: A little test program - */ -#include "sys.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#include "histedit.h" -#include "tokenizer.h" - -static int continuation = 0; -static EditLine *el = NULL; - -static u_char complete(EditLine *, int); - int main(int, char **); -static char *prompt(EditLine *); -static void sig(int); - -static char * -prompt(EditLine *el) -{ - static char a[] = "Edit$"; - static char b[] = "Edit>"; - - return (continuation ? b : a); -} - -static void -sig(int i) -{ - - (void) fprintf(stderr, "Got signal %d.\n", i); - el_reset(el); -} - -static unsigned char -complete(EditLine *el, int ch) -{ - DIR *dd = opendir("."); - struct dirent *dp; - const char* ptr; - const LineInfo *lf = el_line(el); - int len; - - /* - * Find the last word - */ - for (ptr = lf->cursor - 1; !isspace(*ptr) && ptr > lf->buffer; ptr--) - continue; - len = lf->cursor - ++ptr; - - for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) { - if (len > strlen(dp->d_name)) - continue; - if (strncmp(dp->d_name, ptr, len) == 0) { - closedir(dd); - if (el_insertstr(el, &dp->d_name[len]) == -1) - return (CC_ERROR); - else - return (CC_REFRESH); - } - } - - closedir(dd); - return (CC_ERROR); -} - -int -main(int argc, char *argv[]) -{ - int num; - const char *buf; - Tokenizer *tok; - int lastevent = 0, ncontinuation; - History *hist; - HistEvent ev; - - (void) signal(SIGINT, sig); - (void) signal(SIGQUIT, sig); - (void) signal(SIGHUP, sig); - (void) signal(SIGTERM, sig); - - hist = history_init(); /* Init the builtin history */ - /* Remember 100 events */ - history(hist, &ev, H_SETSIZE, 100); - - tok = tok_init(NULL); /* Initialize the tokenizer */ - - /* Initialize editline */ - el = el_init(*argv, stdin, stdout, stderr); - - el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */ - el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */ - el_set(el, EL_PROMPT, prompt); /* Set the prompt function */ - - /* Tell editline to use this history interface */ - el_set(el, EL_HIST, history, hist); - - /* Add a user-defined function */ - el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete); - - /* Bind tab to it */ - el_set(el, EL_BIND, "^I", "ed-complete", NULL); - - /* - * Bind j, k in vi command mode to previous and next line, instead - * of previous and next history. - */ - el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL); - el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL); - - /* - * Source the user's defaults file. - */ - el_source(el, NULL); - - while ((buf = el_gets(el, &num)) != NULL && num != 0) { - int ac; - char **av; -#ifdef DEBUG - (void) fprintf(stderr, "got %d %s", num, buf); -#endif - if (!continuation && num == 1) - continue; - - if (tok_line(tok, buf, &ac, &av) > 0) - ncontinuation = 1; - -#if 0 - if (continuation) { - /* - * Append to the right event in case the user - * moved around in history. - */ - if (history(hist, &ev, H_SET, lastevent) == -1) - err(1, "%d: %s\n", lastevent, ev.str); - history(hist, &ev, H_ADD , buf); - } else { - history(hist, &ev, H_ENTER, buf); - lastevent = ev.num; - } -#else - /* Simpler */ - history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf); -#endif - - continuation = ncontinuation; - ncontinuation = 0; - - if (strcmp(av[0], "history") == 0) { - int rv; - - switch (ac) { - case 1: - for (rv = history(hist, &ev, H_LAST); rv != -1; - rv = history(hist, &ev, H_PREV)) - (void) fprintf(stdout, "%4d %s", - ev.num, ev.str); - break; - - case 2: - if (strcmp(av[1], "clear") == 0) - history(hist, &ev, H_CLEAR); - else - goto badhist; - break; - - case 3: - if (strcmp(av[1], "load") == 0) - history(hist, &ev, H_LOAD, av[2]); - else if (strcmp(av[1], "save") == 0) - history(hist, &ev, H_SAVE, av[2]); - break; - - badhist: - default: - (void) fprintf(stderr, - "Bad history arguments\n"); - break; - } - } else if (el_parse(el, ac, av) == -1) { - switch (fork()) { - case 0: - execvp(av[0], av); - perror(av[0]); - _exit(1); - /*NOTREACHED*/ - break; - - case -1: - perror("fork"); - break; - - default: - if (wait(&num) == -1) - perror("wait"); - (void) fprintf(stderr, "Exit %x\n", num); - break; - } - } - - tok_reset(tok); - } - - el_end(el); - tok_end(tok); - history_end(hist); - - return (0); -} diff --git a/cmd-line-utils/libedit/chared.c b/cmd-line-utils/libedit/chared.c index 4cb6e00d26e..e4823db7147 100644 --- a/cmd-line-utils/libedit/chared.c +++ b/cmd-line-utils/libedit/chared.c @@ -1,4 +1,4 @@ -/* $NetBSD: chared.c,v 1.22 2004/08/13 12:10:38 mycroft Exp $ */ +/* $NetBSD: chared.c,v 1.26 2009/02/06 12:45:25 sketch Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * chared.c: Character editor utilities @@ -40,6 +46,8 @@ #include #include "el.h" +private void ch__clearmacro (EditLine *); + /* value to leave unused in line buffer */ #define EL_LEAVE 2 @@ -51,13 +59,13 @@ cv_undo(EditLine *el) { c_undo_t *vu = &el->el_chared.c_undo; c_redo_t *r = &el->el_chared.c_redo; - int size; + unsigned int size; /* Save entire line for undo */ size = el->el_line.lastchar - el->el_line.buffer; vu->len = size; vu->cursor = el->el_line.cursor - el->el_line.buffer; - memcpy(vu->buf, el->el_line.buffer, (size_t)size); + memcpy(vu->buf, el->el_line.buffer, size); /* save command info for redo */ r->count = el->el_state.doingarg ? el->el_state.argument : 0; @@ -439,6 +447,8 @@ cv__endword(char *p, char *high, int n, int (*wtest)(int)) protected int ch_init(EditLine *el) { + c_macro_t *ma = &el->el_chared.c_macro; + el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ); if (el->el_line.buffer == NULL) return (-1); @@ -479,11 +489,10 @@ ch_init(EditLine *el) el->el_state.argument = 1; el->el_state.lastcmd = ED_UNASSIGNED; - el->el_chared.c_macro.level = -1; - el->el_chared.c_macro.offset = 0; - el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO * - sizeof(char *)); - if (el->el_chared.c_macro.macro == NULL) + ma->level = -1; + ma->offset = 0; + ma->macro = (char **) el_malloc(EL_MAXMACRO * sizeof(char *)); + if (ma->macro == NULL) return (-1); return (0); } @@ -492,7 +501,7 @@ ch_init(EditLine *el) * Reset the character editor */ protected void -ch_reset(EditLine *el) +ch_reset(EditLine *el, int mclear) { el->el_line.cursor = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer; @@ -513,9 +522,19 @@ ch_reset(EditLine *el) el->el_state.argument = 1; el->el_state.lastcmd = ED_UNASSIGNED; - el->el_chared.c_macro.level = -1; - el->el_history.eventno = 0; + + if (mclear) + ch__clearmacro(el); +} + +private void +ch__clearmacro(el) + EditLine *el; +{ + c_macro_t *ma = &el->el_chared.c_macro; + while (ma->level >= 0) + el_free((ptr_t)ma->macro[ma->level--]); } /* ch_enlargebufs(): @@ -623,9 +642,9 @@ ch_end(EditLine *el) el->el_chared.c_redo.cmd = ED_UNASSIGNED; el_free((ptr_t) el->el_chared.c_kill.buf); el->el_chared.c_kill.buf = NULL; + ch_reset(el, 1); el_free((ptr_t) el->el_chared.c_macro.macro); el->el_chared.c_macro.macro = NULL; - ch_reset(el); } diff --git a/cmd-line-utils/libedit/chared.h b/cmd-line-utils/libedit/chared.h index 2dd0a5795c7..fa8f5a58d83 100644 --- a/cmd-line-utils/libedit/chared.h +++ b/cmd-line-utils/libedit/chared.h @@ -1,4 +1,4 @@ -/* $NetBSD: chared.h,v 1.14 2004/08/13 12:10:39 mycroft Exp $ */ +/* $NetBSD: chared.h,v 1.17 2006/03/06 21:11:56 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -48,7 +48,7 @@ #define EL_MAXMACRO 10 /* - * This is a issue of basic "vi" look-and-feel. Defining VI_MOVE works + * This is an issue of basic "vi" look-and-feel. Defining VI_MOVE works * like real vi: i.e. the transition from command<->insert modes moves * the cursor. * @@ -116,11 +116,10 @@ typedef struct el_chared_t { } el_chared_t; -#define STReof "^D\b\b" #define STRQQ "\"\"" #define isglob(a) (strchr("*[]?", (a)) != NULL) -#define isword(a) (isprint(a)) +#define isword(a) (el_isprint(a)) #define NOP 0x00 #define DELETE 0x01 @@ -161,7 +160,7 @@ protected int c_gets(EditLine *, char *, const char *); protected int c_hpos(EditLine *); protected int ch_init(EditLine *); -protected void ch_reset(EditLine *); +protected void ch_reset(EditLine *, int); protected int ch_enlargebufs(EditLine *, size_t); protected void ch_end(EditLine *); diff --git a/cmd-line-utils/libedit/common.c b/cmd-line-utils/libedit/common.c index 81bf9bf29ff..d4d024eae10 100644 --- a/cmd-line-utils/libedit/common.c +++ b/cmd-line-utils/libedit/common.c @@ -1,4 +1,4 @@ -/* $NetBSD: common.c,v 1.16 2003/08/07 16:44:30 agc Exp $ */ +/* $NetBSD: common.c,v 1.21 2008/09/30 08:37:42 aymeric Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * common.c: Common Editor functions @@ -130,7 +136,7 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) +ed_delete_next_char(EditLine *el, int c) { #ifdef notdef /* XXX */ #define EL el->el_line @@ -147,9 +153,8 @@ ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) #ifdef KSHVI return (CC_ERROR); #else - term_overwrite(el, STReof, 4); - /* then do a EOF */ - term__flush(); + /* then do an EOF */ + term_writechar(el, c); return (CC_EOF); #endif } else { @@ -207,13 +212,13 @@ ed_move_to_end(EditLine *el, int c __attribute__((__unused__))) el->el_line.cursor = el->el_line.lastchar; if (el->el_map.type == MAP_VI) { -#ifdef VI_MOVE - el->el_line.cursor--; -#endif if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); return (CC_REFRESH); } +#ifdef VI_MOVE + el->el_line.cursor--; +#endif } return (CC_CURSOR); } @@ -609,7 +614,7 @@ protected el_action_t ed_start_over(EditLine *el, int c __attribute__((__unused__))) { - ch_reset(el); + ch_reset(el, 0); return (CC_REFRESH); } @@ -904,7 +909,7 @@ ed_command(EditLine *el, int c __attribute__((__unused__))) int tmplen; tmplen = c_gets(el, tmpbuf, "\n: "); - term__putc('\n'); + term__putc(el, '\n'); if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1) term_beep(el); diff --git a/cmd-line-utils/libedit/compat.h b/cmd-line-utils/libedit/compat.h deleted file mode 100644 index 3693a2db809..00000000000 --- a/cmd-line-utils/libedit/compat.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __LIBEDIT_COMPATH_H -#define __LIBEDIT_COMPATH_H - -#define __RCSID(x) -#define __COPYRIGHT(x) - -#include "compat_conf.h" - -#ifndef HAVE_VIS_H -/* string visual representation - may want to reimplement */ -#define strvis(d,s,m) strcpy(d,s) -#define strunvis(d,s) strcpy(d,s) -#endif - -#ifndef HAVE_FGETLN -#include "fgetln.h" -#endif - -#ifndef HAVE_ISSETUGID -#define issetugid() (getuid()!=geteuid() || getegid()!=getgid()) -#endif - -#ifndef HAVE_STRLCPY -#include "strlcpy.h" -#endif - -#if HAVE_SYS_CDEFS_H -#include -#endif - -#ifndef __P -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif -#endif - -#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8) -#define __attribute__(A) -#endif - -#endif diff --git a/cmd-line-utils/libedit/compat_conf.h b/cmd-line-utils/libedit/compat_conf.h deleted file mode 100644 index e2b9557f5b1..00000000000 --- a/cmd-line-utils/libedit/compat_conf.h +++ /dev/null @@ -1,2 +0,0 @@ - -#include "my_config.h" diff --git a/cmd-line-utils/libedit/config.h b/cmd-line-utils/libedit/config.h index 642123d1ddc..2c3989ee316 100644 --- a/cmd-line-utils/libedit/config.h +++ b/cmd-line-utils/libedit/config.h @@ -1,16 +1,2 @@ - #include "my_config.h" #include "sys.h" - -#if defined(LIBC_SCCS) && !defined(lint) -#define __RCSID(x) -#define __COPYRIGHT(x) -#endif -#define __RENAME(x) -#define _DIAGASSERT(x) - -#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8) -#define __attribute__(A) -#endif - - diff --git a/cmd-line-utils/libedit/editline.3 b/cmd-line-utils/libedit/editline.3 deleted file mode 100644 index 1b812ebcc79..00000000000 --- a/cmd-line-utils/libedit/editline.3 +++ /dev/null @@ -1,619 +0,0 @@ -.\" $NetBSD: editline.3,v 1.21 2001/04/02 18:29:49 wiz Exp $ -.\" -.\" Copyright (c) 1997-1999 The NetBSD Foundation, Inc. -.\" All rights reserved. -.\" -.\" This file was contributed to The NetBSD Foundation by Luke Mewburn. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation nor the names of its -.\" contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS -.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS -.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -.\" POSSIBILITY OF SUCH DAMAGE. -.\" -.Dd November 12, 1999 -.Os -.Dt EDITLINE 3 -.Sh NAME -.Nm editline , -.Nm el_init , -.Nm el_end , -.Nm el_reset , -.Nm el_gets , -.Nm el_getc , -.Nm el_push , -.Nm el_parse , -.Nm el_set , -.Nm el_source , -.Nm el_resize , -.Nm el_line , -.Nm el_insertstr , -.Nm el_deletestr , -.Nm history_init , -.Nm history_end , -.Nm history -.Nd line editor and history functions -.Sh LIBRARY -.Lb libedit -.Sh SYNOPSIS -.Fd #include -.Ft EditLine * -.Fn el_init "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr" -.Ft void -.Fn el_end "EditLine *e" -.Ft void -.Fn el_reset "EditLine *e" -.Ft const char * -.Fn el_gets "EditLine *e" "int *count" -.Ft int -.Fn el_getc "EditLine *e" "char *ch" -.Ft void -.Fn el_push "EditLine *e" "const char *str" -.Ft int -.Fn el_parse "EditLine *e" "int argc" "char *argv[]" -.Ft int -.Fn el_set "EditLine *e" "int op" "..." -.Ft int -.Fn el_get "EditLine *e" "int op" "void *result" -.Ft int -.Fn el_source "EditLine *e" "const char *file" -.Ft void -.Fn el_resize "EditLine *e" -.Ft const LineInfo * -.Fn el_line "EditLine *e" -.Ft int -.Fn el_insertstr "EditLine *e" "const char *str" -.Ft void -.Fn el_deletestr "EditLine *e" "int count" -.Ft History * -.Fn history_init -.Ft void -.Fn history_end "History *h" -.Ft int -.Fn history "History *h" "HistEvent *ev" "int op" "..." -.Sh DESCRIPTION -The -.Nm -library provides generic line editing and history functions, -similar to those found in -.Xr sh 1 . -.Pp -These functions are available in the -.Nm libedit -library (which needs the -.Nm libtermcap -library). -Programs should be linked with -.Fl ledit ltermcap . -.Sh LINE EDITING FUNCTIONS -The line editing functions use a common data structure, -.Fa EditLine , -which is created by -.Fn el_init -and freed by -.Fn el_end . -.Pp -The following functions are available: -.Bl -tag -width 4n -.It Fn el_init -Initialise the line editor, and return a data structure -to be used by all other line editing functions. -.Fa prog -is the name of the invoking program, used when reading the -.Xr editrc 5 -file to determine which settings to use. -.Fa fin , -.Fa fout -and -.Fa ferr -are the input, output, and error streams (respectively) to use. -In this documentation, references to -.Dq the tty -are actually to this input/output stream combination. -.It Fn el_end -Clean up and finish with -.Fa e , -assumed to have been created with -.Fn el_init . -.It Fn el_reset -Reset the tty and the parser. -This should be called after an error which may have upset the tty's -state. -.It Fn el_gets -Read a line from the tty. -.Fa count -is modified to contain the number of characters read. -Returns the line read if successful, or -.Dv NULL -if no characters were read or if an error occurred. -.It Fn el_getc -Read a character from the tty. -.Fa ch -is modified to contain the character read. -Returns the number of characters read if successful, -1 otherwise. -.It Fn el_push -Pushes -.Fa str -back onto the input stream. -This is used by the macro expansion mechanism. -Refer to the description of -.Ic bind -.Fl s -in -.Xr editrc 5 -for more information. -.It Fn el_parse -Parses the -.Fa argv -array (which is -.Fa argc -elements in size) -to execute builtin -.Nm -commands. -If the command is prefixed with -.Dq prog: -then -.Fn el_parse -will only execute the command if -.Dq prog -matches the -.Fa prog -argument supplied to -.Fn el_init . -The return value is --1 if the command is unknown, -0 if there was no error or -.Dq prog -didn't match, or -1 if the command returned an error. -Refer to -.Xr editrc 5 -for more information. -.It Fn el_set -Set -.Nm -parameters. -.Fa op -determines which parameter to set, and each operation has its -own parameter list. -.Pp -The following values for -.Fa op -are supported, along with the required argument list: -.Bl -tag -width 4n -.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)" -Define prompt printing function as -.Fa f , -which is to return a string that contains the prompt. -.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" -Define right side prompt printing function as -.Fa f , -which is to return a string that contains the prompt. -.It Dv EL_TERMINAL , Fa "const char *type" -Define terminal type of the tty to be -.Fa type , -or to -.Ev TERM -if -.Fa type -is -.Dv NULL . -.It Dv EL_EDITOR , Fa "const char *mode" -Set editing mode to -.Fa mode , -which must be one of -.Dq emacs -or -.Dq vi . -.It Dv EL_SIGNAL , Fa "int flag" -If -.Fa flag -is non-zero, -.Nm -will install its own signal handler for the following signals when -reading command input: -.Dv SIGCONT , -.Dv SIGHUP , -.Dv SIGINT , -.Dv SIGQUIT , -.Dv SIGSTOP , -.Dv SIGTERM , -.Dv SIGTSTP , -and -.Dv SIGWINCH . -Otherwise, the current signal handlers will be used. -.It Dv EL_BIND , Xo -.Fa "const char *" , -.Fa "..." , -.Dv NULL -.Xc -Perform the -.Ic bind -builtin command. -Refer to -.Xr editrc 5 -for more information. -.It Dv EL_ECHOTC , Xo -.Fa "const char *" , -.Fa "..." , -.Dv NULL -.Xc -Perform the -.Ic echotc -builtin command. -Refer to -.Xr editrc 5 -for more information. -.It Dv EL_SETTC , Xo -.Fa "const char *" , -.Fa "..." , -.Dv NULL -.Xc -Perform the -.Ic settc -builtin command. -Refer to -.Xr editrc 5 -for more information. -.It Dv EL_SETTY , Xo -.Fa "const char *" , -.Fa "..." , -.Dv NULL -.Xc -Perform the -.Ic setty -builtin command. -Refer to -.Xr editrc 5 -for more information. -.It Dv EL_TELLTC , Xo -.Fa "const char *" , -.Fa "..." , -.Dv NULL -.Xc -Perform the -.Ic telltc -builtin command. -Refer to -.Xr editrc 5 -for more information. -.It Dv EL_ADDFN , Xo -.Fa "const char *name" , -.Fa "const char *help" , -.Fa "unsigned char (*func)(EditLine *e, int ch) -.Xc -Add a user defined function, -.Fn func , -referred to as -.Fa name -which is invoked when a key which is bound to -.Fa name -is entered. -.Fa help -is a description of -.Fa name . -At invocation time, -.Fa ch -is the key which caused the invocation. -The return value of -.Fn func -should be one of: -.Bl -tag -width "CC_REDISPLAY" -.It Dv CC_NORM -Add a normal character. -.It Dv CC_NEWLINE -End of line was entered. -.It Dv CC_EOF -EOF was entered. -.It Dv CC_ARGHACK -Expecting further command input as arguments, do nothing visually. -.It Dv CC_REFRESH -Refresh display. -.It Dv CC_REFRESH_BEEP -Refresh display, and beep. -.It Dv CC_CURSOR -Cursor moved, so update and perform -.Dv CC_REFRESH. -.It Dv CC_REDISPLAY -Redisplay entire input line. -This is useful if a key binding outputs extra information. -.It Dv CC_ERROR -An error occurred. -Beep, and flush tty. -.It Dv CC_FATAL -Fatal error, reset tty to known state. -.El -.It Dv EL_HIST , Xo -.Fa "History *(*func)(History *, int op, ...)" , -.Fa "const char *ptr" -.Xc -Defines which history function to use, which is usually -.Fn history . -.Fa ptr -should be the value returned by -.Fn history_init . -.It Dv EL_EDITMODE , Fa "int flag" -If -.Fa flag -is non-zero, -editing is enabled (the default). -Note that this is only an indication, and does not -affect the operation of -.Nm "" . -At this time, it is the caller's responsibility to -check this -(using -.Fn el_get ) -to determine if editing should be enabled or not. -.El -.It Fn el_get -Get -.Nm -parameters. -.Fa op -determines which parameter to retrieve into -.Fa result . -.Pp -The following values for -.Fa op -are supported, along with actual type of -.Fa result : -.Bl -tag -width 4n -.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)" -Return a pointer to the function that displays the prompt. -.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" -Return a pointer to the function that displays the rightside prompt. -.It Dv EL_EDITOR , Fa "const char *" -Return the name of the editor, which will be one of -.Dq emacs -or -.Dq vi . -.It Dv EL_SIGNAL , Fa "int *" -Return non-zero if -.Nm -has installed private signal handlers (see -.Fn el_get -above). -.It Dv EL_EDITMODE, Fa "int *" -Return non-zero if editing is enabled. -.El -.It Fn el_source -Initialise -.Nm -by reading the contents of -.Fa file . -.Fn el_parse -is called for each line in -.Fa file . -If -.Fa file -is -.Dv NULL , -try -.Pa $PWD/.editrc -then -.Pa $HOME/.editrc . -Refer to -.Xr editrc 5 -for details on the format of -.Fa file . -.It Fn el_resize -Must be called if the terminal size changes. -If -.Dv EL_SIGNAL -has been set with -.Fn el_set , -then this is done automatically. -Otherwise, it's the responsibility of the application to call -.Fn el_resize -on the appropriate occasions. -.It Fn el_line -Return the editing information for the current line in a -.Fa LineInfo -structure, which is defined as follows: -.Bd -literal -typedef struct lineinfo { - const char *buffer; /* address of buffer */ - const char *cursor; /* address of cursor */ - const char *lastchar; /* address of last character */ -} LineInfo; -.Ed -.It Fn el_insertstr -Insert -.Fa str -into the line at the cursor. -Returns -1 if -.Fa str -is empty or won't fit, and 0 otherwise. -.It Fn el_deletestr -Delete -.Fa num -characters before the cursor. -.El -.Sh HISTORY LIST FUNCTIONS -The history functions use a common data structure, -.Fa History , -which is created by -.Fn history_init -and freed by -.Fn history_end . -.Pp -The following functions are available: -.Bl -tag -width 4n -.It Fn history_init -Initialise the history list, and return a data structure -to be used by all other history list functions. -.It Fn history_end -Clean up and finish with -.Fa h , -assumed to have been created with -.Fn history_init . -.It Fn history -Perform operation -.Fa op -on the history list, with optional arguments as needed by the -operation. -.Fa ev -is changed accordingly to operation. -The following values for -.Fa op -are supported, along with the required argument list: -.Bl -tag -width 4n -.It Dv H_SETSIZE , Fa "int size" -Set size of history to -.Fa size -elements. -.It Dv H_GETSIZE -Get number of events currently in history. -.It Dv H_END -Cleans up and finishes with -.Fa h , -assumed to be created with -.Fn history_init . -.It Dv H_CLEAR -Clear the history. -.It Dv H_FUNC , Xo -.Fa "void *ptr" , -.Fa "history_gfun_t first" , -.Fa "history_gfun_t next" , -.Fa "history_gfun_t last" , -.Fa "history_gfun_t prev" , -.Fa "history_gfun_t curr" , -.Fa "history_sfun_t set" , -.Fa "history_vfun_t clear" , -.Fa "history_efun_t enter" , -.Fa "history_efun_t add" -.Xc -Define functions to perform various history operations. -.Fa ptr -is the argument given to a function when it's invoked. -.It Dv H_FIRST -Return the first element in the history. -.It Dv H_LAST -Return the last element in the history. -.It Dv H_PREV -Return the previous element in the history. -.It Dv H_NEXT -Return the next element in the history. -.It Dv H_CURR -Return the current element in the history. -.It Dv H_SET -Set the cursor to point to the requested element. -.It Dv H_ADD , Fa "const char *str" -Append -.Fa str -to the current element of the history, or create an element with -.It Dv H_APPEND , Fa "const char *str" -Append -.Fa str -to the last new element of the history. -.It Dv H_ENTER , Fa "const char *str" -Add -.Fa str -as a new element to the history, and, if necessary, -removing the oldest entry to keep the list to the created size. -.It Dv H_PREV_STR , Fa "const char *str" -Return the closest previous event that starts with -.Fa str . -.It Dv H_NEXT_STR , Fa "const char *str" -Return the closest next event that starts with -.Fa str . -.It Dv H_PREV_EVENT , Fa "int e" -Return the previous event numbered -.Fa e . -.It Dv H_NEXT_EVENT , Fa "int e" -Return the next event numbered -.Fa e . -.It Dv H_LOAD , Fa "const char *file" -Load the history list stored in -.Fa file . -.It Dv H_SAVE , Fa "const char *file" -Save the history list to -.Fa file . -.El -.Pp -.Fn history -returns 0 if the operation -.Fa op -succeeds. Otherwise, -1 is returned and -.Fa ev -is updated to contain more details about the error. -.El -.\"XXX.Sh EXAMPLES -.\"XXX: provide some examples -.Sh SEE ALSO -.Xr editrc 5 , -.Xr sh 1 , -.Xr signal 3 , -.Xr termcap 3 -.Sh HISTORY -The -.Nm -library first appeared in -.Bx 4.4 . -.Dv CC_REDISPLAY -appeared in -.Nx 1.3 . -.Dv CC_REFRESH_BEEP , -.Dv EL_EDITMODE -and the readline emulation appeared in -.Nx 1.4 . -.Dv EL_RPROMPT -appeared in -.Nx 1.5 . -.Sh AUTHORS -The -.Nm -library was written by Christos Zoulas. -Luke Mewburn wrote this manual and implemented -.Dv CC_REDISPLAY , -.Dv CC_REFRESH_BEEP , -.Dv EL_EDITMODE , -and -.Dv EL_RPROMPT . -Jaromir Dolecek implemented the readline emulation. -.Sh BUGS -The tokenization functions are not publically defined in -.Fd . -.Pp -At this time, it is the responsibility of the caller to -check the result of the -.Dv EL_EDITMODE -operation of -.Fn el_get -(after an -.Fn el_source -or -.Fn el_parse ) -to determine if -.Nm -should be used for further input. -I.e., -.Dv EL_EDITMODE -is purely an indication of the result of the most recent -.Xr editrc 5 -.Ic edit -command. diff --git a/cmd-line-utils/libedit/editrc.5 b/cmd-line-utils/libedit/editrc.5 deleted file mode 100644 index b1122618939..00000000000 --- a/cmd-line-utils/libedit/editrc.5 +++ /dev/null @@ -1,491 +0,0 @@ -.\" $NetBSD: editrc.5,v 1.11 2001/06/19 13:42:09 wiz Exp $ -.\" -.\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc. -.\" All rights reserved. -.\" -.\" This file was contributed to The NetBSD Foundation by Luke Mewburn. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation nor the names of its -.\" contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS -.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS -.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -.\" POSSIBILITY OF SUCH DAMAGE. -.\" -.Dd November 8, 2000 -.Os -.Dt EDITRC 5 -.Sh NAME -.Nm editrc -.Nd configuration file for editline library -.Sh SYNOPSIS -.Nm -.Sh DESCRIPTION -The -.Nm -file defines various settings to be used by the -.Xr editline 3 -library. -.Pp -The format of each line is: -.Dl [prog:]command [arg [...]] -.Pp -.Ar command -is one of the -.Xr editline 3 -builtin commands. -Refer to -.Sx BUILTIN COMMANDS -for more information. -.Pp -.Ar prog -is the program name string that a program defines when it calls -.Xr el_init 3 -to setup -.Xr editline 3 , -which is usually -.Va argv[0] . -.Ar command -will be executed for any program which matches -.Ar prog . -.Pp -.Ar prog -may also be a -.Xr regex 3 -style -regular expression, in which case -.Ar command -will be executed for any program that matches the regular expression. -.Pp -If -.Ar prog -is absent, -.Ar command -is executed for all programs. -.Sh BUILTIN COMMANDS -The -.Nm editline -library has some builtin commands, which affect the way -that the line editing and history functions operate. -These are based on similar named builtins present in the -.Xr tcsh 1 -shell. -.Pp -The following builtin commands are available: -.Bl -tag -width 4n -.It Ic bind Xo -.Op Fl a -.Op Fl e -.Op Fl k -.Op Fl l -.Op Fl r -.Op Fl s -.Op Fl v -.Op Ar key Op Ar command -.Xc -Without options, list all bound keys, and the editor command to which -each is bound. -If -.Ar key -is supplied, show the bindings for -.Ar key . -If -.Ar key command -is supplied, bind -.Ar command -to -.Ar key . -Options include: -.Bl -tag -width 4n -.It Fl e -Bind all keys to the standard GNU Emacs-like bindings. -.It Fl v -Bind all keys to the standard -.Xr vi 1 -like -bindings. -.It Fl a -List or change key bindings in the -.Xr vi 1 -mode alternate (command mode) key map. -.It Fl k -.Ar key -is interpreted as a symbolic arrow key name, which may be one of -.Sq up , -.Sq down , -.Sq left -or -.Sq right . -.It Fl l -List all editor commands and a short description of each. -.It Fl r -Remove a key's binding. -.It Fl s -.Ar command -is taken as a literal string and treated as terminal input when -.Ar key -is typed. -Bound keys in -.Ar command -are themselves reinterpreted, and this continues for ten levels of -interpretation. -.El -.Pp -.Ar command -may be one of the commands documented in -.Sx "EDITOR COMMANDS" -below, or another key. -.Pp -.Ar key -and -.Ar command -can contain control characters of the form -.Sm off -.Sq No ^ Ar character -.Sm on -.Po -e.g. -.Sq ^A -.Pc , -and the following backslashed escape sequences: -.Pp -.Bl -tag -compact -offset indent -width 4n -.It Ic \ea -Bell -.It Ic \eb -Backspace -.It Ic \ee -Escape -.It Ic \ef -Formfeed -.It Ic \en -Newline -.It Ic \er -Carriage return -.It Ic \et -Horizontal tab -.It Ic \ev -Vertical tab -.Sm off -.It Sy \e Ar nnn -.Sm on -The ASCII character corresponding to the octal number -.Ar nnn . -.El -.Pp -.Sq \e -nullifies the special meaning of the following character, -if it has any, notably -.Sq \e -and -.Sq ^ . -.It Ic echotc Xo -.Op Fl sv -.Ar arg -.Ar ... -.Xc -Exercise terminal capabilities given in -.Ar arg Ar ... . -If -.Ar arg -is -.Sq baud , -.Sq cols , -.Sq lines , -.Sq rows , -.Sq meta or -.Sq tabs , -the value of that capability is printed, with -.Dq yes -or -.Dq no -indicating that the terminal does or does not have that capability. -.Pp -.Fl s -returns an emptry string for non-existent capabilities, rather than -causing an error. -.Fl v -causes messages to be verbose. -.It Ic edit Op Li on | Li off -Enable or disable the -.Nm editline -functionality in a program. -.It Ic history -List the history. -.It Ic telltc -List the values of all the terminal capabilities (see -.Xr termcap 5 ). -.It Ic settc Ar cap Ar val -Set the terminal capability -.Ar cap -to -.Ar val , -as defined in -.Xr termcap 5 . -No sanity checking is done. -.It Ic setty Xo -.Op Fl a -.Op Fl d -.Op Fl q -.Op Fl x -.Op Ar +mode -.Op Ar -mode -.Op Ar mode -.Xc -Control which tty modes that -.Nm -won't allow the user to change. -.Fl d , -.Fl q -or -.Fl x -tells -.Ic setty -to act on the -.Sq edit , -.Sq quote -or -.Sq execute -set of tty modes respectively; defaulting to -.Fl x . -.Pp -Without other arguments, -.Ic setty -lists the modes in the chosen set which are fixed on -.Po -.Sq +mode -.Pc -or off -.Po -.Sq -mode -.Pc . -.Fl a -lists all tty modes in the chosen set regardless of the setting. -With -.Ar +mode , -.Ar -mode -or -.Ar mode , -fixes -.Ar mode -on or off or removes control of -.Ar mode -in the chosen set. -.El -.Sh EDITOR COMMANDS -The following editor commands are available for use in key bindings: -.\" Section automatically generated with makelist -.Bl -tag -width 4n -.It Ic vi-paste-next -Vi paste previous deletion to the right of the cursor. -.It Ic vi-paste-prev -Vi paste previous deletion to the left of the cursor. -.It Ic vi-prev-space-word -Vi move to the previous space delimited word. -.It Ic vi-prev-word -Vi move to the previous word. -.It Ic vi-next-space-word -Vi move to the next space delimited word. -.It Ic vi-next-word -Vi move to the next word. -.It Ic vi-change-case -Vi change case of character under the cursor and advance one character. -.It Ic vi-change-meta -Vi change prefix command. -.It Ic vi-insert-at-bol -Vi enter insert mode at the beginning of line. -.It Ic vi-replace-char -Vi replace character under the cursor with the next character typed. -.It Ic vi-replace-mode -Vi enter replace mode. -.It Ic vi-substitute-char -Vi replace character under the cursor and enter insert mode. -.It Ic vi-substitute-line -Vi substitute entire line. -.It Ic vi-change-to-eol -Vi change to end of line. -.It Ic vi-insert -Vi enter insert mode. -.It Ic vi-add -Vi enter insert mode after the cursor. -.It Ic vi-add-at-eol -Vi enter insert mode at end of line. -.It Ic vi-delete-meta -Vi delete prefix command. -.It Ic vi-end-word -Vi move to the end of the current space delimited word. -.It Ic vi-to-end-word -Vi move to the end of the current word. -.It Ic vi-undo -Vi undo last change. -.It Ic vi-command-mode -Vi enter command mode (use alternative key bindings). -.It Ic vi-zero -Vi move to the beginning of line. -.It Ic vi-delete-prev-char -Vi move to previous character (backspace). -.It Ic vi-list-or-eof -Vi list choices for completion or indicate end of file if empty line. -.It Ic vi-kill-line-prev -Vi cut from beginning of line to cursor. -.It Ic vi-search-prev -Vi search history previous. -.It Ic vi-search-next -Vi search history next. -.It Ic vi-repeat-search-next -Vi repeat current search in the same search direction. -.It Ic vi-repeat-search-prev -Vi repeat current search in the opposite search direction. -.It Ic vi-next-char -Vi move to the character specified next. -.It Ic vi-prev-char -Vi move to the character specified previous. -.It Ic vi-to-next-char -Vi move up to the character specified next. -.It Ic vi-to-prev-char -Vi move up to the character specified previous. -.It Ic vi-repeat-next-char -Vi repeat current character search in the same search direction. -.It Ic vi-repeat-prev-char -Vi repeat current character search in the opposite search direction. -.It Ic em-delete-or-list -Delete character under cursor or list completions if at end of line. -.It Ic em-delete-next-word -Cut from cursor to end of current word. -.It Ic em-yank -Paste cut buffer at cursor position. -.It Ic em-kill-line -Cut the entire line and save in cut buffer. -.It Ic em-kill-region -Cut area between mark and cursor and save in cut buffer. -.It Ic em-copy-region -Copy area between mark and cursor to cut buffer. -.It Ic em-gosmacs-traspose -Exchange the two characters before the cursor. -.It Ic em-next-word -Move next to end of current word. -.It Ic em-upper-case -Uppercase the characters from cursor to end of current word. -.It Ic em-capitol-case -Capitalize the characters from cursor to end of current word. -.It Ic em-lower-case -Lowercase the characters from cursor to end of current word. -.It Ic em-set-mark -Set the mark at cursor. -.It Ic em-exchange-mark -Exchange the cursor and mark. -.It Ic em-universal-argument -Universal argument (argument times 4). -.It Ic em-meta-next -Add 8th bit to next character typed. -.It Ic em-toggle-overwrite -Switch from insert to overwrite mode or vice versa. -.It Ic em-copy-prev-word -Copy current word to cursor. -.It Ic em-inc-search-next -Emacs incremental next search. -.It Ic em-inc-search-prev -Emacs incremental reverse search. -.It Ic ed-end-of-file -Indicate end of file. -.It Ic ed-insert -Add character to the line. -.It Ic ed-delete-prev-word -Delete from beginning of current word to cursor. -.It Ic ed-delete-next-char -Delete character under cursor. -.It Ic ed-kill-line -Cut to the end of line. -.It Ic ed-move-to-end -Move cursor to the end of line. -.It Ic ed-move-to-beg -Move cursor to the beginning of line. -.It Ic ed-transpose-chars -Exchange the character to the left of the cursor with the one under it. -.It Ic ed-next-char -Move to the right one character. -.It Ic ed-prev-word -Move to the beginning of the current word. -.It Ic ed-prev-char -Move to the left one character. -.It Ic ed-quoted-insert -Add the next character typed verbatim. -.It Ic ed-digit -Adds to argument or enters a digit. -.It Ic ed-argument-digit -Digit that starts argument. -.It Ic ed-unassigned -Indicates unbound character. -.It Ic ed-tty-sigint -Tty interrupt character. -.It Ic ed-tty-dsusp -Tty delayed suspend character. -.It Ic ed-tty-flush-output -Tty flush output characters. -.It Ic ed-tty-sigquit -Tty quit character. -.It Ic ed-tty-sigtstp -Tty suspend character. -.It Ic ed-tty-stop-output -Tty disallow output characters. -.It Ic ed-tty-start-output -Tty allow output characters. -.It Ic ed-newline -Execute command. -.It Ic ed-delete-prev-char -Delete the character to the left of the cursor. -.It Ic ed-clear-screen -Clear screen leaving current line at the top. -.It Ic ed-redisplay -Redisplay everything. -.It Ic ed-start-over -Erase current line and start from scratch. -.It Ic ed-sequence-lead-in -First character in a bound sequence. -.It Ic ed-prev-history -Move to the previous history line. -.It Ic ed-next-history -Move to the next history line. -.It Ic ed-search-prev-history -Search previous in history for a line matching the current. -.It Ic ed-search-next-history -Search next in history for a line matching the current. -.It Ic ed-prev-line -Move up one line. -.It Ic ed-next-line -Move down one line. -.It Ic ed-command -Editline extended command. -.El -.\" End of section automatically generated with makelist -.Sh SEE ALSO -.Xr editline 3 , -.Xr regex 3 , -.Xr termcap 5 -.Sh AUTHORS -The -.Nm editline -library was written by Christos Zoulas, -and this manual was written by Luke Mewburn, -with some sections inspired by -.Xr tcsh 1 . diff --git a/cmd-line-utils/libedit/el.c b/cmd-line-utils/libedit/el.c index c32a01b2151..d99946eb68f 100644 --- a/cmd-line-utils/libedit/el.c +++ b/cmd-line-utils/libedit/el.c @@ -1,4 +1,4 @@ -/* $NetBSD: el.c,v 1.39 2004/07/08 00:51:36 christos Exp $ */ +/* $NetBSD: el.c,v 1.47 2009/01/18 12:17:24 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * el.c: EditLine interface functions @@ -58,9 +64,12 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) memset(el, 0, sizeof(EditLine)); - el->el_infd = fileno(fin); + el->el_infile = fin; el->el_outfile = fout; el->el_errfile = ferr; + + el->el_infd = fileno(fin); + if ((el->el_prog = el_strdup(prog)) == NULL) { el_free(el); return NULL; @@ -126,7 +135,7 @@ el_reset(EditLine *el) { tty_cookedmode(el); - ch_reset(el); /* XXX: Do we want that? */ + ch_reset(el, 0); /* XXX: Do we want that? */ } @@ -136,29 +145,29 @@ el_reset(EditLine *el) public int el_set(EditLine *el, int op, ...) { - va_list va; + va_list ap; int rv = 0; if (el == NULL) return (-1); - va_start(va, op); + va_start(ap, op); switch (op) { case EL_PROMPT: case EL_RPROMPT: - rv = prompt_set(el, va_arg(va, el_pfunc_t), op); + rv = prompt_set(el, va_arg(ap, el_pfunc_t), op); break; case EL_TERMINAL: - rv = term_set(el, va_arg(va, char *)); + rv = term_set(el, va_arg(ap, char *)); break; case EL_EDITOR: - rv = map_set_editor(el, va_arg(va, char *)); + rv = map_set_editor(el, va_arg(ap, char *)); break; case EL_SIGNAL: - if (va_arg(va, int)) + if (va_arg(ap, int)) el->el_flags |= HANDLE_SIGNALS; else el->el_flags &= ~HANDLE_SIGNALS; @@ -167,6 +176,7 @@ el_set(EditLine *el, int op, ...) case EL_BIND: case EL_TELLTC: case EL_SETTC: + case EL_GETTC: case EL_ECHOTC: case EL_SETTY: { @@ -174,7 +184,7 @@ el_set(EditLine *el, int op, ...) int i; for (i = 1; i < 20; i++) - if ((argv[i] = va_arg(va, char *)) == NULL) + if ((argv[i] = va_arg(ap, char *)) == NULL) break; switch (op) { @@ -213,9 +223,9 @@ el_set(EditLine *el, int op, ...) case EL_ADDFN: { - char *name = va_arg(va, char *); - char *help = va_arg(va, char *); - el_func_t func = va_arg(va, el_func_t); + char *name = va_arg(ap, char *); + char *help = va_arg(ap, char *); + el_func_t func = va_arg(ap, el_func_t); rv = map_addfunc(el, name, help, func); break; @@ -223,15 +233,15 @@ el_set(EditLine *el, int op, ...) case EL_HIST: { - hist_fun_t func = va_arg(va, hist_fun_t); - ptr_t ptr = va_arg(va, char *); + hist_fun_t func = va_arg(ap, hist_fun_t); + ptr_t ptr = va_arg(ap, char *); rv = hist_set(el, func, ptr); break; } case EL_EDITMODE: - if (va_arg(va, int)) + if (va_arg(ap, int)) el->el_flags &= ~EDIT_DISABLED; else el->el_flags |= EDIT_DISABLED; @@ -240,17 +250,17 @@ el_set(EditLine *el, int op, ...) case EL_GETCFN: { - el_rfunc_t rc = va_arg(va, el_rfunc_t); + el_rfunc_t rc = va_arg(ap, el_rfunc_t); rv = el_read_setfn(el, rc); break; } case EL_CLIENTDATA: - el->el_data = va_arg(va, void *); + el->el_data = va_arg(ap, void *); break; case EL_UNBUFFERED: - rv = va_arg(va, int); + rv = va_arg(ap, int); if (rv && !(el->el_flags & UNBUFFERED)) { el->el_flags |= UNBUFFERED; read_prepare(el); @@ -262,7 +272,7 @@ el_set(EditLine *el, int op, ...) break; case EL_PREP_TERM: - rv = va_arg(va, int); + rv = va_arg(ap, int); if (rv) (void) tty_rawmode(el); else @@ -270,12 +280,45 @@ el_set(EditLine *el, int op, ...) rv = 0; break; + case EL_SETFP: + { + FILE *fp; + int what; + + what = va_arg(ap, int); + fp = va_arg(ap, FILE *); + + rv = 0; + switch (what) { + case 0: + el->el_infile = fp; + el->el_infd = fileno(fp); + break; + case 1: + el->el_outfile = fp; + break; + case 2: + el->el_errfile = fp; + break; + default: + rv = -1; + break; + } + break; + } + + case EL_REFRESH: + re_clear_display(el); + re_refresh(el); + term__flush(el); + break; + default: rv = -1; break; } - va_end(va); + va_end(ap); return (rv); } @@ -284,90 +327,71 @@ el_set(EditLine *el, int op, ...) * retrieve the editline parameters */ public int -el_get(EditLine *el, int op, void *ret) +el_get(EditLine *el, int op, ...) { + va_list ap; int rv; - if (el == NULL || ret == NULL) - return (-1); + if (el == NULL) + return -1; + + va_start(ap, op); + switch (op) { case EL_PROMPT: case EL_RPROMPT: - rv = prompt_get(el, (void *) &ret, op); + rv = prompt_get(el, va_arg(ap, el_pfunc_t *), op); break; case EL_EDITOR: - rv = map_get_editor(el, (void *) &ret); + rv = map_get_editor(el, va_arg(ap, const char **)); break; case EL_SIGNAL: - *((int *) ret) = (el->el_flags & HANDLE_SIGNALS); + *va_arg(ap, int *) = (el->el_flags & HANDLE_SIGNALS); rv = 0; break; case EL_EDITMODE: - *((int *) ret) = (!(el->el_flags & EDIT_DISABLED)); + *va_arg(ap, int *) = !(el->el_flags & EDIT_DISABLED); rv = 0; break; case EL_TERMINAL: - term_get(el, (const char **)ret); + term_get(el, va_arg(ap, const char **)); rv = 0; break; -#if 0 /* XXX */ - case EL_BIND: - case EL_TELLTC: - case EL_SETTC: - case EL_ECHOTC: - case EL_SETTY: + case EL_GETTC: { - const char *argv[20]; + static char name[] = "gettc"; + char *argv[20]; int i; - for (i = 1; i < sizeof(argv) / sizeof(argv[0]); i++) - if ((argv[i] = va_arg(va, char *)) == NULL) + for (i = 1; i < (int)(sizeof(argv) / sizeof(argv[0])); i++) + if ((argv[i] = va_arg(ap, char *)) == NULL) break; switch (op) { - case EL_BIND: - argv[0] = "bind"; - rv = map_bind(el, i, argv); - break; - - case EL_TELLTC: - argv[0] = "telltc"; - rv = term_telltc(el, i, argv); - break; - - case EL_SETTC: - argv[0] = "settc"; - rv = term_settc(el, i, argv); - break; - - case EL_ECHOTC: - argv[0] = "echotc"; - rv = term_echotc(el, i, argv); - break; - - case EL_SETTY: - argv[0] = "setty"; - rv = tty_stty(el, i, argv); + case EL_GETTC: + argv[0] = name; + rv = term_gettc(el, i, argv); break; default: rv = -1; - EL_ABORT((el->errfile, "Bad op %d\n", op)); + EL_ABORT((el->el_errfile, "Bad op %d\n", op)); break; } break; } +#if 0 /* XXX */ case EL_ADDFN: { - char *name = va_arg(va, char *); - char *help = va_arg(va, char *); - el_func_t func = va_arg(va, el_func_t); + char *name = va_arg(ap, char *); + char *help = va_arg(ap, char *); + el_func_t func = va_arg(ap, el_func_t); rv = map_addfunc(el, name, help, func); break; @@ -375,31 +399,57 @@ el_get(EditLine *el, int op, void *ret) case EL_HIST: { - hist_fun_t func = va_arg(va, hist_fun_t); - ptr_t ptr = va_arg(va, char *); + hist_fun_t func = va_arg(ap, hist_fun_t); + ptr_t ptr = va_arg(ap, char *); rv = hist_set(el, func, ptr); } break; #endif /* XXX */ case EL_GETCFN: - *((el_rfunc_t *)ret) = el_read_getfn(el); + *va_arg(ap, el_rfunc_t *) = el_read_getfn(el); rv = 0; break; case EL_CLIENTDATA: - *((void **)ret) = el->el_data; + *va_arg(ap, void **) = el->el_data; rv = 0; break; case EL_UNBUFFERED: - *((int *) ret) = (!(el->el_flags & UNBUFFERED)); + *va_arg(ap, int *) = (!(el->el_flags & UNBUFFERED)); rv = 0; break; + case EL_GETFP: + { + int what; + FILE **fpp; + + what = va_arg(ap, int); + fpp = va_arg(ap, FILE **); + rv = 0; + switch (what) { + case 0: + *fpp = el->el_infile; + break; + case 1: + *fpp = el->el_outfile; + break; + case 2: + *fpp = el->el_errfile; + break; + default: + rv = -1; + break; + } + break; + } default: rv = -1; + break; } + va_end(ap); return (rv); } @@ -428,17 +478,17 @@ el_source(EditLine *el, const char *fname) fp = NULL; if (fname == NULL) { +#ifdef HAVE_ISSETUGID static const char elpath[] = "/.editrc"; +/* XXXMYSQL: Portability fix (for which platforms?) */ #ifdef MAXPATHLEN char path[MAXPATHLEN]; #else char path[4096]; #endif -#ifdef HAVE_ISSETUGID if (issetugid()) return (-1); -#endif if ((ptr = getenv("HOME")) == NULL) return (-1); if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path)) @@ -446,6 +496,14 @@ el_source(EditLine *el, const char *fname) if (strlcat(path, elpath, sizeof(path)) >= sizeof(path)) return (-1); fname = path; +#else + /* + * If issetugid() is missing, always return an error, in order + * to keep from inadvertently opening up the user to a security + * hole. + */ + return (-1); +#endif } if (fp == NULL) fp = fopen(fname, "r"); diff --git a/cmd-line-utils/libedit/el.h b/cmd-line-utils/libedit/el.h index d9379d7c8aa..05d88ad88ba 100644 --- a/cmd-line-utils/libedit/el.h +++ b/cmd-line-utils/libedit/el.h @@ -1,4 +1,4 @@ -/* $NetBSD: el.h,v 1.16 2003/10/18 23:48:42 christos Exp $ */ +/* $NetBSD: el.h,v 1.17 2006/12/15 22:13:33 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -110,6 +110,7 @@ typedef struct el_state_t { struct editline { char *el_prog; /* the program name */ + FILE *el_infile; /* Stdio stuff */ FILE *el_outfile; /* Stdio stuff */ FILE *el_errfile; /* Stdio stuff */ int el_infd; /* Input file descriptor */ @@ -136,7 +137,8 @@ struct editline { protected int el_editmode(EditLine *, int, const char **); -#define el_isprint(x) ((unsigned char) (x) < 0x80 ? isprint(x) : 1) +/* XXXMYSQL: Bug#23097 mysql can't insert korean on mysql prompt. */ +#define el_isprint(x) ((unsigned char) (x) < 0x80 ? isprint(x) : 1) #ifdef DEBUG #define EL_ABORT(a) do { \ diff --git a/cmd-line-utils/libedit/el_term.h b/cmd-line-utils/libedit/el_term.h index 00ca48e38e2..0e7ddd555f4 100644 --- a/cmd-line-utils/libedit/el_term.h +++ b/cmd-line-utils/libedit/el_term.h @@ -1,4 +1,4 @@ -/* $NetBSD: term.h,v 1.15 2003/09/14 21:48:55 christos Exp $ */ +/* $NetBSD: term.h,v 1.19 2008/09/10 15:45:37 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -81,25 +81,6 @@ typedef struct { #define A_K_EN 5 #define A_K_NKEYS 6 -#ifdef _SUNOS -extern int tgetent(char *, const char *); -extern int tgetflag(char *); -extern int tgetnum(char *); -extern int tputs(const char *, int, int (*)(int)); -extern char* tgoto(const char*, int, int); -extern char* tgetstr(char*, char**); -#endif - - -#if !HAVE_DECL_TGOTO -/* - 'tgoto' is not declared in the system header files, this causes - problems on 64-bit systems. The function returns a 64 bit pointer - but caller see it as "int" and it's thus truncated to 32-bit -*/ -extern char* tgoto(const char*, int, int); -#endif - protected void term_move_to_line(EditLine *, int); protected void term_move_to_char(EditLine *, int); protected void term_clear_EOL(EditLine *, int); @@ -119,10 +100,12 @@ protected void term_end(EditLine *); protected void term_get(EditLine *, const char **); protected int term_set(EditLine *, const char *); protected int term_settc(EditLine *, int, const char **); +protected int term_gettc(EditLine *, int, char **); protected int term_telltc(EditLine *, int, const char **); protected int term_echotc(EditLine *, int, const char **); -protected int term__putc(int); -protected void term__flush(void); +protected void term_writec(EditLine *, int); +protected int term__putc(EditLine *, int); +protected void term__flush(EditLine *); /* * Easy access macros @@ -134,6 +117,7 @@ protected void term__flush(void); #define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL) #define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB) #define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME) +#define EL_CAN_UP (EL_FLAGS & TERM_CAN_UP) #define EL_HAS_META (EL_FLAGS & TERM_HAS_META) #define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS) #define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS) diff --git a/cmd-line-utils/libedit/emacs.c b/cmd-line-utils/libedit/emacs.c index 79f2bf0c818..135bd75f566 100644 --- a/cmd-line-utils/libedit/emacs.c +++ b/cmd-line-utils/libedit/emacs.c @@ -1,4 +1,4 @@ -/* $NetBSD: emacs.c,v 1.19 2004/10/28 21:14:52 dsl Exp $ */ +/* $NetBSD: emacs.c,v 1.21 2006/03/06 21:11:56 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * emacs.c: Emacs functions @@ -45,15 +51,14 @@ */ protected el_action_t /*ARGSUSED*/ -em_delete_or_list(EditLine *el, int c __attribute__((__unused__))) +em_delete_or_list(EditLine *el, int c) { if (el->el_line.cursor == el->el_line.lastchar) { /* if I'm at the end */ if (el->el_line.cursor == el->el_line.buffer) { /* and the beginning */ - term_overwrite(el, STReof, 4); /* then do a EOF */ - term__flush(); + term_writec(el, c); /* then do an EOF */ return (CC_EOF); } else { /* diff --git a/cmd-line-utils/libedit/fgetln.c b/cmd-line-utils/libedit/fgetln.c deleted file mode 100644 index 5b95b2f6584..00000000000 --- a/cmd-line-utils/libedit/fgetln.c +++ /dev/null @@ -1,88 +0,0 @@ -/* $NetBSD: fgetln.c,v 1.2 2003/12/10 01:30:27 lukem Exp $ */ - -/*- - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Christos Zoulas. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include - - -char * -fgetln(FILE *fp, size_t *len) -{ - static char *buf = NULL; - static size_t bufsiz = 0; - char *ptr; - - - if (buf == NULL) { - bufsiz = BUFSIZ; - if ((buf = malloc(bufsiz)) == NULL) - return NULL; - } - - if (fgets(buf, bufsiz, fp) == NULL) - return NULL; - *len = 0; - - while ((ptr = strchr(&buf[*len], '\n')) == NULL) { - size_t nbufsiz = bufsiz + BUFSIZ; - char *nbuf = realloc(buf, nbufsiz); - - if (nbuf == NULL) { - int oerrno = errno; - free(buf); - errno = oerrno; - buf = NULL; - return NULL; - } else - buf = nbuf; - - *len = bufsiz; - if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) - return buf; - - bufsiz = nbufsiz; - } - - *len = (ptr - buf) + 1; - return buf; -} - diff --git a/cmd-line-utils/libedit/fgetln.h b/cmd-line-utils/libedit/fgetln.h deleted file mode 100644 index b2ddce01da9..00000000000 --- a/cmd-line-utils/libedit/fgetln.h +++ /dev/null @@ -1,3 +0,0 @@ -#include - -char *fgetln(FILE *stream, size_t *len); diff --git a/cmd-line-utils/libedit/filecomplete.c b/cmd-line-utils/libedit/filecomplete.c new file mode 100644 index 00000000000..4c63f57bc45 --- /dev/null +++ b/cmd-line-utils/libedit/filecomplete.c @@ -0,0 +1,558 @@ +/* $NetBSD: filecomplete.c,v 1.13 2009/01/26 17:32:41 apb Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jaromir Dolecek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* AIX requires this to be the first thing in the file. */ +#if defined (_AIX) && !defined (__GNUC__) + #pragma alloca +#endif + +#include "config.h" + +/* XXXMYSQL */ +#ifdef __GNUC__ +# undef alloca +# define alloca(n) __builtin_alloca (n) +#else +# ifdef HAVE_ALLOCA_H +# include +# else +# ifndef _AIX +extern char *alloca (); +# endif +# endif +#endif + +#if !defined(lint) && !defined(SCCSID) +#endif /* not lint && not SCCSID */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_VIS_H +#include +#else +#include "np/vis.h" +#endif +#ifdef HAVE_ALLOCA_H +#include +#endif +#include "el.h" +#include "fcns.h" /* for EL_NUM_FCNS */ +#include "histedit.h" +#include "filecomplete.h" + +static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', + '>', '<', '=', ';', '|', '&', '{', '(', '\0' }; + + +/********************************/ +/* completion functions */ + +/* + * does tilde expansion of strings of type ``~user/foo'' + * if ``user'' isn't valid user name or ``txt'' doesn't start + * w/ '~', returns pointer to strdup()ed copy of ``txt'' + * + * it's callers's responsibility to free() returned string + */ +char * +fn_tilde_expand(const char *txt) +{ + struct passwd pwres, *pass; + char *temp; + size_t len = 0; + char pwbuf[1024]; + + if (txt[0] != '~') + return (strdup(txt)); + + temp = strchr(txt + 1, '/'); + if (temp == NULL) { + temp = strdup(txt + 1); + if (temp == NULL) + return NULL; + } else { + len = temp - txt + 1; /* text until string after slash */ + temp = malloc(len); + if (temp == NULL) + return NULL; + (void)strncpy(temp, txt + 1, len - 2); + temp[len - 2] = '\0'; + } + /* XXXMYSQL: use non-_r functions for now */ + if (temp[0] == 0) { + pass = getpwuid(getuid()); + } else { + pass = getpwnam(temp); + } + free(temp); /* value no more needed */ + if (pass == NULL) + return (strdup(txt)); + + /* update pointer txt to point at string immedially following */ + /* first slash */ + txt += len; + + temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1); + if (temp == NULL) + return NULL; + (void)sprintf(temp, "%s/%s", pass->pw_dir, txt); + + return (temp); +} + + +/* + * return first found file name starting by the ``text'' or NULL if no + * such file can be found + * value of ``state'' is ignored + * + * it's caller's responsibility to free returned string + */ +char * +fn_filename_completion_function(const char *text, int state) +{ + static DIR *dir = NULL; + static char *filename = NULL, *dirname = NULL, *dirpath = NULL; + static size_t filename_len = 0; + struct dirent *entry; + char *temp; + size_t len; + + if (state == 0 || dir == NULL) { + temp = strrchr(text, '/'); + if (temp) { + char *nptr; + temp++; + nptr = realloc(filename, strlen(temp) + 1); + if (nptr == NULL) { + free(filename); + return NULL; + } + filename = nptr; + (void)strcpy(filename, temp); + len = temp - text; /* including last slash */ + nptr = realloc(dirname, len + 1); + if (nptr == NULL) { + free(filename); + return NULL; + } + dirname = nptr; + (void)strncpy(dirname, text, len); + dirname[len] = '\0'; + } else { + if (*text == 0) + filename = NULL; + else { + filename = strdup(text); + if (filename == NULL) + return NULL; + } + dirname = NULL; + } + + if (dir != NULL) { + (void)closedir(dir); + dir = NULL; + } + + /* support for ``~user'' syntax */ + free(dirpath); + + if (dirname == NULL && (dirname = strdup("./")) == NULL) + return NULL; + + if (*dirname == '~') + dirpath = fn_tilde_expand(dirname); + else + dirpath = strdup(dirname); + + if (dirpath == NULL) + return NULL; + + dir = opendir(dirpath); + if (!dir) + return (NULL); /* cannot open the directory */ + + /* will be used in cycle */ + filename_len = filename ? strlen(filename) : 0; + } + + /* find the match */ + while ((entry = readdir(dir)) != NULL) { + /* skip . and .. */ + if (entry->d_name[0] == '.' && (!entry->d_name[1] + || (entry->d_name[1] == '.' && !entry->d_name[2]))) + continue; + if (filename_len == 0) + break; + /* otherwise, get first entry where first */ + /* filename_len characters are equal */ + if (entry->d_name[0] == filename[0] +#if HAVE_STRUCT_DIRENT_D_NAMLEN + && entry->d_namlen >= filename_len +#else + && strlen(entry->d_name) >= filename_len +#endif + && strncmp(entry->d_name, filename, + filename_len) == 0) + break; + } + + if (entry) { /* match found */ + +#if HAVE_STRUCT_DIRENT_D_NAMLEN + len = entry->d_namlen; +#else + len = strlen(entry->d_name); +#endif + + temp = malloc(strlen(dirname) + len + 1); + if (temp == NULL) + return NULL; + (void)sprintf(temp, "%s%s", dirname, entry->d_name); + } else { + (void)closedir(dir); + dir = NULL; + temp = NULL; + } + + return (temp); +} + + +static const char * +append_char_function(const char *name) +{ + struct stat stbuf; + char *expname = *name == '~' ? fn_tilde_expand(name) : NULL; + const char *rs = " "; + + if (stat(expname ? expname : name, &stbuf) == -1) + goto out; + if (S_ISDIR(stbuf.st_mode)) + rs = "/"; +out: + if (expname) + free(expname); + return rs; +} +/* + * returns list of completions for text given + * non-static for readline. + */ +char ** completion_matches(const char *, char *(*)(const char *, int)); +char ** +completion_matches(const char *text, char *(*genfunc)(const char *, int)) +{ + char **match_list = NULL, *retstr, *prevstr; + size_t match_list_len, max_equal, which, i; + size_t matches; + + matches = 0; + match_list_len = 1; + while ((retstr = (*genfunc) (text, (int)matches)) != NULL) { + /* allow for list terminator here */ + if (matches + 3 >= match_list_len) { + char **nmatch_list; + while (matches + 3 >= match_list_len) + match_list_len <<= 1; + nmatch_list = realloc(match_list, + match_list_len * sizeof(char *)); + if (nmatch_list == NULL) { + free(match_list); + return NULL; + } + match_list = nmatch_list; + + } + match_list[++matches] = retstr; + } + + if (!match_list) + return NULL; /* nothing found */ + + /* find least denominator and insert it to match_list[0] */ + which = 2; + prevstr = match_list[1]; + max_equal = strlen(prevstr); + for (; which <= matches; which++) { + for (i = 0; i < max_equal && + prevstr[i] == match_list[which][i]; i++) + continue; + max_equal = i; + } + + retstr = malloc(max_equal + 1); + if (retstr == NULL) { + free(match_list); + return NULL; + } + (void)strncpy(retstr, match_list[1], max_equal); + retstr[max_equal] = '\0'; + match_list[0] = retstr; + + /* add NULL as last pointer to the array */ + match_list[matches + 1] = (char *) NULL; + + return (match_list); +} + +/* + * Sort function for qsort(). Just wrapper around strcasecmp(). + */ +static int +_fn_qsort_string_compare(const void *i1, const void *i2) +{ + const char *s1 = ((const char * const *)i1)[0]; + const char *s2 = ((const char * const *)i2)[0]; + + return strcasecmp(s1, s2); +} + +/* + * Display list of strings in columnar format on readline's output stream. + * 'matches' is list of strings, 'len' is number of strings in 'matches', + * 'max' is maximum length of string in 'matches'. + */ +void +fn_display_match_list (EditLine *el, char **matches, int len, int max) +{ + int i, idx, limit, count; + int screenwidth = el->el_term.t_size.h; + + /* + * Find out how many entries can be put on one line, count + * with two spaces between strings. + */ + limit = screenwidth / (max + 2); + if (limit == 0) + limit = 1; + + /* how many lines of output */ + count = len / limit; + if (count * limit < len) + count++; + + /* Sort the items if they are not already sorted. */ + qsort(&matches[1], (size_t)(len - 1), sizeof(char *), + _fn_qsort_string_compare); + + idx = 1; + for(; count > 0; count--) { + for(i = 0; i < limit && matches[idx]; i++, idx++) + (void)fprintf(el->el_outfile, "%-*s ", max, + matches[idx]); + (void)fprintf(el->el_outfile, "\n"); + } +} + +/* + * Complete the word at or before point, + * 'what_to_do' says what to do with the completion. + * \t means do standard completion. + * `?' means list the possible completions. + * `*' means insert all of the possible completions. + * `!' means to do standard completion, and list all possible completions if + * there is more than one. + * + * Note: '*' support is not implemented + * '!' could never be invoked + */ +int +fn_complete(EditLine *el, + char *(*complet_func)(const char *, int), + char **(*attempted_completion_function)(const char *, int, int), + const char *word_break, const char *special_prefixes, + const char *(*app_func)(const char *), int query_items, + int *completion_type, int *over, int *point, int *end) +{ + const LineInfo *li; + char *temp, **matches; + const char *ctemp; + size_t len; + int what_to_do = '\t'; + int retval = CC_NORM; + + if (el->el_state.lastcmd == el->el_state.thiscmd) + what_to_do = '?'; + + /* readline's rl_complete() has to be told what we did... */ + if (completion_type != NULL) + *completion_type = what_to_do; + + if (!complet_func) + complet_func = fn_filename_completion_function; + if (!app_func) + app_func = append_char_function; + + /* We now look backwards for the start of a filename/variable word */ + li = el_line(el); + ctemp = (const char *) li->cursor; + while (ctemp > li->buffer + && !strchr(word_break, ctemp[-1]) + && (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) ) + ctemp--; + + len = li->cursor - ctemp; +#if defined(__SSP__) || defined(__SSP_ALL__) + temp = malloc(len + 1); +#else + temp = alloca(len + 1); +#endif + (void)strncpy(temp, ctemp, len); + temp[len] = '\0'; + + /* these can be used by function called in completion_matches() */ + /* or (*attempted_completion_function)() */ + if (point != 0) + *point = li->cursor - li->buffer; + if (end != NULL) + *end = li->lastchar - li->buffer; + + if (attempted_completion_function) { + int cur_off = li->cursor - li->buffer; + matches = (*attempted_completion_function) (temp, + (int)(cur_off - len), cur_off); + } else + matches = 0; + if (!attempted_completion_function || + (over != NULL && !*over && !matches)) + matches = completion_matches(temp, complet_func); + + if (over != NULL) + *over = 0; + + if (matches) { + int i; + int matches_num, maxlen, match_len, match_display=1; + + retval = CC_REFRESH; + /* + * Only replace the completed string with common part of + * possible matches if there is possible completion. + */ + if (matches[0][0] != '\0') { + el_deletestr(el, (int) len); + el_insertstr(el, matches[0]); + } + + if (what_to_do == '?') + goto display_matches; + + if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) { + /* + * We found exact match. Add a space after + * it, unless we do filename completion and the + * object is a directory. + */ + el_insertstr(el, (*app_func)(matches[0])); + } else if (what_to_do == '!') { + display_matches: + /* + * More than one match and requested to list possible + * matches. + */ + + for(i=1, maxlen=0; matches[i]; i++) { + match_len = strlen(matches[i]); + if (match_len > maxlen) + maxlen = match_len; + } + matches_num = i - 1; + + /* newline to get on next line from command line */ + (void)fprintf(el->el_outfile, "\n"); + + /* + * If there are too many items, ask user for display + * confirmation. + */ + if (matches_num > query_items) { + (void)fprintf(el->el_outfile, + "Display all %d possibilities? (y or n) ", + matches_num); + (void)fflush(el->el_outfile); + if (getc(stdin) != 'y') + match_display = 0; + (void)fprintf(el->el_outfile, "\n"); + } + + if (match_display) + fn_display_match_list(el, matches, matches_num, + maxlen); + retval = CC_REDISPLAY; + } else if (matches[0][0]) { + /* + * There was some common match, but the name was + * not complete enough. Next tab will print possible + * completions. + */ + el_beep(el); + } else { + /* lcd is not a valid object - further specification */ + /* is needed */ + el_beep(el); + retval = CC_NORM; + } + + /* free elements of array and the array itself */ + for (i = 0; matches[i]; i++) + free(matches[i]); + free(matches); + matches = NULL; + } +#if defined(__SSP__) || defined(__SSP_ALL__) + free(temp); +#endif + return retval; +} + +/* + * el-compatible wrapper around rl_complete; needed for key binding + */ +/* ARGSUSED */ +unsigned char +_el_fn_complete(EditLine *el, int ch __attribute__((__unused__))) +{ + return (unsigned char)fn_complete(el, NULL, NULL, + break_chars, NULL, NULL, 100, + NULL, NULL, NULL, NULL); +} diff --git a/cmd-line-utils/libedit/filecomplete.h b/cmd-line-utils/libedit/filecomplete.h new file mode 100644 index 00000000000..12e0c6f14b0 --- /dev/null +++ b/cmd-line-utils/libedit/filecomplete.h @@ -0,0 +1,44 @@ +/* $NetBSD: filecomplete.h,v 1.6 2008/04/29 06:53:01 martin Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jaromir Dolecek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FILECOMPLETE_H_ +#define _FILECOMPLETE_H_ + +int fn_complete(EditLine *, + char *(*)(const char *, int), + char **(*)(const char *, int, int), + const char *, const char *, const char *(*)(const char *), int, + int *, int *, int *, int *); + +void fn_display_match_list(EditLine *, char **, int, int); +char *fn_tilde_expand(const char *); +char *fn_filename_completion_function(const char *, int); + +#endif diff --git a/cmd-line-utils/libedit/hist.c b/cmd-line-utils/libedit/hist.c index e8f5c0f39ba..c0b23ee6641 100644 --- a/cmd-line-utils/libedit/hist.c +++ b/cmd-line-utils/libedit/hist.c @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * hist.c: History access functions diff --git a/cmd-line-utils/libedit/histedit.h b/cmd-line-utils/libedit/histedit.h index c58eb62dcfa..37823141c06 100644 --- a/cmd-line-utils/libedit/histedit.h +++ b/cmd-line-utils/libedit/histedit.h @@ -1,4 +1,4 @@ -/* $NetBSD: histedit.h,v 1.25 2003/12/05 13:37:48 lukem Exp $ */ +/* $NetBSD: histedit.h,v 1.35 2009/02/05 19:15:44 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -41,11 +41,15 @@ #define _HISTEDIT_H_ #define LIBEDIT_MAJOR 2 -#define LIBEDIT_MINOR 9 +#define LIBEDIT_MINOR 11 #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* * ==== Editing ==== */ @@ -88,7 +92,7 @@ void el_reset(EditLine *); */ const char *el_gets(EditLine *, int *); int el_getc(EditLine *, char *); -void el_push(EditLine *, char *); +void el_push(EditLine *, const char *); /* * Beep! @@ -105,7 +109,8 @@ int el_parse(EditLine *, int, const char **); * Low level editline access functions */ int el_set(EditLine *, int, ...); -int el_get(EditLine *, int, void *); +int el_get(EditLine *, int, ...); +unsigned char _el_fn_complete(EditLine *, int); /* * el_set/el_get parameters @@ -128,8 +133,12 @@ int el_get(EditLine *, int, void *); #define EL_CLIENTDATA 14 /* , void *); */ #define EL_UNBUFFERED 15 /* , int); */ #define EL_PREP_TERM 16 /* , int); */ +#define EL_GETTC 17 /* , const char *, ..., NULL); */ +#define EL_GETFP 18 /* , int, FILE **); */ +#define EL_SETFP 19 /* , int, FILE *); */ +#define EL_REFRESH 20 /* , void); */ -#define EL_BUILTIN_GETCFN (NULL) +#define EL_BUILTIN_GETCFN (NULL) /* * Source named file or $PWD/.editrc or $HOME/.editrc @@ -192,6 +201,7 @@ int history(History *, HistEvent *, int, ...); #define H_CLEAR 19 /* , void); */ #define H_SETUNIQUE 20 /* , int); */ #define H_GETUNIQUE 21 /* , void); */ +#define H_DEL 22 /* , int); */ /* @@ -211,4 +221,8 @@ int tok_line(Tokenizer *, const LineInfo *, int tok_str(Tokenizer *, const char *, int *, const char ***); +#ifdef __cplusplus +} +#endif + #endif /* _HISTEDIT_H_ */ diff --git a/cmd-line-utils/libedit/history.c b/cmd-line-utils/libedit/history.c index c0fa7cc717d..3080dd231f6 100644 --- a/cmd-line-utils/libedit/history.c +++ b/cmd-line-utils/libedit/history.c @@ -1,4 +1,4 @@ -/* $NetBSD: history.c,v 1.28 2004/11/27 18:31:45 christos Exp $ */ +/* $NetBSD: history.c,v 1.33 2009/02/06 14:40:32 sketch Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * hist.c: History access functions @@ -40,7 +46,11 @@ #include #include #include +#ifdef HAVE_VIS_H #include +#else +#include "np/vis.h" +#endif #include static const char hist_cookie[] = "_HiStOrY_V2_\n"; @@ -61,6 +71,7 @@ struct history { history_gfun_t h_prev; /* Get the previous element */ history_gfun_t h_curr; /* Get the current element */ history_sfun_t h_set; /* Set the current element */ + history_sfun_t h_del; /* Set the given element */ history_vfun_t h_clear; /* Clear the history list */ history_efun_t h_enter; /* Add an element */ history_efun_t h_add; /* Append to an element */ @@ -75,6 +86,7 @@ struct history { #define HCLEAR(h, ev) (*(h)->h_clear)((h)->h_ref, ev) #define HENTER(h, ev, str) (*(h)->h_enter)((h)->h_ref, ev, str) #define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str) +#define HDEL(h, ev, n) (*(h)->h_del)((h)->h_ref, ev, n) #define h_strdup(a) strdup(a) #define h_malloc(a) malloc(a) @@ -122,16 +134,18 @@ typedef struct history_t { #define H_UNIQUE 1 /* Store only unique elements */ } history_t; -private int history_def_first(ptr_t, HistEvent *); -private int history_def_last(ptr_t, HistEvent *); private int history_def_next(ptr_t, HistEvent *); +private int history_def_first(ptr_t, HistEvent *); private int history_def_prev(ptr_t, HistEvent *); +private int history_def_last(ptr_t, HistEvent *); private int history_def_curr(ptr_t, HistEvent *); -private int history_def_set(ptr_t, HistEvent *, const int n); +private int history_def_set(ptr_t, HistEvent *, const int); +private void history_def_clear(ptr_t, HistEvent *); private int history_def_enter(ptr_t, HistEvent *, const char *); private int history_def_add(ptr_t, HistEvent *, const char *); +private int history_def_del(ptr_t, HistEvent *, const int); + private int history_def_init(ptr_t *, HistEvent *, int); -private void history_def_clear(ptr_t, HistEvent *); private int history_def_insert(history_t *, HistEvent *, const char *); private void history_def_delete(history_t *, HistEvent *, hentry_t *); @@ -353,6 +367,24 @@ history_def_add(ptr_t p, HistEvent *ev, const char *str) } +/* history_def_del(): + * Delete element hp of the h list + */ +/* ARGSUSED */ +private int +history_def_del(ptr_t p, HistEvent *ev __attribute__((__unused__)), + const int num) +{ + history_t *h = (history_t *) p; + if (history_def_set(h, ev, num) != 0) + return (-1); + ev->str = strdup(h->cursor->ev.str); + ev->num = h->cursor->ev.num; + history_def_delete(h, ev, h->cursor); + return (0); +} + + /* history_def_delete(): * Delete element hp of the h list */ @@ -364,6 +396,8 @@ history_def_delete(history_t *h, HistEventPrivate *evp = (void *)&hp->ev; if (hp == &h->list) abort(); + if (h->cursor == hp) + h->cursor = hp->prev; hp->prev->next = hp->next; hp->next->prev = hp->prev; h_free((ptr_t) evp->str); @@ -497,6 +531,7 @@ history_init(void) h->h_clear = history_def_clear; h->h_enter = history_def_enter; h->h_add = history_def_add; + h->h_del = history_def_del; return (h); } @@ -512,6 +547,8 @@ history_end(History *h) if (h->h_next == history_def_next) history_def_clear(h->h_ref, &ev); + h_free(h->h_ref); + h_free(h); } @@ -597,7 +634,7 @@ history_set_fun(History *h, History *nh) if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL || nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == NULL || nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL || - nh->h_ref == NULL) { + nh->h_del == NULL || nh->h_ref == NULL) { if (h->h_next != history_def_next) { history_def_init(&h->h_ref, &ev, 0); h->h_first = history_def_first; @@ -609,6 +646,7 @@ history_set_fun(History *h, History *nh) h->h_clear = history_def_clear; h->h_enter = history_def_enter; h->h_add = history_def_add; + h->h_del = history_def_del; } return (-1); } @@ -625,6 +663,7 @@ history_set_fun(History *h, History *nh) h->h_clear = nh->h_clear; h->h_enter = nh->h_enter; h->h_add = nh->h_add; + h->h_del = nh->h_del; return (0); } @@ -676,8 +715,8 @@ history_load(History *h, const char *fname) (void) strunvis(ptr, line); line[sz] = c; if (HENTER(h, &ev, ptr) == -1) { - i = -1; - goto oomem; + i = -1; + goto oomem; } } oomem: @@ -841,6 +880,10 @@ history(History *h, HistEvent *ev, int fun, ...) retval = HADD(h, ev, str); break; + case H_DEL: + retval = HDEL(h, ev, va_arg(va, const int)); + break; + case H_ENTER: str = va_arg(va, const char *); if ((retval = HENTER(h, ev, str)) != -1) @@ -925,6 +968,7 @@ history(History *h, HistEvent *ev, int fun, ...) hf.h_clear = va_arg(va, history_vfun_t); hf.h_enter = va_arg(va, history_efun_t); hf.h_add = va_arg(va, history_efun_t); + hf.h_del = va_arg(va, history_sfun_t); if ((retval = history_set_fun(h, &hf)) == -1) he_seterrev(ev, _HE_PARAM_MISSING); diff --git a/cmd-line-utils/libedit/key.c b/cmd-line-utils/libedit/key.c index 35fcf0651b2..cda02816861 100644 --- a/cmd-line-utils/libedit/key.c +++ b/cmd-line-utils/libedit/key.c @@ -1,4 +1,4 @@ -/* $NetBSD: key.c,v 1.15 2003/10/18 23:48:42 christos Exp $ */ +/* $NetBSD: key.c,v 1.19 2006/03/23 20:22:51 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,14 +32,20 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * key.c: This module contains the procedures for maintaining * the extended-key map. * * An extended-key (key) is a sequence of keystrokes introduced - * with an sequence introducer and consisting of an arbitrary + * with a sequence introducer and consisting of an arbitrary * number of characters. This module maintains a map (the el->el_key.map) * to convert these extended-key sequences into input strs * (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE). @@ -78,12 +84,12 @@ private int node_trav(EditLine *, key_node_t *, char *, private int node__try(EditLine *, key_node_t *, const char *, key_value_t *, int); private key_node_t *node__get(int); +private void node__free(key_node_t *); private void node__put(EditLine *, key_node_t *); private int node__delete(EditLine *, key_node_t **, const char *); private int node_lookup(EditLine *, const char *, key_node_t *, int); private int node_enum(EditLine *, key_node_t *, int); -private int key__decode_char(char *, int, int); #define KEY_BUFSIZ EL_BUFSIZ @@ -103,7 +109,6 @@ key_init(EditLine *el) return (0); } - /* key_end(): * Free the key maps */ @@ -113,8 +118,7 @@ key_end(EditLine *el) el_free((ptr_t) el->el_key.buf); el->el_key.buf = NULL; - /* XXX: provide a function to clear the keys */ - el->el_key.map = NULL; + node__free(el->el_key.map); } @@ -443,7 +447,7 @@ node__put(EditLine *el, key_node_t *ptr) /* node__get(): - * Returns pointer to an key_node_t for ch. + * Returns pointer to a key_node_t for ch. */ private key_node_t * node__get(int ch) @@ -461,7 +465,15 @@ node__get(int ch) return (ptr); } - +private void +node__free(key_node_t *k) +{ + if (k == NULL) + return; + node__free(k->sibling); + node__free(k->next); + el_free((ptr_t) k); +} /* node_lookup(): * look for the str starting at node ptr. @@ -483,7 +495,7 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt) /* If match put this char into el->el_key.buf. Recurse */ if (ptr->ch == *str) { /* match found */ - ncnt = key__decode_char(el->el_key.buf, cnt, + ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt, (unsigned char) ptr->ch); if (ptr->next != NULL) /* not yet at leaf */ @@ -537,7 +549,8 @@ node_enum(EditLine *el, key_node_t *ptr, int cnt) return (-1); } /* put this char at end of str */ - ncnt = key__decode_char(el->el_key.buf, cnt, (unsigned char) ptr->ch); + ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt, + (unsigned char)ptr->ch); if (ptr->next == NULL) { /* print this key and function */ el->el_key.buf[ncnt + 1] = '"'; @@ -568,9 +581,10 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype) switch (ntype) { case XK_STR: case XK_EXE: - (void) fprintf(el->el_outfile, fmt, key, - key__decode_str(val->str, unparsbuf, - ntype == XK_STR ? "\"\"" : "[]")); + (void) key__decode_str(val->str, unparsbuf, + sizeof(unparsbuf), + ntype == XK_STR ? "\"\"" : "[]"); + (void) fprintf(el->el_outfile, fmt, key, unparsbuf); break; case XK_CMD: for (fp = el->el_map.help; fp->name; fp++) @@ -595,83 +609,97 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype) } +#define ADDC(c) \ + if (b < eb) \ + *b++ = c; \ + else \ + b++ /* key__decode_char(): * Put a printable form of char in buf. */ -private int -key__decode_char(char *buf, int cnt, int ch) +protected int +key__decode_char(char *buf, int cnt, int off, int ch) { + char *sb = buf + off; + char *eb = buf + cnt; + char *b = sb; if (ch == 0) { - buf[cnt++] = '^'; - buf[cnt] = '@'; - return (cnt); + ADDC('^'); + ADDC('@'); + return b - sb; } if (iscntrl(ch)) { - buf[cnt++] = '^'; + ADDC('^'); if (ch == '\177') - buf[cnt] = '?'; + ADDC('?'); else - buf[cnt] = ch | 0100; + ADDC(ch | 0100); } else if (ch == '^') { - buf[cnt++] = '\\'; - buf[cnt] = '^'; + ADDC('\\'); + ADDC('^'); } else if (ch == '\\') { - buf[cnt++] = '\\'; - buf[cnt] = '\\'; + ADDC('\\'); + ADDC('\\'); } else if (ch == ' ' || (el_isprint(ch) && !isspace(ch))) { - buf[cnt] = ch; + ADDC(ch); } else { - buf[cnt++] = '\\'; - buf[cnt++] = (((unsigned int) ch >> 6) & 7) + '0'; - buf[cnt++] = (((unsigned int) ch >> 3) & 7) + '0'; - buf[cnt] = (ch & 7) + '0'; + ADDC('\\'); + ADDC((((unsigned int) ch >> 6) & 7) + '0'); + ADDC((((unsigned int) ch >> 3) & 7) + '0'); + ADDC((ch & 7) + '0'); } - return (cnt); + return b - sb; } /* key__decode_str(): * Make a printable version of the ey */ -protected char * -key__decode_str(const char *str, char *buf, const char *sep) +protected int +key__decode_str(const char *str, char *buf, int len, const char *sep) { - char *b; + char *b = buf, *eb = b + len; const char *p; b = buf; - if (sep[0] != '\0') - *b++ = sep[0]; - if (*str == 0) { - *b++ = '^'; - *b++ = '@'; - if (sep[0] != '\0' && sep[1] != '\0') - *b++ = sep[1]; - *b++ = 0; - return (buf); + if (sep[0] != '\0') { + ADDC(sep[0]); + } + if (*str == '\0') { + ADDC('^'); + ADDC('@'); + if (sep[0] != '\0' && sep[1] != '\0') { + ADDC(sep[1]); + } + goto done; } for (p = str; *p != 0; p++) { if (iscntrl((unsigned char) *p)) { - *b++ = '^'; - if (*p == '\177') - *b++ = '?'; - else - *b++ = *p | 0100; + ADDC('^'); + if (*p == '\177') { + ADDC('?'); + } else { + ADDC(*p | 0100); + } } else if (*p == '^' || *p == '\\') { - *b++ = '\\'; - *b++ = *p; + ADDC('\\'); + ADDC(*p); } else if (*p == ' ' || (el_isprint((unsigned char) *p) && !isspace((unsigned char) *p))) { - *b++ = *p; + ADDC(*p); } else { - *b++ = '\\'; - *b++ = (((unsigned int) *p >> 6) & 7) + '0'; - *b++ = (((unsigned int) *p >> 3) & 7) + '0'; - *b++ = (*p & 7) + '0'; + ADDC('\\'); + ADDC((((unsigned int) *p >> 6) & 7) + '0'); + ADDC((((unsigned int) *p >> 3) & 7) + '0'); + ADDC((*p & 7) + '0'); } } - if (sep[0] != '\0' && sep[1] != '\0') - *b++ = sep[1]; - *b++ = 0; - return (buf); /* should check for overflow */ + if (sep[0] != '\0' && sep[1] != '\0') { + ADDC(sep[1]); + } +done: + ADDC('\0'); + if (b - buf >= len) + buf[len - 1] = '\0'; + return b - buf; } diff --git a/cmd-line-utils/libedit/key.h b/cmd-line-utils/libedit/key.h index 39a075c504e..9c6844e6d99 100644 --- a/cmd-line-utils/libedit/key.h +++ b/cmd-line-utils/libedit/key.h @@ -1,4 +1,4 @@ -/* $NetBSD: key.h,v 1.8 2003/08/07 16:44:32 agc Exp $ */ +/* $NetBSD: key.h,v 1.10 2006/03/23 20:22:51 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -74,6 +74,8 @@ protected int key_delete(EditLine *, const char *); protected void key_print(EditLine *, const char *); protected void key_kprint(EditLine *, const char *, key_value_t *, int); -protected char *key__decode_str(const char *, char *, const char *); +protected int key__decode_str(const char *, char *, int, + const char *); +protected int key__decode_char(char *, int, int, int); #endif /* _h_el_key */ diff --git a/cmd-line-utils/libedit/libedit_term.h b/cmd-line-utils/libedit/libedit_term.h deleted file mode 100644 index 9f03c549515..00000000000 --- a/cmd-line-utils/libedit/libedit_term.h +++ /dev/null @@ -1,124 +0,0 @@ -/* $NetBSD: term.h,v 1.12 2001/01/04 15:56:32 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)term.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.term.h: Termcap header - */ -#ifndef _h_el_term -#define _h_el_term - -#include "histedit.h" - -typedef struct { /* Symbolic function key bindings */ - const char *name; /* name of the key */ - int key; /* Index in termcap table */ - key_value_t fun; /* Function bound to it */ - int type; /* Type of function */ -} fkey_t; - -typedef struct { - coord_t t_size; /* # lines and cols */ - int t_flags; -#define TERM_CAN_INSERT 0x001 /* Has insert cap */ -#define TERM_CAN_DELETE 0x002 /* Has delete cap */ -#define TERM_CAN_CEOL 0x004 /* Has CEOL cap */ -#define TERM_CAN_TAB 0x008 /* Can use tabs */ -#define TERM_CAN_ME 0x010 /* Can turn all attrs. */ -#define TERM_CAN_UP 0x020 /* Can move up */ -#define TERM_HAS_META 0x040 /* Has a meta key */ -#define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */ -#define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */ - char *t_buf; /* Termcap buffer */ - int t_loc; /* location used */ - char **t_str; /* termcap strings */ - int *t_val; /* termcap values */ - char *t_cap; /* Termcap buffer */ - fkey_t *t_fkey; /* Array of keys */ -} el_term_t; - -/* - * fKey indexes - */ -#define A_K_DN 0 -#define A_K_UP 1 -#define A_K_LT 2 -#define A_K_RT 3 -#define A_K_HO 4 -#define A_K_EN 5 -#define A_K_NKEYS 6 - -protected void term_move_to_line(EditLine *, int); -protected void term_move_to_char(EditLine *, int); -protected void term_clear_EOL(EditLine *, int); -protected void term_overwrite(EditLine *, const char *, int); -protected void term_insertwrite(EditLine *, char *, int); -protected void term_deletechars(EditLine *, int); -protected void term_clear_screen(EditLine *); -protected void term_beep(EditLine *); -protected int term_change_size(EditLine *, int, int); -protected int term_get_size(EditLine *, int *, int *); -protected int term_init(EditLine *); -protected void term_bind_arrow(EditLine *); -protected void term_print_arrow(EditLine *, const char *); -protected int term_clear_arrow(EditLine *, const char *); -protected int term_set_arrow(EditLine *, const char *, key_value_t *, int); -protected void term_end(EditLine *); -protected int term_set(EditLine *, const char *); -protected int term_settc(EditLine *, int, const char **); -protected int term_telltc(EditLine *, int, const char **); -protected int term_echotc(EditLine *, int, const char **); -protected int term__putc(int); -protected void term__flush(void); - -/* - * Easy access macros - */ -#define EL_FLAGS (el)->el_term.t_flags - -#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT) -#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE) -#define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL) -#define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB) -#define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME) -#define EL_HAS_META (EL_FLAGS & TERM_HAS_META) -#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS) -#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS) - -#endif /* _h_el_term */ diff --git a/cmd-line-utils/libedit/makelist.sh b/cmd-line-utils/libedit/makelist.sh index f15b3d1eb9f..fdd3f934e15 100644 --- a/cmd-line-utils/libedit/makelist.sh +++ b/cmd-line-utils/libedit/makelist.sh @@ -1,5 +1,5 @@ #!/bin/sh - -# $NetBSD: makelist,v 1.8 2003/03/10 21:21:10 christos Exp $ +# $NetBSD: makelist,v 1.11 2005/10/22 16:45:03 christos Exp $ # # Copyright (c) 1992, 1993 # The Regents of the University of California. All rights reserved. @@ -15,11 +15,7 @@ # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the University of -# California, Berkeley and its contributors. -# 4. Neither the name of the University nor the names of its contributors +# 3. Neither the name of the University nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # @@ -68,6 +64,7 @@ case $FLAG in /\(\):/ { pr = substr($2, 1, 2); if (pr == "vi" || pr == "em" || pr == "ed") { + # XXXMYSQL: support CRLF name = substr($2, 1, index($2,"(") - 1); # # XXX: need a space between name and prototype so that -fc and -fh @@ -87,7 +84,7 @@ case $FLAG in cat $FILES | $AWK ' BEGIN { printf("/* Automatically generated file, do not edit */\n"); - printf("#include \"config.h\"\n#include \"el.h\"\n"); + printf("#include \"sys.h\"\n#include \"el.h\"\n"); printf("private const struct el_bindings_t el_func_help[] = {\n"); low = "abcdefghijklmnopqrstuvwxyz_"; high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"; @@ -97,6 +94,7 @@ case $FLAG in /\(\):/ { pr = substr($2, 1, 2); if (pr == "vi" || pr == "em" || pr == "ed") { + # XXXMYSQL: support CRLF name = substr($2, 1, index($2,"(") - 1); uname = ""; fname = ""; @@ -117,13 +115,13 @@ case $FLAG in printf(" \""); for (i = 2; i < NF; i++) printf("%s ", $i); - sub("\r", "", $i); + # XXXMYSQL: support CRLF + sub("\r", "", $i); printf("%s\" },\n", $i); ok = 0; } } END { - printf(" { NULL, 0, NULL }\n"); printf("};\n"); printf("\nprotected const el_bindings_t* help__get()"); printf("{ return el_func_help; }\n"); @@ -144,6 +142,7 @@ case $FLAG in # generate fcns.h from various .h files # +# XXXMYSQL: use portable tr syntax -fh) cat $FILES | $AWK '/el_action_t/ { print $3 }' | \ sort | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | $AWK ' @@ -170,7 +169,7 @@ case $FLAG in cat $FILES | $AWK '/el_action_t/ { print $3 }' | sort | $AWK ' BEGIN { printf("/* Automatically generated file, do not edit */\n"); - printf("#include \"config.h\"\n#include \"el.h\"\n"); + printf("#include \"sys.h\"\n#include \"el.h\"\n"); printf("private const el_func_t el_func[] = {"); maxlen = 80; needn = 1; @@ -220,6 +219,7 @@ case $FLAG in /\(\):/ { pr = substr($2, 1, 2); if (pr == "vi" || pr == "em" || pr == "ed") { + # XXXMYSQL: support CRLF name = substr($2, 1, index($2, "(") - 1); fname = ""; for (i = 1; i <= length(name); i++) { diff --git a/cmd-line-utils/libedit/map.c b/cmd-line-utils/libedit/map.c index 6be9279b5e5..693b56c82ba 100644 --- a/cmd-line-utils/libedit/map.c +++ b/cmd-line-utils/libedit/map.c @@ -1,4 +1,4 @@ -/* $NetBSD: map.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $ */ +/* $NetBSD: map.c,v 1.24 2006/04/09 01:36:51 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * map.c: Editor function definitions @@ -1118,11 +1124,12 @@ private void map_print_key(EditLine *el, el_action_t *map, const char *in) { char outbuf[EL_BUFSIZ]; - el_bindings_t *bp; + el_bindings_t *bp, *ep; if (in[0] == '\0' || in[1] == '\0') { - (void) key__decode_str(in, outbuf, ""); - for (bp = el->el_map.help; bp->name != NULL; bp++) + (void) key__decode_str(in, outbuf, sizeof(outbuf), ""); + ep = &el->el_map.help[el->el_map.nfunc]; + for (bp = el->el_map.help; bp < ep; bp++) if (bp->func == map[(unsigned char) *in]) { (void) fprintf(el->el_outfile, "%s\t->\t%s\n", outbuf, bp->name); @@ -1139,7 +1146,7 @@ map_print_key(EditLine *el, el_action_t *map, const char *in) private void map_print_some_keys(EditLine *el, el_action_t *map, int first, int last) { - el_bindings_t *bp; + el_bindings_t *bp, *ep; char firstbuf[2], lastbuf[2]; char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ]; @@ -1148,39 +1155,47 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last) lastbuf[0] = last; lastbuf[1] = 0; if (map[first] == ED_UNASSIGNED) { - if (first == last) + if (first == last) { + (void) key__decode_str(firstbuf, unparsbuf, + sizeof(unparsbuf), STRQQ); (void) fprintf(el->el_outfile, - "%-15s-> is undefined\n", - key__decode_str(firstbuf, unparsbuf, STRQQ)); + "%-15s-> is undefined\n", unparsbuf); + } return; } - for (bp = el->el_map.help; bp->name != NULL; bp++) { + ep = &el->el_map.help[el->el_map.nfunc]; + for (bp = el->el_map.help; bp < ep; bp++) { if (bp->func == map[first]) { if (first == last) { + (void) key__decode_str(firstbuf, unparsbuf, + sizeof(unparsbuf), STRQQ); (void) fprintf(el->el_outfile, "%-15s-> %s\n", - key__decode_str(firstbuf, unparsbuf, STRQQ), - bp->name); + unparsbuf, bp->name); } else { + (void) key__decode_str(firstbuf, unparsbuf, + sizeof(unparsbuf), STRQQ); + (void) key__decode_str(lastbuf, extrabuf, + sizeof(extrabuf), STRQQ); (void) fprintf(el->el_outfile, "%-4s to %-7s-> %s\n", - key__decode_str(firstbuf, unparsbuf, STRQQ), - key__decode_str(lastbuf, extrabuf, STRQQ), - bp->name); + unparsbuf, extrabuf, bp->name); } return; } } #ifdef MAP_DEBUG if (map == el->el_map.key) { + (void) key__decode_str(firstbuf, unparsbuf, + sizeof(unparsbuf), STRQQ); (void) fprintf(el->el_outfile, - "BUG!!! %s isn't bound to anything.\n", - key__decode_str(firstbuf, unparsbuf, STRQQ)); + "BUG!!! %s isn't bound to anything.\n", unparsbuf); (void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n", first, el->el_map.key[first]); } else { + (void) key__decode_str(firstbuf, unparsbuf, + sizeof(unparsbuf), STRQQ); (void) fprintf(el->el_outfile, - "BUG!!! %s isn't bound to anything.\n", - key__decode_str(firstbuf, unparsbuf, STRQQ)); + "BUG!!! %s isn't bound to anything.\n", unparsbuf); (void) fprintf(el->el_outfile, "el->el_map.alt[%d] == %d\n", first, el->el_map.alt[first]); } @@ -1237,7 +1252,7 @@ map_bind(EditLine *el, int argc, const char **argv) char outbuf[EL_BUFSIZ]; const char *in = NULL; char *out = NULL; - el_bindings_t *bp; + el_bindings_t *bp, *ep; int cmd; int key; @@ -1279,8 +1294,8 @@ map_bind(EditLine *el, int argc, const char **argv) return (0); case 'l': - for (bp = el->el_map.help; bp->name != NULL; - bp++) + ep = &el->el_map.help[el->el_map.nfunc]; + for (bp = el->el_map.help; bp < ep; bp++) (void) fprintf(el->el_outfile, "%s\n\t%s\n", bp->name, bp->description); @@ -1367,7 +1382,7 @@ map_bind(EditLine *el, int argc, const char **argv) break; default: - EL_ABORT((el->el_errfile, "Bad XK_ type\n", ntype)); + EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); break; } return (0); @@ -1381,7 +1396,7 @@ protected int map_addfunc(EditLine *el, const char *name, const char *help, el_func_t func) { void *p; - int nf = el->el_map.nfunc + 2; + int nf = el->el_map.nfunc + 1; if (name == NULL || help == NULL || func == NULL) return (-1); @@ -1400,7 +1415,6 @@ map_addfunc(EditLine *el, const char *name, const char *help, el_func_t func) el->el_map.help[nf].name = name; el->el_map.help[nf].func = nf; el->el_map.help[nf].description = help; - el->el_map.help[++nf].name = NULL; el->el_map.nfunc++; return (0); diff --git a/cmd-line-utils/libedit/np/fgetln.c b/cmd-line-utils/libedit/np/fgetln.c index 93da9914dc8..898abc758dc 100644 --- a/cmd-line-utils/libedit/np/fgetln.c +++ b/cmd-line-utils/libedit/np/fgetln.c @@ -1,4 +1,4 @@ -/* $NetBSD: fgetln.c,v 1.1.1.1 1999/04/12 07:43:21 crooksa Exp $ */ +/* $NetBSD: fgetln.c,v 1.9 2008/04/29 06:53:03 martin Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -15,13 +15,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -36,17 +29,24 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifdef HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#else #include "config.h" -#include +#endif + +#if !HAVE_FGETLN #include +#ifndef HAVE_NBTOOL_CONFIG_H +/* These headers are required, but included from nbtool_config.h */ +#include #include #include #include +#endif char * -fgetln(fp, len) - FILE *fp; - size_t *len; +fgetln(FILE *fp, size_t *len) { static char *buf = NULL; static size_t bufsiz = 0; @@ -61,8 +61,8 @@ fgetln(fp, len) if (fgets(buf, bufsiz, fp) == NULL) return NULL; - *len = 0; + *len = 0; while ((ptr = strchr(&buf[*len], '\n')) == NULL) { size_t nbufsiz = bufsiz + BUFSIZ; char *nbuf = realloc(buf, nbufsiz); @@ -76,13 +76,33 @@ fgetln(fp, len) } else buf = nbuf; - *len = bufsiz; - if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) + if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) { + buf[bufsiz] = '\0'; + *len = strlen(buf); return buf; + } + *len = bufsiz; bufsiz = nbufsiz; } *len = (ptr - buf) + 1; return buf; } + +#endif + +#ifdef TEST +int +main(int argc, char *argv[]) +{ + char *p; + size_t len; + + while ((p = fgetln(stdin, &len)) != NULL) { + (void)printf("%zu %s", len, p); + free(p); + } + return 0; +} +#endif diff --git a/cmd-line-utils/libedit/np/strlcat.c b/cmd-line-utils/libedit/np/strlcat.c index 6c9f1e92d79..4e2897d8f35 100644 --- a/cmd-line-utils/libedit/np/strlcat.c +++ b/cmd-line-utils/libedit/np/strlcat.c @@ -1,59 +1,68 @@ +/* $NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */ +/* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */ + /* * Copyright (c) 1998 Todd C. Miller - * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE + * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#if !defined(_KERNEL) && !defined(_STANDALONE) +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#else #include "config.h" +#endif + #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $"; #endif /* LIBC_SCCS and not lint */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD: src/lib/libc/string/strlcat.c,v 1.2.4.2 2001/07/09 23:30:06 obrien Exp $"; -#endif +#ifdef _LIBC +#include "namespace.h" +#endif #include +#include #include +#ifdef _LIBC +# ifdef __weak_alias +__weak_alias(strlcat, _strlcat) +# endif +#endif + +#else +#include +#endif /* !_KERNEL && !_STANDALONE */ + +#if !HAVE_STRLCAT /* * Appends src to string dst of size siz (unlike strncat, siz is the * full size of dst, not space left). At most siz-1 characters * will be copied. Always NUL terminates (unless siz <= strlen(dst)). - * Returns strlen(initial dst) + strlen(src); if retval >= siz, - * truncation occurred. + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. */ -size_t strlcat(dst, src, siz) - char *dst; - const char *src; - size_t siz; +size_t +strlcat(char *dst, const char *src, size_t siz) { - register char *d = dst; - register const char *s = src; - register size_t n = siz; + char *d = dst; + const char *s = src; + size_t n = siz; size_t dlen; + _DIAGASSERT(dst != NULL); + _DIAGASSERT(src != NULL); + /* Find the end of dst and adjust bytes left but don't go past end */ while (n-- != 0 && *d != '\0') d++; @@ -73,3 +82,4 @@ size_t strlcat(dst, src, siz) return(dlen + (s - src)); /* count does not include NUL */ } +#endif diff --git a/cmd-line-utils/libedit/np/strlcpy.c b/cmd-line-utils/libedit/np/strlcpy.c index 1f154bcf2ea..092a9757c0f 100644 --- a/cmd-line-utils/libedit/np/strlcpy.c +++ b/cmd-line-utils/libedit/np/strlcpy.c @@ -1,59 +1,63 @@ -/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */ +/* $NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */ +/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */ /* * Copyright (c) 1998 Todd C. Miller - * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE + * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#if !defined(_KERNEL) && !defined(_STANDALONE) +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#else #include "config.h" -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $"; #endif +#if defined(LIBC_SCCS) && !defined(lint) #endif /* LIBC_SCCS and not lint */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD: src/lib/libc/string/strlcpy.c,v 1.2.4.1 2001/07/09 23:30:06 obrien Exp $"; -#endif +#ifdef _LIBC +#include "namespace.h" +#endif #include +#include #include +#ifdef _LIBC +# ifdef __weak_alias +__weak_alias(strlcpy, _strlcpy) +# endif +#endif +#else +#include +#endif /* !_KERNEL && !_STANDALONE */ + + +#if !HAVE_STRLCPY /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ -size_t strlcpy(dst, src, siz) - char *dst; - const char *src; - size_t siz; +size_t +strlcpy(char *dst, const char *src, size_t siz) { - register char *d = dst; - register const char *s = src; - register size_t n = siz; + char *d = dst; + const char *s = src; + size_t n = siz; + + _DIAGASSERT(dst != NULL); + _DIAGASSERT(src != NULL); /* Copy as many bytes as will fit */ if (n != 0 && --n != 0) { @@ -73,3 +77,4 @@ size_t strlcpy(dst, src, siz) return(s - src - 1); /* count does not include NUL */ } +#endif diff --git a/cmd-line-utils/libedit/np/unvis.c b/cmd-line-utils/libedit/np/unvis.c index 895ff2059ac..3c37c231ceb 100644 --- a/cmd-line-utils/libedit/np/unvis.c +++ b/cmd-line-utils/libedit/np/unvis.c @@ -1,4 +1,4 @@ -/* $NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $ */ +/* $NetBSD: unvis.c,v 1.28 2005/09/13 01:44:09 christos Exp $ */ /*- * Copyright (c) 1989, 1993 @@ -12,11 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -34,34 +30,30 @@ */ #include "config.h" + #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ -#define __LIBC12_SOURCE__ - #include #include #include #include +#ifdef HAVE_VIS_H +#include +#else #include "np/vis.h" +#endif #ifdef __weak_alias __weak_alias(strunvis,_strunvis) -__weak_alias(unvis,_unvis) #endif -#ifdef __warn_references -__warn_references(unvis, - "warning: reference to compatibility unvis(); include for correct reference") -#endif - -#if !HAVE_VIS_H +#if !HAVE_VIS /* * decode driven by state machine */ @@ -72,30 +64,22 @@ __warn_references(unvis, #define S_CTRL 4 /* control char started (^) */ #define S_OCTAL2 5 /* octal digit 2 */ #define S_OCTAL3 6 /* octal digit 3 */ -#define S_HEX1 7 /* hex digit */ -#define S_HEX2 8 /* hex digit 2 */ +#define S_HEX1 7 /* hex digit */ +#define S_HEX2 8 /* hex digit 2 */ #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') #define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) -int -unvis(cp, c, astate, flag) - char *cp; - int c; - int *astate, flag; -{ - return __unvis13(cp, (int)c, astate, flag); -} - /* * unvis - decode characters previously encoded by vis */ int -__unvis13(cp, c, astate, flag) +unvis(cp, c, astate, flag) char *cp; int c; int *astate, flag; { + unsigned char uc = (unsigned char)c; _DIAGASSERT(cp != NULL); _DIAGASSERT(astate != NULL); @@ -105,7 +89,7 @@ __unvis13(cp, c, astate, flag) || *astate == S_HEX2) { *astate = S_GROUND; return (UNVIS_VALID); - } + } return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); } @@ -116,7 +100,7 @@ __unvis13(cp, c, astate, flag) if (c == '\\') { *astate = S_START; return (0); - } + } if ((flag & VIS_HTTPSTYLE) && c == '%') { *astate = S_HEX1; return (0); @@ -193,7 +177,7 @@ __unvis13(cp, c, astate, flag) } *astate = S_GROUND; return (UNVIS_SYNBAD); - + case S_META: if (c == '-') *astate = S_META1; @@ -204,12 +188,12 @@ __unvis13(cp, c, astate, flag) return (UNVIS_SYNBAD); } return (0); - + case S_META1: *astate = S_GROUND; *cp |= c; return (UNVIS_VALID); - + case S_CTRL: if (c == '?') *cp |= 0177; @@ -219,23 +203,23 @@ __unvis13(cp, c, astate, flag) return (UNVIS_VALID); case S_OCTAL2: /* second possible octal digit */ - if (isoctal(c)) { - /* - * yes - and maybe a third + if (isoctal(uc)) { + /* + * yes - and maybe a third */ *cp = (*cp << 3) + (c - '0'); - *astate = S_OCTAL3; + *astate = S_OCTAL3; return (0); - } - /* - * no - done with current sequence, push back passed char + } + /* + * no - done with current sequence, push back passed char */ *astate = S_GROUND; return (UNVIS_VALIDPUSH); case S_OCTAL3: /* third possible octal digit */ *astate = S_GROUND; - if (isoctal(c)) { + if (isoctal(uc)) { *cp = (*cp << 3) + (c - '0'); return (UNVIS_VALID); } @@ -243,27 +227,30 @@ __unvis13(cp, c, astate, flag) * we were done, push back passed char */ return (UNVIS_VALIDPUSH); + case S_HEX1: - if (isxdigit(c)) { - *cp = xtod(c); + if (isxdigit(uc)) { + *cp = xtod(uc); *astate = S_HEX2; return (0); } - /* - * no - done with current sequence, push back passed char + /* + * no - done with current sequence, push back passed char */ *astate = S_GROUND; return (UNVIS_VALIDPUSH); + case S_HEX2: - *astate = S_GROUND; - if (isxdigit(c)) { - *cp = xtod(c) | (*cp << 4); + *astate = S_GROUND; + if (isxdigit(uc)) { + *cp = xtod(uc) | (*cp << 4); return (UNVIS_VALID); } - return (UNVIS_VALIDPUSH); - default: - /* - * decoder in unknown state - (probably uninitialized) + return (UNVIS_VALIDPUSH); + + default: + /* + * decoder in unknown state - (probably uninitialized) */ *astate = S_GROUND; return (UNVIS_SYNBAD); @@ -271,7 +258,7 @@ __unvis13(cp, c, astate, flag) } /* - * strunvis - decode src into dst + * strunvis - decode src into dst * * Number of chars decoded into dst is returned, -1 on error. * Dst is null terminated. @@ -291,8 +278,8 @@ strunvisx(dst, src, flag) _DIAGASSERT(dst != NULL); while ((c = *src++) != '\0') { - again: - switch (__unvis13(dst, c, &state, flag)) { + again: + switch (unvis(dst, c, &state, flag)) { case UNVIS_VALID: dst++; break; @@ -306,7 +293,7 @@ strunvisx(dst, src, flag) return (-1); } } - if (__unvis13(dst, c, &state, UNVIS_END) == UNVIS_VALID) + if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID) dst++; *dst = '\0'; return (dst - start); diff --git a/cmd-line-utils/libedit/np/vis.c b/cmd-line-utils/libedit/np/vis.c index e8f5c195f10..2a746274681 100644 --- a/cmd-line-utils/libedit/np/vis.c +++ b/cmd-line-utils/libedit/np/vis.c @@ -1,7 +1,6 @@ -/* $NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $ */ +/* $NetBSD: vis.c,v 1.38 2008/09/04 09:41:44 lukem Exp $ */ /*- - * Copyright (c) 1999 The NetBSD Foundation, Inc. * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * @@ -13,11 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -34,21 +29,47 @@ * SUCH DAMAGE. */ +/*- + * Copyright (c) 1999, 2005 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + #include "config.h" #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $"); #endif /* LIBC_SCCS and not lint */ #include + #include -#ifdef HAVE_ALLOCA_H -#include +#ifdef HAVE_VIS_H +#include +#else +#include "np/vis.h" #endif #include -#include "np/vis.h" - #ifdef __weak_alias __weak_alias(strsvis,_strsvis) __weak_alias(strsvisx,_strsvisx) @@ -58,63 +79,61 @@ __weak_alias(svis,_svis) __weak_alias(vis,_vis) #endif -#if !HAVE_VIS_H +#if !HAVE_VIS || !HAVE_SVIS #include #include #include #include -#include + +static char *do_svis(char *, int, int, int, const char *); + #undef BELL -#if defined(__STDC__) #define BELL '\a' -#else -#define BELL '\007' -#endif -#define isoctal(c) (((unsigned char)(c)) >= '0' && ((unsigned char)(c)) <= '7') +#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') #define iswhite(c) (c == ' ' || c == '\t' || c == '\n') #define issafe(c) (c == '\b' || c == BELL || c == '\r') #define xtoa(c) "0123456789abcdef"[c] -#define MAXEXTRAS 5 - - -char *MAKEEXTRALIST(unsigned int flag, const char *orig) -{ - const char *o = orig; - char *e, *extra; - while (*o++) - continue; - extra = (char*) malloc((size_t)((o - orig) + MAXEXTRAS)); - assert(extra); - for (o = orig, e = extra; (*e++ = *o++) != '\0';) - continue; - e--; - if (flag & VIS_SP) *e++ = ' '; - if (flag & VIS_TAB) *e++ = '\t'; - if (flag & VIS_NL) *e++ = '\n'; - if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; - *e = '\0'; - return extra; -} +#define MAXEXTRAS 5 +#define MAKEEXTRALIST(flag, extra, orig_str) \ +do { \ + const char *orig = orig_str; \ + const char *o = orig; \ + char *e; \ + while (*o++) \ + continue; \ + extra = malloc((size_t)((o - orig) + MAXEXTRAS)); \ + if (!extra) break; \ + for (o = orig, e = extra; (*e++ = *o++) != '\0';) \ + continue; \ + e--; \ + if (flag & VIS_SP) *e++ = ' '; \ + if (flag & VIS_TAB) *e++ = '\t'; \ + if (flag & VIS_NL) *e++ = '\n'; \ + if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \ + *e = '\0'; \ +} while (/*CONSTCOND*/0) /* - * This is HVIS, the macro of vis used to HTTP style (RFC 1808) + * This is do_hvis, for HTTP style (RFC 1808) */ -#define HVIS(dst, c, flag, nextc, extra) \ -do \ - if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \ - *dst++ = '%'; \ - *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); \ - *dst++ = xtoa((unsigned int)c & 0xf); \ - } else { \ - SVIS(dst, c, flag, nextc, extra); \ - } \ -while (/*CONSTCOND*/0) - +static char * +do_hvis(char *dst, int c, int flag, int nextc, const char *extra) +{ + if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { + *dst++ = '%'; + *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); + *dst++ = xtoa((unsigned int)c & 0xf); + } else { + dst = do_svis(dst, c, flag, nextc, extra); + } + return dst; +} + /* - * This is SVIS, the central macro of vis. + * This is do_vis, the central code of vis. * dst: Pointer to the destination buffer * c: Character to encode * flag: Flag word @@ -122,95 +141,103 @@ while (/*CONSTCOND*/0) * extra: Pointer to the list of extra characters to be * backslash-protected. */ -#define SVIS(dst, c, flag, nextc, extra) \ -do { \ - int isextra, isc; \ - isextra = strchr(extra, c) != NULL; \ - if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \ - ((flag & VIS_SAFE) && issafe(c)))) { \ - *dst++ = c; \ - break; \ - } \ - isc = 0; \ - if (flag & VIS_CSTYLE) { \ - switch (c) { \ - case '\n': \ - isc = 1; *dst++ = '\\'; *dst++ = 'n'; \ - break; \ - case '\r': \ - isc = 1; *dst++ = '\\'; *dst++ = 'r'; \ - break; \ - case '\b': \ - isc = 1; *dst++ = '\\'; *dst++ = 'b'; \ - break; \ - case BELL: \ - isc = 1; *dst++ = '\\'; *dst++ = 'a'; \ - break; \ - case '\v': \ - isc = 1; *dst++ = '\\'; *dst++ = 'v'; \ - break; \ - case '\t': \ - isc = 1; *dst++ = '\\'; *dst++ = 't'; \ - break; \ - case '\f': \ - isc = 1; *dst++ = '\\'; *dst++ = 'f'; \ - break; \ - case ' ': \ - isc = 1; *dst++ = '\\'; *dst++ = 's'; \ - break; \ - case '\0': \ - isc = 1; *dst++ = '\\'; *dst++ = '0'; \ - if (isoctal(nextc)) { \ - *dst++ = '0'; \ - *dst++ = '0'; \ - } \ - } \ - } \ - if (isc) break; \ - if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \ - *dst++ = '\\'; \ - *dst++ = (unsigned char)(((unsigned int)(unsigned char)c >> 6) & 03) + '0'; \ - *dst++ = (unsigned char)(((unsigned int)(unsigned char)c >> 3) & 07) + '0'; \ - *dst++ = (c & 07) + '0'; \ - } else { \ - if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \ - if (c & 0200) { \ - c &= 0177; *dst++ = 'M'; \ - } \ - if (iscntrl(c)) { \ - *dst++ = '^'; \ - if (c == 0177) \ - *dst++ = '?'; \ - else \ - *dst++ = c + '@'; \ - } else { \ - *dst++ = '-'; *dst++ = c; \ - } \ - } \ -} while (/*CONSTCOND*/0) +static char * +do_svis(char *dst, int c, int flag, int nextc, const char *extra) +{ + int isextra; + isextra = strchr(extra, c) != NULL; + if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || + ((flag & VIS_SAFE) && issafe(c)))) { + *dst++ = c; + return dst; + } + if (flag & VIS_CSTYLE) { + switch (c) { + case '\n': + *dst++ = '\\'; *dst++ = 'n'; + return dst; + case '\r': + *dst++ = '\\'; *dst++ = 'r'; + return dst; + case '\b': + *dst++ = '\\'; *dst++ = 'b'; + return dst; + case BELL: + *dst++ = '\\'; *dst++ = 'a'; + return dst; + case '\v': + *dst++ = '\\'; *dst++ = 'v'; + return dst; + case '\t': + *dst++ = '\\'; *dst++ = 't'; + return dst; + case '\f': + *dst++ = '\\'; *dst++ = 'f'; + return dst; + case ' ': + *dst++ = '\\'; *dst++ = 's'; + return dst; + case '\0': + *dst++ = '\\'; *dst++ = '0'; + if (isoctal(nextc)) { + *dst++ = '0'; + *dst++ = '0'; + } + return dst; + default: + if (isgraph(c)) { + *dst++ = '\\'; *dst++ = c; + return dst; + } + } + } + if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { + *dst++ = '\\'; + *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; + *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; + *dst++ = (c & 07) + '0'; + } else { + if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; + if (c & 0200) { + c &= 0177; *dst++ = 'M'; + } + if (iscntrl(c)) { + *dst++ = '^'; + if (c == 0177) + *dst++ = '?'; + else + *dst++ = c + '@'; + } else { + *dst++ = '-'; *dst++ = c; + } + } + return dst; +} /* * svis - visually encode characters, also encoding the characters - * pointed to by `extra' + * pointed to by `extra' */ char * -svis(dst, c, flag, nextc, extra) - char *dst; - int c, flag, nextc; - const char *extra; +svis(char *dst, int c, int flag, int nextc, const char *extra) { - char *nextra, *to_be_freed; + char *nextra = NULL; + _DIAGASSERT(dst != NULL); _DIAGASSERT(extra != NULL); - nextra= to_be_freed= MAKEEXTRALIST(flag, extra); + MAKEEXTRALIST(flag, nextra, extra); + if (!nextra) { + *dst = '\0'; /* can't create nextra, return "" */ + return dst; + } if (flag & VIS_HTTPSTYLE) - HVIS(dst, c, flag, nextc, nextra); + dst = do_hvis(dst, c, flag, nextc, nextra); else - SVIS(dst, c, flag, nextc, nextra); + dst = do_svis(dst, c, flag, nextc, nextra); + free(nextra); *dst = '\0'; - free(to_be_freed); - return(dst); + return dst; } @@ -221,140 +248,146 @@ svis(dst, c, flag, nextc, extra) * be encoded, too. These functions are useful e. g. to * encode strings in such a way so that they are not interpreted * by a shell. - * + * * Dst must be 4 times the size of src to account for possible * expansion. The length of dst, not including the trailing NULL, - * is returned. + * is returned. * * Strsvisx encodes exactly len bytes from src into dst. * This is useful for encoding a block of data. */ int -strsvis(dst, src, flag, extra) - char *dst; - const char *src; - int flag; - const char *extra; +strsvis(char *dst, const char *csrc, int flag, const char *extra) { - char c; + int c; char *start; - char *nextra, *to_be_freed; + char *nextra = NULL; + const unsigned char *src = (const unsigned char *)csrc; _DIAGASSERT(dst != NULL); _DIAGASSERT(src != NULL); _DIAGASSERT(extra != NULL); - nextra= to_be_freed= MAKEEXTRALIST(flag, extra); + MAKEEXTRALIST(flag, nextra, extra); + if (!nextra) { + *dst = '\0'; /* can't create nextra, return "" */ + return 0; + } if (flag & VIS_HTTPSTYLE) { for (start = dst; (c = *src++) != '\0'; /* empty */) - HVIS(dst, c, flag, *src, nextra); + dst = do_hvis(dst, c, flag, *src, nextra); } else { for (start = dst; (c = *src++) != '\0'; /* empty */) - SVIS(dst, c, flag, *src, nextra); + dst = do_svis(dst, c, flag, *src, nextra); } + free(nextra); *dst = '\0'; - free(to_be_freed); return (dst - start); } int -strsvisx(dst, src, len, flag, extra) - char *dst; - const char *src; - size_t len; - int flag; - const char *extra; +strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra) { - char c; + unsigned char c; char *start; - char *nextra, *to_be_freed; + char *nextra = NULL; + const unsigned char *src = (const unsigned char *)csrc; _DIAGASSERT(dst != NULL); _DIAGASSERT(src != NULL); _DIAGASSERT(extra != NULL); - nextra= to_be_freed= MAKEEXTRALIST(flag, extra); + MAKEEXTRALIST(flag, nextra, extra); + if (! nextra) { + *dst = '\0'; /* can't create nextra, return "" */ + return 0; + } if (flag & VIS_HTTPSTYLE) { for (start = dst; len > 0; len--) { c = *src++; - HVIS(dst, c, flag, len ? *src : '\0', nextra); + dst = do_hvis(dst, c, flag, + len > 1 ? *src : '\0', nextra); } } else { for (start = dst; len > 0; len--) { c = *src++; - SVIS(dst, c, flag, len ? *src : '\0', nextra); + dst = do_svis(dst, c, flag, + len > 1 ? *src : '\0', nextra); } } + free(nextra); *dst = '\0'; - free(to_be_freed); return (dst - start); } +#endif - +#if !HAVE_VIS /* * vis - visually encode characters */ char * -vis(dst, c, flag, nextc) - char *dst; - int c, flag, nextc; - +vis(char *dst, int c, int flag, int nextc) { - char *extra, *to_be_freed; + char *extra = NULL; + unsigned char uc = (unsigned char)c; _DIAGASSERT(dst != NULL); - extra= to_be_freed= MAKEEXTRALIST(flag, ""); - + MAKEEXTRALIST(flag, extra, ""); + if (! extra) { + *dst = '\0'; /* can't create extra, return "" */ + return dst; + } if (flag & VIS_HTTPSTYLE) - HVIS(dst, c, flag, nextc, extra); + dst = do_hvis(dst, uc, flag, nextc, extra); else - SVIS(dst, c, flag, nextc, extra); + dst = do_svis(dst, uc, flag, nextc, extra); + free(extra); *dst = '\0'; - free(to_be_freed); - return (dst); + return dst; } /* * strvis, strvisx - visually encode characters from src into dst - * + * * Dst must be 4 times the size of src to account for possible * expansion. The length of dst, not including the trailing NULL, - * is returned. + * is returned. * * Strvisx encodes exactly len bytes from src into dst. * This is useful for encoding a block of data. */ int -strvis(dst, src, flag) - char *dst; - const char *src; - int flag; +strvis(char *dst, const char *src, int flag) { - char *extra; - int tmp; + char *extra = NULL; + int rv; - extra= MAKEEXTRALIST(flag, ""); - tmp= strsvis(dst, src, flag, extra); + MAKEEXTRALIST(flag, extra, ""); + if (!extra) { + *dst = '\0'; /* can't create extra, return "" */ + return 0; + } + rv = strsvis(dst, src, flag, extra); free(extra); - return tmp; + return rv; } int -strvisx(dst, src, len, flag) - char *dst; - const char *src; - size_t len; - int flag; +strvisx(char *dst, const char *src, size_t len, int flag) { - char *extra; - int tmp; + char *extra = NULL; + int rv; - extra= MAKEEXTRALIST(flag, ""); - tmp= strsvisx(dst, src, len, flag, extra); + MAKEEXTRALIST(flag, extra, ""); + if (!extra) { + *dst = '\0'; /* can't create extra, return "" */ + return 0; + } + rv = strsvisx(dst, src, len, flag, extra); free(extra); - return tmp; + return rv; } #endif diff --git a/cmd-line-utils/libedit/np/vis.h b/cmd-line-utils/libedit/np/vis.h index 1a49c9e3ed2..11f5b740e2d 100644 --- a/cmd-line-utils/libedit/np/vis.h +++ b/cmd-line-utils/libedit/np/vis.h @@ -1,4 +1,4 @@ -/* $NetBSD: vis.h,v 1.12 2002/03/23 17:39:05 christos Exp $ */ +/* $NetBSD: vis.h,v 1.16 2005/09/13 01:44:32 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -12,11 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -38,9 +34,7 @@ #ifndef _VIS_H_ #define _VIS_H_ -#ifdef HAVE_SYS_CDEFS_H -#include -#endif +#include /* * to select alternate encoding format @@ -78,6 +72,7 @@ */ #define UNVIS_END 1 /* no more characters */ +__BEGIN_DECLS char *vis(char *, int, int, int); char *svis(char *, int, int, int, const char *); int strvis(char *, const char *, int); @@ -86,11 +81,7 @@ int strvisx(char *, const char *, size_t, int); int strsvisx(char *, const char *, size_t, int, const char *); int strunvis(char *, const char *); int strunvisx(char *, const char *, int); -#ifdef __LIBC12_SOURCE__ int unvis(char *, int, int *, int); -int __unvis13(char *, int, int *, int); -#else -int unvis(char *, int, int *, int) __RENAME(__unvis13); -#endif +__END_DECLS #endif /* !_VIS_H_ */ diff --git a/cmd-line-utils/libedit/parse.c b/cmd-line-utils/libedit/parse.c index 993cf5b752d..5bdefb5a0e4 100644 --- a/cmd-line-utils/libedit/parse.c +++ b/cmd-line-utils/libedit/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.20 2003/12/05 13:37:48 lukem Exp $ */ +/* $NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * parse.c: parse an editline extended command @@ -129,7 +135,7 @@ el_parse(EditLine *el, int argc, const char *argv[]) * the appropriate character or -1 if the escape is not valid */ protected int -parse__escape(const char **const ptr) +parse__escape(const char **ptr) { const char *p; int c; diff --git a/cmd-line-utils/libedit/parse.h b/cmd-line-utils/libedit/parse.h index 4b796666b8e..58dced1aeaa 100644 --- a/cmd-line-utils/libedit/parse.h +++ b/cmd-line-utils/libedit/parse.h @@ -1,4 +1,4 @@ -/* $NetBSD: parse.h,v 1.5 2003/08/07 16:44:32 agc Exp $ */ +/* $NetBSD: parse.h,v 1.6 2005/05/29 04:58:15 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -41,7 +41,7 @@ #define _h_el_parse protected int parse_line(EditLine *, const char *); -protected int parse__escape(const char ** const); +protected int parse__escape(const char **); protected char *parse__string(char *, const char *); protected int parse_cmd(EditLine *, const char *); diff --git a/cmd-line-utils/libedit/prompt.c b/cmd-line-utils/libedit/prompt.c index 455dd60331b..982943afd30 100644 --- a/cmd-line-utils/libedit/prompt.c +++ b/cmd-line-utils/libedit/prompt.c @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * prompt.c: Prompt printing functions diff --git a/cmd-line-utils/libedit/read.c b/cmd-line-utils/libedit/read.c index 51848c2038e..ac768142e79 100644 --- a/cmd-line-utils/libedit/read.c +++ b/cmd-line-utils/libedit/read.c @@ -1,4 +1,4 @@ -/* $NetBSD: read.c,v 1.35 2005/03/09 23:55:02 christos Exp $ */ +/* $NetBSD: read.c,v 1.43 2009/02/05 19:15:44 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * read.c: Clean this junk up! This is horrible code. @@ -50,6 +56,7 @@ private int read__fixio(int, int); private int read_preread(EditLine *); private int read_char(EditLine *, char *); private int read_getcmd(EditLine *, el_action_t *, char *); +private void read_pop(c_macro_t *); /* read_init(): * Initialize the read stuff @@ -205,7 +212,7 @@ read_preread(EditLine *el) * Push a macro */ public void -el_push(EditLine *el, char *str) +el_push(EditLine *el, const char *str) { c_macro_t *ma = &el->el_chared.c_macro; @@ -216,7 +223,7 @@ el_push(EditLine *el, char *str) ma->level--; } term_beep(el); - term__flush(); + term__flush(el); } @@ -294,6 +301,19 @@ read_char(EditLine *el, char *cp) return (num_read); } +/* read_pop(): + * Pop a macro from the stack + */ +private void +read_pop(c_macro_t *ma) +{ + int i; + + el_free(ma->macro[0]); + for (i = ma->level--; i > 0; i--) + ma->macro[i - 1] = ma->macro[i]; + ma->offset = 0; +} /* el_getc(): * Read a character @@ -304,26 +324,28 @@ el_getc(EditLine *el, char *cp) int num_read; c_macro_t *ma = &el->el_chared.c_macro; - term__flush(); + term__flush(el); for (;;) { if (ma->level < 0) { if (!read_preread(el)) break; } + if (ma->level < 0) break; - if (ma->macro[ma->level][ma->offset] == '\0') { - el_free(ma->macro[ma->level--]); - ma->offset = 0; + if (ma->macro[0][ma->offset] == '\0') { + read_pop(ma); continue; } - *cp = ma->macro[ma->level][ma->offset++] & 0377; - if (ma->macro[ma->level][ma->offset] == '\0') { + + *cp = ma->macro[0][ma->offset++] & 0377; + + if (ma->macro[0][ma->offset] == '\0') { /* Needed for QuoteMode On */ - el_free(ma->macro[ma->level--]); - ma->offset = 0; + read_pop(ma); } + return (1); } @@ -357,11 +379,11 @@ read_prepare(EditLine *el) we have the wrong size. */ el_resize(el); re_clear_display(el); /* reset the display stuff */ - ch_reset(el); + ch_reset(el, 0); re_refresh(el); /* print the prompt */ if (el->el_flags & UNBUFFERED) - term__flush(); + term__flush(el); } protected void @@ -438,7 +460,7 @@ el_gets(EditLine *el, int *nread) else cp = el->el_line.lastchar; - term__flush(); + term__flush(el); while ((*el->el_read.read_char)(el, cp) == 1) { /* make sure there is space next character */ @@ -478,7 +500,7 @@ el_gets(EditLine *el, int *nread) #endif /* DEBUG_READ */ break; } - if ((unsigned int)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ + if ((unsigned int)cmdnum >= (unsigned int)el->el_map.nfunc) { /* BUG CHECK command */ #ifdef DEBUG_EDIT (void) fprintf(el->el_errfile, "ERROR: illegal command from key 0%o\r\n", ch); @@ -570,7 +592,7 @@ el_gets(EditLine *el, int *nread) #endif /* DEBUG_READ */ /* put (real) cursor in a known place */ re_clear_display(el); /* reset the display stuff */ - ch_reset(el); /* reset the input pointers */ + ch_reset(el, 1); /* reset the input pointers */ re_refresh(el); /* print the prompt again */ break; @@ -581,7 +603,7 @@ el_gets(EditLine *el, int *nread) "*** editor ERROR ***\r\n\n"); #endif /* DEBUG_READ */ term_beep(el); - term__flush(); + term__flush(el); break; } el->el_state.argument = 1; @@ -591,7 +613,7 @@ el_gets(EditLine *el, int *nread) break; } - term__flush(); /* flush any buffered output */ + term__flush(el); /* flush any buffered output */ /* make sure the tty is set up correctly */ if ((el->el_flags & UNBUFFERED) == 0) { read_finish(el); diff --git a/cmd-line-utils/libedit/read.h b/cmd-line-utils/libedit/read.h index 1982f47253b..bd8d4c1f5bb 100644 --- a/cmd-line-utils/libedit/read.h +++ b/cmd-line-utils/libedit/read.h @@ -1,4 +1,4 @@ -/* $NetBSD: read.h,v 1.4 2004/02/27 14:52:18 christos Exp $ */ +/* $NetBSD: read.h,v 1.6 2008/04/29 06:53:01 martin Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -15,13 +15,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index 004fcf7d183..ca8796fbd37 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -1,4 +1,4 @@ -/* $NetBSD: readline.c,v 1.49 2005/03/10 19:34:46 christos Exp $ */ +/* $NetBSD: readline.c,v 1.78 2009/02/05 19:15:26 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -15,13 +15,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -36,25 +29,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* AIX requires this to be the first thing in the file. */ -#if defined (_AIX) && !defined (__GNUC__) - #pragma alloca -#endif - -#include - -#ifdef __GNUC__ -# undef alloca -# define alloca(n) __builtin_alloca (n) -#else -# ifdef HAVE_ALLOCA_H -# include -# else -# ifndef _AIX -extern char *alloca (); -# endif -# endif -#endif +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#endif /* not lint && not SCCSID */ #include #include @@ -68,12 +45,23 @@ extern char *alloca (); #include #include #include +#include +#ifdef HAVE_VIS_H #include - -#include "readline/readline.h" +#else +#include "np/vis.h" +#endif +#ifdef HAVE_ALLOCA_H +#include +#endif #include "el.h" #include "fcns.h" /* for EL_NUM_FCNS */ #include "histedit.h" +#include "readline/readline.h" +#include "filecomplete.h" + +void rl_prep_terminal(int); +void rl_deprep_terminal(void); /* for rl_complete() */ #define TAB '\r' @@ -94,9 +82,12 @@ FILE *rl_outstream = NULL; int rl_point = 0; int rl_end = 0; char *rl_line_buffer = NULL; -VFunction *rl_linefunc = NULL; +VCPFunction *rl_linefunc = NULL; int rl_done = 0; VFunction *rl_event_hook = NULL; +KEYMAP_ENTRY_ARRAY emacs_standard_keymap, + emacs_meta_keymap, + emacs_ctlx_keymap; int history_base = 1; /* probably never subject to change */ int history_length = 0; @@ -112,21 +103,23 @@ int rl_attempted_completion_over = 0; char *rl_basic_word_break_characters = break_chars; char *rl_completer_word_break_characters = NULL; char *rl_completer_quote_characters = NULL; -CPFunction *rl_completion_entry_function = NULL; +Function *rl_completion_entry_function = NULL; CPPFunction *rl_attempted_completion_function = NULL; Function *rl_pre_input_hook = NULL; Function *rl_startup1_hook = NULL; -Function *rl_getc_function = NULL; +int (*rl_getc_function)(FILE *) = NULL; char *rl_terminal_name = NULL; int rl_already_prompted = 0; int rl_filename_completion_desired = 0; int rl_ignore_completion_duplicates = 0; int rl_catch_signals = 1; +int readline_echoing_p = 1; +int _rl_print_completions_horizontally = 0; VFunction *rl_redisplay_function = NULL; Function *rl_startup_hook = NULL; VFunction *rl_completion_display_matches_hook = NULL; -VFunction *rl_prep_term_function = NULL; -VFunction *rl_deprep_term_function = NULL; +VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal; +VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal; /* * The current prompt string. @@ -150,7 +143,7 @@ int rl_completion_query_items = 100; * in the parsed text when it is passed to the completion function. * Shell uses this to help determine what kind of completing to do. */ -char *rl_special_prefixes = (char *)NULL; +char *rl_special_prefixes = NULL; /* * This is the character appended to the completed words if at the end of @@ -160,25 +153,21 @@ int rl_completion_append_character = ' '; /* stuff below is used internally by libedit for readline emulation */ -/* if not zero, non-unique completions always show list of possible matches */ -static int _rl_complete_show_all = 0; - static History *h = NULL; static EditLine *e = NULL; static Function *map[256]; -static int el_rl_complete_cmdnum = 0; +static jmp_buf topbuf; /* internal functions */ static unsigned char _el_rl_complete(EditLine *, int); static unsigned char _el_rl_tstp(EditLine *, int); static char *_get_prompt(EditLine *); +static int _getc_function(EditLine *, char *); static HIST_ENTRY *_move_history(int); static int _history_expand_command(const char *, size_t, size_t, char **); static char *_rl_compat_sub(const char *, const char *, const char *, int); -static int _rl_complete_internal(int); -static int _rl_qsort_string_compare(const void *, const void *); static int _rl_event_read_char(EditLine *, char *); static void _rl_update_pos(void); @@ -205,16 +194,49 @@ _move_history(int op) return (HIST_ENTRY *) NULL; rl_he.line = ev.str; - rl_he.data = (histdata_t) &(ev.num); + rl_he.data = NULL; return (&rl_he); } +/* + * read one key from user defined input function + */ +static int +/*ARGSUSED*/ +_getc_function(EditLine *el, char *c) +{ + int i; + + i = (*rl_getc_function)(NULL); + if (i == -1) + return 0; + *c = i; + return 1; +} + + /* * READLINE compatibility stuff */ +/* + * Set the prompt + */ +int +rl_set_prompt(const char *prompt) +{ + if (!prompt) + prompt = ""; + if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0) + return 0; + if (rl_prompt) + free(rl_prompt); + rl_prompt = strdup(prompt); + return rl_prompt == NULL ? -1 : 0; +} + /* * initialize rl compat stuff */ @@ -223,7 +245,6 @@ rl_initialize(void) { HistEvent ev; const LineInfo *li; - int i; int editmode = 1; struct termios t; @@ -257,9 +278,12 @@ rl_initialize(void) max_input_history = INT_MAX; el_set(e, EL_HIST, history, h); + /* setup getc function if valid */ + if (rl_getc_function) + el_set(e, EL_GETCFN, _getc_function); + /* for proper prompt printing in readline() */ - rl_prompt = strdup(""); - if (rl_prompt == NULL) { + if (rl_set_prompt("") == -1) { history_end(h); el_end(e); return -1; @@ -291,17 +315,6 @@ rl_initialize(void) "ReadLine compatible suspend function", _el_rl_tstp); el_set(e, EL_BIND, "^Z", "rl_tstp", NULL); - - /* - * Find out where the rl_complete function was added; this is - * used later to detect that lastcmd was also rl_complete. - */ - for(i=EL_NUM_FCNS; i < e->el_map.nfunc; i++) { - if (e->el_map.func[i] == _el_rl_complete) { - el_rl_complete_cmdnum = i; - break; - } - } /* read settings from configuration file */ el_source(e, NULL); @@ -327,9 +340,10 @@ rl_initialize(void) * trailing newline (if there is any) */ char * -readline(const char *prompt) +readline(const char *p) { HistEvent ev; + const char * volatile prompt = p; int count; const char *ret; char *buf; @@ -340,15 +354,11 @@ readline(const char *prompt) rl_done = 0; + (void)setjmp(topbuf); + /* update prompt accordingly to what has been passed */ - if (!prompt) - prompt = ""; - if (strcmp(rl_prompt, prompt) != 0) { - free(rl_prompt); - rl_prompt = strdup(prompt); - if (rl_prompt == NULL) - return NULL; - } + if (rl_set_prompt(prompt) == -1) + return NULL; if (rl_pre_input_hook) (*rl_pre_input_hook)(NULL, 0); @@ -446,7 +456,7 @@ _rl_compat_sub(const char *str, const char *what, const char *with, } else *r++ = *s++; } - *r = 0; + *r = '\0'; return(result); } @@ -467,7 +477,7 @@ get_history_event(const char *cmd, int *cindex, int qchar) return(NULL); /* find out which event to take */ - if (cmd[idx] == history_expansion_char || cmd[idx] == 0) { + if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') { if (history(h, &ev, H_FIRST) != 0) return(NULL); *cindex = cmd[idx]? (idx + 1):idx; @@ -689,7 +699,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, if (aptr) free(aptr); - if (*cmd == 0 || (cmd - (command + offs) >= cmdlen)) { + if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) { *result = tmp; return(1); } @@ -699,7 +709,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, continue; else if (*cmd == 'h') { /* remove trailing path */ if ((aptr = strrchr(tmp, '/')) != NULL) - *aptr = 0; + *aptr = '\0'; } else if (*cmd == 't') { /* remove leading path */ if ((aptr = strrchr(tmp, '/')) != NULL) { aptr = strdup(aptr + 1); @@ -708,7 +718,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, } } else if (*cmd == 'r') { /* remove trailing suffix */ if ((aptr = strrchr(tmp, '.')) != NULL) - *aptr = 0; + *aptr = '\0'; } else if (*cmd == 'e') { /* remove all but suffix */ if ((aptr = strrchr(tmp, '.')) != NULL) { aptr = strdup(aptr); @@ -732,6 +742,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, what = realloc(from, size); if (what == NULL) { free(from); + free(tmp); return 0; } len = 0; @@ -744,6 +755,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, (size <<= 1)); if (nwhat == NULL) { free(what); + free(tmp); return 0; } what = nwhat; @@ -756,10 +768,13 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, free(what); if (search) { from = strdup(search); - if (from == NULL) + if (from == NULL) { + free(tmp); return 0; + } } else { from = NULL; + free(tmp); return (-1); } } @@ -771,6 +786,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, with = realloc(to, size); if (with == NULL) { free(to); + free(tmp); return -1; } len = 0; @@ -782,6 +798,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, nwith = realloc(with, size); if (nwith == NULL) { free(with); + free(tmp); return -1; } with = nwith; @@ -850,12 +867,14 @@ history_expand(char *str, char **output) return 0; } -#define ADD_STRING(what, len) \ +#define ADD_STRING(what, len, fr) \ { \ if (idx + len + 1 > size) { \ char *nresult = realloc(result, (size += len + 1));\ if (nresult == NULL) { \ free(*output); \ + if (/*CONSTCOND*/fr) \ + free(tmp); \ return 0; \ } \ result = nresult; \ @@ -867,6 +886,7 @@ history_expand(char *str, char **output) result = NULL; size = idx = 0; + tmp = NULL; for (i = 0; str[i];) { int qchar, loop_again; size_t len, start, j; @@ -904,13 +924,11 @@ loop: goto loop; } len = i - start; - tmp = &str[start]; - ADD_STRING(tmp, len); + ADD_STRING(&str[start], len, 0); if (str[i] == '\0' || str[i] != history_expansion_char) { len = j - i; - tmp = &str[i]; - ADD_STRING(tmp, len); + ADD_STRING(&str[i], len, 0); if (start == 0) ret = 0; else @@ -920,8 +938,11 @@ loop: ret = _history_expand_command (str, i, (j - i), &tmp); if (ret > 0 && tmp) { len = strlen(tmp); - ADD_STRING(tmp, len); + ADD_STRING(tmp, len, 1); + } + if (tmp) { free(tmp); + tmp = NULL; } i = j; } @@ -973,23 +994,23 @@ history_arg_extract(int start, int end, const char *str) if (start < 0) start = end; - if (start < 0 || end < 0 || start > max || end > max || start > end) + if (start < 0 || end < 0 || (size_t)start > max || (size_t)end > max || start > end) return(NULL); - for (i = start, len = 0; i <= end; i++) + for (i = start, len = 0; i <= (size_t)end; i++) len += strlen(arr[i]) + 1; len++; result = malloc(len); if (result == NULL) return NULL; - for (i = start, len = 0; i <= end; i++) { + for (i = start, len = 0; i <= (size_t)end; i++) { (void)strcpy(result + len, arr[i]); len += strlen(arr[i]); - if (i < end) + if (i < (size_t)end) result[len++] = ' '; } - result[len] = 0; + result[len] = '\0'; for (i = 0; arr[i]; i++) free(arr[i]); @@ -1152,7 +1173,7 @@ history_get(int num) return (NULL); /* error */ /* look backwards for event matching specified offset */ - if (history(h, &ev, H_NEXT_EVENT, num)) + if (history(h, &ev, H_NEXT_EVENT, num + 1)) return (NULL); she.line = ev.str; @@ -1184,6 +1205,31 @@ add_history(const char *line) } +/* + * remove the specified entry from the history list and return it. + */ +HIST_ENTRY * +remove_history(int num) +{ + HIST_ENTRY *she; + HistEvent ev; + + if (h == NULL || e == NULL) + rl_initialize(); + + if (history(h, &ev, H_DEL, num) != 0) + return NULL; + + if ((she = malloc(sizeof(*she))) == NULL) + return NULL; + + she->line = ev.str; + she->data = NULL; + + return she; +} + + /* * clear the history list - delete all entries */ @@ -1377,172 +1423,18 @@ history_search_pos(const char *str, /********************************/ /* completion functions */ -/* - * does tilde expansion of strings of type ``~user/foo'' - * if ``user'' isn't valid user name or ``txt'' doesn't start - * w/ '~', returns pointer to strdup()ed copy of ``txt'' - * - * it's callers's responsibility to free() returned string - */ char * -tilde_expand(char *txt) +tilde_expand(char *name) { - struct passwd *pass; - char *temp; - size_t len = 0; - - if (txt[0] != '~') - return (strdup(txt)); - - temp = strchr(txt + 1, '/'); - if (temp == NULL) { - temp = strdup(txt + 1); - if (temp == NULL) - return NULL; - } else { - len = temp - txt + 1; /* text until string after slash */ - temp = malloc(len); - if (temp == NULL) - return NULL; - (void)strncpy(temp, txt + 1, len - 2); - temp[len - 2] = '\0'; - } - pass = getpwnam(temp); - free(temp); /* value no more needed */ - if (pass == NULL) - return (strdup(txt)); - - /* update pointer txt to point at string immedially following */ - /* first slash */ - txt += len; - - temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1); - if (temp == NULL) - return NULL; - (void)sprintf(temp, "%s/%s", pass->pw_dir, txt); - - return (temp); + return fn_tilde_expand(name); } - -/* - * return first found file name starting by the ``text'' or NULL if no - * such file can be found - * value of ``state'' is ignored - * - * it's caller's responsibility to free returned string - */ char * -filename_completion_function(const char *text, int state) +filename_completion_function(const char *name, int state) { - static DIR *dir = NULL; - static char *filename = NULL, *dirname = NULL; - static size_t filename_len = 0; - struct dirent *entry; - char *temp; - size_t len; - - if (state == 0 || dir == NULL) { - temp = strrchr(text, '/'); - if (temp) { - char *nptr; - temp++; - nptr = realloc(filename, strlen(temp) + 1); - if (nptr == NULL) { - free(filename); - return NULL; - } - filename = nptr; - (void)strcpy(filename, temp); - len = temp - text; /* including last slash */ - nptr = realloc(dirname, len + 1); - if (nptr == NULL) { - free(filename); - return NULL; - } - dirname = nptr; - (void)strncpy(dirname, text, len); - dirname[len] = '\0'; - } else { - if (*text == 0) - filename = NULL; - else { - filename = strdup(text); - if (filename == NULL) - return NULL; - } - dirname = NULL; - } - - /* support for ``~user'' syntax */ - if (dirname && *dirname == '~') { - char *nptr; - temp = tilde_expand(dirname); - if (temp == NULL) - return NULL; - nptr = realloc(dirname, strlen(temp) + 1); - if (nptr == NULL) { - free(dirname); - return NULL; - } - dirname = nptr; - (void)strcpy(dirname, temp); /* safe */ - free(temp); /* no longer needed */ - } - /* will be used in cycle */ - filename_len = filename ? strlen(filename) : 0; - - if (dir != NULL) { - (void)closedir(dir); - dir = NULL; - } - dir = opendir(dirname ? dirname : "."); - if (!dir) - return (NULL); /* cannot open the directory */ - } - /* find the match */ - while ((entry = readdir(dir)) != NULL) { - /* skip . and .. */ - if (entry->d_name[0] == '.' && (!entry->d_name[1] - || (entry->d_name[1] == '.' && !entry->d_name[2]))) - continue; - if (filename_len == 0) - break; - /* otherwise, get first entry where first */ - /* filename_len characters are equal */ - if (entry->d_name[0] == filename[0] - /* Some dirents have d_namlen, but it is not portable. */ - && strlen(entry->d_name) >= filename_len - && strncmp(entry->d_name, filename, - filename_len) == 0) - break; - } - - if (entry) { /* match found */ - - struct stat stbuf; - /* Some dirents have d_namlen, but it is not portable. */ - len = strlen(entry->d_name) + - ((dirname) ? strlen(dirname) : 0) + 1 + 1; - temp = malloc(len); - if (temp == NULL) - return NULL; - (void)sprintf(temp, "%s%s", - dirname ? dirname : "", entry->d_name); /* safe */ - - /* test, if it's directory */ - if (stat(temp, &stbuf) == 0 && S_ISDIR(stbuf.st_mode)) - strcat(temp, "/"); /* safe */ - } else { - (void)closedir(dir); - dir = NULL; - temp = NULL; - } - - return (temp); + return fn_filename_completion_function(name, state); } - /* * a completion generator for usernames; returns _first_ username * which starts with supplied text @@ -1564,6 +1456,7 @@ username_completion_function(const char *text, int state) if (state == 0) setpwent(); + /* XXXMYSQL: just use non-_r functions for now */ while ((pwd = getpwent()) && text[0] == pwd->pw_name[0] && strcmp(text, pwd->pw_name) == 0); @@ -1575,16 +1468,6 @@ username_completion_function(const char *text, int state) } -/* - * el-compatible wrapper around rl_complete; needed for key binding - */ -/* ARGSUSED */ -static unsigned char -_el_rl_complete(EditLine *el __attribute__((__unused__)), int ch) -{ - return (unsigned char) rl_complete(0, ch); -} - /* * el-compatible wrapper to send TSTP on ^Z */ @@ -1596,273 +1479,36 @@ _el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__un return CC_NORM; } -/* - * returns list of completions for text given - */ -char ** -completion_matches(const char *text, CPFunction *genfunc) -{ - char **match_list = NULL, *retstr, *prevstr; - size_t match_list_len, max_equal, which, i; - size_t matches; - - if (h == NULL || e == NULL) - rl_initialize(); - - matches = 0; - match_list_len = 1; - while ((retstr = (*genfunc) (text, (int)matches)) != NULL) { - /* allow for list terminator here */ - if (matches + 3 >= match_list_len) { - char **nmatch_list; - while (matches + 3 >= match_list_len) - match_list_len <<= 1; - nmatch_list = realloc(match_list, - match_list_len * sizeof(char *)); - if (nmatch_list == NULL) { - free(match_list); - return NULL; - } - match_list = nmatch_list; - - } - match_list[++matches] = retstr; - } - - if (!match_list) - return NULL; /* nothing found */ - - /* find least denominator and insert it to match_list[0] */ - which = 2; - prevstr = match_list[1]; - max_equal = strlen(prevstr); - for (; which <= matches; which++) { - for (i = 0; i < max_equal && - prevstr[i] == match_list[which][i]; i++) - continue; - max_equal = i; - } - - retstr = malloc(max_equal + 1); - if (retstr == NULL) { - free(match_list); - return NULL; - } - (void)strncpy(retstr, match_list[1], max_equal); - retstr[max_equal] = '\0'; - match_list[0] = retstr; - - /* add NULL as last pointer to the array */ - match_list[matches + 1] = (char *) NULL; - - return (match_list); -} - -/* - * Sort function for qsort(). Just wrapper around strcasecmp(). - */ -static int -_rl_qsort_string_compare(i1, i2) - const void *i1, *i2; -{ - const char *s1 = ((const char * const *)i1)[0]; - const char *s2 = ((const char * const *)i2)[0]; - - return strcasecmp(s1, s2); -} - /* * Display list of strings in columnar format on readline's output stream. * 'matches' is list of strings, 'len' is number of strings in 'matches', * 'max' is maximum length of string in 'matches'. */ void -rl_display_match_list (matches, len, max) - char **matches; - int len, max; +rl_display_match_list(char **matches, int len, int max) { - int i, idx, limit, count; - int screenwidth = e->el_term.t_size.h; - /* - * Find out how many entries can be put on one line, count - * with two spaces between strings. - */ - limit = screenwidth / (max + 2); - if (limit == 0) - limit = 1; - - /* how many lines of output */ - count = len / limit; - if (count * limit < len) - count++; - - /* Sort the items if they are not already sorted. */ - qsort(&matches[1], (size_t)(len - 1), sizeof(char *), - _rl_qsort_string_compare); - - idx = 1; - for(; count > 0; count--) { - for(i = 0; i < limit && matches[idx]; i++, idx++) - (void)fprintf(e->el_outfile, "%-*s ", max, - matches[idx]); - (void)fprintf(e->el_outfile, "\n"); - } + fn_display_match_list(e, matches, len, max); } -/* - * Complete the word at or before point, called by rl_complete() - * 'what_to_do' says what to do with the completion. - * `?' means list the possible completions. - * TAB means do standard completion. - * `*' means insert all of the possible completions. - * `!' means to do standard completion, and list all possible completions if - * there is more than one. - * - * Note: '*' support is not implemented - */ -static int -_rl_complete_internal(int what_to_do) +static const char * +/*ARGSUSED*/ +_rl_completion_append_character_function(const char *dummy + __attribute__((__unused__))) { - CPFunction *complet_func; - const LineInfo *li; - char *temp, **matches; - const char *ctemp; - size_t len; - - rl_completion_type = what_to_do; - - if (h == NULL || e == NULL) - rl_initialize(); - - complet_func = rl_completion_entry_function; - if (!complet_func) - complet_func = filename_completion_function; - - /* We now look backwards for the start of a filename/variable word */ - li = el_line(e); - ctemp = (const char *) li->cursor; - while (ctemp > li->buffer - && !strchr(rl_basic_word_break_characters, ctemp[-1]) - && (!rl_special_prefixes - || !strchr(rl_special_prefixes, ctemp[-1]) ) ) - ctemp--; - - len = li->cursor - ctemp; - temp = alloca(len + 1); - (void)strncpy(temp, ctemp, len); - temp[len] = '\0'; - - /* these can be used by function called in completion_matches() */ - /* or (*rl_attempted_completion_function)() */ - _rl_update_pos(); - - if (rl_attempted_completion_function) { - int end = li->cursor - li->buffer; - matches = (*rl_attempted_completion_function) (temp, (int) - (end - len), end); - } else - matches = 0; - if (!rl_attempted_completion_function || !matches) - matches = completion_matches(temp, complet_func); - - if (matches) { - int i, retval = CC_REFRESH; - int matches_num, maxlen, match_len, match_display=1; - - /* - * Only replace the completed string with common part of - * possible matches if there is possible completion. - */ - if (matches[0][0] != '\0') { - el_deletestr(e, (int) len); - el_insertstr(e, matches[0]); - } - - if (what_to_do == '?') - goto display_matches; - - if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) { - /* - * We found exact match. Add a space after - * it, unless we do filename completion and the - * object is a directory. - */ - size_t alen = strlen(matches[0]); - if ((complet_func != filename_completion_function - || (alen > 0 && (matches[0])[alen - 1] != '/')) - && rl_completion_append_character) { - char buf[2]; - buf[0] = rl_completion_append_character; - buf[1] = '\0'; - el_insertstr(e, buf); - } - } else if (what_to_do == '!') { - display_matches: - /* - * More than one match and requested to list possible - * matches. - */ - - for(i=1, maxlen=0; matches[i]; i++) { - match_len = strlen(matches[i]); - if (match_len > maxlen) - maxlen = match_len; - } - matches_num = i - 1; - - /* newline to get on next line from command line */ - (void)fprintf(e->el_outfile, "\n"); - - /* - * If there are too many items, ask user for display - * confirmation. - */ - if (matches_num > rl_completion_query_items) { - (void)fprintf(e->el_outfile, - "Display all %d possibilities? (y or n) ", - matches_num); - (void)fflush(e->el_outfile); - if (getc(stdin) != 'y') - match_display = 0; - (void)fprintf(e->el_outfile, "\n"); - } - - if (match_display) - rl_display_match_list(matches, matches_num, - maxlen); - retval = CC_REDISPLAY; - } else if (matches[0][0]) { - /* - * There was some common match, but the name was - * not complete enough. Next tab will print possible - * completions. - */ - el_beep(e); - } else { - /* lcd is not a valid object - further specification */ - /* is needed */ - el_beep(e); - retval = CC_NORM; - } - - /* free elements of array and the array itself */ - for (i = 0; matches[i]; i++) - free(matches[i]); - free(matches), matches = NULL; - - return (retval); - } - return (CC_NORM); + static char buf[2]; + buf[0] = rl_completion_append_character; + buf[1] = '\0'; + return buf; } /* * complete word at current point */ +/* ARGSUSED */ int -/*ARGSUSED*/ -rl_complete(int ignore, int invoking_key) +rl_complete(int ignore __attribute__((__unused__)), int invoking_key) { if (h == NULL || e == NULL) rl_initialize(); @@ -1873,15 +1519,26 @@ rl_complete(int ignore, int invoking_key) arr[1] = '\0'; el_insertstr(e, arr); return (CC_REFRESH); - } else if (e->el_state.lastcmd == el_rl_complete_cmdnum) - return _rl_complete_internal('?'); - else if (_rl_complete_show_all) - return _rl_complete_internal('!'); - else - return _rl_complete_internal(TAB); + } + + /* Just look at how many global variables modify this operation! */ + return fn_complete(e, + (CPFunction *)rl_completion_entry_function, + rl_attempted_completion_function, + rl_basic_word_break_characters, rl_special_prefixes, + _rl_completion_append_character_function, rl_completion_query_items, + &rl_completion_type, &rl_attempted_completion_over, + &rl_point, &rl_end); } +/* ARGSUSED */ +static unsigned char +_el_rl_complete(EditLine *el __attribute__((__unused__)), int ch) +{ + return (unsigned char)rl_complete(0, ch); +} + /* * misc other functions */ @@ -1989,7 +1646,7 @@ int rl_add_defun(const char *name, Function *fun, int c) { char dest[8]; - if (c >= sizeof(map) / sizeof(map[0]) || c < 0) + if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0) return -1; map[(unsigned char)c] = fun; el_set(e, EL_ADDFN, name, name, rl_bind_wrapper); @@ -2007,11 +1664,7 @@ rl_callback_read_char() if (buf == NULL || count-- <= 0) return; -#ifdef CTRL2 /* _AIX */ - if (count == 0 && buf[0] == CTRL2('d')) -#else - if (count == 0 && buf[0] == CTRL('d')) -#endif + if (count == 0 && buf[0] == e->el_tty.t_c[TS_IO][C_EOF]) done = 1; if (buf[count] == '\n' || buf[count] == '\r') done = 2; @@ -2029,14 +1682,12 @@ rl_callback_read_char() } void -rl_callback_handler_install (const char *prompt, VFunction *linefunc) +rl_callback_handler_install(const char *prompt, VCPFunction *linefunc) { if (e == NULL) { rl_initialize(); } - if (rl_prompt) - free(rl_prompt); - rl_prompt = prompt ? strdup(strchr(prompt, *prompt)) : NULL; + (void)rl_set_prompt(prompt); rl_linefunc = linefunc; el_set(e, EL_UNBUFFERED, 1); } @@ -2045,17 +1696,14 @@ void rl_callback_handler_remove(void) { el_set(e, EL_UNBUFFERED, 0); + rl_linefunc = NULL; } void rl_redisplay(void) { char a[2]; -#ifdef CTRL2 /* _AIX */ - a[0] = CTRL2('r'); -#else - a[0] = CTRL('r'); -#endif + a[0] = e->el_tty.t_c[TS_IO][C_REPRINT]; a[1] = '\0'; el_push(e, a); } @@ -2079,7 +1727,7 @@ rl_prep_terminal(int meta_flag) } void -rl_deprep_terminal() +rl_deprep_terminal(void) { el_set(e, EL_PREP_TERM, 0); } @@ -2104,6 +1752,16 @@ rl_parse_and_bind(const char *line) return (argc ? 1 : 0); } +int +rl_variable_bind(const char *var, const char *value) +{ + /* + * The proper return value is undocument, but this is what the + * readline source seems to do. + */ + return ((el_set(e, EL_BIND, "", var, value) == -1) ? 1 : 0); +} + void rl_stuff_char(int c) { @@ -2119,7 +1777,7 @@ _rl_event_read_char(EditLine *el, char *cp) { int n, num_read = 0; - *cp = 0; + *cp = '\0'; while (rl_event_hook) { (*rl_event_hook)(); @@ -2164,3 +1822,142 @@ _rl_update_pos(void) rl_point = li->cursor - li->buffer; rl_end = li->lastchar - li->buffer; } + +void +rl_get_screen_size(int *rows, int *cols) +{ + if (rows) + el_get(e, EL_GETTC, "li", rows); + if (cols) + el_get(e, EL_GETTC, "co", cols); +} + +void +rl_set_screen_size(int rows, int cols) +{ + char buf[64]; + (void)snprintf(buf, sizeof(buf), "%d", rows); + el_set(e, EL_SETTC, "li", buf); + (void)snprintf(buf, sizeof(buf), "%d", cols); + el_set(e, EL_SETTC, "co", buf); +} + +char ** +rl_completion_matches(const char *str, rl_compentry_func_t *fun) +{ + size_t len, max, i, j, min; + char **list, *match, *a, *b; + + len = 1; + max = 10; + if ((list = malloc(max * sizeof(*list))) == NULL) + return NULL; + + while ((match = (*fun)(str, (int)(len - 1))) != NULL) { + if (len == max) { + char **nl; + max += 10; + if ((nl = realloc(list, max * sizeof(*nl))) == NULL) + goto out; + list = nl; + } + list[len++] = match; + } + if (len == 1) + goto out; + list[len] = NULL; + if (len == 2) { + if ((list[0] = strdup(list[1])) == NULL) + goto out; + return list; + } + qsort(&list[1], len - 1, sizeof(*list), + (int (*)(const void *, const void *)) strcmp); + min = SIZE_T_MAX; + for (i = 1, a = list[i]; i < len - 1; i++, a = b) { + b = list[i + 1]; + for (j = 0; a[j] && a[j] == b[j]; j++) + continue; + if (min > j) + min = j; + } + if (min == 0 && *str) { + if ((list[0] = strdup(str)) == NULL) + goto out; + } else { + if ((list[0] = malloc(min + 1)) == NULL) + goto out; + (void)memcpy(list[0], list[1], min); + list[0][min] = '\0'; + } + return list; + +out: + free(list); + return NULL; +} + +char * +rl_filename_completion_function (const char *text, int state) +{ + return fn_filename_completion_function(text, state); +} + +void +rl_forced_update_display(void) +{ + el_set(e, EL_REFRESH); +} + +int +_rl_abort_internal(void) +{ + el_beep(e); + longjmp(topbuf, 1); + /*NOTREACHED*/ +} + +int +_rl_qsort_string_compare(char **s1, char **s2) +{ + return strcoll(*s1, *s2); +} + +int +/*ARGSUSED*/ +rl_kill_text(int from, int to) +{ + return 0; +} + +Keymap +rl_make_bare_keymap(void) +{ + return NULL; +} + +Keymap +rl_get_keymap(void) +{ + return NULL; +} + +void +/*ARGSUSED*/ +rl_set_keymap(Keymap k) +{ +} + +int +/*ARGSUSED*/ +rl_generic_bind(int type, const char * keyseq, const char * data, Keymap k) +{ + return 0; +} + +int +/*ARGSUSED*/ +rl_bind_key_in_map(int key, Function *fun, Keymap k) +{ + return 0; +} diff --git a/cmd-line-utils/libedit/readline/readline.h b/cmd-line-utils/libedit/readline/readline.h index 6b1fa186512..c4806734bc5 100644 --- a/cmd-line-utils/libedit/readline/readline.h +++ b/cmd-line-utils/libedit/readline/readline.h @@ -1,4 +1,4 @@ -/* $NetBSD: readline.h,v 1.12 2004/09/08 18:15:37 christos Exp $ */ +/* $NetBSD: readline.h,v 1.24 2009/02/05 19:15:26 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -15,13 +15,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -45,14 +38,14 @@ /* typedefs */ typedef int Function(const char *, int); typedef void VFunction(void); +typedef void VCPFunction(char *); typedef char *CPFunction(const char *, int); typedef char **CPPFunction(const char *, int, int); - -typedef void *histdata_t; +typedef char *rl_compentry_func_t(const char *, int); typedef struct _hist_entry { const char *line; - histdata_t *data; + const char *data; } HIST_ENTRY; typedef struct _keymap_entry { @@ -73,7 +66,7 @@ typedef KEYMAP_ENTRY *Keymap; #ifndef CTRL #include -#if defined(__GLIBC__) || defined(__MWERKS__) +#if !defined(__sun__) && !defined(__hpux__) #include #endif #ifndef CTRL @@ -102,8 +95,9 @@ extern int max_input_history; extern char *rl_basic_word_break_characters; extern char *rl_completer_word_break_characters; extern char *rl_completer_quote_characters; -extern CPFunction *rl_completion_entry_function; +extern Function *rl_completion_entry_function; extern CPPFunction *rl_attempted_completion_function; +extern int rl_attempted_completion_over; extern int rl_completion_type; extern int rl_completion_query_items; extern char *rl_special_prefixes; @@ -122,11 +116,13 @@ extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_ctlx_keymap; extern int rl_filename_completion_desired; extern int rl_ignore_completion_duplicates; -extern Function *rl_getc_function; +extern int (*rl_getc_function)(FILE *); extern VFunction *rl_redisplay_function; extern VFunction *rl_completion_display_matches_hook; extern VFunction *rl_prep_term_function; extern VFunction *rl_deprep_term_function; +extern int readline_echoing_p; +extern int _rl_print_completions_horizontally; /* supported functions */ char *readline(const char *); @@ -141,6 +137,7 @@ int history_is_stifled(void); int where_history(void); HIST_ENTRY *current_history(void); HIST_ENTRY *history_get(int); +HIST_ENTRY *remove_history(int); int history_total_bytes(void); int history_set_pos(int); HIST_ENTRY *previous_history(void); @@ -168,7 +165,7 @@ void rl_reset_terminal(const char *); int rl_bind_key(int, int (*)(int, int)); int rl_newline(int, int); void rl_callback_read_char(void); -void rl_callback_handler_install(const char *, VFunction *); +void rl_callback_handler_install(const char *, VCPFunction *); void rl_callback_handler_remove(void); void rl_redisplay(void); int rl_get_previous_history(int, int); @@ -176,13 +173,24 @@ void rl_prep_terminal(int); void rl_deprep_terminal(void); int rl_read_init_file(const char *); int rl_parse_and_bind(const char *); +int rl_variable_bind(const char *, const char *); void rl_stuff_char(int); int rl_add_defun(const char *, Function *, int); +void rl_get_screen_size(int *, int *); +void rl_set_screen_size(int, int); +char *rl_filename_completion_function (const char *, int); +int _rl_abort_internal(void); +int _rl_qsort_string_compare(char **, char **); +char **rl_completion_matches(const char *, rl_compentry_func_t *); +void rl_forced_update_display(void); +int rl_set_prompt(const char *); /* * The following are not implemented */ +int rl_kill_text(int, int); Keymap rl_get_keymap(void); +void rl_set_keymap(Keymap); Keymap rl_make_bare_keymap(void); int rl_generic_bind(int, const char *, const char *, Keymap); int rl_bind_key_in_map(int, Function *, Keymap); diff --git a/cmd-line-utils/libedit/refresh.c b/cmd-line-utils/libedit/refresh.c index 46aca15ef08..5edd1fe78fc 100644 --- a/cmd-line-utils/libedit/refresh.c +++ b/cmd-line-utils/libedit/refresh.c @@ -1,4 +1,4 @@ -/* $NetBSD: refresh.c,v 1.26 2003/08/07 16:44:33 agc Exp $ */ +/* $NetBSD: refresh.c,v 1.28 2008/09/10 15:45:37 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * refresh.c: Lower level screen refreshing functions @@ -49,6 +55,7 @@ private void re_update_line(EditLine *, char *, char *, int); private void re_insert (EditLine *, char *, int, int, char *, int); private void re_delete(EditLine *, char *, int, int, int); private void re_fastputc(EditLine *, int); +private void re_clear_eol(EditLine *, int, int, int); private void re__strncopy(char *, char *, size_t); private void re__copy_and_pad(char *, const char *, size_t); @@ -315,9 +322,9 @@ re_goto_bottom(EditLine *el) { term_move_to_line(el, el->el_refresh.r_oldcv); - term__putc('\n'); + term__putc(el, '\n'); re_clear_display(el); - term__flush(); + term__flush(el); } @@ -340,7 +347,7 @@ re_insert(EditLine *el __attribute__((__unused__)), ELRE_DEBUG(1, (__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n", num, dat, dlen, d)); - ELRE_DEBUG(1, (__F, "s == \"%s\"n", s)); + ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); /* open up the space for num chars */ if (num > 0) { @@ -353,7 +360,7 @@ re_insert(EditLine *el __attribute__((__unused__)), ELRE_DEBUG(1, (__F, "re_insert() after insert: %d at %d max %d, d == \"%s\"\n", num, dat, dlen, d)); - ELRE_DEBUG(1, (__F, "s == \"%s\"n", s)); + ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); /* copy the characters */ for (a = d + dat; (a < d + dlen) && (num > 0); num--) @@ -362,7 +369,7 @@ re_insert(EditLine *el __attribute__((__unused__)), ELRE_DEBUG(1, (__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n", num, dat, dlen, d, s)); - ELRE_DEBUG(1, (__F, "s == \"%s\"n", s)); + ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); } @@ -411,6 +418,32 @@ re__strncopy(char *a, char *b, size_t n) *a++ = *b++; } +/* re_clear_eol(): + * Find the number of characters we need to clear till the end of line + * in order to make sure that we have cleared the previous contents of + * the line. fx and sx is the number of characters inserted or deleted + * int the first or second diff, diff is the difference between the + * number of characters between the new and old line. + */ +private void +re_clear_eol(EditLine *el, int fx, int sx, int diff) +{ + + ELRE_DEBUG(1, (__F, "re_clear_eol sx %d, fx %d, diff %d\n", + sx, fx, diff)); + + if (fx < 0) + fx = -fx; + if (sx < 0) + sx = -sx; + if (fx > diff) + diff = fx; + if (sx > diff) + diff = sx; + + ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff)); + term_clear_EOL(el, diff); +} /***************************************************************** re_update_line() is based on finding the middle difference of each line @@ -626,7 +659,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) fx = (nsb - nfd) - (osb - ofd); sx = (nls - nse) - (ols - ose); - ELRE_DEBUG(1, (__F, "\n")); + ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx)); ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n", ofd - old, osb - old, ose - old, ols - old, oe - old)); ELRE_DEBUG(1, (__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n", @@ -775,9 +808,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) * write (nsb-nfd) chars of new starting at nfd */ term_overwrite(el, nfd, (nsb - nfd)); - ELRE_DEBUG(1, (__F, - "cleareol %d\n", (oe - old) - (ne - new))); - term_clear_EOL(el, (oe - old) - (ne - new)); + re_clear_eol(el, fx, sx, (oe - old) - (ne - new)); /* * Done */ @@ -818,10 +849,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) ELRE_DEBUG(1, (__F, "but with nothing left to save\r\n")); term_overwrite(el, nse, (nls - nse)); - ELRE_DEBUG(1, (__F, - "cleareol %d\n", (oe - old) - (ne - new))); - if ((oe - old) - (ne - new) != 0) - term_clear_EOL(el, (oe - old) - (ne - new)); + re_clear_eol(el, fx, sx, (oe - old) - (ne - new)); } } /* @@ -982,7 +1010,7 @@ re_refresh_cursor(EditLine *el) /* now go there */ term_move_to_line(el, v); term_move_to_char(el, h); - term__flush(); + term__flush(el); } @@ -993,7 +1021,7 @@ private void re_fastputc(EditLine *el, int c) { - term__putc(c); + term__putc(el, c); el->el_display[el->el_cursor.v][el->el_cursor.h++] = c; if (el->el_cursor.h >= el->el_term.t_size.h) { /* if we must overflow */ @@ -1020,12 +1048,12 @@ re_fastputc(EditLine *el, int c) } if (EL_HAS_AUTO_MARGINS) { if (EL_HAS_MAGIC_MARGINS) { - term__putc(' '); - term__putc('\b'); + term__putc(el, ' '); + term__putc(el, '\b'); } } else { - term__putc('\r'); - term__putc('\n'); + term__putc(el, '\r'); + term__putc(el, '\n'); } } } @@ -1065,7 +1093,7 @@ re_fastaddc(EditLine *el) re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0')); re_fastputc(el, (c & 7) + '0'); } - term__flush(); + term__flush(el); } @@ -1104,7 +1132,7 @@ re_clear_lines(EditLine *el) } else { term_move_to_line(el, el->el_refresh.r_oldcv); /* go to last line */ - term__putc('\r'); /* go to BOL */ - term__putc('\n'); /* go to new line */ + term__putc(el, '\r'); /* go to BOL */ + term__putc(el, '\n'); /* go to new line */ } } diff --git a/cmd-line-utils/libedit/search.c b/cmd-line-utils/libedit/search.c index 850c5f27140..df50c7e7370 100644 --- a/cmd-line-utils/libedit/search.c +++ b/cmd-line-utils/libedit/search.c @@ -32,12 +32,17 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * search.c: History and character search functions */ -#include #include #if defined(REGEX) #include diff --git a/cmd-line-utils/libedit/sig.c b/cmd-line-utils/libedit/sig.c index 8e70933d606..5307ee6ec60 100644 --- a/cmd-line-utils/libedit/sig.c +++ b/cmd-line-utils/libedit/sig.c @@ -1,4 +1,4 @@ -/* $NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $ */ +/* $NetBSD: sig.c,v 1.12 2008/09/10 15:45:37 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * sig.c: Signal handling stuff. @@ -51,15 +57,15 @@ private const int sighdl[] = { - 1 }; -private void sig_handler(int); +private void el_sig_handler(int); -/* sig_handler(): +/* el_sig_handler(): * This is the handler called for all signals * XXX: we cannot pass any data so we just store the old editline * state in a private variable */ private void -sig_handler(int signo) +el_sig_handler(int signo) { int i; sigset_t nset, oset; @@ -73,7 +79,7 @@ sig_handler(int signo) tty_rawmode(sel); if (ed_redisplay(sel, 0) == CC_REFRESH) re_refresh(sel); - term__flush(); + term__flush(sel); break; case SIGWINCH: @@ -154,7 +160,7 @@ sig_set(EditLine *el) for (i = 0; sighdl[i] != -1; i++) { el_signalhandler_t s; /* This could happen if we get interrupted */ - if ((s = signal(sighdl[i], sig_handler)) != sig_handler) + if ((s = signal(sighdl[i], el_sig_handler)) != el_sig_handler) el->el_signal[i] = s; } sel = el; diff --git a/cmd-line-utils/libedit/sig.h b/cmd-line-utils/libedit/sig.h index 0bf1fc37e39..2bd3c516d46 100644 --- a/cmd-line-utils/libedit/sig.h +++ b/cmd-line-utils/libedit/sig.h @@ -1,4 +1,4 @@ -/* $NetBSD: sig.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */ +/* $NetBSD: sig.h,v 1.6 2008/07/12 15:27:14 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -51,7 +51,6 @@ #define ALLSIGS \ _DO(SIGINT) \ _DO(SIGTSTP) \ - _DO(SIGSTOP) \ _DO(SIGQUIT) \ _DO(SIGHUP) \ _DO(SIGTERM) \ diff --git a/cmd-line-utils/libedit/strlcpy.c b/cmd-line-utils/libedit/strlcpy.c deleted file mode 100644 index e38d6cf1c4b..00000000000 --- a/cmd-line-utils/libedit/strlcpy.c +++ /dev/null @@ -1,73 +0,0 @@ -/* $NetBSD: strlcpy.c,v 1.14 2003/10/27 00:12:42 lukem Exp $ */ -/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */ - -/* - * Copyright (c) 1998 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE - * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include -#include -#include - -#ifdef _LIBC -# ifdef __weak_alias -__weak_alias(strlcpy, _strlcpy) -# endif -#endif - -#if !HAVE_STRLCPY -/* - * Copy src to string dst of size siz. At most siz-1 characters - * will be copied. Always NUL terminates (unless siz == 0). - * Returns strlen(src); if retval >= siz, truncation occurred. - */ -size_t -#ifdef _LIBC -_strlcpy(dst, src, siz) -#else -strlcpy(dst, src, siz) -#endif - char *dst; - const char *src; - size_t siz; -{ - char *d = dst; - const char *s = src; - size_t n = siz; - - _DIAGASSERT(dst != NULL); - _DIAGASSERT(src != NULL); - - /* Copy as many bytes as will fit */ - if (n != 0 && --n != 0) { - do { - if ((*d++ = *s++) == 0) - break; - } while (--n != 0); - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; - } - - return(s - src - 1); /* count does not include NUL */ -} -#endif diff --git a/cmd-line-utils/libedit/strlcpy.h b/cmd-line-utils/libedit/strlcpy.h deleted file mode 100644 index e4d3a7ffa3f..00000000000 --- a/cmd-line-utils/libedit/strlcpy.h +++ /dev/null @@ -1,2 +0,0 @@ -size_t strlcpy(char *dst, const char *src, size_t size); -size_t strlcat(char *dst, const char *src, size_t size); diff --git a/cmd-line-utils/libedit/sys.h b/cmd-line-utils/libedit/sys.h index c8a29dbfb05..a0369affbb0 100644 --- a/cmd-line-utils/libedit/sys.h +++ b/cmd-line-utils/libedit/sys.h @@ -48,14 +48,14 @@ # define __attribute__(A) #endif -#ifndef __P -# define __P(x) x -#endif - #ifndef _DIAGASSERT # define _DIAGASSERT(x) #endif +#ifndef SIZE_T_MAX +# define SIZE_T_MAX UINT_MAX +#endif + #ifndef __BEGIN_DECLS # ifdef __cplusplus # define __BEGIN_DECLS extern "C" { @@ -113,6 +113,25 @@ char *fgetln(FILE *fp, size_t *len); #define REGEX /* Use POSIX.2 regular expression functions */ #undef REGEXP /* Use UNIX V8 regular expression functions */ +#ifdef __SunOS +extern int tgetent(char *, const char *); +extern int tgetflag(char *); +extern int tgetnum(char *); +extern int tputs(const char *, int, int (*)(int)); +extern char* tgoto(const char*, int, int); +extern char* tgetstr(char*, char**); +#endif + +/* XXXMYSQL: Bug#10218 Command line recall rolls into segfault */ +#if !HAVE_DECL_TGOTO +/* + 'tgoto' is not declared in the system header files, this causes + problems on 64-bit systems. The function returns a 64 bit pointer + but caller see it as "int" and it's thus truncated to 32-bit +*/ +extern char* tgoto(const char*, int, int); +#endif + #ifdef notdef # undef REGEX # undef REGEXP diff --git a/cmd-line-utils/libedit/term.c b/cmd-line-utils/libedit/term.c index b516d6753c3..7a9d0250114 100644 --- a/cmd-line-utils/libedit/term.c +++ b/cmd-line-utils/libedit/term.c @@ -1,4 +1,4 @@ -/* $NetBSD: term.c,v 1.40 2004/05/22 23:21:28 christos Exp $ */ +/* $NetBSD: term.c,v 1.48 2009/02/06 20:08:13 sketch Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * term.c: Editor/termcap-curses interface @@ -44,21 +50,26 @@ #include #include #include - +#ifdef HAVE_TERMCAP_H +#include +#endif #ifdef HAVE_CURSES_H -# include -#elif HAVE_NCURSES_H -# include +#include +#endif +#ifdef HAVE_NCURSES_H +#include #endif - /* Solaris's term.h does horrid things. */ -#if (defined(HAVE_TERM_H) && !defined(_SUNOS)) -# include +#if (defined(HAVE_TERM_H) && !defined(__SunOS)) +#include #endif - #include #include +#ifdef _REENTRANT +#include +#endif + #include "el.h" /* @@ -263,9 +274,13 @@ private int term_alloc_display(EditLine *); private void term_alloc(EditLine *, const struct termcapstr *, const char *); private void term_init_arrow(EditLine *); private void term_reset_arrow(EditLine *); +private int term_putc(int); +private void term_tputs(EditLine *, const char *, int); - -private FILE *term_outfile = NULL; /* XXX: How do we fix that? */ +#ifdef _REENTRANT +private pthread_mutex_t term_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif +private FILE *term_outfile = NULL; /* term_setflags(): @@ -313,7 +328,6 @@ term_setflags(EditLine *el) #endif /* DEBUG_SCREEN */ } - /* term_init(): * Initialize the terminal stuff */ @@ -339,7 +353,6 @@ term_init(EditLine *el) if (el->el_term.t_val == NULL) return (-1); (void) memset(el->el_term.t_val, 0, T_val * sizeof(int)); - term_outfile = el->el_outfile; (void) term_set(el, NULL); term_init_arrow(el); return (0); @@ -390,7 +403,8 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap) * New string is shorter; no need to allocate space */ if (clen <= tlen) { - (void) strcpy(*str, cap); /* XXX strcpy is safe */ + if (*str) + (void) strcpy(*str, cap); /* XXX strcpy is safe */ return; } /* @@ -464,8 +478,12 @@ term_alloc_display(EditLine *el) return (-1); for (i = 0; i < c->v; i++) { b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); - if (b[i] == NULL) + if (b[i] == NULL) { + while (--i >= 0) + el_free((ptr_t) b[i]); + el_free((ptr_t) b); return (-1); + } } b[c->v] = NULL; el->el_display = b; @@ -475,8 +493,12 @@ term_alloc_display(EditLine *el) return (-1); for (i = 0; i < c->v; i++) { b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); - if (b[i] == NULL) + if (b[i] == NULL) { + while (--i >= 0) + el_free((ptr_t) b[i]); + el_free((ptr_t) b); return (-1); + } } b[c->v] = NULL; el->el_vdisplay = b; @@ -542,12 +564,12 @@ term_move_to_line(EditLine *el, int where) del--; } else { if ((del > 1) && GoodStr(T_DO)) { - (void) tputs(tgoto(Str(T_DO), del, del), - del, term__putc); + term_tputs(el, tgoto(Str(T_DO), del, + del), del); del = 0; } else { for (; del > 0; del--) - term__putc('\n'); + term__putc(el, '\n'); /* because the \n will become \r\n */ el->el_cursor.h = 0; } @@ -555,12 +577,11 @@ term_move_to_line(EditLine *el, int where) } } else { /* del < 0 */ if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up))) - (void) tputs(tgoto(Str(T_UP), -del, -del), -del, - term__putc); + term_tputs(el, tgoto(Str(T_UP), -del, -del), -del); else { if (GoodStr(T_up)) for (; del < 0; del++) - (void) tputs(Str(T_up), 1, term__putc); + term_tputs(el, Str(T_up), 1); } } el->el_cursor.v = where;/* now where is here */ @@ -587,7 +608,7 @@ mc_again: return; } if (!where) { /* if where is first column */ - term__putc('\r'); /* do a CR */ + term__putc(el, '\r'); /* do a CR */ el->el_cursor.h = 0; return; } @@ -595,12 +616,11 @@ mc_again: if ((del < -4 || del > 4) && GoodStr(T_ch)) /* go there directly */ - (void) tputs(tgoto(Str(T_ch), where, where), where, term__putc); + term_tputs(el, tgoto(Str(T_ch), where, where), where); else { if (del > 0) { /* moving forward */ if ((del > 4) && GoodStr(T_RI)) - (void) tputs(tgoto(Str(T_RI), del, del), - del, term__putc); + term_tputs(el, tgoto(Str(T_RI), del, del), del); else { /* if I can do tabs, use them */ if (EL_CAN_TAB) { @@ -611,7 +631,7 @@ mc_again: (el->el_cursor.h & 0370); i < (where & 0370); i += 8) - term__putc('\t'); + term__putc(el, '\t'); /* then tab over */ el->el_cursor.h = where & 0370; } @@ -631,8 +651,8 @@ mc_again: } } else { /* del < 0 := moving backward */ if ((-del > 4) && GoodStr(T_LE)) - (void) tputs(tgoto(Str(T_LE), -del, -del), - -del, term__putc); + term_tputs(el, tgoto(Str(T_LE), -del, -del), + -del); else { /* can't go directly there */ /* * if the "cost" is greater than the "cost" @@ -643,12 +663,12 @@ mc_again: (((unsigned int) where >> 3) + (where & 07))) : (-del > where)) { - term__putc('\r'); /* do a CR */ + term__putc(el, '\r'); /* do a CR */ el->el_cursor.h = 0; goto mc_again; /* and try again */ } for (i = 0; i < -del; i++) - term__putc('\b'); + term__putc(el, '\b'); } } } @@ -673,7 +693,7 @@ term_overwrite(EditLine *el, const char *cp, int n) return; } do { - term__putc(*cp++); + term__putc(el, *cp++); el->el_cursor.h++; } while (--n); @@ -689,7 +709,7 @@ term_overwrite(EditLine *el, const char *cp, int n) != '\0') term_overwrite(el, &c, 1); else - term__putc(' '); + term__putc(el, ' '); el->el_cursor.h = 1; } } else /* no wrap, but cursor stays on screen */ @@ -723,19 +743,18 @@ term_deletechars(EditLine *el, int num) if (GoodStr(T_DC)) /* if I have multiple delete */ if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more * expen. */ - (void) tputs(tgoto(Str(T_DC), num, num), - num, term__putc); + term_tputs(el, tgoto(Str(T_DC), num, num), num); return; } if (GoodStr(T_dm)) /* if I have delete mode */ - (void) tputs(Str(T_dm), 1, term__putc); + term_tputs(el, Str(T_dm), 1); if (GoodStr(T_dc)) /* else do one at a time */ while (num--) - (void) tputs(Str(T_dc), 1, term__putc); + term_tputs(el, Str(T_dc), 1); if (GoodStr(T_ed)) /* if I have delete mode */ - (void) tputs(Str(T_ed), 1, term__putc); + term_tputs(el, Str(T_ed), 1); } @@ -764,37 +783,35 @@ term_insertwrite(EditLine *el, char *cp, int num) if (GoodStr(T_IC)) /* if I have multiple insert */ if ((num > 1) || !GoodStr(T_ic)) { /* if ic would be more expensive */ - (void) tputs(tgoto(Str(T_IC), num, num), - num, term__putc); + term_tputs(el, tgoto(Str(T_IC), num, num), num); term_overwrite(el, cp, num); /* this updates el_cursor.h */ return; } if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */ - (void) tputs(Str(T_im), 1, term__putc); + term_tputs(el, Str(T_im), 1); el->el_cursor.h += num; do - term__putc(*cp++); + term__putc(el, *cp++); while (--num); if (GoodStr(T_ip)) /* have to make num chars insert */ - (void) tputs(Str(T_ip), 1, term__putc); + term_tputs(el, Str(T_ip), 1); - (void) tputs(Str(T_ei), 1, term__putc); + term_tputs(el, Str(T_ei), 1); return; } do { if (GoodStr(T_ic)) /* have to make num chars insert */ - (void) tputs(Str(T_ic), 1, term__putc); - /* insert a char */ + term_tputs(el, Str(T_ic), 1); - term__putc(*cp++); + term__putc(el, *cp++); el->el_cursor.h++; if (GoodStr(T_ip)) /* have to make num chars insert */ - (void) tputs(Str(T_ip), 1, term__putc); + term_tputs(el, Str(T_ip), 1); /* pad the inserted char */ } while (--num); @@ -810,10 +827,10 @@ term_clear_EOL(EditLine *el, int num) int i; if (EL_CAN_CEOL && GoodStr(T_ce)) - (void) tputs(Str(T_ce), 1, term__putc); + term_tputs(el, Str(T_ce), 1); else { for (i = 0; i < num; i++) - term__putc(' '); + term__putc(el, ' '); el->el_cursor.h += num; /* have written num spaces */ } } @@ -828,14 +845,14 @@ term_clear_screen(EditLine *el) if (GoodStr(T_cl)) /* send the clear screen code */ - (void) tputs(Str(T_cl), Val(T_li), term__putc); + term_tputs(el, Str(T_cl), Val(T_li)); else if (GoodStr(T_ho) && GoodStr(T_cd)) { - (void) tputs(Str(T_ho), Val(T_li), term__putc); /* home */ + term_tputs(el, Str(T_ho), Val(T_li)); /* home */ /* clear to bottom of screen */ - (void) tputs(Str(T_cd), Val(T_li), term__putc); + term_tputs(el, Str(T_cd), Val(T_li)); } else { - term__putc('\r'); - term__putc('\n'); + term__putc(el, '\r'); + term__putc(el, '\n'); } } @@ -848,9 +865,9 @@ term_beep(EditLine *el) { if (GoodStr(T_bl)) /* what termcap says we should use */ - (void) tputs(Str(T_bl), 1, term__putc); + term_tputs(el, Str(T_bl), 1); else - term__putc('\007'); /* an ASCII bell; ^G */ + term__putc(el, '\007'); /* an ASCII bell; ^G */ } @@ -862,9 +879,9 @@ protected void term_clear_to_bottom(EditLine *el) { if (GoodStr(T_cd)) - (void) tputs(Str(T_cd), Val(T_li), term__putc); + term_tputs(el, Str(T_cd), Val(T_li)); else if (GoodStr(T_ce)) - (void) tputs(Str(T_ce), Val(T_li), term__putc); + term_tputs(el, Str(T_ce), Val(T_li)); } #endif @@ -936,7 +953,7 @@ term_set(EditLine *el, const char *term) Val(T_co) = tgetnum("co"); Val(T_li) = tgetnum("li"); for (t = tstr; t->name != NULL; t++) { - /* XXX: some systems tgetstr needs non const */ + /* XXX: some systems' tgetstr needs non const */ term_alloc(el, t, tgetstr(strchr(t->name, *t->name), &area)); } @@ -1220,26 +1237,62 @@ term_bind_arrow(EditLine *el) } } +/* term_putc(): + * Add a character + */ +private int +term_putc(int c) +{ + + if (term_outfile == NULL) + return -1; + return fputc(c, term_outfile); +} + +private void +term_tputs(EditLine *el, const char *cap, int affcnt) +{ +#ifdef _REENTRANT + pthread_mutex_lock(&term_mutex); +#endif + term_outfile = el->el_outfile; + (void)tputs(cap, affcnt, term_putc); +#ifdef _REENTRANT + pthread_mutex_unlock(&term_mutex); +#endif +} /* term__putc(): * Add a character */ protected int -term__putc(int c) +term__putc(EditLine *el, int c) { - return (fputc(c, term_outfile)); + return fputc(c, el->el_outfile); } - /* term__flush(): * Flush output */ protected void -term__flush(void) +term__flush(EditLine *el) { - (void) fflush(term_outfile); + (void) fflush(el->el_outfile); +} + +/* term_writec(): + * Write the given character out, in a human readable form + */ +protected void +term_writec(EditLine *el, int c) +{ + char buf[8]; + int cnt = key__decode_char(buf, sizeof(buf), 0, c); + buf[cnt] = '\0'; + term_overwrite(el, buf, cnt); + term__flush(el); } @@ -1269,11 +1322,17 @@ term_telltc(EditLine *el, int argc __attribute__((__unused__)), (void) fprintf(el->el_outfile, "\tIt %s magic margins\n", EL_HAS_MAGIC_MARGINS ? "has" : "does not have"); - for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++) + for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++) { + const char *ub; + if (*ts && **ts) { + (void) key__decode_str(*ts, upbuf, sizeof(upbuf), ""); + ub = upbuf; + } else { + ub = "(empty)"; + } (void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n", - t->long_name, - t->name, *ts && **ts ? - key__decode_str(*ts, upbuf, "") : "(empty)"); + t->long_name, t->name, ub); + } (void) fputc('\n', el->el_outfile); return (0); } @@ -1292,7 +1351,7 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), const char *what, *how; if (argv == NULL || argv[1] == NULL || argv[2] == NULL) - return (-1); + return -1; what = argv[1]; how = argv[2]; @@ -1307,7 +1366,7 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), if (ts->name != NULL) { term_alloc(el, ts, how); term_setflags(el); - return (0); + return 0; } /* * Do the numeric ones second @@ -1316,46 +1375,100 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), if (strcmp(tv->name, what) == 0) break; - if (tv->name != NULL) { - if (tv == &tval[T_pt] || tv == &tval[T_km] || - tv == &tval[T_am] || tv == &tval[T_xn]) { - if (strcmp(how, "yes") == 0) - el->el_term.t_val[tv - tval] = 1; - else if (strcmp(how, "no") == 0) - el->el_term.t_val[tv - tval] = 0; - else { - (void) fprintf(el->el_errfile, - "settc: Bad value `%s'.\n", how); - return (-1); - } - term_setflags(el); - if (term_change_size(el, Val(T_li), Val(T_co)) == -1) - return (-1); - return (0); - } else { - long i; - char *ep; + if (tv->name != NULL) + return -1; - i = strtol(how, &ep, 10); - if (*ep != '\0') { - (void) fprintf(el->el_errfile, - "settc: Bad value `%s'.\n", how); - return (-1); - } - el->el_term.t_val[tv - tval] = (int) i; - el->el_term.t_size.v = Val(T_co); - el->el_term.t_size.h = Val(T_li); - if (tv == &tval[T_co] || tv == &tval[T_li]) - if (term_change_size(el, Val(T_li), Val(T_co)) - == -1) - return (-1); - return (0); + if (tv == &tval[T_pt] || tv == &tval[T_km] || + tv == &tval[T_am] || tv == &tval[T_xn]) { + if (strcmp(how, "yes") == 0) + el->el_term.t_val[tv - tval] = 1; + else if (strcmp(how, "no") == 0) + el->el_term.t_val[tv - tval] = 0; + else { + (void) fprintf(el->el_errfile, + "%s: Bad value `%s'.\n", argv[0], how); + return -1; } + term_setflags(el); + if (term_change_size(el, Val(T_li), Val(T_co)) == -1) + return -1; + return 0; + } else { + long i; + char *ep; + + i = strtol(how, &ep, 10); + if (*ep != '\0') { + (void) fprintf(el->el_errfile, + "%s: Bad value `%s'.\n", argv[0], how); + return -1; + } + el->el_term.t_val[tv - tval] = (int) i; + el->el_term.t_size.v = Val(T_co); + el->el_term.t_size.h = Val(T_li); + if (tv == &tval[T_co] || tv == &tval[T_li]) + if (term_change_size(el, Val(T_li), Val(T_co)) + == -1) + return -1; + return 0; } - return (-1); } +/* term_gettc(): + * Get the current terminal characteristics + */ +protected int +/*ARGSUSED*/ +term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) +{ + const struct termcapstr *ts; + const struct termcapval *tv; + char *what; + void *how; + + if (argv == NULL || argv[1] == NULL || argv[2] == NULL) + return (-1); + + what = argv[1]; + how = argv[2]; + + /* + * Do the strings first + */ + for (ts = tstr; ts->name != NULL; ts++) + if (strcmp(ts->name, what) == 0) + break; + + if (ts->name != NULL) { + *(char **)how = el->el_term.t_str[ts - tstr]; + return 0; + } + /* + * Do the numeric ones second + */ + for (tv = tval; tv->name != NULL; tv++) + if (strcmp(tv->name, what) == 0) + break; + + if (tv->name == NULL) + return -1; + + if (tv == &tval[T_pt] || tv == &tval[T_km] || + tv == &tval[T_am] || tv == &tval[T_xn]) { + static char yes[] = "yes"; + static char no[] = "no"; + if (el->el_term.t_val[tv - tval]) + *(char **)how = yes; + else + *(char **)how = no; + return 0; + } else { + *(int *)how = el->el_term.t_val[tv - tval]; + return 0; + } +} + /* term_echotc(): * Print the termcap string out with variable substitution */ @@ -1441,7 +1554,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), break; } if (t->name == NULL) { - /* XXX: some systems tgetstr needs non const */ + /* XXX: some systems' tgetstr needs non const */ scap = tgetstr(strchr(*argv, **argv), &area); } if (!scap || scap[0] == '\0') { @@ -1494,7 +1607,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), *argv); return (-1); } - (void) tputs(scap, 1, term__putc); + term_tputs(el, scap, 1); break; case 1: argv++; @@ -1522,7 +1635,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), *argv); return (-1); } - (void) tputs(tgoto(scap, arg_cols, arg_rows), 1, term__putc); + term_tputs(el, tgoto(scap, arg_cols, arg_rows), 1); break; default: /* This is wrong, but I will ignore it... */ @@ -1578,8 +1691,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), *argv); return (-1); } - (void) tputs(tgoto(scap, arg_cols, arg_rows), arg_rows, - term__putc); + term_tputs(el, tgoto(scap, arg_cols, arg_rows), arg_rows); break; } return (0); diff --git a/cmd-line-utils/libedit/tokenizer.c b/cmd-line-utils/libedit/tokenizer.c index 561b41740f8..5161cdd0a22 100644 --- a/cmd-line-utils/libedit/tokenizer.c +++ b/cmd-line-utils/libedit/tokenizer.c @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * tokenize.c: Bourne shell like tokenizer diff --git a/cmd-line-utils/libedit/tokenizer.h b/cmd-line-utils/libedit/tokenizer.h deleted file mode 100644 index 7cc7a3346e4..00000000000 --- a/cmd-line-utils/libedit/tokenizer.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $NetBSD: tokenizer.h,v 1.5 2002/03/18 16:01:00 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tokenizer.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * tokenizer.h: Header file for tokenizer routines - */ -#ifndef _h_tokenizer -#define _h_tokenizer - -typedef struct tokenizer Tokenizer; - -Tokenizer *tok_init(const char *); -void tok_reset(Tokenizer *); -void tok_end(Tokenizer *); -int tok_line(Tokenizer *, const char *, int *, const char ***); - -#endif /* _h_tokenizer */ diff --git a/cmd-line-utils/libedit/tty.c b/cmd-line-utils/libedit/tty.c index 6f73fb4f9e7..3706905fc79 100644 --- a/cmd-line-utils/libedit/tty.c +++ b/cmd-line-utils/libedit/tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.21 2004/08/13 12:10:39 mycroft Exp $ */ +/* $NetBSD: tty.c,v 1.28 2009/02/06 19:53:23 sketch Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,18 +32,25 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * tty.c: tty interface stuff */ #include +#include #include "tty.h" #include "el.h" typedef struct ttymodes_t { const char *m_name; - u_int m_value; + unsigned int m_value; int m_type; } ttymodes_t; @@ -438,13 +445,12 @@ private const ttymodes_t ttymodes[] = { -#define tty_getty(el, td) tcgetattr((el)->el_infd, (td)) -#define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td)) - #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1) #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8) #define tty__cooked_mode(td) ((td)->c_lflag & ICANON) +private int tty_getty(EditLine *, struct termios *); +private int tty_setty(EditLine *, int, const struct termios *); private int tty__getcharindex(int); private void tty__getchar(struct termios *, unsigned char *); private void tty__setchar(struct termios *, unsigned char *); @@ -453,6 +459,29 @@ private int tty_setup(EditLine *); #define t_qu t_ts +/* tty_getty(): + * Wrapper for tcgetattr to handle EINTR + */ +private int +tty_getty(EditLine *el, struct termios *t) +{ + int rv; + while ((rv = tcgetattr(el->el_infd, t)) == -1 && errno == EINTR) + continue; + return rv; +} + +/* tty_setty(): + * Wrapper for tcsetattr to handle EINTR + */ +private int +tty_setty(EditLine *el, int action, const struct termios *t) +{ + int rv; + while ((rv = tcsetattr(el->el_infd, action, t)) == -1 && errno == EINTR) + continue; + return rv; +} /* tty_setup(): * Get the tty parameters and initialize the editing state @@ -514,7 +543,7 @@ tty_setup(EditLine *el) el->el_tty.t_c[TS_IO][rst]; } tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); - if (tty_setty(el, &el->el_tty.t_ex) == -1) { + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) { #ifdef DEBUG_TTY (void) fprintf(el->el_errfile, "tty_setup: tty_setty: %s\n", @@ -522,8 +551,11 @@ tty_setup(EditLine *el) #endif /* DEBUG_TTY */ return (-1); } - } else + } +#ifdef notdef + else tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); +#endif el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask; @@ -1040,7 +1072,7 @@ tty_rawmode(EditLine *el) } } } - if (tty_setty(el, &el->el_tty.t_ed) == -1) { + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { #ifdef DEBUG_TTY (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n", strerror(errno)); @@ -1065,7 +1097,7 @@ tty_cookedmode(EditLine *el) if (el->el_flags & EDIT_DISABLED) return (0); - if (tty_setty(el, &el->el_tty.t_ex) == -1) { + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) { #ifdef DEBUG_TTY (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n", @@ -1101,7 +1133,7 @@ tty_quotemode(EditLine *el) el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask; el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask; - if (tty_setty(el, &el->el_tty.t_qu) == -1) { + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) { #ifdef DEBUG_TTY (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n", strerror(errno)); @@ -1122,7 +1154,7 @@ tty_noquotemode(EditLine *el) if (el->el_tty.t_mode != QU_IO) return (0); - if (tty_setty(el, &el->el_tty.t_ed) == -1) { + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { #ifdef DEBUG_TTY (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n", strerror(errno)); @@ -1193,10 +1225,14 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name); } - x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) - ? '+' : '\0'; - x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) - ? '-' : x; + if (i != -1) { + x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) + ? '+' : '\0'; + x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) + ? '-' : x; + } else { + x = '\0'; + } if (x != '\0' || aflag) { @@ -1221,7 +1257,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) return (0); } while (argv && (s = *argv++)) { - char *p; + const char *p; switch (*s) { case '+': case '-': @@ -1232,10 +1268,10 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) break; } d = s; - if ((p = strchr(s, '=')) != NULL) - *p++ = '\0'; + p = strchr(s, '='); for (m = ttymodes; m->m_name; m++) - if (strcmp(m->m_name, d) == 0 && + if ((p ? strncmp(m->m_name, d, (size_t)(p - d)) : + strcmp(m->m_name, d)) == 0 && (p == NULL || m->m_type == MD_CHAR)) break; @@ -1246,7 +1282,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) } if (p) { int c = ffs((int)m->m_value); - int v = *p ? parse__escape((const char **const) &p) : + int v = *++p ? parse__escape((const char **) &p) : el->el_tty.t_vdisable; assert(c-- != 0); c = tty__getcharindex(c); @@ -1269,6 +1305,17 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) break; } } + + if (el->el_tty.t_mode == z) { + if (tty_setty(el, TCSADRAIN, tios) == -1) { +#ifdef DEBUG_TTY + (void) fprintf(el->el_errfile, + "tty_stty: tty_setty: %s\n", strerror(errno)); +#endif /* DEBUG_TTY */ + return (-1); + } + } + return (0); } diff --git a/cmd-line-utils/libedit/tty.h b/cmd-line-utils/libedit/tty.h index cc7c4ad8c66..10e9b98c953 100644 --- a/cmd-line-utils/libedit/tty.h +++ b/cmd-line-utils/libedit/tty.h @@ -1,4 +1,4 @@ -/* $NetBSD: tty.h,v 1.10 2003/08/07 16:44:34 agc Exp $ */ +/* $NetBSD: tty.h,v 1.11 2005/06/01 11:37:52 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -450,8 +450,8 @@ typedef struct { const char *t_name; - u_int t_setmask; - u_int t_clrmask; + unsigned int t_setmask; + unsigned int t_clrmask; } ttyperm_t[NN_IO][MD_NN]; typedef unsigned char ttychar_t[NN_IO][C_NCC]; diff --git a/cmd-line-utils/libedit/unvis.c b/cmd-line-utils/libedit/unvis.c deleted file mode 100644 index ffa8ac4251c..00000000000 --- a/cmd-line-utils/libedit/unvis.c +++ /dev/null @@ -1,311 +0,0 @@ -/* $NetBSD: unvis.c,v 1.24 2003/08/07 16:42:59 agc Exp $ */ - -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#define __LIBC12_SOURCE__ - -#include - -#include -#include -#include -#include - -#ifdef __weak_alias -__weak_alias(strunvis,_strunvis) -__weak_alias(unvis,_unvis) -#endif - -#ifdef __warn_references -__warn_references(unvis, - "warning: reference to compatibility unvis(); include for correct reference") -#endif - -#if !HAVE_VIS -/* - * decode driven by state machine - */ -#define S_GROUND 0 /* haven't seen escape char */ -#define S_START 1 /* start decoding special sequence */ -#define S_META 2 /* metachar started (M) */ -#define S_META1 3 /* metachar more, regular char (-) */ -#define S_CTRL 4 /* control char started (^) */ -#define S_OCTAL2 5 /* octal digit 2 */ -#define S_OCTAL3 6 /* octal digit 3 */ -#define S_HEX1 7 /* hex digit */ -#define S_HEX2 8 /* hex digit 2 */ - -#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') -#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) - -int -unvis(cp, c, astate, flag) - char *cp; - int c; - int *astate, flag; -{ - return __unvis13(cp, (int)c, astate, flag); -} - -/* - * unvis - decode characters previously encoded by vis - */ -int -__unvis13(cp, c, astate, flag) - char *cp; - int c; - int *astate, flag; -{ - - _DIAGASSERT(cp != NULL); - _DIAGASSERT(astate != NULL); - - if (flag & UNVIS_END) { - if (*astate == S_OCTAL2 || *astate == S_OCTAL3 - || *astate == S_HEX2) { - *astate = S_GROUND; - return (UNVIS_VALID); - } - return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); - } - - switch (*astate) { - - case S_GROUND: - *cp = 0; - if (c == '\\') { - *astate = S_START; - return (0); - } - if ((flag & VIS_HTTPSTYLE) && c == '%') { - *astate = S_HEX1; - return (0); - } - *cp = c; - return (UNVIS_VALID); - - case S_START: - switch(c) { - case '\\': - *cp = c; - *astate = S_GROUND; - return (UNVIS_VALID); - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - *cp = (c - '0'); - *astate = S_OCTAL2; - return (0); - case 'M': - *cp = (char)0200; - *astate = S_META; - return (0); - case '^': - *astate = S_CTRL; - return (0); - case 'n': - *cp = '\n'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'r': - *cp = '\r'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'b': - *cp = '\b'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'a': - *cp = '\007'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'v': - *cp = '\v'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 't': - *cp = '\t'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'f': - *cp = '\f'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 's': - *cp = ' '; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'E': - *cp = '\033'; - *astate = S_GROUND; - return (UNVIS_VALID); - case '\n': - /* - * hidden newline - */ - *astate = S_GROUND; - return (UNVIS_NOCHAR); - case '$': - /* - * hidden marker - */ - *astate = S_GROUND; - return (UNVIS_NOCHAR); - } - *astate = S_GROUND; - return (UNVIS_SYNBAD); - - case S_META: - if (c == '-') - *astate = S_META1; - else if (c == '^') - *astate = S_CTRL; - else { - *astate = S_GROUND; - return (UNVIS_SYNBAD); - } - return (0); - - case S_META1: - *astate = S_GROUND; - *cp |= c; - return (UNVIS_VALID); - - case S_CTRL: - if (c == '?') - *cp |= 0177; - else - *cp |= c & 037; - *astate = S_GROUND; - return (UNVIS_VALID); - - case S_OCTAL2: /* second possible octal digit */ - if (isoctal(c)) { - /* - * yes - and maybe a third - */ - *cp = (*cp << 3) + (c - '0'); - *astate = S_OCTAL3; - return (0); - } - /* - * no - done with current sequence, push back passed char - */ - *astate = S_GROUND; - return (UNVIS_VALIDPUSH); - - case S_OCTAL3: /* third possible octal digit */ - *astate = S_GROUND; - if (isoctal(c)) { - *cp = (*cp << 3) + (c - '0'); - return (UNVIS_VALID); - } - /* - * we were done, push back passed char - */ - return (UNVIS_VALIDPUSH); - case S_HEX1: - if (isxdigit(c)) { - *cp = xtod(c); - *astate = S_HEX2; - return (0); - } - /* - * no - done with current sequence, push back passed char - */ - *astate = S_GROUND; - return (UNVIS_VALIDPUSH); - case S_HEX2: - *astate = S_GROUND; - if (isxdigit(c)) { - *cp = xtod(c) | (*cp << 4); - return (UNVIS_VALID); - } - return (UNVIS_VALIDPUSH); - default: - /* - * decoder in unknown state - (probably uninitialized) - */ - *astate = S_GROUND; - return (UNVIS_SYNBAD); - } -} - -/* - * strunvis - decode src into dst - * - * Number of chars decoded into dst is returned, -1 on error. - * Dst is null terminated. - */ - -int -strunvisx(dst, src, flag) - char *dst; - const char *src; - int flag; -{ - char c; - char *start = dst; - int state = 0; - - _DIAGASSERT(src != NULL); - _DIAGASSERT(dst != NULL); - - while ((c = *src++) != '\0') { - again: - switch (__unvis13(dst, c, &state, flag)) { - case UNVIS_VALID: - dst++; - break; - case UNVIS_VALIDPUSH: - dst++; - goto again; - case 0: - case UNVIS_NOCHAR: - break; - default: - return (-1); - } - } - if (__unvis13(dst, c, &state, UNVIS_END) == UNVIS_VALID) - dst++; - *dst = '\0'; - return (dst - start); -} - -int -strunvis(dst, src) - char *dst; - const char *src; -{ - return strunvisx(dst, src, 0); -} -#endif diff --git a/cmd-line-utils/libedit/vi.c b/cmd-line-utils/libedit/vi.c index b977ce716c6..602383f3231 100644 --- a/cmd-line-utils/libedit/vi.c +++ b/cmd-line-utils/libedit/vi.c @@ -1,4 +1,4 @@ -/* $NetBSD: vi.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $ */ +/* $NetBSD: vi.c,v 1.28 2009/02/06 13:14:37 sketch Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,11 +32,17 @@ * SUCH DAMAGE. */ -#include +#include "config.h" #include #include #include +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * vi.c: Vi mode commands. @@ -64,8 +70,10 @@ cv_action(EditLine *el, int c) el->el_line.lastchar - el->el_line.buffer); el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.pos = 0; - el->el_line.lastchar = el->el_line.buffer; - el->el_line.cursor = el->el_line.buffer; + if (!(c & YANK)) { + el->el_line.lastchar = el->el_line.buffer; + el->el_line.cursor = el->el_line.buffer; + } if (c & INSERT) el->el_map.current = el->el_map.key; @@ -82,7 +90,6 @@ cv_action(EditLine *el, int c) private el_action_t cv_paste(EditLine *el, int c) { - char *ptr; c_kill_t *k = &el->el_chared.c_kill; int len = k->last - k->buf; @@ -96,12 +103,12 @@ cv_paste(EditLine *el, int c) if (!c && el->el_line.cursor < el->el_line.lastchar) el->el_line.cursor++; - ptr = el->el_line.cursor; c_insert(el, len); if (el->el_line.cursor + len > el->el_line.lastchar) return (CC_ERROR); - (void) memcpy(ptr, k->buf, len +0u); + (void) memcpy(el->el_line.cursor, k->buf, len +0u); + return (CC_REFRESH); } @@ -592,13 +599,12 @@ vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_list_or_eof(EditLine *el, int c __attribute__((__unused__))) +vi_list_or_eof(EditLine *el, int c) { if (el->el_line.cursor == el->el_line.lastchar) { if (el->el_line.cursor == el->el_line.buffer) { - term_overwrite(el, STReof, 4); /* then do a EOF */ - term__flush(); + term_writec(el, c); /* then do a EOF */ return (CC_EOF); } else { /* @@ -888,7 +894,7 @@ vi_yank(EditLine *el, int c) /* vi_comment_out(): * Vi comment out current command - * [c] + * [#] */ protected el_action_t /*ARGSUSED*/ @@ -905,18 +911,19 @@ vi_comment_out(EditLine *el, int c) /* vi_alias(): * Vi include shell alias * [@] - * NB: posix impiles that we should enter insert mode, however + * NB: posix implies that we should enter insert mode, however * this is against historical precedent... */ +#ifdef __weak_reference +extern char *get_alias_text(const char *) __weak_reference(get_alias_text); +#endif protected el_action_t /*ARGSUSED*/ vi_alias(EditLine *el, int c) { -#ifdef __weak_extern +#ifdef __weak_reference char alias_name[3]; char *alias_text; - extern char *get_alias_text(const char *); - __weak_extern(get_alias_text); if (get_alias_text == 0) { return CC_ERROR; @@ -1014,7 +1021,7 @@ vi_histedit(EditLine *el, int c) return CC_ERROR; case 0: close(fd); - execlp("vi", "vi", tempfile, (char *) NULL); + execlp("vi", "vi", tempfile, (char *)NULL); exit(0); /*NOTREACHED*/ default: diff --git a/cmd-line-utils/libedit/vis.c b/cmd-line-utils/libedit/vis.c deleted file mode 100644 index 127d28733a8..00000000000 --- a/cmd-line-utils/libedit/vis.c +++ /dev/null @@ -1,392 +0,0 @@ -/* $NetBSD: vis.c,v 1.27 2004/02/26 23:01:15 enami Exp $ */ - -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/*- - * Copyright (c) 1999 The NetBSD Foundation, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* AIX requires this to be the first thing in the file. */ -#if defined (_AIX) && !defined (__GNUC__) - #pragma alloca -#endif - -#include - -#ifdef __GNUC__ -# undef alloca -# define alloca(n) __builtin_alloca (n) -#else -# ifdef HAVE_ALLOCA_H -# include -# else -# ifndef _AIX -extern char *alloca (); -# endif -# endif -#endif - -#include - -#include -#include -#include - -#ifdef __weak_alias -__weak_alias(strsvis,_strsvis) -__weak_alias(strsvisx,_strsvisx) -__weak_alias(strvis,_strvis) -__weak_alias(strvisx,_strvisx) -__weak_alias(svis,_svis) -__weak_alias(vis,_vis) -#endif - -#if !HAVE_VIS || !HAVE_SVIS -#include -#include -#include -#include - -#undef BELL -#define BELL '\a' - -#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') -#define iswhite(c) (c == ' ' || c == '\t' || c == '\n') -#define issafe(c) (c == '\b' || c == BELL || c == '\r') -#define xtoa(c) "0123456789abcdef"[c] - -#define MAXEXTRAS 5 - - -#define MAKEEXTRALIST(flag, extra, orig) \ -do { \ - const char *o = orig; \ - char *e; \ - while (*o++) \ - continue; \ - extra = alloca((size_t)((o - orig) + MAXEXTRAS)); \ - for (o = orig, e = extra; (*e++ = *o++) != '\0';) \ - continue; \ - e--; \ - if (flag & VIS_SP) *e++ = ' '; \ - if (flag & VIS_TAB) *e++ = '\t'; \ - if (flag & VIS_NL) *e++ = '\n'; \ - if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \ - *e = '\0'; \ -} while (/*CONSTCOND*/0) - - -/* - * This is HVIS, the macro of vis used to HTTP style (RFC 1808) - */ -#define HVIS(dst, c, flag, nextc, extra) \ -do \ - if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \ - *dst++ = '%'; \ - *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); \ - *dst++ = xtoa((unsigned int)c & 0xf); \ - } else { \ - SVIS(dst, c, flag, nextc, extra); \ - } \ -while (/*CONSTCOND*/0) - -/* - * This is SVIS, the central macro of vis. - * dst: Pointer to the destination buffer - * c: Character to encode - * flag: Flag word - * nextc: The character following 'c' - * extra: Pointer to the list of extra characters to be - * backslash-protected. - */ -#define SVIS(dst, c, flag, nextc, extra) \ -do { \ - int isextra; \ - isextra = strchr(extra, c) != NULL; \ - if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \ - ((flag & VIS_SAFE) && issafe(c)))) { \ - *dst++ = c; \ - break; \ - } \ - if (flag & VIS_CSTYLE) { \ - switch (c) { \ - case '\n': \ - *dst++ = '\\'; *dst++ = 'n'; \ - continue; \ - case '\r': \ - *dst++ = '\\'; *dst++ = 'r'; \ - continue; \ - case '\b': \ - *dst++ = '\\'; *dst++ = 'b'; \ - continue; \ - case BELL: \ - *dst++ = '\\'; *dst++ = 'a'; \ - continue; \ - case '\v': \ - *dst++ = '\\'; *dst++ = 'v'; \ - continue; \ - case '\t': \ - *dst++ = '\\'; *dst++ = 't'; \ - continue; \ - case '\f': \ - *dst++ = '\\'; *dst++ = 'f'; \ - continue; \ - case ' ': \ - *dst++ = '\\'; *dst++ = 's'; \ - continue; \ - case '\0': \ - *dst++ = '\\'; *dst++ = '0'; \ - if (isoctal(nextc)) { \ - *dst++ = '0'; \ - *dst++ = '0'; \ - } \ - continue; \ - default: \ - if (isgraph(c)) { \ - *dst++ = '\\'; *dst++ = c; \ - continue; \ - } \ - } \ - } \ - if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \ - *dst++ = '\\'; \ - *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; \ - *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; \ - *dst++ = (c & 07) + '0'; \ - } else { \ - if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \ - if (c & 0200) { \ - c &= 0177; *dst++ = 'M'; \ - } \ - if (iscntrl(c)) { \ - *dst++ = '^'; \ - if (c == 0177) \ - *dst++ = '?'; \ - else \ - *dst++ = c + '@'; \ - } else { \ - *dst++ = '-'; *dst++ = c; \ - } \ - } \ -} while (/*CONSTCOND*/0) - - -/* - * svis - visually encode characters, also encoding the characters - * pointed to by `extra' - */ -char * -svis(dst, c, flag, nextc, extra) - char *dst; - int c, flag, nextc; - const char *extra; -{ - char *nextra; - _DIAGASSERT(dst != NULL); - _DIAGASSERT(extra != NULL); - MAKEEXTRALIST(flag, nextra, extra); - if (flag & VIS_HTTPSTYLE) - HVIS(dst, c, flag, nextc, nextra); - else - SVIS(dst, c, flag, nextc, nextra); - *dst = '\0'; - return(dst); -} - - -/* - * strsvis, strsvisx - visually encode characters from src into dst - * - * Extra is a pointer to a \0-terminated list of characters to - * be encoded, too. These functions are useful e. g. to - * encode strings in such a way so that they are not interpreted - * by a shell. - * - * Dst must be 4 times the size of src to account for possible - * expansion. The length of dst, not including the trailing NULL, - * is returned. - * - * Strsvisx encodes exactly len bytes from src into dst. - * This is useful for encoding a block of data. - */ -int -strsvis(dst, csrc, flag, extra) - char *dst; - const char *csrc; - int flag; - const char *extra; -{ - int c; - char *start; - char *nextra; - const unsigned char *src = (const unsigned char *)csrc; - - _DIAGASSERT(dst != NULL); - _DIAGASSERT(src != NULL); - _DIAGASSERT(extra != NULL); - MAKEEXTRALIST(flag, nextra, extra); - if (flag & VIS_HTTPSTYLE) { - for (start = dst; (c = *src++) != '\0'; /* empty */) - HVIS(dst, c, flag, *src, nextra); - } else { - for (start = dst; (c = *src++) != '\0'; /* empty */) - SVIS(dst, c, flag, *src, nextra); - } - *dst = '\0'; - return (dst - start); -} - - -int -strsvisx(dst, csrc, len, flag, extra) - char *dst; - const char *csrc; - size_t len; - int flag; - const char *extra; -{ - int c; - char *start; - char *nextra; - const unsigned char *src = (const unsigned char *)csrc; - - _DIAGASSERT(dst != NULL); - _DIAGASSERT(src != NULL); - _DIAGASSERT(extra != NULL); - MAKEEXTRALIST(flag, nextra, extra); - - if (flag & VIS_HTTPSTYLE) { - for (start = dst; len > 0; len--) { - c = *src++; - HVIS(dst, c, flag, len ? *src : '\0', nextra); - } - } else { - for (start = dst; len > 0; len--) { - c = *src++; - SVIS(dst, c, flag, len ? *src : '\0', nextra); - } - } - *dst = '\0'; - return (dst - start); -} -#endif - -#if !HAVE_VIS -/* - * vis - visually encode characters - */ -char * -vis(dst, c, flag, nextc) - char *dst; - int c, flag, nextc; - -{ - char *extra; - - _DIAGASSERT(dst != NULL); - - MAKEEXTRALIST(flag, extra, ""); - if (flag & VIS_HTTPSTYLE) - HVIS(dst, c, flag, nextc, extra); - else - SVIS(dst, c, flag, nextc, extra); - *dst = '\0'; - return (dst); -} - - -/* - * strvis, strvisx - visually encode characters from src into dst - * - * Dst must be 4 times the size of src to account for possible - * expansion. The length of dst, not including the trailing NULL, - * is returned. - * - * Strvisx encodes exactly len bytes from src into dst. - * This is useful for encoding a block of data. - */ -int -strvis(dst, src, flag) - char *dst; - const char *src; - int flag; -{ - char *extra; - - MAKEEXTRALIST(flag, extra, ""); - return (strsvis(dst, src, flag, extra)); -} - - -int -strvisx(dst, src, len, flag) - char *dst; - const char *src; - size_t len; - int flag; -{ - char *extra; - - MAKEEXTRALIST(flag, extra, ""); - return (strsvisx(dst, src, len, flag, extra)); -} -#endif diff --git a/cmd-line-utils/libedit/vis.h b/cmd-line-utils/libedit/vis.h deleted file mode 100644 index 44f6fc7d785..00000000000 --- a/cmd-line-utils/libedit/vis.h +++ /dev/null @@ -1,92 +0,0 @@ -/* $NetBSD: vis.h,v 1.15 2005/02/03 04:39:32 perry Exp $ */ - -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)vis.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef _VIS_H_ -#define _VIS_H_ - -#include - -/* - * to select alternate encoding format - */ -#define VIS_OCTAL 0x01 /* use octal \ddd format */ -#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropiate */ - -/* - * to alter set of characters encoded (default is to encode all - * non-graphic except space, tab, and newline). - */ -#define VIS_SP 0x04 /* also encode space */ -#define VIS_TAB 0x08 /* also encode tab */ -#define VIS_NL 0x10 /* also encode newline */ -#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) -#define VIS_SAFE 0x20 /* only encode "unsafe" characters */ - -/* - * other - */ -#define VIS_NOSLASH 0x40 /* inhibit printing '\' */ -#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */ - -/* - * unvis return codes - */ -#define UNVIS_VALID 1 /* character valid */ -#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */ -#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */ -#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */ -#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */ - -/* - * unvis flags - */ -#define UNVIS_END 1 /* no more characters */ - -__BEGIN_DECLS -char *vis(char *, int, int, int); -char *svis(char *, int, int, int, const char *); -int strvis(char *, const char *, int); -int strsvis(char *, const char *, int, const char *); -int strvisx(char *, const char *, size_t, int); -int strsvisx(char *, const char *, size_t, int, const char *); -int strunvis(char *, const char *); -int strunvisx(char *, const char *, int); -#ifdef __LIBC12_SOURCE__ -int unvis(char *, int, int *, int); -int __unvis13(char *, int, int *, int); -#else -int unvis(char *, int, int *, int); -#endif -__END_DECLS - -#endif /* !_VIS_H_ */ -- cgit v1.2.1 From de7665acf854996213743cd98658a95fff280a53 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 10 Feb 2009 20:19:03 +0200 Subject: fixed a libedit compilation problem --- cmd-line-utils/libedit/Makefile.am | 2 +- cmd-line-utils/libedit/term.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd-line-utils/libedit/Makefile.am b/cmd-line-utils/libedit/Makefile.am index 5a01a746963..ddafa4aab44 100644 --- a/cmd-line-utils/libedit/Makefile.am +++ b/cmd-line-utils/libedit/Makefile.am @@ -21,7 +21,7 @@ pkginclude_HEADERS = readline/readline.h noinst_HEADERS = chared.h el.h el_term.h histedit.h key.h parse.h refresh.h sig.h \ sys.h config.h hist.h map.h prompt.h read.h \ - search.h tty.h filecomplete.h + search.h tty.h filecomplete.h np/vis.h EXTRA_DIST = makelist.sh diff --git a/cmd-line-utils/libedit/term.c b/cmd-line-utils/libedit/term.c index 7a9d0250114..488c760da14 100644 --- a/cmd-line-utils/libedit/term.c +++ b/cmd-line-utils/libedit/term.c @@ -50,9 +50,11 @@ static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; #include #include #include +#if 0 /* TODO: do we need this */ #ifdef HAVE_TERMCAP_H #include #endif +#endif #ifdef HAVE_CURSES_H #include #endif -- cgit v1.2.1 From 83c7e92fe3d9933a9dc061899da2093da43ce182 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 11 Feb 2009 12:04:40 +0200 Subject: changed the tree id pending a merge of 5.0-bugteam -> 5.0-main --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..f79c1cd6319 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.0-bugteam" +tree_name = "mysql-5.0" -- cgit v1.2.1 From e2fe3db93fbe77f4a7fe51e339a44d7bd8b8cf77 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 12 Feb 2009 13:49:44 +0400 Subject: BUG#36737 - having + full text operator crashes mysql MATCH() function accepts column list as an argument. It was possible to override this requirement with aliased non-column select expression. Which results in server crash. With this fix aliased non-column select expressions are not accepted by MATCH() function, returning an error. mysql-test/r/fulltext.result: A test case for BUG#36737. mysql-test/t/fulltext.test: A test case for BUG#36737. sql/item_func.cc: Only accept fields as arguments to MATCH(). --- mysql-test/r/fulltext.result | 4 ++++ mysql-test/t/fulltext.test | 8 ++++++++ sql/item_func.cc | 5 ++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 6821691c9d0..6ea17644f9d 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -506,3 +506,7 @@ SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) FROM t1; MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) 2 DROP TABLE t1; +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; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 77d84c730d9..76661ba4e63 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -432,3 +432,11 @@ INSERT INTO t1 VALUES('aaa15'); SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa16' IN BOOLEAN MODE) FROM t1; SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) FROM t1; DROP TABLE t1; + +# +# BUG#36737 - having + full text operator crashes mysql +# +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; diff --git a/sql/item_func.cc b/sql/item_func.cc index 913b32ccb88..55324923fe2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4961,7 +4961,10 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref) if (item->type() == Item::REF_ITEM) args[i]= item= *((Item_ref *)item)->ref; if (item->type() != Item::FIELD_ITEM) - key=NO_SUCH_KEY; + { + my_error(ER_WRONG_ARGUMENTS, MYF(0), "AGAINST"); + return TRUE; + } } /* Check that all columns come from the same table. -- cgit v1.2.1 From 371102e4c7a37eff4241aea7bd356c0a6e4c9836 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 12 Feb 2009 16:36:43 +0200 Subject: Bug #33813: Schema names are case-sensitive in DROP FUNCTION Additional fix: 1. Revert the unification of DROP FUNCTION and DROP PROCEDURE, because DROP FUNCTION can be used to drop UDFs (that have a non-qualified name and don't require database name to be present and valid). 2. Fixed the case sensitivity problem by adding a call to check_db_name() (similar to the sp_name production). --- sql/sql_yacc.yy | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index fbaf761cc33..51fb5dbdfe4 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7507,9 +7507,16 @@ drop: lex->drop_if_exists=$3; lex->name=$4.str; } - | DROP FUNCTION_SYM if_exists sp_name + | DROP FUNCTION_SYM if_exists ident '.' ident { - LEX *lex= Lex; + THD *thd= YYTHD; + LEX *lex= thd->lex; + sp_name *spname; + if ($4.str && check_db_name($4.str)) + { + my_error(ER_WRONG_DB_NAME, MYF(0), $4.str); + MYSQL_YYABORT; + } if (lex->sphead) { my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION"); @@ -7517,7 +7524,32 @@ drop: } lex->sql_command = SQLCOM_DROP_FUNCTION; lex->drop_if_exists= $3; - lex->spname= $4; + spname= new sp_name($4, $6, true); + if (spname == NULL) + MYSQL_YYABORT; + spname->init_qname(thd); + lex->spname= spname; + } + | DROP FUNCTION_SYM if_exists ident + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + LEX_STRING db= {0, 0}; + sp_name *spname; + if (lex->sphead) + { + my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION"); + MYSQL_YYABORT; + } + if (thd->db && lex->copy_db_to(&db.str, &db.length)) + MYSQL_YYABORT; + lex->sql_command = SQLCOM_DROP_FUNCTION; + lex->drop_if_exists= $3; + spname= new sp_name(db, $4, false); + if (spname == NULL) + MYSQL_YYABORT; + spname->init_qname(thd); + lex->spname= spname; } | DROP PROCEDURE if_exists sp_name { -- cgit v1.2.1 From aa8645bb7c36d93dce987944d1e97774702a9cad Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 13 Feb 2009 17:26:20 -0200 Subject: Remove test case for bug 40264. Dirty close tricky does not work on Windows. mysql-test/r/query_cache_notembedded.result: Remove test case result. mysql-test/t/query_cache_notembedded.test: Remove test case. --- mysql-test/r/query_cache_notembedded.result | 16 ---------------- mysql-test/t/query_cache_notembedded.test | 29 ----------------------------- 2 files changed, 45 deletions(-) diff --git a/mysql-test/r/query_cache_notembedded.result b/mysql-test/r/query_cache_notembedded.result index bf582bfaec6..8e5df012cfb 100644 --- a/mysql-test/r/query_cache_notembedded.result +++ b/mysql-test/r/query_cache_notembedded.result @@ -345,19 +345,3 @@ id drop table t1; drop function f1; set GLOBAL query_cache_size=0; -DROP TABLE IF EXISTS t1; -FLUSH STATUS; -SET GLOBAL query_cache_size=1048576; -CREATE TABLE t1 (a INT); -INSERT INTO t1 VALUES (1),(2),(3),(4),(5); -SHOW STATUS LIKE 'Qcache_queries_in_cache'; -Variable_name Value -Qcache_queries_in_cache 0 -LOCK TABLES t1 WRITE; -SELECT * FROM t1; -UNLOCK TABLES; -SHOW STATUS LIKE 'Qcache_queries_in_cache'; -Variable_name Value -Qcache_queries_in_cache 0 -DROP TABLE t1; -SET GLOBAL query_cache_size= default; diff --git a/mysql-test/t/query_cache_notembedded.test b/mysql-test/t/query_cache_notembedded.test index d98ed691c7b..112856117ce 100644 --- a/mysql-test/t/query_cache_notembedded.test +++ b/mysql-test/t/query_cache_notembedded.test @@ -230,35 +230,6 @@ connection default; set GLOBAL query_cache_size=0; -# -# Bug#40264: Aborted cached query causes query to hang indefinitely on next cache hit -# - ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - -FLUSH STATUS; -SET GLOBAL query_cache_size=1048576; -CREATE TABLE t1 (a INT); -INSERT INTO t1 VALUES (1),(2),(3),(4),(5); -SHOW STATUS LIKE 'Qcache_queries_in_cache'; -LOCK TABLES t1 WRITE; -connect(con1,localhost,root,,); ---send SELECT * FROM t1 -connection default; -let $show_type= open tables where `table`='t1' and in_use=2; -let $show_pattern= '%t1%2%'; ---source include/wait_show_pattern.inc -dirty_close con1; -UNLOCK TABLES; -let $show_type= open tables where `table`='t1' and in_use=0; -let $show_pattern= '%t1%0%'; ---source include/wait_show_pattern.inc -SHOW STATUS LIKE 'Qcache_queries_in_cache'; -DROP TABLE t1; -SET GLOBAL query_cache_size= default; - # End of 5.0 tests # Wait till we reached the initial number of concurrent sessions -- cgit v1.2.1 From e6dcc01a8eae71321f52001374bcf7e7e121a9fe Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Sat, 14 Feb 2009 18:36:57 +0300 Subject: Fixed bdb_gis and ndb_gis test failures in PB introduced by the patch for bug #21205. mysql-test/r/bdb_gis.result: Take additional precision into account. mysql-test/r/ndb_gis.result: Take additional precision into account. mysql-test/t/type_float.test: Added missing DROP TABLE. --- mysql-test/r/bdb_gis.result | 6 +++--- mysql-test/r/ndb_gis.result | 12 ++++++------ mysql-test/t/type_float.test | 1 + 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/bdb_gis.result b/mysql-test/r/bdb_gis.result index 6651421b51c..3187d7bef99 100644 --- a/mysql-test/r/bdb_gis.result +++ b/mysql-test/r/bdb_gis.result @@ -291,7 +291,7 @@ Note 1003 select astext(startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint SELECT fid, AsText(Centroid(g)) FROM gis_polygon ORDER by fid; fid AsText(Centroid(g)) 108 POINT(15 15) -109 POINT(25.416666666667 25.416666666667) +109 POINT(25.4166666666667 25.4166666666667) 110 POINT(20 10) SELECT fid, Area(g) FROM gis_polygon ORDER by fid; fid Area(g) @@ -325,8 +325,8 @@ fid IsClosed(g) 116 0 SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid; fid AsText(Centroid(g)) -117 POINT(55.588527753042 17.426536064114) -118 POINT(55.588527753042 17.426536064114) +117 POINT(55.5885277530424 17.426536064114) +118 POINT(55.5885277530424 17.426536064114) 119 POINT(2 2) SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid; fid Area(g) diff --git a/mysql-test/r/ndb_gis.result b/mysql-test/r/ndb_gis.result index ec064ace651..0625128195b 100644 --- a/mysql-test/r/ndb_gis.result +++ b/mysql-test/r/ndb_gis.result @@ -291,7 +291,7 @@ Note 1003 select astext(startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint SELECT fid, AsText(Centroid(g)) FROM gis_polygon ORDER by fid; fid AsText(Centroid(g)) 108 POINT(15 15) -109 POINT(25.416666666667 25.416666666667) +109 POINT(25.4166666666667 25.4166666666667) 110 POINT(20 10) SELECT fid, Area(g) FROM gis_polygon ORDER by fid; fid Area(g) @@ -325,8 +325,8 @@ fid IsClosed(g) 116 0 SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid; fid AsText(Centroid(g)) -117 POINT(55.588527753042 17.426536064114) -118 POINT(55.588527753042 17.426536064114) +117 POINT(55.5885277530424 17.426536064114) +118 POINT(55.5885277530424 17.426536064114) 119 POINT(2 2) SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid; fid Area(g) @@ -835,7 +835,7 @@ Note 1003 select astext(startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint SELECT fid, AsText(Centroid(g)) FROM gis_polygon ORDER by fid; fid AsText(Centroid(g)) 108 POINT(15 15) -109 POINT(25.416666666667 25.416666666667) +109 POINT(25.4166666666667 25.4166666666667) 110 POINT(20 10) SELECT fid, Area(g) FROM gis_polygon ORDER by fid; fid Area(g) @@ -869,8 +869,8 @@ fid IsClosed(g) 116 0 SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid; fid AsText(Centroid(g)) -117 POINT(55.588527753042 17.426536064114) -118 POINT(55.588527753042 17.426536064114) +117 POINT(55.5885277530424 17.426536064114) +118 POINT(55.5885277530424 17.426536064114) 119 POINT(2 2) SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid; fid Area(g) diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 42703e11863..3b7b30db6f8 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -274,5 +274,6 @@ drop table t1; CREATE TABLE t1 (f1 DOUBLE); INSERT INTO t1 VALUES(-1.79769313486231e+308); SELECT f1 FROM t1; +DROP TABLE t1; --echo End of 5.0 tests -- cgit v1.2.1 From 726f5a6bdd6390db15219c28816771fa35205132 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Sat, 14 Feb 2009 18:58:07 +0300 Subject: Fixed several test failures in the funcs_1 suite introduced by the patch for bug #21205. mysql-test/suite/funcs_1/r/memory_func_view.result: Take additional precision into account. mysql-test/suite/funcs_1/r/memory_views.result: Take additional precision into account. mysql-test/suite/funcs_1/r/myisam_func_view.result: Take additional precision into account. mysql-test/suite/funcs_1/r/myisam_views.result: Take additional precision into account. --- mysql-test/suite/funcs_1/r/memory_func_view.result | 4 ++-- mysql-test/suite/funcs_1/r/memory_views.result | 6 +++--- mysql-test/suite/funcs_1/r/myisam_func_view.result | 4 ++-- mysql-test/suite/funcs_1/r/myisam_views.result | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mysql-test/suite/funcs_1/r/memory_func_view.result b/mysql-test/suite/funcs_1/r/memory_func_view.result index c2689a36801..0bd83c81bcf 100644 --- a/mysql-test/suite/funcs_1/r/memory_func_view.result +++ b/mysql-test/suite/funcs_1/r/memory_func_view.result @@ -5245,7 +5245,7 @@ WHERE select_id = 1 OR select_id IS NULL order by id; sqrt(my_bigint) my_bigint id NULL NULL 1 NULL -9223372036854775808 2 -3037000499.976 9223372036854775807 3 +3037000499.97605 9223372036854775807 3 0 0 4 NULL -1 5 2 4 6 @@ -5259,7 +5259,7 @@ WHERE select_id = 1 OR select_id IS NULL) order by id; sqrt(my_bigint) my_bigint id NULL NULL 1 NULL -9223372036854775808 2 -3037000499.976 9223372036854775807 3 +3037000499.97605 9223372036854775807 3 0 0 4 NULL -1 5 2 4 6 diff --git a/mysql-test/suite/funcs_1/r/memory_views.result b/mysql-test/suite/funcs_1/r/memory_views.result index 7bd674b8d76..d24d72473fd 100644 --- a/mysql-test/suite/funcs_1/r/memory_views.result +++ b/mysql-test/suite/funcs_1/r/memory_views.result @@ -22825,7 +22825,7 @@ f1 f2 ABC 3 SELECT * FROM v1 order by 2; f1 my_sqrt -ABC 1.7320508075689 +ABC 1.73205080756888 ALTER TABLE t1 CHANGE COLUMN f2 f2 VARCHAR(30); INSERT INTO t1 SET f1 = 'ABC', f2 = 'DEF'; DESCRIBE t1; @@ -22843,7 +22843,7 @@ ABC DEF SELECT * FROM v1 order by 2; f1 my_sqrt ABC 0 -ABC 1.7320508075689 +ABC 1.73205080756888 SELECT SQRT('DEF'); SQRT('DEF') 0 @@ -22863,7 +22863,7 @@ my_sqrt double YES NULL SELECT * FROM v2 order by 2; f1 my_sqrt ABC 0 -ABC 1.7320508075689 +ABC 1.73205080756888 CREATE TABLE t2 AS SELECT f1, SQRT(f2) my_sqrt FROM t1; SELECT * FROM t2 order by 2; f1 ABC diff --git a/mysql-test/suite/funcs_1/r/myisam_func_view.result b/mysql-test/suite/funcs_1/r/myisam_func_view.result index c2689a36801..0bd83c81bcf 100644 --- a/mysql-test/suite/funcs_1/r/myisam_func_view.result +++ b/mysql-test/suite/funcs_1/r/myisam_func_view.result @@ -5245,7 +5245,7 @@ WHERE select_id = 1 OR select_id IS NULL order by id; sqrt(my_bigint) my_bigint id NULL NULL 1 NULL -9223372036854775808 2 -3037000499.976 9223372036854775807 3 +3037000499.97605 9223372036854775807 3 0 0 4 NULL -1 5 2 4 6 @@ -5259,7 +5259,7 @@ WHERE select_id = 1 OR select_id IS NULL) order by id; sqrt(my_bigint) my_bigint id NULL NULL 1 NULL -9223372036854775808 2 -3037000499.976 9223372036854775807 3 +3037000499.97605 9223372036854775807 3 0 0 4 NULL -1 5 2 4 6 diff --git a/mysql-test/suite/funcs_1/r/myisam_views.result b/mysql-test/suite/funcs_1/r/myisam_views.result index bde591c13bf..e4d6dd4cf8e 100644 --- a/mysql-test/suite/funcs_1/r/myisam_views.result +++ b/mysql-test/suite/funcs_1/r/myisam_views.result @@ -24527,7 +24527,7 @@ f1 f2 ABC 3 SELECT * FROM v1 order by 2; f1 my_sqrt -ABC 1.7320508075689 +ABC 1.73205080756888 ALTER TABLE t1 CHANGE COLUMN f2 f2 VARCHAR(30); INSERT INTO t1 SET f1 = 'ABC', f2 = 'DEF'; DESCRIBE t1; @@ -24545,7 +24545,7 @@ ABC DEF SELECT * FROM v1 order by 2; f1 my_sqrt ABC 0 -ABC 1.7320508075689 +ABC 1.73205080756888 SELECT SQRT('DEF'); SQRT('DEF') 0 @@ -24565,7 +24565,7 @@ my_sqrt double YES NULL SELECT * FROM v2 order by 2; f1 my_sqrt ABC 0 -ABC 1.7320508075689 +ABC 1.73205080756888 CREATE TABLE t2 AS SELECT f1, SQRT(f2) my_sqrt FROM t1; SELECT * FROM t2 order by 2; f1 ABC -- cgit v1.2.1 From 54d405613c2e132f9c3514f84cfe298699d96e36 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Sat, 14 Feb 2009 20:12:14 +0300 Subject: Added missing DROP TABLE to type_float.result. mysql-test/r/type_float.result: Added missing DROP TABLE. --- mysql-test/r/type_float.result | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 757cd6f5d71..d3a136d53d2 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -406,4 +406,5 @@ INSERT INTO t1 VALUES(-1.79769313486231e+308); SELECT f1 FROM t1; f1 -1.79769313486231e+308 +DROP TABLE t1; End of 5.0 tests -- cgit v1.2.1 From 58fd8b2d9918232ecd1144950a27c7a83dddadce Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Sun, 15 Feb 2009 12:26:08 +0300 Subject: Fixed PB failures on IA64 hosts introduced by the patch for bug #21205. mysql-test/t/gis.test: IA64 gcc backend lacks -fno-fused-madd option, so we have to adjust results. --- mysql-test/t/gis.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index cf2e4a21419..cc2ac5b7392 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -355,6 +355,9 @@ insert into t1 values ('85984',GeomFromText('MULTIPOLYGON(((-115.006363 select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from t1 where object_id=85998; +# Expected result is 36.3310176346905, but IA64 returns 36.3310176346904 +# due to fused multiply-add instructions. +--replace_result 36.3310176346904 36.3310176346905 select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from t1 where object_id=85984; -- cgit v1.2.1 From 4d6d19f07feca07a7419f9bc8fd3409f3539c2d1 Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Mon, 16 Feb 2009 15:38:18 +0100 Subject: Bug#42027: Incorrect parsing of debug and verbose options for mysqldumpslow Options got normalised to long rather than short options since we gave primary name and alias in wrong order. Consequently querying for the option using the short options (the correct primary name) didn't work, rendering the options in question inaccessible. We restore the right order of the universe, or at least the alii for --debug and --verbose. scripts/mysqldumpslow.sh: Normalise --verbose/-v and --debug/-d to short options, not long options. --- scripts/mysqldumpslow.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mysqldumpslow.sh b/scripts/mysqldumpslow.sh index f05761bb837..009745fd896 100644 --- a/scripts/mysqldumpslow.sh +++ b/scripts/mysqldumpslow.sh @@ -17,9 +17,9 @@ my %opt = ( ); GetOptions(\%opt, - 'verbose|v+',# verbose + 'v|verbose+',# verbose 'help+', # write usage info - 'debug|d+', # debug + 'd|debug+', # debug 's=s', # what to sort by (t, at, l, al, r, ar etc) 'r!', # reverse the sort order (largest last instead of first) 't=i', # just show the top n queries -- cgit v1.2.1 From ec6f787d2a9aff0eedc2ee75045857fa1857430d Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 17 Feb 2009 18:22:48 +0400 Subject: Bug#25830 SHOW TABLE STATUS behaves differently depending on table name(for 5.0 only) replace wild_case_compare with my_wildcmp which is multibyte safe function mysql-test/r/lowercase_utf8.result: test result mysql-test/t/lowercase_utf8-master.opt: test case mysql-test/t/lowercase_utf8.test: test case sql/sql_show.cc: replace wild_case_compare with my_wildcmp which is multibyte safe function --- mysql-test/r/lowercase_utf8.result | 9 +++++++++ mysql-test/t/lowercase_utf8-master.opt | 4 ++++ mysql-test/t/lowercase_utf8.test | 9 +++++++++ sql/sql_show.cc | 18 ++++++++++++++---- 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 mysql-test/r/lowercase_utf8.result create mode 100644 mysql-test/t/lowercase_utf8-master.opt create mode 100644 mysql-test/t/lowercase_utf8.test diff --git a/mysql-test/r/lowercase_utf8.result b/mysql-test/r/lowercase_utf8.result new file mode 100644 index 00000000000..945e0912e80 --- /dev/null +++ b/mysql-test/r/lowercase_utf8.result @@ -0,0 +1,9 @@ +set names utf8; +create table `Ð` (id int); +show tables from test like 'Ð'; +Tables_in_test (Ð) +а +show tables from test like 'а'; +Tables_in_test (а) +а +drop table `Ð`; diff --git a/mysql-test/t/lowercase_utf8-master.opt b/mysql-test/t/lowercase_utf8-master.opt new file mode 100644 index 00000000000..1b70aa33023 --- /dev/null +++ b/mysql-test/t/lowercase_utf8-master.opt @@ -0,0 +1,4 @@ +--lower-case-table-names=1 --character-set-server=utf8 + + + diff --git a/mysql-test/t/lowercase_utf8.test b/mysql-test/t/lowercase_utf8.test new file mode 100644 index 00000000000..a0d847d5b9f --- /dev/null +++ b/mysql-test/t/lowercase_utf8.test @@ -0,0 +1,9 @@ +# +# Bug#25830 SHOW TABLE STATUS behaves differently depending on table name +# +set names utf8; +create table `Ð` (id int); +show tables from test like 'Ð'; +show tables from test like 'а'; +drop table `Ð`; + diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d6bb3427fe4..19155eec06b 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -287,11 +287,18 @@ find_files(THD *thd, List *files, const char *db, #ifndef NO_EMBEDDED_ACCESS_CHECKS uint col_access=thd->col_access; #endif + uint wild_length= 0; TABLE_LIST table_list; DBUG_ENTER("find_files"); - if (wild && !wild[0]) - wild=0; + if (wild) + { + if (!wild[0]) + wild= 0; + else + wild_length= strlen(wild); + } + bzero((char*) &table_list,sizeof(table_list)); @@ -340,8 +347,11 @@ find_files(THD *thd, List *files, const char *db, { if (lower_case_table_names) { - if (wild_case_compare(files_charset_info, file->name, wild)) - continue; + if (my_wildcmp(files_charset_info, + file->name, file->name + strlen(file->name), + wild, wild + wild_length, + wild_prefix, wild_one,wild_many)) + continue; } else if (wild_compare(file->name,wild,0)) continue; -- cgit v1.2.1 From f715c458e0364442bf436df913b3310e16b4e8f4 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 18 Feb 2009 12:18:38 +0200 Subject: Bug #26724: mysql command line client, ignores input to internal cmd after space Removed the misleading "NOTE:" from the \h command. client/mysql.cc: Bug #26724: removed the misleading note from the \h command --- client/mysql.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysql.cc b/client/mysql.cc index 88ddd40fa68..2ecfd637453 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -243,7 +243,7 @@ static COMMANDS commands[] = { { "connect",'r', com_connect,1, "Reconnect to the server. Optional arguments are db and host." }, { "delimiter", 'd', com_delimiter, 1, - "Set statement delimiter. NOTE: Takes the rest of the line as new delimiter." }, + "Set statement delimiter." }, #ifdef USE_POPEN { "edit", 'e', com_edit, 0, "Edit command with $EDITOR."}, #endif -- cgit v1.2.1 From 1d54b7e05c215cabcad0fd089d89414c0d55d3d8 Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Thu, 19 Feb 2009 04:58:10 +0100 Subject: Bug#37400: mysql: Bad help message for charset command Typo existed in help-text for command "charset" in mysql client, making the parameter-name different for long and short forms of the command for no good reason. Fixed. client/mysql.cc: Make parameter-name in help-text the same for long and short forms, for consistency. --- client/mysql.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysql.cc b/client/mysql.cc index 2ecfd637453..d1d36d79565 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2832,7 +2832,7 @@ com_charset(String *buffer __attribute__((unused)), char *line) param= get_arg(buff, 0); if (!param || !*param) { - return put_info("Usage: \\C char_setname | charset charset_name", + return put_info("Usage: \\C charset_name | charset charset_name", INFO_ERROR, 0); } new_cs= get_charset_by_csname(param, MY_CS_PRIMARY, MYF(MY_WME)); -- cgit v1.2.1 From 074b4bad3e501dcff8b0eff746d16c048d794a26 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Thu, 19 Feb 2009 11:49:35 +0300 Subject: Fix for bug #41078: With CURSOR_TYPE_READ_ONLY mysql_stmt_fetch() returns short string value. Multibyte character sets were not taken into account when calculating max_length in Item_param::convert_str_value(). As a result, string parameters of a prepared statement could be truncated later when calculating string length in characters by dividing length in bytes by the charset's mbmaxlen value (e.g. in Field_varstring::store()). Fixed by taking charset's mbmaxlen into account when calculating max_length in Item_param::convert_str_value(). sql/item.cc: Multiply string's length in characters by charset's mbmaxlen when calculating max_length. tests/mysql_client_test.c: Added a test case for bug #41078. --- sql/item.cc | 2 +- tests/mysql_client_test.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/sql/item.cc b/sql/item.cc index bc1ae683e93..c9edb7b8f6c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3010,7 +3010,7 @@ bool Item_param::convert_str_value(THD *thd) str_value.set_charset(value.cs_info.final_character_set_of_str_value); /* Here str_value is guaranteed to be in final_character_set_of_str_value */ - max_length= str_value.length(); + max_length= str_value.numchars() * str_value.charset()->mbmaxlen; decimals= 0; /* str_value_ptr is returned from val_str(). It must be not alloced diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 0fddffebf82..f848e93a5c6 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16410,6 +16410,69 @@ static void test_bug36326() #endif +/** + Bug#41078: With CURSOR_TYPE_READ_ONLY mysql_stmt_fetch() returns short + string value. +*/ + +static void test_bug41078(void) +{ + uint rc; + MYSQL_STMT *stmt= 0; + MYSQL_BIND param, result; + ulong cursor_type= CURSOR_TYPE_READ_ONLY; + ulong len; + char str[64]; + const char param_str[]= "abcdefghijklmn"; + my_bool is_null, error; + + DBUG_ENTER("test_bug41078"); + + rc= mysql_query(mysql, "SET NAMES UTF8"); + myquery(rc); + + stmt= mysql_simple_prepare(mysql, "SELECT ?"); + check_stmt(stmt); + verify_param_count(stmt, 1); + + rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor_type); + check_execute(stmt, rc); + + bzero(¶m, sizeof(param)); + param.buffer_type= MYSQL_TYPE_STRING; + param.buffer= (void *) param_str; + len= sizeof(param_str) - 1; + param.length= &len; + + rc= mysql_stmt_bind_param(stmt, ¶m); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + bzero(&result, sizeof(result)); + result.buffer_type= MYSQL_TYPE_STRING; + result.buffer= str; + result.buffer_length= sizeof(str); + result.is_null= &is_null; + result.length= &len; + result.error= &error; + + rc= mysql_stmt_bind_result(stmt, &result); + check_execute(stmt, rc); + + rc= mysql_stmt_store_result(stmt); + check_execute(stmt, rc); + + rc= mysql_stmt_fetch(stmt); + check_execute(stmt, rc); + + DIE_UNLESS(len == sizeof(param_str) - 1 && !strcmp(str, param_str)); + + mysql_stmt_close(stmt); + + DBUG_VOID_RETURN; +} /* Read and parse arguments and MySQL options from my.cnf @@ -16713,6 +16776,7 @@ static struct my_tests_st my_tests[]= { #ifdef HAVE_QUERY_CACHE { "test_bug36326", test_bug36326 }, #endif + { "test_bug41078", test_bug41078 }, { 0, 0 } }; -- cgit v1.2.1 From b68e5b66ed2241e8b6a90a057894d9b557b60a81 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 19 Feb 2009 17:20:44 +0400 Subject: Bug#37601 Cast Is Not Done On Row Comparison In case of ROW item each compared pair does not check if argumet collations can be aggregated and thus appropiriate item conversion does not happen. The fix is to add the check and convertion for ROW pairs. mysql-test/r/row.result: test result mysql-test/t/row.test: test case sql/item.cc: added agg_item_set_converter() function which was a part of agg_item_charsets() func. The only difference is that agg_item_set_converter() checks and converts items using already known collation. sql/item.h: added agg_item_set_converter() function sql/item_cmpfunc.cc: In case of ROW item each compared pair does not check if argumet collations can be aggregated and thus appropiriate item conversion does not happen. The fix is to add the check and convertion for ROW pairs. --- mysql-test/r/row.result | 14 +++++++++ mysql-test/t/row.test | 18 ++++++++++++ sql/item.cc | 76 ++++++++++++++++++++++++++++--------------------- sql/item.h | 2 ++ sql/item_cmpfunc.cc | 13 ++++++++- 5 files changed, 89 insertions(+), 34 deletions(-) diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result index 98c79d4bc00..9afb528b6dd 100644 --- a/mysql-test/r/row.result +++ b/mysql-test/r/row.result @@ -443,3 +443,17 @@ SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a; ROW(a, 1) IN (SELECT SUM(b), 3) 0 DROP TABLE t1; +create table t1 (a varchar(200), +b int unsigned not null primary key auto_increment) +default character set 'utf8'; +create table t2 (c varchar(200), +d int unsigned not null primary key auto_increment) +default character set 'latin1'; +insert into t1 (a) values('abc'); +insert into t2 (c) values('abc'); +select * from t1,t2 where (a,b) = (c,d); +a b c d +abc 1 abc 1 +select host,user from mysql.user where (host,user) = ('localhost','test'); +host user +drop table t1,t2; diff --git a/mysql-test/t/row.test b/mysql-test/t/row.test index 1601f7afd0e..fcc4259168b 100644 --- a/mysql-test/t/row.test +++ b/mysql-test/t/row.test @@ -237,3 +237,21 @@ SELECT ROW(a, 1) IN (SELECT SUM(b), 1) FROM t1 GROUP BY a; SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a; DROP TABLE t1; + +# +# Bug#37601 Cast Is Not Done On Row Comparison +# +create table t1 (a varchar(200), + b int unsigned not null primary key auto_increment) +default character set 'utf8'; + +create table t2 (c varchar(200), + d int unsigned not null primary key auto_increment) +default character set 'latin1'; + +insert into t1 (a) values('abc'); +insert into t2 (c) values('abc'); +select * from t1,t2 where (a,b) = (c,d); + +select host,user from mysql.user where (host,user) = ('localhost','test'); +drop table t1,t2; diff --git a/sql/item.cc b/sql/item.cc index c9edb7b8f6c..14422bd3e92 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1608,42 +1608,11 @@ bool agg_item_collations_for_comparison(DTCollation &c, const char *fname, } -/* - Collect arguments' character sets together. - We allow to apply automatic character set conversion in some cases. - The conditions when conversion is possible are: - - arguments A and B have different charsets - - A wins according to coercibility rules - (i.e. a column is stronger than a string constant, - an explicit COLLATE clause is stronger than a column) - - character set of A is either superset for character set of B, - or B is a string constant which can be converted into the - character set of A without data loss. - - If all of the above is true, then it's possible to convert - B into the character set of A, and then compare according - to the collation of A. - - For functions with more than two arguments: - - collect(A,B,C) ::= collect(collect(A,B),C) - Since this function calls THD::change_item_tree() on the passed Item ** - pointers, it is necessary to pass the original Item **'s, not copies. - Otherwise their values will not be properly restored (see BUG#20769). - If the items are not consecutive (eg. args[2] and args[5]), use the - item_sep argument, ie. - - agg_item_charsets(coll, fname, &args[2], 2, flags, 3) - -*/ - -bool agg_item_charsets(DTCollation &coll, const char *fname, - Item **args, uint nargs, uint flags, int item_sep) +bool agg_item_set_converter(DTCollation &coll, const char *fname, + Item **args, uint nargs, uint flags, int item_sep) { Item **arg, *safe_args[2]; - if (agg_item_collations(coll, fname, args, nargs, flags, item_sep)) - return TRUE; /* For better error reporting: save the first and the second argument. @@ -1724,6 +1693,47 @@ bool agg_item_charsets(DTCollation &coll, const char *fname, } +/* + Collect arguments' character sets together. + We allow to apply automatic character set conversion in some cases. + The conditions when conversion is possible are: + - arguments A and B have different charsets + - A wins according to coercibility rules + (i.e. a column is stronger than a string constant, + an explicit COLLATE clause is stronger than a column) + - character set of A is either superset for character set of B, + or B is a string constant which can be converted into the + character set of A without data loss. + + If all of the above is true, then it's possible to convert + B into the character set of A, and then compare according + to the collation of A. + + For functions with more than two arguments: + + collect(A,B,C) ::= collect(collect(A,B),C) + + Since this function calls THD::change_item_tree() on the passed Item ** + pointers, it is necessary to pass the original Item **'s, not copies. + Otherwise their values will not be properly restored (see BUG#20769). + If the items are not consecutive (eg. args[2] and args[5]), use the + item_sep argument, ie. + + agg_item_charsets(coll, fname, &args[2], 2, flags, 3) + +*/ + +bool agg_item_charsets(DTCollation &coll, const char *fname, + Item **args, uint nargs, uint flags, int item_sep) +{ + Item **arg, *safe_args[2]; + if (agg_item_collations(coll, fname, args, nargs, flags, item_sep)) + return TRUE; + + return agg_item_set_converter(coll, fname, args, nargs, flags, item_sep); +} + + void Item_ident_for_show::make_field(Send_field *tmp_field) { tmp_field->table_name= tmp_field->org_table_name= table_name; diff --git a/sql/item.h b/sql/item.h index 1058cc5dbb8..852b0fcc1ba 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1169,6 +1169,8 @@ bool agg_item_collations(DTCollation &c, const char *name, Item **items, uint nitems, uint flags, int item_sep); bool agg_item_collations_for_comparison(DTCollation &c, const char *name, Item **items, uint nitems, uint flags); +bool agg_item_set_converter(DTCollation &coll, const char *fname, + Item **args, uint nargs, uint flags, int item_sep); bool agg_item_charsets(DTCollation &c, const char *name, Item **items, uint nitems, uint flags, int item_sep); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3b1d18b4252..01d3e9bed52 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -490,7 +490,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols()); return 1; } - comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i)); + if (comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i))) + return 1; } break; } @@ -835,6 +836,16 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, get_value_func= &get_time_value; return 0; } + else if (type == STRING_RESULT && + (*a)->result_type() == STRING_RESULT && + (*b)->result_type() == STRING_RESULT) + { + DTCollation coll; + coll.set((*a)->collation.collation); + if (agg_item_set_converter(coll, owner_arg->func_name(), + b, 1, MY_COLL_CMP_CONV, 1)) + return 1; + } return set_compare_func(owner_arg, type); } -- cgit v1.2.1 From 7c0b3153872b8e49a115140fe7b0779f3b678c89 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 19 Feb 2009 17:30:03 +0200 Subject: Bug #42419: Server crash with "Pure virtual method called" on two concurrent connections The problem is that tables can enter open table cache for a thread without being properly cleaned up. This can happen if make_join_statistics() fails to read a const table because of e.g. a deadlock. It does set a member of TABLE structure to a value it allocates, but doesn't clean-up this setting on error nor does it set the rest of the members in JOIN to allow for automatic cleanup. As a result when such an error occurs and the next statement depends re-uses the table from the open tables cache it will get it with this TABLE::reginfo.join_tab pointing to a memory area that's freed. Fixed by making sure make_join_statistics() cleans up TABLE::reginfo.join_tab on error. mysql-test/r/innodb_mysql.result: Bug #42419: test case mysql-test/t/innodb_mysql-master.opt: Bug #42419: increase the timeout so it covers te conservative sleep 3 in the test mysql-test/t/innodb_mysql.test: Bug #42419: test case sql/sql_select.cc: Bug #42419: clean up the members of TABLE on failure in make_join_statisitcs() --- mysql-test/r/innodb_mysql.result | 16 +++++++++++ mysql-test/t/innodb_mysql-master.opt | 2 +- mysql-test/t/innodb_mysql.test | 51 ++++++++++++++++++++++++++++++++++++ sql/sql_select.cc | 36 ++++++++++++++++--------- 4 files changed, 92 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 682cc2e82e2..78a56cddb08 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1267,4 +1267,20 @@ CREATE INDEX i1 on t1 (a(3)); SELECT * FROM t1 WHERE a = 'abcde'; a DROP TABLE t1; +CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +SET AUTOCOMMIT = 0; +CREATE TEMPORARY TABLE t1_tmp (b INT); +INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 3; +INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 2; +SET AUTOCOMMIT = 0; +CREATE TEMPORARY TABLE t2_tmp ( a INT, new_a INT); +INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; +INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/innodb_mysql-master.opt b/mysql-test/t/innodb_mysql-master.opt index 205c733455d..c8613e0ccd5 100644 --- a/mysql-test/t/innodb_mysql-master.opt +++ b/mysql-test/t/innodb_mysql-master.opt @@ -1 +1 @@ ---innodb-lock-wait-timeout=2 +--innodb-lock-wait-timeout=3 diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index b4fc425cb7c..eb23739386e 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -1025,4 +1025,55 @@ CREATE INDEX i1 on t1 (a(3)); SELECT * FROM t1 WHERE a = 'abcde'; DROP TABLE t1; +# +# Bug #42419: Server crash with "Pure virtual method called" on two +# concurrent connections +# + +connect (c1, localhost, root,,); +connect (c2, localhost, root,,); + +CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT) + ENGINE=InnoDB; + +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); + +connection c1; + +SET AUTOCOMMIT = 0; + +CREATE TEMPORARY TABLE t1_tmp (b INT); + +INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 3; +INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 2; + +connection c2; + +SET AUTOCOMMIT = 0; + +CREATE TEMPORARY TABLE t2_tmp ( a INT, new_a INT); +INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); + +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; + +--send +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; + +--sleep 3 + +connection c1; + +--error ER_LOCK_DEADLOCK +INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 1; + +connection c2; + +--reap +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; + +connection default; +disconnect c1; +disconnect c2; +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a341cf5e0e9..a820e9966dc 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2373,11 +2373,12 @@ typedef struct st_sargable_param */ static bool -make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, +make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds, DYNAMIC_ARRAY *keyuse_array) { int error; TABLE *table; + TABLE_LIST *tables= tables_arg; uint i,table_count,const_count,key; table_map found_const_table_map, all_table_map, found_ref, refs; key_map const_ref, eq_part; @@ -2415,10 +2416,10 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, table_vector[i]=s->table=table=tables->table; table->pos_in_table_list= tables; error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); - if(error) + if (error) { - table->file->print_error(error, MYF(0)); - DBUG_RETURN(1); + table->file->print_error(error, MYF(0)); + goto error; } table->quick_keys.clear_all(); table->reginfo.join_tab=s; @@ -2503,7 +2504,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, { join->tables=0; // Don't use join->table my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0)); - DBUG_RETURN(1); + goto error; } s->key_dependent= s->dependent; } @@ -2513,7 +2514,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables, conds, join->cond_equal, ~outer_join, join->select_lex, &sargables)) - DBUG_RETURN(1); + goto error; /* Read tables with 0 or 1 rows (system tables) */ join->const_table_map= 0; @@ -2529,7 +2530,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if ((tmp=join_read_const_table(s, p_pos))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= s->table->map; @@ -2601,7 +2602,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if ((tmp= join_read_const_table(s, join->positions+const_count-1))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= table->map; @@ -2650,12 +2651,12 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, set_position(join,const_count++,s,start_keyuse); if (create_ref_for_key(join, s, start_keyuse, found_const_table_map)) - DBUG_RETURN(1); + goto error; if ((tmp=join_read_const_table(s, join->positions+const_count-1))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= table->map; @@ -2732,7 +2733,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, *s->on_expr_ref ? *s->on_expr_ref : conds, 1, &error); if (!select) - DBUG_RETURN(1); + goto error; records= get_quick_record_count(join->thd, select, s->table, &s->const_keys, join->row_limit); s->quick=select->quick; @@ -2778,7 +2779,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, { optimize_keyuse(join, keyuse_array); if (choose_plan(join, all_table_map & ~join->const_table_map)) - DBUG_RETURN(TRUE); + goto error; } else { @@ -2788,6 +2789,17 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, } /* Generate an execution plan from the found optimal join order. */ DBUG_RETURN(join->thd->killed || get_best_combination(join)); + +error: + /* + Need to clean up join_tab from TABLEs in case of error. + They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab + may not be assigned yet by this function (which is building join_tab). + Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke. + */ + for (tables= tables_arg; tables; tables= tables->next_leaf) + tables->table->reginfo.join_tab= NULL; + DBUG_RETURN (1); } -- cgit v1.2.1 From c2e926176ab1d66845d1ce02e07bb4fc9b91a134 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Thu, 19 Feb 2009 15:37:40 -0500 Subject: Bug#38831: 11 test cases fail on Windows due to missing commands Replaced Unix calls with mysql-test-run's built-in functions / SQL manipulation where possible. Replaced error codes with error names as well. Disabled two tests on Windows due to more complex Unix command usage See Bug#41307, Bug#41308 --- mysql-test/include/ndb_backup.inc | 7 +++ mysql-test/r/mysqlbinlog.result | 9 +++- mysql-test/r/mysqltest.result | 2 - mysql-test/r/trigger-compat.result | 4 +- mysql-test/t/mysqlbinlog.test | 28 ++++++++-- mysql-test/t/mysqltest.test | 108 +++++++++++++++++++++++-------------- mysql-test/t/ndb_autodiscover.test | 6 +++ mysql-test/t/rpl_trigger.test | 3 +- mysql-test/t/trigger-compat.test | 24 +++++++-- 9 files changed, 136 insertions(+), 55 deletions(-) diff --git a/mysql-test/include/ndb_backup.inc b/mysql-test/include/ndb_backup.inc index f0a883d4e11..3239030bb64 100644 --- a/mysql-test/include/ndb_backup.inc +++ b/mysql-test/include/ndb_backup.inc @@ -2,6 +2,13 @@ # By JBM 2006-02-16 So that the code is not repeated # # in test cases and can be reused. # ###################################################### + +# Bug#41307: Tests using include/ndb_backup.inc won't work on Windows due to +# 'grep' call +# This test is disabled on Windows via the next line until the above bug is +# resolved +--source include/not_windows.inc + --exec $NDB_MGM --no-defaults --ndb-connectstring="localhost:$NDBCLUSTER_PORT" -e "start backup" >> $NDB_TOOLS_OUTPUT # there is no neat way to find the backupid, this is a hack to find it... diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index 4fd87861ded..fe536950b4c 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -353,7 +353,14 @@ flush logs; INSERT INTO t1 VALUES ('0123456789'); flush logs; DROP TABLE t1; -# Query thread_id=REMOVED exec_time=REMOVED error_code=REMOVED +We expect this value to be 1 +The bug being tested was that 'Query' lines were not preceded by '#' +If the line is in the table, it had to have been preceded by a '#' + +SELECT COUNT(*) AS `BUG#28293_expect_1` FROM patch WHERE a LIKE '%Query%'; +BUG#28293_expect_1 +1 +DROP TABLE patch; flush logs; create table t1(a int); insert into t1 values(connection_id()); diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index a7df1a523cf..e445bf3cc9b 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -210,7 +210,6 @@ source database "MySQL: The world's most popular ;open source database" echo message echo message -mysqltest: At line 1: command "false" failed mysqltest: At line 1: Missing argument in exec MySQL "MySQL" @@ -378,7 +377,6 @@ mysqltest: At line 1: The argument to dec must be a variable (start with $) mysqltest: At line 1: End of line junk detected: "1000" mysqltest: At line 1: Missing arguments to system, nothing to do! mysqltest: At line 1: Missing arguments to system, nothing to do! -mysqltest: At line 1: system command 'false' failed system command 'NonExistsinfComamdn 2> /dev/null' failed test test2 diff --git a/mysql-test/r/trigger-compat.result b/mysql-test/r/trigger-compat.result index 6839cacab43..81c7a14c173 100644 --- a/mysql-test/r/trigger-compat.result +++ b/mysql-test/r/trigger-compat.result @@ -13,9 +13,7 @@ GRANT CREATE ON mysqltest_db1.* TO mysqltest_dfn@localhost; ---> connection: wl2818_definer_con CREATE TABLE t1(num_value INT); CREATE TABLE t2(user_str TEXT); -CREATE TRIGGER wl2818_trg1 BEFORE INSERT ON t1 -FOR EACH ROW -INSERT INTO t2 VALUES(CURRENT_USER()); +CREATE TRIGGER wl2818_trg1 BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES(CURRENT_USER()); ---> patching t1.TRG... diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 5b4a43c8fe8..1f3d0fed334 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -1,7 +1,9 @@ # We are using .opt file since we need small binlog size - -- source include/have_log_bin.inc +# Currently disabling this test on Windows due to use of grep and sed +--source include/not_windows.inc + # we need this for getting fixed timestamps inside of this test set timestamp=1000000000; @@ -174,7 +176,8 @@ delimiter ;// flush logs; call p1(); drop procedure p1; ---error 1305 +--error ER_SP_DOES_NOT_EXIST + call p1(); --replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form $MYSQLTEST_VARDIR/log/master-bin.000007 @@ -226,7 +229,26 @@ flush logs; INSERT INTO t1 VALUES ('0123456789'); flush logs; DROP TABLE t1; ---exec $MYSQL_BINLOG --hexdump --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000011 | grep 'Query' | sed 's/[0-9]\{1,\}/REMOVED/g' + +# We create a table, patch, and load the output into it +# By using LINES STARTING BY '#' + SELECT WHERE a LIKE 'Query' +# We can easily see if a 'Query' line is missing the '#' character +# as described in the original bug + +--disable_query_log +CREATE TABLE patch (a blob); +--exec $MYSQL_BINLOG --hexdump --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000011 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat +eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat' + INTO TABLE patch FIELDS TERMINATED by '' LINES STARTING BY '#'; +--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat +--enable_query_log + +--echo We expect this value to be 1 +--echo The bug being tested was that 'Query' lines were not preceded by '#' +--echo If the line is in the table, it had to have been preceded by a '#' +--echo +SELECT COUNT(*) AS `BUG#28293_expect_1` FROM patch WHERE a LIKE '%Query%'; +DROP TABLE patch; # # Bug #29928: incorrect connection_id() restoring from mysqlbinlog out diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 5856bfff036..93528f81449 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -62,7 +62,8 @@ select otto from (select 1 as otto) as t1; --exec echo "select friedrich from (select 1 as otto) as t1;" | $MYSQL_TEST 2>&1 # expectation = response ---error 1054 +--error ER_BAD_FIELD_ERROR + select friedrich from (select 1 as otto) as t1; # The following unmasked unsuccessful statement must give @@ -131,14 +132,16 @@ eval select $mysql_errno as "after_successful_stmt_errno" ; #---------------------------------------------------------------------------- # check mysql_errno = 1064 after statement with wrong syntax # ---------------------------------------------------------------------------- ---error 1064 +--error ER_PARSE_ERROR + garbage ; eval select $mysql_errno as "after_wrong_syntax_errno" ; # ---------------------------------------------------------------------------- # check if let $my_var= 'abc' ; affects $mysql_errno # ---------------------------------------------------------------------------- ---error 1064 +--error ER_PARSE_ERROR + garbage ; let $my_var= 'abc' ; eval select $mysql_errno as "after_let_var_equal_value" ; @@ -146,7 +149,8 @@ eval select $mysql_errno as "after_let_var_equal_value" ; # ---------------------------------------------------------------------------- # check if set @my_var= 'abc' ; affects $mysql_errno # ---------------------------------------------------------------------------- ---error 1064 +--error ER_PARSE_ERROR + garbage ; set @my_var= 'abc' ; eval select $mysql_errno as "after_set_var_equal_value" ; @@ -155,7 +159,8 @@ eval select $mysql_errno as "after_set_var_equal_value" ; # check if the setting of --disable-warnings itself affects $mysql_errno # (May be -- modifies $mysql_errno.) # ---------------------------------------------------------------------------- ---error 1064 +--error ER_PARSE_ERROR + garbage ; --disable_warnings eval select $mysql_errno as "after_disable_warnings_command" ; @@ -166,7 +171,8 @@ eval select $mysql_errno as "after_disable_warnings_command" ; # (May be disabled warnings affect $mysql_errno.) # ---------------------------------------------------------------------------- drop table if exists t1 ; ---error 1064 +--error ER_PARSE_ERROR + garbage ; drop table if exists t1 ; eval select $mysql_errno as "after_disable_warnings" ; @@ -175,21 +181,26 @@ eval select $mysql_errno as "after_disable_warnings" ; # ---------------------------------------------------------------------------- # check if masked errors affect $mysql_errno # ---------------------------------------------------------------------------- ---error 1064 +--error ER_PARSE_ERROR + garbage ; ---error 1146 +--error ER_NO_SUCH_TABLE + select 3 from t1 ; eval select $mysql_errno as "after_minus_masked" ; ---error 1064 +--error ER_PARSE_ERROR + garbage ; ---error 1146 +--error ER_NO_SUCH_TABLE + select 3 from t1 ; eval select $mysql_errno as "after_!_masked" ; # ---------------------------------------------------------------------------- # Will manipulations of $mysql_errno be possible and visible ? # ---------------------------------------------------------------------------- ---error 1064 +--error ER_PARSE_ERROR + garbage ; let $mysql_errno= -1; eval select $mysql_errno as "after_let_errno_equal_value" ; @@ -198,50 +209,61 @@ eval select $mysql_errno as "after_let_errno_equal_value" ; # How affect actions on prepared statements $mysql_errno ? # ---------------------------------------------------------------------------- # failing prepare ---error 1064 +--error ER_PARSE_ERROR + garbage ; ---error 1146 +--error ER_NO_SUCH_TABLE + prepare stmt from "select 3 from t1" ; eval select $mysql_errno as "after_failing_prepare" ; create table t1 ( f1 char(10)); # successful prepare ---error 1064 +--error ER_PARSE_ERROR + garbage ; prepare stmt from "select 3 from t1" ; eval select $mysql_errno as "after_successful_prepare" ; # successful execute ---error 1064 +--error ER_PARSE_ERROR + garbage ; execute stmt; eval select $mysql_errno as "after_successful_execute" ; # failing execute (table has been dropped) drop table t1; ---error 1064 +--error ER_PARSE_ERROR + garbage ; ---error 1146 +--error ER_NO_SUCH_TABLE + execute stmt; eval select $mysql_errno as "after_failing_execute" ; # failing execute (unknown statement) ---error 1064 +--error ER_PARSE_ERROR + garbage ; ---error 1243 +--error ER_UNKNOWN_STMT_HANDLER + execute __stmt_; eval select $mysql_errno as "after_failing_execute" ; # successful deallocate ---error 1064 +--error ER_PARSE_ERROR + garbage ; deallocate prepare stmt; eval select $mysql_errno as "after_successful_deallocate" ; # failing deallocate ( statement handle does not exist ) ---error 1064 +--error ER_PARSE_ERROR + garbage ; ---error 1243 +--error ER_UNKNOWN_STMT_HANDLER + deallocate prepare __stmt_; eval select $mysql_errno as "after_failing_deallocate" ; @@ -266,7 +288,8 @@ eval select $mysql_errno as "after_failing_deallocate" ; # ---------------------------------------------------------------------------- # Switch off the abort on error and check the effect on $mysql_errno # ---------------------------------------------------------------------------- ---error 1064 +--error ER_PARSE_ERROR + garbage ; --disable_abort_on_error eval select $mysql_errno as "after_--disable_abort_on_error" ; @@ -280,9 +303,11 @@ select 3 from t1 ; # masked failing statements # ---------------------------------------------------------------------------- # expected error = response ---error 1146 +--error ER_NO_SUCH_TABLE + select 3 from t1 ; ---error 1146 +--error ER_NO_SUCH_TABLE + select 3 from t1 ; eval select $mysql_errno as "after_!errno_masked_error" ; # expected error <> response @@ -296,7 +321,8 @@ eval select $mysql_errno as "after_!errno_masked_error" ; # ---------------------------------------------------------------------------- # Switch the abort on error on and check the effect on $mysql_errno # ---------------------------------------------------------------------------- ---error 1064 +--error ER_PARSE_ERROR + garbage ; --enable_abort_on_error eval select $mysql_errno as "after_--enable_abort_on_error" ; @@ -305,7 +331,8 @@ eval select $mysql_errno as "after_--enable_abort_on_error" ; # masked failing statements # ---------------------------------------------------------------------------- # expected error = response ---error 1146 +--error ER_NO_SUCH_TABLE + select 3 from t1 ; # ---------------------------------------------------------------------------- @@ -568,9 +595,6 @@ echo ; # ---------------------------------------------------------------------------- # Illegal use of exec ---error 1 ---exec echo "--exec false" | $MYSQL_TEST 2>&1 - --error 1 --exec echo "--exec " | $MYSQL_TEST 2>&1 @@ -951,8 +975,6 @@ system echo "hej" > /dev/null; --exec echo "system;" | $MYSQL_TEST 2>&1 --error 1 --exec echo "system $NONEXISTSINFVAREABLI;" | $MYSQL_TEST 2>&1 ---error 1 ---exec echo "system false;" | $MYSQL_TEST 2>&1 --disable_abort_on_error system NonExistsinfComamdn 2> /dev/null; @@ -1370,7 +1392,8 @@ connection default; let $num= 2; while ($num) { - --error 1064 + --error ER_PARSE_ERROR + failing_statement; dec $num; @@ -1429,7 +1452,7 @@ select "this will be executed"; # # Test zero length result file. Should not pass # ---exec touch $MYSQLTEST_VARDIR/tmp/zero_length_file.result +--exec echo '' > $MYSQLTEST_VARDIR/tmp/zero_length_file.result --exec echo "echo ok;" > $MYSQLTEST_VARDIR/tmp/query.sql --error 1 --exec $MYSQL_TEST -x $MYSQLTEST_VARDIR/tmp/query.sql -R $MYSQLTEST_VARDIR/tmp/zero_length_file.result > /dev/null 2>&1 @@ -1482,7 +1505,8 @@ drop table t1; --error 1 --exec $MYSQL_TEST --record -x $MYSQLTEST_VARDIR/tmp/bug11731.sql -R $MYSQLTEST_VARDIR/tmp/bug11731.out 2>&1 # The .out file should be non existent ---exec test ! -s $MYSQLTEST_VARDIR/tmp/bug11731.out +--error 1 +--file_exists $MYSQLTEST_VARDIR/tmp/bug11731.out drop table t1; @@ -1503,7 +1527,7 @@ drop table t1; --exec $MYSQL_TEST --record -x $MYSQLTEST_VARDIR/tmp/bug11731.sql -R $MYSQLTEST_VARDIR/tmp/bug11731.out 2>&1 # The .out file should exist ---exec test -s $MYSQLTEST_VARDIR/tmp/bug11731.out +--file_exists $MYSQLTEST_VARDIR/tmp/bug11731.out drop table t1; remove_file $MYSQLTEST_VARDIR/tmp/bug11731.out; remove_file $MYSQLTEST_VARDIR/log/bug11731.log; @@ -1515,14 +1539,17 @@ remove_file $MYSQLTEST_VARDIR/tmp/bug11731.sql; # It should be possible to use the command "query" to force mysqltest to # send the command to the server although it's a builtin mysqltest command. ---error 1064 +--error ER_PARSE_ERROR + query sleep; ---error 1064 +--error ER_PARSE_ERROR + --query sleep # Just an empty query command ---error 1065 +--error ER_EMPTY_QUERY + query ; # test for replace_regex @@ -1915,7 +1942,8 @@ eval $my_stmt; # 8. Ensure that "sorted_result " does not change the semantics of # "--error ...." or the protocol output after such an expected failure --sorted_result ---error 1146 +--error ER_NO_SUCH_TABLE + SELECT '2' as "my_col1",2 as "my_col2" UNION SELECT '1',1 from t2; diff --git a/mysql-test/t/ndb_autodiscover.test b/mysql-test/t/ndb_autodiscover.test index dc450aeb9cf..73c04ad6764 100644 --- a/mysql-test/t/ndb_autodiscover.test +++ b/mysql-test/t/ndb_autodiscover.test @@ -1,6 +1,12 @@ -- source include/have_ndb.inc -- source include/not_embedded.inc +# Bug#41308: Test main.ndb_autodiscover.test doesn't work on Windows due +# to 'grep' calls +# Test is currently disabled on Windows via the next line until this bug +# can be resolved. +--source include/not_windows.inc + --disable_warnings drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; --enable_warnings diff --git a/mysql-test/t/rpl_trigger.test b/mysql-test/t/rpl_trigger.test index da6cea10698..d5472b47b7b 100644 --- a/mysql-test/t/rpl_trigger.test +++ b/mysql-test/t/rpl_trigger.test @@ -293,7 +293,8 @@ STOP SLAVE; connection master; FLUSH LOGS; -exec cp $MYSQL_TEST_DIR/std_data/bug16266.000001 $MYSQLTEST_VARDIR/log/master-bin.000001; +--remove_file $MYSQLTEST_VARDIR/log/master-bin.000001 +--copy_file $MYSQL_TEST_DIR/std_data/bug16266.000001 $MYSQLTEST_VARDIR/log/master-bin.000001 # Make the slave to replay the new binlog. diff --git a/mysql-test/t/trigger-compat.test b/mysql-test/t/trigger-compat.test index f2e350cb161..db410ba2f18 100644 --- a/mysql-test/t/trigger-compat.test +++ b/mysql-test/t/trigger-compat.test @@ -50,9 +50,7 @@ GRANT CREATE ON mysqltest_db1.* TO mysqltest_dfn@localhost; CREATE TABLE t1(num_value INT); CREATE TABLE t2(user_str TEXT); -CREATE TRIGGER wl2818_trg1 BEFORE INSERT ON t1 - FOR EACH ROW - INSERT INTO t2 VALUES(CURRENT_USER()); +CREATE TRIGGER wl2818_trg1 BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES(CURRENT_USER()); # # Remove definers from TRG file. @@ -61,8 +59,24 @@ CREATE TRIGGER wl2818_trg1 BEFORE INSERT ON t1 --echo --echo ---> patching t1.TRG... ---exec grep -v 'definers=' $MYSQLTEST_VARDIR/master-data/mysqltest_db1/t1.TRG > $MYSQLTEST_VARDIR/tmp/t1.TRG ---exec mv $MYSQLTEST_VARDIR/tmp/t1.TRG $MYSQLTEST_VARDIR/master-data/mysqltest_db1/t1.TRG +# Here we remove definers. This is somewhat complex than the original test +# Previously, the test only used grep -v 'definers=' t1.TRG, but grep is not +# portable and we have to load the file into a table, exclude the definers line, +# then load the data to an outfile to accomplish the same effect + +--disable_query_log +--connection default +CREATE TABLE patch (a blob); +eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/master-data/mysqltest_db1/t1.TRG' INTO TABLE patch; +# remove original t1.TRG file so SELECT INTO OUTFILE won't fail +--remove_file $MYSQLTEST_VARDIR/master-data/mysqltest_db1/t1.TRG +eval SELECT SUBSTRING_INDEX(a,'definers=',1) INTO OUTFILE + '$MYSQLTEST_VARDIR/master-data/mysqltest_db1/t1.TRG' +FROM patch; +DROP TABLE patch; +--connection wl2818_definer_con +--enable_query_log + # # Create a new trigger. -- cgit v1.2.1 From decee3cb1c359c1b468ced17b4514eea443f7d4f Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Thu, 19 Feb 2009 16:35:29 -0500 Subject: Bug#38831: 11 test cases fail on Windows due to missing commands Re-enabling mysqlbinlog.test on Windows - removed the use of grep/sed --- mysql-test/t/mysqlbinlog.test | 3 --- 1 file changed, 3 deletions(-) diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 1f3d0fed334..b52ab9c5496 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -1,9 +1,6 @@ # We are using .opt file since we need small binlog size -- source include/have_log_bin.inc -# Currently disabling this test on Windows due to use of grep and sed ---source include/not_windows.inc - # we need this for getting fixed timestamps inside of this test set timestamp=1000000000; -- cgit v1.2.1 From 81956f43dbd5c45243832edbf54af8d6888ea3ec Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 20 Feb 2009 11:12:06 +0200 Subject: Bug #42419: test suite fix Moved the test case for the bug into a separate file (and restored the original innodb_mysql test setup). Used the new wait_show_condition test macro to avoid the usage of sleep mysql-test/include/wait_show_condition.inc: Bug #42419: new test macro to wait for a row in SHOW to have a certain value. mysql-test/r/innodb_bug42419.result: Bug #42419: test case mysql-test/r/innodb_mysql.result: Bug #42419: revert to the original innodb_mysql test mysql-test/t/innodb_bug42419.test: Bug #42419: test case mysql-test/t/innodb_mysql-master.opt: Bug #42419: revert to the original innodb_mysql test mysql-test/t/innodb_mysql.test: Bug #42419: revert to the original innodb_mysql test --- mysql-test/include/wait_show_condition.inc | 78 ++++++++++++++++++++++++++++++ mysql-test/r/innodb_bug42419.result | 17 +++++++ mysql-test/r/innodb_mysql.result | 16 ------ mysql-test/t/innodb_bug42419.test | 77 +++++++++++++++++++++++++++++ mysql-test/t/innodb_mysql-master.opt | 2 +- mysql-test/t/innodb_mysql.test | 51 ------------------- 6 files changed, 173 insertions(+), 68 deletions(-) create mode 100644 mysql-test/include/wait_show_condition.inc create mode 100644 mysql-test/r/innodb_bug42419.result create mode 100644 mysql-test/t/innodb_bug42419.test diff --git a/mysql-test/include/wait_show_condition.inc b/mysql-test/include/wait_show_condition.inc new file mode 100644 index 00000000000..253101d1e07 --- /dev/null +++ b/mysql-test/include/wait_show_condition.inc @@ -0,0 +1,78 @@ +# include/wait_show_condition.inc +# +# SUMMARY +# +# Waits until the show statement ($show_statement) has at least within one of +# the rows of the result set for the field ($field) a value which fulfils +# a condition ($condition), or the operation times out. +# +# +# USAGE +# +# let $show_statement= SHOW PROCESSLIST; +# let $field= State; +# let $condition= = 'Updating'; +# --source include/wait_show_condition.inc +# +# OR +# +# let $wait_timeout= 60; # Override default of 30 seconds with 60. +# let $show_statement= SHOW PROCESSLIST; +# let $field= State; +# let $condition= = 'Updating'; +# --source include/wait_show_condition.inc +# +# Please do not use this use routine if you can replace the SHOW statement +# with a select. In such a case include/wait_condition.inc is recommended. +# +# Created: 2009-02-18 mleich +# + +let $max_run_time= 30; +if ($wait_timeout) +{ + let $max_run_time= $wait_timeout; +} +# Reset $wait_timeout so that its value won't be used on subsequent +# calls, and default will be used instead. +let $wait_timeout= 0; + +# The smallest timespan till UNIX_TIMESTAMP() gets incremented is ~0 seconds. +# We add one second to avoid the case that somebody measures timespans on a +# real clock with fractions of seconds, detects that n seconds are sufficient, +# assigns n to this routine and suffers because he sometimes gets n - 1 +# seconds in reality. +inc $max_run_time; + +let $found= 0; +let $max_end_time= `SELECT UNIX_TIMESTAMP() + $max_run_time`; +while (`SELECT UNIX_TIMESTAMP() <= $max_end_time AND $found = 0`) +{ + # Sleep a bit to avoid too heavy load. + real_sleep 0.2; + let $rowno= 1; + let $process_result= 1; + while (`SELECT $process_result = 1 AND $found = 0`) + { + let $field_value= query_get_value($show_statement, $field, $rowno); + if (`SELECT '$field_value' $condition`) + { + let $found= 1; + } + if (`SELECT '$field_value' = 'No such row'`) + { + # We are behind the last row of the result set. + let $process_result= 0; + } + inc $rowno; + } +} +if (!$found) +{ + echo # Timeout in include/wait_show_condition.inc for $wait_condition; + echo # show_statement : $show_statement; + echo # field : $field; + echo # condition : $condition; + echo # max_run_time : $max_run_time; +} + diff --git a/mysql-test/r/innodb_bug42419.result b/mysql-test/r/innodb_bug42419.result new file mode 100644 index 00000000000..f304bb634cb --- /dev/null +++ b/mysql-test/r/innodb_bug42419.result @@ -0,0 +1,17 @@ +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +COMMIT; +SET AUTOCOMMIT = 0; +CREATE TEMPORARY TABLE t1_tmp ( b INT ); +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 3; +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 2; +SET AUTOCOMMIT = 0; +CREATE TEMPORARY TABLE t2_tmp ( a int, new_a int ); +INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +Reap the server message for connection user2 UPDATE t1 ... +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; +DROP TABLE t1; diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 78a56cddb08..682cc2e82e2 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1267,20 +1267,4 @@ CREATE INDEX i1 on t1 (a(3)); SELECT * FROM t1 WHERE a = 'abcde'; a DROP TABLE t1; -CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT) -ENGINE=InnoDB; -INSERT INTO t1 VALUES (1,1),(2,2),(3,3); -SET AUTOCOMMIT = 0; -CREATE TEMPORARY TABLE t1_tmp (b INT); -INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 3; -INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 2; -SET AUTOCOMMIT = 0; -CREATE TEMPORARY TABLE t2_tmp ( a INT, new_a INT); -INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); -UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; -UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; -INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 1; -ERROR 40001: Deadlock found when trying to get lock; try restarting transaction -UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; -DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/innodb_bug42419.test b/mysql-test/t/innodb_bug42419.test new file mode 100644 index 00000000000..389093a8465 --- /dev/null +++ b/mysql-test/t/innodb_bug42419.test @@ -0,0 +1,77 @@ +# +# Testcase for InnoDB +# Bug#42419 Server crash with "Pure virtual method called" on two concurrent connections +# + +--source include/have_innodb.inc + +let $innodb_lock_wait_timeout= query_get_value(SHOW VARIABLES LIKE 'innodb_lock_wait_timeout%', Value, 1); +if (`SELECT $innodb_lock_wait_timeout < 10`) +{ + --echo # innodb_lock_wait_timeout must be >= 10 seconds + --echo # so that this test can work all time fine on an overloaded testing box + SHOW VARIABLES LIKE 'innodb_lock_wait_timeout'; + exit; +} + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +# First session +connection default; + + +--enable_warnings +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE = InnoDB; + +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +COMMIT; +SET AUTOCOMMIT = 0; + +CREATE TEMPORARY TABLE t1_tmp ( b INT ); + +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 3; +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 2; + +# Second session +connect (user2,localhost,root,,,$MASTER_MYPORT,$MASTER_MYSOCK); + +SET AUTOCOMMIT = 0; + +CREATE TEMPORARY TABLE t2_tmp ( a int, new_a int ); +INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); + +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; +send +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; + +# The last update will wait for a lock held by the first session + +# First session +connection default; + +# Poll till the UPDATE of the second session waits for lock +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Updating'; +--source include/wait_show_condition.inc + +# If the testing box is overloadeded and innodb_lock_wait_timeout is too small +# we might get here ER_LOCK_WAIT_TIMEOUT. +--error ER_LOCK_DEADLOCK +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 1; + +# Second session +connection user2; +--echo Reap the server message for connection user2 UPDATE t1 ... +reap; + +# The server crashed when executing this UPDATE or the succeeding SQL command. +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; + +connection default; +disconnect user2; +DROP TABLE t1; + +# Wait till all disconnects are completed +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/innodb_mysql-master.opt b/mysql-test/t/innodb_mysql-master.opt index c8613e0ccd5..205c733455d 100644 --- a/mysql-test/t/innodb_mysql-master.opt +++ b/mysql-test/t/innodb_mysql-master.opt @@ -1 +1 @@ ---innodb-lock-wait-timeout=3 +--innodb-lock-wait-timeout=2 diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index eb23739386e..b4fc425cb7c 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -1025,55 +1025,4 @@ CREATE INDEX i1 on t1 (a(3)); SELECT * FROM t1 WHERE a = 'abcde'; DROP TABLE t1; -# -# Bug #42419: Server crash with "Pure virtual method called" on two -# concurrent connections -# - -connect (c1, localhost, root,,); -connect (c2, localhost, root,,); - -CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT) - ENGINE=InnoDB; - -INSERT INTO t1 VALUES (1,1),(2,2),(3,3); - -connection c1; - -SET AUTOCOMMIT = 0; - -CREATE TEMPORARY TABLE t1_tmp (b INT); - -INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 3; -INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 2; - -connection c2; - -SET AUTOCOMMIT = 0; - -CREATE TEMPORARY TABLE t2_tmp ( a INT, new_a INT); -INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); - -UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; - ---send -UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; - ---sleep 3 - -connection c1; - ---error ER_LOCK_DEADLOCK -INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 1; - -connection c2; - ---reap -UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; - -connection default; -disconnect c1; -disconnect c2; -DROP TABLE t1; - --echo End of 5.0 tests -- cgit v1.2.1 From 1ee9cfa037d8cdb8d67e4be1c2e58ce0279611f8 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 20 Feb 2009 11:42:35 +0200 Subject: fixed a warning --- sql/item.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/item.cc b/sql/item.cc index 14422bd3e92..f32828629cf 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1726,7 +1726,6 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname, bool agg_item_charsets(DTCollation &coll, const char *fname, Item **args, uint nargs, uint flags, int item_sep) { - Item **arg, *safe_args[2]; if (agg_item_collations(coll, fname, args, nargs, flags, item_sep)) return TRUE; -- cgit v1.2.1 From e2e6e14c06fa833665154425c0fae126f78ae8d7 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Fri, 20 Feb 2009 13:55:43 +0200 Subject: Bug #37313 BINLOG Contains Incorrect server id Signed integer format specifier forced to print the binlog header with server_id negative if the unsigned value sets the sign-bit ON. Fixed with correcting the specifier to correspond to typeof(server_id) == ulong. mysql-test/r/mysqlbinlog.result: results changed. mysql-test/t/mysqlbinlog.test: displaying the expected unsignedly formatted server_id value, bug#37313. sql/log_event.cc: Format specifier is corrected to correspond to typeof(server_id). --- mysql-test/r/mysqlbinlog.result | 10 ++++++++++ mysql-test/t/mysqlbinlog.test | 20 ++++++++++++++++++++ sql/log_event.cc | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index 4fd87861ded..b5ac22437cd 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -362,4 +362,14 @@ drop table t1; 1 drop table t1; shell> mysqlbinlog std_data/corrupt-relay-bin.000624 > var/tmp/bug31793.sql +set @@global.server_id= 4294967295; +reset master; +select +(@a:=load_file("MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog")) +is not null; +(@a:=load_file("MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog")) +is not null +1 +*** Unsigned server_id 4294967295 is found: 1 *** +set @@global.server_id= 1; End of 5.0 tests diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 5b4a43c8fe8..cf4bc1523df 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -253,4 +253,24 @@ echo shell> mysqlbinlog std_data/corrupt-relay-bin.000624 > var/tmp/bug31793.sql error 1; exec $MYSQL_BINLOG $MYSQL_TEST_DIR/std_data/corrupt-relay-bin.000624 > $MYSQLTEST_VARDIR/tmp/bug31793.sql; +# +# Bug #37313 BINLOG Contains Incorrect server id +# + +let $save_server_id= `select @@global.server_id`; +let $s_id_max=`select (1 << 32) - 1`; +eval set @@global.server_id= $s_id_max; + +reset master; +--exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval select +(@a:=load_file("$MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog")) +is not null; +let $s_id_unsigned= `select @a like "%server id $s_id_max%" /* must return 1 */`; +echo *** Unsigned server_id $s_id_max is found: $s_id_unsigned ***; + +eval set @@global.server_id= $save_server_id; +--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog + --echo End of 5.0 tests diff --git a/sql/log_event.cc b/sql/log_event.cc index ef419aaee40..90805877502 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -976,7 +976,7 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info) fputc('#', file); print_timestamp(file); - fprintf(file, " server id %d end_log_pos %s ", server_id, + fprintf(file, " server id %lu end_log_pos %s ", server_id, llstr(log_pos,llbuff)); /* mysqlbinlog --hexdump */ -- cgit v1.2.1 From 1b5d173b80951e094d389d8e44aed6cd59e5a1de Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Mon, 23 Feb 2009 14:28:26 +0200 Subject: Fix for bug #15936: "round" differs on Windows to Unix Both of our own implementations of rint(3) were inconsistent with the most common behavior of rint() on those platforms that have it: round to nearest, break ties by rounding to nearest even. Fixed by leaving just one implementation of rint() in our source tree, and changing its behavior to match the most common native implementations on other platforms. configure.in: Added checks for fenv.h and fesetround(). include/config-win.h: Removed the incorrect implementation of rint() for Windows. include/my_global.h: Added an rint() implementation for platforms that do not have it. mysql-test/r/func_math.result: Added a test case for bug #15936. mysql-test/t/func_math.test: Added a test case for bug #15936. sql/mysqld.cc: Explicitly set the FPU rounding mode with fesetround(). --- configure.in | 4 ++-- include/config-win.h | 9 -------- include/my_global.h | 35 +++++++++++++++++++++++++++-- mysql-test/r/func_math.result | 30 +++++++++++++++++++++++++ mysql-test/t/func_math.test | 20 +++++++++++++++++ sql/mysqld.cc | 51 ++++++++++++++++++++++++------------------- 6 files changed, 113 insertions(+), 36 deletions(-) diff --git a/configure.in b/configure.in index 9591b5bbc5a..8c2c4a9cf79 100644 --- a/configure.in +++ b/configure.in @@ -825,7 +825,7 @@ AC_TYPE_SIZE_T AC_HEADER_DIRENT AC_HEADER_STDC AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS(fcntl.h float.h floatingpoint.h ieeefp.h limits.h \ +AC_CHECK_HEADERS(fcntl.h fenv.h float.h floatingpoint.h ieeefp.h limits.h \ memory.h pwd.h select.h \ stdlib.h stddef.h \ strings.h string.h synch.h sys/mman.h sys/socket.h netinet/in.h arpa/inet.h \ @@ -2060,7 +2060,7 @@ AC_FUNC_UTIME_NULL AC_FUNC_VPRINTF AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \ - fconvert fdatasync finite fpresetsticky fpsetmask fsync ftruncate \ + fconvert fdatasync fesetround finite fpresetsticky fpsetmask fsync ftruncate \ getcwd gethostbyaddr_r gethostbyname_r getpass getpassphrase getpwnam \ getpwuid getrlimit getrusage getwd gmtime_r index initgroups isnan \ localtime_r locking longjmp lrand48 madvise mallinfo memcpy memmove \ diff --git a/include/config-win.h b/include/config-win.h index eba699159c7..ab463a7c142 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -31,7 +31,6 @@ functions */ #include #include -#include /* Because of rint() */ #include #include #include @@ -223,13 +222,6 @@ typedef uint rf_SetTimer; #define inline __inline #endif /* __cplusplus */ -inline double rint(double nr) -{ - double f = floor(nr); - double c = ceil(nr); - return (((c-nr) >= (nr-f)) ? f :c); -} - #ifdef _WIN64 #define ulonglong2double(A) ((double) (ulonglong) (A)) #define my_off_t2double(A) ((double) (my_off_t) (A)) @@ -281,7 +273,6 @@ inline ulonglong double2ulonglong(double d) #define HAVE_FLOAT_H #define HAVE_LIMITS_H #define HAVE_STDDEF_H -#define HAVE_RINT /* defined in this file */ #define NO_FCNTL_NONBLOCK /* No FCNTL */ #define HAVE_ALLOCA #define HAVE_STRPBRK diff --git a/include/my_global.h b/include/my_global.h index 845ae042a42..3f872bfc855 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -484,8 +484,39 @@ typedef unsigned short ushort; #define set_bits(type, bit_count) (sizeof(type)*8 <= (bit_count) ? ~(type) 0 : ((((type) 1) << (bit_count)) - (type) 1)) #define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0]))) #ifndef HAVE_RINT -#define rint(A) floor((A)+(((A) < 0)? -0.5 : 0.5)) -#endif +/** + All integers up to this number can be represented exactly as double precision + values (DBL_MANT_DIG == 53 for IEEE 754 hardware). +*/ +#define MAX_EXACT_INTEGER ((1LL << DBL_MANT_DIG) - 1) + +/** + rint(3) implementation for platforms that do not have it. + Always rounds to the nearest integer with ties being rounded to the nearest + even integer to mimic glibc's rint() behavior in the "round-to-nearest" + FPU mode. Hardware-specific optimizations are possible (frndint on x86). + Unlike this implementation, hardware will also honor the FPU rounding mode. +*/ + +static inline double rint(double x) +{ + double f, i; + f = modf(x, &i); + /* + All doubles with absolute values > MAX_EXACT_INTEGER are even anyway, + no need to check it. + */ + if (x > 0.0) + i += (double) ((f > 0.5) || (f == 0.5 && + i <= (double) MAX_EXACT_INTEGER && + (longlong) i % 2)); + else + i -= (double) ((f < -0.5) || (f == -0.5 && + i >= (double) -MAX_EXACT_INTEGER && + (longlong) i % 2)); + return i; +} +#endif /* HAVE_RINT */ /* Define some general constants */ #ifndef TRUE diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index 0d7adbbba5e..87cfb5b86a5 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -360,4 +360,34 @@ SELECT a DIV 2 FROM t1 UNION SELECT a DIV 2 FROM t1; a DIV 2 0 DROP TABLE t1; +CREATE TABLE t1 (a DOUBLE); +INSERT INTO t1 VALUES (-1.1), (1.1), +(-1.5), (1.5), +(-1.9), (1.9), +(-2.1), (2.1), +(-2.5), (2.5), +(-2.9), (2.9), +# Check numbers with absolute values > 2^53 - 1 +# (see comments for MAX_EXACT_INTEGER) +(-1e16 - 0.5), (1e16 + 0.5), +(-1e16 - 1.5), (1e16 + 1.5); +SELECT a, ROUND(a) FROM t1; +a ROUND(a) +-1.1 -1 +1.1 1 +-1.5 -2 +1.5 2 +-1.9 -2 +1.9 2 +-2.1 -2 +2.1 2 +-2.5 -2 +2.5 2 +-2.9 -3 +2.9 3 +-1e+16 -10000000000000000 +1e+16 10000000000000000 +-1e+16 -10000000000000002 +1e+16 10000000000000002 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index 9f12fdd696e..593cfe90c1b 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -229,5 +229,25 @@ INSERT INTO t1 VALUES ('a'); SELECT a DIV 2 FROM t1 UNION SELECT a DIV 2 FROM t1; DROP TABLE t1; +# +# Bug #15936: "round" differs on Windows to Unix +# + +CREATE TABLE t1 (a DOUBLE); + +INSERT INTO t1 VALUES (-1.1), (1.1), + (-1.5), (1.5), + (-1.9), (1.9), + (-2.1), (2.1), + (-2.5), (2.5), + (-2.9), (2.9), +# Check numbers with absolute values > 2^53 - 1 +# (see comments for MAX_EXACT_INTEGER) + (-1e16 - 0.5), (1e16 + 0.5), + (-1e16 - 1.5), (1e16 + 1.5); + +SELECT a, ROUND(a) FROM t1; + +DROP TABLE t1; --echo End of 5.0 tests diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ca68976d939..7856309b095 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -186,39 +186,44 @@ int initgroups(const char *,unsigned int); #ifdef HAVE_FP_EXCEPT // Fix type conflict typedef fp_except fp_except_t; #endif +#endif /* __FreeBSD__ && HAVE_IEEEFP_H */ +#ifdef HAVE_FENV_H +#include +#endif +#ifdef HAVE_SYS_FPU_H +/* for IRIX to use set_fpc_csr() */ +#include +#endif +inline void setup_fpu() +{ +#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) /* We can't handle floating point exceptions with threads, so disable this on freebsd + Don't fall for overflow, underflow,divide-by-zero or loss of precision */ - -inline void set_proper_floating_point_mode() -{ - /* Don't fall for overflow, underflow,divide-by-zero or loss of precision */ #if defined(__i386__) fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ | FP_X_IMP)); #else - fpsetmask(~(FP_X_INV | FP_X_OFL | FP_X_UFL | FP_X_DZ | - FP_X_IMP)); -#endif -} -#elif defined(__sgi) -/* for IRIX to use set_fpc_csr() */ -#include + fpsetmask(~(FP_X_INV | FP_X_OFL | FP_X_UFL | FP_X_DZ | + FP_X_IMP)); +#endif /* __i386__ */ +#endif /* __FreeBSD__ && HAVE_IEEEFP_H */ -inline void set_proper_floating_point_mode() -{ +#ifdef HAVE_FESETROUND + /* Set FPU rounding mode to "round-to-nearest" */ + fesetround(FE_TONEAREST); +#endif /* HAVE_FESETROUND */ + +#if defined(__sgi) && defined(HAVE_SYS_FPU_H) /* Enable denormalized DOUBLE values support for IRIX */ - { - union fpc_csr n; - n.fc_word = get_fpc_csr(); - n.fc_struct.flush = 0; - set_fpc_csr(n.fc_word); - } + union fpc_csr n; + n.fc_word = get_fpc_csr(); + n.fc_struct.flush = 0; + set_fpc_csr(n.fc_word); +#endif } -#else -#define set_proper_floating_point_mode() -#endif /* __FreeBSD__ && HAVE_IEEEFP_H */ } /* cplusplus */ @@ -3279,7 +3284,7 @@ static int init_server_components() query_cache_init(); query_cache_resize(query_cache_size); randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2); - set_proper_floating_point_mode(); + setup_fpu(); init_thr_lock(); #ifdef HAVE_REPLICATION init_slave_list(); -- cgit v1.2.1 From 990bca3b7716909b50d46558f4fdcf5351542782 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 24 Feb 2009 10:15:21 +0100 Subject: Bug#41110: crash with handler command when used concurrently with alter table Bug#41112: crash in mysql_ha_close_table/get_lock_data with alter table The problem is that the server wasn't handling robustly failures to re-open a table during a HANDLER .. READ statement. If the table needed to be re-opened due to it's storage engine being altered to one that doesn't support HANDLER, a reference (dangling pointer) to a closed table could be left in place and accessed in later attempts to fetch from the table using the handler. Also, if the server failed to set a error message if the re-open failed. These problems could lead to server crashes or hangs. The solution is to remove any references to a closed table and to set a error if reopening a table during a HANDLER .. READ statement fails. There is no test case in this change set as the test depends on a testing feature only available on 5.1 and later. sql/sql_handler.cc: Remove redundant reopen check. Set errors even if reopening table. Reset TABLE_LIST::table reference when the table is closed. --- sql/sql_handler.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 822f2b2c419..f58a4ec4921 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -151,6 +151,9 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables) } VOID(pthread_mutex_unlock(&LOCK_open)); } + + /* Mark table as closed, ready for re-open if necessary. */ + tables->table= NULL; } /* @@ -168,8 +171,7 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables) 'reopen' is set when a handler table is to be re-opened. In this case, 'tables' is the pointer to the hashed TABLE_LIST object which has been saved on the original open. - 'reopen' is also used to suppress the sending of an 'ok' message or - error messages. + 'reopen' is also used to suppress the sending of an 'ok' message. RETURN FALSE OK @@ -205,8 +207,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) strlen(tables->alias) + 1)) { DBUG_PRINT("info",("duplicate '%s'", tables->alias)); - if (! reopen) - my_error(ER_NONUNIQ_TABLE, MYF(0), tables->alias); + my_error(ER_NONUNIQ_TABLE, MYF(0), tables->alias); goto err; } } @@ -251,8 +252,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) /* There can be only one table in '*tables'. */ if (! (tables->table->file->table_flags() & HA_CAN_SQL_HANDLER)) { - if (! reopen) - my_error(ER_ILLEGAL_HA, MYF(0), tables->alias); + my_error(ER_ILLEGAL_HA, MYF(0), tables->alias); goto err; } @@ -464,8 +464,7 @@ retry: if (need_reopen) { - mysql_ha_close_table(thd, tables); - hash_tables->table= NULL; + mysql_ha_close_table(thd, hash_tables); /* The lock might have been aborted, we need to manually reset thd->some_tables_deleted because handler's tables are closed -- cgit v1.2.1 From 83aa3e94a686c11b0a95ee47610d85cad8b7120b Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Tue, 24 Feb 2009 12:05:37 +0200 Subject: Bug#39370: wrong output for error code 153 Add all HA error numbers and descriptions to perror. Add reminder to header. This is already fixed in smarter ways in future codebases, and this codebase is unlikely to change, since new development is forbidden here. --- extra/perror.c | 11 +++++++++++ include/my_base.h | 1 + 2 files changed, 12 insertions(+) diff --git a/extra/perror.c b/extra/perror.c index 37d6b45c8dd..ba638aca819 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -97,6 +97,17 @@ static HA_ERRORS ha_errlist[]= { 150,"Foreign key constraint is incorrectly formed"}, { 151,"Cannot add a child row"}, { 152,"Cannot delete a parent row"}, + { 153,"No savepoint with that name"}, + { 154,"Non unique key block size"}, + { 155,"The table does not exist in engine"}, + { 156,"The table existed in storage engine"}, + { 157,"Could not connect to storage engine"}, + { 158,"NULLs are not supported in spatial index"}, + { 159,"The table changed in storage engine"}, + { 160,"The table changed in storage engine"}, + { 161,"The table is not writable"}, + { 162,"Failed to get the next autoinc value"}, + { 163,"Failed to set the row autoinc value"}, { -30999, "DB_INCOMPLETE: Sync didn't finish"}, { -30998, "DB_KEYEMPTY: Key/data deleted or never created"}, { -30997, "DB_KEYEXIST: The key/data pair already exists"}, diff --git a/include/my_base.h b/include/my_base.h index 9240b01a9f1..e45a73d68ed 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -377,6 +377,7 @@ enum ha_base_keytype { #define HA_ERR_TABLE_READONLY 161 /* The table is not writable */ #define HA_ERR_AUTOINC_READ_FAILED 162/* Failed to get the next autoinc value */ #define HA_ERR_AUTOINC_ERANGE 163 /* Failed to set the row autoinc value */ +/* You must also add numbers and description to extra/perror.c ! */ #define HA_ERR_LAST 163 /*Copy last error nr.*/ /* Add error numbers before HA_ERR_LAST and change it accordingly. */ -- cgit v1.2.1 From a201577dd89d8eddef18dccab0971e5854d7df67 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 24 Feb 2009 15:06:28 +0200 Subject: Bug #31060: MySQL CLI parser bug 2 There was a problem when a DELIMITER COMMAND is not the first command on the line. I this case an extra line feed was added to the glob buffer and this was causing subsequent attempts to enter this delimiter to fail. Fixed by not adding a new line to the glob buffer if the command being added is a DELIMITER client/mysql.cc: Bug #31060: Don't add a new line if DELIMTER is added to the glob buffer mysql-test/r/mysql.result: Bug #31060: test case mysql-test/t/mysql.test: Bug #31060: test case --- client/mysql.cc | 16 +++++++++++++++- mysql-test/r/mysql.result | 4 ++++ mysql-test/t/mysql.test | 17 +++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/client/mysql.cc b/client/mysql.cc index d1d36d79565..1a025345190 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2222,8 +2222,22 @@ static bool add_line(String &buffer,char *line,char *in_string, } if (out != line || !buffer.is_empty()) { - *out++='\n'; uint length=(uint) (out-line); + + if (length < 9 || + my_strnncoll (charset_info, + (uchar *)line, 9, (const uchar *) "delimiter", 9)) + { + /* + Don't add a new line in case there's a DELIMITER command to be + added to the glob buffer (e.g. on processing a line like + ";DELIMITER ") : similar to how a new line is + not added in the case when the DELIMITER is the first command + entered with an empty glob buffer. + */ + *out++='\n'; + length++; + } if (buffer.length() + length >= buffer.alloced_length()) buffer.realloc(buffer.length()+length+IO_SIZE); if ((!*ml_comment || preserve_comments) && buffer.append(line, length)) diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 9bad3b9f791..10537f6da16 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -188,4 +188,8 @@ delimiter 2 @z:='1' @z=database() 1 NULL +1 +1 +1 +1 End of 5.0 tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 68a01a309d4..594d10e46a5 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -314,4 +314,21 @@ remove_file $MYSQLTEST_VARDIR/tmp/bug38158.sql; # --exec $MYSQL -e "select @z:='1',@z=database()" + +# +# Bug #31060: MySQL CLI parser bug 2 +# + +--write_file $MYSQLTEST_VARDIR/tmp/bug31060.sql +;DELIMITER DELIMITER +; +SELECT 1DELIMITER +DELIMITER ; +SELECT 1; +EOF + +--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug31060.sql 2>&1 + +remove_file $MYSQLTEST_VARDIR/tmp/bug31060.sql; + --echo End of 5.0 tests -- cgit v1.2.1 From 1e1f4c221cedc5a2fdb236f327cc75c953e8e753 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Tue, 24 Feb 2009 16:17:34 +0200 Subject: fixing compilation warning and adding flush logs to test of bug#37313 --- mysql-test/r/mysqlbinlog.result | 1 + mysql-test/t/mysqlbinlog.test | 1 + sql/log_event.cc | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index b5ac22437cd..dbbf49e7920 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -364,6 +364,7 @@ drop table t1; shell> mysqlbinlog std_data/corrupt-relay-bin.000624 > var/tmp/bug31793.sql set @@global.server_id= 4294967295; reset master; +flush logs; select (@a:=load_file("MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog")) is not null; diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index cf4bc1523df..d88ca7d0504 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -262,6 +262,7 @@ let $s_id_max=`select (1 << 32) - 1`; eval set @@global.server_id= $s_id_max; reset master; +flush logs; --exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select diff --git a/sql/log_event.cc b/sql/log_event.cc index 90805877502..b74b38e55b2 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -976,7 +976,7 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info) fputc('#', file); print_timestamp(file); - fprintf(file, " server id %lu end_log_pos %s ", server_id, + fprintf(file, " server id %lu end_log_pos %s ", (ulong) server_id, llstr(log_pos,llbuff)); /* mysqlbinlog --hexdump */ -- cgit v1.2.1 From 4a5393e4b1bb3f70d28b84ac252b39a7e1fbc591 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Wed, 25 Feb 2009 10:36:11 +0200 Subject: Fixed a build failure on Ubuntu 8.10 introduced by the patch for bug #15936. On some platforms fenv.h may #undef the min/max macros defined in my_global.h. Fixed by moving the #include directive for fenv.h from mysqld.cc to my_global.h before definitions for min/max. include/my_global.h: Moved #include from mysqld.cc. sql/mysqld.cc: Moved #include to my_global.h. --- include/my_global.h | 3 +++ sql/mysqld.cc | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index 3f872bfc855..f5a3016bb1e 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -324,6 +324,9 @@ C_MODE_END #ifdef HAVE_FLOAT_H #include #endif +#ifdef HAVE_FENV_H +#include /* For fesetround() */ +#endif #ifdef HAVE_SYS_TYPES_H #include diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7856309b095..fcde4e2b626 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -187,9 +187,6 @@ int initgroups(const char *,unsigned int); typedef fp_except fp_except_t; #endif #endif /* __FreeBSD__ && HAVE_IEEEFP_H */ -#ifdef HAVE_FENV_H -#include -#endif #ifdef HAVE_SYS_FPU_H /* for IRIX to use set_fpc_csr() */ #include -- cgit v1.2.1 From b0a8db577b868960e2ba47cd75a737c3a3542fab Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 25 Feb 2009 14:20:20 +0400 Subject: Bug#30305 Create routine in wrong context in SHOW PRIVILEGES Changed context of Create routine to Databases. mysql-test/r/grant.result: result fix mysql-test/r/sp.result: result fix sql/sql_show.cc: Changed context of Create routine to Databases. --- mysql-test/r/grant.result | 2 +- mysql-test/r/sp.result | 4 ++-- sql/sql_show.cc | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 97945a702d8..7a5b0520f7c 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -457,7 +457,7 @@ Privilege Context Comment Alter Tables To alter the table Alter routine Functions,Procedures To alter or drop stored functions/procedures Create Databases,Tables,Indexes To create new databases and tables -Create routine Functions,Procedures To use CREATE FUNCTION/PROCEDURE +Create routine Databases To use CREATE FUNCTION/PROCEDURE Create temporary tables Databases To use CREATE TEMPORARY TABLE Create view Tables To create new views Create user Server Admin To create new users diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index bfa2f51e4fc..84a4166a45d 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -2475,7 +2475,7 @@ Privilege Context Comment Alter Tables To alter the table Alter routine Functions,Procedures To alter or drop stored functions/procedures Create Databases,Tables,Indexes To create new databases and tables -Create routine Functions,Procedures To use CREATE FUNCTION/PROCEDURE +Create routine Databases To use CREATE FUNCTION/PROCEDURE Create temporary tables Databases To use CREATE TEMPORARY TABLE Create view Tables To create new views Create user Server Admin To create new users @@ -2527,7 +2527,7 @@ Privilege Context Comment Alter Tables To alter the table Alter routine Functions,Procedures To alter or drop stored functions/procedures Create Databases,Tables,Indexes To create new databases and tables -Create routine Functions,Procedures To use CREATE FUNCTION/PROCEDURE +Create routine Databases To use CREATE FUNCTION/PROCEDURE Create temporary tables Databases To use CREATE TEMPORARY TABLE Create view Tables To create new views Create user Server Admin To create new users diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 19155eec06b..50bbdeb2771 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -106,7 +106,7 @@ static struct show_privileges_st sys_privileges[]= {"Alter", "Tables", "To alter the table"}, {"Alter routine", "Functions,Procedures", "To alter or drop stored functions/procedures"}, {"Create", "Databases,Tables,Indexes", "To create new databases and tables"}, - {"Create routine","Functions,Procedures","To use CREATE FUNCTION/PROCEDURE"}, + {"Create routine","Databases","To use CREATE FUNCTION/PROCEDURE"}, {"Create temporary tables","Databases","To use CREATE TEMPORARY TABLE"}, {"Create view", "Tables", "To create new views"}, {"Create user", "Server Admin", "To create new users"}, -- cgit v1.2.1 From ff27f3a41694374684cf57ad1b776004e8eb2559 Mon Sep 17 00:00:00 2001 From: "Bernt M. Johnsen" Date: Wed, 25 Feb 2009 11:37:30 +0100 Subject: Prepare for push of BUG#43111 --- mysql-test/r/ps.result | 2 +- mysql-test/t/ps.test | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 09deaf2f322..d3fbbf0d538 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -235,7 +235,7 @@ execute stmt1; prepare stmt1 from "insert into t1 select i from t1"; execute stmt1; execute stmt1; -prepare stmt1 from "select * from t1 into outfile 'f1.txt'"; +prepare stmt1 from "select * from t1 into outfile '/tmp/f1.txt'"; execute stmt1; deallocate prepare stmt1; drop table t1; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 6c3f98f6a1a..d9e593fd76f 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -228,6 +228,10 @@ drop table t1; # statements or are correctly created and deleted on each execute # +--let $outfile=$MYSQLTEST_VARDIR/tmp/f1.txt +--error 0,1 +--remove_file $outfile + prepare stmt1 from "select 1 into @var"; execute stmt1; execute stmt1; @@ -238,11 +242,14 @@ execute stmt1; prepare stmt1 from "insert into t1 select i from t1"; execute stmt1; execute stmt1; -prepare stmt1 from "select * from t1 into outfile 'f1.txt'"; +--replace_result $MYSQLTEST_VARDIR +eval prepare stmt1 from "select * from t1 into outfile '$outfile'"; execute stmt1; deallocate prepare stmt1; drop table t1; +--remove_file $outfile + # # BUG#5242 "Prepared statement names are case sensitive" # -- cgit v1.2.1 From 3eea4552de2e5e18c6d9fdff71e73f035459c8e3 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 25 Feb 2009 15:44:50 +0400 Subject: Bug#40345 MySQLDump prefixes view name with database name when view references other db print compact view name if the view belongs to the current database mysql-test/r/information_schema_db.result: result fix mysql-test/r/mysqldump.result: result fix mysql-test/r/view_grant.result: result fix sql/sql_show.cc: print compact view name if the view belongs to the current database --- mysql-test/r/information_schema_db.result | 2 +- mysql-test/r/mysqldump.result | 2 +- mysql-test/r/view_grant.result | 4 ++-- sql/sql_show.cc | 18 +++++++++++------- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result index b9c3358f47e..67c9921e1ca 100644 --- a/mysql-test/r/information_schema_db.result +++ b/mysql-test/r/information_schema_db.result @@ -188,7 +188,7 @@ Field Type Null Key Default Extra f1 char(4) YES NULL show create view v2; View Create View -v2 CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_2`@`localhost` SQL SECURITY DEFINER VIEW `test`.`v2` AS select `v1`.`f1` AS `f1` from `testdb_1`.`v1` +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_2`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `v1`.`f1` AS `f1` from `testdb_1`.`v1` show create view testdb_1.v1; ERROR 42000: SHOW VIEW command denied to user 'testdb_2'@'localhost' for table 'v1' select table_name from information_schema.columns a diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index c612f6c5073..49430a5c62d 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -3246,7 +3246,7 @@ USE `mysqldump_views`; /*!50001 DROP TABLE `nasishnasifu`*/; /*!50001 CREATE ALGORITHM=UNDEFINED */ /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ -/*!50001 VIEW `mysqldump_views`.`nasishnasifu` AS select `mysqldump_tables`.`basetable`.`id` AS `id` from `mysqldump_tables`.`basetable` */; +/*!50001 VIEW `nasishnasifu` AS select `mysqldump_tables`.`basetable`.`id` AS `id` from `mysqldump_tables`.`basetable` */; drop view nasishnasifu; drop database mysqldump_views; drop table mysqldump_tables.basetable; diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result index 53ad8642ba4..2f8462045ca 100644 --- a/mysql-test/r/view_grant.result +++ b/mysql-test/r/view_grant.result @@ -26,7 +26,7 @@ create view v2 as select * from mysqltest.t2; ERROR 42000: ANY command denied to user 'mysqltest_1'@'localhost' for table 't2' show create view v1; View Create View -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_1`@`localhost` SQL SECURITY DEFINER VIEW `test`.`v1` AS select `mysqltest`.`t1`.`a` AS `a`,`mysqltest`.`t1`.`b` AS `b` from `mysqltest`.`t1` +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_1`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `mysqltest`.`t1`.`a` AS `a`,`mysqltest`.`t1`.`b` AS `b` from `mysqltest`.`t1` grant create view,drop,select on test.* to mysqltest_1@localhost; use test; alter view v1 as select * from mysqltest.t1; @@ -307,7 +307,7 @@ grant create view,select on test.* to mysqltest_1@localhost; create view v1 as select * from mysqltest.t1; show create view v1; View Create View -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_1`@`localhost` SQL SECURITY DEFINER VIEW `test`.`v1` AS select `mysqltest`.`t1`.`a` AS `a`,`mysqltest`.`t1`.`b` AS `b` from `mysqltest`.`t1` +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_1`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `mysqltest`.`t1`.`a` AS `a`,`mysqltest`.`t1`.`b` AS `b` from `mysqltest`.`t1` revoke select on mysqltest.t1 from mysqltest_1@localhost; select * from v1; ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 50bbdeb2771..a3ccf770a3c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1232,21 +1232,25 @@ void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user, static int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff) { + my_bool compact_view_name= TRUE; my_bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL | MODE_ORACLE | MODE_MSSQL | MODE_DB2 | MODE_MAXDB | MODE_ANSI)) != 0; - /* - Compact output format for view can be used - - if user has db of this view as current db - - if this view only references table inside it's own db - */ + if (!thd->db || strcmp(thd->db, table->view_db.str)) - table->compact_view_format= FALSE; + /* + print compact view name if the view belongs to the current database + */ + compact_view_name= table->compact_view_format= FALSE; else { + /* + Compact output format for view body can be used + if this view only references table inside it's own db + */ TABLE_LIST *tbl; table->compact_view_format= TRUE; for (tbl= thd->lex->query_tables; @@ -1267,7 +1271,7 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff) view_store_options(thd, table, buff); } buff->append(STRING_WITH_LEN("VIEW ")); - if (!table->compact_view_format) + if (!compact_view_name) { append_identifier(thd, buff, table->view_db.str, table->view_db.length); buff->append('.'); -- cgit v1.2.1 From b3089c080d7d01ff552d97c2d01ea5a948561e26 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 25 Feb 2009 16:57:49 +0100 Subject: Bug#43082: mysqld 32 bit cannot use big buffers due to 2GB usermode address space limit. Fix: use /LARGEADDRESSAWARE link option when linking 32 bit executables --- CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae069498da1..f66453ef492 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,7 +114,13 @@ IF(MSVC) STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS_INIT ${CMAKE_CXX_FLAGS_INIT}) STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS_DEBUG_INIT ${CMAKE_CXX_FLAGS_DEBUG_INIT}) - + + # Mark 32 bit executables large address aware so they can + # use > 2GB address space + IF(CMAKE_SIZEOF_VOID_P MATCHES 4) + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE") + ENDIF(CMAKE_SIZEOF_VOID_P MATCHES 4) + # Disable automatic manifest generation. STRING(REPLACE "/MANIFEST" "/MANIFEST:NO" CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}) -- cgit v1.2.1 From 877fedaacdaa743159cf5619c15aff1e5f7274e9 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Thu, 26 Feb 2009 12:34:15 +0400 Subject: Fix for bug#19829:make test Failed in mysql_client_test *with --with-charset=utf8* Problem: wrong LONG TEXT field length is sent to a client when multibyte server character set used. Fix: always limit field length sent to a client to 2^32, as we store it in 4 byte slot. Note: mysql_client_test changed accordingly. sql/protocol.cc: Fix for bug#19829:make test Failed in mysql_client_test *with --with-charset=utf8* - limit field length sent to client to UINT_MAX32 as it may exceeds 32 bit slot for LONG TEXT fields if thd_charset->mbmaxlen > 1. tests/mysql_client_test.c: Fix for bug#19829:make test Failed in mysql_client_test *with --with-charset=utf8* - checking field members have in mind that field length is limited to UINT_MAX32. --- sql/protocol.cc | 22 ++++++++++++++++------ tests/mysql_client_test.c | 15 +++++++++------ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/sql/protocol.cc b/sql/protocol.cc index ff58d96f59b..2309bac88a9 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -616,7 +616,8 @@ bool Protocol::send_fields(List *list, uint flags) else { /* With conversion */ - uint max_char_len; + ulonglong max_length; + uint32 field_length; int2store(pos, thd_charset->number); /* For TEXT/BLOB columns, field_length describes the maximum data @@ -627,12 +628,21 @@ bool Protocol::send_fields(List *list, uint flags) char_count * mbmaxlen, where character count is taken from the definition of the column. In other words, the maximum number of characters here is limited by the column definition. + + When one has a LONG TEXT column with a single-byte + character set, and the connection character set is multi-byte, the + client may get fields longer than UINT_MAX32, due to + -> conversion. + In that case column max length does not fit into the 4 bytes + reserved for it in the protocol. */ - max_char_len= (field.type >= (int) MYSQL_TYPE_TINY_BLOB && - field.type <= (int) MYSQL_TYPE_BLOB) ? - field.length / item->collation.collation->mbminlen : - field.length / item->collation.collation->mbmaxlen; - int4store(pos+2, max_char_len * thd_charset->mbmaxlen); + max_length= (field.type >= MYSQL_TYPE_TINY_BLOB && + field.type <= MYSQL_TYPE_BLOB) ? + field.length / item->collation.collation->mbminlen : + field.length / item->collation.collation->mbmaxlen; + max_length*= thd_charset->mbmaxlen; + field_length= (max_length > UINT_MAX32) ? UINT_MAX32 : max_length; + int4store(pos + 2, field_length); } pos[6]= field.type; int2store(pos+7,field.flags); diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index f848e93a5c6..7df84c600c9 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -714,6 +714,7 @@ static void do_verify_prepare_field(MYSQL_RES *result, { MYSQL_FIELD *field; CHARSET_INFO *cs; + ulonglong expected_field_length; if (!(field= mysql_fetch_field_direct(result, no))) { @@ -722,6 +723,8 @@ static void do_verify_prepare_field(MYSQL_RES *result, } cs= get_charset(field->charsetnr, 0); DIE_UNLESS(cs); + if ((expected_field_length= length * cs->mbmaxlen) > UINT_MAX32) + expected_field_length= UINT_MAX32; if (!opt_silent) { fprintf(stdout, "\n field[%d]:", no); @@ -736,8 +739,8 @@ static void do_verify_prepare_field(MYSQL_RES *result, fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)", field->org_table, org_table); fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db); - fprintf(stdout, "\n length :`%lu`\t(expected: `%lu`)", - field->length, length * cs->mbmaxlen); + fprintf(stdout, "\n length :`%lu`\t(expected: `%llu`)", + field->length, expected_field_length); fprintf(stdout, "\n maxlength:`%ld`", field->max_length); fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr); fprintf(stdout, "\n default :`%s`\t(expected: `%s`)", @@ -773,11 +776,11 @@ static void do_verify_prepare_field(MYSQL_RES *result, as utf8. Field length is calculated as number of characters * maximum number of bytes a character can occupy. */ - if (length && field->length != length * cs->mbmaxlen) + if (length && (field->length != expected_field_length)) { - fprintf(stderr, "Expected field length: %d, got length: %d\n", - (int) (length * cs->mbmaxlen), (int) field->length); - DIE_UNLESS(field->length == length * cs->mbmaxlen); + fprintf(stderr, "Expected field length: %llu, got length: %lu\n", + expected_field_length, field->length); + DIE_UNLESS(field->length == expected_field_length); } if (def) DIE_UNLESS(strcmp(field->def, def) == 0); -- cgit v1.2.1 From b88fefba2a65b36b2eb03706c938da69a56cce09 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Thu, 26 Feb 2009 10:57:33 +0200 Subject: Bug#41893: main.variables mysql-test fails if new variable like '%alloc%' is added. Started fix in 5.0 as the same issue is here. Revising queries used given what appears to be the scope of this test to only select the manipulated variables. Added tests for values that are / are not multiples of 1024 to test rounding / constraints. This behavior is not currently documented (docs bug has been opened) --- mysql-test/r/variables.result | 46 +++++++++++++++++++++++++++++++++++++------ mysql-test/t/variables.test | 38 ++++++++++++++++++++++++++++++----- 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 376a8ffa38e..04ccf3d688c 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -236,32 +236,66 @@ set @@rand_seed1=10000000,@@rand_seed2=1000000; select ROUND(RAND(),5); ROUND(RAND(),5) 0.02887 -show variables like '%alloc%'; + +==+ Testing %alloc% system variables +== +==+ NOTE: These values *must* be a multiple of 1024 +== +==+ Other values will be rounded down to nearest multiple +== + +==+ Show initial values +== +SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size', +'query_alloc_block_size', 'query_prealloc_size', +'transaction_alloc_block_size', 'transaction_prealloc_size'); Variable_name Value query_alloc_block_size 8192 query_prealloc_size 8192 range_alloc_block_size 4096 transaction_alloc_block_size 8192 transaction_prealloc_size 4096 -set @@range_alloc_block_size=1024*16; +==+ Manipulate variable values += +Testing values that are multiples of 1024 +set @@range_alloc_block_size=1024*15+1024; +set @@query_alloc_block_size=1024*15+1024*2; +set @@query_prealloc_size=1024*18-1024; +set @@transaction_alloc_block_size=1024*21-1024*1; +set @@transaction_prealloc_size=1024*21-2048; +==+ Check manipulated values ==+ +SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size', +'query_alloc_block_size', 'query_prealloc_size', +'transaction_alloc_block_size', 'transaction_prealloc_size'); +Variable_name Value +query_alloc_block_size 17408 +query_prealloc_size 17408 +range_alloc_block_size 16384 +transaction_alloc_block_size 20480 +transaction_prealloc_size 19456 +==+ Manipulate variable values +== +Testing values that are not 1024 multiples +set @@range_alloc_block_size=1024*16+1023; set @@query_alloc_block_size=1024*17+2; -set @@query_prealloc_size=1024*18; +set @@query_prealloc_size=1024*18-1023; set @@transaction_alloc_block_size=1024*20-1; set @@transaction_prealloc_size=1024*21-1; select @@query_alloc_block_size; @@query_alloc_block_size 17408 -show variables like '%alloc%'; +==+ Check manipulated values ==+ +SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size', +'query_alloc_block_size', 'query_prealloc_size', +'transaction_alloc_block_size', 'transaction_prealloc_size'); Variable_name Value query_alloc_block_size 17408 -query_prealloc_size 18432 +query_prealloc_size 17408 range_alloc_block_size 16384 transaction_alloc_block_size 19456 transaction_prealloc_size 20480 +==+ Set values back to the default values +== set @@range_alloc_block_size=default; set @@query_alloc_block_size=default, @@query_prealloc_size=default; set transaction_alloc_block_size=default, @@transaction_prealloc_size=default; -show variables like '%alloc%'; +==+ Check the values not that they are reset +== +SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size', +'query_alloc_block_size', 'query_prealloc_size', +'transaction_alloc_block_size', 'transaction_prealloc_size'); Variable_name Value query_alloc_block_size 8192 query_prealloc_size 8192 diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 60254ad9a1d..173be9d87c6 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -150,18 +150,46 @@ select @@timestamp>0; set @@rand_seed1=10000000,@@rand_seed2=1000000; select ROUND(RAND(),5); -show variables like '%alloc%'; -set @@range_alloc_block_size=1024*16; +--echo +--echo ==+ Testing %alloc% system variables +== +--echo ==+ NOTE: These values *must* be a multiple of 1024 +== +--echo ==+ Other values will be rounded down to nearest multiple +== +--echo +--echo ==+ Show initial values +== +SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size', +'query_alloc_block_size', 'query_prealloc_size', +'transaction_alloc_block_size', 'transaction_prealloc_size'); +--echo ==+ Manipulate variable values += +--echo Testing values that are multiples of 1024 +set @@range_alloc_block_size=1024*15+1024; +set @@query_alloc_block_size=1024*15+1024*2; +set @@query_prealloc_size=1024*18-1024; +set @@transaction_alloc_block_size=1024*21-1024*1; +set @@transaction_prealloc_size=1024*21-2048; +--echo ==+ Check manipulated values ==+ +SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size', +'query_alloc_block_size', 'query_prealloc_size', +'transaction_alloc_block_size', 'transaction_prealloc_size'); +--echo ==+ Manipulate variable values +== +--echo Testing values that are not 1024 multiples +set @@range_alloc_block_size=1024*16+1023; set @@query_alloc_block_size=1024*17+2; -set @@query_prealloc_size=1024*18; +set @@query_prealloc_size=1024*18-1023; set @@transaction_alloc_block_size=1024*20-1; set @@transaction_prealloc_size=1024*21-1; select @@query_alloc_block_size; -show variables like '%alloc%'; +--echo ==+ Check manipulated values ==+ +SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size', +'query_alloc_block_size', 'query_prealloc_size', +'transaction_alloc_block_size', 'transaction_prealloc_size'); +--echo ==+ Set values back to the default values +== set @@range_alloc_block_size=default; set @@query_alloc_block_size=default, @@query_prealloc_size=default; set transaction_alloc_block_size=default, @@transaction_prealloc_size=default; -show variables like '%alloc%'; +--echo ==+ Check the values not that they are reset +== +SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size', +'query_alloc_block_size', 'query_prealloc_size', +'transaction_alloc_block_size', 'transaction_prealloc_size'); # # Bug #10904 Illegal mix of collations between -- cgit v1.2.1 From 1003f3eeed895374f7ddcdb8540038a115a45829 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Thu, 26 Feb 2009 18:00:47 +0200 Subject: Bug#41893 - main.variables mysql-test fails if new variable like '%alloc%' is added. Fixed a typo in the bug fix patch. --- mysql-test/t/variables.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 173be9d87c6..424776dfda4 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -186,7 +186,7 @@ SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size', set @@range_alloc_block_size=default; set @@query_alloc_block_size=default, @@query_prealloc_size=default; set transaction_alloc_block_size=default, @@transaction_prealloc_size=default; ---echo ==+ Check the values not that they are reset +== +--echo ==+ Check the values now that they are reset +== SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size', 'query_alloc_block_size', 'query_prealloc_size', 'transaction_alloc_block_size', 'transaction_prealloc_size'); -- cgit v1.2.1 From 6f026345388911f30956c07a7a8d5e89e3464195 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 26 Feb 2009 19:00:44 +0200 Subject: Bug #41354: Access control is bypassed when all columns of a view are selected by * wildcard Backported a part of the fix for 36086 to 5.0 mysql-test/r/view_grant.result: Bug #41354: test case mysql-test/t/view_grant.test: Bug #41354: test case sql/sql_acl.cc: Bug #41354: return table error when no access and * sql/sql_base.cc: Bug #41354: backported the check in bug 36086 to 5.0 --- mysql-test/r/view_grant.result | 26 ++++++++++++++++++++++++++ mysql-test/t/view_grant.test | 40 ++++++++++++++++++++++++++++++++++++++++ sql/sql_acl.cc | 28 ++++++++++++++++++++++------ sql/sql_base.cc | 2 +- 4 files changed, 89 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result index 2f8462045ca..1df8ed335a7 100644 --- a/mysql-test/r/view_grant.result +++ b/mysql-test/r/view_grant.result @@ -919,4 +919,30 @@ c4 DROP DATABASE mysqltest1; DROP DATABASE mysqltest2; DROP USER mysqltest_u1@localhost; +CREATE DATABASE db1; +USE db1; +CREATE TABLE t1(f1 INT, f2 INT); +CREATE VIEW v1 AS SELECT f1, f2 FROM t1; +GRANT SELECT (f1) ON t1 TO foo; +GRANT SELECT (f1) ON v1 TO foo; +USE db1; +SELECT f1 FROM t1; +f1 +SELECT f2 FROM t1; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'f2' in table 't1' +SELECT * FROM t1; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't1' +SELECT f1 FROM v1; +f1 +SELECT f2 FROM v1; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'f2' in table 'v1' +SELECT * FROM v1; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 'v1' +USE test; +REVOKE SELECT (f1) ON db1.t1 FROM foo; +REVOKE SELECT (f1) ON db1.v1 FROM foo; +DROP USER foo; +DROP VIEW db1.v1; +DROP TABLE db1.t1; +DROP DATABASE db1; End of 5.0 tests. diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test index be9daacec4f..c8b31f711b5 100644 --- a/mysql-test/t/view_grant.test +++ b/mysql-test/t/view_grant.test @@ -1185,4 +1185,44 @@ DROP DATABASE mysqltest1; DROP DATABASE mysqltest2; DROP USER mysqltest_u1@localhost; + +# +# Bug #41354: Access control is bypassed when all columns of a view are +# selected by * wildcard + +CREATE DATABASE db1; +USE db1; +CREATE TABLE t1(f1 INT, f2 INT); +CREATE VIEW v1 AS SELECT f1, f2 FROM t1; + +GRANT SELECT (f1) ON t1 TO foo; +GRANT SELECT (f1) ON v1 TO foo; + +connect (addconfoo, localhost, foo,,); +connection addconfoo; +USE db1; + + +SELECT f1 FROM t1; +--error ER_COLUMNACCESS_DENIED_ERROR +SELECT f2 FROM t1; +--error ER_TABLEACCESS_DENIED_ERROR +SELECT * FROM t1; + +SELECT f1 FROM v1; +--error ER_COLUMNACCESS_DENIED_ERROR +SELECT f2 FROM v1; +--error ER_TABLEACCESS_DENIED_ERROR +SELECT * FROM v1; + +connection default; +USE test; +disconnect addconfoo; +REVOKE SELECT (f1) ON db1.t1 FROM foo; +REVOKE SELECT (f1) ON db1.v1 FROM foo; +DROP USER foo; +DROP VIEW db1.v1; +DROP TABLE db1.t1; +DROP DATABASE db1; + --echo End of 5.0 tests. diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 22135d376fe..c59c42d512a 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3866,6 +3866,11 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg, Security_context *sctx= thd->security_ctx; ulong want_access= want_access_arg; const char *table_name= NULL; + /* + Flag that gets set if privilege checking has to be performed on column + level. + */ + bool using_column_privileges= FALSE; if (grant_option) { @@ -3909,6 +3914,8 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg, GRANT_COLUMN *grant_column= column_hash_search(grant_table, field_name, (uint) strlen(field_name)); + if (grant_column) + using_column_privileges= TRUE; if (!grant_column || (~grant_column->rights & want_access)) goto err; } @@ -3924,12 +3931,21 @@ err: char command[128]; get_privilege_desc(command, sizeof(command), want_access); - my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), - command, - sctx->priv_user, - sctx->host_or_ip, - fields->name(), - table_name); + /* + Do not give an error message listing a column name unless the user has + privilege to see all columns. + */ + if (using_column_privileges) + my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), + command, sctx->priv_user, + sctx->host_or_ip, table_name); + else + my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), + command, + sctx->priv_user, + sctx->host_or_ip, + fields->name(), + table_name); return 1; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 881c6a421e8..781bbc0a553 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5479,7 +5479,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Ensure that we have access rights to all fields to be inserted. */ - if (!((table && (table->grant.privilege & SELECT_ACL) || + if (!((table && !tables->view && (table->grant.privilege & SELECT_ACL) || tables->view && (tables->grant.privilege & SELECT_ACL))) && !any_privileges) { -- cgit v1.2.1 From cc5faa28825f873cf7458f8e4e557ed974f3289e Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 27 Feb 2009 09:41:39 +0200 Subject: addendum to the fix for bug #41354: fixed the error returned by SELECT * --- mysql-test/r/grant2.result | 2 +- mysql-test/t/grant2.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 95748c89103..698e602e2e6 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -433,7 +433,7 @@ USE db1; SELECT c FROM t2; ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2' SELECT * FROM t2; -ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2' +ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for table 't2' SELECT * FROM t1 JOIN t2 USING (b); ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2' USE test; diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index 8f83c365170..2393bb1c6d8 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -615,7 +615,7 @@ connection conn1; USE db1; --error ER_COLUMNACCESS_DENIED_ERROR SELECT c FROM t2; ---error ER_COLUMNACCESS_DENIED_ERROR +--error ER_TABLEACCESS_DENIED_ERROR SELECT * FROM t2; --error ER_COLUMNACCESS_DENIED_ERROR SELECT * FROM t1 JOIN t2 USING (b); -- cgit v1.2.1 From f803b81daa2a542f0689cdc5a1c0e9799a7ecbf5 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Fri, 27 Feb 2009 15:00:49 +0200 Subject: Bug#41893: Removal of trailing space noise causing Pushbuild failure. --- mysql-test/r/variables.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 04ccf3d688c..fbec38c9a9f 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -292,7 +292,7 @@ transaction_prealloc_size 20480 set @@range_alloc_block_size=default; set @@query_alloc_block_size=default, @@query_prealloc_size=default; set transaction_alloc_block_size=default, @@transaction_prealloc_size=default; -==+ Check the values not that they are reset +== +==+ Check the values now that they are reset +== SHOW VARIABLES WHERE variable_name IN ('range_alloc_block_size', 'query_alloc_block_size', 'query_prealloc_size', 'transaction_alloc_block_size', 'transaction_prealloc_size'); -- cgit v1.2.1 From baf8838530c300cf6264b00ee83613d9754b56ee Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 27 Feb 2009 15:25:06 +0200 Subject: Bug #41610: key_infix_len can be overwritten causing some group by queries to return no rows The algorithm of determining the best key for loose index scan is doing a loop over the available indexes and selects the one that has the best cost. It retrieves the parameters of the current index into a set of variables. If the cost of using the current index is lower than the best cost so far it copies these variables into another set of variables that contain the information for the best index so far. After having checked all the indexes it uses these variables (outside of the index loop) to create the table read plan object instance. The was a single omission : the key_infix/key_infix_len variables were used outside of the loop without being preserved in the loop for the best index so far. This causes these variables to get overwritten by the next index(es) checked. Fixed by adding variables to hold the data for the current index, passing the new variables to the function that assigns values to them and copying the new variables into the existing ones when selecting a new current best index. To avoid further such problems moved the declarations of the variables used to keep information about the current index inside the loop's compound statement. mysql-test/r/group_min_max.result: Bug #41610: test case mysql-test/t/group_min_max.test: Bug #41610: test case sql/opt_range.cc: Bug #41610: copy the infix data for the current best index --- mysql-test/r/group_min_max.result | 15 +++++++++++ mysql-test/t/group_min_max.test | 23 ++++++++++++++++ sql/opt_range.cc | 57 ++++++++++++++++++++++----------------- 3 files changed, 70 insertions(+), 25 deletions(-) diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index f2f488650d5..58be2af1bb8 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2429,3 +2429,18 @@ id select_type table type possible_keys key key_len ref rows Extra Warnings: Note 1003 select sql_buffer_result `test`.`t1`.`a` AS `a`,(max(`test`.`t1`.`b`) + 1) AS `max(b)+1` from `test`.`t1` where (`test`.`t1`.`a` = 0) group by `test`.`t1`.`a` drop table t1; +CREATE TABLE t1 (a int, b int, c int, d int, +KEY foo (c,d,a,b), KEY bar (c,a,b,d)); +INSERT INTO t1 VALUES (1, 1, 1, 1), (1, 1, 1, 2), (1, 1, 1, 3), (1, 1, 1, 4); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT a,b,c+1,d FROM t1; +EXPLAIN SELECT DISTINCT c FROM t1 WHERE d=4; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL foo 10 NULL 9 Using where; Using index for group-by +SELECT DISTINCT c FROM t1 WHERE d=4; +c +1 +2 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index f7aed7301fb..e124bf9e786 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -935,3 +935,26 @@ insert into t1 (a,b) select a, max(b)+1 from t1 where a = 0 group by a; select * from t1; explain extended select sql_buffer_result a, max(b)+1 from t1 where a = 0 group by a; drop table t1; + + +# +# Bug #41610: key_infix_len can be overwritten causing some group by queries +# to return no rows +# + +CREATE TABLE t1 (a int, b int, c int, d int, + KEY foo (c,d,a,b), KEY bar (c,a,b,d)); + +INSERT INTO t1 VALUES (1, 1, 1, 1), (1, 1, 1, 2), (1, 1, 1, 3), (1, 1, 1, 4); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT a,b,c+1,d FROM t1; + +#Should be non-empty +--ordered_result +EXPLAIN SELECT DISTINCT c FROM t1 WHERE d=4; +SELECT DISTINCT c FROM t1 WHERE d=4; + +DROP TABLE t1; + +--echo End of 5.0 tests diff --git a/sql/opt_range.cc b/sql/opt_range.cc index ebebfafb5d8..018fc8a9d44 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7775,32 +7775,37 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) */ KEY *cur_index_info= table->key_info; KEY *cur_index_info_end= cur_index_info + table->s->keys; - KEY_PART_INFO *cur_part= NULL; - KEY_PART_INFO *end_part; /* Last part for loops. */ - /* Last index part. */ - KEY_PART_INFO *last_part= NULL; - KEY_PART_INFO *first_non_group_part= NULL; - KEY_PART_INFO *first_non_infix_part= NULL; - uint key_infix_parts= 0; - uint cur_group_key_parts= 0; - uint cur_group_prefix_len= 0; /* Cost-related variables for the best index so far. */ double best_read_cost= DBL_MAX; ha_rows best_records= 0; SEL_ARG *best_index_tree= NULL; ha_rows best_quick_prefix_records= 0; uint best_param_idx= 0; - double cur_read_cost= DBL_MAX; - ha_rows cur_records; + + const uint pk= param->table->s->primary_key; SEL_ARG *cur_index_tree= NULL; ha_rows cur_quick_prefix_records= 0; uint cur_param_idx=MAX_KEY; - key_map cur_used_key_parts; - uint pk= param->table->s->primary_key; for (uint cur_index= 0 ; cur_index_info != cur_index_info_end ; cur_index_info++, cur_index++) { + KEY_PART_INFO *cur_part; + KEY_PART_INFO *end_part; /* Last part for loops. */ + /* Last index part. */ + KEY_PART_INFO *last_part; + KEY_PART_INFO *first_non_group_part; + KEY_PART_INFO *first_non_infix_part; + uint key_infix_parts; + uint cur_group_key_parts= 0; + uint cur_group_prefix_len= 0; + double cur_read_cost; + ha_rows cur_records; + key_map used_key_parts_map; + uint cur_key_infix_len= 0; + byte cur_key_infix[MAX_KEY_LENGTH]; + uint cur_used_key_parts; + /* Check (B1) - if current index is covering. */ if (!table->used_keys.is_set(cur_index)) goto next_index; @@ -7879,7 +7884,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) else if (join->select_distinct) { select_items_it.rewind(); - cur_used_key_parts.clear_all(); + used_key_parts_map.clear_all(); uint max_key_part= 0; while ((item= select_items_it++)) { @@ -7890,13 +7895,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) Check if this attribute was already present in the select list. If it was present, then its corresponding key part was alredy used. */ - if (cur_used_key_parts.is_set(key_part_nr)) + if (used_key_parts_map.is_set(key_part_nr)) continue; if (key_part_nr < 1 || key_part_nr > join->fields_list.elements) goto next_index; cur_part= cur_index_info->key_part + key_part_nr - 1; cur_group_prefix_len+= cur_part->store_length; - cur_used_key_parts.set_bit(key_part_nr); + used_key_parts_map.set_bit(key_part_nr); ++cur_group_key_parts; max_key_part= max(max_key_part,key_part_nr); } @@ -7908,7 +7913,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) */ ulonglong all_parts, cur_parts; all_parts= (1<> 1; + cur_parts= used_key_parts_map.to_ulonglong() >> 1; if (all_parts != cur_parts) goto next_index; } @@ -7958,7 +7963,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) &dummy); if (!get_constant_key_infix(cur_index_info, index_range_tree, first_non_group_part, min_max_arg_part, - last_part, thd, key_infix, &key_infix_len, + last_part, thd, cur_key_infix, + &cur_key_infix_len, &first_non_infix_part)) goto next_index; } @@ -8010,9 +8016,9 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) } /* If we got to this point, cur_index_info passes the test. */ - key_infix_parts= key_infix_len ? + key_infix_parts= cur_key_infix_len ? (first_non_infix_part - first_non_group_part) : 0; - used_key_parts= cur_group_key_parts + key_infix_parts; + cur_used_key_parts= cur_group_key_parts + key_infix_parts; /* Compute the cost of using this index. */ if (tree) @@ -8024,7 +8030,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) cur_quick_prefix_records= check_quick_select(param, cur_param_idx, cur_index_tree); } - cost_group_min_max(table, cur_index_info, used_key_parts, + cost_group_min_max(table, cur_index_info, cur_used_key_parts, cur_group_key_parts, tree, cur_index_tree, cur_quick_prefix_records, have_min, have_max, &cur_read_cost, &cur_records); @@ -8035,7 +8041,6 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) */ if (cur_read_cost < best_read_cost - (DBL_EPSILON * cur_read_cost)) { - DBUG_ASSERT(tree != 0 || cur_param_idx == MAX_KEY); index_info= cur_index_info; index= cur_index; best_read_cost= cur_read_cost; @@ -8045,11 +8050,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) best_param_idx= cur_param_idx; group_key_parts= cur_group_key_parts; group_prefix_len= cur_group_prefix_len; + key_infix_len= cur_key_infix_len; + if (key_infix_len) + memcpy (key_infix, cur_key_infix, sizeof (key_infix)); + used_key_parts= cur_used_key_parts; } - next_index: - cur_group_key_parts= 0; - cur_group_prefix_len= 0; + next_index:; } if (!index_info) /* No usable index found. */ DBUG_RETURN(NULL); -- cgit v1.2.1 From 76ff67d6c9b45f78108ab2d126a9fe8369df7c45 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Fri, 27 Feb 2009 16:11:15 +0200 Subject: Recommit for merging and pushing --- mysql-test/r/preload.result | 4 ++-- mysql-test/r/ps.result | 12 ++++++------ mysql-test/r/repair.result | 2 +- mysql-test/r/rpl_failed_optimize.result | 2 +- mysql-test/suite/funcs_1/r/innodb_views.result | 2 +- mysql-test/suite/funcs_1/r/memory_views.result | 2 +- sql/sql_table.cc | 7 ++++++- 7 files changed, 18 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/preload.result b/mysql-test/r/preload.result index 24a6e594a14..7ed0c62f33a 100644 --- a/mysql-test/r/preload.result +++ b/mysql-test/r/preload.result @@ -144,7 +144,7 @@ Key_reads 0 load index into cache t3, t2 key (primary,b) ; Table Op Msg_type Msg_text test.t3 preload_keys Error Table 'test.t3' doesn't exist -test.t3 preload_keys error Corrupt +test.t3 preload_keys status Operation failed test.t2 preload_keys status OK show status like "key_read%"; Variable_name Value @@ -159,7 +159,7 @@ Key_reads 0 load index into cache t3 key (b), t2 key (c) ; Table Op Msg_type Msg_text test.t3 preload_keys Error Table 'test.t3' doesn't exist -test.t3 preload_keys error Corrupt +test.t3 preload_keys status Operation failed test.t2 preload_keys Error Key 'c' doesn't exist in table 't2' test.t2 preload_keys status Operation failed show status like "key_read%"; diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 09deaf2f322..116014a38d2 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1386,13 +1386,13 @@ execute stmt; Table Op Msg_type Msg_text test.t1 repair status OK test.t4 repair Error Table 'test.t4' doesn't exist -test.t4 repair error Corrupt +test.t4 repair status Operation failed test.t3 repair status OK execute stmt; Table Op Msg_type Msg_text test.t1 repair status OK test.t4 repair Error Table 'test.t4' doesn't exist -test.t4 repair error Corrupt +test.t4 repair status Operation failed test.t3 repair status OK prepare stmt from "optimize table t1, t3, t4"; execute stmt; @@ -1400,23 +1400,23 @@ Table Op Msg_type Msg_text test.t1 optimize status OK test.t3 optimize status OK test.t4 optimize Error Table 'test.t4' doesn't exist -test.t4 optimize error Corrupt +test.t4 optimize status Operation failed execute stmt; Table Op Msg_type Msg_text test.t1 optimize status Table is already up to date test.t3 optimize status Table is already up to date test.t4 optimize Error Table 'test.t4' doesn't exist -test.t4 optimize error Corrupt +test.t4 optimize status Operation failed prepare stmt from "analyze table t4, t1"; execute stmt; Table Op Msg_type Msg_text test.t4 analyze Error Table 'test.t4' doesn't exist -test.t4 analyze error Corrupt +test.t4 analyze status Operation failed test.t1 analyze status Table is already up to date execute stmt; Table Op Msg_type Msg_text test.t4 analyze Error Table 'test.t4' doesn't exist -test.t4 analyze error Corrupt +test.t4 analyze status Operation failed test.t1 analyze status Table is already up to date deallocate prepare stmt; drop table t1, t2, t3; diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result index c59a5300e64..e7866ae7656 100644 --- a/mysql-test/r/repair.result +++ b/mysql-test/r/repair.result @@ -27,7 +27,7 @@ drop table t1; repair table t1 use_frm; Table Op Msg_type Msg_text test.t1 repair Error Table 'test.t1' doesn't exist -test.t1 repair error Corrupt +test.t1 repair status Operation failed create table t1 engine=myisam SELECT 1,"table 1"; flush tables; repair table t1; diff --git a/mysql-test/r/rpl_failed_optimize.result b/mysql-test/r/rpl_failed_optimize.result index 33a8cdc4a2f..ff7f6ad6177 100644 --- a/mysql-test/r/rpl_failed_optimize.result +++ b/mysql-test/r/rpl_failed_optimize.result @@ -16,5 +16,5 @@ Error 1205 Lock wait timeout exceeded; try restarting transaction OPTIMIZE TABLE non_existing; Table Op Msg_type Msg_text test.non_existing optimize Error Table 'test.non_existing' doesn't exist -test.non_existing optimize error Corrupt +test.non_existing optimize status Operation failed drop table t1; diff --git a/mysql-test/suite/funcs_1/r/innodb_views.result b/mysql-test/suite/funcs_1/r/innodb_views.result index d29e38925f6..3d5c5a1e698 100644 --- a/mysql-test/suite/funcs_1/r/innodb_views.result +++ b/mysql-test/suite/funcs_1/r/innodb_views.result @@ -21367,7 +21367,7 @@ ERROR 42S02: Table 'test.v1' doesn't exist CHECK TABLE v1; Table Op Msg_type Msg_text test.v1 check Error Table 'test.v1' doesn't exist -test.v1 check error Corrupt +test.v1 check status Operation failed DESCRIBE v1; ERROR 42S02: Table 'test.v1' doesn't exist EXPLAIN SELECT * FROM v1; diff --git a/mysql-test/suite/funcs_1/r/memory_views.result b/mysql-test/suite/funcs_1/r/memory_views.result index d24d72473fd..9935e17a1dc 100644 --- a/mysql-test/suite/funcs_1/r/memory_views.result +++ b/mysql-test/suite/funcs_1/r/memory_views.result @@ -21368,7 +21368,7 @@ ERROR 42S02: Table 'test.v1' doesn't exist CHECK TABLE v1; Table Op Msg_type Msg_text test.v1 check Error Table 'test.v1' doesn't exist -test.v1 check error Corrupt +test.v1 check status Operation failed DESCRIBE v1; ERROR 42S02: Table 'test.v1' doesn't exist EXPLAIN SELECT * FROM v1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index eefe2a5596e..ff7f874ffcb 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2314,7 +2314,12 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, view_checksum(thd, table) == HA_ADMIN_WRONG_CHECKSUM) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, ER_VIEW_CHECKSUM, ER(ER_VIEW_CHECKSUM)); - result_code= HA_ADMIN_CORRUPT; + if (thd->net.last_errno == ER_NO_SUCH_TABLE) + /* A missing table is just issued as a failed command */ + result_code= HA_ADMIN_FAILED; + else + /* Default failure code is corrupt table */ + result_code= HA_ADMIN_CORRUPT; goto send_result; } -- cgit v1.2.1 From 8a5d64a0635aa5f6ac52e8cba1b8555b1cca4d13 Mon Sep 17 00:00:00 2001 From: "Bernt M. Johnsen" Date: Mon, 2 Mar 2009 11:03:13 +0100 Subject: Prepared BUG#42711 for push --- mysql-test/r/show_check.result | 2 +- mysql-test/t/mysql.test | 56 ++++++++++++++++++++++---------------- mysql-test/t/mysqldump-compat.test | 8 ++++-- mysql-test/t/mysqltest.test | 2 +- mysql-test/t/show_check.test | 9 ++++-- 5 files changed, 47 insertions(+), 30 deletions(-) diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index ad3138e80ea..15f28fb9610 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -1094,7 +1094,7 @@ CREATE DATABASE mysqltest1; use mysqltest1; CREATE TABLE t1(ËÏÌÏÎËÁ1 INT); ----> Dumping mysqltest1 to show_check.mysqltest1.sql +---> Dumping mysqltest1 to outfile1 DROP DATABASE mysqltest1; diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 594d10e46a5..12431e26596 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -98,35 +98,43 @@ drop table t1; # Bug #20432: mysql client interprets commands in comments # +--let $file = $MYSQLTEST_VARDIR/tmp/bug20432.sql + # if the client sees the 'use' within the comment, we haven't fixed ---exec echo "/*" > $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec echo "use" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec echo "*/" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1 +--exec echo "/*" > $file +--exec echo "use" >> $file +--exec echo "*/" >> $file +--exec $MYSQL < $file 2>&1 # SQL can have embedded comments => workie ---exec echo "select /*" > $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec echo "use" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec echo "*/ 1" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1 +--exec echo "select /*" > $file +--exec echo "use" >> $file +--exec echo "*/ 1" >> $file +--exec $MYSQL < $file 2>&1 # client commands on the other hand must be at BOL => error ---exec echo "/*" > $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec echo "xxx" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec echo "*/ use" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql +--exec echo "/*" > $file +--exec echo "xxx" >> $file +--exec echo "*/ use" >> $file --error 1 ---exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1 +--exec $MYSQL < $file 2>&1 # client comment recognized, but parameter missing => error ---exec echo "use" > $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1 +--exec echo "use" > $file +--exec $MYSQL < $file 2>&1 + +--remove_file $file # # Bug #20328: mysql client interprets commands in comments # ---exec $MYSQL -e "help" > $MYSQLTEST_VARDIR/tmp/bug20328_1.result ---exec $MYSQL -e "help " > $MYSQLTEST_VARDIR/tmp/bug20328_2.result ---diff_files $MYSQLTEST_VARDIR/tmp/bug20328_1.result $MYSQLTEST_VARDIR/tmp/bug20328_2.result +--let $file1 = $MYSQLTEST_VARDIR/tmp/bug20328_1.result +--let $file2 = $MYSQLTEST_VARDIR/tmp/bug20328_2.result +--exec $MYSQL -e "help" > $file1 +--exec $MYSQL -e "help " > $file2 +--diff_files $file1 $file2 +--remove_file $file1 +--remove_file $file2 # # Bug #19216: Client crashes on long SELECT @@ -152,13 +160,15 @@ EOF # # Bug #20103: Escaping with backslash does not work # ---exec echo "SET SQL_MODE = 'NO_BACKSLASH_ESCAPES';" > $MYSQLTEST_VARDIR/tmp/bug20103.sql ---exec echo "SELECT '\';" >> $MYSQLTEST_VARDIR/tmp/bug20103.sql ---exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20103.sql 2>&1 +--let $file = $MYSQLTEST_VARDIR/tmp/bug20103.sql +--exec echo "SET SQL_MODE = 'NO_BACKSLASH_ESCAPES';" > $file +--exec echo "SELECT '\';" >> $file +--exec $MYSQL < $file 2>&1 ---exec echo "SET SQL_MODE = '';" > $MYSQLTEST_VARDIR/tmp/bug20103.sql ---exec echo "SELECT '\';';" >> $MYSQLTEST_VARDIR/tmp/bug20103.sql ---exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20103.sql 2>&1 +--exec echo "SET SQL_MODE = '';" > $file +--exec echo "SELECT '\';';" >> $file +--exec $MYSQL < $file 2>&1 +--remove_file $file # # Bug#17583: mysql drops connection when stdout is not writable diff --git a/mysql-test/t/mysqldump-compat.test b/mysql-test/t/mysqldump-compat.test index 848d66cc728..9a830b16f26 100644 --- a/mysql-test/t/mysqldump-compat.test +++ b/mysql-test/t/mysqldump-compat.test @@ -5,9 +5,13 @@ # Bug #30126: semicolon before closing */ in /*!... CREATE DATABASE ;*/ # +--let $file = $MYSQLTEST_VARDIR/tmp/bug30126.sql + CREATE DATABASE mysqldump_30126; USE mysqldump_30126; CREATE TABLE t1 (c1 int); ---exec $MYSQL_DUMP --add-drop-database mysqldump_30126 > $MYSQLTEST_VARDIR/tmp/bug30126.sql ---exec $MYSQL mysqldump_30126 < $MYSQLTEST_VARDIR/tmp/bug30126.sql +--exec $MYSQL_DUMP --add-drop-database mysqldump_30126 > $file +--exec $MYSQL mysqldump_30126 < $file DROP DATABASE mysqldump_30126; + +--remove_file $file diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 93528f81449..d087d38560b 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1459,7 +1459,7 @@ select "this will be executed"; remove_file $MYSQLTEST_VARDIR/tmp/zero_length_file.result; --error 0,1 -remove_file $MYSQLTEST_VARDIR/log/zero_length_file.reject; +remove_file $MYSQLTEST_VARDIR/tmp/zero_length_file.reject; --error 0,1 remove_file $MYSQL_TEST_DIR/r/zero_length_file.reject; diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index f4e0b906f60..2d261aa0675 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -794,10 +794,12 @@ CREATE TABLE t1( # Check: # - Dump mysqltest1; +--let $outfile1=$MYSQLTEST_VARDIR/tmp/show_check.mysqltest1.sql + --echo ---echo ---> Dumping mysqltest1 to show_check.mysqltest1.sql +--echo ---> Dumping mysqltest1 to outfile1 ---exec $MYSQL_DUMP --default-character-set=latin1 --character-sets-dir=$CHARSETSDIR --databases mysqltest1 > $MYSQLTEST_VARDIR/tmp/show_check.mysqltest1.sql +--exec $MYSQL_DUMP --default-character-set=latin1 --character-sets-dir=$CHARSETSDIR --databases mysqltest1 > $outfile1 # - Clean mysqltest1; @@ -812,7 +814,8 @@ DROP DATABASE mysqltest1; --echo --echo ---> Restoring mysqltest1... ---exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/show_check.mysqltest1.sql +--exec $MYSQL test < $outfile1 +--remove_file $outfile1 # - Check definition of the table. -- cgit v1.2.1 From 9486c5e1f5ef91611d87adbb0b544f8bdc081028 Mon Sep 17 00:00:00 2001 From: Timothy Smith Date: Mon, 2 Mar 2009 17:24:23 -0700 Subject: Applying InnoDB snashot 5.0-ss4007, part 1. Fixes Bug #39939: DROP TABLE/DISCARD TABLESPACE takes long time in buf_LRU_invalidate_tablespace() This was already fixed in 5.1+; this is a backport to 5.0. Detailed revision comments: r2743 | inaam | 2008-10-08 22:18:12 +0300 (Wed, 08 Oct 2008) | 13 lines branches/5.0: Backport of r2742 from branches/5.1: Fix Bug#39939 DROP TABLE/DISCARD TABLESPACE takes long time in buf_LRU_invalidate_tablespace() Improve implementation of buf_LRU_invalidate_tablespace by attempting hash index drop in batches instead of doing it one by one. Reviewed by: Heikki, Sunny, Marko Approved by: Heikki --- innobase/buf/buf0lru.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c index 0f632f0752a..6984c196701 100644 --- a/innobase/buf/buf0lru.c +++ b/innobase/buf/buf0lru.c @@ -42,6 +42,11 @@ initial segment in buf_LRU_get_recent_limit */ #define BUF_LRU_INITIAL_RATIO 8 +/* When dropping the search hash index entries before deleting an ibd +file, we build a local array of pages belonging to that tablespace +in the buffer pool. Following is the size of that array. */ +#define BUF_LRU_DROP_SEARCH_HASH_SIZE 1024 + /* If we switch on the InnoDB monitor because there are too few available frames in the buffer pool, we set this to TRUE */ ibool buf_lru_switched_on_innodb_mon = FALSE; @@ -65,6 +70,120 @@ buf_LRU_block_free_hashed_page( buf_block_t* block); /* in: block, must contain a file page and be in a state where it can be freed */ +/********************************************************************** +Attempts to drop page hash index on a batch of pages belonging to a +particular space id. */ +static +void +buf_LRU_drop_page_hash_batch( +/*=========================*/ + ulint id, /* in: space id */ + const ulint* arr, /* in: array of page_no */ + ulint count) /* in: number of entries in array */ +{ + ulint i; + + ut_ad(arr != NULL); + ut_ad(count <= BUF_LRU_DROP_SEARCH_HASH_SIZE); + + for (i = 0; i < count; ++i) { + btr_search_drop_page_hash_when_freed(id, arr[i]); + } +} + +/********************************************************************** +When doing a DROP TABLE/DISCARD TABLESPACE we have to drop all page +hash index entries belonging to that table. This function tries to +do that in batch. Note that this is a 'best effort' attempt and does +not guarantee that ALL hash entries will be removed. */ +static +void +buf_LRU_drop_page_hash_for_tablespace( +/*==================================*/ + ulint id) /* in: space id */ +{ + buf_block_t* block; + ulint* page_arr; + ulint num_entries; + + page_arr = ut_malloc(sizeof(ulint) + * BUF_LRU_DROP_SEARCH_HASH_SIZE); + mutex_enter(&buf_pool->mutex); + +scan_again: + num_entries = 0; + block = UT_LIST_GET_LAST(buf_pool->LRU); + + while (block != NULL) { + buf_block_t* prev_block; + + mutex_enter(&block->mutex); + prev_block = UT_LIST_GET_PREV(LRU, block); + + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + + if (block->space != id + || block->buf_fix_count > 0 + || block->io_fix != 0) { + /* We leave the fixed pages as is in this scan. + To be dealt with later in the final scan. */ + mutex_exit(&block->mutex); + goto next_page; + } + + ut_ad(block->space == id); + if (block->is_hashed) { + + /* Store the offset(i.e.: page_no) in the array + so that we can drop hash index in a batch + later. */ + page_arr[num_entries] = block->offset; + mutex_exit(&block->mutex); + ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE); + ++num_entries; + + if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) { + goto next_page; + } + /* Array full. We release the buf_pool->mutex to + obey the latching order. */ + mutex_exit(&buf_pool->mutex); + + buf_LRU_drop_page_hash_batch(id, page_arr, + num_entries); + num_entries = 0; + mutex_enter(&buf_pool->mutex); + } else { + mutex_exit(&block->mutex); + } + +next_page: + /* Note that we may have released the buf_pool->mutex + above after reading the prev_block during processing + of a page_hash_batch (i.e.: when the array was full). + This means that prev_block can change in LRU list. + This is OK because this function is a 'best effort' + to drop as many search hash entries as possible and + it does not guarantee that ALL such entries will be + dropped. */ + block = prev_block; + + /* If, however, block has been removed from LRU list + to the free list then we should restart the scan. + block->state is protected by buf_pool->mutex. */ + if (block && block->state != BUF_BLOCK_FILE_PAGE) { + ut_a(num_entries == 0); + goto scan_again; + } + } + + mutex_exit(&buf_pool->mutex); + + /* Drop any remaining batch of search hashed pages. */ + buf_LRU_drop_page_hash_batch(id, page_arr, num_entries); + ut_free(page_arr); +} + /********************************************************************** Invalidates all pages belonging to a given tablespace when we are deleting the data file(s) of that tablespace. */ @@ -78,6 +197,14 @@ buf_LRU_invalidate_tablespace( ulint page_no; ibool all_freed; + /* Before we attempt to drop pages one by one we first + attempt to drop page hash index entries in batches to make + it more efficient. The batching attempt is a best effort + attempt and does not guarantee that all pages hash entries + will be dropped. We get rid of remaining page hash entries + one by one below. */ + buf_LRU_drop_page_hash_for_tablespace(id); + scan_again: mutex_enter(&(buf_pool->mutex)); -- cgit v1.2.1 From 2560975963fba398d02abdb0166cf4d3418ccfd4 Mon Sep 17 00:00:00 2001 From: Timothy Smith Date: Mon, 2 Mar 2009 17:57:09 -0700 Subject: Applying InnoDB snashot 5.0-ss4007, part 2. Fixes Bug #18828: If InnoDB runs out of undo slots, it returns misleading 'table is full' This is a backport of code already in 5.1+. The error message change referred to in the detailed revision comments is still pending. Detailed revision comments: r3937 | calvin | 2009-01-15 03:11:56 +0200 (Thu, 15 Jan 2009) | 17 lines branches/5.0: Backport the fix for Bug#18828. Return DB_TOO_MANY_CONCURRENT_TRXS when we run out of UNDO slots in the rollback segment. The backport is requested by MySQL under bug#41529 - Safe handling of InnoDB running out of undo log slots. This is a partial fix since the MySQL error code requested to properly report the error condition back to the client has not yet materialized. Currently we have #ifdef'd the error code translation in ha_innodb.cc. This will have to be changed as and when MySQl add the new requested code or an equivalent code that we can then use. Given the above, currently we will get the old behavior, not the "fixed" and intended behavior. Approved by: Heikki (on IM) --- innobase/dict/dict0crea.c | 3 +- innobase/include/db0err.h | 5 +++ innobase/include/trx0undo.h | 13 +++--- innobase/row/row0mysql.c | 3 +- innobase/trx/trx0rec.c | 15 ++++--- innobase/trx/trx0undo.c | 105 +++++++++++++++++++++++++++----------------- sql/ha_innodb.cc | 14 ++++++ 7 files changed, 103 insertions(+), 55 deletions(-) diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index e20d8b6e83a..12d99734796 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -1249,7 +1249,8 @@ dict_create_or_check_foreign_constraint_tables(void) fprintf(stderr, "InnoDB: error %lu in creation\n", (ulong) error); - ut_a(error == DB_OUT_OF_FILE_SPACE); + ut_a(error == DB_OUT_OF_FILE_SPACE + || error == DB_TOO_MANY_CONCURRENT_TRXS); fprintf(stderr, "InnoDB: creation failed\n"); fprintf(stderr, "InnoDB: tablespace is full\n"); diff --git a/innobase/include/db0err.h b/innobase/include/db0err.h index 247c5de67db..68bdcdc8b7f 100644 --- a/innobase/include/db0err.h +++ b/innobase/include/db0err.h @@ -70,6 +70,11 @@ Created 5/24/1996 Heikki Tuuri work with e.g., FT indexes created by a later version of the engine. */ +#define DB_TOO_MANY_CONCURRENT_TRXS 47 /* when InnoDB runs out of the + preconfigured undo slots, this can + only happen when there are too many + concurrent transactions */ + /* The following are partial failure codes */ #define DB_FAIL 1000 #define DB_OVERFLOW 1001 diff --git a/innobase/include/trx0undo.h b/innobase/include/trx0undo.h index 4f1847aa88c..152a09c0f76 100644 --- a/innobase/include/trx0undo.h +++ b/innobase/include/trx0undo.h @@ -222,13 +222,16 @@ trx_undo_lists_init( Assigns an undo log for a transaction. A new undo log is created or a cached undo log reused. */ -trx_undo_t* +ulint trx_undo_assign_undo( /*=================*/ - /* out: the undo log, NULL if did not succeed: out of - space */ - trx_t* trx, /* in: transaction */ - ulint type); /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ + /* out: DB_SUCCESS if undo log assign + * successful, possible error codes are: + * ER_TOO_MANY_CONCURRENT_TRXS + * DB_OUT_OF_FILE_SPAC + * DB_OUT_OF_MEMORY */ + trx_t* trx, /* in: transaction */ + ulint type); /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ /********************************************************************** Sets the state of the undo log segment at a transaction finish. */ diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 4bc5f39359c..d7213b25145 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -494,7 +494,8 @@ handle_new_error: /* MySQL will roll back the latest SQL statement */ } else if (err == DB_ROW_IS_REFERENCED || err == DB_NO_REFERENCED_ROW - || err == DB_CANNOT_ADD_CONSTRAINT) { + || err == DB_CANNOT_ADD_CONSTRAINT + || err == DB_TOO_MANY_CONCURRENT_TRXS) { if (savept) { /* Roll back the latest, possibly incomplete insertion or update */ diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c index 3b7171e6038..44b734625dd 100644 --- a/innobase/trx/trx0rec.c +++ b/innobase/trx/trx0rec.c @@ -1013,6 +1013,7 @@ trx_undo_report_row_operation( ibool is_insert; trx_rseg_t* rseg; mtr_t mtr; + ulint err = DB_SUCCESS; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; @@ -1024,7 +1025,7 @@ trx_undo_report_row_operation( *roll_ptr = ut_dulint_zero; - return(DB_SUCCESS); + return(err); } ut_ad(thr); @@ -1042,7 +1043,7 @@ trx_undo_report_row_operation( if (trx->insert_undo == NULL) { - trx_undo_assign_undo(trx, TRX_UNDO_INSERT); + err = trx_undo_assign_undo(trx, TRX_UNDO_INSERT); } undo = trx->insert_undo; @@ -1052,7 +1053,7 @@ trx_undo_report_row_operation( if (trx->update_undo == NULL) { - trx_undo_assign_undo(trx, TRX_UNDO_UPDATE); + err = trx_undo_assign_undo(trx, TRX_UNDO_UPDATE); } @@ -1060,11 +1061,11 @@ trx_undo_report_row_operation( is_insert = FALSE; } - if (undo == NULL) { - /* Did not succeed: out of space */ + if (err != DB_SUCCESS) { + /* Did not succeed: return the error encountered */ mutex_exit(&(trx->undo_mutex)); - return(DB_OUT_OF_FILE_SPACE); + return(err); } page_no = undo->last_page_no; @@ -1154,7 +1155,7 @@ trx_undo_report_row_operation( if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } - return(DB_SUCCESS); + return(err); } /*============== BUILDING PREVIOUS VERSION OF A RECORD ===============*/ diff --git a/innobase/trx/trx0undo.c b/innobase/trx/trx0undo.c index 251cd355897..997f25a66d8 100644 --- a/innobase/trx/trx0undo.c +++ b/innobase/trx/trx0undo.c @@ -374,27 +374,32 @@ trx_undo_page_init( /******************************************************************* Creates a new undo log segment in file. */ static -page_t* +ulint trx_undo_seg_create( /*================*/ - /* out: segment header page x-latched, NULL - if no space left */ + /* out: DB_SUCCESS if page creation OK + possible error codes are: + DB_TOO_MANY_CONCURRENT_TRXS + DB_OUT_OF_FILE_SPACE */ trx_rseg_t* rseg __attribute__((unused)),/* in: rollback segment */ trx_rsegf_t* rseg_hdr,/* in: rollback segment header, page x-latched */ ulint type, /* in: type of the segment: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ ulint* id, /* out: slot index within rseg header */ + page_t** undo_page, + /* out: segment header page x-latched, NULL + if there was an error */ mtr_t* mtr) /* in: mtr */ { ulint slot_no; ulint space; - page_t* undo_page; trx_upagef_t* page_hdr; trx_usegf_t* seg_hdr; ulint n_reserved; ibool success; - + ulint err = DB_SUCCESS; + ut_ad(mtr && id && rseg_hdr); #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(rseg->mutex))); @@ -411,7 +416,7 @@ trx_undo_seg_create( "InnoDB: Warning: cannot find a free slot for an undo log. Do you have too\n" "InnoDB: many active transactions running concurrently?\n"); - return(NULL); + return(DB_TOO_MANY_CONCURRENT_TRXS); } space = buf_frame_get_space_id(rseg_hdr); @@ -420,29 +425,29 @@ trx_undo_seg_create( mtr); if (!success) { - return(NULL); + return(DB_OUT_OF_FILE_SPACE); } /* Allocate a new file segment for the undo log */ - undo_page = fseg_create_general(space, 0, + *undo_page = fseg_create_general(space, 0, TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER, TRUE, mtr); fil_space_release_free_extents(space, n_reserved); - if (undo_page == NULL) { + if (*undo_page == NULL) { /* No space left */ - return(NULL); + return(DB_OUT_OF_FILE_SPACE); } #ifdef UNIV_SYNC_DEBUG - buf_page_dbg_add_level(undo_page, SYNC_TRX_UNDO_PAGE); + buf_page_dbg_add_level(*undo_page, SYNC_TRX_UNDO_PAGE); #endif /* UNIV_SYNC_DEBUG */ - page_hdr = undo_page + TRX_UNDO_PAGE_HDR; - seg_hdr = undo_page + TRX_UNDO_SEG_HDR; + page_hdr = *undo_page + TRX_UNDO_PAGE_HDR; + seg_hdr = *undo_page + TRX_UNDO_SEG_HDR; - trx_undo_page_init(undo_page, type, mtr); + trx_undo_page_init(*undo_page, type, mtr); mlog_write_ulint(page_hdr + TRX_UNDO_PAGE_FREE, TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE, @@ -456,10 +461,11 @@ trx_undo_seg_create( page_hdr + TRX_UNDO_PAGE_NODE, mtr); trx_rsegf_set_nth_undo(rseg_hdr, slot_no, - buf_frame_get_page_no(undo_page), mtr); + buf_frame_get_page_no(*undo_page), mtr); + *id = slot_no; - return(undo_page); + return(err); } /************************************************************************** @@ -1400,6 +1406,11 @@ trx_undo_mem_create( undo = mem_alloc(sizeof(trx_undo_t)); + if (undo == NULL) { + + return NULL; + } + undo->id = id; undo->type = type; undo->state = TRX_UNDO_ACTIVE; @@ -1479,11 +1490,15 @@ trx_undo_mem_free( /************************************************************************** Creates a new undo log. */ static -trx_undo_t* +ulint trx_undo_create( /*============*/ - /* out: undo log object, NULL if did not - succeed: out of space */ + /* out: DB_SUCCESS if successful in creating + the new undo lob object, possible error + codes are: + DB_TOO_MANY_CONCURRENT_TRXS + DB_OUT_OF_FILE_SPACE + DB_OUT_OF_MEMORY*/ trx_t* trx, /* in: transaction */ trx_rseg_t* rseg, /* in: rollback segment memory copy */ ulint type, /* in: type of the log: TRX_UNDO_INSERT or @@ -1491,36 +1506,39 @@ trx_undo_create( dulint trx_id, /* in: id of the trx for which the undo log is created */ XID* xid, /* in: X/Open transaction identification*/ + trx_undo_t** undo, /* out: the new undo log object, undefined + * if did not succeed */ mtr_t* mtr) /* in: mtr */ { trx_rsegf_t* rseg_header; ulint page_no; ulint offset; ulint id; - trx_undo_t* undo; page_t* undo_page; - + ulint err; + #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(rseg->mutex))); #endif /* UNIV_SYNC_DEBUG */ if (rseg->curr_size == rseg->max_size) { - return(NULL); + return(DB_OUT_OF_FILE_SPACE); } rseg->curr_size++; rseg_header = trx_rsegf_get(rseg->space, rseg->page_no, mtr); - undo_page = trx_undo_seg_create(rseg, rseg_header, type, &id, mtr); + err = trx_undo_seg_create(rseg, rseg_header, type, &id, + &undo_page, mtr); - if (undo_page == NULL) { + if (err != DB_SUCCESS) { /* Did not succeed */ rseg->curr_size--; - return(NULL); + return(err); } page_no = buf_frame_get_page_no(undo_page); @@ -1532,9 +1550,14 @@ trx_undo_create( undo_page + offset, mtr); } - undo = trx_undo_mem_create(rseg, id, type, trx_id, xid, + *undo = trx_undo_mem_create(rseg, id, type, trx_id, xid, page_no, offset); - return(undo); + if (*undo == NULL) { + + err = DB_OUT_OF_MEMORY; + } + + return(err); } /*================ UNDO LOG ASSIGNMENT AND CLEANUP =====================*/ @@ -1653,17 +1676,20 @@ trx_undo_mark_as_dict_operation( Assigns an undo log for a transaction. A new undo log is created or a cached undo log reused. */ -trx_undo_t* +ulint trx_undo_assign_undo( /*=================*/ - /* out: the undo log, NULL if did not succeed: out of - space */ - trx_t* trx, /* in: transaction */ - ulint type) /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ + /* out: DB_SUCCESS if undo log assign + successful, possible error codes are: + DD_TOO_MANY_CONCURRENT_TRXS + DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY*/ + trx_t* trx, /* in: transaction */ + ulint type) /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ { trx_rseg_t* rseg; trx_undo_t* undo; mtr_t mtr; + ulint err = DB_SUCCESS; ut_ad(trx); ut_ad(trx->rseg); @@ -1684,15 +1710,11 @@ trx_undo_assign_undo( undo = trx_undo_reuse_cached(trx, rseg, type, trx->id, &trx->xid, &mtr); if (undo == NULL) { - undo = trx_undo_create(trx, rseg, type, trx->id, &trx->xid, - &mtr); - if (undo == NULL) { - /* Did not succeed */ + err = trx_undo_create(trx, rseg, type, trx->id, &trx->xid, + &undo, &mtr); + if (err != DB_SUCCESS) { - mutex_exit(&(rseg->mutex)); - mtr_commit(&mtr); - - return(NULL); + goto func_exit; } } @@ -1710,10 +1732,11 @@ trx_undo_assign_undo( trx_undo_mark_as_dict_operation(trx, undo, &mtr); } +func_exit: mutex_exit(&(rseg->mutex)); mtr_commit(&mtr); - return(undo); + return err; } /********************************************************************** diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index e0b7fb6e7f5..3bae0da3e02 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -524,6 +524,20 @@ convert_error_code_to_mysql( mark_transaction_to_rollback(thd, TRUE); return(HA_ERR_LOCK_TABLE_FULL); + } else if (error == DB_TOO_MANY_CONCURRENT_TRXS) { + + /* Once MySQL add the appropriate code to errmsg.txt then + we can get rid of this #ifdef. NOTE: The code checked by + the #ifdef is the suggested name for the error condition + and the actual error code name could very well be different. + This will require some monitoring, ie. the status + of this request on our part.*/ +#ifdef ER_TOO_MANY_CONCURRENT_TRXS + return(ER_TOO_MANY_CONCURRENT_TRXS); +#else + return(HA_ERR_RECORD_FILE_FULL); +#endif + } else if (error == DB_UNSUPPORTED) { return(HA_ERR_UNSUPPORTED); -- cgit v1.2.1 From 31f226b093d5651aa60b06e62153c82ef0f1c2a3 Mon Sep 17 00:00:00 2001 From: Timothy Smith Date: Mon, 2 Mar 2009 18:00:23 -0700 Subject: Applying InnoDB snashot 5.0-ss4007, part 3. Fixes Bug #41571: MySQL segfaults after innodb recovery This 5.0 fix will not be pushed into 5.1; a separate fix (from innodb-5.1-ss4007) will be pushed into 5.1+. Detailed revision comments: r4003 | marko | 2009-01-20 16:12:50 +0200 (Tue, 20 Jan 2009) | 10 lines branches/5.0: rec_set_nth_field(): When the field already is SQL null, do nothing when it is being changed to SQL null. (Bug #41571) Normally, MySQL does not pass "do-nothing" updates to the storage engine. When it does and a column of an InnoDB table that is in ROW_FORMAT=COMPACT is being updated from NULL to NULL, the InnoDB buffer pool will be corrupted without this fix. rb://81 approved by Heikki Tuuri --- innobase/include/rem0rec.h | 11 ++++------- innobase/include/rem0rec.ic | 19 +++++++++---------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/innobase/include/rem0rec.h b/innobase/include/rem0rec.h index 69b397c9682..b573c5d4c3b 100644 --- a/innobase/include/rem0rec.h +++ b/innobase/include/rem0rec.h @@ -368,8 +368,9 @@ rec_set_field_extern_bits( /*************************************************************** This is used to modify the value of an already existing field in a record. The previous value must have exactly the same size as the new value. If len -is UNIV_SQL_NULL then the field is treated as an SQL null for old-style -records. For new-style records, len must not be UNIV_SQL_NULL. */ +is UNIV_SQL_NULL then the field is treated as an SQL null. +For records in ROW_FORMAT=COMPACT (new-style records), len must not be +UNIV_SQL_NULL unless the field already is SQL null. */ UNIV_INLINE void rec_set_nth_field( @@ -378,11 +379,7 @@ rec_set_nth_field( const ulint* offsets,/* in: array returned by rec_get_offsets() */ ulint n, /* in: index number of the field */ const void* data, /* in: pointer to the data if not SQL null */ - ulint len); /* in: length of the data or UNIV_SQL_NULL. - If not SQL null, must have the same - length as the previous value. - If SQL null, previous value must be - SQL null. */ + ulint len); /* in: length of the data or UNIV_SQL_NULL */ /************************************************************** The following function returns the data size of an old-style physical record, that is the sum of field lengths. SQL null fields diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic index 1abbb503bab..64c91724386 100644 --- a/innobase/include/rem0rec.ic +++ b/innobase/include/rem0rec.ic @@ -1204,8 +1204,9 @@ rec_get_nth_field_size( /*************************************************************** This is used to modify the value of an already existing field in a record. The previous value must have exactly the same size as the new value. If len -is UNIV_SQL_NULL then the field is treated as an SQL null for old-style -records. For new-style records, len must not be UNIV_SQL_NULL. */ +is UNIV_SQL_NULL then the field is treated as an SQL null. +For records in ROW_FORMAT=COMPACT (new-style records), len must not be +UNIV_SQL_NULL unless the field already is SQL null. */ UNIV_INLINE void rec_set_nth_field( @@ -1215,11 +1216,7 @@ rec_set_nth_field( ulint n, /* in: index number of the field */ const void* data, /* in: pointer to the data if not SQL null */ - ulint len) /* in: length of the data or UNIV_SQL_NULL. - If not SQL null, must have the same - length as the previous value. - If SQL null, previous value must be - SQL null. */ + ulint len) /* in: length of the data or UNIV_SQL_NULL */ { byte* data2; ulint len2; @@ -1227,9 +1224,11 @@ rec_set_nth_field( ut_ad(rec); ut_ad(rec_offs_validate(rec, NULL, offsets)); - if (len == UNIV_SQL_NULL) { - ut_ad(!rec_offs_comp(offsets)); - rec_set_nth_field_sql_null(rec, n); + if (UNIV_UNLIKELY(len == UNIV_SQL_NULL)) { + if (!rec_offs_nth_sql_null(offsets, n)) { + ut_a(!rec_offs_comp(offsets)); + rec_set_nth_field_sql_null(rec, n); + } return; } -- cgit v1.2.1 From 91cb65a60443d87f9c461c47c7ba16d50f8c4e60 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Thu, 5 Mar 2009 18:10:44 +0800 Subject: BUG#37051 Replication rules not evaluated correctly Backporting patch to 5.0. --- mysql-test/include/master-slave-end.inc | 6 + mysql-test/include/start_slave.inc | 21 +++ mysql-test/include/stop_slave.inc | 21 +++ mysql-test/include/wait_for_slave_sql_error.inc | 40 ++++ .../include/wait_for_slave_sql_error_and_skip.inc | 39 ++++ mysql-test/r/multi_update.result | 4 +- mysql-test/r/rpl_filter_tables_not_exist.result | 151 +++++++++++++++ mysql-test/t/rpl_filter_tables_not_exist-slave.opt | 1 + mysql-test/t/rpl_filter_tables_not_exist.test | 206 +++++++++++++++++++++ sql/log_event.cc | 47 +++-- sql/log_event.h | 22 ++- sql/sql_class.cc | 6 +- sql/sql_class.h | 7 + sql/sql_parse.cc | 48 ++++- sql/sql_update.cc | 2 +- 15 files changed, 594 insertions(+), 27 deletions(-) create mode 100644 mysql-test/include/master-slave-end.inc create mode 100644 mysql-test/include/start_slave.inc create mode 100644 mysql-test/include/stop_slave.inc create mode 100644 mysql-test/include/wait_for_slave_sql_error.inc create mode 100644 mysql-test/include/wait_for_slave_sql_error_and_skip.inc create mode 100644 mysql-test/r/rpl_filter_tables_not_exist.result create mode 100644 mysql-test/t/rpl_filter_tables_not_exist-slave.opt create mode 100644 mysql-test/t/rpl_filter_tables_not_exist.test diff --git a/mysql-test/include/master-slave-end.inc b/mysql-test/include/master-slave-end.inc new file mode 100644 index 00000000000..74e4c7b608a --- /dev/null +++ b/mysql-test/include/master-slave-end.inc @@ -0,0 +1,6 @@ +--connection master +--sync_slave_with_master +--connection slave +--disable_query_log +STOP SLAVE; +--enable_query_log diff --git a/mysql-test/include/start_slave.inc b/mysql-test/include/start_slave.inc new file mode 100644 index 00000000000..78a02736de8 --- /dev/null +++ b/mysql-test/include/start_slave.inc @@ -0,0 +1,21 @@ +# ==== Purpose ==== +# +# Issues START SLAVE on the current connection. Then waits until both +# the IO and SQL threads have started, or until a timeout is reached. +# +# Please use this instead of 'START SLAVE', to reduce the risk of test +# case bugs. +# +# ==== Usage ==== +# +# source include/wait_for_slave_to_start.inc; +# +# Parameters to this macro are $slave_timeout and +# $master_connection. See wait_for_slave_param.inc for +# descriptions. + +--disable_query_log +START SLAVE; +--enable_query_log +--echo include/start_slave.inc +source include/wait_for_slave_to_start.inc; diff --git a/mysql-test/include/stop_slave.inc b/mysql-test/include/stop_slave.inc new file mode 100644 index 00000000000..7161e6fe739 --- /dev/null +++ b/mysql-test/include/stop_slave.inc @@ -0,0 +1,21 @@ +# ==== Purpose ==== +# +# Issues STOP SLAVE on the current connection. Then waits until both +# the IO and SQL threads have stopped, or until a timeout is reached. +# +# Please use this instead of 'STOP SLAVE', to reduce the risk of test +# case bugs. +# +# ==== Usage ==== +# +# source include/wait_for_slave_to_start.inc; +# +# Parameters to this macro are $slave_timeout and +# $master_connection. See wait_for_slave_param.inc for +# descriptions. + +--disable_query_log +STOP SLAVE; +--enable_query_log +--echo include/stop_slave.inc +source include/wait_for_slave_to_stop.inc; diff --git a/mysql-test/include/wait_for_slave_sql_error.inc b/mysql-test/include/wait_for_slave_sql_error.inc new file mode 100644 index 00000000000..1a708cee780 --- /dev/null +++ b/mysql-test/include/wait_for_slave_sql_error.inc @@ -0,0 +1,40 @@ +# ==== Purpose ==== +# +# Waits until the SQL thread of the current connection has got an +# error, or until a timeout is reached. Also waits until the SQL +# thread has completely stopped. +# +# ==== Usage ==== +# +# source include/wait_for_slave_sql_error.inc; +# +# Parameters: +# +# $slave_sql_errno +# The expected SQL error number. This is required. +# (After BUG#41956 has been fixed, this will be required to be a +# symbolic name instead of a number.) +# +# $slave_timeout +# See wait_for_slave_param.inc for description. +# +# $master_connection +# See wait_for_slave_param.inc for description. + +if (`SELECT '$slave_sql_errno' = ''`) { + --echo !!!ERROR IN TEST: you must set \$slave_sql_errno before sourcing wait_fro_slave_sql_error.inc + exit; +} + +let $slave_param= Slave_SQL_Running; +let $slave_param_value= No; +let $slave_error_message= Failed while waiting for slave to stop the SQL thread (expecting error in the SQL thread); +source include/wait_for_slave_param.inc; + +# NOTE: on mysql-5.0, there is no way to distinguish slave SQL error from IO error +let $_error= query_get_value(SHOW SLAVE STATUS, Last_Errno, 1); +if (`SELECT '$_error' != '$slave_sql_errno'`) { + --echo Slave stopped with wrong error code: $_error (expected $slave_sql_errno) + source include/show_rpl_debug_info.inc; + exit; +} diff --git a/mysql-test/include/wait_for_slave_sql_error_and_skip.inc b/mysql-test/include/wait_for_slave_sql_error_and_skip.inc new file mode 100644 index 00000000000..5723720f4b7 --- /dev/null +++ b/mysql-test/include/wait_for_slave_sql_error_and_skip.inc @@ -0,0 +1,39 @@ +# ==== Purpose ==== +# +# Wait for slave SQL error, skip the erroneous statement and restart +# slave +# +# ==== Usage ==== +# +# let $slave_sql_error= ; +# source include/wait_for_slave_sql_error_and_skip.inc; +# +# Parameters: +# +# $slave_sql_errno +# The error number to wait for. This is required. (See +# wait_for_slave_sql_error.inc) +# +# $show_sql_error +# If set, will print the error to the query log. +# +# $slave_timeout +# See wait_for_slave_param.inc for description. +# +# $master_connection +# See wait_for_slave_param.inc for description. + +echo --source include/wait_for_slave_sql_error_and_skip.inc; +connection slave; +source include/wait_for_slave_sql_error.inc; +if ($show_sql_error) +{ + # NOTE: on mysql-5.0, there is no way to distinguish slave SQL error from IO error + let $error= query_get_value("SHOW SLAVE STATUS", Last_Error, 1); + echo Last_SQL_Error = $error; +} + +# skip the erroneous statement +set global sql_slave_skip_counter=1; +source include/start_slave.inc; +connection master; diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index f6dbac31c2a..c04948c6fa7 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -522,7 +522,7 @@ a b 4 4 show master status /* there must be the UPDATE query event */; File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 189 +master-bin.000001 198 delete from t1; delete from t2; insert into t1 values (1,2),(3,4),(4,4); @@ -532,7 +532,7 @@ UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a; ERROR 23000: Duplicate entry '4' for key 1 show master status /* there must be the UPDATE query event */; File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 204 +master-bin.000001 213 drop table t1, t2; drop table if exists t1, t2, t3; CREATE TABLE t1 (a int, PRIMARY KEY (a)); diff --git a/mysql-test/r/rpl_filter_tables_not_exist.result b/mysql-test/r/rpl_filter_tables_not_exist.result new file mode 100644 index 00000000000..7eddaabc636 --- /dev/null +++ b/mysql-test/r/rpl_filter_tables_not_exist.result @@ -0,0 +1,151 @@ +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 t1 (id int, a int); +CREATE TABLE t2 (id int, b int); +CREATE TABLE t3 (id int, c int); +CREATE TABLE t4 (id int, d int); +CREATE TABLE t5 (id int, e int); +CREATE TABLE t6 (id int, f int); +CREATE TABLE t7 (id int, g int); +CREATE TABLE t8 (id int, h int); +CREATE TABLE t9 (id int, i int); +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t3 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t5 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t6 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t7 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t8 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t9 VALUES (1, 1), (2, 2), (3, 3); +[on slave] +SHOW TABLES LIKE 't%'; +Tables_in_test (t%) +t1 +t2 +t3 +[on master] +UPDATE t7 LEFT JOIN t4 ON (t4.id=t7.id) SET d=0, g=0 where t7.id=1; +UPDATE t7 LEFT JOIN (t4, t5, t6) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t6.id) SET d=0, e=0, f=0, g=0 where t7.id=1; +UPDATE t4 LEFT JOIN (t7, t8, t9) ON (t4.id=t7.id and t4.id=t8.id and t4.id=t9.id) SET d=0, g=0, h=0, i=0 where t4.id=1; +UPDATE t7 LEFT JOIN (t8, t9) ON (t7.id=t8.id and t7.id=t9.id) SET g=0, h=0, i=0 where t7.id=1; +UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET d=0 where t1.id=1; +UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET g=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET d=0, e=0, f=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t4, t5, t8) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t8.id) SET d=0, e=0, h=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t7, t8, t5) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t5.id) SET g=0, h=0, e=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t2, t3, t5) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t5.id) SET e=0 where t1.id=1; +UPDATE t4 LEFT JOIN t1 ON (t1.id=t4.id) SET a=0, d=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t7) ON (t4.id=t1.id and t7.id=t4.id) SET a = 0, d=0, g=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t2, t3) ON (t1.id=t4.id and t2.id=t4.id and t3.id=t4.id) SET a=0, b=0, c=0, d=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t2, t5) ON (t1.id=t4.id and t2.id=t4.id and t5.id=t4.id) SET a=0, b=0, e=0, d=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t6, t7) ON (t4.id=t1.id and t4.id=t6.id and t4.id=t7.id) SET a=0, d=0, f=0, g=0 where t4.id=1; +UPDATE t7 LEFT JOIN (t4, t1, t2) ON (t7.id=t4.id and t7.id=t1.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1; +UPDATE t7 LEFT JOIN (t8, t4, t1) ON (t7.id=t8.id and t7.id=t4.id and t7.id=t1.id) SET a=0, d=0, g=0, h=0 where t7.id=1; +UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0 where t1.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0 where t1.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t1 LEFT JOIN (t4, t7) ON (t1.id=t4.id and t1.id=t7.id) SET a=0 where t1.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t4, t7) ON (t1.id=t4.id and t1.id=t7.id) SET a=0 where t1.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t1 LEFT JOIN (t2, t4, t7) ON (t1.id=t2.id and t1.id=t4.id and t1.id=t7.id) SET a=0, b=0 where t1.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t2, t4, t7) ON (t1.id=t2.id and t1.id=t4.id and t1.id=t7.id) SET a=0, b=0 where t1.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t1 LEFT JOIN (t2, t3, t7) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t7.id) SET a=0, b=0, c=0 where t1.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t2, t3, t7) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t7.id) SET a=0, b=0, c=0 where t1.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET a=0, g=0 where t1.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET a=0, g=0 where t1.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t7 LEFT JOIN t1 ON (t1.id=t7.id) SET a=0, g=0 where t7.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN t1 ON (t1.id=t7.id) SET a=0, g=0 where t7.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t1 LEFT JOIN (t4, t5, t7) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t7.id) SET a=0, g=0 where t1.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t4, t5, t7) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t7.id) SET a=0, g=0 where t1.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t1 LEFT JOIN (t4, t7, t8) ON (t1.id=t4.id and t1.id=t7.id and t1.id=t8.id) SET a=0, g=0 where t1.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t4, t7, t8) ON (t1.id=t4.id and t1.id=t7.id and t1.id=t8.id) SET a=0, g=0 where t1.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t1 LEFT JOIN (t7, t8, t9) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t9.id) SET a=0, g=0, h=0, i=0 where t1.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t7, t8, t9) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t9.id) SET a=0, g=0, h=0, i=0 where t1.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t7 LEFT JOIN (t1, t2, t3) ON (t7.id=t1.id and t7.id=t2.id and t7.id=t3.id) SET g=0, a=0, b=0, c=0 where t7.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN (t1, t2, t3) ON (t7.id=t1.id and t7.id=t2.id and t7.id=t3.id) SET g=0, a=0, b=0, c=0 where t7.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t7 LEFT JOIN (t4, t5, t3) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t3.id) SET g=0, c=0 where t7.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN (t4, t5, t3) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t3.id) SET g=0, c=0 where t7.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t7 LEFT JOIN (t8, t9, t3) ON (t7.id=t8.id and t7.id=t9.id and t7.id=t3.id) SET g=0, h=0, i=0, c=0 where t7.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN (t8, t9, t3) ON (t7.id=t8.id and t7.id=t9.id and t7.id=t3.id) SET g=0, h=0, i=0, c=0 where t7.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0, d=0 where t1.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0, d=0 where t1.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET a=0, d=0, e=0, f=0 where t1.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET a=0, d=0, e=0, f=0 where t1.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t4 LEFT JOIN (t1, t5, t6) ON (t4.id=t1.id and t4.id=t5.id and t4.id=t6.id) SET a=0, e=0, f=0 where t4.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t4 LEFT JOIN (t1, t5, t6) ON (t4.id=t1.id and t4.id=t5.id and t4.id=t6.id) SET a=0, e=0, f=0 where t4.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +UPDATE t7 LEFT JOIN (t1, t4, t2) ON (t7.id=t1.id and t7.id=t4.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1; +--source include/wait_for_slave_sql_error_and_skip.inc +Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN (t1, t4, t2) ON (t7.id=t1.id and t7.id=t4.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1' +set global sql_slave_skip_counter=1; +include/start_slave.inc +[on slave] +show tables like 't%'; +Tables_in_test (t%) +t1 +t2 +t3 +SELECT * FROM t1; +id a +1 1 +2 2 +3 3 +SELECT * FROM t2; +id b +1 1 +2 2 +3 3 +SELECT * FROM t3; +id c +1 1 +2 2 +3 3 +[on master] +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/t/rpl_filter_tables_not_exist-slave.opt b/mysql-test/t/rpl_filter_tables_not_exist-slave.opt new file mode 100644 index 00000000000..42acd3ea33d --- /dev/null +++ b/mysql-test/t/rpl_filter_tables_not_exist-slave.opt @@ -0,0 +1 @@ +--replicate-do-table=test.t1 --replicate-do-table=test.t2 --replicate-do-table=test.t3 --replicate-ignore-table=test.t4 --replicate-ignore-table=test.t5 --replicate-ignore-table=test.t6 diff --git a/mysql-test/t/rpl_filter_tables_not_exist.test b/mysql-test/t/rpl_filter_tables_not_exist.test new file mode 100644 index 00000000000..d1153e584c8 --- /dev/null +++ b/mysql-test/t/rpl_filter_tables_not_exist.test @@ -0,0 +1,206 @@ +# Test evaluation of replication table filter rules +# +# ==== Purpose ==== +# +# Test if replication table filter rules are properly evaluated when +# some of the tables referenced by the multiple-table update do not +# exist on slave. +# +# ==== Method ==== +# +# Master creates tables t1, t2, t3, t4, t5, t6, t7, t8, t9 and the +# slave is started with the following replication table filter rules: +# +# --replicate-do-table=t1 +# --replicate-do-table=t2 +# --replicate-do-table=t3 +# +# and +# +# --replicate-ignore-table=t4 +# --replicate-ignore-table=t5 +# --replicate-ignore-table=t6 +# +# So the slave only replicate changes to tables t1, t2 and t3 and only +# these tables exist on slave. +# +# From now on, tables t1, t2, and t3 are referenced as do tables, +# tables t4, t5, t6 are referenced as ignore tables, and tables t7, +# t8, t9 are referenced as other tables. +# +# All multi-table update tests reference tables that are not do +# tables, which do not exist on slave. And the following situations +# of multi-table update will be tested: +# +# 1. Do tables are not referenced at all +# 2. Do tables are not referenced for update +# 3. Ignore tables are referenced for update before do tables +# 4. Only do tables are referenced for update +# 5. Do tables and other tables are referenced for update +# 6. Do tables are referenced for update before ignore tables +# +# For 1, 2 and 3, the statement should be ignored by slave, for 4, 5 +# and 6 the statement should be accepted by slave and cause an error +# because of non-exist tables. +# +# ==== Related bugs ==== +# +# BUG#37051 Replication rules not evaluated correctly + + +source include/master-slave.inc; + +# These tables are mentioned in do-table rules +CREATE TABLE t1 (id int, a int); +CREATE TABLE t2 (id int, b int); +CREATE TABLE t3 (id int, c int); + +# These tables are mentioned in ignore-table rules +CREATE TABLE t4 (id int, d int); +CREATE TABLE t5 (id int, e int); +CREATE TABLE t6 (id int, f int); + +# These tables are not mentioned in do-table or ignore-table rules +CREATE TABLE t7 (id int, g int); +CREATE TABLE t8 (id int, h int); +CREATE TABLE t9 (id int, i int); + +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t3 VALUES (1, 1), (2, 2), (3, 3); + +INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t5 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t6 VALUES (1, 1), (2, 2), (3, 3); + +INSERT INTO t7 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t8 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t9 VALUES (1, 1), (2, 2), (3, 3); + +# Only t1, t2, t3 should be replicated to slave +sync_slave_with_master; +echo [on slave]; +SHOW TABLES LIKE 't%'; + +connection master; +echo [on master]; + +# +# Do tables are not referenced, these statements should be ignored by +# slave. +# +UPDATE t7 LEFT JOIN t4 ON (t4.id=t7.id) SET d=0, g=0 where t7.id=1; +UPDATE t7 LEFT JOIN (t4, t5, t6) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t6.id) SET d=0, e=0, f=0, g=0 where t7.id=1; +UPDATE t4 LEFT JOIN (t7, t8, t9) ON (t4.id=t7.id and t4.id=t8.id and t4.id=t9.id) SET d=0, g=0, h=0, i=0 where t4.id=1; +UPDATE t7 LEFT JOIN (t8, t9) ON (t7.id=t8.id and t7.id=t9.id) SET g=0, h=0, i=0 where t7.id=1; + +# +# Do tables are not referenced for update, these statements should be +# ignored by slave. +# +UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET d=0 where t1.id=1; +UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET g=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET d=0, e=0, f=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t4, t5, t8) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t8.id) SET d=0, e=0, h=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t7, t8, t5) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t5.id) SET g=0, h=0, e=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t2, t3, t5) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t5.id) SET e=0 where t1.id=1; + +# +# Ignore tables are referenced for update before do tables, these +# statements should be ignore by slave. +# +UPDATE t4 LEFT JOIN t1 ON (t1.id=t4.id) SET a=0, d=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t7) ON (t4.id=t1.id and t7.id=t4.id) SET a = 0, d=0, g=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t2, t3) ON (t1.id=t4.id and t2.id=t4.id and t3.id=t4.id) SET a=0, b=0, c=0, d=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t2, t5) ON (t1.id=t4.id and t2.id=t4.id and t5.id=t4.id) SET a=0, b=0, e=0, d=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t6, t7) ON (t4.id=t1.id and t4.id=t6.id and t4.id=t7.id) SET a=0, d=0, f=0, g=0 where t4.id=1; +UPDATE t7 LEFT JOIN (t4, t1, t2) ON (t7.id=t4.id and t7.id=t1.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1; +UPDATE t7 LEFT JOIN (t8, t4, t1) ON (t7.id=t8.id and t7.id=t4.id and t7.id=t1.id) SET a=0, d=0, g=0, h=0 where t7.id=1; + +# Sync slave to make sure all above statements are correctly ignored, +# if any of the above statement are not ignored, it would cause error +# and stop slave sql thread. +sync_slave_with_master; +connection master; + +# Parameters for include/wait_for_slave_sql_error_and_skip.inc: +# Ask it to show SQL error message. +let $show_sql_error= 1; +# The expected error will always be 1146 (ER_NO_SUCH_TABLE). +let $slave_sql_errno= 1146; + +# +# Only do tables are referenced for update, these statements should +# cause error on slave +# +UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t4, t7) ON (t1.id=t4.id and t1.id=t7.id) SET a=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t2, t4, t7) ON (t1.id=t2.id and t1.id=t4.id and t1.id=t7.id) SET a=0, b=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t2, t3, t7) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t7.id) SET a=0, b=0, c=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +# +# Do tables and other tables are referenced for update, these +# statements should cause error on slave +# +UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET a=0, g=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN t1 ON (t1.id=t7.id) SET a=0, g=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t4, t5, t7) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t7.id) SET a=0, g=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t4, t7, t8) ON (t1.id=t4.id and t1.id=t7.id and t1.id=t8.id) SET a=0, g=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t7, t8, t9) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t9.id) SET a=0, g=0, h=0, i=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN (t1, t2, t3) ON (t7.id=t1.id and t7.id=t2.id and t7.id=t3.id) SET g=0, a=0, b=0, c=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN (t4, t5, t3) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t3.id) SET g=0, c=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN (t8, t9, t3) ON (t7.id=t8.id and t7.id=t9.id and t7.id=t3.id) SET g=0, h=0, i=0, c=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +# +# Do tables are referenced for update before ignore tables +# +UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0, d=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET a=0, d=0, e=0, f=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t4 LEFT JOIN (t1, t5, t6) ON (t4.id=t1.id and t4.id=t5.id and t4.id=t6.id) SET a=0, e=0, f=0 where t4.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN (t1, t4, t2) ON (t7.id=t1.id and t7.id=t4.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +sync_slave_with_master; +echo [on slave]; + +# We should only have tables t1, t2, t3 on slave +show tables like 't%'; + +# The rows in these tables should remain untouched +SELECT * FROM t1; +SELECT * FROM t2; +SELECT * FROM t3; + +# Clean up +connection master; +echo [on master]; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +source include/master-slave-end.inc; diff --git a/sql/log_event.cc b/sql/log_event.cc index b74b38e55b2..ba282fd8e59 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1117,6 +1117,11 @@ void Query_log_event::pack_info(Protocol *protocol) static void write_str_with_code_and_len(char **dst, const char *src, int len, uint code) { + /* + only 1 byte to store the length of catalog, so it should not + surpass 255 + */ + DBUG_ASSERT(len <= 255); DBUG_ASSERT(src); *((*dst)++)= code; *((*dst)++)= (uchar) len; @@ -1136,16 +1141,8 @@ static void write_str_with_code_and_len(char **dst, const char *src, bool Query_log_event::write(IO_CACHE* file) { - uchar buf[QUERY_HEADER_LEN+ - 1+4+ // code of flags2 and flags2 - 1+8+ // code of sql_mode and sql_mode - 1+1+FN_REFLEN+ // code of catalog and catalog length and catalog - 1+4+ // code of autoinc and the 2 autoinc variables - 1+6+ // code of charset and charset - 1+1+MAX_TIME_ZONE_NAME_LENGTH+ // code of tz and tz length and tz name - 1+2+ // code of lc_time_names and lc_time_names_number - 1+2 // code of charset_database and charset_database_number - ], *start, *start_of_status; + uchar buf[QUERY_HEADER_LEN + MAX_SIZE_LOG_EVENT_STATUS]; + uchar *start, *start_of_status; ulong event_length; if (!query) @@ -1251,10 +1248,8 @@ bool Query_log_event::write(IO_CACHE* file) { /* In the TZ sys table, column Name is of length 64 so this should be ok */ DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH); - *start++= Q_TIME_ZONE_CODE; - *start++= time_zone_len; - memcpy(start, time_zone_str, time_zone_len); - start+= time_zone_len; + write_str_with_code_and_len((char **)(&start), + time_zone_str, time_zone_len, Q_TIME_ZONE_CODE); } if (lc_time_names_number) { @@ -1270,7 +1265,17 @@ bool Query_log_event::write(IO_CACHE* file) int2store(start, charset_database_number); start+= 2; } + if (table_map_for_update) + { + *start++= Q_TABLE_MAP_FOR_UPDATE_CODE; + int8store(start, table_map_for_update); + start+= 8; + } /* + NOTE: When adding new status vars, please don't forget to update + the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update function + code_name in this file. + Here there could be code like if (command-line-option-which-says-"log_this_variable" && inited) { @@ -1348,7 +1353,8 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, auto_increment_increment(thd_arg->variables.auto_increment_increment), auto_increment_offset(thd_arg->variables.auto_increment_offset), lc_time_names_number(thd_arg->variables.lc_time_names->number), - charset_database_number(0) + charset_database_number(0), + table_map_for_update((ulonglong)thd_arg->table_map_for_update) { time_t end_time; @@ -1471,6 +1477,7 @@ code_name(int code) case Q_CATALOG_NZ_CODE: return "Q_CATALOG_NZ_CODE"; case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE"; case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE"; + case Q_TABLE_MAP_FOR_UPDATE_CODE: return "Q_TABLE_MAP_FOR_UPDATE_CODE"; } sprintf(buf, "CODE#%d", code); return buf; @@ -1507,7 +1514,8 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, db(NullS), catalog_len(0), status_vars_len(0), flags2_inited(0), sql_mode_inited(0), charset_inited(0), auto_increment_increment(1), auto_increment_offset(1), - time_zone_len(0), lc_time_names_number(0), charset_database_number(0) + time_zone_len(0), lc_time_names_number(0), charset_database_number(0), + table_map_for_update(0) { ulong data_len; uint32 tmp; @@ -1649,6 +1657,11 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, charset_database_number= uint2korr(pos); pos+= 2; break; + case Q_TABLE_MAP_FOR_UPDATE_CODE: + CHECK_SPACE(pos, end, 8); + table_map_for_update= uint8korr(pos); + pos+= 8; + break; default: /* That's why you must write status vars in growing order of code */ DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\ @@ -2036,6 +2049,8 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, else thd->variables.collation_database= thd->db_charset; + thd->table_map_for_update= (table_map)table_map_for_update; + /* Execute the query (note that we bypass dispatch_command()) */ const char* found_semicolon= NULL; mysql_parse(thd, thd->query, thd->query_length, &found_semicolon); diff --git a/sql/log_event.h b/sql/log_event.h index 5b065a33dd1..6ccbf8e4d5c 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -204,12 +204,15 @@ struct sql_ex_info packet (i.e. a query) sent from client to master; First, an auxiliary log_event status vars estimation: */ -#define MAX_SIZE_LOG_EVENT_STATUS (4 /* flags2 */ + \ - 8 /* sql mode */ + \ - 1 + 1 + 255 /* catalog */ + \ - 4 /* autoinc */ + \ - 6 /* charset */ + \ - MAX_TIME_ZONE_NAME_LENGTH) +#define MAX_SIZE_LOG_EVENT_STATUS (1 + 4 /* type, flags2 */ + \ + 1 + 8 /* type, sql_mode */ + \ + 1 + 1 + 255 /* type, length, catalog */ + \ + 1 + 4 /* type, auto_increment */ + \ + 1 + 6 /* type, charset */ + \ + 1 + 1 + 255 /* type, length, time_zone */ + \ + 1 + 2 /* type, lc_time_names_number */ + \ + 1 + 2 /* type, charset_database_number */ + \ + 1 + 8 /* type, table_map_for_update */) #define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \ LOG_EVENT_HEADER_LEN + /* write_header */ \ QUERY_HEADER_LEN + /* write_data */ \ @@ -273,6 +276,8 @@ struct sql_ex_info #define Q_LC_TIME_NAMES_CODE 7 #define Q_CHARSET_DATABASE_CODE 8 + +#define Q_TABLE_MAP_FOR_UPDATE_CODE 9 /* Intvar event post-header */ #define I_TYPE_OFFSET 0 @@ -800,6 +805,11 @@ public: const char *time_zone_str; uint lc_time_names_number; /* 0 means en_US */ uint charset_database_number; + /* + map for tables that will be updated for a multi-table update query + statement, for other query statements, this will be zero. + */ + ulonglong table_map_for_update; #ifndef MYSQL_CLIENT diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9ff602bb62e..4ea621f428d 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -172,7 +172,9 @@ THD::THD() /* statement id */ 0), Open_tables_state(refresh_version), lock_id(&main_lock_id), - user_time(0), in_sub_stmt(0), global_read_lock(0), is_fatal_error(0), + user_time(0), in_sub_stmt(0), + table_map_for_update(0), + global_read_lock(0), is_fatal_error(0), transaction_rollback_request(0), is_fatal_sub_stmt_error(0), rand_used(0), time_zone_used(0), last_insert_id_used(0), last_insert_id_used_bin_log(0), insert_id_used(0), @@ -651,6 +653,8 @@ void THD::cleanup_after_query() free_items(); /* Reset where. */ where= THD::DEFAULT_WHERE; + /* reset table map for multi-table update */ + table_map_for_update= 0; } diff --git a/sql/sql_class.h b/sql/sql_class.h index cc7ef7809d4..3e3dfcd08fa 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1358,6 +1358,13 @@ public: Note: in the parser, stmt_arena == thd, even for PS/SP. */ Query_arena *stmt_arena; + + /* + map for tables that will be updated for a multi-table update query + statement, for other query statements, this will be zero. + */ + table_map table_map_for_update; + /* next_insert_id is set on SET INSERT_ID= #. This is used as the next generated auto_increment value in handler.cc diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1d3632fd468..dafe4baa9e5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2584,6 +2584,10 @@ mysql_execute_command(THD *thd) TABLE_LIST *all_tables; /* most outer SELECT_LEX_UNIT of query */ SELECT_LEX_UNIT *unit= &lex->unit; +#ifdef HAVE_REPLICATION + /* have table map for update for multi-update statement (BUG#37051) */ + bool have_table_map_for_update= FALSE; +#endif /* Saved variable value */ DBUG_ENTER("mysql_execute_command"); thd->net.no_send_error= 0; @@ -2663,6 +2667,48 @@ mysql_execute_command(THD *thd) // force searching in slave.cc:tables_ok() all_tables->updating= 1; } + + /* + For fix of BUG#37051, the master stores the table map for update + in the Query_log_event, and the value is assigned to + thd->variables.table_map_for_update before executing the update + query. + + If thd->variables.table_map_for_update is set, then we are + replicating from a new master, we can use this value to apply + filter rules without opening all the tables. However If + thd->variables.table_map_for_update is not set, then we are + replicating from an old master, so we just skip this and + continue with the old method. And of course, the bug would still + exist for old masters. + */ + if (lex->sql_command == SQLCOM_UPDATE_MULTI && + thd->table_map_for_update) + { + have_table_map_for_update= TRUE; + table_map table_map_for_update= thd->table_map_for_update; + uint nr= 0; + TABLE_LIST *table; + for (table=all_tables; table; table=table->next_global, nr++) + { + if (table_map_for_update & ((table_map)1 << nr)) + table->updating= TRUE; + else + table->updating= FALSE; + } + + if (all_tables_not_ok(thd, all_tables)) + { + /* we warn the slave SQL thread */ + my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); + if (thd->one_shot_set) + reset_one_shot_variables(thd); + DBUG_RETURN(0); + } + + for (table=all_tables; table; table=table->next_global) + table->updating= TRUE; + } /* Check if statment should be skipped because of slave filtering @@ -3608,7 +3654,7 @@ end_with_restore_list: #ifdef HAVE_REPLICATION /* Check slave filtering rules */ - if (unlikely(thd->slave_thread)) + if (unlikely(thd->slave_thread && !have_table_map_for_update)) { if (all_tables_not_ok(thd, all_tables)) { diff --git a/sql/sql_update.cc b/sql/sql_update.cc index f15db220a3b..8a3f5bcdc26 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -775,7 +775,7 @@ reopen_tables: DBUG_RETURN(TRUE); } - tables_for_update= get_table_map(fields); + thd->table_map_for_update= tables_for_update= get_table_map(fields); /* Setup timestamp handling and locking mode -- cgit v1.2.1