Commit d40abf91 authored by Mats Kindahl's avatar Mats Kindahl

Merging with mysql-5.5-bugteam.

parents 0a9c3968 15ccca1d
...@@ -600,3 +600,10 @@ NULL ...@@ -600,3 +600,10 @@ NULL
SELECT -9223372036854775808 MOD -1; SELECT -9223372036854775808 MOD -1;
-9223372036854775808 MOD -1 -9223372036854775808 MOD -1
0 0
#
# Bug #57209 valgrind + Assertion failed: dst > buf
#
SELECT floor(log10(format(concat_ws(5445796E25, 5306463, 30837), -358821)))
as foo;
foo
2
...@@ -123,16 +123,20 @@ SET DEBUG_SYNC="now WAIT_FOR parked1_1"; ...@@ -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 ** 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 ** because of a debug hook placed just before the mutex lock after which
** the first part of the result set is written. ** 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; 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 =================================== Connection thd3
** On THD3: Insert another result into the cache and block on the same ** On THD3: Insert another result into the cache and block on the same
** debug hook. ** debug hook.
SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3"; SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3 EXECUTE 1";
SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5;; SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5;
=================================== Connection default =================================== Connection default
** Assert that the two SELECT-stmt threads to reach the hook. ** Assert that the SELECT-stmt thread reaches the sync point.
SET DEBUG_SYNC="now WAIT_FOR parked2";
SET DEBUG_SYNC="now WAIT_FOR parked3"; SET DEBUG_SYNC="now WAIT_FOR parked3";
** **
** **
......
...@@ -458,3 +458,9 @@ SELECT 2 DIV -2; ...@@ -458,3 +458,9 @@ SELECT 2 DIV -2;
SELECT -(1 DIV 0); SELECT -(1 DIV 0);
# Crashed the server with SIGFPE before the bugfix # Crashed the server with SIGFPE before the bugfix
SELECT -9223372036854775808 MOD -1; 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;
...@@ -170,20 +170,26 @@ connection thd2; ...@@ -170,20 +170,26 @@ connection thd2;
--echo ** On THD2: Insert a result into the cache. This attempt will be blocked --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 ** because of a debug hook placed just before the mutex lock after which
--echo ** the first part of the result set is written. --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 --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; connection thd3;
--echo =================================== Connection thd3 --echo =================================== Connection thd3
--echo ** On THD3: Insert another result into the cache and block on the same --echo ** On THD3: Insert another result into the cache and block on the same
--echo ** debug hook. --echo ** debug hook.
SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3"; 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; --send SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5
connection default; connection default;
--echo =================================== Connection default --echo =================================== Connection default
--echo ** Assert that the two SELECT-stmt threads to reach the hook. --echo ** Assert that the SELECT-stmt thread reaches the sync point.
SET DEBUG_SYNC="now WAIT_FOR parked2";
SET DEBUG_SYNC="now WAIT_FOR parked3"; SET DEBUG_SYNC="now WAIT_FOR parked3";
--echo ** --echo **
--echo ** --echo **
......
...@@ -2299,7 +2299,8 @@ String *Item_func_format::val_str_ascii(String *str) ...@@ -2299,7 +2299,8 @@ String *Item_func_format::val_str_ascii(String *str)
if (lc->grouping[0] > 0 && if (lc->grouping[0] > 0 &&
str_length >= dec_length + 1 + lc->grouping[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; int count;
const char *grouping= lc->grouping; const char *grouping= lc->grouping;
char sign_length= *str->ptr() == '-' ? 1 : 0; char sign_length= *str->ptr() == '-' ? 1 : 0;
...@@ -2323,7 +2324,7 @@ String *Item_func_format::val_str_ascii(String *str) ...@@ -2323,7 +2324,7 @@ String *Item_func_format::val_str_ascii(String *str)
count will be initialized to -1 and count will be initialized to -1 and
we'll never get into this "if" anymore. we'll never get into this "if" anymore.
*/ */
if (!count) if (count == 0)
{ {
*--dst= lc->thousand_sep; *--dst= lc->thousand_sep;
if (grouping[1]) if (grouping[1])
......
...@@ -384,6 +384,22 @@ TODO list: ...@@ -384,6 +384,22 @@ TODO list:
#endif #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. 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. Sets the thread state name in the constructor, resets on destructor.
...@@ -879,7 +895,7 @@ Query_cache::insert(Query_cache_tls *query_cache_tls, ...@@ -879,7 +895,7 @@ Query_cache::insert(Query_cache_tls *query_cache_tls,
if (is_disabled() || query_cache_tls->first_query_block == NULL) if (is_disabled() || query_cache_tls->first_query_block == NULL)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
DEBUG_SYNC(current_thd, "wait_in_query_cache_insert"); QC_DEBUG_SYNC("wait_in_query_cache_insert");
if (try_lock()) if (try_lock())
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -1975,7 +1991,7 @@ void Query_cache::flush() ...@@ -1975,7 +1991,7 @@ void Query_cache::flush()
if (is_disabled()) if (is_disabled())
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
DEBUG_SYNC(current_thd, "wait_in_query_cache_flush1"); QC_DEBUG_SYNC("wait_in_query_cache_flush1");
lock_and_suspend(); lock_and_suspend();
if (query_cache_size > 0) if (query_cache_size > 0)
...@@ -2315,7 +2331,7 @@ void Query_cache::free_cache() ...@@ -2315,7 +2331,7 @@ void Query_cache::free_cache()
void Query_cache::flush_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); my_hash_reset(&queries);
while (queries_blocks != 0) while (queries_blocks != 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment