From: Bjorn Munch
Date: September 16 2010 11:46am
Subject: bzr commit into mysql-5.5-mtr branch (bjorn.munch:3088)
List-Archive: http://lists.mysql.com/commits/118390
Message-Id: <201009161146.o8GBkExw028909@khepri15.norway.sun.com>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="===============1234804897=="
--===============1234804897==
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-16 [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,
--===============1234804897==
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: 2da0a7c2f7bca9cc36fc90fe0bab830abd47f49d
# timestamp: 2010-09-16 13:46:14 +0200
# source_branch: file:///home/bm136801/my/mysql-5.5/
# base_revision_id: bjorn.munch@stripped\
# 7p79p11wjb9xn8wn
#
# Begin bundle
IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWSh+XrAAMk7/gHexACZ9////
/////v////pgU75xn2Z7u733dE5XvHXnyU1x6p53YVmqa1zjcqp3311549e9p7ba77t8k9s233fe
lXFvm998718n3t6e9Ha57u9k00w9TrgDjGXVnXpnt0PQPPdxQTu7XPs055d1HTt994PS7Q50ZoH1
jdm5oe7Hvd2fd3sz2+Zpz0J33efFL7tOGfOE90Xvm9Owx2jve3Wd99z5B717z33vulwTfZm2t7hb
uonX3vVw9jXo9PS9vWrset6Yi71zcdOtdrVUocW5UNN569zz1DTd98vffVLNN3b5DUrBRpvYOEkh
AACMIDUGhojKabU0U21Rk9RPU9TTR+qB6jDUeo8EglCAAmhBCZUn6ephIeUxQ9Ro0A0AAAAAAEoB
BJoBBkmIJoCn4pPJD0nqHlA09IaHqAA0AeoJNKIQJoJ6BJ6npT0j0KGmag8oZANPU9QD1DRoAAAR
KIBBoTKaMTNAgyBT0Rp6mpp6nonom1GEzU0PUA0NAkSCACDRABMjITVHiT1P1T1PFD1A0yaaAABo
A+JrhBfOzq4lQqp+4grRIgGsNadf+1h3DV9GD8w+gc9EjxXQ/bjrpbn/9T20mdPUSVlLZK0ruPTD
e6AZwv+bDyi/gyf79zG7ccs/BoWFbv/JTqdKemZvyXhyL1XOKn6gTcvgqDdFG+Ebo7+1mX3rdeS9
cfq0okuoq/i3eQf4z+UVNf72LPOmR3sUQhdUGVMKXUT9Mnpcf3/+/3xNyP5fw1jjwJCU1P4HZJqu
fOfXkzoRFmJWTB/t/Q/hDUqL756v9v3+ELFnfllskjHTtG+PfHFB0WUT3O7NfA/5PfB737Dy9Ibh
wvfd02aVq0+W2sh+teWtp2egQj2+dvlaqMZd9N/Cp7OFsXp1r7L/RHnXkthfauN/HovJ0MxxZtnJ
nOSr5SmdEk8hvRaO/fGV4cmLQy/aj3zx3dvRsRtSWJWImlLzAufJpHQRTaUNF/AYlv12nOb4MdLJ
c70yKEQTGVHbvTO2Lti6/zum9ihgcZudjrw/tVCdKnbewcU/OrM1nxT4b7702mXUqUUhbHXiP8/Y
eRIDEAXSNbu0D+qBA2ENQxLHoudhxZ5bWR8Muq3vIrKhnPNrqlrrhqmz3msXxfGFa+9Vh1bfFmF4
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
--===============1234804897==--