[Commits] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (monty:2847)

#At lp:maria/5.2 based on revid:monty@mysql.com-20100810220446-jzy713163fjegn30 2847 Michael Widenius 2010-08-25 [merge] Automerge with 5.1 removed: mysql-test/include/have_exampledb.inc mysql-test/r/exampledb.result mysql-test/suite/pbxt/t/suite.opt mysql-test/t/exampledb.test added: BUILD/compile-amd64-debug-all BUILD/compile-pentium-debug-all BUILD/compile-pentium64-debug-all mysql-test/README.suites mysql-test/include/have_binlog_format_mixed.opt mysql-test/include/have_binlog_format_row.opt mysql-test/include/have_binlog_format_statement.opt mysql-test/include/have_innodb.opt mysql-test/include/have_log_bin-master.opt mysql-test/include/have_log_bin-slave.opt mysql-test/include/have_pbxt.opt mysql-test/lib/My/Suite.pm mysql-test/suite/federated/federated_bug_32426.result mysql-test/suite/federated/federated_bug_32426.test mysql-test/suite/innodb_plugin/combinations mysql-test/suite/innodb_plugin/suite.pm mysql-test/suite/rpl/t/rpl_ddl-slave.opt scripts/convert-debug-for-diff.sh modified: .bzrignore BUILD/SETUP.sh client/mysql.cc client/mysqlcheck.c client/mysqldump.c client/mysqlimport.c extra/my_print_defaults.c include/my_global.h mysql-test/Makefile.am mysql-test/README mysql-test/include/default_my.cnf mysql-test/include/default_mysqld.cnf mysql-test/include/have_innodb.inc mysql-test/include/have_innodb_plugin.inc mysql-test/include/have_log_bin.inc mysql-test/lib/My/Config.pm mysql-test/lib/My/ConfigFactory.pm mysql-test/lib/My/Handles.pm* mysql-test/lib/My/SafeProcess.pm mysql-test/lib/My/Test.pm mysql-test/lib/mtr_cases.pm mysql-test/lib/mtr_report.pm mysql-test/mysql-test-run.pl mysql-test/r/group_by.result mysql-test/r/subselect4.result mysql-test/r/warnings_engine_disabled.result mysql-test/suite/binlog/t/binlog_base64_flag.test mysql-test/suite/binlog/t/binlog_old_versions.test mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam-master.opt mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam-master.opt mysql-test/suite/federated/federated_innodb-slave.opt mysql-test/suite/federated/federated_server.result mysql-test/suite/federated/my.cnf mysql-test/suite/funcs_1/t/is_columns_is.test mysql-test/suite/innodb/t/innodb-master.opt mysql-test/suite/innodb/t/innodb-semi-consistent-master.opt mysql-test/suite/innodb/t/innodb_autoinc_lock_mode_zero-master.opt mysql-test/suite/innodb/t/innodb_bug30919-master.opt mysql-test/suite/innodb/t/innodb_bug39438-master.opt mysql-test/suite/innodb/t/innodb_bug52663-master.opt mysql-test/suite/innodb/t/innodb_bug53674-master.opt mysql-test/suite/innodb/t/innodb_bug53674.test mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1-master.opt mysql-test/suite/innodb/t/innodb_misc1-master.opt mysql-test/suite/innodb/t/innodb_mysql-master.opt mysql-test/suite/innodb/t/innodb_mysql_rbk-master.opt mysql-test/suite/innodb/t/innodb_timeout_rollback-master.opt mysql-test/suite/innodb_plugin/t/innodb-consistent-master.opt mysql-test/suite/innodb_plugin/t/innodb-master.opt mysql-test/suite/innodb_plugin/t/innodb-semi-consistent-master.opt mysql-test/suite/innodb_plugin/t/innodb-use-sys-malloc-master.opt mysql-test/suite/innodb_plugin/t/innodb_autoinc_lock_mode_zero-master.opt mysql-test/suite/innodb_plugin/t/innodb_bug30919-master.opt mysql-test/suite/innodb_plugin/t/innodb_bug39438-master.opt mysql-test/suite/innodb_plugin/t/innodb_bug42101-nonzero-master.opt mysql-test/suite/innodb_plugin/t/innodb_bug53674-master.opt mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1-master.opt mysql-test/suite/innodb_plugin/t/innodb_mysql-master.opt mysql-test/suite/innodb_plugin/t/innodb_mysql_rbk-master.opt mysql-test/suite/innodb_plugin/t/innodb_timeout_rollback-master.opt mysql-test/suite/ndb_team/t/rpl_ndb_mix_innodb-master.opt mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt mysql-test/suite/parts/t/partition_special_innodb-master.opt mysql-test/suite/pbxt/my.cnf mysql-test/suite/percona/percona_innodb_doublewrite_file-master.opt mysql-test/suite/rpl/r/rpl_row_basic_11bugs-master.opt mysql-test/suite/rpl/r/rpl_row_basic_11bugs-slave.opt mysql-test/suite/rpl/rpl_1slave_base.cnf mysql-test/suite/rpl/t/rpl_begin_commit_rollback-master.opt mysql-test/suite/rpl/t/rpl_begin_commit_rollback-slave.opt mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.cnf mysql-test/suite/rpl/t/rpl_concurrency_error-master.opt mysql-test/suite/rpl/t/rpl_deadlock_innodb-slave.opt mysql-test/suite/rpl/t/rpl_innodb-master.opt mysql-test/suite/rpl/t/rpl_innodb_bug28430-master.opt mysql-test/suite/rpl/t/rpl_innodb_bug28430-slave.opt mysql-test/suite/rpl/t/rpl_start_stop_slave-slave.opt mysql-test/suite/rpl/t/rpl_trigger.test mysql-test/suite/rpl/t/rpl_typeconv-slave.opt mysql-test/suite/rpl_ndb/t/rpl_ndb_2innodb-slave.opt mysql-test/suite/rpl_ndb/t/rpl_ndb_2other-slave.opt mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_2ch.cnf mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb2ndb-master.opt mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb_trans-slave.opt mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_engines_transactions-master.opt mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_engines_transactions-slave.opt mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_tables-master.opt mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_tables-slave.opt mysql-test/suite/rpl_ndb/t/rpl_ndb_stm_innodb-master.opt mysql-test/suite/sys_vars/t/autocommit_func-master.opt mysql-test/suite/sys_vars/t/character_set_filesystem_func-master.opt mysql-test/suite/sys_vars/t/identity_func-master.opt mysql-test/suite/sys_vars/t/innodb_autoinc_lock_mode_func-master.opt mysql-test/suite/sys_vars/t/last_insert_id_func-master.opt mysql-test/suite/sys_vars/t/max_binlog_cache_size_func-master.opt mysql-test/suite/sys_vars/t/storage_engine_basic-master.opt mysql-test/suite/sys_vars/t/tx_isolation_func-master.opt mysql-test/t/bug46760-master.opt mysql-test/t/concurrent_innodb_safelog-master.opt mysql-test/t/concurrent_innodb_unsafelog-master.opt mysql-test/t/connect.cnf mysql-test/t/disabled.def mysql-test/t/group_by.test mysql-test/t/partition_innodb-master.opt mysql-test/t/partition_innodb_semi_consistent-master.opt mysql-test/t/pool_of_threads.cnf mysql-test/t/sp_trans_log.test mysql-test/t/subselect4.test mysql-test/t/unsafe_binlog_innodb-master.opt mysql-test/t/warnings_engine_disabled.test mysys/my_getwd.c scripts/Makefile.am sql/item.h sql/item_func.h sql/item_sum.cc sql/item_sum.h sql/log.cc sql/mysqld.cc sql/sql_select.cc sql/sql_select.h storage/federatedx/federatedx_io_mysql.cc storage/federatedx/federatedx_io_null.cc storage/federatedx/ha_federatedx.cc storage/federatedx/ha_federatedx.h storage/maria/ha_maria.cc storage/maria/ma_bitmap.c storage/maria/ma_blockrec.c storage/maria/ma_check.c storage/maria/ma_checkpoint.c storage/maria/ma_key_recover.c storage/maria/ma_recovery.c storage/maria/ma_static.c storage/maria/ma_test2.c storage/maria/ma_write.c storage/maria/maria_chk.c storage/maria/maria_def.h storage/maria/maria_pack.c storage/maria/maria_read_log.c storage/maria/unittest/ma_test_recovery.pl storage/xtradb/buf/buf0lru.c storage/xtradb/fil/fil0fil.c storage/xtradb/handler/i_s.cc storage/xtradb/srv/srv0srv.c support-files/compiler_warnings.supp unittest/mytap/tap.h === modified file '.bzrignore' --- a/.bzrignore 2010-06-01 19:52:20 +0000 +++ b/.bzrignore 2010-08-24 22:44:50 +0000 @@ -1936,3 +1936,5 @@ sql/client_plugin.c *.dgcov libmysqld/create_options.cc storage/pbxt/bin/xtstat +mysql-test/mtr_command +scripts/convert-debug-for-diff === modified file 'BUILD/SETUP.sh' --- a/BUILD/SETUP.sh 2010-08-05 19:56:11 +0000 +++ b/BUILD/SETUP.sh 2010-08-24 22:44:50 +0000 @@ -91,8 +91,8 @@ path=`dirname $0` get_make_parallel_flag # SSL library to use.--with-ssl will select our bundled yaSSL -# implementation of SSL. To use openSSl you will nee too point out -# the location of openSSL headers and lbs on your system. +# implementation of SSL. To use OpenSSL you will need to specify +# the location of OpenSSL headers and libs on your system. # Ex --with-ssl=/usr SSL_LIBRARY=--with-ssl @@ -182,8 +182,7 @@ max_no_embedded_configs="$SSL_LIBRARY -- max_no_qc_configs="$SSL_LIBRARY --with-plugins=max --without-query-cache" max_no_ndb_configs="$SSL_LIBRARY --with-plugins=max-no-ndb --with-embedded-server --with-libevent" max_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-libevent" -# Disable NDB in maria max builds -max_configs=$max_no_ndb_configs +all_configs="$SSL_LIBRARY --with-plugins=max --with-plugin-ndbcluster --with-embedded-server --with-libevent" # # CPU and platform specific compilation flags. === added file 'BUILD/compile-amd64-debug-all' --- a/BUILD/compile-amd64-debug-all 1970-01-01 00:00:00 +0000 +++ b/BUILD/compile-amd64-debug-all 2010-08-10 14:36:04 +0000 @@ -0,0 +1,7 @@ +#! /bin/sh +path=`dirname $0` +. "$path/SETUP.sh" +extra_flags="$amd64_cflags $debug_cflags" +extra_configs="$amd64_configs $debug_configs $all_configs" + +. "$path/FINISH.sh" === added file 'BUILD/compile-pentium-debug-all' --- a/BUILD/compile-pentium-debug-all 1970-01-01 00:00:00 +0000 +++ b/BUILD/compile-pentium-debug-all 2010-08-10 14:36:04 +0000 @@ -0,0 +1,10 @@ +#! /bin/sh + +path=`dirname $0` +set -- "$@" --with-debug=full +. "$path/SETUP.sh" + +extra_flags="$pentium_cflags $debug_cflags" +extra_configs="$pentium_configs $debug_configs $all_configs $error_inject --with-experimental-collations" + +. "$path/FINISH.sh" === added file 'BUILD/compile-pentium64-debug-all' --- a/BUILD/compile-pentium64-debug-all 1970-01-01 00:00:00 +0000 +++ b/BUILD/compile-pentium64-debug-all 2010-08-10 14:36:04 +0000 @@ -0,0 +1,12 @@ +#! /bin/sh + +path=`dirname $0` +set -- "$@" --with-debug=full +. "$path/SETUP.sh" + +extra_flags="$pentium64_cflags $debug_cflags" +extra_configs="$pentium_configs $debug_configs $all_configs" + +extra_configs="$extra_configs " +CC="$CC --pipe" +. "$path/FINISH.sh" === modified file 'client/mysql.cc' --- a/client/mysql.cc 2010-08-05 19:56:11 +0000 +++ b/client/mysql.cc 2010-08-24 22:44:50 +0000 @@ -156,6 +156,7 @@ static my_bool ignore_errors=0,wait_flag static my_bool debug_info_flag, debug_check_flag, batch_abort_on_error; static my_bool column_types_flag; static my_bool preserve_comments= 0; +static my_bool in_com_source, aborted= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; static uint my_end_arg; @@ -1088,6 +1089,7 @@ int main(int argc,char *argv[]) "\\N [\\d]> ",MYF(MY_WME)); current_prompt = my_strdup(default_prompt,MYF(MY_WME)); prompt_counter=0; + aborted= 0; outfile[0]=0; // no (default) outfile strmov(pager, "stdout"); // the default, if --pager wasn't given @@ -1282,8 +1284,10 @@ sig_handler mysql_end(int sig) /* This function handles sigint calls If query is in process, kill query + If 'source' is executed, abort source command no query in process, terminate like previous behavior */ + sig_handler handle_sigint(int sig) { char kill_buffer[40]; @@ -1322,7 +1326,8 @@ sig_handler handle_sigint(int sig) mysql_close(kill_mysql); tee_fprintf(stdout, "Ctrl-C -- query killed. Continuing normally.\n"); interrupted_query= 0; - + if (in_com_source) + aborted= 1; // Abort source command return; err: @@ -1886,7 +1891,7 @@ static int read_and_execute(bool interac String buffer; #endif - char *line; + char *line= 0; char in_string=0; ulong line_number=0; bool ml_comment= 0; @@ -1894,7 +1899,7 @@ static int read_and_execute(bool interac bool truncated= 0; status.exit_status=1; - for (;;) + while (!aborted) { if (!interactive) { @@ -4074,17 +4079,19 @@ static int com_source(String *buffer, ch status.file_name=source_name; glob_buffer.length(0); // Empty command buffer ignore_errors= !batch_abort_on_error; + in_com_source= 1; error= read_and_execute(false); ignore_errors= save_ignore_errors; status=old_status; // Continue as before + in_com_source= aborted= 0; my_fclose(sql_file,MYF(0)); batch_readline_end(line_buff); /* If we got an error during source operation, don't abort the client if ignore_errors is set */ - if (error && batch_abort_on_error && ignore_errors) - error= -1; + if (error && !batch_abort_on_error && ignore_errors) + error= -1; // Ignore error return error; } === modified file 'client/mysqlcheck.c' --- a/client/mysqlcheck.c 2010-08-02 09:01:24 +0000 +++ b/client/mysqlcheck.c 2010-08-11 10:55:54 +0000 @@ -71,8 +71,8 @@ static struct my_option my_long_options[ &opt_auto_repair, &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory for character set files.", &charsets_dir, - &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Directory for character set files.", (char**) &charsets_dir, + (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"check", 'c', "Check table for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"check-only-changed", 'C', === modified file 'client/mysqldump.c' --- a/client/mysqldump.c 2010-08-02 09:01:24 +0000 +++ b/client/mysqldump.c 2010-08-11 10:55:54 +0000 @@ -211,8 +211,8 @@ static struct my_option my_long_options[ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory for character set files.", &charsets_dir, - &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Directory for character set files.", (char**) &charsets_dir, + (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"comments", 'i', "Write additional information.", &opt_comments, &opt_comments, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -242,8 +242,8 @@ static struct my_option my_long_options[ {"debug", '#', "This is a non-debug version. Catch this and exit.", 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, #else - {"debug", '#', "Output debug log.", &default_dbug_option, - &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"debug", '#', "Output debug log.", (char**) &default_dbug_option, + (char**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", &debug_check_flag, &debug_check_flag, 0, === modified file 'client/mysqlimport.c' --- a/client/mysqlimport.c 2010-06-10 20:16:43 +0000 +++ b/client/mysqlimport.c 2010-08-11 10:55:54 +0000 @@ -73,8 +73,8 @@ static struct my_option my_long_options[ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory for character set files.", &charsets_dir, - &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Directory for character set files.", (char**) &charsets_dir, + (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, "Set the default character set.", &default_charset, &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, === modified file 'extra/my_print_defaults.c' --- a/extra/my_print_defaults.c 2010-08-04 18:36:11 +0000 +++ b/extra/my_print_defaults.c 2010-08-11 10:55:54 +0000 @@ -55,8 +55,8 @@ static struct my_option my_long_options[ {"debug", '#', "This is a non-debug version. Catch this and exit", 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, #else - {"debug", '#', "Output debug log", &default_dbug_option, - &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"debug", '#', "Output debug log", (char**) &default_dbug_option, + (char**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif {"defaults-file", 'c', "Like --config-file, except: if first option, " "then read this file only, do not read global or per-user config " === modified file 'include/my_global.h' --- a/include/my_global.h 2010-08-05 19:56:11 +0000 +++ b/include/my_global.h 2010-08-24 22:44:50 +0000 @@ -807,10 +807,10 @@ typedef SOCKET_SIZE_TYPE size_socket; #endif /* get memory in huncs */ #define ONCE_ALLOC_INIT (uint) (4096-MALLOC_OVERHEAD) - /* Typical record cash */ -#define RECORD_CACHE_SIZE (uint) (64*1024-MALLOC_OVERHEAD) - /* Typical key cash */ -#define KEY_CACHE_SIZE (uint) (8*1024*1024-MALLOC_OVERHEAD) + /* Typical record cache */ +#define RECORD_CACHE_SIZE (uint) (128*1024-MALLOC_OVERHEAD) + /* Typical key cache */ +#define KEY_CACHE_SIZE (uint) (128L*1024L*1024L-MALLOC_OVERHEAD) /* Default size of a key cache block */ #define KEY_CACHE_BLOCK_SIZE (uint) 1024 === modified file 'mysql-test/Makefile.am' --- a/mysql-test/Makefile.am 2010-08-05 19:56:11 +0000 +++ b/mysql-test/Makefile.am 2010-08-24 22:44:50 +0000 @@ -63,13 +63,14 @@ nobase_test_DATA = \ lib/My/SafeProcess.pm \ lib/My/File/Path.pm \ lib/My/SysInfo.pm \ + lib/My/Suite.pm \ lib/My/CoreDump.pm \ lib/My/SafeProcess/Base.pm \ lib/My/SafeProcess/safe_process.pl SUBDIRS = lib/My/SafeProcess -EXTRA_DIST = README \ +EXTRA_DIST = README README.suites \ $(test_SCRIPTS) \ $(nobase_test_DATA) @@ -101,7 +102,7 @@ TEST_DIRS = t r include std_data std_dat suite/ndb suite/ndb/t suite/ndb/r \ suite/rpl_ndb suite/rpl_ndb/t suite/rpl_ndb/r \ suite/parts suite/parts/t suite/parts/r suite/parts/inc \ - suite/pbxt/t suite/pbxt/r \ + suite/pbxt/t suite/pbxt/r suite/pbxt \ suite/innodb suite/innodb/t suite/innodb/r suite/innodb/include \ suite/vcol suite/vcol/t suite/vcol/r suite/vcol/inc \ suite/oqgraph suite/oqgraph/t suite/oqgraph/r suite/oqgraph/include \ === modified file 'mysql-test/README' --- a/mysql-test/README 2006-03-02 00:51:33 +0000 +++ b/mysql-test/README 2010-08-18 07:52:57 +0000 @@ -18,7 +18,7 @@ the test suite expects you to provide th For example, here is the command to run the "alias" and "analyze" tests with an external server: -mysql-test-run --extern alias analyze +mysql-test-run --extern socket=/tmp/mysql.sock alias analyze To match your setup, you might also need to provide --socket, --user, and other relevant options. === added file 'mysql-test/README.suites' --- a/mysql-test/README.suites 1970-01-01 00:00:00 +0000 +++ b/mysql-test/README.suites 2010-08-24 12:33:34 +0000 @@ -0,0 +1,138 @@ +These are the assorted notes that will be turned into a manual eventually. + +========================== +Tests are organized in suites. +A "suite" is a subdirectory inside, one of, + + <basedir>/mysql-test/suite + <basedir>/mysql-test + <basedir>/share/mysql-test/suite + <basedir>/share/mysql-test + <basedir>/share/mysql/mysql-test/suite + <basedir>/share/mysql/mysql-test + <basedir>/storage/*/mysql-test-suites + +This is supposed to cover running mtr from a source directory and installed. + +========================== +A suite contains *.test and *.result files. They can be in the t/ and r/ +subdirectories under the suitedir or directly in the suitedir +(that is suitedir/t/*.test or suitedir/*.test, same for *.result)) + +========================== +A suite can contain a suite.opt file - at the same location where .test +files are. As usual, the .opt file can use $-substitutions for the +environment variables. + +Usually, using my.cnf template (see below) is preferrable. +========================== +A suite can have suite.pm file in the suitedir. It must declare a +package that inherits from My::Suite. + +The suite.pm needs to have @ISA=qw(My::Suite) and it must end +with bless {}; - that is it must return an object of that class. +It can also return a string - in this case all tests in the suite +will be skipped, with this string being printed as a reason. + +A suite class can define config_files() and servers() methods. + +A config_files method returns a list of additional config files (besides +my.cnf), that this suite needs to be created. For every file it specifies +a function that will create it, when given a My::Config object. For example: + + sub config_files { ( 'config.ini' => \&write_ini, + 'new.conf' => \&do_new_conf ) } + +A servers method returns a list of processes that needs to be started for +this suite. A process is specified as a pair (regex, hash). A regex must +match a section in the my.cnf template (for example, qr/mysqld\./ corresponds +to all mysqld processes), a hash contains these options: + + SORT => a number, processes are started in the order of increasing SORT + values (and stopped in the reverse order). mysqld has number 300. + START => a function to start a process. It takes two arguments, + My::Config::Group and My::Test. If START is undefined the process + will not be started. + WAIT => a function waits for the process to be started. It takes + My::Config::Group as an argument. Internallys mtr first invokes + START for all processes, then WAIT for all started processes. + +example: sub servers { ( qr/^foo$/ => { SORT => 200, + START => \&start_foo, + WAIT => \&wait_foo } ) } + +See sphinx suite for an example. + +========================== +A suite can have my.cnf template file in the suitedir. +A my.cnf template uses a normal my.cnf syntax - groups, options, +and values - with templating extensions. They are + +* There can be groups with non-standard names, not used by mysqld. + These groups may be used by the suite.pm file somehow. + For example, they can be written to the additional config files. + See sphinx suite for an example. + +* There can be ENV group. It sets values for the environment variables. + +* Values can refer to each other - they will be expanded as needed. + A reference to a value of an option looks like @groupname.optionname. + For example + + [mysqld.2] + master-port= @mysqld.1.port + + it sets the master-port in the mysqld.2 group to the value of + port in the mysqld.1 group. + +* An option name may start from '#'. In the resulting my.cnf it will look + like a comment, but it still can be referred to. For example: + + [example] + #foo = localhost:@mysqld.1.port + bar = http://@example.#foo/index.html + +* There are two special - in this regard - groups. + + Via the ENV group one can refer to any environment variable, not only + to values in the [ENV] group of my.cnf file. + + Via the OPT group one can refer to special values: + @OPT.vardir - a path to vardir + @OPT.port - a new port number is reserved out of the pool. It will not + match any other port number used by this test run. + See sphinx suite for an example. + +Most probably a suite my.cnf will need to start from + + !include include/default_my.cnf + +and then modify the configuration as necessary. +========================== + +A suite can have combinations file in the suitedir. It uses my.cnf syntax +but it cannot use @-substitutions. Instead, it can use $-substitutions for +the environment variables. Because the combination options will not be +merged to a my.cnf, but will be added to the command line. Example: + + [conf1] + opt1=val1 + + [conf2] + opt1=val2 + opt2=$HAVE_SOMETHING + +Such a file will cause every test from the suite to be run twice - once +with mysqld using --opt1=val1 and the other one with mysqld using +--opt1=val2 --opt2=$HAVE_SOMETHING + +One can limit mtr run to a subset of combinations by setting environment +variable SUITENAME_COMBINATIONS to the ':'-separated set of combination +names. E.g. + + RPL_COMBINATIONS=mix:row ./mtr --suite rpl + +See innodb_plugin suite for an example of how suite.pm may set this variable +to exclude unsupported configurations. +========================== + === modified file 'mysql-test/include/default_my.cnf' --- a/mysql-test/include/default_my.cnf 2007-12-12 17:19:24 +0000 +++ b/mysql-test/include/default_my.cnf 2010-08-17 07:14:46 +0000 @@ -6,9 +6,6 @@ # Run the master.sh script before starting this process #!run-master-sh -log-bin= master-bin - - [mysqlbinlog] disable-force-if-open === modified file 'mysql-test/include/default_mysqld.cnf' --- a/mysql-test/include/default_mysqld.cnf 2010-03-28 18:10:00 +0000 +++ b/mysql-test/include/default_mysqld.cnf 2010-08-17 07:14:46 +0000 @@ -13,9 +13,10 @@ key_buffer_size= 1M sort_buffer= 256K max_heap_table_size= 1M +loose-skip-innodb +loose-skip-pbxt + loose-innodb_data_file_path= ibdata1:10M:autoextend slave-net-timeout=120 -log-bin=mysqld-bin - === added file 'mysql-test/include/have_binlog_format_mixed.opt' --- a/mysql-test/include/have_binlog_format_mixed.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/include/have_binlog_format_mixed.opt 2010-08-17 07:14:46 +0000 @@ -0,0 +1 @@ +--binlog-format=mixed === added file 'mysql-test/include/have_binlog_format_row.opt' --- a/mysql-test/include/have_binlog_format_row.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/include/have_binlog_format_row.opt 2010-08-17 07:14:46 +0000 @@ -0,0 +1 @@ +--binlog-format=row === added file 'mysql-test/include/have_binlog_format_statement.opt' --- a/mysql-test/include/have_binlog_format_statement.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/include/have_binlog_format_statement.opt 2010-08-17 07:14:46 +0000 @@ -0,0 +1,2 @@ +--binlog-format=statement + === removed file 'mysql-test/include/have_exampledb.inc' --- a/mysql-test/include/have_exampledb.inc 2008-07-04 18:48:25 +0000 +++ b/mysql-test/include/have_exampledb.inc 1970-01-01 00:00:00 +0000 @@ -1,4 +0,0 @@ -disable_query_log; ---require r/true.require -select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'example'; -enable_query_log; === modified file 'mysql-test/include/have_innodb.inc' --- a/mysql-test/include/have_innodb.inc 2010-03-31 13:04:40 +0000 +++ b/mysql-test/include/have_innodb.inc 2010-08-17 07:14:46 +0000 @@ -1,4 +1,5 @@ -disable_query_log; ---require r/true.require -select (support = 'YES' or support = 'DEFAULT' or support = 'ENABLED') as `TRUE` from information_schema.engines where engine = 'innodb'; -enable_query_log; +if (!`SELECT count(*) FROM information_schema.engines WHERE + (support = 'YES' OR support = 'DEFAULT') AND + engine = 'innodb'`){ + skip Needs innodb engine; +} === added file 'mysql-test/include/have_innodb.opt' --- a/mysql-test/include/have_innodb.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/include/have_innodb.opt 2010-08-17 07:14:46 +0000 @@ -0,0 +1 @@ +--loose-innodb === modified file 'mysql-test/include/have_innodb_plugin.inc' --- a/mysql-test/include/have_innodb_plugin.inc 2010-08-03 21:26:17 +0000 +++ b/mysql-test/include/have_innodb_plugin.inc 2010-08-17 07:14:46 +0000 @@ -1,4 +1,5 @@ -disable_query_log; ---require r/true.require -SELECT (plugin_library LIKE 'ha_innodb_plugin%' OR plugin_description LIKE '%xtradb%') AS `TRUE` FROM information_schema.plugins WHERE LOWER(plugin_name) = 'innodb' AND LOWER(plugin_status) = 'active'; -enable_query_log; +if (!`SELECT COUNT(*) FROM INFORMATION_SCHEMA.PLUGINS + WHERE PLUGIN_NAME = 'innodb' AND PLUGIN_STATUS = 'active' AND + (PLUGIN_LIBRARY LIKE 'ha_innodb_plugin%' OR PLUGIN_DESCRIPTION LIKE '%xtradb%')`) { + skip Need InnoDB plugin or XtraDB; +} === added file 'mysql-test/include/have_log_bin-master.opt' --- a/mysql-test/include/have_log_bin-master.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/include/have_log_bin-master.opt 2010-08-17 07:14:46 +0000 @@ -0,0 +1 @@ +--log-bin=master-bin === added file 'mysql-test/include/have_log_bin-slave.opt' --- a/mysql-test/include/have_log_bin-slave.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/include/have_log_bin-slave.opt 2010-08-17 07:14:46 +0000 @@ -0,0 +1 @@ +--log-bin=slave-bin === modified file 'mysql-test/include/have_log_bin.inc' --- a/mysql-test/include/have_log_bin.inc 2008-08-04 05:04:47 +0000 +++ b/mysql-test/include/have_log_bin.inc 2010-08-17 07:14:46 +0000 @@ -6,6 +6,8 @@ # # source include/have_log_bin.inc; +source include/not_embedded.inc; + -- require r/have_log_bin.require disable_query_log; show variables like 'log_bin'; === added file 'mysql-test/include/have_pbxt.opt' --- a/mysql-test/include/have_pbxt.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/include/have_pbxt.opt 2010-08-17 07:14:46 +0000 @@ -0,0 +1 @@ +--loose-pbxt === modified file 'mysql-test/lib/My/Config.pm' --- a/mysql-test/lib/My/Config.pm 2008-09-05 13:31:09 +0000 +++ b/mysql-test/lib/My/Config.pm 2010-08-17 07:14:46 +0000 @@ -6,7 +6,6 @@ use strict; use warnings; use Carp; - sub new { my ($class, $option_name, $option_value)= @_; my $self= bless { name => $option_name, @@ -61,7 +60,7 @@ sub insert { $option->{value}= $value; } else { - my $option= My::Config::Option->new($option_name, $value); + $option= My::Config::Option->new($option_name, $value); # Insert option in list push(@{$self->{options}}, $option); # Insert option in hash @@ -163,6 +162,62 @@ sub if_exist { return $option->value(); } +package My::Config::Group::ENV; +our @ISA=qw(My::Config::Group); + +use strict; +use warnings; +use Carp; + +sub new { + my ($class, $group_name)= @_; + bless My::Config::Group->new($group_name), $class; +} + +# +# Return value for an option in the group, fail if it does not exist +# +sub value { + my ($self, $option_name)= @_; + my $option= $self->option($option_name); + + if (! defined($option) and defined $ENV{$option_name}) { + my $value= $ENV{$option_name}; + $option= My::Config::Option->new($option_name, $value); + } + + croak "No option named '$option_name' in group '$self->{name}'" + if ! defined($option); + + return $option->value(); +} + +package My::Config::Group::OPT; +our @ISA=qw(My::Config::Group); + +use strict; +use warnings; +use Carp; + +sub new { + my ($class, $group_name)= @_; + bless My::Config::Group->new($group_name), $class; +} + +sub options { + my ($self)= @_; + () +} + +sub value { + my ($self, $option_name)= @_; + my $option= $self->option($option_name); + + croak "No option named '$option_name' in group '$self->{name}'" + if ! defined($option); + + return $option->value()->(); +} package My::Config; @@ -182,7 +237,10 @@ sub new { my ($class, $path)= @_; my $group_name= undef; - my $self= bless { groups => [] }, $class; + my $self= bless { groups => [ + My::Config::Group::ENV->new('ENV'), + My::Config::Group::OPT->new('OPT'), + ] }, $class; my $F= IO::File->new($path, "<") or croak "Could not open '$path': $!"; @@ -199,19 +257,13 @@ sub new { } # Magic #! comments - elsif ( $line =~ /^#\!/) { - my $magic= $line; + elsif ( $line =~ /^(#\!\S+)(?:\s*(.*?)\s*)?$/) { + my ($magic, $arg)= ($1, $2); croak "Found magic comment '$magic' outside of group" unless $group_name; #print "$magic\n"; - $self->insert($group_name, $magic, undef); - } - - # Comments - elsif ( $line =~ /^#/ || $line =~ /^;/) { - # Skip comment - next; + $self->insert($group_name, $magic, $arg); } # Empty lines @@ -236,7 +288,7 @@ sub new { } # <option> - elsif ( $line =~ /^([\@\w-]+)\s*$/ ) { + elsif ( $line =~ /^(#?[\w-]+)\s*$/ ) { my $option= $1; croak "Found option '$option' outside of group" @@ -247,7 +299,7 @@ sub new { } # <option>=<value> - elsif ( $line =~ /^([\@\w-]+)\s*=\s*(.*?)\s*$/ ) { + elsif ( $line =~ /^(#?[\w-]+)\s*=\s*(.*?)\s*$/ ) { my $option= $1; my $value= $2; @@ -256,10 +308,17 @@ sub new { #print "$option=$value\n"; $self->insert($group_name, $option, $value); - } else { - croak "Unexpected line '$line' found in '$path'"; } + # Comments + elsif ( $line =~ /^#/ || $line =~ /^;/) { + # Skip comment + next; + } + + else { + croak "Unexpected line '$line' found in '$path'"; + } } undef $F; # Close the file @@ -437,44 +496,4 @@ sub exists { return defined($option); } - -# Overload "to string"-operator with 'stringify' -use overload - '""' => \&stringify; - -# -# Return the config as a string in my.cnf file format -# -sub stringify { - my ($self)= @_; - my $res; - - foreach my $group ($self->groups()) { - $res .= "[$group->{name}]\n"; - - foreach my $option ($group->options()) { - $res .= $option->name(); - my $value= $option->value(); - if (defined $value) { - $res .= "=$value"; - } - $res .= "\n"; - } - $res .= "\n"; - } - return $res; -} - - -# -# Save the config to named file -# -sub save { - my ($self, $path)= @_; - my $F= IO::File->new($path, ">") - or croak "Could not open '$path': $!"; - print $F $self; - undef $F; # Close the file -} - 1; === modified file 'mysql-test/lib/My/ConfigFactory.pm' --- a/mysql-test/lib/My/ConfigFactory.pm 2010-04-28 12:52:24 +0000 +++ b/mysql-test/lib/My/ConfigFactory.pm 2010-08-17 07:14:46 +0000 @@ -57,16 +57,12 @@ sub fix_pidfile { sub fix_port { my ($self, $config, $group_name, $group)= @_; - my $hostname= $group->value('#host'); - return $self->{HOSTS}->{$hostname}++; + return $self->{PORT}++; } sub fix_host { my ($self)= @_; - # Get next host from HOSTS array - my @hosts= keys(%{$self->{HOSTS}});; - my $host_no= $self->{NEXT_HOST}++ % @hosts; - return $hosts[$host_no]; + 'localhost' } sub is_unique { @@ -229,7 +225,7 @@ if (IS_WINDOWS) sub fix_ndb_mgmd_port { my ($self, $config, $group_name, $group)= @_; my $hostname= $group->value('HostName'); - return $self->{HOSTS}->{$hostname}++; + return $self->{PORT}++; } @@ -428,20 +424,24 @@ sub post_check_embedded_group { sub resolve_at_variable { my ($self, $config, $group, $option)= @_; + local $_ = $option->value(); + my ($res, $after); - # Split the options value on last . - my @parts= split(/\./, $option->value()); - my $option_name= pop(@parts); - my $group_name= join('.', @parts); - - $group_name =~ s/^\@//; # Remove at - - my $from_group= $config->group($group_name) - or croak "There is no group named '$group_name' that ", - "can be used to resolve '$option_name'"; + while (m/(.*?)\@((?:\w+\.)+)(#?[-\w]+)/g) { + my ($before, $group_name, $option_name)= ($1, $2, $3); + $after = $'; + chop($group_name); - my $from= $from_group->value($option_name); - $config->insert($group->name(), $option->name(), $from) + my $from_group= $config->group($group_name) + or croak "There is no group named '$group_name' that ", + "can be used to resolve '$option_name'"; + + my $value= $from_group->value($option_name); + $res .= $before.$value; + } + $res .= $after; + + $config->insert($group->name(), $option->name(), $res) } @@ -453,7 +453,7 @@ sub post_fix_resolve_at_variables { next unless defined $option->value(); $self->resolve_at_variable($config, $group, $option) - if ($option->value() =~ /^\@/); + if ($option->value() =~ /\@/); } } } @@ -595,28 +595,18 @@ sub new_config { croak "you must pass '$required'" unless defined $args->{$required}; } - # Fill in hosts/port hash - my $hosts= {}; - my $baseport= $args->{baseport}; - $args->{hosts}= [ 'localhost' ] unless exists($args->{hosts}); - foreach my $host ( @{$args->{hosts}} ) { - $hosts->{$host}= $baseport; - } - # Open the config template my $config= My::Config->new($args->{'template_path'}); - my $extra_template_path= $args->{'extra_template_path'}; - if ($extra_template_path){ - $config->append(My::Config->new($extra_template_path)); - } my $self= bless { CONFIG => $config, ARGS => $args, - HOSTS => $hosts, - NEXT_HOST => 0, + PORT => $args->{baseport}, SERVER_ID => 1, }, $class; + # add auto-options + $config->insert('OPT', 'port' => sub { fix_port($self, $config) }); + $config->insert('OPT', 'vardir' => sub { shift->{ARGS}->{vardir} }); { # Run pre rules === modified file 'mysql-test/lib/My/Handles.pm' (properties changed: +x to -x) === modified file 'mysql-test/lib/My/SafeProcess.pm' --- a/mysql-test/lib/My/SafeProcess.pm 2010-04-28 12:52:24 +0000 +++ b/mysql-test/lib/My/SafeProcess.pm 2010-08-17 07:14:46 +0000 @@ -120,7 +120,7 @@ sub new { my $input = delete($opts{'input'}); my $output = delete($opts{'output'}); my $error = delete($opts{'error'}); - my $verbose = delete($opts{'verbose'}); + my $verbose = delete($opts{'verbose'}) || $::opt_verbose; my $nocore = delete($opts{'nocore'}); my $host = delete($opts{'host'}); my $shutdown = delete($opts{'shutdown'}); === added file 'mysql-test/lib/My/Suite.pm' --- a/mysql-test/lib/My/Suite.pm 1970-01-01 00:00:00 +0000 +++ b/mysql-test/lib/My/Suite.pm 2010-08-17 07:14:46 +0000 @@ -0,0 +1,10 @@ +# A default suite class that is used for all suites without their owns suite.pm +# see README.suites for a description + +package My::Suite; + +sub config_files { () } +sub servers { () } + +bless { }; + === modified file 'mysql-test/lib/My/Test.pm' --- a/mysql-test/lib/My/Test.pm 2009-03-20 14:18:22 +0000 +++ b/mysql-test/lib/My/Test.pm 2010-08-17 07:14:46 +0000 @@ -20,6 +20,12 @@ sub new { return $self; } +sub fullname { + my ($self)= @_; + $self->{name} . (defined $self->{combination} + ? " '$self->{combination}'" + : "") +} # # Return a unique key that can be used to === modified file 'mysql-test/lib/mtr_cases.pm' --- a/mysql-test/lib/mtr_cases.pm 2010-08-05 19:56:11 +0000 +++ b/mysql-test/lib/mtr_cases.pm 2010-08-24 22:44:50 +0000 @@ -39,7 +39,6 @@ our $enable_disabled; our $default_storage_engine; our $opt_with_ndbcluster_only; our $defaults_file; -our $defaults_extra_file; our $quick_collect; sub collect_option { @@ -68,21 +67,10 @@ require "mtr_misc.pl"; my $do_test_reg; my $skip_test_reg; -# Related to adding InnoDB plugin combinations -my $lib_innodb_plugin; - # If "Quick collect", set to 1 once a test to run has been found. my $some_test_found; -sub find_innodb_plugin { - $lib_innodb_plugin= - my_find_file($::basedir, - ["storage/innodb_plugin", "storage/innodb_plugin/.libs", - "lib/mysql/plugin", "lib/plugin"], - ["ha_innodb_plugin.dll", "ha_innodb_plugin.so", - "ha_innodb_plugin.sl"], - NOT_REQUIRED); -} +my $default_suite_object = do 'My/Suite.pm'; sub init_pattern { my ($from, $what)= @_; @@ -116,8 +104,6 @@ sub collect_test_cases ($$$) { $do_test_reg= init_pattern($do_test, "--do-test"); $skip_test_reg= init_pattern($skip_test, "--skip-test"); - &find_innodb_plugin; - # If not reordering, we also shouldn't group by suites, unless # no test cases were named. # This also effects some logic in the loop following this. @@ -188,17 +174,17 @@ sub collect_test_cases ($$$) { my $opts= $tinfo->{'master_opt'} ? $tinfo->{'master_opt'} : []; push(@criteria, join("!", sort @{$opts}) . "~"); - $sort_criteria{$tinfo->{name}} = join(" ", @criteria); + $sort_criteria{$tinfo->fullname()} = join(" ", @criteria); } @$cases = sort { - $sort_criteria{$a->{'name'}} . $a->{'name'} cmp - $sort_criteria{$b->{'name'}} . $b->{'name'}; } @$cases; + $sort_criteria{$a->fullname()} . $a->fullname() cmp + $sort_criteria{$b->fullname()} . $b->fullname() } @$cases; # For debugging the sort-order # foreach my $tinfo (@$cases) # { - # print("$sort_criteria{$tinfo->{'name'}} -> \t$tinfo->{'name'}\n"); + # print $sort_criteria{$tinfo->fullname()}," -> \t",$tinfo->fullname(),"\n"; # } } @@ -310,6 +296,17 @@ sub collect_one_suite mtr_verbose("testdir: $testdir"); mtr_verbose("resdir: $resdir"); + # + # Load the Suite object + # + unless ($::suites{$suite}) { + if (-f "$suitedir/suite.pm") { + $::suites{$suite} = do "$suitedir/suite.pm"; + } else { + $::suites{$suite} = $default_suite_object; + } + } + # ---------------------------------------------------------------------- # Build a hash of disabled testcases for this suite # ---------------------------------------------------------------------- @@ -438,14 +435,16 @@ sub collect_one_suite { # Read combinations file in my.cnf format mtr_verbose("Read combinations file"); + my %env_filter = map { $_ => 1 } split /:/, $ENV{"\U${suite}_COMBINATIONS"}; my $config= My::Config->new($combination_file); foreach my $group ($config->groups()) { my $comb= {}; $comb->{name}= $group->name(); + next if %env_filter and not $env_filter{$comb->{name}}; foreach my $option ( $group->options() ) { push(@{$comb->{comb_opt}}, $option->option()); } - push(@combinations, $comb); + push(@combinations, $comb) if $comb->{comb_opt}; } } @@ -539,28 +538,7 @@ sub optimize_cases { # support it # ======================================================= #print "binlog_format: $binlog_format\n"; - if (defined $binlog_format ) - { - # ======================================================= - # Fixed --binlog-format=x specified on command line - # ======================================================= - if ( defined $tinfo->{'binlog_formats'} ) - { - #print "binlog_formats: ". join(", ", @{$tinfo->{binlog_formats}})."\n"; - - # The test supports different binlog formats - # check if the selected one is ok - my $supported= - grep { $_ eq $binlog_format } @{$tinfo->{'binlog_formats'}}; - if ( !$supported ) - { - $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= - "Doesn't support --binlog-format='$binlog_format'"; - } - } - } - else + if (not defined $binlog_format ) { # ======================================================= # Use dynamic switching of binlog format @@ -623,10 +601,6 @@ sub optimize_cases { $tinfo->{'ndb_test'}= 1 if ( $default_engine =~ /^ndb/i ); - $tinfo->{'innodb_test'}= 1 - if ( $default_engine =~ /^innodb/i ); - $tinfo->{'pbxt_test'}= 1 - if ( $default_engine =~ /^pbxt/i ); } } @@ -758,7 +732,7 @@ sub collect_one_test_case { name => "$suitename.$tname", shortname => $tname, path => "$testdir/$filename", - + suite => $suitename, ); my $result_file= "$resdir/$tname.result"; @@ -880,7 +854,7 @@ sub collect_one_test_case { if ( -f "$testdir/$tname.slave-mi"); - tags_from_test_file($tinfo,"$testdir/${tname}.test"); + my @source_files = tags_from_test_file($tinfo,"$testdir/${tname}.test"); # Get default storage engine from suite.opt file @@ -897,12 +871,6 @@ sub collect_one_test_case { $tinfo->{'ndb_test'}= 1 if ( $local_default_storage_engine =~ /^ndb/i ); - $tinfo->{'innodb_test'}= 1 - if ( $local_default_storage_engine =~ /^innodb/i ); - - $tinfo->{'pbxt_test'}= 1 - if ( $local_default_storage_engine =~ /^pbxt/i ); - } if ( $tinfo->{'big_test'} and ! $::opt_big_test ) @@ -949,72 +917,6 @@ sub collect_one_test_case { } } - if ($tinfo->{'federated_test'}) - { - # This is a test that needs federated, enable it - push(@{$tinfo->{'master_opt'}}, "--loose-federated"); - push(@{$tinfo->{'slave_opt'}}, "--loose-federated"); - } - - if ( $tinfo->{'innodb_test'} ) - { - # This is a test that needs innodb - if ( $::mysqld_variables{'innodb'} eq "OFF" || - ! exists $::mysqld_variables{'innodb'} ) - { - # innodb is not supported, skip it - $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "No innodb support"; - return $tinfo; - } - } - elsif ( $tinfo->{'innodb_plugin_test'} ) - { - # This is a test that needs the innodb plugin - if (&find_innodb_plugin) - { - my $sep= (IS_WINDOWS) ? ';' : ':'; - my $plugin_filename= basename($lib_innodb_plugin); - my $plugin_list= - "innodb=$plugin_filename$sep" . - "innodb_trx=$plugin_filename$sep" . - "innodb_locks=$plugin_filename$sep" . - "innodb_lock_waits=$plugin_filename$sep" . - "innodb_cmp=$plugin_filename$sep" . - "innodb_cmp_reset=$plugin_filename$sep" . - "innodb_cmpmem=$plugin_filename$sep" . - "innodb_cmpmem_reset=$plugin_filename"; - - foreach my $k ('master_opt', 'slave_opt') { - push(@{$tinfo->{$k}}, '--ignore-builtin-innodb'); - push(@{$tinfo->{$k}}, '--plugin-dir=' . dirname($lib_innodb_plugin)); - push(@{$tinfo->{$k}}, "--plugin-load=$plugin_list"); - } - } - } - else - { - push(@{$tinfo->{'master_opt'}}, "--loose-skip-innodb"); - push(@{$tinfo->{'slave_opt'}}, "--loose-skip-innodb"); - } - - if ( $tinfo->{'need_binlog'} ) - { - if (grep(/^--skip-log-bin/, @::opt_extra_mysqld_opt) ) - { - $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "Test needs binlog"; - return $tinfo; - } - } - else - { - # Test does not need binlog, add --skip-binlog to - # the options used when starting - push(@{$tinfo->{'master_opt'}}, "--loose-skip-log-bin"); - push(@{$tinfo->{'slave_opt'}}, "--loose-skip-log-bin"); - } - if ( $tinfo->{'rpl_test'} ) { if ( $skip_rpl ) @@ -1085,28 +987,6 @@ sub collect_one_test_case { $tinfo->{template_path}= $config; } - if ( $tinfo->{'pbxt_test'} ) - { - # This is a test that needs pbxt - if ( $::mysqld_variables{'pbxt'} eq "OFF" || - ! exists $::mysqld_variables{'pbxt'} ) - { - # Engine is not supported, skip it - $tinfo->{'skip'}= 1; - return $tinfo; - } - } - else - { - # Only disable engine if it's on by default (to avoid warnings about - # not existing loose options - if ( $::mysqld_variables{'pbxt'} eq "ON") - { - push(@{$tinfo->{'master_opt'}}, "--loose-skip-pbxt"); - push(@{$tinfo->{'slave_opt'}}, "--loose-skip-pbxt"); - } - } - if ( $tinfo->{'example_plugin_test'} ) { if ( !$ENV{'HA_EXAMPLE_SO'} ) @@ -1127,27 +1007,27 @@ sub collect_one_test_case { } } - - # Set extra config file to use - if (defined $defaults_extra_file) { - $tinfo->{extra_template_path}= $defaults_extra_file; + if (not ref $::suites{$tinfo->{suite}}) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= $::suites{$tinfo->{suite}}; + return $tinfo; } # ---------------------------------------------------------------------- - # Append mysqld extra options to both master and slave + # Append mysqld extra options to master and slave, as appropriate # ---------------------------------------------------------------------- + for (@source_files) { + s/\.\w+$//; + process_opts_file($tinfo, "$_.opt", 'master_opt'); + process_opts_file($tinfo, "$_.opt", 'slave_opt'); + process_opts_file($tinfo, "$_-master.opt", 'master_opt'); + process_opts_file($tinfo, "$_-slave.opt", 'slave_opt'); + } + push(@{$tinfo->{'master_opt'}}, @::opt_extra_mysqld_opt); push(@{$tinfo->{'slave_opt'}}, @::opt_extra_mysqld_opt); - # ---------------------------------------------------------------------- - # Add master opts, extra options only for master - # ---------------------------------------------------------------------- - process_opts_file($tinfo, "$testdir/$tname-master.opt", 'master_opt'); - - # ---------------------------------------------------------------------- - # Add slave opts, list of extra option only for slave - # ---------------------------------------------------------------------- - process_opts_file($tinfo, "$testdir/$tname-slave.opt", 'slave_opt'); return $tinfo; } @@ -1157,24 +1037,6 @@ sub collect_one_test_case { # the specified value in "tinfo" my @tags= ( - ["include/have_binlog_format_row.inc", "binlog_formats", ["row"]], - ["include/have_binlog_format_statement.inc", "binlog_formats", ["statement"]], - ["include/have_binlog_format_mixed.inc", "binlog_formats", ["mixed"]], - ["include/have_binlog_format_mixed_or_row.inc", - "binlog_formats", ["mixed", "row"]], - ["include/have_binlog_format_mixed_or_statement.inc", - "binlog_formats", ["mixed", "statement"]], - ["include/have_binlog_format_row_or_statement.inc", - "binlog_formats", ["row", "statement"]], - - ["include/have_log_bin.inc", "need_binlog", 1], - - ["include/have_innodb.inc", "innodb_test", 1], - ["include/have_innodb_plugin.inc", "innodb_plugin_test", 1], - ["include/have_real.inc", "innodb_test", 1], - ["include/have_real_innodb_plugin.inc", "innodb_plugin_test", 1], - ["include/have_xtradb.inc", "innodb_test", 1], - ["include/have_pbxt.inc", "pbxt_test", 1], ["include/big_test.inc", "big_test", 1], ["include/have_debug.inc", "need_debug", 1], ["include/have_ndb.inc", "ndb_test", 1], @@ -1182,7 +1044,6 @@ my @tags= ["include/master-slave.inc", "rpl_test", 1], ["include/ndb_master-slave.inc", "rpl_test", 1], ["include/ndb_master-slave.inc", "ndb_test", 1], - ["federated.inc", "federated_test", 1], ["include/not_embedded.inc", "not_embedded", 1], ["include/not_valgrind.inc", "not_valgrind", 1], ["include/have_example_plugin.inc", "example_plugin_test", 1], @@ -1196,6 +1057,7 @@ sub tags_from_test_file { my $file= shift; #mtr_verbose("$file"); my $F= IO::File->new($file) or mtr_error("can't open file \"$file\": $!"); + my @all_files=($file); while ( my $line= <$F> ) { @@ -1231,13 +1093,13 @@ sub tags_from_test_file { # Only source the file if it exists, we may get # false positives in the regexes above if someone # writes "source nnnn;" in a test case(such as mysqltest.test) - tags_from_test_file($tinfo, $sourced_file); + unshift @all_files, tags_from_test_file($tinfo, $sourced_file); last; } } } - } + @all_files; } sub unspace { @@ -1250,6 +1112,7 @@ sub unspace { sub opts_from_file ($) { my $file= shift; + local $_; open(FILE,"<",$file) or mtr_error("can't open file \"$file\": $!"); my @args; === modified file 'mysql-test/lib/mtr_report.pm' --- a/mysql-test/lib/mtr_report.pm 2010-04-28 12:52:24 +0000 +++ b/mysql-test/lib/mtr_report.pm 2010-08-17 07:14:46 +0000 @@ -61,14 +61,10 @@ sub _name { sub _mtr_report_test_name ($) { my $tinfo= shift; - my $tname= $tinfo->{name}; + my $tname= $tinfo->fullname(); return unless defined $verbose; - # Add combination name if any - $tname.= " '$tinfo->{combination}'" - if defined $tinfo->{combination}; - print _name(). _timestamp(); printf "%-40s ", $tname; my $worker = $tinfo->{worker}; === modified file 'mysql-test/mysql-test-run.pl' --- a/mysql-test/mysql-test-run.pl 2010-08-09 17:49:42 +0000 +++ b/mysql-test/mysql-test-run.pl 2010-08-24 22:44:50 +0000 @@ -130,7 +130,7 @@ my $path_config_file; # The ge # executables will be used by the test suite. our $opt_vs_config = $ENV{'MTR_VS_CONFIG'}; -my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,parts,innodb,innodb_plugin,percona,vcol,oqgraph"; +my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,parts,innodb,innodb_plugin,percona,vcol,oqgraph,ndb"; my $opt_suites; our $opt_verbose= 0; # Verbose output, enable with --verbose @@ -257,6 +257,8 @@ our $debug_compiled_binaries; our %mysqld_variables; +our %suites; + my $source_dist= 0; my $opt_max_save_core= env_or_val(MTR_MAX_SAVE_CORE => 5); @@ -711,6 +713,8 @@ sub run_test_server ($$$) { $next= splice(@$tests, $second_best, 1); } + xterm_stat(scalar(@$tests)); + if ($next) { #$next->print_test(); $next->write_test($sock, 'TESTCASE'); @@ -807,7 +811,7 @@ sub run_worker ($) { # We need to gracefully shut down the servers to see any # Valgrind memory leak errors etc. since last server restart. if ($opt_warnings) { - stop_servers(all_servers()); + stop_servers(reverse all_servers()); if(check_warnings_post_shutdown($server)) { # Warnings appeared in log file(s) during final server shutdown. exit(1); @@ -1592,7 +1596,7 @@ sub collect_mysqld_features { my $cmd= join(" ", $exe_mysqld, @$args); my $list= `$cmd`; - print "cmd: $cmd\n"; + mtr_verbose("cmd: $cmd"); foreach my $line (split('\n', $list)) { @@ -2490,7 +2494,7 @@ sub check_ndbcluster_support ($) { } -sub ndbcluster_wait_started($$){ +sub ndbcluster_wait_started { my $cluster= shift; my $ndb_waiter_extra_opt= shift; my $path_waitlog= join('/', $opt_vardir, $cluster->name(), "ndb_waiter.log"); @@ -2658,7 +2662,7 @@ sub ndbd_start { sub ndbcluster_start ($) { - my $cluster= shift; + my ($cluster) = @_; mtr_verbose("ndbcluster_start '".$cluster->name()."'"); @@ -2678,6 +2682,109 @@ sub ndbcluster_start ($) { } +sub mysql_server_start($) { + my ($mysqld, $tinfo) = @_; + + if ( $mysqld->{proc} ) + { + # Already started + + # Write start of testcase to log file + mark_log($mysqld->value('#log-error'), $tinfo); + + return; + } + + my $datadir= $mysqld->value('datadir'); + if (not $opt_start_dirty) + { + + my @options= ('log-bin', 'relay-log'); + foreach my $option_name ( @options ) { + next unless $mysqld->option($option_name); + + my $file_name= $mysqld->value($option_name); + next unless + defined $file_name and + -e $file_name; + + mtr_debug(" -removing '$file_name'"); + unlink($file_name) or die ("unable to remove file '$file_name'"); + } + + if (-d $datadir ) { + preserve_error_log($mysqld); + mtr_verbose(" - removing '$datadir'"); + rmtree($datadir); + } + } + + my $mysqld_basedir= $mysqld->value('basedir'); + if ( $basedir eq $mysqld_basedir ) + { + if (! $opt_start_dirty) # If dirty, keep possibly grown system db + { + # Copy datadir from installed system db + for my $path ( "$opt_vardir", "$opt_vardir/..") { + my $install_db= "$path/install.db"; + copytree($install_db, $datadir) + if -d $install_db; + } + mtr_error("Failed to copy system db to '$datadir'") + unless -d $datadir; + } + } + else + { + mysql_install_db($mysqld); # For versional testing + + mtr_error("Failed to install system db to '$datadir'") + unless -d $datadir; + + } + restore_error_log($mysqld); + + # Create the servers tmpdir + my $tmpdir= $mysqld->value('tmpdir'); + mkpath($tmpdir) unless -d $tmpdir; + + # Write start of testcase to log file + mark_log($mysqld->value('#log-error'), $tinfo); + + # Run <tname>-master.sh + if ($mysqld->option('#!run-master-sh') and + run_sh_script($tinfo->{master_sh}) ) + { + $tinfo->{'comment'}= "Failed to execute '$tinfo->{master_sh}'"; + return 1; + } + + # Run <tname>-slave.sh + if ($mysqld->option('#!run-slave-sh') and + run_sh_script($tinfo->{slave_sh})) + { + $tinfo->{'comment'}= "Failed to execute '$tinfo->{slave_sh}'"; + return 1; + } + + if (!$opt_embedded_server) + { + my $extra_opts= get_extra_opts($mysqld, $tinfo); + mysqld_start($mysqld,$extra_opts); + + # Save this test case information, so next can examine it + $mysqld->{'started_tinfo'}= $tinfo; + } +} + +sub mysql_server_wait { + my ($mysqld) = @_; + + return not sleep_until_file_created($mysqld->value('pid-file'), + $opt_start_timeout, + $mysqld->{'proc'}); +} + sub create_config_file_for_extern { my %opts= ( @@ -3452,9 +3559,82 @@ sub restart_forced_by_test # Return timezone value of tinfo or default value sub timezone { my ($tinfo)= @_; - return $tinfo->{timezone} || "DEFAULT"; + local $_ = $tinfo->{timezone}; + return 'DEFAULT' unless defined $_; + s/\$\{(\w+)\}/envsubst($1)/ge; + s/\$(\w+)/envsubst($1)/ge; + $_; +} + +sub mycnf_create { + my ($config) = @_; + my $res; + + foreach my $group ($config->groups()) { + $res .= "[$group->{name}]\n"; + + foreach my $option ($group->options()) { + $res .= $option->name(); + my $value= $option->value(); + if (defined $value) { + $res .= "=$value"; + } + $res .= "\n"; + } + $res .= "\n"; + } + $res; +} + +sub config_files($) { + my ($tinfo) = @_; + ( + 'my.cnf' => \&mycnf_create, + $suites{$tinfo->{suite}}->config_files() + ); +} + +sub _like { return $config ? $config->like($_[0]) : (); } +sub mysqlds { return _like('mysqld\.'); } +sub ndbds { return _like('cluster_config\.ndbd\.');} +sub ndb_mgmds { return _like('cluster_config\.ndb_mgmd\.'); } + +sub fix_servers($) { + my ($tinfo) = @_; + return () unless $config; + my %servers = ( + qr/mysqld\./ => { + SORT => 300, + START => \&mysql_server_start, + WAIT => \&mysql_server_wait, + }, + qr/mysql_cluster\./ => { + SORT => 200, + START => \&ndbcluster_start, + WAIT => \&ndbcluster_wait_started, + }, + qr/cluster_config\.ndb_mgmd\./ => { + SORT => 210, + START => undef, + }, + qr/cluster_config\.ndbd\./ => { + SORT => 220, + START => undef, + }, + $suites{$tinfo->{suite}}->servers() + ); + for ($config->groups()) { + while (my ($re,$prop) = each %servers) { + @$_{keys %$prop} = values %$prop if $_->{name} =~ /^$re/; + } + } } +sub all_servers { + return unless $config; + ( sort { $a->{SORT} <=> $b->{SORT} } + grep { defined $_->{SORT} } $config->groups() ); +} # Storage for changed environment variables my %old_env; @@ -3497,7 +3677,7 @@ sub run_testcase ($$) { if ( @restart != 0) { # Remember that we restarted for this test case (count restarts) $tinfo->{'restarted'}= 1; - stop_servers(@restart ); + stop_servers(reverse @restart); if ($opt_warnings) { check_warnings_post_shutdown($server_socket); } @@ -3533,7 +3713,6 @@ sub run_testcase ($$) { vardir => $opt_vardir, tmpdir => $opt_tmpdir, baseport => $baseport, - #hosts => [ 'host1', 'host2' ], user => $opt_user, password => '', ssl => $opt_ssl_supported, @@ -3541,8 +3720,16 @@ sub run_testcase ($$) { } ); - # Write the new my.cnf - $config->save($path_config_file); + fix_servers($tinfo); + + # Write config files: + my %config_files = config_files($tinfo); + while (my ($file, $generate) = each %config_files) { + my ($path) = "$opt_vardir/$file"; + open (F, '>', $path) or die "Could not open '$path': $!"; + print F &$generate($config); + close F; + } # Remember current config so a restart can occur when a test need # to use a different one @@ -3685,7 +3872,7 @@ sub run_testcase ($$) { if ($opt_warnings) { # Checking error logs for warnings, so need to stop server # gracefully so that memory leaks etc. can be properly detected. - stop_servers(all_servers()); + stop_servers(reverse all_servers()); check_warnings_post_shutdown($server_socket); # Even if we got warnings here, we should not fail this # particular test, as the warnings may be caused by an earlier @@ -3843,7 +4030,8 @@ sub run_testcase ($$) { # valuable debugging information even if there is no test failure recorded. sub _preserve_error_log_names { my ($mysqld)= @_; - my $error_log_file= $mysqld->value('#log-error'); + my $error_log_file= $mysqld->if_exist('#log-error'); + return unless $error_log_file and -r $error_log_file; my $error_log_dir= dirname($error_log_file); my $save_name= $error_log_dir ."/../". $mysqld->name() .".error.log"; return ($error_log_file, $save_name); @@ -3852,14 +4040,14 @@ sub _preserve_error_log_names { sub preserve_error_log { my ($mysqld)= @_; my ($error_log_file, $save_name)= _preserve_error_log_names($mysqld); - my $res= rename($error_log_file, $save_name); + rename($error_log_file, $save_name) if $save_name; # Ignore any errors, as it's just a best-effort to keep the log if possible. } sub restore_error_log { my ($mysqld)= @_; my ($error_log_file, $save_name)= _preserve_error_log_names($mysqld); - my $res= rename($save_name, $error_log_file); + rename($save_name, $error_log_file) if $save_name; } # Keep track of last position in mysqld error log where we scanned for @@ -3903,6 +4091,8 @@ sub pre_write_errorlog { sub extract_server_log ($$) { my ($error_log, $tname) = @_; + + return unless $error_log; # Open the servers .err log file and read all lines # belonging to current test into @lines @@ -3945,9 +4135,9 @@ sub get_log_from_proc ($$) { my ($proc, $name)= @_; my $srv_log= ""; - foreach my $mysqld (mysqlds()) { + foreach my $mysqld (all_servers()) { if ($mysqld->{proc} eq $proc) { - my @srv_lines= extract_server_log($mysqld->value('#log-error'), $name); + my @srv_lines= extract_server_log($mysqld->if_exist('#log-error'), $name); $srv_log= "\nServer log from this test:\n" . join ("", @srv_lines); last; } @@ -4026,15 +4216,18 @@ sub extract_warning_lines ($) { my @antipatterns = ( qr/error .*connecting to master/, + qr/Plugin 'ndbcluster' will be forced to shutdown/, qr/InnoDB: Error: in ALTER TABLE `test`.`t[12]`/, qr/InnoDB: Error: table `test`.`t[12]` does not exist in the InnoDB internal/, qr/Slave: Unknown table 't1' Error_code: 1051/, qr/Slave SQL:.*(Error_code: [[:digit:]]+|Query:.*)/, qr/slave SQL thread aborted/, - qr/unknown option '--loose-/, - qr/unknown variable 'loose-/, + qr/unknown option '--loose[-_]/, + qr/unknown variable 'loose[-_]/, qr/Now setting lower_case_table_names to [02]/, qr/Setting lower_case_table_names=2/, + qr/You have forced lower_case_table_names to 0/, + qr/Plugin 'ndbcluster' will be forced to shutdow/, qr/deprecated/, qr/Slave SQL thread retried transaction/, qr/Slave \(additional info\)/, @@ -4343,29 +4536,18 @@ sub clean_dir { sub clean_datadir { - mtr_verbose("Cleaning datadirs..."); if (started(all_servers()) != 0){ mtr_error("Trying to clean datadir before all servers stopped"); } - foreach my $cluster ( clusters() ) + for (all_servers()) { - my $cluster_dir= "$opt_vardir/".$cluster->{name}; - mtr_verbose(" - removing '$cluster_dir'"); - rmtree($cluster_dir); - - } - - foreach my $mysqld ( mysqlds() ) - { - my $mysqld_dir= dirname($mysqld->value('datadir')); - preserve_error_log($mysqld); - if (-d $mysqld_dir ) { - mtr_verbose(" - removing '$mysqld_dir'"); - rmtree($mysqld_dir); - } + preserve_error_log($_); # or at least, try to + my $dir= "$opt_vardir/".$_->{name}; + mtr_verbose(" - removing '$dir'"); + rmtree($dir); } # Remove all files in tmp and var/tmp @@ -4388,17 +4570,6 @@ sub save_datadir_after_failure($$) { } -sub remove_ndbfs_from_ndbd_datadir { - my ($ndbd_datadir)= @_; - # Remove the ndb_*_fs directory from ndbd.X/ dir - foreach my $ndbfs_dir ( glob("$ndbd_datadir/ndb_*_fs") ) - { - next unless -d $ndbfs_dir; # Skip if not a directory - rmtree($ndbfs_dir); - } -} - - sub after_failure ($) { my ($tinfo)= @_; @@ -4415,31 +4586,18 @@ sub after_failure ($) { mkpath($save_dir) if ! -d $save_dir; - # Save the used my.cnf file - copy($path_config_file, $save_dir); + # Save the used config files + my %config_files = config_files($tinfo); + while (my ($file, $generate) = each %config_files) { + copy("$opt_vardir/$file", $save_dir); + } # Copy the tmp dir copytree("$opt_vardir/tmp/", "$save_dir/tmp/"); - if ( clusters() ) { - foreach my $cluster ( clusters() ) { - my $cluster_dir= "$opt_vardir/".$cluster->{name}; - - # Remove the fileystem of each ndbd - foreach my $ndbd ( in_cluster($cluster, ndbds()) ) - { - my $ndbd_datadir= $ndbd->value("DataDir"); - remove_ndbfs_from_ndbd_datadir($ndbd_datadir); - } - - save_datadir_after_failure($cluster_dir, $save_dir); - } - } - else { - foreach my $mysqld ( mysqlds() ) { - my $data_dir= $mysqld->value('datadir'); - save_datadir_after_failure(dirname($data_dir), $save_dir); - } + foreach (all_servers()) { + my $dir= "$opt_vardir/".$_->{name}; + save_datadir_after_failure($dir, $save_dir); } } @@ -4577,8 +4735,8 @@ sub mysqld_arguments ($$$) { mtr_add_arg($args, "%s--log-output=table,file"); } - # Check if "extra_opt" contains skip-log-bin - my $skip_binlog= grep(/^(--|--loose-)skip-log-bin/, @$extra_opts); + # Check if "extra_opt" contains --log-bin + my $skip_binlog= not grep /^--(loose-)?log-bin/, @$extra_opts; # Indicate to mysqld it will be debugged in debugger if ( $glob_debugger ) @@ -4834,8 +4992,7 @@ sub server_need_restart { return 1; } - my $is_mysqld= grep ($server eq $_, mysqlds()); - if ($is_mysqld) + if ($server->name() =~ /^mysqld\./) { # Check that running process was started with same options @@ -4887,17 +5044,9 @@ sub servers_need_restart($) { -# -# Return list of specific servers -# - there is no servers in an empty config -# -sub _like { return $config ? $config->like($_[0]) : (); } -sub mysqlds { return _like('mysqld.'); } -sub ndbds { return _like('cluster_config.ndbd.');} -sub ndb_mgmds { return _like('cluster_config.ndb_mgmd.'); } -sub clusters { return _like('mysql_cluster.'); } -sub all_servers { return ( mysqlds(), ndb_mgmds(), ndbds() ); } +############################################ +############################################ # # Filter a list of servers and return only those that are part @@ -4951,28 +5100,10 @@ sub get_extra_opts { sub stop_servers($$) { my (@servers)= @_; - if ( join('|', @servers) eq join('|', all_servers()) ) - { - # All servers are going down, use some kind of order to - # avoid too many warnings in the log files - - mtr_report("Restarting all servers"); - - # mysqld processes - My::SafeProcess::shutdown( $opt_shutdown_timeout, started(mysqlds()) ); - - # cluster processes - My::SafeProcess::shutdown( $opt_shutdown_timeout, - started(ndbds(), ndb_mgmds()) ); - } - else - { - mtr_report("Restarting ", started(@servers)); + mtr_report("Restarting ", started(@servers)); - # Stop only some servers - My::SafeProcess::shutdown( $opt_shutdown_timeout, - started(@servers) ); - } + My::SafeProcess::shutdown($opt_shutdown_timeout, + started(@servers)); foreach my $server (@servers) { @@ -4999,145 +5130,14 @@ sub stop_servers($$) { sub start_servers($) { my ($tinfo)= @_; - # Start clusters - foreach my $cluster ( clusters() ) - { - ndbcluster_start($cluster); - } - - # Start mysqlds - foreach my $mysqld ( mysqlds() ) - { - if ( $mysqld->{proc} ) - { - # Already started - - # Write start of testcase to log file - mark_log($mysqld->value('#log-error'), $tinfo); - - next; - } - - my $datadir= $mysqld->value('datadir'); - if ($opt_start_dirty) - { - # Don't delete anything if starting dirty - ; - } - else - { - - my @options= ('log-bin', 'relay-log'); - foreach my $option_name ( @options ) { - next unless $mysqld->option($option_name); - - my $file_name= $mysqld->value($option_name); - next unless - defined $file_name and - -e $file_name; - - mtr_debug(" -removing '$file_name'"); - unlink($file_name) or die ("unable to remove file '$file_name'"); - } - - if (-d $datadir ) { - preserve_error_log($mysqld); - mtr_verbose(" - removing '$datadir'"); - rmtree($datadir); - } - } - - my $mysqld_basedir= $mysqld->value('basedir'); - if ( $basedir eq $mysqld_basedir ) - { - if (! $opt_start_dirty) # If dirty, keep possibly grown system db - { - # Copy datadir from installed system db - for my $path ( "$opt_vardir", "$opt_vardir/..") { - my $install_db= "$path/install.db"; - copytree($install_db, $datadir) - if -d $install_db; - } - mtr_error("Failed to copy system db to '$datadir'") - unless -d $datadir; - } - } - else - { - mysql_install_db($mysqld); # For versional testing - - mtr_error("Failed to install system db to '$datadir'") - unless -d $datadir; - - } - restore_error_log($mysqld); - - # Create the servers tmpdir - my $tmpdir= $mysqld->value('tmpdir'); - mkpath($tmpdir) unless -d $tmpdir; - - # Write start of testcase to log file - mark_log($mysqld->value('#log-error'), $tinfo); - - # Run <tname>-master.sh - if ($mysqld->option('#!run-master-sh') and - run_sh_script($tinfo->{master_sh}) ) - { - $tinfo->{'comment'}= "Failed to execute '$tinfo->{master_sh}'"; - return 1; - } - - # Run <tname>-slave.sh - if ($mysqld->option('#!run-slave-sh') and - run_sh_script($tinfo->{slave_sh})) - { - $tinfo->{'comment'}= "Failed to execute '$tinfo->{slave_sh}'"; - return 1; - } - - if (!$opt_embedded_server) - { - my $extra_opts= get_extra_opts($mysqld, $tinfo); - mysqld_start($mysqld,$extra_opts); - - # Save this test case information, so next can examine it - $mysqld->{'started_tinfo'}= $tinfo; - } - - } - - # Wait for clusters to start - foreach my $cluster ( clusters() ) - { - if (ndbcluster_wait_started($cluster, "")) - { - # failed to start - $tinfo->{'comment'}= "Start of '".$cluster->name()."' cluster failed"; - return 1; - } + for (all_servers()) { + $_->{START}->($_, $tinfo) if $_->{START}; } - # Wait for mysqlds to start - foreach my $mysqld ( mysqlds() ) - { - next if !started($mysqld); - - if (sleep_until_file_created($mysqld->value('pid-file'), - $opt_start_timeout, - $mysqld->{'proc'}) == 0) { - $tinfo->{comment}= - "Failed to start ".$mysqld->name(); - - my $logfile= $mysqld->value('#log-error'); - if ( defined $logfile and -f $logfile ) - { - my @srv_lines= extract_server_log($logfile, $tinfo->{name}); - $tinfo->{logfile}= "Server log is:\n" . join ("", @srv_lines); - } - else - { - $tinfo->{logfile}= "Could not open server logfile: '$logfile'"; - } + for (all_servers()) { + next unless $_->{WAIT} and started($_); + if ($_->{WAIT}->($_)) { + $tinfo->{comment}= "Failed to start ".$_->name(); return 1; } } @@ -5835,3 +5835,25 @@ sub list_options ($) { exit(1); } + +sub time_format($) { + sprintf '%d:%02d:%02d', $_[0]/3600, ($_[0]/60)%60, $_[0]%60; +} + +my $num_tests; + +sub xterm_stat { + if (-t STDOUT and $ENV{TERM} =~ /xterm/) { + my ($left) = @_; + + # 2.5 -> best by test + $num_tests = $left + 2.5 unless $num_tests; + + my $done = $num_tests - $left; + my $spent = time - $^T; + + printf "\e];mtr: spent %s on %d tests. %s (%d tests) left\a", + time_format($spent), $done, + time_format($spent/$done * $left), $left; + } +} === removed file 'mysql-test/r/exampledb.result' --- a/mysql-test/r/exampledb.result 2006-05-05 17:08:40 +0000 +++ b/mysql-test/r/exampledb.result 1970-01-01 00:00:00 +0000 @@ -1,8 +0,0 @@ -drop database if exists events_test; -drop database if exists events_test2; -drop table if exists t1; -CREATE TABLE t1 ( -Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, -Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL -) ENGINE=example; -drop table t1; === modified file 'mysql-test/r/group_by.result' --- a/mysql-test/r/group_by.result 2010-05-12 16:10:33 +0000 +++ b/mysql-test/r/group_by.result 2010-08-23 09:46:25 +0000 @@ -1809,5 +1809,22 @@ SELECT MAX(t2.a) FROM t2 LEFT JOIN t1 ON MAX(t2.a) 2 DROP TABLE t1, t2; +CREATE TABLE t1 (a int(11) NOT NULL); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 ( +key_col int(11) NOT NULL, +KEY (key_col) +); +INSERT INTO t2 VALUES (1),(2); +select min(t2.key_col) from t1,t2 where t1.a=1; +min(t2.key_col) +1 +select min(t2.key_col) from t1,t2 where t1.a > 1000; +min(t2.key_col) +NULL +select min(t2.key_col)+1 from t1,t2 where t1.a> 1000; +min(t2.key_col)+1 +NULL +drop table t1,t2; # # End of 5.1 tests === modified file 'mysql-test/r/subselect4.result' --- a/mysql-test/r/subselect4.result 2009-09-28 13:48:40 +0000 +++ b/mysql-test/r/subselect4.result 2010-08-23 09:46:25 +0000 @@ -59,3 +59,26 @@ FROM t3 WHERE 1 = 0 GROUP BY 1; (SELECT 1 FROM t1,t2 WHERE t2.b > t3.b) DROP TABLE t1,t2,t3; End of 5.0 tests. +CREATE TABLE t1 (col_int_nokey int(11) NOT NULL, col_varchar_nokey varchar(1) NOT NULL) engine=myisam; +INSERT INTO t1 VALUES (2,'s'),(0,'v'),(2,'s'); +CREATE TABLE t2 ( +pk int(11) NOT NULL AUTO_INCREMENT, +`col_int_key` int(11) NOT NULL, +col_varchar_key varchar(1) NOT NULL, +PRIMARY KEY (pk), +KEY `col_int_key` (`col_int_key`), +KEY `col_varchar_key` (`col_varchar_key`) +) ENGINE=MyISAM; +INSERT INTO t2 VALUES (4,10,'g'), (5,20,'v'); +SELECT t1.col_int_nokey,(SELECT MIN( t2_a.col_int_key ) FROM t2 t2_a, t2 t2_b, t1 t1_a WHERE t1_a.col_varchar_nokey = t2_b.col_varchar_key and t1.col_int_nokey ) as sub FROM t1; +col_int_nokey sub +2 10 +0 NULL +2 10 +SELECT t1.col_int_nokey,(SELECT MIN( t2_a.col_int_key ) +1 FROM t2 t2_a, t2 t2_b, t1 t1_a WHERE t1_a.col_varchar_nokey = t2_b.col_varchar_key and t1.col_int_nokey ) as sub FROM t1; +col_int_nokey sub +2 11 +0 NULL +2 11 +DROP TABLE t1,t2; +End of 5.1 tests. === modified file 'mysql-test/r/warnings_engine_disabled.result' --- a/mysql-test/r/warnings_engine_disabled.result 2008-12-17 15:45:34 +0000 +++ b/mysql-test/r/warnings_engine_disabled.result 2010-08-17 07:14:46 +0000 @@ -1,15 +1,14 @@ -create table t1 (id int) engine=NDB; +create table t1 (id int) engine=InnoDB; Warnings: -Warning 1286 Unknown table engine 'NDB' +Warning 1286 Unknown table engine 'InnoDB' Warning 1266 Using storage engine MyISAM for table 't1' -alter table t1 engine=NDB; +alter table t1 engine=InnoDB; Warnings: -Warning 1286 Unknown table engine 'NDB' +Warning 1286 Unknown table engine 'InnoDB' drop table t1; -SELECT ENGINE, SUPPORT FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE='ndbcluster'; +SELECT ENGINE, SUPPORT FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE='InnoDB'; ENGINE SUPPORT -ndbcluster NO -SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE -PLUGIN_NAME='ndbcluster'; +InnoDB NO +SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='InnoDB'; PLUGIN_NAME PLUGIN_STATUS -ndbcluster DISABLED +InnoDB DISABLED === modified file 'mysql-test/suite/binlog/t/binlog_base64_flag.test' --- a/mysql-test/suite/binlog/t/binlog_base64_flag.test 2010-06-18 17:32:23 +0000 +++ b/mysql-test/suite/binlog/t/binlog_base64_flag.test 2010-08-17 07:14:46 +0000 @@ -7,6 +7,7 @@ # BINLOG statement does not work in embedded mode. +source include/have_log_bin.inc; source include/not_embedded.inc; disable_warnings; === modified file 'mysql-test/suite/binlog/t/binlog_old_versions.test' --- a/mysql-test/suite/binlog/t/binlog_old_versions.test 2008-02-07 11:38:13 +0000 +++ b/mysql-test/suite/binlog/t/binlog_old_versions.test 2010-08-17 07:14:46 +0000 @@ -22,6 +22,7 @@ # Related bugs: BUG#27779, BUG#31581, BUG#31582, BUG#31583, BUG#32407 +source include/have_log_bin.inc; source include/not_embedded.inc; --disable_warnings === modified file 'mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam-master.opt' --- a/mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam-master.opt 2007-06-27 12:28:02 +0000 +++ b/mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=2 +--loose-innodb_lock_wait_timeout=2 === modified file 'mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam-master.opt' --- a/mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam-master.opt 2007-06-27 12:28:02 +0000 +++ b/mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=2 +--loose-innodb_lock_wait_timeout=2 === added file 'mysql-test/suite/federated/federated_bug_32426.result' --- a/mysql-test/suite/federated/federated_bug_32426.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/federated/federated_bug_32426.result 2010-08-18 07:52:57 +0000 @@ -0,0 +1,30 @@ +CREATE DATABASE federated; +CREATE DATABASE federated; +# +# Bug #32426: FEDERATED query returns corrupt results for ORDER BY +# on a TEXT column +# +CREATE TABLE federated.t1(a TEXT); +INSERT INTO federated.t1 VALUES('abc'), ('gh'), ('f'), ('ijk'), ('de'); +CREATE TABLE federated.t1(a TEXT) ENGINE=FEDERATED +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +SELECT * FROM federated.t1 ORDER BY A; +a +abc +de +f +gh +ijk +SELECT * FROM federated.t1 ORDER BY A DESC; +a +ijk +gh +f +de +abc +DROP TABLE federated.t1; +DROP TABLE federated.t1; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; === added file 'mysql-test/suite/federated/federated_bug_32426.test' --- a/mysql-test/suite/federated/federated_bug_32426.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/federated/federated_bug_32426.test 2010-08-18 07:52:57 +0000 @@ -0,0 +1,24 @@ +source federated.inc; + +--echo # +--echo # Bug #32426: FEDERATED query returns corrupt results for ORDER BY +--echo # on a TEXT column +--echo # +connection slave; +CREATE TABLE federated.t1(a TEXT); +INSERT INTO federated.t1 VALUES('abc'), ('gh'), ('f'), ('ijk'), ('de'); + +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE federated.t1(a TEXT) ENGINE=FEDERATED + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; +SELECT * FROM federated.t1 ORDER BY A; +SELECT * FROM federated.t1 ORDER BY A DESC; +DROP TABLE federated.t1; + +connection slave; +DROP TABLE federated.t1; + +connection default; + +source federated_cleanup.inc; === modified file 'mysql-test/suite/federated/federated_innodb-slave.opt' --- a/mysql-test/suite/federated/federated_innodb-slave.opt 2007-12-12 17:19:24 +0000 +++ b/mysql-test/suite/federated/federated_innodb-slave.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb +--loose-innodb === modified file 'mysql-test/suite/federated/federated_server.result' --- a/mysql-test/suite/federated/federated_server.result 2010-07-16 13:43:46 +0000 +++ b/mysql-test/suite/federated/federated_server.result 2010-08-12 17:52:52 +0000 @@ -213,7 +213,7 @@ id name alter server s1 options (database 'db_bogus'); flush tables; select * from federated.t1; -ERROR 42000: Got error: 1044 : Access denied for user 'test_fed'@'localhost' to database 'db_bogus' +ERROR 42000: Received error: 1044 : Access denied for user 'test_fed'@'localhost' to database 'db_bogus' drop server if exists 's1'; ERROR 42000: Access denied; you need the SUPER privilege for this operation create server 's1' foreign data wrapper 'mysql' options === modified file 'mysql-test/suite/federated/my.cnf' --- a/mysql-test/suite/federated/my.cnf 2009-09-30 22:25:06 +0000 +++ b/mysql-test/suite/federated/my.cnf 2010-08-17 07:14:46 +0000 @@ -3,9 +3,10 @@ [mysqld.1] log-bin= master-bin +loose-federated [mysqld.2] - +loose-federated [ENV] MASTER_MYPORT= @mysqld.1.port === modified file 'mysql-test/suite/funcs_1/t/is_columns_is.test' --- a/mysql-test/suite/funcs_1/t/is_columns_is.test 2010-08-05 11:40:54 +0000 +++ b/mysql-test/suite/funcs_1/t/is_columns_is.test 2010-08-17 07:14:46 +0000 @@ -18,6 +18,7 @@ --source include/not_embedded.inc # This test depends on having the PBXT information_schema stuff. --source include/have_pbxt.inc +--source include/have_innodb.inc --source include/have_xtradb.inc let $my_where = WHERE table_schema = 'information_schema' === modified file 'mysql-test/suite/innodb/t/innodb-master.opt' --- a/mysql-test/suite/innodb/t/innodb-master.opt 2010-04-12 11:56:24 +0000 +++ b/mysql-test/suite/innodb/t/innodb-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---binlog_cache_size=32768 --innodb_lock_wait_timeout=1 +--binlog_cache_size=32768 --loose-innodb_lock_wait_timeout=1 === modified file 'mysql-test/suite/innodb/t/innodb-semi-consistent-master.opt' --- a/mysql-test/suite/innodb/t/innodb-semi-consistent-master.opt 2010-04-12 11:56:24 +0000 +++ b/mysql-test/suite/innodb/t/innodb-semi-consistent-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=2 +--loose-innodb_lock_wait_timeout=2 === modified file 'mysql-test/suite/innodb/t/innodb_autoinc_lock_mode_zero-master.opt' --- a/mysql-test/suite/innodb/t/innodb_autoinc_lock_mode_zero-master.opt 2010-06-03 09:50:32 +0000 +++ b/mysql-test/suite/innodb/t/innodb_autoinc_lock_mode_zero-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb-autoinc-lock-mode=0 +--loose-innodb-autoinc-lock-mode=0 === modified file 'mysql-test/suite/innodb/t/innodb_bug30919-master.opt' --- a/mysql-test/suite/innodb/t/innodb_bug30919-master.opt 2010-06-03 09:50:32 +0000 +++ b/mysql-test/suite/innodb/t/innodb_bug30919-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb --innodb_autoinc_lock_mode=0 +--loose-innodb --loose-innodb_autoinc_lock_mode=0 === modified file 'mysql-test/suite/innodb/t/innodb_bug39438-master.opt' --- a/mysql-test/suite/innodb/t/innodb_bug39438-master.opt 2010-04-12 11:56:24 +0000 +++ b/mysql-test/suite/innodb/t/innodb_bug39438-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb-file-per-table=1 +--loose-innodb-file-per-table=1 === modified file 'mysql-test/suite/innodb/t/innodb_bug52663-master.opt' --- a/mysql-test/suite/innodb/t/innodb_bug52663-master.opt 2010-04-26 10:27:25 +0000 +++ b/mysql-test/suite/innodb/t/innodb_bug52663-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=1 +--loose-innodb_lock_wait_timeout=1 === modified file 'mysql-test/suite/innodb/t/innodb_bug53674-master.opt' --- a/mysql-test/suite/innodb/t/innodb_bug53674-master.opt 2010-06-02 10:26:37 +0000 +++ b/mysql-test/suite/innodb/t/innodb_bug53674-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---log-bin --innodb-locks-unsafe-for-binlog --binlog-format=mixed +--loose-innodb-locks-unsafe-for-binlog --binlog-format=mixed === modified file 'mysql-test/suite/innodb/t/innodb_bug53674.test' --- a/mysql-test/suite/innodb/t/innodb_bug53674.test 2010-06-02 10:26:37 +0000 +++ b/mysql-test/suite/innodb/t/innodb_bug53674.test 2010-08-17 07:14:46 +0000 @@ -1,4 +1,5 @@ -- source include/have_innodb.inc +-- source include/have_log_bin.inc create table bug53674(a int)engine=innodb; insert into bug53674 values (1),(2); === modified file 'mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1-master.opt' --- a/mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1-master.opt 2010-06-03 09:50:32 +0000 +++ b/mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=1 +--loose-innodb_lock_wait_timeout=1 === modified file 'mysql-test/suite/innodb/t/innodb_misc1-master.opt' --- a/mysql-test/suite/innodb/t/innodb_misc1-master.opt 2010-04-27 06:09:08 +0000 +++ b/mysql-test/suite/innodb/t/innodb_misc1-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---binlog_cache_size=32768 --innodb_lock_wait_timeout=1 +--binlog_cache_size=32768 --loose-innodb_lock_wait_timeout=1 === modified file 'mysql-test/suite/innodb/t/innodb_mysql-master.opt' --- a/mysql-test/suite/innodb/t/innodb_mysql-master.opt 2010-06-03 09:50:32 +0000 +++ b/mysql-test/suite/innodb/t/innodb_mysql-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb-lock-wait-timeout=2 +--loose-innodb-lock-wait-timeout=2 === modified file 'mysql-test/suite/innodb/t/innodb_mysql_rbk-master.opt' --- a/mysql-test/suite/innodb/t/innodb_mysql_rbk-master.opt 2010-06-03 09:50:32 +0000 +++ b/mysql-test/suite/innodb/t/innodb_mysql_rbk-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=1 --innodb_rollback_on_timeout=1 +--loose-innodb_lock_wait_timeout=1 --loose-innodb_rollback_on_timeout=1 === modified file 'mysql-test/suite/innodb/t/innodb_timeout_rollback-master.opt' --- a/mysql-test/suite/innodb/t/innodb_timeout_rollback-master.opt 2010-06-03 09:50:32 +0000 +++ b/mysql-test/suite/innodb/t/innodb_timeout_rollback-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=2 --innodb_rollback_on_timeout +--loose-innodb_lock_wait_timeout=2 --loose-innodb_rollback_on_timeout === added file 'mysql-test/suite/innodb_plugin/combinations' --- a/mysql-test/suite/innodb_plugin/combinations 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/innodb_plugin/combinations 2010-08-17 07:14:46 +0000 @@ -0,0 +1,12 @@ +[innodb_plugin] +ignore-builtin-innodb +plugin-load=$HA_INNODB_PLUGIN_SO +innodb + +[xtradb_plugin] +ignore-builtin-innodb +plugin-load=$HA_XTRADB_SO +innodb + +[xtradb] +innodb === added file 'mysql-test/suite/innodb_plugin/suite.pm' --- a/mysql-test/suite/innodb_plugin/suite.pm 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/innodb_plugin/suite.pm 2010-08-24 12:33:34 +0000 @@ -0,0 +1,19 @@ +package My::Suite::InnoDB_plugin; + +@ISA = qw(My::Suite); + +############# initialization ###################### +my @combinations; + +push @combinations, 'innodb_plugin' if $ENV{HA_INNODB_PLUGIN_SO}; +push @combinations, 'xtradb_plugin' if $ENV{HA_XTRADB_SO}; +push @combinations, 'xtradb' if $::mysqld_variables{'innodb'} eq "ON"; + +return "Neither innodb_plugin nor xtradb are available" unless @combinations; + +$ENV{INNODB_PLUGIN_COMBINATIONS}=join ':', @combinations + unless $ENV{INNODB_PLUGIN_COMBINATIONS}; + +############# return an object ###################### +bless { }; + === modified file 'mysql-test/suite/innodb_plugin/t/innodb-consistent-master.opt' --- a/mysql-test/suite/innodb_plugin/t/innodb-consistent-master.opt 2010-04-09 12:56:51 +0000 +++ b/mysql-test/suite/innodb_plugin/t/innodb-consistent-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=2 +--loose-innodb_lock_wait_timeout=2 === modified file 'mysql-test/suite/innodb_plugin/t/innodb-master.opt' --- a/mysql-test/suite/innodb_plugin/t/innodb-master.opt 2010-04-09 12:56:51 +0000 +++ b/mysql-test/suite/innodb_plugin/t/innodb-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---binlog_cache_size=32768 --innodb_lock_wait_timeout=1 +--binlog_cache_size=32768 --loose-innodb_lock_wait_timeout=1 === modified file 'mysql-test/suite/innodb_plugin/t/innodb-semi-consistent-master.opt' --- a/mysql-test/suite/innodb_plugin/t/innodb-semi-consistent-master.opt 2010-04-09 12:56:51 +0000 +++ b/mysql-test/suite/innodb_plugin/t/innodb-semi-consistent-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=2 +--loose-innodb_lock_wait_timeout=2 === modified file 'mysql-test/suite/innodb_plugin/t/innodb-use-sys-malloc-master.opt' --- a/mysql-test/suite/innodb_plugin/t/innodb-use-sys-malloc-master.opt 2010-04-09 12:56:51 +0000 +++ b/mysql-test/suite/innodb_plugin/t/innodb-use-sys-malloc-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb-use-sys-malloc=true +--loose-innodb-use-sys-malloc=true === modified file 'mysql-test/suite/innodb_plugin/t/innodb_autoinc_lock_mode_zero-master.opt' --- a/mysql-test/suite/innodb_plugin/t/innodb_autoinc_lock_mode_zero-master.opt 2010-06-03 09:48:59 +0000 +++ b/mysql-test/suite/innodb_plugin/t/innodb_autoinc_lock_mode_zero-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb-autoinc-lock-mode=0 +--loose-innodb-autoinc-lock-mode=0 === modified file 'mysql-test/suite/innodb_plugin/t/innodb_bug30919-master.opt' --- a/mysql-test/suite/innodb_plugin/t/innodb_bug30919-master.opt 2010-06-03 09:48:59 +0000 +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug30919-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb --innodb_autoinc_lock_mode=0 +--loose-innodb_autoinc_lock_mode=0 === modified file 'mysql-test/suite/innodb_plugin/t/innodb_bug39438-master.opt' --- a/mysql-test/suite/innodb_plugin/t/innodb_bug39438-master.opt 2010-04-09 12:56:51 +0000 +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug39438-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb-file-per-table=1 +--loose-innodb-file-per-table=1 === modified file 'mysql-test/suite/innodb_plugin/t/innodb_bug42101-nonzero-master.opt' --- a/mysql-test/suite/innodb_plugin/t/innodb_bug42101-nonzero-master.opt 2010-04-09 12:56:51 +0000 +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug42101-nonzero-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_commit_concurrency=1 +--loose-innodb_commit_concurrency=1 === modified file 'mysql-test/suite/innodb_plugin/t/innodb_bug53674-master.opt' --- a/mysql-test/suite/innodb_plugin/t/innodb_bug53674-master.opt 2010-06-02 10:37:14 +0000 +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug53674-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---log-bin --innodb-locks-unsafe-for-binlog --binlog-format=mixed +--log-bin=master-bin --loose-innodb-locks-unsafe-for-binlog --binlog-format=mixed === modified file 'mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1-master.opt' --- a/mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1-master.opt 2010-06-03 09:48:59 +0000 +++ b/mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=1 +--loose-innodb_lock_wait_timeout=1 === modified file 'mysql-test/suite/innodb_plugin/t/innodb_mysql-master.opt' --- a/mysql-test/suite/innodb_plugin/t/innodb_mysql-master.opt 2010-06-03 09:48:59 +0000 +++ b/mysql-test/suite/innodb_plugin/t/innodb_mysql-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb-lock-wait-timeout=2 +--loose-innodb-lock-wait-timeout=2 === modified file 'mysql-test/suite/innodb_plugin/t/innodb_mysql_rbk-master.opt' --- a/mysql-test/suite/innodb_plugin/t/innodb_mysql_rbk-master.opt 2010-06-03 09:48:59 +0000 +++ b/mysql-test/suite/innodb_plugin/t/innodb_mysql_rbk-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=1 --innodb_rollback_on_timeout=1 +--loose-innodb_lock_wait_timeout=1 --loose-innodb_rollback_on_timeout=1 === modified file 'mysql-test/suite/innodb_plugin/t/innodb_timeout_rollback-master.opt' --- a/mysql-test/suite/innodb_plugin/t/innodb_timeout_rollback-master.opt 2010-06-03 09:48:59 +0000 +++ b/mysql-test/suite/innodb_plugin/t/innodb_timeout_rollback-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=2 --innodb_rollback_on_timeout +--loose-innodb_lock_wait_timeout=2 --loose-innodb_rollback_on_timeout === modified file 'mysql-test/suite/ndb_team/t/rpl_ndb_mix_innodb-master.opt' --- a/mysql-test/suite/ndb_team/t/rpl_ndb_mix_innodb-master.opt 2008-01-04 14:33:01 +0000 +++ b/mysql-test/suite/ndb_team/t/rpl_ndb_mix_innodb-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb --default-storage-engine=innodb +--loose-innodb --default-storage-engine=innodb === modified file 'mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt' --- a/mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt 2010-03-17 14:10:41 +0000 +++ b/mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_file_per_table=1 +--loose-innodb_file_per_table=1 === modified file 'mysql-test/suite/parts/t/partition_special_innodb-master.opt' --- a/mysql-test/suite/parts/t/partition_special_innodb-master.opt 2008-08-20 15:29:14 +0000 +++ b/mysql-test/suite/parts/t/partition_special_innodb-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=2 +--loose-innodb_lock_wait_timeout=2 === modified file 'mysql-test/suite/pbxt/my.cnf' --- a/mysql-test/suite/pbxt/my.cnf 2009-10-26 11:35:42 +0000 +++ b/mysql-test/suite/pbxt/my.cnf 2010-08-17 07:14:46 +0000 @@ -2,6 +2,7 @@ !include include/default_mysqld.cnf [mysqld.1] +pbxt default-storage-engine=pbxt [ENV] === removed file 'mysql-test/suite/pbxt/t/suite.opt' --- a/mysql-test/suite/pbxt/t/suite.opt 2010-03-30 12:36:49 +0000 +++ b/mysql-test/suite/pbxt/t/suite.opt 1970-01-01 00:00:00 +0000 @@ -1 +0,0 @@ ---default-storage-engine=pbxt === modified file 'mysql-test/suite/percona/percona_innodb_doublewrite_file-master.opt' --- a/mysql-test/suite/percona/percona_innodb_doublewrite_file-master.opt 2010-08-03 10:54:05 +0000 +++ b/mysql-test/suite/percona/percona_innodb_doublewrite_file-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_doublewrite_file=ib_doublewrite +--loose-innodb_doublewrite_file=ib_doublewrite === modified file 'mysql-test/suite/rpl/r/rpl_row_basic_11bugs-master.opt' --- a/mysql-test/suite/rpl/r/rpl_row_basic_11bugs-master.opt 2007-06-27 12:28:02 +0000 +++ b/mysql-test/suite/rpl/r/rpl_row_basic_11bugs-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb +--loose-innodb === modified file 'mysql-test/suite/rpl/r/rpl_row_basic_11bugs-slave.opt' --- a/mysql-test/suite/rpl/r/rpl_row_basic_11bugs-slave.opt 2007-06-27 12:28:02 +0000 +++ b/mysql-test/suite/rpl/r/rpl_row_basic_11bugs-slave.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb +--loose-innodb === modified file 'mysql-test/suite/rpl/rpl_1slave_base.cnf' --- a/mysql-test/suite/rpl/rpl_1slave_base.cnf 2008-11-04 17:07:14 +0000 +++ b/mysql-test/suite/rpl/rpl_1slave_base.cnf 2010-08-17 07:14:46 +0000 @@ -8,8 +8,6 @@ log-bin= master-bin -loose-innodb - [mysqld.2] # Run the slave.sh script before starting this process #!run-slave-sh @@ -18,7 +16,6 @@ loose-innodb # starting the mysqld #!use-slave-opt -log-bin= slave-bin relay-log= slave-relay-bin init-rpl-role= slave === modified file 'mysql-test/suite/rpl/t/rpl_begin_commit_rollback-master.opt' --- a/mysql-test/suite/rpl/t/rpl_begin_commit_rollback-master.opt 2010-03-28 11:57:33 +0000 +++ b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb --binlog-ignore-db=db2 +--loose-innodb --binlog-ignore-db=db2 === modified file 'mysql-test/suite/rpl/t/rpl_begin_commit_rollback-slave.opt' --- a/mysql-test/suite/rpl/t/rpl_begin_commit_rollback-slave.opt 2009-05-31 05:44:41 +0000 +++ b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback-slave.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb --replicate-do-db=db1 +--loose-innodb --replicate-do-db=db1 === modified file 'mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.cnf' --- a/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.cnf 2008-04-25 16:54:42 +0000 +++ b/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.cnf 2010-08-17 07:14:46 +0000 @@ -2,19 +2,19 @@ [mysqld.1] log-slave-updates -innodb +loose-innodb [mysqld.2] log-slave-updates -innodb +loose-innodb [mysqld.3] log-slave-updates -innodb +loose-innodb [mysqld.4] log-slave-updates -innodb +loose-innodb [ENV] SLAVE_MYPORT1= @mysqld.3.port === modified file 'mysql-test/suite/rpl/t/rpl_concurrency_error-master.opt' --- a/mysql-test/suite/rpl/t/rpl_concurrency_error-master.opt 2009-07-06 08:02:14 +0000 +++ b/mysql-test/suite/rpl/t/rpl_concurrency_error-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb-lock-wait-timeout=1 +--loose-innodb-lock-wait-timeout=1 === added file 'mysql-test/suite/rpl/t/rpl_ddl-slave.opt' --- a/mysql-test/suite/rpl/t/rpl_ddl-slave.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/rpl/t/rpl_ddl-slave.opt 2010-08-17 07:14:46 +0000 @@ -0,0 +1 @@ +--loose-skip-innodb === modified file 'mysql-test/suite/rpl/t/rpl_deadlock_innodb-slave.opt' --- a/mysql-test/suite/rpl/t/rpl_deadlock_innodb-slave.opt 2008-10-29 13:25:03 +0000 +++ b/mysql-test/suite/rpl/t/rpl_deadlock_innodb-slave.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=4 --slave-transaction-retries=2 --max-relay-log-size=4096 +--loose-innodb-lock-wait-timeout=4 --slave-transaction-retries=2 --max-relay-log-size=4096 === modified file 'mysql-test/suite/rpl/t/rpl_innodb-master.opt' --- a/mysql-test/suite/rpl/t/rpl_innodb-master.opt 2008-10-29 13:25:03 +0000 +++ b/mysql-test/suite/rpl/t/rpl_innodb-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_autoinc_lock_mode=0 +--loose-innodb-autoinc-lock-mode=0 === modified file 'mysql-test/suite/rpl/t/rpl_innodb_bug28430-master.opt' --- a/mysql-test/suite/rpl/t/rpl_innodb_bug28430-master.opt 2008-10-29 13:25:03 +0000 +++ b/mysql-test/suite/rpl/t/rpl_innodb_bug28430-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_autoinc_lock_mode=0 +--loose-innodb-autoinc-lock-mode=0 === modified file 'mysql-test/suite/rpl/t/rpl_innodb_bug28430-slave.opt' --- a/mysql-test/suite/rpl/t/rpl_innodb_bug28430-slave.opt 2008-10-29 13:25:03 +0000 +++ b/mysql-test/suite/rpl/t/rpl_innodb_bug28430-slave.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_autoinc_lock_mode=0 +--loose-innodb-autoinc-lock-mode=0 === modified file 'mysql-test/suite/rpl/t/rpl_start_stop_slave-slave.opt' --- a/mysql-test/suite/rpl/t/rpl_start_stop_slave-slave.opt 2009-03-26 08:25:06 +0000 +++ b/mysql-test/suite/rpl/t/rpl_start_stop_slave-slave.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=60 +--loose-innodb-lock-wait-timeout=60 === modified file 'mysql-test/suite/rpl/t/rpl_trigger.test' --- a/mysql-test/suite/rpl/t/rpl_trigger.test 2010-01-13 09:00:03 +0000 +++ b/mysql-test/suite/rpl/t/rpl_trigger.test 2010-08-17 07:14:46 +0000 @@ -4,6 +4,11 @@ # TODO: Remove statement include once 12574 is patched --source include/have_binlog_format_mixed_or_statement.inc --source include/master-slave.inc +--source include/have_innodb.inc +connection slave; +--source include/have_innodb.inc +connection master; + CALL mtr.add_suppression("Statement may not be safe to log in statement format."); @@ -506,11 +511,9 @@ sync_slave_with_master; connection master; source include/master-slave-reset.inc; -source include/have_innodb.inc; connection slave; -source include/have_innodb.inc; - connection master; + create table t1 ( f int ) engine = innodb; create table log ( r int ) engine = myisam; create trigger tr === modified file 'mysql-test/suite/rpl/t/rpl_typeconv-slave.opt' --- a/mysql-test/suite/rpl/t/rpl_typeconv-slave.opt 2010-03-17 14:28:49 +0000 +++ b/mysql-test/suite/rpl/t/rpl_typeconv-slave.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb \ No newline at end of file +--loose-innodb === modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_2innodb-slave.opt' --- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_2innodb-slave.opt 2008-01-04 14:33:01 +0000 +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_2innodb-slave.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb --default-storage-engine=innodb --ndbcluster=0 +--loose-innodb --default-storage-engine=innodb --ndbcluster=0 === modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_2other-slave.opt' --- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_2other-slave.opt 2009-05-18 11:39:13 +0000 +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_2other-slave.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb --loose-ndbcluster=OFF --log-slave-updates=0 +--loose-innodb --loose-ndbcluster=OFF --log-slave-updates=0 === modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_2ch.cnf' --- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_2ch.cnf 2008-10-31 14:11:44 +0000 +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_2ch.cnf 2010-08-17 07:14:46 +0000 @@ -2,15 +2,12 @@ [mysqld.1.1] server-id= 1 -log-bin [mysqld.2.1] server-id= 1 -log-bin [mysqld.1.slave] server-id= 2 -log-bin skip-slave-start [mysqld.2.slave] @@ -21,7 +18,6 @@ master-password= @mysqld.2.1.#password master-user= @mysqld.2.1.#user master-connect-retry= 1 init-rpl-role= slave -log-bin skip-slave-start ndb_connectstring= @mysql_cluster.slave.ndb_connectstring === modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb2ndb-master.opt' --- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb2ndb-master.opt 2007-06-27 12:28:02 +0000 +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb2ndb-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb +--loose-innodb === modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb_trans-slave.opt' --- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb_trans-slave.opt 2007-06-27 12:28:02 +0000 +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb_trans-slave.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb +--loose-innodb === modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_engines_transactions-master.opt' --- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_engines_transactions-master.opt 2008-07-06 10:53:25 +0000 +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_engines_transactions-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb +--loose-innodb === modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_engines_transactions-slave.opt' --- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_engines_transactions-slave.opt 2008-07-06 10:53:25 +0000 +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_engines_transactions-slave.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb +--loose-innodb === modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_tables-master.opt' --- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_tables-master.opt 2009-09-23 09:43:43 +0000 +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_tables-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb --ndbcluster +--loose-innodb --ndbcluster === modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_tables-slave.opt' --- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_tables-slave.opt 2009-09-23 09:43:43 +0000 +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_tables-slave.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb --ndbcluster --replicate-ignore-table=mysql.ndb_apply_status +--loose-innodb --ndbcluster --replicate-ignore-table=mysql.ndb_apply_status === modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_stm_innodb-master.opt' --- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_stm_innodb-master.opt 2007-07-04 20:38:53 +0000 +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_stm_innodb-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb --default-storage-engine=innodb +--loose-innodb --default-storage-engine=innodb === modified file 'mysql-test/suite/sys_vars/t/autocommit_func-master.opt' --- a/mysql-test/suite/sys_vars/t/autocommit_func-master.opt 2008-12-19 15:12:15 +0000 +++ b/mysql-test/suite/sys_vars/t/autocommit_func-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb +--loose-innodb === modified file 'mysql-test/suite/sys_vars/t/character_set_filesystem_func-master.opt' --- a/mysql-test/suite/sys_vars/t/character_set_filesystem_func-master.opt 2008-12-19 15:12:15 +0000 +++ b/mysql-test/suite/sys_vars/t/character_set_filesystem_func-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---secure-file-priv=$MYSQL_TEST_DIR --innodb +--secure-file-priv=$MYSQL_TEST_DIR --loose-innodb === modified file 'mysql-test/suite/sys_vars/t/identity_func-master.opt' --- a/mysql-test/suite/sys_vars/t/identity_func-master.opt 2008-12-19 15:12:15 +0000 +++ b/mysql-test/suite/sys_vars/t/identity_func-master.opt 2010-08-17 07:14:46 +0000 @@ -1,2 +1,2 @@ ---innodb +--loose-innodb === modified file 'mysql-test/suite/sys_vars/t/innodb_autoinc_lock_mode_func-master.opt' --- a/mysql-test/suite/sys_vars/t/innodb_autoinc_lock_mode_func-master.opt 2008-12-19 15:12:15 +0000 +++ b/mysql-test/suite/sys_vars/t/innodb_autoinc_lock_mode_func-master.opt 2010-08-17 07:14:46 +0000 @@ -1,2 +1,2 @@ ---innodb-autoinc-lock-mode=1 +--loose-innodb-autoinc-lock-mode=1 === modified file 'mysql-test/suite/sys_vars/t/last_insert_id_func-master.opt' --- a/mysql-test/suite/sys_vars/t/last_insert_id_func-master.opt 2008-12-19 15:12:15 +0000 +++ b/mysql-test/suite/sys_vars/t/last_insert_id_func-master.opt 2010-08-17 07:14:46 +0000 @@ -1,2 +1,2 @@ ---innodb +--loose-innodb === modified file 'mysql-test/suite/sys_vars/t/max_binlog_cache_size_func-master.opt' --- a/mysql-test/suite/sys_vars/t/max_binlog_cache_size_func-master.opt 2008-12-19 15:12:15 +0000 +++ b/mysql-test/suite/sys_vars/t/max_binlog_cache_size_func-master.opt 2010-08-17 07:14:46 +0000 @@ -1,2 +1,2 @@ --log-bin ---innodb +--loose-innodb === modified file 'mysql-test/suite/sys_vars/t/storage_engine_basic-master.opt' --- a/mysql-test/suite/sys_vars/t/storage_engine_basic-master.opt 2008-12-19 15:12:15 +0000 +++ b/mysql-test/suite/sys_vars/t/storage_engine_basic-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb +--loose-innodb === modified file 'mysql-test/suite/sys_vars/t/tx_isolation_func-master.opt' --- a/mysql-test/suite/sys_vars/t/tx_isolation_func-master.opt 2008-12-19 15:12:15 +0000 +++ b/mysql-test/suite/sys_vars/t/tx_isolation_func-master.opt 2010-08-17 07:14:46 +0000 @@ -1,3 +1,3 @@ ---innodb ---innodb_lock_wait_timeout=2 +--loose-innodb +--loose-innodb_lock_wait_timeout=2 --binlog-format=row \ No newline at end of file === modified file 'mysql-test/t/bug46760-master.opt' --- a/mysql-test/t/bug46760-master.opt 2009-09-18 13:01:18 +0000 +++ b/mysql-test/t/bug46760-master.opt 2010-08-17 07:14:46 +0000 @@ -1,2 +1,2 @@ ---innodb-lock-wait-timeout=2 ---innodb-file-per-table +--loose-innodb-lock-wait-timeout=2 +--loose-innodb-file-per-table === modified file 'mysql-test/t/concurrent_innodb_safelog-master.opt' --- a/mysql-test/t/concurrent_innodb_safelog-master.opt 2008-08-15 18:48:14 +0000 +++ b/mysql-test/t/concurrent_innodb_safelog-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=1 +--loose-innodb_lock_wait_timeout=1 === modified file 'mysql-test/t/concurrent_innodb_unsafelog-master.opt' --- a/mysql-test/t/concurrent_innodb_unsafelog-master.opt 2008-08-15 18:48:14 +0000 +++ b/mysql-test/t/concurrent_innodb_unsafelog-master.opt 2010-08-17 07:14:46 +0000 @@ -1,2 +1,2 @@ ---innodb_locks_unsafe_for_binlog ---innodb_lock_wait_timeout=1 +--loose-innodb_locks_unsafe_for_binlog +--loose-innodb_lock_wait_timeout=1 === modified file 'mysql-test/t/connect.cnf' --- a/mysql-test/t/connect.cnf 2009-03-18 15:46:32 +0000 +++ b/mysql-test/t/connect.cnf 2010-08-17 07:14:46 +0000 @@ -5,4 +5,4 @@ extra-port= @mysqld.1.#extra-port extra-max-connections=1 [ENV] -MASTER_EXTRA_PORT= @mysqld.1.extra-port +MASTER_EXTRA_PORT= @mysqld.1.#extra-port === modified file 'mysql-test/t/disabled.def' --- a/mysql-test/t/disabled.def 2010-08-02 09:01:24 +0000 +++ b/mysql-test/t/disabled.def 2010-08-11 21:33:15 +0000 @@ -14,3 +14,4 @@ query_cache_28249 : Bug#43861 200 partition_innodb_plugin : Bug#53307 2010-04-30 VasilDimov valgrind warnings main.mysqlhotcopy_myisam : bug#54129 2010-06-04 Horst main.mysqlhotcopy_archive: bug#54129 2010-06-04 Horst +main.events_time_zone : Test is not predictable as it depends on precise timing. === removed file 'mysql-test/t/exampledb.test' --- a/mysql-test/t/exampledb.test 2006-05-05 17:08:40 +0000 +++ b/mysql-test/t/exampledb.test 1970-01-01 00:00:00 +0000 @@ -1,22 +0,0 @@ -# -# Simple test for the example storage engine -# Taken fromm the select test -# --- source include/have_exampledb.inc - ---disable_warnings -# Clean up if event's test fails -drop database if exists events_test; -drop database if exists events_test2; - -drop table if exists t1; ---enable_warnings - -CREATE TABLE t1 ( - Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, - Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL -) ENGINE=example; - -drop table t1; - -# End of 4.1 tests === modified file 'mysql-test/t/group_by.test' --- a/mysql-test/t/group_by.test 2010-05-12 16:10:33 +0000 +++ b/mysql-test/t/group_by.test 2010-08-23 09:46:25 +0000 @@ -1219,6 +1219,23 @@ EXPLAIN SELECT MAX(t2.a) FROM t2 LEFT JO SELECT MAX(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a; DROP TABLE t1, t2; +# +# min() returns wrong value when used in expression when there is no matching +# rows +# + +CREATE TABLE t1 (a int(11) NOT NULL); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 ( + key_col int(11) NOT NULL, + KEY (key_col) +); +INSERT INTO t2 VALUES (1),(2); + +select min(t2.key_col) from t1,t2 where t1.a=1; +select min(t2.key_col) from t1,t2 where t1.a > 1000; +select min(t2.key_col)+1 from t1,t2 where t1.a> 1000; +drop table t1,t2; --echo # === modified file 'mysql-test/t/partition_innodb-master.opt' --- a/mysql-test/t/partition_innodb-master.opt 2010-01-18 16:49:18 +0000 +++ b/mysql-test/t/partition_innodb-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=1 +--loose-innodb_lock_wait_timeout=1 === modified file 'mysql-test/t/partition_innodb_semi_consistent-master.opt' --- a/mysql-test/t/partition_innodb_semi_consistent-master.opt 2008-12-16 11:44:18 +0000 +++ b/mysql-test/t/partition_innodb_semi_consistent-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_lock_wait_timeout=2 +--loose-innodb_lock_wait_timeout=2 === modified file 'mysql-test/t/pool_of_threads.cnf' --- a/mysql-test/t/pool_of_threads.cnf 2009-05-06 12:03:24 +0000 +++ b/mysql-test/t/pool_of_threads.cnf 2010-08-17 07:14:46 +0000 @@ -11,4 +11,4 @@ extra-max-connections=1 connect-timeout= 2 [ENV] -MASTER_EXTRA_PORT= @mysqld.1.extra-port +MASTER_EXTRA_PORT= @mysqld.1.#extra-port === modified file 'mysql-test/t/sp_trans_log.test' --- a/mysql-test/t/sp_trans_log.test 2010-05-24 13:54:08 +0000 +++ b/mysql-test/t/sp_trans_log.test 2010-08-17 07:14:46 +0000 @@ -3,7 +3,7 @@ # part of sp_trans test that appeared to be sensitive to binlog format --source include/have_innodb.inc ---source include/have_binlog_format_mixed_or_row.inc +--source include/have_binlog_format_mixed.inc delimiter |; === modified file 'mysql-test/t/subselect4.test' --- a/mysql-test/t/subselect4.test 2009-09-18 09:34:08 +0000 +++ b/mysql-test/t/subselect4.test 2010-08-23 09:46:25 +0000 @@ -62,3 +62,29 @@ FROM t3 WHERE 1 = 0 GROUP BY 1; DROP TABLE t1,t2,t3; --echo End of 5.0 tests. + +# +# Fix for LP#612894 +# Some aggregate functions (such as MIN MAX) work incorrectly in subqueries +# after getting NULL value +# + +CREATE TABLE t1 (col_int_nokey int(11) NOT NULL, col_varchar_nokey varchar(1) NOT NULL) engine=myisam; +INSERT INTO t1 VALUES (2,'s'),(0,'v'),(2,'s'); +CREATE TABLE t2 ( + pk int(11) NOT NULL AUTO_INCREMENT, + `col_int_key` int(11) NOT NULL, + col_varchar_key varchar(1) NOT NULL, + PRIMARY KEY (pk), + KEY `col_int_key` (`col_int_key`), + KEY `col_varchar_key` (`col_varchar_key`) +) ENGINE=MyISAM; +INSERT INTO t2 VALUES (4,10,'g'), (5,20,'v'); + +SELECT t1.col_int_nokey,(SELECT MIN( t2_a.col_int_key ) FROM t2 t2_a, t2 t2_b, t1 t1_a WHERE t1_a.col_varchar_nokey = t2_b.col_varchar_key and t1.col_int_nokey ) as sub FROM t1; + +SELECT t1.col_int_nokey,(SELECT MIN( t2_a.col_int_key ) +1 FROM t2 t2_a, t2 t2_b, t1 t1_a WHERE t1_a.col_varchar_nokey = t2_b.col_varchar_key and t1.col_int_nokey ) as sub FROM t1; + +DROP TABLE t1,t2; + +--echo End of 5.1 tests. === modified file 'mysql-test/t/unsafe_binlog_innodb-master.opt' --- a/mysql-test/t/unsafe_binlog_innodb-master.opt 2006-08-16 12:58:49 +0000 +++ b/mysql-test/t/unsafe_binlog_innodb-master.opt 2010-08-17 07:14:46 +0000 @@ -1 +1 @@ ---innodb_locks_unsafe_for_binlog=true --innodb_lock_wait_timeout=1 +--loose-innodb_locks_unsafe_for_binlog=true --loose-innodb_lock_wait_timeout=1 === modified file 'mysql-test/t/warnings_engine_disabled.test' --- a/mysql-test/t/warnings_engine_disabled.test 2008-12-17 15:45:34 +0000 +++ b/mysql-test/t/warnings_engine_disabled.test 2010-08-17 07:14:46 +0000 @@ -2,23 +2,22 @@ # Only run this test with a compiled in but disabled # engine # -disable_query_log; ---require r/true.require -select support = 'NO' as `TRUE` from information_schema.engines where engine = 'ndbcluster'; -enable_query_log; +if (!`SELECT count(*) FROM information_schema.engines WHERE + support = 'NO' AND engine = 'innodb'`){ + skip Needs innodb engine; +} # # Test for handler type, will select MyISAM and print a warning -# about that - since NDB is disabled +# about that - since InnoDB is disabled # -create table t1 (id int) engine=NDB; -alter table t1 engine=NDB; +create table t1 (id int) engine=InnoDB; +alter table t1 engine=InnoDB; drop table t1; # # Bug#29263 disabled storage engines omitted in SHOW ENGINES # -SELECT ENGINE, SUPPORT FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE='ndbcluster'; -SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE -PLUGIN_NAME='ndbcluster'; +SELECT ENGINE, SUPPORT FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE='InnoDB'; +SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='InnoDB'; === modified file 'mysys/my_getwd.c' --- a/mysys/my_getwd.c 2010-05-05 08:54:52 +0000 +++ b/mysys/my_getwd.c 2010-08-14 14:44:45 +0000 @@ -51,7 +51,7 @@ int my_getwd(char * buf, size_t size, my (long) buf, (uint) size, MyFlags)); if (size < 1) - return(-1); + DBUG_RETURN(-1); if (curr_dir[0]) /* Current pos is saved here */ VOID(strmake(buf,&curr_dir[0],size-1)); @@ -59,12 +59,12 @@ int my_getwd(char * buf, size_t size, my { #if defined(HAVE_GETCWD) if (size < 2) - return(-1); + DBUG_RETURN(-1); if (!getcwd(buf,(uint) (size-2)) && MyFlags & MY_WME) { my_errno=errno; my_error(EE_GETWD,MYF(ME_BELL+ME_WAITTANG),errno); - return(-1); + DBUG_RETURN(-1); } #elif defined(HAVE_GETWD) { @@ -74,12 +74,12 @@ int my_getwd(char * buf, size_t size, my } #elif defined(VMS) if (size < 2) - return(-1); + DBUG_RETURN(-1); if (!getcwd(buf,size-2,1) && MyFlags & MY_WME) { my_errno=errno; my_error(EE_GETWD,MYF(ME_BELL+ME_WAITTANG),errno); - return(-1); + DBUG_RETURN(-1); } intern_filename(buf,buf); #else === modified file 'scripts/Makefile.am' --- a/scripts/Makefile.am 2010-04-28 12:52:24 +0000 +++ b/scripts/Makefile.am 2010-08-18 07:52:57 +0000 @@ -37,7 +37,8 @@ bin_SCRIPTS = @server_scripts@ \ mysqld_multi noinst_SCRIPTS = make_binary_distribution \ - make_sharedlib_distribution + make_sharedlib_distribution \ + convert-debug-for-diff EXTRA_SCRIPTS = make_binary_distribution.sh \ make_sharedlib_distribution.sh \ @@ -59,7 +60,8 @@ EXTRA_SCRIPTS = make_binary_distributio mysqlhotcopy.sh \ mysqldumpslow.sh \ mysqld_multi.sh \ - mysqld_safe.sh + mysqld_safe.sh \ + convert-debug-for-diff.sh EXTRA_DIST = $(EXTRA_SCRIPTS) \ mysqlaccess.conf \ @@ -91,6 +93,7 @@ CLEANFILES = @server_scripts@ \ mysqlhotcopy \ mysqldumpslow \ mysqld_multi \ + convert-debug-for-diff \ $(EXTRA_PROGRAMS) pkgplugindir = $(pkglibdir)/plugin === added file 'scripts/convert-debug-for-diff.sh' --- a/scripts/convert-debug-for-diff.sh 1970-01-01 00:00:00 +0000 +++ b/scripts/convert-debug-for-diff.sh 2010-08-23 09:52:57 +0000 @@ -0,0 +1,25 @@ +#!/usr/bin/perl -i +# +# This script converts all numbers that look like addresses or memory sizes, +# in a debug files generated by --debug (like mysqld --debug), to #. +# The script also deletes all thread id's from the start of the line. + +# This allows you to easily compare the files (for example with diff) +# to find out what changes between different executions. +# This is extremely useful for comparing two mysqld versions to see +# why things now work differently. + +# The script converts the files in place. +# +# Typical usage: +# +# convert-debug-for-diff /tmp/mysqld.trace /tmp/mysqld-old.trace +# diff /tmp/mysqld.trace /tmp/mysqld-old.trace + +while (<>) +{ + s/^T@[0-9]+\s*://g; + s/0x[0-9a-f]+(\s|\n|\))/#$1/g; + s/size: [0-9]+/size: #/g; + print $_; +} === modified file 'sql/item.h' --- a/sql/item.h 2010-08-05 19:56:11 +0000 +++ b/sql/item.h 2010-08-24 22:44:50 +0000 @@ -870,6 +870,7 @@ public: set value of aggregate function in case of no rows for grouping were found */ virtual void no_rows_in_result() {} + virtual void restore_to_before_no_rows_in_result() {} virtual Item *copy_or_same(THD *thd) { return this; } virtual Item *copy_andor_structure(THD *thd) { return this; } virtual Item *real_item() { return this; } @@ -926,6 +927,21 @@ public: virtual bool register_field_in_read_map(uchar *arg) { return 0; } virtual bool enumerate_field_refs_processor(uchar *arg) { return 0; } virtual bool mark_as_eliminated_processor(uchar *arg) { return 0; } + + /* To call bool function for all arguments */ + struct bool_func_call_args + { + Item *original_func_item; + void (Item::*bool_function)(); + }; + bool call_bool_func_processor(uchar *org_item) + { + bool_func_call_args *info= (bool_func_call_args*) org_item; + /* Avoid recursion, as walk also calls for original item */ + if (info->original_func_item != this) + (this->*(info->bool_function))(); + return FALSE; + } /* The next function differs from the previous one that a bitmap to be updated is passed as uchar *arg. @@ -2404,6 +2420,14 @@ public: return (*ref)->walk(processor, walk_subquery, arg) || (this->*processor)(arg); } + void no_rows_in_result() + { + (*ref)->no_rows_in_result(); + } + void restore_to_before_no_rows_in_result() + { + (*ref)->restore_to_before_no_rows_in_result(); + } virtual void print(String *str, enum_query_type query_type); bool result_as_longlong() { === modified file 'sql/item_func.h' --- a/sql/item_func.h 2010-03-15 11:51:23 +0000 +++ b/sql/item_func.h 2010-08-24 22:44:50 +0000 @@ -217,6 +217,21 @@ public: { return functype() == *(Functype *) arg; } + + void no_rows_in_result() + { + bool_func_call_args info; + info.original_func_item= this; + info.bool_function= &Item::no_rows_in_result; + walk(&Item::call_bool_func_processor, FALSE, (uchar*) &info); + } + void restore_to_before_no_rows_in_result() + { + bool_func_call_args info; + info.original_func_item= this; + info.bool_function= &Item::restore_to_before_no_rows_in_result; + walk(&Item::call_bool_func_processor, FALSE, (uchar*) &info); + } }; === modified file 'sql/item_sum.cc' --- a/sql/item_sum.cc 2010-08-02 09:01:24 +0000 +++ b/sql/item_sum.cc 2010-08-23 09:46:25 +0000 @@ -1638,8 +1638,22 @@ void Item_sum_hybrid::cleanup() void Item_sum_hybrid::no_rows_in_result() { - was_values= FALSE; - clear(); + /* We may be called here twice in case of ref field in function */ + if (was_values) + { + was_values= FALSE; + was_null_value= value->null_value; + clear(); + } +} + +void Item_sum_hybrid::restore_to_before_no_rows_in_result() +{ + if (!was_values) + { + was_values= TRUE; + null_value= value->null_value= was_null_value; + } } === modified file 'sql/item_sum.h' --- a/sql/item_sum.h 2010-08-05 19:56:11 +0000 +++ b/sql/item_sum.h 2010-08-24 22:44:50 +0000 @@ -500,7 +500,7 @@ public: enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; } void reset_field() {} // not used void update_field() {} // not used - virtual void no_rows_in_result() {} + void no_rows_in_result() {} void fix_length_and_dec(); enum Item_result result_type () const { return val.traits->type(); } virtual void calculate_val_and_count(); @@ -857,6 +857,7 @@ protected: enum_field_types hybrid_field_type; int cmp_sign; bool was_values; // Set if we have found at least one row (for max/min only) + bool was_null_value; public: Item_sum_hybrid(Item *item_par,int sign) @@ -888,6 +889,7 @@ protected: void cleanup(); bool any_value() { return was_values; } void no_rows_in_result(); + void restore_to_before_no_rows_in_result(); Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length); }; === modified file 'sql/log.cc' --- a/sql/log.cc 2010-08-05 19:56:11 +0000 +++ b/sql/log.cc 2010-08-24 22:44:50 +0000 @@ -372,6 +372,7 @@ bool Log_to_csv_event_handler:: Open_tables_state open_tables_backup; ulonglong save_thd_options; bool save_time_zone_used; + DBUG_ENTER("log_general"); /* CSV uses TIME_to_timestamp() internally if table needs to be repaired @@ -490,7 +491,7 @@ err: thd->options= save_thd_options; thd->time_zone_used= save_time_zone_used; - return result; + DBUG_RETURN(result); } === modified file 'sql/mysqld.cc' --- a/sql/mysqld.cc 2010-08-09 17:49:42 +0000 +++ b/sql/mysqld.cc 2010-08-24 22:44:50 +0000 @@ -9380,6 +9380,8 @@ bool is_secure_file_path(char *path) static int fix_paths(void) { char buff[FN_REFLEN],*pos; + DBUG_ENTER("fix_paths"); + convert_dirname(mysql_home,mysql_home,NullS); /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */ my_realpath(mysql_home,mysql_home,MYF(0)); @@ -9424,12 +9426,12 @@ static int fix_paths(void) charsets_dir=mysql_charsets_dir; if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir)) - return 1; + DBUG_RETURN(1); #ifdef HAVE_REPLICATION if (!slave_load_tmpdir) { if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE)))) - return 1; + DBUG_RETURN(1); } #endif /* HAVE_REPLICATION */ /* @@ -9450,7 +9452,7 @@ static int fix_paths(void) if (my_realpath(buff, opt_secure_file_priv, 0)) { sql_print_warning("Failed to normalize the argument for --secure-file-priv."); - return 1; + DBUG_RETURN(1); } secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE)); convert_dirname(secure_file_real_path, buff, NullS); @@ -9458,7 +9460,7 @@ static int fix_paths(void) opt_secure_file_priv= secure_file_real_path; } } - return 0; + DBUG_RETURN(0); } === modified file 'sql/sql_select.cc' --- a/sql/sql_select.cc 2010-08-07 12:27:23 +0000 +++ b/sql/sql_select.cc 2010-08-24 22:44:50 +0000 @@ -1688,6 +1688,16 @@ JOIN::reinit() func->clear(); } + if (no_rows_in_result_called) + { + /* Reset effect of possible no_rows_in_result() */ + List_iterator_fast<Item> it(fields_list); + Item *item; + + no_rows_in_result_called= 0; + while ((item= it++)) + item->restore_to_before_no_rows_in_result(); + } DBUG_RETURN(0); } @@ -12697,8 +12707,11 @@ end_send_group(JOIN *join, JOIN_TAB *joi { List_iterator_fast<Item> it(*join->fields); Item *item; + DBUG_PRINT("info", ("no matching rows")); + /* No matching rows for group function */ join->clear(); + join->no_rows_in_result_called= 1; while ((item= it++)) item->no_rows_in_result(); === modified file 'sql/sql_select.h' --- a/sql/sql_select.h 2010-04-28 12:52:24 +0000 +++ b/sql/sql_select.h 2010-08-24 17:17:17 +0000 @@ -365,24 +365,31 @@ public: the number of rows in it may vary from one subquery execution to another. */ bool no_const_tables; + /* + This flag is set if we call no_rows_in_result() as par of end_group(). + This is used as a simple speed optimization to avoiding calling + restore_no_rows_in_result() in ::reinit() + */ + bool no_rows_in_result_called; /** Copy of this JOIN to be used with temporary tables. - tmp_join is used when the JOIN needs to be "reusable" (e.g. in a subquery - that gets re-executed several times) and we know will use temporary tables - for materialization. The materialization to a temporary table overwrites the - JOIN structure to point to the temporary table after the materialization is - done. This is where tmp_join is used : it's a copy of the JOIN before the - materialization and is used in restoring before re-execution by overwriting - the current JOIN structure with the saved copy. - Because of this we should pay extra care of not freeing up helper structures - that are referenced by the original contents of the JOIN. We can check for - this by making sure the "current" join is not the temporary copy, e.g. - !tmp_join || tmp_join != join + tmp_join is used when the JOIN needs to be "reusable" (e.g. in a + subquery that gets re-executed several times) and we know will use + temporary tables for materialization. The materialization to a + temporary table overwrites the JOIN structure to point to the + temporary table after the materialization is done. This is where + tmp_join is used : it's a copy of the JOIN before the + materialization and is used in restoring before re-execution by + overwriting the current JOIN structure with the saved copy. + Because of this we should pay extra care of not freeing up helper + structures that are referenced by the original contents of the + JOIN. We can check for this by making sure the "current" join is + not the temporary copy, e.g. !tmp_join || tmp_join != join - We should free these sub-structures at JOIN::destroy() if the "current" join - has a copy is not that copy. + We should free these sub-structures at JOIN::destroy() if the + "current" join has a copy is not that copy. */ JOIN *tmp_join; ROLLUP rollup; ///< Used with rollup @@ -512,6 +519,7 @@ public: optimized= 0; cond_equal= 0; group_optimized_away= 0; + no_rows_in_result_called= 0; all_fields= fields_arg; if (&fields_list != &fields_arg) /* Avoid valgrind-warning */ === modified file 'storage/federatedx/federatedx_io_mysql.cc' --- a/storage/federatedx/federatedx_io_mysql.cc 2009-11-14 19:33:59 +0000 +++ b/storage/federatedx/federatedx_io_mysql.cc 2010-08-12 17:52:52 +0000 @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2007, Antony T Curtis All rights reserved. @@ -51,6 +51,12 @@ typedef struct federatedx_savepoint uint flags; } SAVEPT; +struct mysql_position +{ + MYSQL_RES* result; + MYSQL_ROW_OFFSET offset; +}; + class federatedx_io_mysql :public federatedx_io { @@ -76,16 +82,16 @@ public: virtual int error_code(); virtual const char *error_str(); - + void reset(); int commit(); int rollback(); - + int savepoint_set(ulong sp); ulong savepoint_release(ulong sp); ulong savepoint_rollback(ulong sp); void savepoint_restrict(ulong sp); - + ulong last_savepoint() const; ulong actual_savepoint() const; bool is_autocommit() const; @@ -94,7 +100,7 @@ public: uint table_name_length, uint flag); /* resultset operations */ - + virtual void free_result(FEDERATEDX_IO_RESULT *io_result); virtual unsigned int get_num_fields(FEDERATEDX_IO_RESULT *io_result); virtual my_ulonglong get_num_rows(FEDERATEDX_IO_RESULT *io_result); @@ -104,6 +110,12 @@ public: unsigned int column); virtual bool is_column_null(const FEDERATEDX_IO_ROW *row, unsigned int column) const; + + virtual size_t get_ref_length() const; + virtual void mark_position(FEDERATEDX_IO_RESULT *io_result, + void *ref); + virtual int seek_position(FEDERATEDX_IO_RESULT **io_result, + const void *ref); }; @@ -466,14 +478,13 @@ const char *federatedx_io_mysql::error_s return mysql_error(&mysql); } - FEDERATEDX_IO_RESULT *federatedx_io_mysql::store_result() { FEDERATEDX_IO_RESULT *result; DBUG_ENTER("federatedx_io_mysql::store_result"); - + result= (FEDERATEDX_IO_RESULT *) mysql_store_result(&mysql); - + DBUG_RETURN(result); } @@ -590,3 +601,45 @@ error: free_result(result); return 1; } + + + +size_t federatedx_io_mysql::get_ref_length() const +{ + return sizeof(mysql_position); +} + + +void federatedx_io_mysql::mark_position(FEDERATEDX_IO_RESULT *io_result, + void *ref) +{ + MYSQL_ROWS *tmp= 0; + mysql_position& pos= *reinterpret_cast<mysql_position*>(ref); + pos.result= (MYSQL_RES *) io_result; + + if (pos.result && pos.result->data) + { + for (tmp= pos.result->data->data; + tmp && (tmp->next != pos.result->data_cursor); + tmp= tmp->next) + {} + } + + pos.offset= tmp; +} + +int federatedx_io_mysql::seek_position(FEDERATEDX_IO_RESULT **io_result, + const void *ref) +{ + const mysql_position& pos= *reinterpret_cast<const mysql_position*>(ref); + + if (!pos.result || !pos.offset) + return HA_ERR_END_OF_FILE; + + pos.result->current_row= 0; + pos.result->data_cursor= pos.offset; + *io_result= (FEDERATEDX_IO_RESULT*) pos.result; + + return 0; +} + === modified file 'storage/federatedx/federatedx_io_null.cc' --- a/storage/federatedx/federatedx_io_null.cc 2009-11-14 19:33:59 +0000 +++ b/storage/federatedx/federatedx_io_null.cc 2010-08-12 17:52:52 +0000 @@ -96,6 +96,11 @@ public: unsigned int column); virtual bool is_column_null(const FEDERATEDX_IO_ROW *row, unsigned int column) const; + virtual size_t get_ref_length() const; + virtual void mark_position(FEDERATEDX_IO_RESULT *io_result, + void *ref); + virtual int seek_position(FEDERATEDX_IO_RESULT **io_result, + const void *ref); }; @@ -275,3 +280,20 @@ bool federatedx_io_null::table_metadata( return 0; } + +size_t federatedx_io_null::get_ref_length() const +{ + return sizeof(int); +} + + +void federatedx_io_null::mark_position(FEDERATEDX_IO_RESULT *io_result, + void *ref) +{ +} + +int federatedx_io_null::seek_position(FEDERATEDX_IO_RESULT **io_result, + const void *ref) +{ + return 0; +} === modified file 'storage/federatedx/ha_federatedx.cc' --- a/storage/federatedx/ha_federatedx.cc 2010-07-25 15:09:21 +0000 +++ b/storage/federatedx/ha_federatedx.cc 2010-08-24 22:44:50 +0000 @@ -1717,14 +1717,14 @@ federatedx_txn *ha_federatedx::get_txn(T return *txnp; } - + int ha_federatedx::disconnect(handlerton *hton, MYSQL_THD thd) { federatedx_txn *txn= (federatedx_txn *) thd_get_ha_data(thd, hton); delete txn; return 0; } - + /* Used for opening tables. The name will be the name of the file. @@ -1756,14 +1756,15 @@ int ha_federatedx::open(const char *name free_share(txn, share); DBUG_RETURN(error); } - + + ref_length= io->get_ref_length(); + txn->release(&io); - - ref_length= (table->s->primary_key != MAX_KEY ? - table->key_info[table->s->primary_key].key_length : - table->s->reclength); + DBUG_PRINT("info", ("ref_length: %u", ref_length)); + my_init_dynamic_array(&results, sizeof(FEDERATEDX_IO_RESULT*), 4, 4); + reset(); DBUG_RETURN(0); @@ -1788,8 +1789,9 @@ int ha_federatedx::close(void) DBUG_ENTER("ha_federatedx::close"); /* free the result set */ - if (stored_result) - retval= free_result(); + reset(); + + delete_dynamic(&results); /* Disconnect from mysql */ if (!thd || !(txn= get_txn(thd, true))) @@ -1799,7 +1801,7 @@ int ha_federatedx::close(void) tmp_txn.release(&io); DBUG_ASSERT(io == NULL); - + if ((error= free_share(&tmp_txn, share))) retval= error; } @@ -2525,7 +2527,7 @@ int ha_federatedx::index_read_idx(uchar uint key_len, enum ha_rkey_function find_flag) { int retval; - FEDERATEDX_IO_RESULT *io_result; + FEDERATEDX_IO_RESULT *io_result= 0; DBUG_ENTER("ha_federatedx::index_read_idx"); if ((retval= index_read_idx_with_result_set(buf, index, key, @@ -2601,7 +2603,7 @@ int ha_federatedx::index_read_idx_with_r if (!(retval= read_next(buf, *result))) DBUG_RETURN(retval); - io->free_result(*result); + insert_dynamic(&results, (uchar*) result); *result= 0; table->status= STATUS_NOT_FOUND; DBUG_RETURN(retval); @@ -2669,10 +2671,7 @@ int ha_federatedx::read_range_first(cons DBUG_RETURN(retval); if (stored_result) - { - io->free_result(stored_result); - stored_result= 0; - } + (void) free_result(); if (io->query(sql_query.ptr(), sql_query.length())) { @@ -2773,10 +2772,7 @@ int ha_federatedx::rnd_init(bool scan) DBUG_RETURN(error); if (stored_result) - { - io->free_result(stored_result); - stored_result= 0; - } + (void) free_result(); if (io->query(share->select_query, strlen(share->select_query))) @@ -2803,17 +2799,35 @@ int ha_federatedx::rnd_end() int ha_federatedx::free_result() { int error; - federatedx_io *tmp_io= 0, **iop; + DBUG_ENTER("ha_federatedx::free_result"); DBUG_ASSERT(stored_result); - if (!*(iop= &io) && (error= txn->acquire(share, TRUE, (iop= &tmp_io)))) + for (uint i= 0; i < results.elements; ++i) + { + FEDERATEDX_IO_RESULT *result= 0; + get_dynamic(&results, (uchar*) &result, i); + if (result == stored_result) + goto end; + } + if (position_called) + { + insert_dynamic(&results, (uchar*) &stored_result); + } + else { - DBUG_ASSERT(0); // Fail when testing - return error; + federatedx_io *tmp_io= 0, **iop; + if (!*(iop= &io) && (error= txn->acquire(share, TRUE, (iop= &tmp_io)))) + { + DBUG_ASSERT(0); // Fail when testing + insert_dynamic(&results, (uchar*) &stored_result); + goto end; + } + (*iop)->free_result(stored_result); + txn->release(&tmp_io); } - (*iop)->free_result(stored_result); +end: stored_result= 0; - txn->release(&tmp_io); - return 0; + position_called= FALSE; + DBUG_RETURN(0); } int ha_federatedx::index_end(void) @@ -2862,8 +2876,8 @@ int ha_federatedx::rnd_next(uchar *buf) SYNOPSIS field_in_record_is_null() - buf byte pointer to record - result mysql result set + buf byte pointer to record + result mysql result set DESCRIPTION This method is a wrapper method that reads one record from a result @@ -2896,24 +2910,43 @@ int ha_federatedx::read_next(uchar *buf, } -/* - store reference to current row so that we can later find it for - a re-read, update or delete. +/** + @brief Store a reference to current row. - In case of federatedx, a reference is either a primary key or - the whole record. + @details During a query execution we may have different result sets (RS), + e.g. for different ranges. All the RS's used are stored in + memory and placed in @c results dynamic array. At the end of + execution all stored RS's are freed at once in the + @c ha_federated::reset(). + So, in case of federated, a reference to current row is a + stored result address and current data cursor position. + As we keep all RS in memory during a query execution, + we can get any record using the reference any time until + @c ha_federated::reset() is called. + TODO: we don't have to store all RS's rows but only those + we call @c ha_federated::position() for, so we can free memory + where we store other rows in the @c ha_federated::index_end(). + + @param[in] record record data (unused) - Called from filesort.cc, sql_select.cc, sql_delete.cc and sql_update.cc. */ -void ha_federatedx::position(const uchar *record) +void ha_federatedx::position(const uchar *record __attribute__ ((unused))) { DBUG_ENTER("ha_federatedx::position"); - if (table->s->primary_key != MAX_KEY) - key_copy(ref, (uchar *)record, table->key_info + table->s->primary_key, - ref_length); - else - memcpy(ref, record, ref_length); + + bzero(ref, ref_length); + + if (!stored_result) + DBUG_VOID_RETURN; + + if (txn->acquire(share, TRUE, &io)) + DBUG_VOID_RETURN; + + io->mark_position(stored_result, ref); + + position_called= TRUE; + DBUG_VOID_RETURN; } @@ -2929,23 +2962,23 @@ void ha_federatedx::position(const uchar int ha_federatedx::rnd_pos(uchar *buf, uchar *pos) { - int result; + int retval; + FEDERATEDX_IO_RESULT *result= stored_result; DBUG_ENTER("ha_federatedx::rnd_pos"); ha_statistic_increment(&SSV::ha_read_rnd_count); - if (table->s->primary_key != MAX_KEY) - { - /* We have a primary key, so use index_read_idx to find row */ - result= index_read_idx(buf, table->s->primary_key, pos, - ref_length, HA_READ_KEY_EXACT); - } - else - { - /* otherwise, get the old record ref as obtained in ::position */ - memcpy(buf, pos, ref_length); - result= 0; - } - table->status= result ? STATUS_NOT_FOUND : 0; - DBUG_RETURN(result); + + if ((retval= txn->acquire(share, TRUE, &io))) + goto error; + + if ((retval= io->seek_position(&result, pos))) + goto error; + + retval= read_next(buf, result); + DBUG_RETURN(retval); + +error: + table->status= STATUS_NOT_FOUND; + DBUG_RETURN(retval); } @@ -2996,15 +3029,20 @@ int ha_federatedx::rnd_pos(uchar *buf, u int ha_federatedx::info(uint flag) { uint error_code; + THD *thd= current_thd; + federatedx_txn *tmp_txn; federatedx_io *tmp_io= 0, **iop= 0; DBUG_ENTER("ha_federatedx::info"); error_code= ER_QUERY_ON_FOREIGN_DATA_SOURCE; + // external_lock may not have been called so txn may not be set + tmp_txn= get_txn(thd); + /* we want not to show table status if not needed to do so */ if (flag & (HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO)) { - if (!*(iop= &io) && (error_code= txn->acquire(share, TRUE, (iop= &tmp_io)))) + if (!*(iop= &io) && (error_code= tmp_txn->acquire(share, TRUE, (iop= &tmp_io)))) goto fail; } @@ -3029,14 +3067,14 @@ int ha_federatedx::info(uint flag) If ::info created it's own transaction, close it. This happens in case of show table status; */ - txn->release(&tmp_io); + tmp_txn->release(&tmp_io); DBUG_RETURN(0); error: if (iop && *iop) { - my_printf_error((*iop)->error_code(), "Got error: %d : %s", MYF(0), + my_printf_error((*iop)->error_code(), "Received error: %d : %s", MYF(0), (*iop)->error_code(), (*iop)->error_str()); } else if (remote_error_number != -1 /* error already reported */) @@ -3045,7 +3083,7 @@ error: my_error(error_code, MYF(0), ER(error_code)); } fail: - txn->release(&tmp_io); + tmp_txn->release(&tmp_io); DBUG_RETURN(error_code); } @@ -3105,12 +3143,44 @@ int ha_federatedx::extra(ha_extra_functi int ha_federatedx::reset(void) { + int error = 0; + insert_dup_update= FALSE; ignore_duplicates= FALSE; replace_duplicates= FALSE; - return 0; -} + position_called= FALSE; + + if (stored_result) + insert_dynamic(&results, (uchar*) &stored_result); + stored_result= 0; + + if (results.elements) + { + federatedx_txn *tmp_txn; + federatedx_io *tmp_io= 0, **iop; + // external_lock may not have been called so txn may not be set + tmp_txn= get_txn(current_thd); + + if (!*(iop= &io) && (error= tmp_txn->acquire(share, TRUE, (iop= &tmp_io)))) + { + DBUG_ASSERT(0); // Fail when testing + return error; + } + + for (uint i= 0; i < results.elements; ++i) + { + FEDERATEDX_IO_RESULT *result= 0; + get_dynamic(&results, (uchar*) &result, i); + (*iop)->free_result(result); + } + tmp_txn->release(&tmp_io); + reset_dynamic(&results); + } + + return error; + +} /* Used to delete all rows in a table. Both for cases of truncate and @@ -3237,7 +3307,7 @@ static int test_connection(MYSQL_THD thd str.length(0); str.append(STRING_WITH_LEN("SELECT * FROM ")); - append_identifier(thd, &str, share->table_name, + append_identifier(thd, &str, share->table_name, share->table_name_length); str.append(STRING_WITH_LEN(" WHERE 1=0")); @@ -3288,14 +3358,14 @@ int ha_federatedx::create(const char *na pthread_mutex_lock(&federatedx_mutex); tmp_share.s= get_server(&tmp_share, NULL); pthread_mutex_unlock(&federatedx_mutex); - + if (tmp_share.s) { tmp_txn= get_txn(thd); if (!(retval= tmp_txn->acquire(&tmp_share, TRUE, &tmp_io))) { retval= test_connection(thd, tmp_io, &tmp_share); - tmp_txn->release(&tmp_io); + tmp_txn->release(&tmp_io); } free_server(tmp_txn, tmp_share.s); } === modified file 'storage/federatedx/ha_federatedx.h' --- a/storage/federatedx/ha_federatedx.h 2010-07-23 20:37:21 +0000 +++ b/storage/federatedx/ha_federatedx.h 2010-08-12 17:52:52 +0000 @@ -1,5 +1,5 @@ -/* -Copyright (c) 2008, Patrick Galbraith +/* +Copyright (c) 2008, Patrick Galbraith All rights reserved. Redistribution and use in source and binary forms, with or without @@ -43,7 +43,7 @@ class federatedx_io; typedef struct st_fedrated_server { MEM_ROOT mem_root; uint use_count, io_count; - + uchar *key; uint key_length; @@ -74,10 +74,10 @@ typedef struct st_fedrated_server { #include <mysql.h> -/* +/* handler::print_error has a case statement for error numbers. - This value is (10000) is far out of range and will envoke the - default: case. + This value is (10000) is far out of range and will envoke the + default: case. (Current error range is 120-159 from include/my_base.h) */ #define HA_FEDERATEDX_ERROR_WITH_REMOTE_SYSTEM 10000 @@ -158,7 +158,7 @@ public: const char * get_database() const { return server->database; } ushort get_port() const { return server->port; } const char * get_socket() const { return server->socket; } - + static bool handles_scheme(const char *scheme); static federatedx_io *construct(MEM_ROOT *server_root, FEDERATEDX_SERVER *server); @@ -167,7 +167,7 @@ public: { return alloc_root(mem_root, size); } static void operator delete(void *ptr, size_t size) { TRASH(ptr, size); } - + virtual int query(const char *buffer, uint length)=0; virtual FEDERATEDX_IO_RESULT *store_result()=0; @@ -178,25 +178,25 @@ public: virtual int error_code()=0; virtual const char *error_str()=0; - + virtual void reset()=0; virtual int commit()=0; virtual int rollback()=0; - + virtual int savepoint_set(ulong sp)=0; virtual ulong savepoint_release(ulong sp)=0; virtual ulong savepoint_rollback(ulong sp)=0; virtual void savepoint_restrict(ulong sp)=0; - + virtual ulong last_savepoint() const=0; virtual ulong actual_savepoint() const=0; virtual bool is_autocommit() const=0; virtual bool table_metadata(ha_statistics *stats, const char *table_name, uint table_name_length, uint flag) = 0; - + /* resultset operations */ - + virtual void free_result(FEDERATEDX_IO_RESULT *io_result)=0; virtual unsigned int get_num_fields(FEDERATEDX_IO_RESULT *io_result)=0; virtual my_ulonglong get_num_rows(FEDERATEDX_IO_RESULT *io_result)=0; @@ -206,6 +206,13 @@ public: unsigned int column)=0; virtual bool is_column_null(const FEDERATEDX_IO_ROW *row, unsigned int column) const=0; + + virtual size_t get_ref_length() const=0; + virtual void mark_position(FEDERATEDX_IO_RESULT *io_result, + void *ref)=0; + virtual int seek_position(FEDERATEDX_IO_RESULT **io_result, + const void *ref)=0; + }; @@ -215,12 +222,12 @@ class federatedx_txn ulong savepoint_level; ulong savepoint_stmt; ulong savepoint_next; - + void release_scan(); public: federatedx_txn(); ~federatedx_txn(); - + bool has_connections() const { return txn_list != NULL; } bool in_transaction() const { return savepoint_next != 0; } int acquire(FEDERATEDX_SHARE *share, bool readonly, federatedx_io **io); @@ -254,8 +261,12 @@ class ha_federatedx: public handler federatedx_txn *txn; federatedx_io *io; FEDERATEDX_IO_RESULT *stored_result; + /** + Array of all stored results we get during a query execution. + */ + DYNAMIC_ARRAY results; + bool position_called; uint fetch_num; // stores the fetch num - FEDERATEDX_IO_OFFSET current_position; // Current position used by ::position() int remote_error_number; char remote_error_buf[FEDERATEDX_QUERY_BUFFER_SIZE]; bool ignore_duplicates, replace_duplicates; @@ -269,7 +280,7 @@ private: */ uint convert_row_to_internal_format(uchar *buf, FEDERATEDX_IO_ROW *row, FEDERATEDX_IO_RESULT *result); - bool create_where_from_key(String *to, KEY *key_info, + bool create_where_from_key(String *to, KEY *key_info, const key_range *start_key, const key_range *end_key, bool records_in_range, bool eq_range); @@ -348,18 +359,18 @@ public: Talk to Kostja about this - how to get the number of rows * ... disk scan time on other side (block size, size of the row) + network time ... - The reason for "records * 1000" is that such a large number forces + The reason for "records * 1000" is that such a large number forces this to use indexes " */ double scan_time() { DBUG_PRINT("info", ("records %lu", (ulong) stats.records)); - return (double)(stats.records*1000); + return (double)(stats.records*1000); } /* The next method will never be called if you do not implement indexes. */ - double read_time(uint index, uint ranges, ha_rows rows) + double read_time(uint index, uint ranges, ha_rows rows) { /* Per Brian, this number is bugus, but this method must be implemented, === modified file 'storage/maria/ha_maria.cc' --- a/storage/maria/ha_maria.cc 2010-08-06 12:51:07 +0000 +++ b/storage/maria/ha_maria.cc 2010-08-24 22:44:50 +0000 @@ -248,7 +248,7 @@ static MYSQL_THDVAR_ULONG(repair_threads static MYSQL_THDVAR_ULONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG, "The buffer that is allocated when sorting the index when doing a " "REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.", - 0, 0, 8192*1024, 4, ~0L, 1); + 0, 0, 128L*1024L*1024L, 4, ~0L, 1); static MYSQL_THDVAR_ENUM(stats_method, PLUGIN_VAR_RQCMDARG, "Specifies how maria index statistics collection code should treat " @@ -1850,7 +1850,7 @@ int ha_maria::enable_indexes(uint mode) "retrying", my_errno, param.db_name, param.table_name); /* This should never fail normally */ - DBUG_ASSERT(0); + DBUG_ASSERT(thd->killed != 0); /* Repairing by sort failed. Now try standard repair method. */ param.testflag &= ~T_REP_BY_SORT; error= (repair(thd, ¶m, 0) != HA_ADMIN_OK); === modified file 'storage/maria/ma_bitmap.c' --- a/storage/maria/ma_bitmap.c 2010-08-10 21:58:08 +0000 +++ b/storage/maria/ma_bitmap.c 2010-08-23 09:52:57 +0000 @@ -365,8 +365,8 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE */ if (bitmap->changed) { - res= write_changed_bitmap(share, bitmap); bitmap->changed= FALSE; + res= write_changed_bitmap(share, bitmap); } /* We do NOT use FLUSH_KEEP_LAZY because we must be sure that bitmap @@ -2063,6 +2063,13 @@ my_bool _ma_bitmap_set_full_page_bits(MA safe_mutex_assert_owner(&info->s->bitmap.bitmap_lock); bitmap_page= page - page % bitmap->pages_covered; + if (page == bitmap_page || + page + page_count >= bitmap_page + bitmap->pages_covered) + { + DBUG_ASSERT(0); /* Wrong in data */ + DBUG_RETURN(1); + } + if (bitmap_page != bitmap->page && _ma_change_bitmap_page(info, bitmap, bitmap_page)) DBUG_RETURN(1); @@ -2142,12 +2149,12 @@ void _ma_bitmap_flushable(MARIA_HA *info DBUG_VOID_RETURN; bitmap= &share->bitmap; + pthread_mutex_lock(&bitmap->bitmap_lock); + if (non_flushable_inc == -1) { - pthread_mutex_lock(&bitmap->bitmap_lock); DBUG_ASSERT((int) bitmap->non_flushable > 0); DBUG_ASSERT(info->non_flushable_state == 1); - info->non_flushable_state= 0; if (--bitmap->non_flushable == 0) { /* @@ -2164,11 +2171,11 @@ void _ma_bitmap_flushable(MARIA_HA *info } DBUG_PRINT("info", ("bitmap->non_flushable: %u", bitmap->non_flushable)); pthread_mutex_unlock(&bitmap->bitmap_lock); + info->non_flushable_state= 0; DBUG_VOID_RETURN; } DBUG_ASSERT(non_flushable_inc == 1); DBUG_ASSERT(info->non_flushable_state == 0); - pthread_mutex_lock(&bitmap->bitmap_lock); while (unlikely(bitmap->flush_all_requested)) { /* @@ -2186,9 +2193,9 @@ void _ma_bitmap_flushable(MARIA_HA *info pthread_cond_wait(&bitmap->bitmap_cond, &bitmap->bitmap_lock); } bitmap->non_flushable++; - info->non_flushable_state= 1; DBUG_PRINT("info", ("bitmap->non_flushable: %u", bitmap->non_flushable)); pthread_mutex_unlock(&bitmap->bitmap_lock); + info->non_flushable_state= 1; DBUG_VOID_RETURN; } @@ -2217,6 +2224,8 @@ void _ma_bitmap_flushable(MARIA_HA *info Note that we may have 'filler blocks' that are used to split a block in half; These can be recognized by that they have page_count == 0. + This code also reverse the effect of ma_bitmap_flushable(.., 1); + RETURN 0 ok 1 error (Couldn't write or read bitmap page) === modified file 'storage/maria/ma_blockrec.c' --- a/storage/maria/ma_blockrec.c 2010-08-10 21:58:08 +0000 +++ b/storage/maria/ma_blockrec.c 2010-08-24 17:17:17 +0000 @@ -334,12 +334,13 @@ typedef struct st_maria_extent_cursor } \ } while (0) + static my_bool delete_tails(MARIA_HA *info, MARIA_RECORD_POS *tails); static my_bool delete_head_or_tail(MARIA_HA *info, pgcache_page_no_t page, uint record_number, my_bool head, my_bool from_update); #ifndef DBUG_OFF -static void _ma_print_directory(uchar *buff, uint block_size); +static void _ma_print_directory(FILE *file, uchar *buff, uint block_size); #endif static uchar *store_page_range(uchar *to, MARIA_BITMAP_BLOCK *block, uint block_size, ulong length, @@ -615,7 +616,7 @@ static inline uint end_of_previous_entry #ifndef DBUG_OFF -static void _ma_print_directory(uchar *buff, uint block_size) +static void _ma_print_directory(FILE *file, uchar *buff, uint block_size) { uint max_entry= (uint) ((uchar *) buff)[DIR_COUNT_OFFSET], row= 0; uint end_of_prev_row= PAGE_HEADER_SIZE; @@ -624,40 +625,46 @@ static void _ma_print_directory(uchar *b dir= dir_entry_pos(buff, block_size, max_entry-1); end= dir_entry_pos(buff, block_size, 0); - DBUG_LOCK_FILE; - fprintf(DBUG_FILE,"Directory dump (pos:length):\n"); + DBUG_LOCK_FILE; /* If using DBUG_FILE */ + fprintf(file,"Directory dump (pos:length):\n"); for (row= 1; dir <= end ; end-= DIR_ENTRY_SIZE, row++) { uint offset= uint2korr(end); uint length= uint2korr(end+2); - fprintf(DBUG_FILE, " %4u:%4u", offset, offset ? length : 0); + fprintf(file, " %4u:%4u", offset, offset ? length : 0); if (!(row % (80/12))) - fputc('\n', DBUG_FILE); + fputc('\n', file); if (offset) { DBUG_ASSERT(offset >= end_of_prev_row); end_of_prev_row= offset + length; } } - fputc('\n', DBUG_FILE); - fflush(DBUG_FILE); + fputc('\n', file); + fflush(file); DBUG_UNLOCK_FILE; } -static void check_directory(uchar *buff, uint block_size, uint min_row_length) +static void check_directory(uchar *buff, uint block_size, uint min_row_length, + uint real_empty_size) { uchar *dir, *end; uint max_entry= (uint) buff[DIR_COUNT_OFFSET]; uint start_of_dir, deleted; - uchar free_entry, prev_free_entry; uint end_of_prev_row= PAGE_HEADER_SIZE; + uint empty_size_on_page; + uint empty_size; + uchar free_entry, prev_free_entry; dir= dir_entry_pos(buff, block_size, max_entry-1); start_of_dir= (uint) (dir - buff); end= dir_entry_pos(buff, block_size, 0); - deleted= 0; + deleted= empty_size= 0; + + empty_size_on_page= (real_empty_size != (uint) -1 ? real_empty_size : + uint2korr(buff + EMPTY_SPACE_OFFSET)); /* Ensure that all rows are in increasing order and no overlaps */ for (; dir <= end ; end-= DIR_ENTRY_SIZE) @@ -668,12 +675,15 @@ static void check_directory(uchar *buff, { DBUG_ASSERT(offset >= end_of_prev_row); DBUG_ASSERT(!length || length >= min_row_length); + empty_size+= offset - end_of_prev_row; end_of_prev_row= offset + length; } else deleted++; } + empty_size+= start_of_dir - end_of_prev_row; DBUG_ASSERT(end_of_prev_row <= start_of_dir); + DBUG_ASSERT(empty_size == empty_size_on_page); /* check free links */ free_entry= buff[DIR_FREE_OFFSET]; @@ -690,7 +700,7 @@ static void check_directory(uchar *buff, DBUG_ASSERT(deleted == 0); } #else -#define check_directory(A,B,C) +#define check_directory(A,B,C,D) #endif /* DBUG_OFF */ @@ -792,20 +802,27 @@ static my_bool extend_area_on_page(MARIA uint *empty_space, uint *ret_offset, uint *ret_length) { - uint rec_offset, length; + uint rec_offset, length, org_rec_length; uint max_entry= (uint) buff[DIR_COUNT_OFFSET]; DBUG_ENTER("extend_area_on_page"); + /* + We can't check for min length here as we may have called + extend_directory() to create a new (empty) entry just before + */ + check_directory(buff, block_size, 0, *empty_space); + rec_offset= uint2korr(dir); if (rec_offset) { /* Extending old row; Mark current space as 'free' */ - length= uint2korr(dir + 2); + length= org_rec_length= uint2korr(dir + 2); DBUG_PRINT("info", ("rec_offset: %u length: %u request_length: %u " "empty_space: %u", - rec_offset, length, request_length, *empty_space)); + rec_offset, org_rec_length, request_length, + *empty_space)); - *empty_space+= length; + *empty_space+= org_rec_length; } else { @@ -875,6 +892,7 @@ static my_bool extend_area_on_page(MARIA "length: %u request_length: %u", length, request_length)); my_errno= HA_ERR_WRONG_IN_RECORD; /* File crashed */ + DBUG_ASSERT(0); /* For debugging */ DBUG_RETURN(1); /* Error in block */ } *empty_space= length; /* All space is here */ @@ -885,7 +903,9 @@ static my_bool extend_area_on_page(MARIA int2store(dir + 2, length); *ret_offset= rec_offset; *ret_length= length; - check_directory(buff, block_size, info ? info->s->base.min_block_length : 0); + + check_directory(buff, block_size, info ? info->s->base.min_block_length : 0, + *empty_space - length); DBUG_RETURN(0); } @@ -1094,7 +1114,7 @@ static uchar *find_free_position(MARIA_H *res_length= length; check_directory(buff, block_size, - info ? info->s->base.min_block_length : 0); + info ? info->s->base.min_block_length : 0, (uint) -1); DBUG_RETURN(dir); } /* No free places in dir; create a new one */ @@ -1115,7 +1135,8 @@ static uchar *find_free_position(MARIA_H *res_rownr= max_entry; *res_length= length; - check_directory(buff, block_size, info ? info->s->base.min_block_length : 0); + check_directory(buff, block_size, info ? info->s->base.min_block_length : 0, + *empty_space); DBUG_RETURN(dir); } @@ -1195,7 +1216,8 @@ static my_bool extend_directory(MARIA_HA } check_directory(buff, block_size, - info ? min(info->s->base.min_block_length, length) : 0); + info ? min(info->s->base.min_block_length, length) : 0, + *empty_space); DBUG_RETURN(0); } @@ -1496,6 +1518,8 @@ void _ma_compact_block_page(uchar *buff, { /* Move all entries after rownr to end of page */ uint rownr_length; + + DBUG_ASSERT(extend_block); /* Should always be true */ next_free_pos= end_of_found_block= page_pos= block_size - DIR_ENTRY_SIZE * max_entry - PAGE_SUFFIX_SIZE; diff= 0; @@ -1567,13 +1591,13 @@ void _ma_compact_block_page(uchar *buff, int2store(dir, offset + diff); /* correct current pos */ next_free_pos= offset; } - if (page_pos != end_of_found_block) { uint length= (end_of_found_block - next_free_pos); memmove(buff + page_pos - length, buff + next_free_pos, length); next_free_pos= page_pos- length; } + /* Extend rownr block to cover hole */ rownr_length= next_free_pos - start_of_found_block; int2store(dir+2, rownr_length); @@ -1596,8 +1620,9 @@ void _ma_compact_block_page(uchar *buff, } buff[PAGE_TYPE_OFFSET]&= ~(uchar) PAGE_CAN_BE_COMPACTED; } - check_directory(buff, block_size, min_row_length); - DBUG_EXECUTE("directory", _ma_print_directory(buff, block_size);); + check_directory(buff, block_size, min_row_length, + extend_block ? 0 : (uint) -1); + DBUG_EXECUTE("directory", _ma_print_directory(DBUG_FILE, buff, block_size);); DBUG_VOID_RETURN; } @@ -1826,16 +1851,11 @@ static my_bool get_rowpos_in_head_or_tai goto err; } + /* + The following dir entry is unused in case of insert / update but + not in case of undo_update / undo_delete + */ dir= dir_entry_pos(buff, block_size, rownr); -#ifdef SANITY_CHECKS - /* Tail's should always be unused */ - if (page_type == TAIL_PAGE && max_entry > rownr && - (dir[0] != 0 || dir[1] != 0)) - { - DBUG_ASSERT(0); - goto err; - } -#endif if (extend_area_on_page(page_type == HEAD_PAGE ? info : 0, buff, dir, rownr, block_size, length, @@ -2212,6 +2232,8 @@ static void store_extent_info(uchar *to, MARIA_BITMAP_BLOCK *block, *end_block; uint copy_length; my_bool first_found= 0; + DBUG_ENTER("store_extent_info"); + DBUG_PRINT("enter", ("count: %u", count)); for (block= first_block, end_block= first_block+count ; block < end_block; block++) @@ -2231,6 +2253,7 @@ static void store_extent_info(uchar *to, page_count|= START_EXTENT_BIT; } pagerange_store(to + PAGE_STORE_SIZE, page_count); + DBUG_DUMP("extent", to, ROW_EXTENT_SIZE); to+= ROW_EXTENT_SIZE; if (!first_found) { @@ -2245,6 +2268,7 @@ static void store_extent_info(uchar *to, data. */ bzero(to, (size_t) (row_extents_second_part + copy_length - to)); + DBUG_VOID_RETURN; } @@ -2263,7 +2287,8 @@ static void store_extent_info(uchar *to, @return @retval 0 ok - @retval 1 Error (out of memory or disk error changing bitmap) + @retval 1 Error (out of memory or disk error changing bitmap) or + wrong information in extent information */ static my_bool extent_to_bitmap_blocks(MARIA_HA *info, @@ -2274,7 +2299,7 @@ static my_bool extent_to_bitmap_blocks(M { MARIA_BITMAP_BLOCK *block, *start_block; MARIA_SHARE *share= info->s; - uint i; + uint i, tail_page; DBUG_ENTER("extent_to_bitmap_blocks"); if (allocate_dynamic(&info->bitmap_blocks, extent_count + 2)) @@ -2300,13 +2325,36 @@ static my_bool extent_to_bitmap_blocks(M page_count&= ~START_EXTENT_BIT; start_block->sub_blocks= (uint) (block - start_block); start_block= block; - } block->page= page_korr(extent_info); block->page_count= page_count; block->sub_blocks= 0; + if (block->page_count == 0) + { + /* Extend allocated but not used by write_block_record() */ + DBUG_ASSERT(block->page == 0); + /* This is the last block */ + blocks->count= i; + break; + } + if ((tail_page= page_count & TAIL_BIT)) + page_count= 1; - if (page_count & TAIL_BIT) + /* Check if wrong data */ + if (block->page == 0 || page_count == 0 || + (block->page + page_count) * share->block_size > + share->state.state.data_file_length) + { + DBUG_PRINT("error", ("page: %lu page_count: %u tail: %u length: %ld data_length: %ld", + (ulong) block->page, + (block->page_count & ~TAIL_BIT), + (uint) test(block->page_count & TAIL_BIT), + (ulong) ((block->page + (page_count & ~TAIL_BIT)) * + share->block_size), + (ulong) share->state.state.data_file_length)); + DBUG_RETURN(1); + } + if (tail_page) { block->org_bitmap_value= _ma_bitmap_get_page_bits(info, &share->bitmap, block->page); @@ -2318,7 +2366,7 @@ static my_bool extent_to_bitmap_blocks(M my_bool res; pthread_mutex_lock(&share->bitmap.bitmap_lock); res= _ma_bitmap_set_full_page_bits(info, &share->bitmap, - block->page, block->page_count); + block->page, page_count); pthread_mutex_unlock(&share->bitmap.bitmap_lock); if (res) DBUG_RETURN(1); @@ -2740,9 +2788,16 @@ static my_bool write_block_record(MARIA_ sizeof(char*)); memcpy(data, tmp_pos, *blob_lengths); data+= *blob_lengths; - /* Skip over tail page that was to be used to store blob */ - block++; - bitmap_blocks->tail_page_skipped= 1; + /* + The following is not true when we want to insert data into original + place. In this case we don't have any extra blocks allocated + */ + if (likely(undo_lsn == LSN_ERROR)) + { + /* Skip over tail page that was prepared for storing blob */ + block++; + bitmap_blocks->tail_page_skipped= 1; + } } if (head_block->sub_blocks > 1) { @@ -2755,7 +2810,9 @@ static my_bool write_block_record(MARIA_ /* Update page directory */ head_length= (uint) (data - row_pos->data); - DBUG_PRINT("info", ("Used head length on page: %u", head_length)); + DBUG_PRINT("info", ("Used head length on page: %u header_length: %u", + head_length, + (uint) (flag & ROW_FLAG_TRANSID ? TRANSID_SIZE : 0))); DBUG_ASSERT(data <= end_of_data); if (head_length < share->base.min_block_length) { @@ -2765,6 +2822,7 @@ static my_bool write_block_record(MARIA_ data+= diff_length; head_length= share->base.min_block_length; } + DBUG_ASSERT(undo_lsn == LSN_ERROR || head_length == row_pos->length); int2store(row_pos->dir + 2, head_length); /* update empty space at start of block */ row_pos->empty_space-= head_length; @@ -2776,7 +2834,8 @@ static my_bool write_block_record(MARIA_ head_block->empty_space= 0; /* Page is full */ head_block->used|= BLOCKUSED_USED; - check_directory(page_buff, share->block_size, share->base.min_block_length); + check_directory(page_buff, share->block_size, share->base.min_block_length, + (uint) -1); /* Now we have to write tail pages, as we need to store the position @@ -2827,11 +2886,13 @@ static my_bool write_block_record(MARIA_ { /* Set only a bit, to not cause bitmap code to believe a block is full - when there is still a lot of entries in it + when there is still a lot of entries in it. */ block->used|= BLOCKUSED_USED; } } + DBUG_ASSERT((undo_lsn == LSN_ERROR || + block == bitmap_blocks->block + bitmap_blocks->count)); column= save_column; block= save_block; blob_lengths= save_blob_lengths; @@ -3225,9 +3286,10 @@ static my_bool write_block_record(MARIA_ else { uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE + - PAGE_STORE_SIZE + DIRPOS_STORE_SIZE + + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE + 2 + HA_CHECKSUM_STORE_SIZE + 2 + PAGERANGE_STORE_SIZE + ROW_EXTENT_SIZE]; + uchar *log_pos; ha_checksum checksum_delta; /* LOGREC_UNDO_ROW_INSERT & LOGREC_UNDO_ROW_UPDATE share same header */ @@ -3237,18 +3299,17 @@ static my_bool write_block_record(MARIA_ dirpos_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + PAGE_STORE_SIZE, row_pos->rownr); - - log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data; - log_array[TRANSLOG_INTERNAL_PARTS + 0].length= - (LSN_STORE_SIZE + FILEID_STORE_SIZE + PAGE_STORE_SIZE + - DIRPOS_STORE_SIZE); + log_pos= (log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE); store_checksum_in_rec(share, checksum_delta, row->checksum - old_record_checksum, - log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + - PAGE_STORE_SIZE + DIRPOS_STORE_SIZE, - log_array[TRANSLOG_INTERNAL_PARTS + 0].length); + log_pos, log_pos); compile_time_assert(sizeof(ha_checksum) == HA_CHECKSUM_STORE_SIZE); + log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data; + log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - + log_data); + if (!old_record) { /* Store undo_lsn in case we are aborting the insert */ @@ -3267,16 +3328,18 @@ static my_bool write_block_record(MARIA_ else { /* Write UNDO log record for the UPDATE */ - uchar *log_pos= (log_data + - log_array[TRANSLOG_INTERNAL_PARTS + 0].length); size_t row_length, extents_length; - uint row_parts_count; + uint row_parts_count, cur_head_length; /* Write head length and extents of the original row so that we - during UNDO can put it back in the original position + during UNDO can put it back in the original position. + We don't store size for TRANSID, as we don't write this during + UNDO. */ - int2store(log_pos, info->cur_row.head_length); + cur_head_length= (info->cur_row.head_length - + info->cur_row.header_length); + int2store(log_pos, cur_head_length); pagerange_store(log_pos + 2, info->cur_row.extents_count); log_pos+= 2 + PAGERANGE_STORE_SIZE; log_array[TRANSLOG_INTERNAL_PARTS + 0].length+= (2 + @@ -3589,6 +3652,7 @@ static my_bool _ma_update_block_record2( MARIA_PINNED_PAGE page_link; uint rownr, org_empty_size, head_length; uint block_size= info->s->block_size; + uint errpos= 0; uchar *dir; pgcache_page_no_t page; struct st_row_pos_info row_pos; @@ -3627,11 +3691,21 @@ static my_bool _ma_update_block_record2( rownr= ma_recordpos_to_dir_entry(record_pos); dir= dir_entry_pos(buff, block_size, rownr); - if ((org_empty_size + cur_row->head_length) >= new_row->total_length) + /* + We can't use cur_row->head_length as the block may have been compacted + since we read it. + */ + head_length= uint2korr(dir + 2); + + if ((org_empty_size + head_length) >= new_row->total_length) { uint rec_offset, length; MARIA_BITMAP_BLOCK block; + DBUG_PRINT("info", ("org_empty_size: %u org_length: %u new_length: %lu", + org_empty_size, head_length, + new_row->total_length)); + /* We can fit the new row in the same page as the original head part of the row @@ -3641,7 +3715,10 @@ static my_bool _ma_update_block_record2( if (extend_area_on_page(info, buff, dir, rownr, block_size, new_row->total_length, &org_empty_size, &rec_offset, &length)) + { + errpos= 1; goto err; + } row_pos.buff= buff; row_pos.rownr= rownr; @@ -3658,9 +3735,15 @@ static my_bool _ma_update_block_record2( if (*cur_row->tail_positions && delete_tails(info, cur_row->tail_positions)) + { + errpos= 2; goto err; + } if (cur_row->extents_count && free_full_pages(info, cur_row)) + { + errpos= 3; goto err; + } res= write_block_record(info, oldrec, record, new_row, blocks, 1, &row_pos, undo_lsn, old_checksum); /* We can't update or delete this without re-reading it again */ @@ -3670,14 +3753,23 @@ static my_bool _ma_update_block_record2( /* Delete old row */ if (*cur_row->tail_positions && delete_tails(info, cur_row->tail_positions)) + { + errpos= 4; goto err; + } if (cur_row->extents_count && free_full_pages(info, cur_row)) + { + errpos= 5; goto err; + } head_length= uint2korr(dir + 2); if (_ma_bitmap_find_new_place(info, new_row, page, head_length + org_empty_size, blocks)) + { + errpos= 6; goto err; + } /* Allocate all size in block for record @@ -3704,10 +3796,14 @@ static my_bool _ma_update_block_record2( row_pos.length= head_length; if ((res= write_block_record(info, oldrec, record, new_row, blocks, 1, &row_pos, undo_lsn, old_checksum))) + { + errpos= 7; goto err; + } DBUG_RETURN(0); err: + DBUG_PRINT("error", ("errpos: %d", errpos)); if (info->non_flushable_state) _ma_bitmap_flushable(info, -1); _ma_unpin_all_pages_and_finalize_row(info, LSN_IMPOSSIBLE); @@ -3725,6 +3821,8 @@ err: This is the main reason we don't make a lot of subfunctions that are common between _ma_update_block_record2() and this function. + + Note: If something goes wrong we mark the file crashed */ static my_bool _ma_update_at_original_place(MARIA_HA *info, @@ -3780,6 +3878,10 @@ static my_bool _ma_update_at_original_pl if ((org_empty_size + cur_row->head_length) < length_on_head_page) { + DBUG_PRINT("error", + ("org_empty_size: %u head_length: %u length_on_page: %u", + org_empty_size, (uint) cur_row->head_length, + length_on_head_page)); my_errno= HA_ERR_WRONG_IN_RECORD; goto err; } @@ -3799,7 +3901,6 @@ static my_bool _ma_update_at_original_pl row_pos.empty_space= empty_size; row_pos.dir= dir; row_pos.data= buff + rec_offset; - row_pos.length= length_on_head_page; /* Delete old row */ if (*cur_row->tail_positions && @@ -3829,12 +3930,17 @@ static my_bool _ma_update_at_original_pl max(new_row->total_length, share->base.min_block_length) <= length_on_head_page); + /* Store same amount of data on head page as on original page */ + row_pos.length= (length_on_head_page - + (extent_count + 1 - blocks->count) * ROW_EXTENT_SIZE); + set_if_bigger(row_pos.length, share->base.min_block_length); if ((res= write_block_record(info, oldrec, record, new_row, blocks, 1, &row_pos, undo_lsn, old_checksum))) goto err; DBUG_RETURN(0); err: + _ma_mark_file_crashed(share); if (info->non_flushable_state) _ma_bitmap_flushable(info, -1); _ma_unpin_all_pages_and_finalize_row(info, LSN_IMPOSSIBLE); @@ -3888,7 +3994,7 @@ static int delete_dir_entry(uchar *buff, } #endif - check_directory(buff, block_size, 0); + check_directory(buff, block_size, 0, (uint) -1); empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET); dir= dir_entry_pos(buff, block_size, record_number); length= uint2korr(dir + 2); @@ -3963,7 +4069,7 @@ static int delete_dir_entry(uchar *buff, *empty_space_res= empty_space; - check_directory(buff, block_size, 0); + check_directory(buff, block_size, 0, empty_space); DBUG_RETURN(0); } @@ -4165,7 +4271,8 @@ my_bool _ma_delete_block_record(MARIA_HA log_pos= log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + PAGE_STORE_SIZE; dirpos_store(log_pos, record_number); log_pos+= DIRPOS_STORE_SIZE; - int2store(log_pos, info->cur_row.head_length); + int2store(log_pos, info->cur_row.head_length - + info->cur_row.header_length); log_pos+= 2; pagerange_store(log_pos, info->cur_row.extents_count); log_pos+= PAGERANGE_STORE_SIZE; @@ -4543,6 +4650,8 @@ int _ma_read_block_record2(MARIA_HA *inf cur_row->head_length= (uint) (end_of_data - data); cur_row->full_page_count= cur_row->tail_count= 0; cur_row->blob_length= 0; + /* Number of bytes in header that we don't need to write during undo */ + cur_row->header_length= total_header_size[(flag & PRECALC_HEADER_BITMASK)]-1; if (flag & ROW_FLAG_TRANSID) { @@ -4554,7 +4663,7 @@ int _ma_read_block_record2(MARIA_HA *inf } /* Skip trans header (for now, until we have MVCC csupport) */ - data+= total_header_size[(flag & PRECALC_HEADER_BITMASK)]; + data+= cur_row->header_length + 1 ; if (flag & ROW_FLAG_NULLS_EXTENDED) cur_null_bytes+= data[-1]; @@ -4950,7 +5059,10 @@ int _ma_read_block_record(MARIA_HA *info uint offset; uint block_size= share->block_size; DBUG_ENTER("_ma_read_block_record"); - DBUG_PRINT("enter", ("rowid: %lu", (long) record_pos)); + DBUG_PRINT("enter", ("rowid: %lu page: %lu rownr: %u", + (ulong) record_pos, + (ulong) ma_recordpos_to_page(record_pos), + ma_recordpos_to_dir_entry(record_pos))); offset= ma_recordpos_to_dir_entry(record_pos); @@ -6698,7 +6810,7 @@ my_bool _ma_apply_undo_row_insert(MARIA_ pgcache_page_no_t page; uint rownr; uchar *buff; - my_bool res= 1; + my_bool res; MARIA_PINNED_PAGE page_link; MARIA_SHARE *share= info->s; ha_checksum checksum; @@ -6744,11 +6856,16 @@ my_bool _ma_apply_undo_row_insert(MARIA_ goto err; res= 0; -err: +end: if (info->non_flushable_state) _ma_bitmap_flushable(info, -1); _ma_unpin_all_pages_and_finalize_row(info, lsn); DBUG_RETURN(res); + +err: + res= 1; + _ma_mark_file_crashed(share); + goto end; } @@ -6971,6 +7088,10 @@ my_bool _ma_apply_undo_row_delete(MARIA_ { DBUG_ASSERT(row.checksum == (share->calc_checksum)(info, record)); } + /* Store same amount of data on head page as on original page */ + row_pos.length= (length_on_head_page - + (extent_count + 1 - blocks->count) * ROW_EXTENT_SIZE); + set_if_bigger(row_pos.length, share->base.min_block_length); if (write_block_record(info, (uchar*) 0, record, &row, blocks, blocks->block->org_bitmap_value != 0, &row_pos, undo_lsn, 0)) @@ -6980,6 +7101,7 @@ my_bool _ma_apply_undo_row_delete(MARIA_ DBUG_RETURN(0); err: + _ma_mark_file_crashed(share); if (info->non_flushable_state) _ma_bitmap_flushable(info, -1); _ma_unpin_all_pages_and_finalize_row(info, LSN_IMPOSSIBLE); @@ -7010,7 +7132,7 @@ my_bool _ma_apply_undo_row_update(MARIA_ pgcache_page_no_t page; ha_checksum checksum_delta; uint rownr, field_length_header, extent_count, length_on_head_page; - int error= 1; + int error; DBUG_ENTER("_ma_apply_undo_row_update"); LINT_INIT(checksum_delta); @@ -7018,6 +7140,7 @@ my_bool _ma_apply_undo_row_update(MARIA_ header+= PAGE_STORE_SIZE; rownr= dirpos_korr(header); header+= DIRPOS_STORE_SIZE; + record_pos= ma_recordpos(page, rownr); DBUG_PRINT("enter", ("rowid: %lu page: %lu rownr: %u", (ulong) record_pos, (ulong) page, rownr)); @@ -7147,9 +7270,14 @@ my_bool _ma_apply_undo_row_update(MARIA_ goto err; error= 0; -err: +end: my_free(current_record, MYF(0)); DBUG_RETURN(error); + +err: + error= 1; + _ma_mark_file_crashed(share); + goto end; } @@ -7229,3 +7357,25 @@ void maria_ignore_trids(MARIA_HA *info) info->trn->min_read_from= ~(TrID) 0; } } + + +#ifndef DBUG_OFF + +/* The following functions are useful to call from debugger */ + +void _ma_print_block_info(uchar *buff) +{ + LSN lsn= lsn_korr(buff); + + printf("LSN: %lu,0x%lx type: %u dir_entries: %u dir_free: %u empty_space: %u\n", + LSN_IN_PARTS(lsn), + (uint)buff[PAGE_TYPE_OFFSET], + (uint)buff[DIR_COUNT_OFFSET], + (uint)buff[DIR_FREE_OFFSET], + (uint) uint2korr(buff + EMPTY_SPACE_OFFSET)); + printf("Start of directory: %lu\n", + maria_block_size - PAGE_SUFFIX_SIZE - + (uint) buff[DIR_COUNT_OFFSET] * DIR_ENTRY_SIZE); + _ma_print_directory(stdout, buff, maria_block_size); +} +#endif === modified file 'storage/maria/ma_check.c' --- a/storage/maria/ma_check.c 2010-08-10 21:58:08 +0000 +++ b/storage/maria/ma_check.c 2010-08-12 16:46:36 +0000 @@ -1930,7 +1930,7 @@ static int check_block_record(HA_CHECK * _ma_check_print_error(param, "Page %9s: Wrong data in bitmap. Page_type: " "%d full: %d empty_space: %u Bitmap-bits: %d", - llstr(page, llbuff), full_dir, page_type, + llstr(page, llbuff), page_type, full_dir, empty_space, bitmap_pattern); if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE)) goto err; === modified file 'storage/maria/ma_checkpoint.c' --- a/storage/maria/ma_checkpoint.c 2009-04-03 09:23:26 +0000 +++ b/storage/maria/ma_checkpoint.c 2010-08-24 22:44:50 +0000 @@ -789,7 +789,6 @@ static int collect_tables(LEX_STRING *st not seen again in the loop. */ share->in_checkpoint= MARIA_CHECKPOINT_LOOKS_AT_ME; - /** @todo avoid strlen() */ total_names_length+= share->open_file_name.length; } } === modified file 'storage/maria/ma_key_recover.c' --- a/storage/maria/ma_key_recover.c 2010-08-09 17:05:42 +0000 +++ b/storage/maria/ma_key_recover.c 2010-08-23 09:52:57 +0000 @@ -64,8 +64,9 @@ void _ma_unpin_all_pages(MARIA_HA *info, builds. */ #ifdef EXTRA_DEBUG - DBUG_ASSERT(!pinned_page->changed || - undo_lsn != LSN_IMPOSSIBLE || !info->s->now_transactional); + DBUG_ASSERT((!pinned_page->changed || + undo_lsn != LSN_IMPOSSIBLE || !info->s->now_transactional) || + (info->s->state.changed & STATE_CRASHED)); #endif pagecache_unlock_by_link(info->s->pagecache, pinned_page->link, pinned_page->unlock, PAGECACHE_UNPIN, @@ -923,7 +924,7 @@ uint _ma_apply_redo_index(MARIA_HA *info if (length < 0) bmove(buff + page_offset, buff + page_offset - length, page_length - page_offset + length); - else + else if (page_length != page_offset) bmove_upp(buff + page_length + length, buff + page_length, page_length - page_offset); page_length+= length; === modified file 'storage/maria/ma_recovery.c' --- a/storage/maria/ma_recovery.c 2010-08-05 15:56:31 +0000 +++ b/storage/maria/ma_recovery.c 2010-08-23 09:52:57 +0000 @@ -494,8 +494,10 @@ end: } else if (!error && max_trid_in_control_file != max_long_trid) { - /* Set max trid in log file so that one can run maria_chk on the tables */ - max_trid_in_control_file= trnman_get_max_trid(); + /* + maria_end() will set max trid in log file so that one can run + maria_chk on the tables + */ maria_recovery_changed_data= 1; } @@ -2395,6 +2397,7 @@ static int run_redo_phase(LSN lsn, LSN l struct st_translog_scanner_data scanner; int len; uint i; + DBUG_ENTER("run_redo_phase"); /* install hooks for execution */ #define install_redo_exec_hook(R) \ @@ -2459,7 +2462,7 @@ static int run_redo_phase(LSN lsn, LSN l { tprint(tracef, "checkpoint address refers to the log end log or " "log is empty, nothing to do.\n"); - return 0; + DBUG_RETURN(0); } len= translog_read_record_header(lsn, &rec); @@ -2467,12 +2470,12 @@ static int run_redo_phase(LSN lsn, LSN l if (len == RECHEADER_READ_ERROR) { eprint(tracef, "Failed to read header of the first record."); - return 1; + DBUG_RETURN(1); } if (translog_scanner_init(lsn, 1, &scanner, 1)) { tprint(tracef, "Scanner init failed\n"); - return 1; + DBUG_RETURN(1); } for (i= 1;;i++) { @@ -2525,7 +2528,7 @@ static int run_redo_phase(LSN lsn, LSN l LSN_IN_PARTS(rec2.lsn)); translog_destroy_scanner(&scanner); translog_free_record_header(&rec); - return(0); + DBUG_RETURN(0); } if (translog_scanner_init(rec2.lsn, 1, &scanner2, 1)) @@ -2623,12 +2626,12 @@ static int run_redo_phase(LSN lsn, LSN l fflush(stderr); procent_printed= 1; } - return 0; + DBUG_RETURN(0); err: translog_destroy_scanner(&scanner); translog_free_record_header(&rec); - return 1; + DBUG_RETURN(1); } @@ -3167,6 +3170,8 @@ static LSN parse_checkpoint_record(LSN l return LSN_ERROR; next_dirty_page_in_pool= dirty_pages_pool; minimum_rec_lsn_of_dirty_pages= LSN_MAX; + if (maria_recovery_verbose) + tprint(tracef, "Table_id Is_index Page_id Rec_lsn\n"); for (i= 0; i < nb_dirty_pages ; i++) { pgcache_page_no_t page_id; @@ -3183,6 +3188,9 @@ static LSN parse_checkpoint_record(LSN l if (new_page((is_index << 16) | table_id, page_id, rec_lsn, next_dirty_page_in_pool++)) return LSN_ERROR; + if (maria_recovery_verbose) + tprint(tracef, "%8u %8u %12lu %lu,0x%lx\n", (uint) table_id, + (uint) is_index, (ulong) page_id, LSN_IN_PARTS(rec_lsn)); set_if_smaller(minimum_rec_lsn_of_dirty_pages, rec_lsn); } /* after that, there will be no insert/delete into the hash */ === modified file 'storage/maria/ma_static.c' --- a/storage/maria/ma_static.c 2010-06-13 22:13:32 +0000 +++ b/storage/maria/ma_static.c 2010-08-18 07:52:57 +0000 @@ -37,7 +37,7 @@ my_bool maria_flush= 0, maria_single_use my_bool maria_delay_key_write= 0, maria_page_checksums= 1; my_bool maria_inited= FALSE; my_bool maria_in_ha_maria= FALSE; /* If used from ha_maria or not */ -my_bool maria_recovery_changed_data= 0; +my_bool maria_recovery_changed_data= 0, maria_recovery_verbose= 0; pthread_mutex_t THR_LOCK_maria; #if defined(THREAD) && !defined(DONT_USE_RW_LOCKS) ulong maria_concurrent_insert= 2; === modified file 'storage/maria/ma_test2.c' --- a/storage/maria/ma_test2.c 2009-01-12 11:12:00 +0000 +++ b/storage/maria/ma_test2.c 2010-08-20 07:29:26 +0000 @@ -83,6 +83,9 @@ int main(int argc, char *argv[]) if (! async_io) my_disable_async_io=1; + /* If we sync or not have no affect on this test */ + my_disable_sync= 1; + maria_data_root= (char *)"."; /* Maria requires that we always have a page cache */ if (maria_init() || @@ -351,7 +354,10 @@ int main(int argc, char *argv[]) key3[atoi((char*) read_record+keyinfo[2].seg[0].start)]=0; } else + { puts("Warning: Skipping delete test because no dupplicate keys"); + break; + } } if (testflag == 3) goto end; === modified file 'storage/maria/ma_write.c' --- a/storage/maria/ma_write.c 2010-08-10 13:29:50 +0000 +++ b/storage/maria/ma_write.c 2010-08-20 07:29:26 +0000 @@ -1973,6 +1973,21 @@ my_bool _ma_log_change(MARIA_PAGE *ma_pa /** @brief Write log entry for page splitting + @fn _ma_log_split() + @param + ma_page Page that is changed + org_length Original length of page + new_length New length of page + key_pos Where key is inserted on page (may be 0 if no key) + key_length Number of bytes changed at key_pos + move_length Number of bytes moved at key_pos to make room for key + prefix_or_suffix KEY_OP_NONE Ignored + KEY_OP_ADD_PREFIX Add data to start of page + KEY_OP_ADD_SUFFIX Add data to end of page + data What data was added + data_length Number of bytes added first or last + changed_length Number of bytes changed first or last. + @note Write log entry for page that has got a key added to the page under one and only one of the following senarios: @@ -1980,9 +1995,6 @@ my_bool _ma_log_change(MARIA_PAGE *ma_pa - Data is added to end of page - Data added at front of page - @param prefix_or_suffix KEY_OP_NONE Ignored - KEY_OP_ADD_PREFIX Add data to start of page - KEY_OP_ADD_SUFFIX Add data to end of page */ @@ -2005,6 +2017,8 @@ static my_bool _ma_log_split(MARIA_PAGE DBUG_PRINT("enter", ("page: %lu org_length: %u new_length: %u", (ulong) ma_page->pos, org_length, new_length)); + DBUG_ASSERT(changed_length >= data_length); + log_pos= log_data + FILEID_STORE_SIZE; page= ma_page->pos / info->s->block_size; page_store(log_pos, page); @@ -2027,6 +2041,7 @@ static my_bool _ma_log_split(MARIA_PAGE log_pos+= 3; translog_parts= 1; extra_length= 0; + DBUG_ASSERT(data_length == 0); } else { @@ -2046,10 +2061,13 @@ static my_bool _ma_log_split(MARIA_PAGE log_pos[0]= KEY_OP_DEL_SUFFIX; int2store(log_pos + 1, diff); log_pos+= 3; + DBUG_ASSERT(data_length == 0); /* Page is shortened */ + DBUG_ASSERT(offset <= org_length - diff); } else { DBUG_ASSERT(new_length == org_length + move_length + data_length); + DBUG_ASSERT(offset <= org_length); } log_pos[0]= KEY_OP_OFFSET; === modified file 'storage/maria/maria_chk.c' --- a/storage/maria/maria_chk.c 2010-08-10 22:04:46 +0000 +++ b/storage/maria/maria_chk.c 2010-08-24 22:44:50 +0000 @@ -1252,7 +1252,7 @@ static int maria_chk(HA_CHECK *param, ch } else if ((param->testflag & T_CHECK) || !(param->testflag & T_AUTO_INC)) { - if (!(param->testflag & T_SILENT) || param->testflag & T_INFO) + if (!(param->testflag & T_VERY_SILENT) || param->testflag & T_INFO) printf("Checking MARIA file: %s\n",filename); if (!(param->testflag & T_SILENT)) printf("Data records: %7s Deleted blocks: %7s\n", === modified file 'storage/maria/maria_def.h' --- a/storage/maria/maria_def.h 2010-07-30 07:45:27 +0000 +++ b/storage/maria/maria_def.h 2010-08-24 17:17:17 +0000 @@ -459,8 +459,9 @@ typedef struct st_maria_row uint *null_field_lengths; /* All null field lengths */ ulong *blob_lengths; /* Length for each blob */ ulong min_length, normal_length, char_length, varchar_length; - ulong blob_length, head_length, total_length; + ulong blob_length, total_length; size_t extents_buffer_length; /* Size of 'extents' buffer */ + uint head_length, header_length; uint field_lengths_length; /* Length of data in field_lengths */ uint extents_count; /* number of extents in 'extents' */ uint full_page_count, tail_count; /* For maria_chk */ @@ -797,6 +798,7 @@ extern uint maria_quick_table_bits; extern char *maria_data_root; extern uchar maria_zero_string[]; extern my_bool maria_inited, maria_in_ha_maria, maria_recovery_changed_data; +extern my_bool maria_recovery_verbose; extern HASH maria_stored_state; extern int (*maria_create_trn_hook)(MARIA_HA *); === modified file 'storage/maria/maria_pack.c' --- a/storage/maria/maria_pack.c 2010-08-02 09:01:24 +0000 +++ b/storage/maria/maria_pack.c 2010-08-11 10:55:54 +0000 @@ -261,8 +261,8 @@ static struct my_option my_long_options[ {"backup", 'b', "Make a backup of the table as table_name.OLD.", &backup, &backup, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"character-sets-dir", OPT_CHARSETS_DIR_MP, - "Directory where character sets are.", &charsets_dir, - &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Directory where character sets are.", (char**) &charsets_dir, + (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"force", 'f', === modified file 'storage/maria/maria_read_log.c' --- a/storage/maria/maria_read_log.c 2010-08-10 21:58:08 +0000 +++ b/storage/maria/maria_read_log.c 2010-08-18 07:52:57 +0000 @@ -33,7 +33,7 @@ static my_bool opt_display_only, opt_app static my_bool opt_check; static const char *opt_tmpdir; static ulong opt_page_buffer_size; -static ulonglong opt_start_from_lsn, opt_end_lsn; +static ulonglong opt_start_from_lsn, opt_end_lsn, opt_start_from_checkpoint; static MY_TMPDIR maria_chk_tmpdir; @@ -94,7 +94,6 @@ int main(int argc, char **argv) if (opt_display_only) printf("You are using --display-only, NOTHING will be written to disk\n"); - /* LSN could be also --start-from-lsn=# */ lsn= translog_first_lsn_in_log(); if (lsn == LSN_ERROR) { @@ -105,8 +104,16 @@ int main(int argc, char **argv) { fprintf(stdout, "The transaction log is empty\n"); } - fprintf(stdout, "The transaction log starts from lsn (%lu,0x%lx)\n", - LSN_IN_PARTS(lsn)); + if (opt_start_from_checkpoint && !opt_start_from_lsn && + last_checkpoint_lsn != LSN_IMPOSSIBLE) + { + lsn= LSN_IMPOSSIBLE; /* LSN set in maria_apply_log() */ + fprintf(stdout, "Starting from checkpoint (%lu,0x%lx)\n", + LSN_IN_PARTS(last_checkpoint_lsn)); + } + else + fprintf(stdout, "The transaction log starts from lsn (%lu,0x%lx)\n", + LSN_IN_PARTS(lsn)); if (opt_start_from_lsn) { @@ -183,7 +190,7 @@ static struct my_option my_long_options[ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"display-only", 'd', "display brief info read from records' header", - (uchar **) &opt_display_only, (uchar **) &opt_display_only, 0, GET_BOOL, + &opt_display_only, &opt_display_only, 0, GET_BOOL, NO_ARG,0, 0, 0, 0, 0, 0}, {"maria-log-dir-path", 'l', "Path to the directory where to store transactional log", @@ -197,11 +204,17 @@ static struct my_option my_long_options[ { "start-from-lsn", 'o', "Start reading log from this lsn", &opt_start_from_lsn, &opt_start_from_lsn, 0, GET_ULL, REQUIRED_ARG, 0, 0, ~(longlong) 0, 0, 0, 0 }, + {"start-from-checkpoint", 'C', "Start applying from last checkpoint", + &opt_start_from_checkpoint, &opt_start_from_checkpoint, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, { "end-lsn", 'e', "Stop applying at this lsn. If end-lsn is used, UNDO:s " "will not be applied", &opt_end_lsn, &opt_end_lsn, 0, GET_ULL, REQUIRED_ARG, 0, 0, ~(longlong) 0, 0, 0, 0 }, {"silent", 's', "Print less information during apply/undo phase", - (uchar **) &opt_silent, (uchar **) &opt_silent, 0, + &opt_silent, &opt_silent, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"verbose", 'v', "Print more information during apply/undo phase", + &maria_recovery_verbose, &maria_recovery_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"tmpdir", 't', "Path for temporary files. Multiple paths can be specified, " "separated by " === modified file 'storage/maria/unittest/ma_test_recovery.pl' --- a/storage/maria/unittest/ma_test_recovery.pl 2008-07-09 09:02:27 +0000 +++ b/storage/maria/unittest/ma_test_recovery.pl 2010-08-20 07:29:26 +0000 @@ -300,7 +300,7 @@ sub check_table_is_same $com.= "| grep -v \"file length\" | grep -v \"LSNs:\" | grep -v \"UUID:\" > $tmp/maria_chk_message.txt 2>&1"; $res= `$com`; print MY_LOG $res; - $res= `$maria_exe_path/maria_chk$suffix -s -e --read-only $table`; + $res= `$maria_exe_path/maria_chk$suffix -ss -e --read-only $table`; print MY_LOG $res; $checksum2= `$maria_exe_path/maria_chk$suffix -dss $table`; if ("$checksum" ne "$checksum2") @@ -415,7 +415,7 @@ sub physical_cmp # save original tables to restore them later copy("$table.MAD", "$tmp/before_zerofill$table_no.MAD") || die(); copy("$table.MAI", "$tmp/before_zerofill$table_no.MAI") || die(); - $com= "$maria_exe_path/maria_chk$suffix -s --zerofill-keep-lsn $table"; + $com= "$maria_exe_path/maria_chk$suffix -ss --zerofill-keep-lsn $table"; $res= `$com`; print MY_LOG $res; $table_no= $table_no + 1; === modified file 'storage/xtradb/buf/buf0lru.c' --- a/storage/xtradb/buf/buf0lru.c 2010-08-04 08:39:53 +0000 +++ b/storage/xtradb/buf/buf0lru.c 2010-08-11 10:55:54 +0000 @@ -2131,7 +2131,7 @@ ibool buf_LRU_file_dump(void) /*===================*/ { - os_file_t dump_file = -1; + os_file_t dump_file = (os_file_t) -1; ibool success; byte* buffer_base = NULL; byte* buffer = NULL; @@ -2221,7 +2221,7 @@ buf_LRU_file_dump(void) ret = TRUE; end: - if (dump_file != -1) + if (dump_file != (os_file_t) -1) os_file_close(dump_file); if (buffer_base) ut_free(buffer_base); @@ -2235,7 +2235,7 @@ ibool buf_LRU_file_restore(void) /*======================*/ { - os_file_t dump_file = -1; + os_file_t dump_file = (os_file_t) -1; ibool success; byte* buffer_base = NULL; byte* buffer = NULL; @@ -2326,7 +2326,7 @@ buf_LRU_file_restore(void) " (requested: %lu, read: %lu)\n", req, reads); ret = TRUE; end: - if (dump_file != -1) + if (dump_file != (os_file_t) -1) os_file_close(dump_file); if (buffer_base) ut_free(buffer_base); === modified file 'storage/xtradb/fil/fil0fil.c' --- a/storage/xtradb/fil/fil0fil.c 2010-08-05 19:56:11 +0000 +++ b/storage/xtradb/fil/fil0fil.c 2010-08-24 22:44:50 +0000 @@ -3044,7 +3044,7 @@ fil_open_single_table_tablespace( dulint new_id[31]; ulint root_page[31]; ulint n_index; - os_file_t info_file = -1; + os_file_t info_file = (os_file_t) -1; char* info_file_path; ulint i; int len; @@ -3130,7 +3130,7 @@ fil_open_single_table_tablespace( } skip_info: - if (info_file != -1) + if (info_file != (os_file_t) -1) os_file_close(info_file); /* === modified file 'storage/xtradb/handler/i_s.cc' --- a/storage/xtradb/handler/i_s.cc 2010-08-05 19:56:11 +0000 +++ b/storage/xtradb/handler/i_s.cc 2010-08-24 22:44:50 +0000 @@ -3459,7 +3459,7 @@ i_s_innodb_table_stats_fill( field_store_string(i_s_table->field[0], buf); field_store_string(i_s_table->field[1], ptr); - i_s_table->field[2]->store(table->stat_n_rows); + i_s_table->field[2]->store(table->stat_n_rows, 1); i_s_table->field[3]->store(table->stat_clustered_index_size); i_s_table->field[4]->store(table->stat_sum_of_other_index_sizes); i_s_table->field[5]->store(table->stat_modified_counter); === modified file 'storage/xtradb/srv/srv0srv.c' --- a/storage/xtradb/srv/srv0srv.c 2010-08-04 08:39:53 +0000 +++ b/storage/xtradb/srv/srv0srv.c 2010-08-11 10:55:54 +0000 @@ -2897,7 +2897,7 @@ loop: if (bpl) { retry_flush_batch: n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, - bpl, + (ulint) bpl, oldest_lsn + (lsn - lsn_old)); if (n_pages_flushed == ULINT_UNDEFINED) { os_thread_sleep(5000); === modified file 'support-files/compiler_warnings.supp' --- a/support-files/compiler_warnings.supp 2010-08-06 06:36:09 +0000 +++ b/support-files/compiler_warnings.supp 2010-08-20 13:16:47 +0000 @@ -44,6 +44,7 @@ buf/buf0buf\.c: .*block_mutex.* might be btr/btr0cur\.c: null argument where non-null required: 1800-3000 btr/btr0btr\.c: null argument where non-null required: 2500-3000 ibuf/ibuf0ibuf.c: null argument where non-null required: 700-1000 +fsp/fsp0fsp\.c: result of 32-bit shift implicitly converted to 64 bits # # bdb is not critical to keep up to date @@ -108,6 +109,7 @@ signal\.c : .*unused parameter.* .* : conversion from '.*size_t' to 'UINT'.* .* : conversion from '.*size_t' to 'uInt'.* .* : conversion from '.*size_t' to 'uint16'.* +.* : The following environment variables were not found.* # # The following should be fixed by the ndb team @@ -125,6 +127,8 @@ storage/maria/ma_pagecache.c: .*'info_ch # Pbxt # xaction_xt\.cc: may be used uninitialized in this function +lock_xt\.cc : uninitialized local variable .* used +restart_xt\.cc : dereferencing pointer .* does break strict-aliasing # # I think these are due to mix of C and C++. === modified file 'unittest/mytap/tap.h' --- a/unittest/mytap/tap.h 2010-08-02 09:01:24 +0000 +++ b/unittest/mytap/tap.h 2010-08-11 10:55:54 +0000 @@ -106,7 +106,7 @@ extern int skip_big_tests; @param count The planned number of tests to run. */ -void plan(int const count); +void plan(int count); /** @@ -125,7 +125,7 @@ void plan(int const count); which case nothing is printed. */ -void ok(int const pass, char const *fmt, ...) +void ok(int pass, char const *fmt, ...) __attribute__((format(printf,2,3)));
participants (1)
-
Michael Widenius