From e976b27ea65c365953199ac6be9b80479d149525 Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Wed, 11 Mar 2009 19:09:56 +0100 Subject: [PATCH 01/21] Bug#36751: Segmentation fault in ctype-bin.c:308; Linux 86_64, with-max-indexes=128 mysqld is optimized for the default case (up to 64-indices); for a greater number of indices it goes through a different code path. As that code-path is a compile-time option and can not easily be covered in standard tests, bitrot occurred. key-fields need an explicit initialization in the non- optimized case; this setup was presumably not added when a new key- vector was added. Changeset adds the necessary initialisations. No test case added due to dependence on compile-time option. sql/sql_select.cc: Init merge_keys as well. If we don't, things blow up badly outside of the optimized-for-64-keys case! sql/table.cc: Init merge_keys as well. If we don't, things blow up badly outside of the optimized-for-64-keys case! --- sql/sql_select.cc | 1 + sql/table.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bea748562eb..825d3c870d8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9788,6 +9788,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, table->in_use= thd; table->quick_keys.init(); table->covering_keys.init(); + table->merge_keys.init(); table->keys_in_use_for_query.init(); table->s= share; diff --git a/sql/table.cc b/sql/table.cc index 17454ffb012..f67929ad96b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1652,6 +1652,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, goto err; outparam->quick_keys.init(); outparam->covering_keys.init(); + outparam->merge_keys.init(); outparam->keys_in_use_for_query.init(); /* Allocate handler */ From 99524127985de26ee61ccc7fd93165f5c14b450b Mon Sep 17 00:00:00 2001 From: Leonard Zhou Date: Thu, 12 Mar 2009 17:48:41 +0800 Subject: [PATCH 02/21] BUG#39858 rpl.rpl_rotate (rpl.rpl_rotate_logs) failed on pushbuild: result mismatch The method to purge binary log files produces different results in some platforms. The reason is that the purge time is calculated based on table modified time and that can't guarantee to purge master-bin.000002 in all platforms.(eg. windows) Use a new way that sets the time to purge binlog file 1 second after the last modified time of master-bin.000002. That can be sure that the file is always deleted in any platform. mysql-test/suite/rpl/r/rpl_rotate_logs.result: Test result mysql-test/suite/rpl/t/rpl_rotate_logs.test: Test file --- mysql-test/suite/rpl/r/rpl_rotate_logs.result | 4 +--- mysql-test/suite/rpl/t/rpl_rotate_logs.test | 24 +++++++++++++------ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_rotate_logs.result b/mysql-test/suite/rpl/r/rpl_rotate_logs.result index 6314a9a61fb..013ba87ec0b 100644 --- a/mysql-test/suite/rpl/r/rpl_rotate_logs.result +++ b/mysql-test/suite/rpl/r/rpl_rotate_logs.result @@ -87,9 +87,7 @@ show binary logs; Log_name File_size master-bin.000002 # master-bin.000003 # -select @time_for_purge:=DATE_ADD(UPDATE_TIME, INTERVAL 1 SECOND) -from information_schema.tables -where TABLE_SCHEMA="test" and TABLE_NAME="t2"; +SELECT @time_for_purge:=DATE_ADD('tmpval', INTERVAL 1 SECOND); purge master logs before (@time_for_purge); show binary logs; Log_name File_size diff --git a/mysql-test/suite/rpl/t/rpl_rotate_logs.test b/mysql-test/suite/rpl/t/rpl_rotate_logs.test index 2bad7b27272..e06099fd707 100644 --- a/mysql-test/suite/rpl/t/rpl_rotate_logs.test +++ b/mysql-test/suite/rpl/t/rpl_rotate_logs.test @@ -112,14 +112,24 @@ source include/show_master_logs.inc; purge binary logs to 'master-bin.000002'; source include/show_binary_logs.inc; -# Calculate time to use in "purge master logs before" by taking -# last modification time of t2 and adding 1 second -# This is donw in order to handle the case where file system -# time differs from mysqld's time +# Set the purge time 1 second after the last modify time of master-bin.000002. +perl; +open F, ">>".$ENV{'MYSQLTEST_VARDIR'}.'/tmp/rpl_rotate_logs.tmp' or die "Tmp file rpl_rotate_logs.tmp not found"; +my $binlogpath = $ENV{'MYSQLTEST_VARDIR'}.'/mysqld.1/data/master-bin.000002'; +my @array = stat($binlogpath); +my $filemodifytime = $array[9]; +my @t = localtime $filemodifytime; +my $modifytime = sprintf "%04u-%02u-%02u %02u:%02u:%02u",$t[5]+1900,$t[4]+1,$t[3],$t[2],$t[1],$t[0]; +printf F ("let \$tmpval = %s;",$modifytime); +close F; +EOF + +--source $MYSQLTEST_VARDIR/tmp/rpl_rotate_logs.tmp +remove_file $MYSQLTEST_VARDIR/tmp/rpl_rotate_logs.tmp; + --disable_result_log -select @time_for_purge:=DATE_ADD(UPDATE_TIME, INTERVAL 1 SECOND) - from information_schema.tables - where TABLE_SCHEMA="test" and TABLE_NAME="t2"; +--replace_result $tmpval tmpval +--eval SELECT @time_for_purge:=DATE_ADD('$tmpval', INTERVAL 1 SECOND) --enable_result_log purge master logs before (@time_for_purge); From 99eeb9fbbc812ac96d53a215f94aa329e767c88c Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 13 Mar 2009 21:01:19 +0100 Subject: [PATCH 03/21] Raise version number after cloning 5.1.33 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 069da9ef36e..d86218bd782 100644 --- a/configure.in +++ b/configure.in @@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM # # When changing major version number please also check switch statement # in mysqlbinlog::check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.1.33) +AM_INIT_AUTOMAKE(mysql, 5.1.34) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 From b42c29cfe33b5c5aab33661357fa4eb309e86132 Mon Sep 17 00:00:00 2001 From: Leonard Zhou Date: Mon, 16 Mar 2009 16:21:29 +0800 Subject: [PATCH 04/21] BUG#22504 load data infile sql statement in replication architecture get error The problem is issued because we set wrong start position and stop position of query string into binlog. That two values are stored as part of head info of query string. When we parse binlog, we first get position values then get the query string according position values. But seems that two values are not calculated correctly after the parse of Yacc. We don't want to touch so much of yacc because it may influence other codes. So just add one space after 'INTO' key word when parsing. This can easily resolve the problem. mysql-test/suite/rpl/r/rpl_loaddatalocal.result: Test result mysql-test/suite/rpl/t/rpl_loaddatalocal.test: Test case sql/log_event.cc: Add space after 'INTO'. --- .../suite/rpl/r/rpl_loaddatalocal.result | 25 ++++++++++++++ mysql-test/suite/rpl/r/rpl_stm_log.result | 2 +- mysql-test/suite/rpl/t/rpl_loaddatalocal.test | 34 +++++++++++++++++++ sql/log_event.cc | 4 +-- 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_loaddatalocal.result b/mysql-test/suite/rpl/r/rpl_loaddatalocal.result index 96de55e9dcf..93ef33f3fc0 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddatalocal.result +++ b/mysql-test/suite/rpl/r/rpl_loaddatalocal.result @@ -29,3 +29,28 @@ a 2 3 drop table t1; +==== Bug22504 Initialize ==== +[on master] +SET sql_mode='ignore_space'; +CREATE TABLE t1(a int); +insert into t1 values (1), (2), (3), (4); +select * into outfile 'MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' from t1; +truncate table t1; +load data local infile 'MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' into table t1; +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +4 +[on slave] +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +4 +==== Clean up ==== +[on master] +DROP TABLE t1; +[on slave] diff --git a/mysql-test/suite/rpl/r/rpl_stm_log.result b/mysql-test/suite/rpl/r/rpl_stm_log.result index 715d4976a95..bcefc6f9d3d 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_log.result +++ b/mysql-test/suite/rpl/r/rpl_stm_log.result @@ -218,7 +218,7 @@ slave-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL) slave-bin.000001 # Query 1 # use `test`; drop table t1 slave-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM slave-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581 -slave-bin.000001 # Execute_load_query 1 # use `test`; load data INFILE '../../tmp/SQL_LOAD-2-1-1.data' INTO table t1 ignore 1 lines ;file_id=1 +slave-bin.000001 # Execute_load_query 1 # use `test`; load data INFILE '../../tmp/SQL_LOAD-2-1-1.data' INTO table t1 ignore 1 lines ;file_id=1 slave-bin.000001 # Query 1 # use `test`; create table t3 (a int)ENGINE=MyISAM slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4 show binlog events in 'slave-bin.000002' from 4; diff --git a/mysql-test/suite/rpl/t/rpl_loaddatalocal.test b/mysql-test/suite/rpl/t/rpl_loaddatalocal.test index 0de402f301a..23c802ab3de 100644 --- a/mysql-test/suite/rpl/t/rpl_loaddatalocal.test +++ b/mysql-test/suite/rpl/t/rpl_loaddatalocal.test @@ -64,3 +64,37 @@ drop table t1; save_master_pos; connection slave; sync_with_master; + + +# +# Bug22504 load data infile sql statement in replication architecture get error +# +--echo ==== Bug22504 Initialize ==== + +--echo [on master] +--connection master + +SET sql_mode='ignore_space'; +CREATE TABLE t1(a int); +insert into t1 values (1), (2), (3), (4); +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval select * into outfile '$MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' from t1; +truncate table t1; +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval load data local infile '$MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' into table t1; +--remove_file $MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile +SELECT * FROM t1 ORDER BY a; + +--echo [on slave] +sync_slave_with_master; +SELECT * FROM t1 ORDER BY a; + +--echo ==== Clean up ==== + +--echo [on master] +connection master; +DROP TABLE t1; + +--echo [on slave] +sync_slave_with_master; + diff --git a/sql/log_event.cc b/sql/log_event.cc index 0e400ac2705..5d959412d36 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -6618,7 +6618,7 @@ void Execute_load_query_log_event::print(FILE* file, my_b_printf(&cache, "\'"); if (dup_handling == LOAD_DUP_REPLACE) my_b_printf(&cache, " REPLACE"); - my_b_printf(&cache, " INTO"); + my_b_printf(&cache, " INTO "); my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end); my_b_printf(&cache, "\n%s\n", print_event_info->delimiter); } @@ -6699,7 +6699,7 @@ Execute_load_query_log_event::do_apply_event(Relay_log_info const *rli) /* Ordinary load data */ break; } - p= strmake(p, STRING_WITH_LEN(" INTO")); + p= strmake(p, STRING_WITH_LEN(" INTO ")); p= strmake(p, query+fn_pos_end, q_len-fn_pos_end); error= Query_log_event::do_apply_event(rli, buf, p-buf); From c924f116f65d96818be88dae79018a83e19411b5 Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Mon, 16 Mar 2009 14:54:28 -0400 Subject: [PATCH 05/21] Bug#39326: mysqld_safe doesn't use --basedir value in search of \ my_print_defaults Now use basedir to set an unset ledir and to find the location of my_print_defaults . --- scripts/mysqld_safe.sh | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 5e7a177a546..502c981c72a 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -212,15 +212,26 @@ fi MY_PWD=`pwd` # Check for the directories we would expect from a binary release install -if test -f "$relpkgdata"/english/errmsg.sys -a -x ./bin/mysqld +if test -n "$MY_BASEDIR_VERSION" -a -d "$MY_BASEDIR_VERSION" then - MY_BASEDIR_VERSION=$MY_PWD # Where bin, share and data are - ledir=$MY_BASEDIR_VERSION/bin # Where mysqld is + # BASEDIR is already overridden on command line. Do not re-set. + + # Use BASEDIR to discover le. + if test -x "$MY_BASEDIR_VERSION/libexec/mysqld" + then + ledir="$MY_BASEDIR_VERSION/libexec" + else + ledir="$MY_BASEDIR_VERSION/bin" + fi +elif test -f "$relpkgdata"/english/errmsg.sys -a -x "$MY_PWD/bin/mysqld" +then + MY_BASEDIR_VERSION="$MY_PWD" # Where bin, share and data are + ledir="$MY_PWD/bin" # Where mysqld is # Check for the directories we would expect from a source install -elif test -f "$relpkgdata"/english/errmsg.sys -a -x ./libexec/mysqld +elif test -f "$relpkgdata"/english/errmsg.sys -a -x "$MY_PWD/libexec/mysqld" then - MY_BASEDIR_VERSION=$MY_PWD # Where libexec, share and var are - ledir=$MY_BASEDIR_VERSION/libexec # Where mysqld is + MY_BASEDIR_VERSION="$MY_PWD" # Where libexec, share and var are + ledir="$MY_PWD/libexec" # Where mysqld is # Since we didn't find anything, used the compiled-in defaults else MY_BASEDIR_VERSION=@prefix@ @@ -274,7 +285,10 @@ export MYSQL_HOME # Get first arguments from the my.cnf file, groups [mysqld] and [mysqld_safe] # and then merge with the command line arguments -if test -x ./bin/my_print_defaults +if test -x "$MY_BASEDIR_VERSION/bin/my_print_defaults" +then + print_defaults="$MY_BASEDIR_VERSION/bin/my_print_defaults" +elif test -x ./bin/my_print_defaults then print_defaults="./bin/my_print_defaults" elif test -x @bindir@/my_print_defaults From 3b32eea2a2d2e1d1cb1a0605a2f73ecbbc502aa5 Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Mon, 16 Mar 2009 15:28:06 -0400 Subject: [PATCH 06/21] Fix several quoting problems, and clean up IFS on failure in my_which(). --- scripts/mysqld_safe.sh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 502c981c72a..960c3e39bab 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -18,7 +18,7 @@ niceness=0 logging=init want_syslog=0 syslog_tag= -user=@MYSQLD_USER@ +user='@MYSQLD_USER@' pid_file= err_log= @@ -64,9 +64,10 @@ my_which () { save_ifs="${IFS-UNSET}" IFS=: + ret=0 for file do - for dir in $PATH + for dir in "$PATH" do if [ -f "$dir/$file" ] then @@ -74,15 +75,18 @@ my_which () continue 2 fi done - return 1 # Failure, didn't find file in path + + ret=1 #signal an error + break done + if [ "$save_ifs" = UNSET ] then unset IFS else IFS="$save_ifs" fi - return 0 # Success + return $ret # Success } log_generic () { @@ -234,8 +238,8 @@ then ledir="$MY_PWD/libexec" # Where mysqld is # Since we didn't find anything, used the compiled-in defaults else - MY_BASEDIR_VERSION=@prefix@ - ledir=@libexecdir@ + MY_BASEDIR_VERSION='@prefix@' + ledir='@libexecdir@' fi @@ -413,7 +417,7 @@ then MYSQLD=mysqld fi -if test ! -x $ledir/$MYSQLD +if test ! -x "$ledir/$MYSQLD" then log_error "The file $ledir/$MYSQLD does not exist or is not executable. Please cd to the mysql installation @@ -425,7 +429,7 @@ fi if test -z "$pid_file" then - pid_file=$DATADIR/`@HOSTNAME@`.pid + pid_file="$DATADIR/`@HOSTNAME@`.pid" else case "$pid_file" in /* ) ;; From 95618bb3f3c2dd8c9f0f760ef36e638096166138 Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Tue, 17 Mar 2009 15:31:07 -0400 Subject: [PATCH 07/21] Bug#42675: Dangling pointer leads to a client crash (mysys/my_error.c \ patch enclosed) One call to my_error_unregister_all() would free pointers, but leave one pointer to just-freed memory still assigned. That's the bug. Subsequent calls of this function would try to follow pointers into deallocated, garbage memory and almost certainly SEGV. Now, after freeing a linked list, unset the initial pointer. --- mysys/my_error.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/mysys/my_error.c b/mysys/my_error.c index 07656dda979..06f2ef6ba0f 100644 --- a/mysys/my_error.c +++ b/mysys/my_error.c @@ -252,11 +252,16 @@ const char **my_error_unregister(int first, int last) void my_error_unregister_all(void) { - struct my_err_head *list, *next; - for (list= my_errmsgs_globerrs.meh_next; list; list= next) + struct my_err_head *cursor, *saved_next; + + for (cursor= my_errmsgs_globerrs.meh_next; cursor != NULL; cursor= saved_next) { - next= list->meh_next; - my_free((uchar*) list, MYF(0)); + /* We need this ptr, but we're about to free its container, so save it. */ + saved_next= cursor->meh_next; + + my_free((uchar*) cursor, MYF(0)); } + my_errmsgs_globerrs.meh_next= NULL; /* Freed in first iteration above. */ + my_errmsgs_list= &my_errmsgs_globerrs; } From 35d47c36317c46a1fd1bc7c9ea2042bd011783fe Mon Sep 17 00:00:00 2001 From: Chad MILLER Date: Tue, 17 Mar 2009 15:43:00 -0400 Subject: [PATCH 08/21] Fix indentation. tab -> spaces --- mysys/my_error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/my_error.c b/mysys/my_error.c index 06f2ef6ba0f..2cf704d0089 100644 --- a/mysys/my_error.c +++ b/mysys/my_error.c @@ -256,7 +256,7 @@ void my_error_unregister_all(void) for (cursor= my_errmsgs_globerrs.meh_next; cursor != NULL; cursor= saved_next) { - /* We need this ptr, but we're about to free its container, so save it. */ + /* We need this ptr, but we're about to free its container, so save it. */ saved_next= cursor->meh_next; my_free((uchar*) cursor, MYF(0)); From 9e655bfffcda0a016943c96c4d911049d38f4c40 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 17 Mar 2009 23:28:24 +0100 Subject: [PATCH 09/21] Bug #43715 Link errors when trying to link mysql_embedded.exe The reason for the error is incorrectly specified link dependencies for mysql_embedded, mysqltest_embedded and mysql_client_test_embedded in CMakeLists.txt (ADD_DEPENDENCIES should be TARGET_LINK_LIBRARIES) libmysqld/CMakeLists.txt: changed library type for libmysqld to SHARED instead of MODULE. MODULE in CMake notation is a shared library that is used only in dlopen/dlsym/LoadLibrary scenarios. Hence it was impossible to use TARGET_LINK_LIBRARIES with a MODULE. libmysqld/examples/CMakeLists.txt: Use TARGET_LINK_LIBRARIES (instead of previously incorrectly used ADD_DEPENDENCIES) to specify link dependency from libmysqld --- libmysqld/CMakeLists.txt | 2 +- libmysqld/examples/CMakeLists.txt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index 1582f0898d8..1c8f80768d4 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -201,6 +201,6 @@ ADD_LIBRARY(mysqlserver STATIC ${LIBMYSQLD_SOURCES}) ADD_DEPENDENCIES(mysqlserver GenServerSource GenError) TARGET_LINK_LIBRARIES(mysqlserver) -ADD_LIBRARY(libmysqld MODULE cmake_dummy.c libmysqld.def) +ADD_LIBRARY(libmysqld SHARED cmake_dummy.c libmysqld.def) ADD_DEPENDENCIES(libmysqld mysqlserver) TARGET_LINK_LIBRARIES(libmysqld mysqlserver wsock32) diff --git a/libmysqld/examples/CMakeLists.txt b/libmysqld/examples/CMakeLists.txt index fa9711b54da..5194836a728 100644 --- a/libmysqld/examples/CMakeLists.txt +++ b/libmysqld/examples/CMakeLists.txt @@ -30,12 +30,12 @@ ADD_EXECUTABLE(mysql_embedded ../../client/completion_hash.cc ../../client/mysql.cc ../../client/readline.cc ../../client/sql_string.cc) TARGET_LINK_LIBRARIES(mysql_embedded debug dbug strings mysys vio yassl taocrypt regex ws2_32) -ADD_DEPENDENCIES(mysql_embedded libmysqld) +TARGET_LINK_LIBRARIES(mysql_embedded libmysqld) ADD_EXECUTABLE(mysqltest_embedded ../../client/mysqltest.cc) TARGET_LINK_LIBRARIES(mysqltest_embedded debug dbug strings mysys vio yassl taocrypt regex ws2_32) -ADD_DEPENDENCIES(mysqltest_embedded libmysqld) +TARGET_LINK_LIBRARIES(mysqltest_embedded libmysqld) ADD_EXECUTABLE(mysql_client_test_embedded ../../tests/mysql_client_test.c) TARGET_LINK_LIBRARIES(mysql_client_test_embedded debug dbug strings mysys vio yassl taocrypt regex ws2_32) -ADD_DEPENDENCIES(mysql_client_test_embedded libmysqld) +TARGET_LINK_LIBRARIES(mysql_client_test_embedded libmysqld) From 497db6ac0f1efb1a962158d9ee108b0236b88e5c Mon Sep 17 00:00:00 2001 From: Satya B Date: Wed, 18 Mar 2009 11:16:21 +0530 Subject: [PATCH 10/21] Fix for BUG#32880 - Repairing Archive table fails with internal error 144 Any statement reading corrupt archive data file (CHECK/REPAIR/SELECT/UPDATE/DELETE) may cause assertion failure in debug builds. This assertion has been removed and an error is returned instead. Also fixed that CHECK/REPAIR returns vague error message when it mets corruption in archive data file. This is fixed by returning proper error code. mysql-test/r/archive.result: A test case for BUG#32880 mysql-test/std_data/bug32880.ARN: corrupted archive table to test check and repair table operation mysql-test/std_data/bug32880.ARZ: corrupted archive table to test check and repair table operation mysql-test/std_data/bug32880.frm: corrupted archive table to test check and repair table operation mysql-test/t/archive.test: A test case for BUG#32880 storage/archive/ha_archive.cc: Fixed unpack_row() to return the error instead of throwing assertion and also fixed repair() to throw better error when repair table operation fails on corrupted archive table --- mysql-test/r/archive.result | 19 +++++++++++++++++++ mysql-test/std_data/bug32880.ARN | Bin 0 -> 131 bytes mysql-test/std_data/bug32880.ARZ | Bin 0 -> 8744 bytes mysql-test/std_data/bug32880.frm | Bin 0 -> 8578 bytes mysql-test/t/archive.test | 15 +++++++++++++++ storage/archive/ha_archive.cc | 6 ++---- 6 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 mysql-test/std_data/bug32880.ARN create mode 100644 mysql-test/std_data/bug32880.ARZ create mode 100644 mysql-test/std_data/bug32880.frm diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index 8c26ea1ff82..02acccb234e 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12695,3 +12695,22 @@ a b 1 NULL 2 NULL DROP TABLE t1; +# +# BUG#32880 - Repairing Archive table fails with internal error 144 +# + +# Test with an existing table which is corrupted +# Copy t1 from std_data +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` blob +) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check error Corrupt +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair error Corrupt +DROP TABLE t1; diff --git a/mysql-test/std_data/bug32880.ARN b/mysql-test/std_data/bug32880.ARN new file mode 100644 index 0000000000000000000000000000000000000000..643b0dfbad59af05495571978acc8b5eeaf8b509 GIT binary patch literal 131 zcmeyz%qYO%$AAi8dqei4wVSWE@5vi;Yx=ZHHrNyljV=3 gvkA%YRCc;{PVKA|P+c6Av6_|P_LJg8GZ+~d03i_-e*gdg literal 0 HcmV?d00001 diff --git a/mysql-test/std_data/bug32880.ARZ b/mysql-test/std_data/bug32880.ARZ new file mode 100644 index 0000000000000000000000000000000000000000..4e151822647f1b7e0f3f2b9952ef543f9a7954ce GIT binary patch literal 8744 zcmeI&ze>YE90%}kE^WOwLQ_+U|G-v?pi7-QR7DDkP{ct*5RxuFL%>0bOI#ep7w|I1m=0(}aH((^7}($&Gi!uKHg{qC2`-SL@!GuQDk05EFlmmMEA5AD2YV{h9gHUv8Q z`pMQ~=9GO`*BoHqe5%gZ3yCt2?j*CS`S)`S)UraS12nSrP z3Q&Lo|5iXi<#(HBwzPz!i{q2i%YMFu2?Z!X0SZun0u-PC1t>rP3Q&Lo3nnmf(tdyi zyY=5)*MUG6rY)k1Qoiju8oF*q7p@TX-R3U`3J{U*nGi!1gy)$}HtzK{uI`{H3MtJQ zwTC(|Jpfdsh6=j-!j4H4hF@dZzFK<>&h~=%@NQ@It^K_9ep_1ET#l1|@{+`fS*+Bg Wb>pSU>r>;WvOc)BNhQ>$RK5X*A2h-M literal 0 HcmV?d00001 diff --git a/mysql-test/std_data/bug32880.frm b/mysql-test/std_data/bug32880.frm new file mode 100644 index 0000000000000000000000000000000000000000..66a4c7d7538ef06353e4b38b8699203736844857 GIT binary patch literal 8578 zcmeI&u?oU45C-5s*H%+Hw8i4$($%TXT|`9CO&r|YClT?@dj)_ z@U6LrNs9<546x7zIYNj<3M77Shhm}0?Fy7bp=p46*l?u)1t>rP3Q&Lo6rcbFC_n)U zP~d9?1TMVooxMt9tPbn#?zjm@m{5QM6rcbFC_n)UP=Epypa2CZ@M8jJqo4kN90r0G z6BWoY3J!ZrweF)uBvQ@m4+Alz)0qkB5lfc&CbN^aiFAS@5o`S&<)s4dOTcxmcX$FK Cm=+HJ literal 0 HcmV?d00001 diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 7139d95ab49..0d521f95b38 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1599,3 +1599,18 @@ INSERT INTO t1 VALUES (NULL, NULL),(NULL, NULL); FLUSH TABLE t1; SELECT * FROM t1 ORDER BY a; DROP TABLE t1; + +--echo # +--echo # BUG#32880 - Repairing Archive table fails with internal error 144 +--echo # +--echo +--echo # Test with an existing table which is corrupted +--echo # Copy t1 from std_data +let $MYSQLD_DATADIR= `select @@datadir`; +copy_file std_data/bug32880.frm $MYSQLD_DATADIR/test/t1.frm; +copy_file std_data/bug32880.ARZ $MYSQLD_DATADIR/test/t1.ARZ; +copy_file std_data/bug32880.ARN $MYSQLD_DATADIR/test/t1.ARN; +SHOW CREATE TABLE t1; +CHECK TABLE t1; +REPAIR TABLE t1; +DROP TABLE t1; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 7edfca53751..d20ab3bf723 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1076,11 +1076,9 @@ int ha_archive::unpack_row(azio_stream *file_to_read, uchar *record) read= azread(file_to_read, record_buffer->buffer, row_len, &error); - DBUG_ASSERT(row_len == read); - if (read != row_len || error) { - DBUG_RETURN(-1); + DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); } /* Copy null bits */ @@ -1257,7 +1255,7 @@ int ha_archive::repair(THD* thd, HA_CHECK_OPT* check_opt) int rc= optimize(thd, check_opt); if (rc) - DBUG_RETURN(HA_ERR_CRASHED_ON_REPAIR); + DBUG_RETURN(HA_ADMIN_CORRUPT); share->crashed= FALSE; DBUG_RETURN(0); From 0ba1cc2523f1c7603627d0d683355d042ea85b65 Mon Sep 17 00:00:00 2001 From: Guangbao Ni Date: Wed, 18 Mar 2009 13:48:23 +0000 Subject: [PATCH 11/21] Bug #42217 mysql.procs_priv does not get replicated mysql.procs_priv table itself does not get replicated. Inserting routine privilege record into mysql.procs_priv table is triggered by creating function/procedure statements according to current user's privileges. Because the current user of SQL thread has GLOBAL_ACL, which doesn't need any check mysql.procs_priv privilege when create/alter/execute routines. Corresponding GLOBAL_ACL privilege user doesn't insert routine privilege record into mysql.procs_priv when creating a routine. Fixed by switching the current user of SQL thread to definer user if the definer user exists on slave. That populates procs_priv, otherwise to keep the SQL thread user and procs_priv remains unchanged. mysql-test/suite/rpl/r/rpl_do_grant.result: Test case result for routine privilege when definer user exist or not on slave mysql-test/suite/rpl/t/rpl_do_grant.test: Test case result for routine privilege when definer user exist or not on slave sql/sql_parse.cc: Switch current user of SQL thread to definer user if the definer user existes on slave when checking whether the routine privilege is needed to insert mysql.procs_priv table or not. --- mysql-test/suite/rpl/r/rpl_do_grant.result | 78 +++++++++++++++++ mysql-test/suite/rpl/t/rpl_do_grant.test | 97 ++++++++++++++++++++++ sql/sql_parse.cc | 36 +++++++- 3 files changed, 210 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/rpl/r/rpl_do_grant.result b/mysql-test/suite/rpl/r/rpl_do_grant.result index f7f1ce66656..69bcfad4347 100644 --- a/mysql-test/suite/rpl/r/rpl_do_grant.result +++ b/mysql-test/suite/rpl/r/rpl_do_grant.result @@ -89,3 +89,81 @@ show grants for rpl_do_grant2@localhost; ERROR 42000: There is no such grant defined for user 'rpl_do_grant2' on host 'localhost' show grants for rpl_do_grant2@localhost; ERROR 42000: There is no such grant defined for user 'rpl_do_grant2' on host 'localhost' +DROP DATABASE IF EXISTS bug42217_db; +CREATE DATABASE bug42217_db; +GRANT CREATE ROUTINE ON bug42217_db.* TO 'create_rout_db'@'localhost' + IDENTIFIED BY 'create_rout_db' WITH GRANT OPTION; +USE bug42217_db; +CREATE FUNCTION upgrade_del_func() RETURNS CHAR(30) +BEGIN +RETURN "INSIDE upgrade_del_func()"; +END// +USE bug42217_db; +SELECT * FROM mysql.procs_priv; +Host Db User Routine_name Routine_type Grantor Proc_priv Timestamp +localhost bug42217_db create_rout_db upgrade_del_func FUNCTION create_rout_db@localhost Execute,Alter Routine # +SELECT upgrade_del_func(); +upgrade_del_func() +INSIDE upgrade_del_func() +SELECT * FROM mysql.procs_priv; +Host Db User Routine_name Routine_type Grantor Proc_priv Timestamp +localhost bug42217_db create_rout_db upgrade_del_func FUNCTION create_rout_db@localhost Execute,Alter Routine # +SHOW GRANTS FOR 'create_rout_db'@'localhost'; +Grants for create_rout_db@localhost +GRANT USAGE ON *.* TO 'create_rout_db'@'localhost' IDENTIFIED BY PASSWORD '*08792480350CBA057BDE781B9DF183B263934601' +GRANT CREATE ROUTINE ON `bug42217_db`.* TO 'create_rout_db'@'localhost' WITH GRANT OPTION +GRANT EXECUTE, ALTER ROUTINE ON FUNCTION `bug42217_db`.`upgrade_del_func` TO 'create_rout_db'@'localhost' +USE bug42217_db; +SHOW CREATE FUNCTION upgrade_del_func; +Function sql_mode Create Function character_set_client collation_connection Database Collation +upgrade_del_func CREATE DEFINER=`create_rout_db`@`localhost` FUNCTION `upgrade_del_func`() RETURNS char(30) CHARSET latin1 +BEGIN +RETURN "INSIDE upgrade_del_func()"; +END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT upgrade_del_func(); +upgrade_del_func() +INSIDE upgrade_del_func() +"Check whether the definer user will be able to execute the replicated routine on slave" +USE bug42217_db; +SHOW CREATE FUNCTION upgrade_del_func; +Function sql_mode Create Function character_set_client collation_connection Database Collation +upgrade_del_func CREATE DEFINER=`create_rout_db`@`localhost` FUNCTION `upgrade_del_func`() RETURNS char(30) CHARSET latin1 +BEGIN +RETURN "INSIDE upgrade_del_func()"; +END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT upgrade_del_func(); +upgrade_del_func() +INSIDE upgrade_del_func() +DELETE FROM mysql.procs_priv; +FLUSH PRIVILEGES; +USE bug42217_db; +"Can't execute the replicated routine on slave like before after procs privilege is deleted " +SELECT upgrade_del_func(); +ERROR 42000: execute command denied to user 'create_rout_db'@'localhost' for routine 'bug42217_db.upgrade_del_func' +"Test the user who creates a function on master doesn't exist on slave." +"Hence SQL thread ACL_GLOBAL privilege jumps in and no mysql.procs_priv is inserted" +DROP USER 'create_rout_db'@'localhost'; +CREATE FUNCTION upgrade_alter_func() RETURNS CHAR(30) +BEGIN +RETURN "INSIDE upgrade_alter_func()"; +END// +SELECT upgrade_alter_func(); +upgrade_alter_func() +INSIDE upgrade_alter_func() +SHOW CREATE FUNCTION upgrade_alter_func; +Function sql_mode Create Function character_set_client collation_connection Database Collation +upgrade_alter_func CREATE DEFINER=`create_rout_db`@`localhost` FUNCTION `upgrade_alter_func`() RETURNS char(30) CHARSET latin1 +BEGIN +RETURN "INSIDE upgrade_alter_func()"; +END latin1 latin1_swedish_ci latin1_swedish_ci +"Should no privilege record for upgrade_alter_func in mysql.procs_priv" +SELECT * FROM mysql.procs_priv; +Host Db User Routine_name Routine_type Grantor Proc_priv Timestamp +SELECT upgrade_alter_func(); +ERROR HY000: The user specified as a definer ('create_rout_db'@'localhost') does not exist +USE bug42217_db; +DROP FUNCTION upgrade_del_func; +DROP FUNCTION upgrade_alter_func; +DROP DATABASE bug42217_db; +DROP USER 'create_rout_db'@'localhost'; +"End of test" diff --git a/mysql-test/suite/rpl/t/rpl_do_grant.test b/mysql-test/suite/rpl/t/rpl_do_grant.test index 5615900c2dd..806de780086 100644 --- a/mysql-test/suite/rpl/t/rpl_do_grant.test +++ b/mysql-test/suite/rpl/t/rpl_do_grant.test @@ -112,3 +112,100 @@ show grants for rpl_do_grant2@localhost; sync_slave_with_master; --error 1141 show grants for rpl_do_grant2@localhost; + +##################################################### +# Purpose +# Test whether mysql.procs_priv get replicated +# Related bugs: +# BUG42217 mysql.procs_priv does not get replicated +##################################################### +connection master; + +--disable_warnings +DROP DATABASE IF EXISTS bug42217_db; +--enable_warnings +CREATE DATABASE bug42217_db; + +GRANT CREATE ROUTINE ON bug42217_db.* TO 'create_rout_db'@'localhost' + IDENTIFIED BY 'create_rout_db' WITH GRANT OPTION; + +connect (create_rout_db_master, localhost, create_rout_db, create_rout_db, bug42217_db,$MASTER_MYPORT,); +connect (create_rout_db_slave, localhost, create_rout_db, create_rout_db, bug42217_db, $SLAVE_MYPORT,); + +connection create_rout_db_master; + + +USE bug42217_db; + +DELIMITER //; +CREATE FUNCTION upgrade_del_func() RETURNS CHAR(30) +BEGIN + RETURN "INSIDE upgrade_del_func()"; +END// + +DELIMITER ;// + +connection master; + +USE bug42217_db; +--replace_column 8 # +SELECT * FROM mysql.procs_priv; +SELECT upgrade_del_func(); + +sync_slave_with_master; +--replace_column 8 # +SELECT * FROM mysql.procs_priv; +SHOW GRANTS FOR 'create_rout_db'@'localhost'; + +USE bug42217_db; +SHOW CREATE FUNCTION upgrade_del_func; +SELECT upgrade_del_func(); + +--echo "Check whether the definer user will be able to execute the replicated routine on slave" +connection create_rout_db_slave; +USE bug42217_db; +SHOW CREATE FUNCTION upgrade_del_func; +SELECT upgrade_del_func(); + +connection slave; +DELETE FROM mysql.procs_priv; +FLUSH PRIVILEGES; +USE bug42217_db; +--echo "Can't execute the replicated routine on slave like before after procs privilege is deleted " +--error 1370 +SELECT upgrade_del_func(); + +--echo "Test the user who creates a function on master doesn't exist on slave." +--echo "Hence SQL thread ACL_GLOBAL privilege jumps in and no mysql.procs_priv is inserted" +DROP USER 'create_rout_db'@'localhost'; + +connection create_rout_db_master; +DELIMITER //; +CREATE FUNCTION upgrade_alter_func() RETURNS CHAR(30) +BEGIN + RETURN "INSIDE upgrade_alter_func()"; +END// +DELIMITER ;// + +connection master; +SELECT upgrade_alter_func(); + +sync_slave_with_master; +SHOW CREATE FUNCTION upgrade_alter_func; +--echo "Should no privilege record for upgrade_alter_func in mysql.procs_priv" +--replace_column 8 # +SELECT * FROM mysql.procs_priv; +--error 1449 +SELECT upgrade_alter_func(); + +###### CLEAN UP SECTION ############## +disconnect create_rout_db_master; +disconnect create_rout_db_slave; +connection master; +USE bug42217_db; +DROP FUNCTION upgrade_del_func; +DROP FUNCTION upgrade_alter_func; +DROP DATABASE bug42217_db; +DROP USER 'create_rout_db'@'localhost'; + +--echo "End of test" diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f7e895d150f..94725b1b53f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4129,9 +4129,32 @@ end_with_restore_list: res= (sp_result= lex->sphead->create(thd)); switch (sp_result) { - case SP_OK: + case SP_OK: { #ifndef NO_EMBEDDED_ACCESS_CHECKS /* only add privileges if really neccessary */ + + Security_context security_context; + bool restore_backup_context= false; + Security_context *backup= NULL; + LEX_USER *definer= thd->lex->definer; + /* + Check if the definer exists on slave, + then use definer privilege to insert routine privileges to mysql.procs_priv. + + For current user of SQL thread has GLOBAL_ACL privilege, + which doesn't any check routine privileges, + so no routine privilege record will insert into mysql.procs_priv. + */ + if (thd->slave_thread && is_acl_user(definer->host.str, definer->user.str)) + { + security_context.change_security_context(thd, + &thd->lex->definer->user, + &thd->lex->definer->host, + &thd->lex->sphead->m_db, + &backup); + restore_backup_context= true; + } + if (sp_automatic_privileges && !opt_noacl && check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS, lex->sphead->m_db.str, name, @@ -4143,8 +4166,19 @@ end_with_restore_list: ER_PROC_AUTO_GRANT_FAIL, ER(ER_PROC_AUTO_GRANT_FAIL)); } + + /* + Restore current user with GLOBAL_ACL privilege of SQL thread + */ + if (restore_backup_context) + { + DBUG_ASSERT(thd->slave_thread == 1); + thd->security_ctx->restore_security_context(thd, backup); + } + #endif break; + } case SP_WRITE_ROW_FAILED: my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name); break; From 6290bc7e61ed97fb7af629c5e4c6f6d9e3ccc9b0 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 18 Mar 2009 14:52:31 +0200 Subject: [PATCH 12/21] addendum to the 22047 fix : updated funcs_1 test suite --- mysql-test/suite/funcs_1/r/is_columns_is.result | 5 +++-- mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result | 4 ++-- mysql-test/suite/funcs_1/r/processlist_val_no_prot.result | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index 94aa75c6db2..ccb94c63d46 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -166,7 +166,7 @@ NULL information_schema PROCESSLIST HOST 3 NO varchar 64 192 NULL NULL utf8 utf NULL information_schema PROCESSLIST ID 1 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4) select NULL information_schema PROCESSLIST INFO 8 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select NULL information_schema PROCESSLIST STATE 7 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select -NULL information_schema PROCESSLIST TIME 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(7) select +NULL information_schema PROCESSLIST TIME 6 0 NO int NULL NULL 10 0 NULL NULL int(7) select NULL information_schema PROCESSLIST USER 2 NO varchar 16 48 NULL NULL utf8 utf8_general_ci varchar(16) select NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select @@ -340,6 +340,7 @@ ORDER BY CHARACTER_SET_NAME, COLLATION_NAME, COL_CML; COL_CML DATA_TYPE CHARACTER_SET_NAME COLLATION_NAME NULL bigint NULL NULL NULL datetime NULL NULL +NULL int NULL NULL --> CHAR(0) is allowed (see manual), and here both CHARACHTER_* values --> are 0, which is intended behavior, and the result of 0 / 0 IS NULL SELECT CHARACTER_OCTET_LENGTH / CHARACTER_MAXIMUM_LENGTH AS COL_CML, @@ -519,7 +520,7 @@ NULL information_schema PROCESSLIST ID bigint NULL NULL NULL NULL bigint(4) 3.0000 information_schema PROCESSLIST HOST varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema PROCESSLIST DB varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema PROCESSLIST COMMAND varchar 16 48 utf8 utf8_general_ci varchar(16) -NULL information_schema PROCESSLIST TIME bigint NULL NULL NULL NULL bigint(7) +NULL information_schema PROCESSLIST TIME int NULL NULL NULL NULL int(7) 3.0000 information_schema PROCESSLIST STATE varchar 64 192 utf8 utf8_general_ci varchar(64) 1.0000 information_schema PROCESSLIST INFO longtext 4294967295 4294967295 utf8 utf8_general_ci longtext 3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512) diff --git a/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result b/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result index d862b7424e0..3d341292be1 100644 --- a/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result +++ b/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result @@ -27,7 +27,7 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` ( `HOST` varchar(64) NOT NULL DEFAULT '', `DB` varchar(64) DEFAULT NULL, `COMMAND` varchar(16) NOT NULL DEFAULT '', - `TIME` bigint(7) NOT NULL DEFAULT '0', + `TIME` int(7) NOT NULL DEFAULT '0', `STATE` varchar(64) DEFAULT NULL, `INFO` longtext ) ENGINE=MyISAM DEFAULT CHARSET=utf8 @@ -97,7 +97,7 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` ( `HOST` varchar(64) NOT NULL DEFAULT '', `DB` varchar(64) DEFAULT NULL, `COMMAND` varchar(16) NOT NULL DEFAULT '', - `TIME` bigint(7) NOT NULL DEFAULT '0', + `TIME` int(7) NOT NULL DEFAULT '0', `STATE` varchar(64) DEFAULT NULL, `INFO` longtext ) ENGINE=MyISAM DEFAULT CHARSET=utf8 diff --git a/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result b/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result index 482e143fd23..b0cae801fd6 100644 --- a/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result +++ b/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result @@ -17,7 +17,7 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` ( `HOST` varchar(64) NOT NULL DEFAULT '', `DB` varchar(64) DEFAULT NULL, `COMMAND` varchar(16) NOT NULL DEFAULT '', - `TIME` bigint(7) NOT NULL DEFAULT '0', + `TIME` int(7) NOT NULL DEFAULT '0', `STATE` varchar(64) DEFAULT NULL, `INFO` longtext ) ENGINE=MyISAM DEFAULT CHARSET=utf8 From 09c1a26b681ad9755ca2a0c52616dec7267134f3 Mon Sep 17 00:00:00 2001 From: Horst Hunger Date: Wed, 18 Mar 2009 17:23:39 +0100 Subject: [PATCH 13/21] Due to bug#43733 I disabled "concurrent_innodb_(un)safelog.test" for embedded server. --- mysql-test/include/concurrent.inc | 2 ++ mysql-test/t/disabled.def | 2 ++ 2 files changed, 4 insertions(+) diff --git a/mysql-test/include/concurrent.inc b/mysql-test/include/concurrent.inc index fe670cef08e..2180ec4cc9c 100644 --- a/mysql-test/include/concurrent.inc +++ b/mysql-test/include/concurrent.inc @@ -25,6 +25,8 @@ # new wrapper t/concurrent_innodb_safelog.test # +--source include/not_embedded.inc + connection default; # # Show prerequisites for this test. diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 3f61176e37b..eab0542314a 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -11,3 +11,5 @@ ############################################################################## kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild. innodb_bug39438 : BUG#42383 2009-01-28 lsoares "This fails in embedded and on windows. Note that this test is not run on windows and on embedded in PB for main trees currently" +#concurrent_innodb_safelog: disabled for embedded server due to bug#43733 Select on processlist let the embedded server crash (concurrent_innodb_safelog). +#concurrent_innodb_unsafelog: disabled for embedded server due to bug#43733. From 73a7d99331d8fd0819fb9f7a10081e393590a94d Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Wed, 18 Mar 2009 11:18:24 +0300 Subject: [PATCH 14/21] Fix for bug#41486: extra character appears in BLOB for every ~40Mb after mysqldump/import When the input string exceeds the maximum allowed size for the internal buffer, batch_readline() returns a truncated string. Since there was no way for a caller to determine whether the string was truncated or not, the command line client assumed batch_readline() to always return the whole input string and appended a newline character. This resulted in garbled data when importing dumps containing strings longer than the maximum input buffer size. Fixed by adding a flag to the batch_readline() interface to signal a truncated string to the caller. Other minor problems fixed during patch implementation: - The maximum allowed buffer size for batch_readline() was set up depending on the client's max_allowed_packet value. It does not actully make any sense, as those variables are not related. The input buffer size limit is now always set to 1 MB. - fill_buffer() did not always set the EOF flag. - The input buffer could actually grow twice as the specified limit due to insufficient checks in intern_read_line(). client/my_readline.h: Changed the interface of batch_readline(). client/mysql.cc: Honor the truncated flag returned by batch_readline() and do not append the newline character if it was set. Since we can't change the interfaces for readline()/fgets() used in the interactive mode, always assume the returned string was not truncated. In addition, always set the batch_readline() internal buffer to 1 MB, independently from the client's max_allowed_packet. client/readline.cc: Added the 'truncated' argument do batch_readline() to signal truncated string to a caller. Fixed fill_buffer() to set the EOF flag correctly. Fixed checks in intern_read_line() to not allow the internal buffer grow past the specified limit. mysql-test/r/mysql.result: Added a test case for bug #41486. mysql-test/t/mysql.test: Added a test case for bug #41486. --- client/my_readline.h | 2 +- client/mysql.cc | 22 +++++++++++-------- client/readline.cc | 46 +++++++++++++++++++++++++++++---------- mysql-test/r/mysql.result | 11 ++++++++++ mysql-test/t/mysql.test | 27 +++++++++++++++++++++++ 5 files changed, 86 insertions(+), 22 deletions(-) diff --git a/client/my_readline.h b/client/my_readline.h index 47be7fa9294..32d6da4c626 100644 --- a/client/my_readline.h +++ b/client/my_readline.h @@ -29,5 +29,5 @@ typedef struct st_line_buffer extern LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file); extern LINE_BUFFER *batch_readline_command(LINE_BUFFER *buffer, my_string str); -extern char *batch_readline(LINE_BUFFER *buffer); +extern char *batch_readline(LINE_BUFFER *buffer, bool *truncated); extern void batch_readline_end(LINE_BUFFER *buffer); diff --git a/client/mysql.cc b/client/mysql.cc index 1a025345190..0a4587d1c92 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -112,6 +112,8 @@ extern "C" { #define PROMPT_CHAR '\\' #define DEFAULT_DELIMITER ";" +#define MAX_BATCH_BUFFER_SIZE (1024L * 1024L) + typedef struct st_status { int exit_status; @@ -1035,7 +1037,7 @@ static void fix_history(String *final_command); static COMMANDS *find_command(char *name,char cmd_name); static bool add_line(String &buffer,char *line,char *in_string, - bool *ml_comment); + bool *ml_comment, bool truncated); static void remove_cntrl(String &buffer); static void print_table_data(MYSQL_RES *result); static void print_table_data_html(MYSQL_RES *result); @@ -1117,7 +1119,7 @@ int main(int argc,char *argv[]) exit(1); } if (status.batch && !status.line_buff && - !(status.line_buff=batch_readline_init(opt_max_allowed_packet+512,stdin))) + !(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, stdin))) { free_defaults(defaults_argv); my_end(0); @@ -1766,13 +1768,14 @@ static int read_and_execute(bool interactive) ulong line_number=0; bool ml_comment= 0; COMMANDS *com; + bool truncated= 0; status.exit_status=1; for (;;) { if (!interactive) { - line=batch_readline(status.line_buff); + line=batch_readline(status.line_buff, &truncated); /* Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF. Editors like "notepad" put this marker in @@ -1891,7 +1894,7 @@ static int read_and_execute(bool interactive) #endif continue; } - if (add_line(glob_buffer,line,&in_string,&ml_comment)) + if (add_line(glob_buffer,line,&in_string,&ml_comment, truncated)) break; } /* if in batch mode, send last query even if it doesn't end with \g or go */ @@ -1977,7 +1980,7 @@ static COMMANDS *find_command(char *name,char cmd_char) static bool add_line(String &buffer,char *line,char *in_string, - bool *ml_comment) + bool *ml_comment, bool truncated) { uchar inchar; char buff[80], *pos, *out; @@ -2224,9 +2227,10 @@ static bool add_line(String &buffer,char *line,char *in_string, { uint length=(uint) (out-line); - if (length < 9 || - my_strnncoll (charset_info, - (uchar *)line, 9, (const uchar *) "delimiter", 9)) + if (!truncated && + (length < 9 || + my_strnncoll (charset_info, + (uchar *)line, 9, (const uchar *) "delimiter", 9))) { /* Don't add a new line in case there's a DELIMITER command to be @@ -3886,7 +3890,7 @@ static int com_source(String *buffer, char *line) return put_info(buff, INFO_ERROR, 0); } - if (!(line_buff=batch_readline_init(opt_max_allowed_packet+512,sql_file))) + if (!(line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, sql_file))) { my_fclose(sql_file,MYF(0)); return put_info("Can't initialize batch_readline", INFO_ERROR, 0); diff --git a/client/readline.cc b/client/readline.cc index ad42ed2ee10..726d9cd9415 100644 --- a/client/readline.cc +++ b/client/readline.cc @@ -24,7 +24,7 @@ static bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size, ulong max_size); static bool init_line_buffer_from_string(LINE_BUFFER *buffer,my_string str); static uint fill_buffer(LINE_BUFFER *buffer); -static char *intern_read_line(LINE_BUFFER *buffer,ulong *out_length); +static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated); LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) @@ -42,12 +42,13 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) } -char *batch_readline(LINE_BUFFER *line_buff) +char *batch_readline(LINE_BUFFER *line_buff, bool *truncated) { char *pos; ulong out_length; + DBUG_ASSERT(truncated != NULL); - if (!(pos=intern_read_line(line_buff,&out_length))) + if (!(pos=intern_read_line(line_buff,&out_length, truncated))) return 0; if (out_length && pos[out_length-1] == '\n') if (--out_length && pos[out_length-1] == '\r') /* Remove '\n' */ @@ -149,6 +150,14 @@ static uint fill_buffer(LINE_BUFFER *buffer) read_count=(buffer->bufread - bufbytes)/IO_SIZE; if ((read_count*=IO_SIZE)) break; + if (buffer->bufread * 2 > buffer->max_size) + { + /* + So we must grow the buffer but we cannot due to the max_size limit. + Return 0 w/o setting buffer->eof to signal this condition. + */ + return 0; + } buffer->bufread *= 2; if (!(buffer->buffer = (char*) my_realloc(buffer->buffer, buffer->bufread+1, @@ -172,11 +181,15 @@ static uint fill_buffer(LINE_BUFFER *buffer) DBUG_PRINT("fill_buff", ("Got %d bytes", read_count)); - /* Kludge to pretend every nonempty file ends with a newline. */ - if (!read_count && bufbytes && buffer->end[-1] != '\n') + if (!read_count) { - buffer->eof = read_count = 1; - *buffer->end = '\n'; + buffer->eof = 1; + /* Kludge to pretend every nonempty file ends with a newline. */ + if (bufbytes && buffer->end[-1] != '\n') + { + read_count = 1; + *buffer->end = '\n'; + } } buffer->end_of_line=(buffer->start_of_line=buffer->buffer)+bufbytes; buffer->end+=read_count; @@ -186,7 +199,7 @@ static uint fill_buffer(LINE_BUFFER *buffer) -char *intern_read_line(LINE_BUFFER *buffer,ulong *out_length) +char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated) { char *pos; uint length; @@ -200,14 +213,23 @@ char *intern_read_line(LINE_BUFFER *buffer,ulong *out_length) pos++; if (pos == buffer->end) { - if ((uint) (pos - buffer->start_of_line) < buffer->max_size) + /* + fill_buffer() can return 0 either on EOF in which case we abort + or when the internal buffer has hit the size limit. In the latter case + return what we have read so far and signal string truncation. + */ + if (!(length=fill_buffer(buffer)) || length == (uint) -1) { - if (!(length=fill_buffer(buffer)) || length == (uint) -1) - DBUG_RETURN(0); - continue; + if (buffer->eof) + DBUG_RETURN(0); } + else + continue; pos--; /* break line here */ + *truncated= 1; } + else + *truncated= 0; buffer->end_of_line=pos+1; *out_length=(ulong) (pos + 1 - buffer->eof - buffer->start_of_line); DBUG_RETURN(buffer->start_of_line); diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 10537f6da16..a6087e0134b 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -192,4 +192,15 @@ delimiter 1 1 1 +set @old_max_allowed_packet = @@global.max_allowed_packet; +set @@global.max_allowed_packet = 2 * 1024 * 1024 + 1024; +set @@max_allowed_packet = @@global.max_allowed_packet; +CREATE TABLE t1(data LONGBLOB); +INSERT INTO t1 SELECT REPEAT('1', 2*1024*1024); +SELECT LENGTH(data) FROM t1; +LENGTH(data) +2097152 +DROP TABLE t1; +set @@global.max_allowed_packet = @old_max_allowed_packet; +set @@max_allowed_packet = @@global.max_allowed_packet; End of 5.0 tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 594d10e46a5..0030f624be6 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -331,4 +331,31 @@ EOF remove_file $MYSQLTEST_VARDIR/tmp/bug31060.sql; +# +# Bug #41486: extra character appears in BLOB for every ~40Mb after +# mysqldump/import +# + +# Have to change the global variable as the mysql client will use +# a separate session +set @old_max_allowed_packet = @@global.max_allowed_packet; +# 2 MB blob length + some space for the rest of INSERT query +set @@global.max_allowed_packet = 2 * 1024 * 1024 + 1024; +set @@max_allowed_packet = @@global.max_allowed_packet; + +CREATE TABLE t1(data LONGBLOB); +INSERT INTO t1 SELECT REPEAT('1', 2*1024*1024); + +--exec $MYSQL_DUMP test t1 >$MYSQLTEST_VARDIR/tmp/bug41486.sql +# Check that the mysql client does not insert extra newlines when loading +# strings longer than client's max_allowed_packet +--exec $MYSQL --max_allowed_packet=1M test < $MYSQLTEST_VARDIR/tmp/bug41486.sql 2>&1 +SELECT LENGTH(data) FROM t1; + +remove_file $MYSQLTEST_VARDIR/tmp/bug41486.sql; +DROP TABLE t1; + +set @@global.max_allowed_packet = @old_max_allowed_packet; +set @@max_allowed_packet = @@global.max_allowed_packet; + --echo End of 5.0 tests From 4d32be13fe8f3e4d027e2d0039cc55f28e4ba8ab Mon Sep 17 00:00:00 2001 From: "Bernt M. Johnsen" Date: Wed, 18 Mar 2009 15:07:13 +0100 Subject: [PATCH 15/21] Bug#43329 prepared for commit on 5.0 --- mysql-test/r/union.result | 16 ++++++------ mysql-test/t/union.test | 51 ++++++++++++++++++++++++++++----------- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 6007fdd403a..04bd818df89 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1447,12 +1447,12 @@ SELECT a FROM t1 UNION SELECT a FROM t1 ) alias; -SELECT a INTO OUTFILE 'union.out.file' FROM ( +SELECT a INTO OUTFILE '/tmp/union.out.file' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 ) alias; -SELECT a INTO DUMPFILE 'union.out.file2' FROM ( +SELECT a INTO DUMPFILE '/tmp/union.out.file' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 @@ -1465,21 +1465,21 @@ SELECT a INTO @v FROM t1 SELECT a FROM ( SELECT a FROM t1 UNION -SELECT a INTO OUTFILE 'union.out.file3' FROM t1 +SELECT a INTO OUTFILE '/tmp/union.out.file' FROM t1 ) alias; SELECT a FROM ( SELECT a FROM t1 UNION -SELECT a INTO DUMPFILE 'union.out.file4' FROM t1 +SELECT a INTO DUMPFILE '/tmp/union.out.file' FROM t1 ) alias; SELECT a FROM t1 UNION SELECT a INTO @v FROM t1; -SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1; -SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1; +SELECT a FROM t1 UNION SELECT a INTO OUTFILE '/tmp/union.out.file' FROM t1; +SELECT a FROM t1 UNION SELECT a INTO DUMPFILE '/tmp/union.out.file' FROM t1; SELECT a INTO @v FROM t1 UNION SELECT a FROM t1; ERROR HY000: Incorrect usage of UNION and INTO -SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1; +SELECT a INTO OUTFILE '/tmp/union.out.file' FROM t1 UNION SELECT a FROM t1; ERROR HY000: Incorrect usage of UNION and INTO -SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1; +SELECT a INTO DUMPFILE '/tmp/union.out.file' FROM t1 UNION SELECT a FROM t1; ERROR HY000: Incorrect usage of UNION and INTO DROP TABLE t1; CREATE TABLE t1 (a INT); diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 44f21abda19..3c792f28d4f 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -933,17 +933,25 @@ SELECT a INTO @v FROM ( SELECT a FROM t1 ) alias; -SELECT a INTO OUTFILE 'union.out.file' FROM ( - SELECT a FROM t1 - UNION - SELECT a FROM t1 WHERE 0 -) alias; +--let $outfile = $MYSQLTEST_VARDIR/tmp/union.out.file +--error 0,1 +--remove_file $outfile -SELECT a INTO DUMPFILE 'union.out.file2' FROM ( +--replace_result $MYSQLTEST_VARDIR +eval SELECT a INTO OUTFILE '$outfile' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 ) alias; +--remove_file $outfile + +--replace_result $MYSQLTEST_VARDIR +eval SELECT a INTO DUMPFILE '$outfile' FROM ( + SELECT a FROM t1 + UNION + SELECT a FROM t1 WHERE 0 +) alias; +--remove_file $outfile # # INTO will not be allowed in subqueries in version 5.1 and above. @@ -954,27 +962,42 @@ SELECT a FROM ( SELECT a INTO @v FROM t1 ) alias; -SELECT a FROM ( +--replace_result $MYSQLTEST_VARDIR +eval SELECT a FROM ( SELECT a FROM t1 UNION - SELECT a INTO OUTFILE 'union.out.file3' FROM t1 + SELECT a INTO OUTFILE '$outfile' FROM t1 ) alias; +--remove_file $outfile -SELECT a FROM ( +--replace_result $MYSQLTEST_VARDIR +eval SELECT a FROM ( SELECT a FROM t1 UNION - SELECT a INTO DUMPFILE 'union.out.file4' FROM t1 + SELECT a INTO DUMPFILE '$outfile' FROM t1 ) alias; +--remove_file $outfile SELECT a FROM t1 UNION SELECT a INTO @v FROM t1; -SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1; -SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1; + +--replace_result $MYSQLTEST_VARDIR +eval SELECT a FROM t1 UNION SELECT a INTO OUTFILE '$outfile' FROM t1; +--remove_file $outfile + +--replace_result $MYSQLTEST_VARDIR +eval SELECT a FROM t1 UNION SELECT a INTO DUMPFILE '$outfile' FROM t1; +--remove_file $outfile + --error ER_WRONG_USAGE SELECT a INTO @v FROM t1 UNION SELECT a FROM t1; + +--replace_result $MYSQLTEST_VARDIR --error ER_WRONG_USAGE -SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1; +eval SELECT a INTO OUTFILE '$outfile' FROM t1 UNION SELECT a FROM t1; + +--replace_result $MYSQLTEST_VARDIR --error ER_WRONG_USAGE -SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1; +eval SELECT a INTO DUMPFILE '$outfile' FROM t1 UNION SELECT a FROM t1; DROP TABLE t1; From cad09dab8f8685341274ecfe74db43088b970386 Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 19 Mar 2009 11:36:37 +0530 Subject: [PATCH 16/21] Fix for BUG#21360 - mysqldump error on federated tables When loading dump created by mysqldump tool an error is thrown saying storage engine for the table doesn't have an option. mysqldump tries to re-insert the data into the federated table which causes the error. Since the data is already available on the remote server, mysqldump shouldn't try to dump the data again for FEDERATED tables. As stated in the bug page, it can be considered similar to the MERGE ENGINE with "view only" nature. Fixed by adding the "FEDERATED ENGINE" to the exception list to ignore the data. client/mysqldump.c: Fixed check_if_ignore_table() to ignore FEDERATED engine when dumping the table data. mysql-test/r/federated.result: Result file for BUG#21360 mysql-test/t/federated.test: Testcase for BUG#21360 --- client/mysqldump.c | 3 ++- mysql-test/r/federated.result | 20 ++++++++++++++++++++ mysql-test/t/federated.test | 22 ++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index af6a6d10121..8ffc83b5684 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -3576,7 +3576,8 @@ char check_if_ignore_table(const char *table_name, char *table_type) If these two types, we do want to skip dumping the table */ if (!opt_no_data && - (!strcmp(table_type,"MRG_MyISAM") || !strcmp(table_type,"MRG_ISAM"))) + (!strcmp(table_type,"MRG_MyISAM") || !strcmp(table_type,"MRG_ISAM") || + !strcmp(table_type,"FEDERATED"))) result= IGNORE_DATA; } mysql_free_result(res); diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result index f0de3e9b04a..026886cb07d 100644 --- a/mysql-test/r/federated.result +++ b/mysql-test/r/federated.result @@ -2094,6 +2094,26 @@ SELECT t1.a FROM t1, t1 as t2 WHERE t2.b NOT LIKE t1.b; a DROP TABLE t1; DROP TABLE t1; +# +# BUG#21360 - mysqldump error on federated tables +# +#Switch to Connection Slave +CREATE TABLE t1(id VARCHAR(20) NOT NULL, PRIMARY KEY(id)); +INSERT INTO t1 VALUES ('text1'),('text2'),('text3'),('text4'); +#Switch to Connection Master +CREATE TABLE t1(id VARCHAR(20) NOT NULL, PRIMARY KEY(id)) ENGINE=FEDERATED +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1'; +# Dump table t1 using mysqldump tool +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( + `id` varchar(20) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1'; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE t1; +#Switch to Connection Slave +DROP TABLE t1; End of 5.0 tests SET @@GLOBAL.CONCURRENT_INSERT= @OLD_MASTER_CONCURRENT_INSERT; SET @@GLOBAL.CONCURRENT_INSERT= @OLD_SLAVE_CONCURRENT_INSERT; diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test index c977cb65fa0..ee9d1981558 100644 --- a/mysql-test/t/federated.test +++ b/mysql-test/t/federated.test @@ -1843,6 +1843,28 @@ DROP TABLE t1; connection master; DROP TABLE t1; +--echo # +--echo # BUG#21360 - mysqldump error on federated tables +--echo # +connection slave; +--echo #Switch to Connection Slave +CREATE TABLE t1(id VARCHAR(20) NOT NULL, PRIMARY KEY(id)); +INSERT INTO t1 VALUES ('text1'),('text2'),('text3'),('text4'); + +connection master; +--echo #Switch to Connection Master +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1(id VARCHAR(20) NOT NULL, PRIMARY KEY(id)) ENGINE=FEDERATED + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; +--echo # Dump table t1 using mysqldump tool +--replace_result $SLAVE_MYPORT SLAVE_PORT +--exec $MYSQL_DUMP --compact test t1 +DROP TABLE t1; + +connection slave; +--echo #Switch to Connection Slave +DROP TABLE t1; + connection default; --echo End of 5.0 tests From af016f72b90163d1a5e2d9d3368cc6d7f9f2394c Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 19 Mar 2009 12:20:28 +0400 Subject: [PATCH 17/21] Bug#41627 Illegal mix of collations in LEAST / GREATEST / CASE Don't throw an error after checking the first and the second arguments. Continue with checking the third and higher arguments and if some of them is stronger according to coercibility rules, then this argument's collation is set as result collation. mysql-test/r/ctype_collate.result: test result mysql-test/t/ctype_collate.test: test case sql/item.cc: Don't throw an error after checking the first and the second arguments. Continue with checking the third and higher arguments and if some of them is stronger according to coercibility rules, then this argument's collation is set as result collation. --- mysql-test/r/ctype_collate.result | 19 +++++++++++++++++++ mysql-test/t/ctype_collate.test | 14 ++++++++++++++ sql/item.cc | 19 ++++++++++++++++++- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ctype_collate.result b/mysql-test/r/ctype_collate.result index 7e9513f06e9..8bcd488cb69 100644 --- a/mysql-test/r/ctype_collate.result +++ b/mysql-test/r/ctype_collate.result @@ -611,3 +611,22 @@ check table t1 extended; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; +select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci); +least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) +a +create table t1 +select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as f1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` varchar(1) character set latin5 NOT NULL default '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +select case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate +latin5_turkish_ci then 2 else 3 end; +case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate +latin5_turkish_ci then 2 else 3 end +3 +select concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci); +concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) +abc diff --git a/mysql-test/t/ctype_collate.test b/mysql-test/t/ctype_collate.test index cfef8dfe81a..6b6abbcfbcc 100644 --- a/mysql-test/t/ctype_collate.test +++ b/mysql-test/t/ctype_collate.test @@ -229,3 +229,17 @@ insert into t1 set a=0x6c; insert into t1 set a=0x4c98; check table t1 extended; drop table t1; + +# +# Bug#41627 Illegal mix of collations in LEAST / GREATEST / CASE +# +select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci); +create table t1 +select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as f1; +show create table t1; +drop table t1; + +select case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate +latin5_turkish_ci then 2 else 3 end; + +select concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci); diff --git a/sql/item.cc b/sql/item.cc index f32828629cf..c80d1b7a455 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1498,7 +1498,8 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) else { // Cannot apply conversion - set(0, DERIVATION_NONE, 0); + set(&my_charset_bin, DERIVATION_NONE, + (dt.repertoire|repertoire)); return 1; } } @@ -1581,15 +1582,31 @@ bool agg_item_collations(DTCollation &c, const char *fname, { uint i; Item **arg; + bool unknown_cs= 0; + c.set(av[0]->collation); for (i= 1, arg= &av[item_sep]; i < count; i++, arg++) { if (c.aggregate((*arg)->collation, flags)) { + if (c.derivation == DERIVATION_NONE && + c.collation == &my_charset_bin) + { + unknown_cs= 1; + continue; + } my_coll_agg_error(av, count, fname, item_sep); return TRUE; } } + + if (unknown_cs && + c.derivation != DERIVATION_EXPLICIT) + { + my_coll_agg_error(av, count, fname, item_sep); + return TRUE; + } + if ((flags & MY_COLL_DISALLOW_NONE) && c.derivation == DERIVATION_NONE) { From 8c7789c313cdd18d06e6659dbb850900c597c040 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 19 Mar 2009 12:37:34 +0400 Subject: [PATCH 18/21] Bug#41268 Help Text for \c is misleading in client command line interface fixed help message client/mysql.cc: fixed help message --- client/mysql.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysql.cc b/client/mysql.cc index 0a4587d1c92..a2857620647 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1199,7 +1199,7 @@ int main(int argc,char *argv[]) #endif sprintf(buff, "%s", #ifndef NOT_YET - "Type 'help;' or '\\h' for help. Type '\\c' to clear the buffer.\n"); + "Type 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.\n"); #else "Type 'help [[%]function name[%]]' to get help on usage of function.\n"); #endif From afcfe81fea26b9f746ee7043c41d8dff52333067 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Thu, 19 Mar 2009 13:02:23 +0300 Subject: [PATCH 19/21] Fixed test failures in 5.1/6.0 introduced by the patch for bug #41486. Session max_allowed_packet is read-only as of MySQL 5.1.31. In addition, the global variable now has no effect on the current session. --- mysql-test/r/mysql.result | 2 -- mysql-test/t/mysql.test | 14 ++++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index a6087e0134b..cef5e08ec6b 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -194,7 +194,6 @@ delimiter 1 set @old_max_allowed_packet = @@global.max_allowed_packet; set @@global.max_allowed_packet = 2 * 1024 * 1024 + 1024; -set @@max_allowed_packet = @@global.max_allowed_packet; CREATE TABLE t1(data LONGBLOB); INSERT INTO t1 SELECT REPEAT('1', 2*1024*1024); SELECT LENGTH(data) FROM t1; @@ -202,5 +201,4 @@ LENGTH(data) 2097152 DROP TABLE t1; set @@global.max_allowed_packet = @old_max_allowed_packet; -set @@max_allowed_packet = @@global.max_allowed_packet; End of 5.0 tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 0030f624be6..f352c08fb5b 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -336,12 +336,16 @@ remove_file $MYSQLTEST_VARDIR/tmp/bug31060.sql; # mysqldump/import # -# Have to change the global variable as the mysql client will use -# a separate session +# Have to change the global variable as the session variable is +# read-only. set @old_max_allowed_packet = @@global.max_allowed_packet; # 2 MB blob length + some space for the rest of INSERT query set @@global.max_allowed_packet = 2 * 1024 * 1024 + 1024; -set @@max_allowed_packet = @@global.max_allowed_packet; + +# Create a new connection since the global max_allowed_packet +# has no effect for the current connection +connect (con1, localhost, root,,); +connection con1; CREATE TABLE t1(data LONGBLOB); INSERT INTO t1 SELECT REPEAT('1', 2*1024*1024); @@ -355,7 +359,9 @@ SELECT LENGTH(data) FROM t1; remove_file $MYSQLTEST_VARDIR/tmp/bug41486.sql; DROP TABLE t1; +connection default; +disconnect con1; + set @@global.max_allowed_packet = @old_max_allowed_packet; -set @@max_allowed_packet = @@global.max_allowed_packet; --echo End of 5.0 tests From 28f4090bda66bd4eb33ab0fd25fe2c29d24975a4 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Thu, 19 Mar 2009 11:27:45 +0100 Subject: [PATCH 20/21] Bug #42502 huge memory leak possible with timezone functions Unknown timezone specifications are properly rejected by the server, but are copied into tz_storage before rejection, and hence is retained until end of server life. With sufficiently large bogus timezone specs, it is easy to exhaust system memory. Allocation of memory for a copy of the timezone name is delayed until after verification of validity, at the cost of a memcpy of the timezone info. This only happens once, future lookups will hit the cached structure. --- sql/tztime.cc | 77 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 25 deletions(-) diff --git a/sql/tztime.cc b/sql/tztime.cc index d3d952e3c1e..d73a1ca0111 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1871,6 +1871,12 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) #ifdef ABBR_ARE_USED char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))]; #endif + /* + Used as a temporary tz_info until we decide that we actually want to + allocate and keep the tz info and tz name in tz_storage. + */ + TIME_ZONE_INFO tmp_tz_info; + memset(&tmp_tz_info, 0, sizeof(TIME_ZONE_INFO)); DBUG_ENTER("tz_load_from_open_tables"); @@ -1914,7 +1920,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) Most probably user has mistyped time zone name, so no need to bark here unless we need it for debugging. */ - sql_print_error("Can't find description of time zone '%s'", tz_name_buff); + sql_print_error("Can't find description of time zone '%.*s'", + tz_name->length(), tz_name->ptr()); #endif goto end; } @@ -1943,8 +1950,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) /* If Uses_leap_seconds == 'Y' */ if (table->field[1]->val_int() == 1) { - tz_info->leapcnt= tz_leapcnt; - tz_info->lsis= tz_lsis; + tmp_tz_info.leapcnt= tz_leapcnt; + tmp_tz_info.lsis= tz_lsis; } (void)table->file->ha_index_end(); @@ -1981,18 +1988,18 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) #ifdef ABBR_ARE_USED // FIXME should we do something with duplicates here ? table->field[4]->val_str(&abbr, &abbr); - if (tz_info->charcnt + abbr.length() + 1 > sizeof(chars)) + if (tmp_tz_info.charcnt + abbr.length() + 1 > sizeof(chars)) { sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition_type table: not enough " "room for abbreviations"); goto end; } - ttis[ttid].tt_abbrind= tz_info->charcnt; - memcpy(chars + tz_info->charcnt, abbr.ptr(), abbr.length()); - tz_info->charcnt+= abbr.length(); - chars[tz_info->charcnt]= 0; - tz_info->charcnt++; + ttis[ttid].tt_abbrind= tmp_tz_info.charcnt; + memcpy(chars + tmp_tz_info.charcnt, abbr.ptr(), abbr.length()); + tmp_tz_info.charcnt+= abbr.length(); + chars[tmp_tz_info.charcnt]= 0; + tmp_tz_info.charcnt++; DBUG_PRINT("info", ("time_zone_transition_type table: tz_id=%u tt_id=%u tt_gmtoff=%ld " @@ -2005,9 +2012,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) #endif /* ttid is increasing because we are reading using index */ - DBUG_ASSERT(ttid >= tz_info->typecnt); + DBUG_ASSERT(ttid >= tmp_tz_info.typecnt); - tz_info->typecnt= ttid + 1; + tmp_tz_info.typecnt= ttid + 1; res= table->file->index_next_same(table->record[0], (byte*)table->field[0]->ptr, 4); @@ -2040,14 +2047,14 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) ttime= (my_time_t)table->field[1]->val_int(); ttid= (uint)table->field[2]->val_int(); - if (tz_info->timecnt + 1 > TZ_MAX_TIMES) + if (tmp_tz_info.timecnt + 1 > TZ_MAX_TIMES) { sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition table: " "too much transitions"); goto end; } - if (ttid + 1 > tz_info->typecnt) + if (ttid + 1 > tmp_tz_info.typecnt) { sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition table: " @@ -2055,9 +2062,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) goto end; } - ats[tz_info->timecnt]= ttime; - types[tz_info->timecnt]= ttid; - tz_info->timecnt++; + ats[tmp_tz_info.timecnt]= ttime; + types[tmp_tz_info.timecnt]= ttid; + tmp_tz_info.timecnt++; DBUG_PRINT("info", ("time_zone_transition table: tz_id: %u tt_time: %lu tt_id: %u", @@ -2081,6 +2088,34 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) (void)table->file->ha_index_end(); table= 0; + /* + Let us check how correct our time zone description is. We don't check for + tz->timecnt < 1 since it is ok for GMT. + */ + if (tmp_tz_info.typecnt < 1) + { + sql_print_error("loading time zone without transition types"); + goto end; + } + + /* Allocate memory for the timezone info and timezone name in tz_storage. */ + if (!(alloc_buff= (char*) alloc_root(&tz_storage, sizeof(TIME_ZONE_INFO) + + tz_name->length() + 1))) + { + sql_print_error("Out of memory while loading time zone description"); + return 0; + } + + /* Move the temporary tz_info into the allocated area */ + tz_info= (TIME_ZONE_INFO *)alloc_buff; + memcpy(tz_info, &tmp_tz_info, sizeof(TIME_ZONE_INFO)); + tz_name_buff= alloc_buff + sizeof(TIME_ZONE_INFO); + /* + By writing zero to the end we guarantee that we can call ptr() + instead of c_ptr() for time zone name. + */ + strmake(tz_name_buff, tz_name->ptr(), tz_name->length()); + /* Now we will allocate memory and init TIME_ZONE_INFO structure. */ @@ -2112,15 +2147,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) tz_info->ttis= (TRAN_TYPE_INFO *)alloc_buff; memcpy(tz_info->ttis, ttis, tz_info->typecnt * sizeof(TRAN_TYPE_INFO)); - /* - Let us check how correct our time zone description and build - reversed map. We don't check for tz->timecnt < 1 since it ok for GMT. - */ - if (tz_info->typecnt < 1) - { - sql_print_error("loading time zone without transition types"); - goto end; - } + /* Build reversed map. */ if (prepare_tz_info(tz_info, &tz_storage)) { sql_print_error("Unable to build mktime map for time zone"); From 667a004c530db9d4ef516f75ab65e763deb23d46 Mon Sep 17 00:00:00 2001 From: Horst Hunger Date: Thu, 19 Mar 2009 12:21:38 +0100 Subject: [PATCH 21/21] Reviewed patch for Bug#39862. --- mysql-test/suite/sys_vars/t/concurrent_insert_func.test | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/sys_vars/t/concurrent_insert_func.test b/mysql-test/suite/sys_vars/t/concurrent_insert_func.test index cdeb76d9cac..1a600ffd7f6 100644 --- a/mysql-test/suite/sys_vars/t/concurrent_insert_func.test +++ b/mysql-test/suite/sys_vars/t/concurrent_insert_func.test @@ -11,6 +11,11 @@ # Creation Date: 2008-03-07 # # Author: Salman Rawala # # # +# Modified: HHunger 2009-02-23 Inserted a wait condition right after the # +# "INSERT ..record_6" to wait for the end of # +# the insert. # +# mleich This test needs some inporovements # +# # # Description: Test Cases of Dynamic System Variable "concurrent_insert" # # that checks functionality of this variable # # # @@ -62,7 +67,6 @@ connection test_con1; INSERT INTO t1(name) VALUES('Record_4'); SELECT * FROM t1; - --echo ## unlocking tables ## --echo connection default; connection default; @@ -106,6 +110,8 @@ UNLOCK TABLES; --echo ## table contens after UNLOCK ## SELECT * FROM t1; INSERT INTO t1(name) VALUES('Record_6'); +let $wait_condition= SELECT COUNT(*) = 5 FROM t1; +--source include/wait_condition.inc --echo connection test_con1; connection test_con1;