diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 7c19f60471a..5eb651e2fca 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -646,4 +646,12 @@ drop procedure if exists bug10537| create procedure bug10537() load data local infile '/tmp/somefile' into table t1| ERROR 0A000: LOAD DATA is not allowed in stored procedures +drop function if exists bug8409| +create function bug8409() +returns int +begin +flush tables; +return 5; +end| +ERROR 0A000: FLUSH is not allowed in stored procedures drop table t1| diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index c1164380f09..da54c100178 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3098,4 +3098,15 @@ call bug5963_2(1)| call bug5963_2(1)| drop procedure bug5963_2| drop table t3| +drop function if exists bug9559| +create function bug9559() +returns int +begin +set @y = -6/2; +return @y; +end| +select bug9559()| +bug9559() +-3 +drop function bug9559| drop table t1,t2; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 67e9be5dd5d..78a6cdd49e1 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -905,6 +905,21 @@ create procedure bug10537() load data local infile '/tmp/somefile' into table t1| +# +# BUG#8409: Stored procedure crash if function contains FLUSH +# +--disable_warnings +drop function if exists bug8409| +--enable_warnings +--error ER_SP_BADSTATEMENT +create function bug8409() + returns int +begin + flush tables; + return 5; +end| + + # # BUG#NNNN: New bug synopsis # diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 80acaacfdb3..18389f4d80a 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -3801,6 +3801,25 @@ call bug5963_2(1)| drop procedure bug5963_2| drop table t3| +# +# BUG#9559: Functions: Numeric Operations using -ve value gives incorrect +# results. +# +--disable_warnings +drop function if exists bug9559| +--enable_warnings +create function bug9559() + returns int +begin + set @y = -6/2; + return @y; +end| + +select bug9559()| + +drop function bug9559| + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 8761f8076ca..378d3645caf 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2321,7 +2321,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) */ and_tables_cache= ~(table_map) 0; - if (check_stack_overrun(thd, buff)) + if (check_stack_overrun(thd, STACK_MIN_SIZE)) return TRUE; // Fatal error flag is set! /* The following optimization reduces the depth of an AND-OR tree. diff --git a/sql/item_func.cc b/sql/item_func.cc index 72a4dff74e5..13c9aa92d6e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -293,14 +293,11 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { DBUG_ASSERT(fixed == 0); Item **arg,**arg_end; -#ifndef EMBEDDED_LIBRARY // Avoid compiler warning - char buff[STACK_BUFF_ALLOC]; // Max argument in function -#endif used_tables_cache= not_null_tables_cache= 0; const_item_cache=1; - if (check_stack_overrun(thd, buff)) + if (check_stack_overrun(thd, STACK_MIN_SIZE+STACK_BUFF_ALLOC)) return TRUE; // Fatal error if flag is set! if (arg_count) { // Print purify happy @@ -2567,12 +2564,9 @@ bool udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, uint arg_count, Item **arguments) { -#ifndef EMBEDDED_LIBRARY // Avoid compiler warning - char buff[STACK_BUFF_ALLOC]; // Max argument in function -#endif DBUG_ENTER("Item_udf_func::fix_fields"); - if (check_stack_overrun(thd, buff)) + if (check_stack_overrun(thd, STACK_MIN_SIZE+STACK_BUFF_ALLOC)) DBUG_RETURN(TRUE); // Fatal error flag is set! udf_func *tmp_udf=find_udf(u_d->name.str,(uint) u_d->name.length,1); @@ -3603,7 +3597,7 @@ longlong user_var_entry::val_int(my_bool *null_value) case DECIMAL_RESULT: { longlong result; - my_decimal2int(E_DEC_FATAL_ERROR, (my_decimal *)value, 1, &result); + my_decimal2int(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, &result); return result; } case STRING_RESULT: diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 29c52e73159..328bc75757b 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -138,7 +138,7 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) DBUG_ASSERT(fixed == 0); engine->set_thd((thd= thd_param)); - if (check_stack_overrun(thd, (gptr)&res)) + if (check_stack_overrun(thd, STACK_MIN_SIZE)) return TRUE; res= engine->prepare(); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 0675bce636d..e9a325f1fa7 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1077,7 +1077,7 @@ extern ulong max_connections,max_connect_errors, connect_timeout; extern ulong slave_net_timeout, slave_trans_retries; extern uint max_user_connections; extern ulong what_to_log,flush_time; -extern ulong query_buff_size, thread_stack,thread_stack_min; +extern ulong query_buff_size, thread_stack; extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit; extern ulong max_binlog_size, max_relay_log_size; extern ulong rpl_recovery_rank, thread_cache_size; @@ -1429,7 +1429,7 @@ inline int hexchar_to_int(char c) #ifndef EMBEDDED_LIBRARY extern "C" void unireg_abort(int exit_code); void kill_delayed_threads(void); -bool check_stack_overrun(THD *thd,char *dummy); +bool check_stack_overrun(THD *thd, long margin); #else #define unireg_abort(exit_code) DBUG_RETURN(exit_code) inline void kill_delayed_threads(void) {} diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3843ad04a02..e3a74d378fa 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -349,7 +349,7 @@ uint tc_heuristic_recover= 0; uint volatile thread_count, thread_running; ulong back_log, connect_timeout, concurrency; ulong server_id, thd_startup_options; -ulong table_cache_size, thread_stack, thread_stack_min, what_to_log; +ulong table_cache_size, thread_stack, what_to_log; ulong query_buff_size, slow_launch_time, slave_open_temp_tables; ulong open_files_limit, max_binlog_size, max_relay_log_size; ulong slave_net_timeout, slave_trans_retries; @@ -2090,7 +2090,13 @@ static void start_signal_handler(void) (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); if (!(opt_specialflag & SPECIAL_NO_PRIOR)) my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR); +#if defined(__ia64__) || defined(__ia64) + /* Peculiar things with ia64 platforms - it seems we only have half the + stack size in reality, so we have to double it here */ + pthread_attr_setstacksize(&thr_attr,thread_stack*2); +#else pthread_attr_setstacksize(&thr_attr,thread_stack); +#endif #endif (void) pthread_mutex_lock(&LOCK_thread_count); @@ -3011,23 +3017,35 @@ int main(int argc, char **argv) init_signals(); if (!(opt_specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),CONNECT_PRIOR); +#if defined(__ia64__) || defined(__ia64) + /* Peculiar things with ia64 platforms - it seems we only have half the + stack size in reality, so we have to double it here */ + pthread_attr_setstacksize(&connection_attrib,thread_stack*2); +#else pthread_attr_setstacksize(&connection_attrib,thread_stack); +#endif #ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE { /* Retrieve used stack size; Needed for checking stack overflows */ size_t stack_size= 0; pthread_attr_getstacksize(&connection_attrib, &stack_size); +#if defined(__ia64__) || defined(__ia64) + stack_size/= 2; +#endif /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */ if (stack_size && stack_size < thread_stack) { if (global_system_variables.log_warnings) sql_print_warning("Asked for %ld thread stack, but got %ld", - thread_stack, stack_size); + thread_stack, stack_size); +#if defined(__ia64__) || defined(__ia64) + thread_stack= stack_size*2; +#else thread_stack= stack_size; +#endif } } #endif - thread_stack_min=thread_stack - STACK_MIN_SIZE; (void) thr_setconcurrency(concurrency); // 10 by default diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 217bcc0b728..9d055d55f54 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -564,13 +564,11 @@ sp_head::execute(THD *thd) Item_change_list old_change_list; String old_packet; - -#ifndef EMBEDDED_LIBRARY - if (check_stack_overrun(thd, olddb)) + /* Use some extra margin for possible SP recursion and functions */ + if (check_stack_overrun(thd, 4*STACK_MIN_SIZE)) { DBUG_RETURN(-1); } -#endif dbchanged= FALSE; if (m_db.length && diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index aaec001f47b..7edd93f8d0d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4986,11 +4986,11 @@ long max_stack_used; #endif #ifndef EMBEDDED_LIBRARY -bool check_stack_overrun(THD *thd,char *buf __attribute__((unused))) +bool check_stack_overrun(THD *thd, long margin) { long stack_used; if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >= - (long) thread_stack_min) + thread_stack - margin) { sprintf(errbuff[0],ER(ER_STACK_OVERRUN),stack_used,thread_stack); my_message(ER_STACK_OVERRUN,errbuff[0],MYF(0)); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8181521969a..708dcb7a0d9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6511,6 +6511,11 @@ flush: FLUSH_SYM opt_no_write_to_binlog { LEX *lex=Lex; + if (lex->sphead && lex->sphead->m_type == TYPE_ENUM_FUNCTION) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "FLUSH"); + YYABORT; + } lex->sql_command= SQLCOM_FLUSH; lex->type=0; lex->no_write_to_binlog= $2; } diff --git a/sql/table.cc b/sql/table.cc index db753b2ed1c..bc31a38f24a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1815,7 +1815,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds, bool res= FALSE; DBUG_ENTER("st_table_list::setup_ancestor"); - if (check_stack_overrun(thd, (char *)&res)) + if (check_stack_overrun(thd, STACK_MIN_SIZE)) return TRUE; for (tbl= ancestor; tbl; tbl= tbl->next_local)