diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index 307f17141329d9b4786d966a4a5b43cc0f47e06d..bfb3af0afffe15c4b9c91d6f7d9c84ec789f00a4 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -600,3 +600,10 @@ NULL SELECT -9223372036854775808 MOD -1; -9223372036854775808 MOD -1 0 +# +# Bug #57209 valgrind + Assertion failed: dst > buf +# +SELECT floor(log10(format(concat_ws(5445796E25, 5306463, 30837), -358821))) +as foo; +foo +2 diff --git a/mysql-test/r/query_cache_debug.result b/mysql-test/r/query_cache_debug.result index 30996e5e86b71a84d6571092cd060c8b3b88c444..50a3a02fe4da22995c09411888f4bd2e2edcbd5e 100644 --- a/mysql-test/r/query_cache_debug.result +++ b/mysql-test/r/query_cache_debug.result @@ -123,16 +123,20 @@ SET DEBUG_SYNC="now WAIT_FOR parked1_1"; ** On THD2: Insert a result into the cache. This attempt will be blocked ** because of a debug hook placed just before the mutex lock after which ** the first part of the result set is written. -SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2"; +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2 EXECUTE 1"; SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3; +=================================== Connection default +** Assert that the SELECT-stmt thread reaches the sync point. +SET DEBUG_SYNC="now WAIT_FOR parked2"; +** +** =================================== Connection thd3 ** On THD3: Insert another result into the cache and block on the same ** debug hook. -SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3"; -SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5;; +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3 EXECUTE 1"; +SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5; =================================== Connection default -** Assert that the two SELECT-stmt threads to reach the hook. -SET DEBUG_SYNC="now WAIT_FOR parked2"; +** Assert that the SELECT-stmt thread reaches the sync point. SET DEBUG_SYNC="now WAIT_FOR parked3"; ** ** diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index 44af2f5ad3f575542d24be7dbc1f1d6a7bb2af49..efdf7201a40ae17e5457d50ac4e674f86cf9287a 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -458,3 +458,9 @@ SELECT 2 DIV -2; SELECT -(1 DIV 0); # Crashed the server with SIGFPE before the bugfix SELECT -9223372036854775808 MOD -1; + +--echo # +--echo # Bug #57209 valgrind + Assertion failed: dst > buf +--echo # +SELECT floor(log10(format(concat_ws(5445796E25, 5306463, 30837), -358821))) +as foo; diff --git a/mysql-test/t/query_cache_debug.test b/mysql-test/t/query_cache_debug.test index 77e714aa6f5c377c28bce08116d128fe7feb47f8..2f85813d1ef22966dbf0915604b17e8d13b80440 100644 --- a/mysql-test/t/query_cache_debug.test +++ b/mysql-test/t/query_cache_debug.test @@ -170,20 +170,26 @@ connection thd2; --echo ** On THD2: Insert a result into the cache. This attempt will be blocked --echo ** because of a debug hook placed just before the mutex lock after which --echo ** the first part of the result set is written. -SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2"; +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2 EXECUTE 1"; --send SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3 +connection default; +--echo =================================== Connection default +--echo ** Assert that the SELECT-stmt thread reaches the sync point. +SET DEBUG_SYNC="now WAIT_FOR parked2"; +--echo ** +--echo ** + connection thd3; --echo =================================== Connection thd3 --echo ** On THD3: Insert another result into the cache and block on the same --echo ** debug hook. -SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3"; ---send SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5; +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3 EXECUTE 1"; +--send SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5 connection default; --echo =================================== Connection default ---echo ** Assert that the two SELECT-stmt threads to reach the hook. -SET DEBUG_SYNC="now WAIT_FOR parked2"; +--echo ** Assert that the SELECT-stmt thread reaches the sync point. SET DEBUG_SYNC="now WAIT_FOR parked3"; --echo ** --echo ** diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 6d3514bf356e1f1107a71e79c526eeb3b1940972..89c1e785c719c74ee5203c85ac7b70f688f0bc05 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2299,7 +2299,8 @@ String *Item_func_format::val_str_ascii(String *str) if (lc->grouping[0] > 0 && str_length >= dec_length + 1 + lc->grouping[0]) { - char buf[DECIMAL_MAX_STR_LENGTH * 2]; /* 2 - in the worst case when grouping=1 */ + /* We need space for ',' between each group of digits as well. */ + char buf[2 * FLOATING_POINT_BUFFER]; int count; const char *grouping= lc->grouping; char sign_length= *str->ptr() == '-' ? 1 : 0; @@ -2323,7 +2324,7 @@ String *Item_func_format::val_str_ascii(String *str) count will be initialized to -1 and we'll never get into this "if" anymore. */ - if (!count) + if (count == 0) { *--dst= lc->thousand_sep; if (grouping[1]) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 8c3abdbf1b0f2ddeb90362d4b56e8872cc3e712f..9876c46bbb3a7087c7e13e0587ce74ec785ec605 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -384,6 +384,22 @@ TODO list: #endif +/** + Macro that executes the requested action at a synchronization point + only if the thread has a associated THD session. +*/ +#if defined(ENABLED_DEBUG_SYNC) +#define QC_DEBUG_SYNC(name) \ + do { \ + THD *thd= current_thd; \ + if (thd) \ + DEBUG_SYNC(thd, name); \ + } while (0) +#else +#define QC_DEBUG_SYNC(name) +#endif + + /** Thread state to be used when the query cache lock needs to be acquired. Sets the thread state name in the constructor, resets on destructor. @@ -879,7 +895,7 @@ Query_cache::insert(Query_cache_tls *query_cache_tls, if (is_disabled() || query_cache_tls->first_query_block == NULL) DBUG_VOID_RETURN; - DEBUG_SYNC(current_thd, "wait_in_query_cache_insert"); + QC_DEBUG_SYNC("wait_in_query_cache_insert"); if (try_lock()) DBUG_VOID_RETURN; @@ -1975,7 +1991,7 @@ void Query_cache::flush() if (is_disabled()) DBUG_VOID_RETURN; - DEBUG_SYNC(current_thd, "wait_in_query_cache_flush1"); + QC_DEBUG_SYNC("wait_in_query_cache_flush1"); lock_and_suspend(); if (query_cache_size > 0) @@ -2315,7 +2331,7 @@ void Query_cache::free_cache() void Query_cache::flush_cache() { - DEBUG_SYNC(current_thd, "wait_in_query_cache_flush2"); + QC_DEBUG_SYNC("wait_in_query_cache_flush2"); my_hash_reset(&queries); while (queries_blocks != 0)