From: Bjorn Munch
Date: September 20 2010 8:06am
Subject: bzr commit into mysql-5.5-mtr branch (bjorn.munch:3088)
List-Archive: http://lists.mysql.com/commits/118561
Message-Id: <201009200806.o8K86cnQ016812@khepri15.norway.sun.com>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="===============1064192271=="
--===============1064192271==
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
#At file:///home/bm136801/my/mtr-55/ based on revid:bjorn.munch@stripped
3088 Bjorn Munch 2010-09-20 [merge]
merge from 5.5
added:
mysql-test/include/ctype_filesort2.inc
modified:
client/CMakeLists.txt
client/sql_string.cc
configure.in
include/CMakeLists.txt
include/Makefile.am
include/m_ctype.h
mysql-test/r/ctype_utf16.result
mysql-test/r/ctype_utf32.result
mysql-test/r/ctype_utf8mb4.result
mysql-test/r/func_if.result
mysql-test/r/sp-destruct.result
mysql-test/t/ctype_utf16.test
mysql-test/t/ctype_utf32.test
mysql-test/t/ctype_utf8mb4.test
mysql-test/t/func_if.test
mysql-test/t/sp-destruct.test
scripts/CMakeLists.txt
scripts/make_win_bin_dist
sql/CMakeLists.txt
sql/field.cc
sql/item_cmpfunc.cc
sql/mdl.cc
sql/mdl.h
sql/sp.cc
sql/sql_base.cc
sql/sql_base.h
sql/sql_string.cc
sql/table.cc
strings/ctype-ucs2.c
strings/ctype-utf8.c
=== modified file 'client/CMakeLists.txt'
--- a/client/CMakeLists.txt 2010-08-12 15:19:57 +0000
+++ b/client/CMakeLists.txt 2010-09-06 11:26:23 +0000
@@ -64,7 +64,10 @@ MYSQL_ADD_EXECUTABLE(mysqlslap mysqlslap
SET_SOURCE_FILES_PROPERTIES(mysqlslap.c PROPERTIES COMPILE_FLAGS "-DTHREADS")
TARGET_LINK_LIBRARIES(mysqlslap mysqlclient)
-ADD_EXECUTABLE(echo echo.c)
+# "WIN32" also covers 64 bit. "echo" is used in some files below "mysql-test/".
+IF(WIN32)
+ MYSQL_ADD_EXECUTABLE(echo echo.c)
+ENDIF(WIN32)
SET_TARGET_PROPERTIES (mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow mysqlslap
PROPERTIES HAS_CXX TRUE)
=== modified file 'client/sql_string.cc'
--- a/client/sql_string.cc 2010-07-09 12:28:51 +0000
+++ b/client/sql_string.cc 2010-08-25 15:57:53 +0000
@@ -31,9 +31,12 @@
** String functions
*****************************************************************************/
-bool String::real_alloc(uint32 arg_length)
+bool String::real_alloc(uint32 length)
{
- arg_length=ALIGN_SIZE(arg_length+1);
+ uint32 arg_length= ALIGN_SIZE(length + 1);
+ DBUG_ASSERT(arg_length > length);
+ if (arg_length <= length)
+ return TRUE; /* Overflow */
str_length=0;
if (Alloced_length < arg_length)
{
@@ -56,6 +59,9 @@ bool String::real_alloc(uint32 arg_lengt
bool String::realloc(uint32 alloc_length)
{
uint32 len=ALIGN_SIZE(alloc_length+1);
+ DBUG_ASSERT(len > alloc_length);
+ if (len <= alloc_length)
+ return TRUE; /* Overflow */
if (Alloced_length < len)
{
char *new_ptr;
=== modified file 'configure.in'
--- a/configure.in 2010-08-25 14:05:33 +0000
+++ b/configure.in 2010-09-10 18:48:13 +0000
@@ -27,7 +27,7 @@ dnl
dnl When changing the major version number please also check the switch
dnl statement in mysqlbinlog::check_master_version(). You may also need
dnl to update version.c in ndb.
-AC_INIT([MySQL Server], [5.5.7-m3], [], [mysql])
+AC_INIT([MySQL Server], [5.5.7-rc], [], [mysql])
AC_CONFIG_SRCDIR([sql/mysqld.cc])
AC_CANONICAL_SYSTEM
=== modified file 'include/CMakeLists.txt'
--- a/include/CMakeLists.txt 2010-08-12 15:19:57 +0000
+++ b/include/CMakeLists.txt 2010-08-31 14:33:19 +0000
@@ -54,6 +54,7 @@ SET(HEADERS
keycache.h
m_ctype.h
my_attribute.h
+ my_compiler.h
${HEADERS_GEN_CONFIGURE}
)
=== modified file 'include/Makefile.am'
--- a/include/Makefile.am 2010-08-16 12:50:27 +0000
+++ b/include/Makefile.am 2010-09-10 18:48:13 +0000
@@ -32,8 +32,9 @@ pkginclude_HEADERS = $(HEADERS_ABI) my_d
decimal.h errmsg.h my_global.h my_net.h \
my_getopt.h sslopt-longopts.h my_dir.h \
sslopt-vars.h sslopt-case.h sql_common.h keycache.h \
- m_ctype.h my_attribute.h $(HEADERS_GEN_CONFIGURE) \
- $(HEADERS_GEN_MAKE) probes_mysql.h probes_mysql_nodtrace.h
+ m_ctype.h my_attribute.h my_compiler.h \
+ $(HEADERS_GEN_CONFIGURE) $(HEADERS_GEN_MAKE) \
+ probes_mysql.h probes_mysql_nodtrace.h
noinst_HEADERS = lf.h my_bit.h \
heap.h my_bitmap.h my_uctype.h password.h \
@@ -47,7 +48,7 @@ noinst_HEADERS = lf.h my_bit.h \
my_user.h my_atomic.h atomic/nolock.h \
atomic/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \
atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \
- atomic/solaris.h mysql/innodb_priv.h my_compiler.h
+ atomic/solaris.h mysql/innodb_priv.h
pkgpsiinclude_HEADERS = mysql/psi/psi.h mysql/psi/mysql_thread.h \
mysql/psi/mysql_file.h
=== modified file 'include/m_ctype.h'
--- a/include/m_ctype.h 2010-03-31 14:05:33 +0000
+++ b/include/m_ctype.h 2010-08-31 14:22:03 +0000
@@ -539,6 +539,11 @@ size_t my_strnxfrm_unicode(CHARSET_INFO
uchar *dst, size_t dstlen,
const uchar *src, size_t srclen);
+size_t my_strnxfrm_unicode_full_bin(CHARSET_INFO *,
+ uchar *dst, size_t dstlen,
+ const uchar *src, size_t srclen);
+size_t my_strnxfrmlen_unicode_full_bin(CHARSET_INFO *, size_t);
+
int my_wildcmp_unicode(CHARSET_INFO *cs,
const char *str, const char *str_end,
const char *wildstr, const char *wildend,
=== added file 'mysql-test/include/ctype_filesort2.inc'
--- a/mysql-test/include/ctype_filesort2.inc 1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/ctype_filesort2.inc 2010-08-31 14:22:03 +0000
@@ -0,0 +1,16 @@
+#
+# Testing filesort for full Unicode character sets
+# with supplementary characters.
+#
+
+--echo #
+--echo # Bug#55980 Character sets: supplementary character _bin ordering is wrong
+--echo #
+CREATE TABLE t1 AS SELECT REPEAT('a',1) AS a LIMIT 0;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (_utf8mb4 0xEFBE9D),(_utf8mb4 0xF0908E84);
+INSERT INTO t1 VALUES (_utf8mb4 0xCE85),(_utf8mb4 0xF4808080);
+SELECT HEX(a), HEX(CONVERT(a USING utf8mb4)) FROM t1 ORDER BY a;
+ALTER TABLE t1 ADD KEY(a);
+SELECT HEX(a), HEX(CONVERT(a USING utf8mb4)) FROM t1 ORDER BY a;
+DROP TABLE IF EXISTS t1;
=== modified file 'mysql-test/r/ctype_utf16.result'
--- a/mysql-test/r/ctype_utf16.result 2010-06-02 12:23:50 +0000
+++ b/mysql-test/r/ctype_utf16.result 2010-08-31 14:22:03 +0000
@@ -611,6 +611,31 @@ utf16_bin 00610009
utf16_bin 0061
utf16_bin 00610020
drop table t1;
+#
+# Bug#55980 Character sets: supplementary character _bin ordering is wrong
+#
+CREATE TABLE t1 AS SELECT REPEAT('a',1) AS a LIMIT 0;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(1) CHARACTER SET utf16 COLLATE utf16_bin NOT NULL DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (_utf8mb4 0xEFBE9D),(_utf8mb4 0xF0908E84);
+INSERT INTO t1 VALUES (_utf8mb4 0xCE85),(_utf8mb4 0xF4808080);
+SELECT HEX(a), HEX(CONVERT(a USING utf8mb4)) FROM t1 ORDER BY a;
+HEX(a) HEX(CONVERT(a USING utf8mb4))
+0385 CE85
+D800DF84 F0908E84
+DBC0DC00 F4808080
+FF9D EFBE9D
+ALTER TABLE t1 ADD KEY(a);
+SELECT HEX(a), HEX(CONVERT(a USING utf8mb4)) FROM t1 ORDER BY a;
+HEX(a) HEX(CONVERT(a USING utf8mb4))
+0385 CE85
+D800DF84 F0908E84
+DBC0DC00 F4808080
+FF9D EFBE9D
+DROP TABLE IF EXISTS t1;
select @@collation_connection;
@@collation_connection
utf16_bin
=== modified file 'mysql-test/r/ctype_utf32.result'
--- a/mysql-test/r/ctype_utf32.result 2010-08-26 12:36:33 +0000
+++ b/mysql-test/r/ctype_utf32.result 2010-09-10 18:48:13 +0000
@@ -610,6 +610,31 @@ utf32_bin 0000006100000009
utf32_bin 00000061
utf32_bin 0000006100000020
drop table t1;
+#
+# Bug#55980 Character sets: supplementary character _bin ordering is wrong
+#
+CREATE TABLE t1 AS SELECT REPEAT('a',1) AS a LIMIT 0;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(1) CHARACTER SET utf32 COLLATE utf32_bin NOT NULL DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (_utf8mb4 0xEFBE9D),(_utf8mb4 0xF0908E84);
+INSERT INTO t1 VALUES (_utf8mb4 0xCE85),(_utf8mb4 0xF4808080);
+SELECT HEX(a), HEX(CONVERT(a USING utf8mb4)) FROM t1 ORDER BY a;
+HEX(a) HEX(CONVERT(a USING utf8mb4))
+00000385 CE85
+0000FF9D EFBE9D
+00010384 F0908E84
+00100000 F4808080
+ALTER TABLE t1 ADD KEY(a);
+SELECT HEX(a), HEX(CONVERT(a USING utf8mb4)) FROM t1 ORDER BY a;
+HEX(a) HEX(CONVERT(a USING utf8mb4))
+00000385 CE85
+0000FF9D EFBE9D
+00010384 F0908E84
+00100000 F4808080
+DROP TABLE IF EXISTS t1;
select @@collation_connection;
@@collation_connection
utf32_bin
=== modified file 'mysql-test/r/ctype_utf8mb4.result'
--- a/mysql-test/r/ctype_utf8mb4.result 2010-06-02 12:23:50 +0000
+++ b/mysql-test/r/ctype_utf8mb4.result 2010-08-31 14:22:03 +0000
@@ -987,6 +987,31 @@ utf8mb4_bin 6109
utf8mb4_bin 61
utf8mb4_bin 6120
drop table t1;
+#
+# Bug#55980 Character sets: supplementary character _bin ordering is wrong
+#
+CREATE TABLE t1 AS SELECT REPEAT('a',1) AS a LIMIT 0;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (_utf8mb4 0xEFBE9D),(_utf8mb4 0xF0908E84);
+INSERT INTO t1 VALUES (_utf8mb4 0xCE85),(_utf8mb4 0xF4808080);
+SELECT HEX(a), HEX(CONVERT(a USING utf8mb4)) FROM t1 ORDER BY a;
+HEX(a) HEX(CONVERT(a USING utf8mb4))
+CE85 CE85
+EFBE9D EFBE9D
+F0908E84 F0908E84
+F4808080 F4808080
+ALTER TABLE t1 ADD KEY(a);
+SELECT HEX(a), HEX(CONVERT(a USING utf8mb4)) FROM t1 ORDER BY a;
+HEX(a) HEX(CONVERT(a USING utf8mb4))
+CE85 CE85
+EFBE9D EFBE9D
+F0908E84 F0908E84
+F4808080 F4808080
+DROP TABLE IF EXISTS t1;
select @@collation_connection;
@@collation_connection
utf8mb4_bin
=== modified file 'mysql-test/r/func_if.result'
--- a/mysql-test/r/func_if.result 2008-12-12 14:19:33 +0000
+++ b/mysql-test/r/func_if.result 2010-08-25 15:57:53 +0000
@@ -186,3 +186,13 @@ MAX(IFNULL(CAST(c AS UNSIGNED), 0))
12345678901234567890
DROP TABLE t1;
End of 5.0 tests
+#
+# Bug#55077: Assertion failed: width > 0 && to != ((void *)0), file .\dtoa.c
+#
+CREATE TABLE t1 (a LONGBLOB, b DOUBLE);
+INSERT INTO t1 VALUES (NULL, 0), (NULL, 1);
+SELECT IF(b, (SELECT a FROM t1 LIMIT 1), b) c FROM t1 GROUP BY c;
+c
+NULL
+0
+DROP TABLE t1;
=== modified file 'mysql-test/r/sp-destruct.result'
--- a/mysql-test/r/sp-destruct.result 2010-03-03 09:24:53 +0000
+++ b/mysql-test/r/sp-destruct.result 2010-08-31 13:49:41 +0000
@@ -134,3 +134,19 @@ Warning 1405 Failed to revoke all privil
# Restore the procs_priv table
RENAME TABLE procs_priv_backup TO mysql.procs_priv;
FLUSH TABLE mysql.procs_priv;
+#
+# Bug #56137 "Assertion `thd->lock == 0' failed on upgrading from
+# 5.1.50 to 5.5.6".
+#
+drop database if exists mysqltest;
+# Backup mysql.proc.
+flush table mysql.proc;
+create database mysqltest;
+# Corrupt mysql.proc to make it unusable by current version of server.
+alter table mysql.proc drop column type;
+# The below statement should not cause assertion failure.
+drop database mysqltest;
+Warnings:
+Error 1547 Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
+# Restore mysql.proc.
+drop table mysql.proc;
=== modified file 'mysql-test/t/ctype_utf16.test'
--- a/mysql-test/t/ctype_utf16.test 2010-06-02 12:23:50 +0000
+++ b/mysql-test/t/ctype_utf16.test 2010-08-31 14:22:03 +0000
@@ -326,6 +326,7 @@ SET collation_connection='utf16_general_
SET NAMES latin1;
SET collation_connection='utf16_bin';
-- source include/ctype_filesort.inc
+-- source include/ctype_filesort2.inc
-- source include/ctype_like_escape.inc
#
=== modified file 'mysql-test/t/ctype_utf32.test'
--- a/mysql-test/t/ctype_utf32.test 2010-08-26 12:36:33 +0000
+++ b/mysql-test/t/ctype_utf32.test 2010-09-10 18:48:13 +0000
@@ -328,6 +328,7 @@ SET collation_connection='utf32_general_
SET NAMES latin1;
SET collation_connection='utf32_bin';
-- source include/ctype_filesort.inc
+-- source include/ctype_filesort2.inc
-- source include/ctype_like_escape.inc
#
=== modified file 'mysql-test/t/ctype_utf8mb4.test'
--- a/mysql-test/t/ctype_utf8mb4.test 2010-06-02 12:23:50 +0000
+++ b/mysql-test/t/ctype_utf8mb4.test 2010-08-31 14:22:03 +0000
@@ -733,6 +733,7 @@ SET collation_connection='utf8mb4_genera
-- source include/ctype_german.inc
SET collation_connection='utf8mb4_bin';
-- source include/ctype_filesort.inc
+-- source include/ctype_filesort2.inc
-- source include/ctype_like_escape.inc
#
=== modified file 'mysql-test/t/func_if.test'
--- a/mysql-test/t/func_if.test 2008-12-12 13:16:25 +0000
+++ b/mysql-test/t/func_if.test 2010-08-25 15:57:53 +0000
@@ -165,3 +165,15 @@ DROP TABLE t1;
--echo End of 5.0 tests
+
+
+--echo #
+--echo # Bug#55077: Assertion failed: width > 0 && to != ((void *)0), file .\dtoa.c
+--echo #
+
+CREATE TABLE t1 (a LONGBLOB, b DOUBLE);
+INSERT INTO t1 VALUES (NULL, 0), (NULL, 1);
+
+SELECT IF(b, (SELECT a FROM t1 LIMIT 1), b) c FROM t1 GROUP BY c;
+
+DROP TABLE t1;
=== modified file 'mysql-test/t/sp-destruct.test'
--- a/mysql-test/t/sp-destruct.test 2010-03-03 09:24:53 +0000
+++ b/mysql-test/t/sp-destruct.test 2010-08-31 13:49:41 +0000
@@ -222,3 +222,33 @@ SHOW WARNINGS;
--echo # Restore the procs_priv table
RENAME TABLE procs_priv_backup TO mysql.procs_priv;
FLUSH TABLE mysql.procs_priv;
+
+
+--echo #
+--echo # Bug #56137 "Assertion `thd->lock == 0' failed on upgrading from
+--echo # 5.1.50 to 5.5.6".
+--echo #
+--disable_warnings
+drop database if exists mysqltest;
+--enable_warnings
+--echo # Backup mysql.proc.
+flush table mysql.proc;
+let $MYSQLD_DATADIR= `select @@datadir`;
+--copy_file $MYSQLD_DATADIR/mysql/proc.frm $MYSQLTEST_VARDIR/tmp/proc.frm
+--copy_file $MYSQLD_DATADIR/mysql/proc.MYD $MYSQLTEST_VARDIR/tmp/proc.MYD
+--copy_file $MYSQLD_DATADIR/mysql/proc.MYI $MYSQLTEST_VARDIR/tmp/proc.MYI
+
+create database mysqltest;
+--echo # Corrupt mysql.proc to make it unusable by current version of server.
+alter table mysql.proc drop column type;
+--echo # The below statement should not cause assertion failure.
+drop database mysqltest;
+
+--echo # Restore mysql.proc.
+drop table mysql.proc;
+--copy_file $MYSQLTEST_VARDIR/tmp/proc.frm $MYSQLD_DATADIR/mysql/proc.frm
+--copy_file $MYSQLTEST_VARDIR/tmp/proc.MYD $MYSQLD_DATADIR/mysql/proc.MYD
+--copy_file $MYSQLTEST_VARDIR/tmp/proc.MYI $MYSQLD_DATADIR/mysql/proc.MYI
+--remove_file $MYSQLTEST_VARDIR/tmp/proc.frm
+--remove_file $MYSQLTEST_VARDIR/tmp/proc.MYD
+--remove_file $MYSQLTEST_VARDIR/tmp/proc.MYI
=== modified file 'scripts/CMakeLists.txt'
--- a/scripts/CMakeLists.txt 2010-08-19 12:11:31 +0000
+++ b/scripts/CMakeLists.txt 2010-09-07 15:05:16 +0000
@@ -139,6 +139,7 @@ ELSE()
ENDIF()
SET(HOSTNAME "hostname")
+SET(MYSQLD_USER "mysql")
# Required for mysqlbug until autotools are deprecated, once done remove these
# and expand default cmake variables
=== modified file 'scripts/make_win_bin_dist'
--- a/scripts/make_win_bin_dist 2010-07-23 20:14:04 +0000
+++ b/scripts/make_win_bin_dist 2010-08-31 14:33:19 +0000
@@ -260,6 +260,7 @@ cp include/mysql.h \
include/keycache.h \
include/m_ctype.h \
include/my_attribute.h \
+ include/my_compiler.h \
include/mysqld_error.h \
include/sql_state.h \
include/mysqld_ername.h \
=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt 2010-08-18 11:29:04 +0000
+++ b/sql/CMakeLists.txt 2010-08-31 11:06:56 +0000
@@ -271,8 +271,7 @@ IF(WIN32 AND MYSQLD_EXECUTABLE)
COMMAND ${CMAKE_COMMAND}
${CONFIG_PARAM} -P ${CMAKE_CURRENT_BINARY_DIR}/create_initial_db.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data
- COMMAND ${CMAKE_COMMAND} -E touch initdb.dep
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/initdb.dep
DEPENDS mysqld
)
ADD_CUSTOM_TARGET(initial_database
=== modified file 'sql/field.cc'
--- a/sql/field.cc 2010-08-23 09:56:21 +0000
+++ b/sql/field.cc 2010-08-25 15:57:53 +0000
@@ -4189,6 +4189,7 @@ String *Field_float::val_str(String *val
String *val_ptr __attribute__((unused)))
{
ASSERT_COLUMN_MARKED_FOR_READ;
+ DBUG_ASSERT(field_length <= MAX_FIELD_CHARLENGTH);
float nr;
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
@@ -4199,8 +4200,13 @@ String *Field_float::val_str(String *val
#endif
memcpy(&nr, ptr, sizeof(nr));
- uint to_length=max(field_length,70);
- val_buffer->alloc(to_length);
+ uint to_length= 70;
+ if (val_buffer->alloc(to_length))
+ {
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
+ return val_buffer;
+ }
+
char *to=(char*) val_buffer->ptr();
size_t len;
@@ -4209,7 +4215,7 @@ String *Field_float::val_str(String *val
else
{
/*
- We are safe here because the buffer length is >= 70, and
+ We are safe here because the buffer length is 70, and
fabs(float) < 10^39, dec < NOT_FIXED_DEC. So the resulting string
will be not longer than 69 chars + terminating '\0'.
*/
@@ -4506,6 +4512,7 @@ String *Field_double::val_str(String *va
String *val_ptr __attribute__((unused)))
{
ASSERT_COLUMN_MARKED_FOR_READ;
+ DBUG_ASSERT(field_length <= MAX_FIELD_CHARLENGTH);
double nr;
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
@@ -4515,9 +4522,13 @@ String *Field_double::val_str(String *va
else
#endif
doubleget(nr,ptr);
+ uint to_length= DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE;
+ if (val_buffer->alloc(to_length))
+ {
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
+ return val_buffer;
+ }
- uint to_length=max(field_length, DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE);
- val_buffer->alloc(to_length);
char *to=(char*) val_buffer->ptr();
size_t len;
=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc 2010-08-19 11:55:35 +0000
+++ b/sql/item_cmpfunc.cc 2010-08-25 15:57:53 +0000
@@ -2560,27 +2560,30 @@ Item_func_if::fix_length_and_dec()
cached_result_type= arg2_type;
collation.set(args[2]->collation.collation);
cached_field_type= args[2]->field_type();
+ max_length= args[2]->max_length;
+ return;
}
- else if (null2)
+
+ if (null2)
{
cached_result_type= arg1_type;
collation.set(args[1]->collation.collation);
cached_field_type= args[1]->field_type();
+ max_length= args[1]->max_length;
+ return;
+ }
+
+ agg_result_type(&cached_result_type, args + 1, 2);
+ if (cached_result_type == STRING_RESULT)
+ {
+ if (agg_arg_charsets_for_string_result(collation, args + 1, 2))
+ return;
}
else
{
- agg_result_type(&cached_result_type, args+1, 2);
- if (cached_result_type == STRING_RESULT)
- {
- if (agg_arg_charsets_for_string_result(collation, args + 1, 2))
- return;
- }
- else
- {
- collation.set_numeric(); // Number
- }
- cached_field_type= agg_field_type(args + 1, 2);
+ collation.set_numeric(); // Number
}
+ cached_field_type= agg_field_type(args + 1, 2);
uint32 char_length;
if ((cached_result_type == DECIMAL_RESULT )
=== modified file 'sql/mdl.cc'
--- a/sql/mdl.cc 2010-08-12 13:50:23 +0000
+++ b/sql/mdl.cc 2010-09-06 17:29:02 +0000
@@ -124,7 +124,6 @@ public:
Deadlock_detection_visitor(MDL_context *start_node_arg)
: m_start_node(start_node_arg),
m_victim(NULL),
- m_current_search_depth(0),
m_found_deadlock(FALSE)
{}
virtual bool enter_node(MDL_context *node);
@@ -133,6 +132,8 @@ public:
virtual bool inspect_edge(MDL_context *dest);
MDL_context *get_victim() const { return m_victim; }
+
+ void abort_traversal(MDL_context *node);
private:
/**
Change the deadlock victim to a new one if it has lower deadlock
@@ -147,13 +148,6 @@ private:
MDL_context *m_start_node;
/** If a deadlock is found, the context that identifies the victim. */
MDL_context *m_victim;
- /** Set to the 0 at start. Increased whenever
- we descend into another MDL context (aka traverse to the next
- wait-for graph node). When MAX_SEARCH_DEPTH is reached, we
- assume that a deadlock is found, even if we have not found a
- loop.
- */
- uint m_current_search_depth;
/** TRUE if we found a deadlock. */
bool m_found_deadlock;
/**
@@ -187,7 +181,7 @@ private:
bool Deadlock_detection_visitor::enter_node(MDL_context *node)
{
- m_found_deadlock= ++m_current_search_depth >= MAX_SEARCH_DEPTH;
+ m_found_deadlock= m_current_search_depth >= MAX_SEARCH_DEPTH;
if (m_found_deadlock)
{
DBUG_ASSERT(! m_victim);
@@ -207,7 +201,6 @@ bool Deadlock_detection_visitor::enter_n
void Deadlock_detection_visitor::leave_node(MDL_context *node)
{
- --m_current_search_depth;
if (m_found_deadlock)
opt_change_victim_to(node);
}
@@ -252,6 +245,21 @@ Deadlock_detection_visitor::opt_change_v
/**
+ Abort traversal of a wait-for graph and report a deadlock.
+
+ @param node Node which we were about to visit when abort
+ was initiated.
+*/
+
+void Deadlock_detection_visitor::abort_traversal(MDL_context *node)
+{
+ DBUG_ASSERT(! m_victim);
+ m_found_deadlock= TRUE;
+ opt_change_victim_to(node);
+}
+
+
+/**
Get a bit corresponding to enum_mdl_type value in a granted/waiting bitmaps
and compatibility matrices.
*/
@@ -2056,8 +2064,13 @@ bool MDL_lock::visit_subgraph(MDL_ticket
are visiting it but this is OK: in the worst case we might do some
extra work and one more context might be chosen as a victim.
*/
+ ++gvisitor->m_current_search_depth;
+
if (gvisitor->enter_node(src_ctx))
+ {
+ --gvisitor->m_current_search_depth;
goto end;
+ }
/*
We do a breadth-first search first -- that is, inspect all
@@ -2114,6 +2127,7 @@ bool MDL_lock::visit_subgraph(MDL_ticket
end_leave_node:
gvisitor->leave_node(src_ctx);
+ --gvisitor->m_current_search_depth;
end:
mysql_prlock_unlock(&m_rwlock);
=== modified file 'sql/mdl.h'
--- a/sql/mdl.h 2010-08-12 13:50:23 +0000
+++ b/sql/mdl.h 2010-09-06 17:29:02 +0000
@@ -385,7 +385,10 @@ public:
virtual bool inspect_edge(MDL_context *dest) = 0;
virtual ~MDL_wait_for_graph_visitor();
- MDL_wait_for_graph_visitor() :m_lock_open_count(0) {}
+ MDL_wait_for_graph_visitor() :m_lock_open_count(0),
+ m_current_search_depth(0)
+ { }
+ virtual void abort_traversal(MDL_context *node) = 0;
public:
/**
XXX, hack: During deadlock search, we may need to
@@ -396,6 +399,17 @@ public:
LOCK_open since it has significant performance impacts.
*/
uint m_lock_open_count;
+ /**
+ Set to the 0 at start. Increased whenever
+ we descend into another MDL context (aka traverse to the next
+ wait-for graph node). When MAX_SEARCH_DEPTH is reached, we
+ assume that a deadlock is found, even if we have not found a
+ loop.
+
+ XXX: This member belongs to this class only temporarily until
+ bug #56405 is fixed.
+ */
+ uint m_current_search_depth;
};
/**
=== modified file 'sql/sp.cc'
--- a/sql/sp.cc 2010-07-27 10:25:53 +0000
+++ b/sql/sp.cc 2010-08-31 13:49:41 +0000
@@ -440,6 +440,7 @@ static TABLE *open_proc_table_for_update
{
TABLE_LIST table_list;
TABLE *table;
+ MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint();
DBUG_ENTER("open_proc_table_for_update");
table_list.init_one_table("mysql", 5, "proc", 4, "proc", TL_WRITE);
@@ -450,6 +451,9 @@ static TABLE *open_proc_table_for_update
if (!proc_table_intact.check(table, &proc_table_def))
DBUG_RETURN(table);
+ close_thread_tables(thd);
+ thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
+
DBUG_RETURN(NULL);
}
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2010-08-20 08:24:32 +0000
+++ b/sql/sql_base.cc 2010-09-06 17:29:02 +0000
@@ -100,6 +100,8 @@ bool No_such_table_error_handler::safely
TABLE_SHAREs, refresh_version and the table id counter.
*/
mysql_mutex_t LOCK_open;
+mysql_mutex_t LOCK_dd_owns_lock_open;
+uint dd_owns_lock_open= 0;
#ifdef HAVE_PSI_INTERFACE
static PSI_mutex_key key_LOCK_open;
@@ -298,6 +300,7 @@ bool table_def_init(void)
init_tdc_psi_keys();
#endif
mysql_mutex_init(key_LOCK_open, &LOCK_open, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(NULL, &LOCK_dd_owns_lock_open, MY_MUTEX_INIT_FAST);
oldest_unused_share= &end_of_unused_share;
end_of_unused_share.prev= &oldest_unused_share;
@@ -341,6 +344,7 @@ void table_def_free(void)
table_def_inited= 0;
/* Free table definitions. */
my_hash_free(&table_def_cache);
+ mysql_mutex_destroy(&LOCK_dd_owns_lock_open);
mysql_mutex_destroy(&LOCK_open);
}
DBUG_VOID_RETURN;
=== modified file 'sql/sql_base.h'
--- a/sql/sql_base.h 2010-08-20 08:24:32 +0000
+++ b/sql/sql_base.h 2010-09-06 17:29:02 +0000
@@ -71,6 +71,8 @@ enum enum_tdc_remove_table_type {TDC_RT_
bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
extern mysql_mutex_t LOCK_open;
+extern mysql_mutex_t LOCK_dd_owns_lock_open;
+extern uint dd_owns_lock_open;
bool table_cache_init(void);
void table_cache_free(void);
bool table_def_init(void);
=== modified file 'sql/sql_string.cc'
--- a/sql/sql_string.cc 2010-07-09 12:28:51 +0000
+++ b/sql/sql_string.cc 2010-08-25 15:57:53 +0000
@@ -31,9 +31,12 @@
** String functions
*****************************************************************************/
-bool String::real_alloc(uint32 arg_length)
+bool String::real_alloc(uint32 length)
{
- arg_length=ALIGN_SIZE(arg_length+1);
+ uint32 arg_length= ALIGN_SIZE(length + 1);
+ DBUG_ASSERT(arg_length > length);
+ if (arg_length <= length)
+ return TRUE; /* Overflow */
str_length=0;
if (Alloced_length < arg_length)
{
@@ -56,6 +59,9 @@ bool String::real_alloc(uint32 arg_lengt
bool String::realloc(uint32 alloc_length)
{
uint32 len=ALIGN_SIZE(alloc_length+1);
+ DBUG_ASSERT(len > alloc_length);
+ if (len <= alloc_length)
+ return TRUE; /* Overflow */
if (Alloced_length < len)
{
char *new_ptr;
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2010-08-18 11:29:04 +0000
+++ b/sql/table.cc 2010-09-06 17:29:02 +0000
@@ -3085,7 +3085,30 @@ bool TABLE_SHARE::visit_subgraph(Wait_fo
holding a write-lock on MDL_lock::m_rwlock.
*/
if (gvisitor->m_lock_open_count++ == 0)
+ {
+ /*
+ To circumvent bug #56405 "Deadlock in the MDL deadlock detector"
+ we don't try to lock LOCK_open mutex if some thread doing
+ deadlock detection already owns it and current search depth is
+ greater than 0. Instead we report a deadlock.
+
+ TODO/FIXME: The proper fix for this bug is to use rwlocks for
+ protection of table shares/instead of LOCK_open.
+ Unfortunately it requires more effort/has significant
+ performance effect.
+ */
+ mysql_mutex_lock(&LOCK_dd_owns_lock_open);
+ if (gvisitor->m_current_search_depth > 0 && dd_owns_lock_open > 0)
+ {
+ mysql_mutex_unlock(&LOCK_dd_owns_lock_open);
+ --gvisitor->m_lock_open_count;
+ gvisitor->abort_traversal(src_ctx);
+ return TRUE;
+ }
+ ++dd_owns_lock_open;
+ mysql_mutex_unlock(&LOCK_dd_owns_lock_open);
mysql_mutex_lock(&LOCK_open);
+ }
I_P_List_iterator
tables_it(used_tables);
@@ -3100,8 +3123,12 @@ bool TABLE_SHARE::visit_subgraph(Wait_fo
goto end;
}
+ ++gvisitor->m_current_search_depth;
if (gvisitor->enter_node(src_ctx))
+ {
+ --gvisitor->m_current_search_depth;
goto end;
+ }
while ((table= tables_it++))
{
@@ -3124,10 +3151,16 @@ bool TABLE_SHARE::visit_subgraph(Wait_fo
end_leave_node:
gvisitor->leave_node(src_ctx);
+ --gvisitor->m_current_search_depth;
end:
if (gvisitor->m_lock_open_count-- == 1)
+ {
mysql_mutex_unlock(&LOCK_open);
+ mysql_mutex_lock(&LOCK_dd_owns_lock_open);
+ --dd_owns_lock_open;
+ mysql_mutex_unlock(&LOCK_dd_owns_lock_open);
+ }
return result;
}
=== modified file 'strings/ctype-ucs2.c'
--- a/strings/ctype-ucs2.c 2010-07-23 20:09:27 +0000
+++ b/strings/ctype-ucs2.c 2010-08-31 14:22:03 +0000
@@ -1469,7 +1469,7 @@ my_strnncoll_utf16_bin(CHARSET_INFO *cs,
}
if (s_wc != t_wc)
{
- return s_wc > t_wc ? 1 : -1;
+ return my_bincmp(s, s + s_res, t, t + t_res);
}
s+= s_res;
@@ -1511,7 +1511,7 @@ my_strnncollsp_utf16_bin(CHARSET_INFO *c
if (s_wc != t_wc)
{
- return s_wc > t_wc ? 1 : -1;
+ return my_bincmp(s, s + s_res, t, t + t_res);
}
s+= s_res;
@@ -1684,8 +1684,8 @@ static MY_COLLATION_HANDLER my_collation
NULL, /* init */
my_strnncoll_utf16_bin,
my_strnncollsp_utf16_bin,
- my_strnxfrm_unicode,
- my_strnxfrmlen_simple,
+ my_strnxfrm_unicode_full_bin,
+ my_strnxfrmlen_unicode_full_bin,
my_like_range_utf16,
my_wildcmp_utf16_bin,
my_strcasecmp_mb2_or_mb4,
@@ -2711,8 +2711,8 @@ static MY_COLLATION_HANDLER my_collation
NULL, /* init */
my_strnncoll_utf32_bin,
my_strnncollsp_utf32_bin,
- my_strnxfrm_unicode,
- my_strnxfrmlen_utf32,
+ my_strnxfrm_unicode_full_bin,
+ my_strnxfrmlen_unicode_full_bin,
my_like_range_utf32,
my_wildcmp_utf32_bin,
my_strcasecmp_mb2_or_mb4,
=== modified file 'strings/ctype-utf8.c'
--- a/strings/ctype-utf8.c 2010-03-04 11:00:32 +0000
+++ b/strings/ctype-utf8.c 2010-08-31 14:22:03 +0000
@@ -1893,7 +1893,13 @@ my_wildcmp_unicode(CHARSET_INFO *cs,
/*
- This function is shared between utf8mb3/utf8mb4/ucs2/utf16/utf32
+ Store sorting weights using 2 bytes per character.
+
+ This function is shared between
+ - utf8mb3_general_ci, utf8_bin, ucs2_general_ci, ucs2_bin
+ which support BMP only (U+0000..U+FFFF).
+ - utf8mb4_general_ci, utf16_general_ci, utf32_general_ci,
+ which map all supplementary characters to weight 0xFFFD.
*/
size_t
my_strnxfrm_unicode(CHARSET_INFO *cs,
@@ -1937,6 +1943,70 @@ my_strnxfrm_unicode(CHARSET_INFO *cs,
}
+/*
+ Store sorting weights using 3 bytes per character.
+ This function is shared between utf8mb4_bin, utf16_bin, utf32_bin.
+*/
+size_t
+my_strnxfrm_unicode_full_bin(CHARSET_INFO *cs,
+ uchar *dst, size_t dstlen,
+ const uchar *src, size_t srclen)
+{
+ my_wc_t wc;
+ uchar *de= dst + dstlen;
+ uchar *de_beg= de - 2; /* The beginning of the last chunk */
+ const uchar *se = src + srclen;
+
+ LINT_INIT(wc);
+ DBUG_ASSERT(src);
+ DBUG_ASSERT(cs->state & MY_CS_BINSORT);
+
+ while (dst < de_beg)
+ {
+ int res;
+ if ((res= cs->cset->mb_wc(cs, &wc, src, se)) <= 0)
+ break;
+ src+= res;
+ if (cs->mbminlen == 2) /* utf16_bin */
+ {
+ /*
+ Reorder code points to weights as follows:
+ U+0000..U+D7FF -> [00][00][00]..[00][D7][FF] BMP part #1
+ U+10000..U+10FFFF -> [01][00][00]..[10][FF][FF] Supplementary
+ U+E000..U+FFFF -> [20][E0][00]..[20][FF][FF] BMP part #2
+ */
+ if (wc >= 0xE000 && wc <= 0xFFFF)
+ wc+= 0x200000;
+ }
+ *dst++= (uchar) (wc >> 16);
+ *dst++= (uchar) ((wc >> 8) & 0xFF);
+ *dst++= (uchar) (wc & 0xFF);
+ }
+
+ while (dst < de_beg) /* Fill the tail with keys for space character */
+ {
+ *dst++= 0x00;
+ *dst++= 0x00;
+ *dst++= 0x20;
+ }
+
+ /* Clear the last one or two bytes, if "dstlen" was not divisible by 3 */
+ if (dst < de)
+ {
+ *dst++= 0x00;
+ if (dst < de)
+ *dst= 0x00;
+ }
+
+ return dstlen;
+}
+
+
+size_t
+my_strnxfrmlen_unicode_full_bin(CHARSET_INFO *cs, size_t len)
+{
+ return ((len + 3) / cs->mbmaxlen) * 3;
+}
#endif /* HAVE_UNIDATA */
@@ -5067,8 +5137,8 @@ static MY_COLLATION_HANDLER my_collation
NULL, /* init */
my_strnncoll_mb_bin,
my_strnncollsp_mb_bin,
- my_strnxfrm_unicode,
- my_strnxfrmlen_utf8mb4,
+ my_strnxfrm_unicode_full_bin,
+ my_strnxfrmlen_unicode_full_bin,
my_like_range_mb,
my_wildcmp_mb_bin,
my_strcasecmp_mb_bin,
--===============1064192271==
MIME-Version: 1.0
Content-Type: text/bzr-bundle; charset="us-ascii";
name="bzr/bjorn.munch@stripped"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: bjorn.munch@stripped
# target_branch: file:///home/bm136801/my/mtr-55/
# testament_sha1: 7a5bce2e7cd02d10d7a74f5ec92f1f1bc58c292e
# timestamp: 2010-09-20 10:06:38 +0200
# source_branch: file:///home/bm136801/my/mysql-5.5/
# base_revision_id: bjorn.munch@stripped\
# 7p79p11wjb9xn8wn
#
# Begin bundle
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
ngqWGy/E5iH4eNuJyKo2kn9Tc+hleSUIadH5bgOGQTzNKHyv4H2B1WG06G+cl40wdZT3+IcUYgxQ
DD7d5dmMOSy2b2Yy2QQMhwyj3lss3z5CV2wE+hTSbvmuIqO1ookVrZeplXr0OJwCjW2JHDZ7P2xK
mSklT/5gNKQJrRPJWC9xSyt4l+9Z2TxJ5/lqdyZwYLFkvTu/rKjpTbOy3aJMl6/a7pGP8rWIdIw8
lM4yv5mhyfzdTeUdqUPS+k1MDjg5xtvBi4eVD49ZRlV9HbpqVu0CYv8LaOUkiwkkDsKWtbuKilSz
LP5xWlGoKQsHpv+bykuw7Mu3bjYst7CaKkFkzum/W9TtNUF2GSqUuzEpQxFX3o3oeXM9a4nsSyq5
7GibRxXFFrpCH27aprIlSP3fXCbyODhXFU+/7SNSv6B4Gp36J1puMlV5M9ReqA/DlJ7TOq2hEl1X
9ps3Ej9M5qeHP4VMqRzP9d7JAkyz8yze6RQxFiEh7dtxMSXm0ja+kZV2HIkSkO0IcGzQIJvwX4+P
QEfSczJvHb4+/7r6bFiT5tb7170Eoj/dzXacdbwwVVMXcEHLegQ51IxxcvWd/2jM/Ep4wpgilXqY
NltdZjyziRi2QWuPz7SREvo+VZWb3lceDeDC7rFNVz3yc6mUypNYXUwdUZ1ypPzNh7yfCkdXJbIU
69j+bjxpFQUXjfpBtzoZZ/LWO0ehJsq1YkkqQfWDlL8PdZRJ6+bHVUvwqpneML7sJFjG+dAiIkcY
Kq1UMJciZPQe52Mo5tum8d26yb7KXMt0plwVKyS7Sm9X3LY1ZOSYiA3ZTJhmmP+wa8pitfXtEWp4
dOq1W1J0GqyFXRo+hSxsmZ9kBDQ63hhVN1cuGTfDv2tO0ce1iQ6VrkisN5nhXGOmu+fPtYXg02Rr
pt6dKYnXtJY4vFS3xxQhXUpm6v52cj1I2Mo55qTnjwxFfAkRyJehJopq8NqiCygWVrJRzhK7Qv9p
b6YixoYny+Vq22MVM+7B5dj2I2a4mVwViPxAvuBOC0GHszLA4GzM7Sg27q5JIM8q/2xxMoqYY8ps
hAhFPB5L8W9NvR5rOZjaTw8YCMzjkJ4bfUY5kWxH1auJzel3W+973nRZJAaFG089Gg2sx8XpK9Fe
GIUpo1F5UtjcKVXAlj9ZJ/X+CXuL4D0qkEbpd39RvmJOZuHRcEDZZGH9DJzol+Ohr3Pm2cntRU6x
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
--===============1064192271==--