From 317d545b14b821b336187090008b52c9eea6733f Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 23 Oct 2008 19:04:52 +0200 Subject: [PATCH 1/4] 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 From 839b60a8da25207cae9b9f75d824d4566eb13899 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 23 Oct 2008 19:36:48 +0200 Subject: [PATCH 2/4] 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; + } + } } } From 2b7ba54cb62bdfe9f8e9ad01d5c9ed55e378c1e5 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 23 Oct 2008 19:39:56 +0200 Subject: [PATCH 3/4] 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") From 0fb0db53d60ffaa121d432e51feec1a94eb69682 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 23 Oct 2008 21:46:46 +0200 Subject: [PATCH 4/4] 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; }