diff --git a/client/mysqltest.cc b/client/mysqltest.cc index fd848957531..1d7f0b0b445 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -97,7 +97,7 @@ static my_bool sp_protocol= 0, sp_protocol_enabled= 0; static my_bool view_protocol= 0, view_protocol_enabled= 0; static my_bool cursor_protocol= 0, cursor_protocol_enabled= 0; static my_bool parsing_disabled= 0; -static my_bool display_result_vertically= FALSE, +static my_bool display_result_vertically= FALSE, display_result_lower= FALSE, display_metadata= FALSE, display_result_sorted= FALSE; static my_bool disable_query_log= 0, disable_result_log= 0; static my_bool disable_warnings= 0; @@ -230,6 +230,8 @@ struct st_connection char *name; size_t name_len; MYSQL_STMT* stmt; + /* Set after send to disallow other queries before reap */ + my_bool pending; #ifdef EMBEDDED_LIBRARY const char *cur_query; @@ -273,6 +275,7 @@ enum enum_commands { Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR, Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS, Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL, Q_SORTED_RESULT, + Q_LOWERCASE, Q_START_TIMER, Q_END_TIMER, Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL, Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT, @@ -344,6 +347,7 @@ const char *command_names[]= "query_vertical", "query_horizontal", "sorted_result", + "lowercase_result", "start_timer", "end_timer", "character_set", @@ -4651,7 +4655,8 @@ void do_close_connection(struct st_command *command) if (con->util_mysql) mysql_close(con->util_mysql); con->util_mysql= 0; - + con->pending= FALSE; + my_free(con->name, MYF(0)); /* @@ -6483,6 +6488,9 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, if (flags & QUERY_SEND_FLAG) { + if (cn->pending) + die ("Cannot run query on connection between send and reap"); + /* Send the query */ @@ -6502,8 +6510,11 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, wait_query_thread_end(cn); #endif /*EMBEDDED_LIBRARY*/ if (!(flags & QUERY_REAP_FLAG)) + { + cn->pending= TRUE; DBUG_VOID_RETURN; - + } + do { /* @@ -6587,6 +6598,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, end: + cn->pending= FALSE; /* We save the return code (mysql_errno(mysql)) from the last call sent to the server into the mysqltest builtin variable $mysql_errno. This @@ -7841,6 +7853,13 @@ int main(int argc, char **argv) */ display_result_sorted= TRUE; break; + case Q_LOWERCASE: + /* + Turn on lowercasing of result, will be reset after next + command + */ + display_result_lower= TRUE; + break; case Q_LET: do_let(command); break; case Q_EVAL_RESULT: die("'eval_result' command is deprecated"); @@ -8056,8 +8075,9 @@ int main(int argc, char **argv) */ free_all_replace(); - /* Also reset "sorted_result" */ + /* Also reset "sorted_result" and "lowercase"*/ display_result_sorted= FALSE; + display_result_lower= FALSE; } last_command_executed= command_executed; @@ -9461,6 +9481,18 @@ void replace_dynstr_append_mem(DYNAMIC_STRING *ds, fix_win_paths(val, len); #endif + if (display_result_lower) + { + /* Convert to lower case, and do this first */ + char lower[512]; + char *c= lower; + for (const char *v= val; *v; v++) + *c++= my_tolower(charset_info, *v); + *c= '\0'; + /* Copy from this buffer instead */ + val= lower; + } + if (glob_replace_regex) { /* Regex replace */ diff --git a/mysql-test/lib/mtr_gprof.pl b/mysql-test/lib/mtr_gprof.pl index f6615301dd7..5820a4007b8 100644 --- a/mysql-test/lib/mtr_gprof.pl +++ b/mysql-test/lib/mtr_gprof.pl @@ -20,43 +20,20 @@ use strict; -# These are not to be prefixed with "mtr_" +sub gprof_collect ($@) { + my ($exe_mysqld, @gprof_dirs)= @_; -sub gprof_prepare (); -sub gprof_collect (); + print ("Collecting gprof reports.....\n"); -############################################################################## -# -# -# -############################################################################## - -sub gprof_prepare () { - - rmtree($::opt_gprof_dir); - mkdir($::opt_gprof_dir); -} - -# FIXME what about master1 and slave1?! -sub gprof_collect () { - - if ( -f "$::master->[0]->{'path_myddir'}/gmon.out" ) + foreach my $datadir (@gprof_dirs) { - # FIXME check result code?! - mtr_run("gprof", - [$::exe_master_mysqld, - "$::master->[0]->{'path_myddir'}/gmon.out"], - $::opt_gprof_master, "", "", ""); - print "Master execution profile has been saved in $::opt_gprof_master\n"; - } - if ( -f "$::slave->[0]->{'path_myddir'}/gmon.out" ) - { - # FIXME check result code?! - mtr_run("gprof", - [$::exe_slave_mysqld, - "$::slave->[0]->{'path_myddir'}/gmon.out"], - $::opt_gprof_slave, "", "", ""); - print "Slave execution profile has been saved in $::opt_gprof_slave\n"; + my $gprof_msg= "$datadir/gprof.msg"; + my $gprof_err= "$datadir/gprof.err"; + if ( -f "$datadir/gmon.out" ) + { + system("gprof $exe_mysqld $datadir/gmon.out 2>$gprof_err >$gprof_msg"); + print ("GPROF output in $gprof_msg, errors in $gprof_err\n"); + } } } diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 43aa3595dc1..5b439fbc91e 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -87,6 +87,7 @@ use IO::Select; require "lib/mtr_process.pl"; require "lib/mtr_io.pl"; require "lib/mtr_gcov.pl"; +require "lib/mtr_gprof.pl"; require "lib/mtr_misc.pl"; $SIG{INT}= sub { mtr_error("Got ^C signal"); }; @@ -167,6 +168,9 @@ our $opt_gcov_exe= "gcov"; our $opt_gcov_err= "mysql-test-gcov.msg"; our $opt_gcov_msg= "mysql-test-gcov.err"; +our $opt_gprof; +our %gprof_dirs; + our $glob_debugger= 0; our $opt_gdb; our $opt_client_gdb; @@ -745,6 +749,9 @@ sub run_worker ($) { if ($opt_valgrind_mysqld) { valgrind_exit_reports(); } + if ( $opt_gprof ) { + gprof_collect (find_mysqld($basedir), keys %gprof_dirs); + } exit(0); } else { @@ -857,6 +864,7 @@ sub command_line_setup { # Coverage, profiling etc 'gcov' => \$opt_gcov, + 'gprof' => \$opt_gprof, 'valgrind|valgrind-all' => \$opt_valgrind, 'valgrind-mysqltest' => \$opt_valgrind_mysqltest, 'valgrind-mysqld' => \$opt_valgrind_mysqld, @@ -1249,7 +1257,7 @@ sub command_line_setup { # -------------------------------------------------------------------------- # Gcov flag # -------------------------------------------------------------------------- - if ( $opt_gcov and ! $source_dist ) + if ( ($opt_gcov or $opt_gprof) and ! $source_dist ) { mtr_error("Coverage test needs the source - please use source dist"); } @@ -3549,7 +3557,7 @@ sub run_testcase ($) { { # mysqltest failed, probably crashed $tinfo->{comment}= - "mysqltest failed with unexpected return code $res"; + "mysqltest failed with unexpected return code $res\n"; report_failure_and_restart($tinfo); } @@ -4140,6 +4148,20 @@ sub report_failure_and_restart ($) { # about what failed has been saved to file. Save the report # in tinfo $tinfo->{logfile}= mtr_fromfile($logfile); + # If no newlines in the test log: + # (it will contain the CURRENT_TEST written by mtr, so is not empty) + if ($tinfo->{logfile} !~ /\n/) + { + # Show how far it got before suddenly failing + $tinfo->{comment}.= "mysqltest failed but provided no output\n"; + my $log_file_name= $opt_vardir."/log/".$tinfo->{shortname}.".log"; + if (-e $log_file_name) { + $tinfo->{comment}.= + "The result from queries just before the failure was:". + "\n< snip >\n". + mtr_lastlinesfromfile($log_file_name, 20)."\n"; + } + } } else { @@ -4351,6 +4373,8 @@ sub mysqld_start ($$) { } # Remember this log file for valgrind error report search $mysqld_logs{$output}= 1 if $opt_valgrind; + # Remember data dir for gmon.out files if using gprof + $gprof_dirs{$mysqld->value('datadir')}= 1 if $opt_gprof; if ( defined $exe ) { diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 671f88cb00a..e77dcd7b0a6 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -523,6 +523,26 @@ a D 1 1 1 4 drop table t1; +create table t1 ( f1 char(10)); +insert into t1 values ("Abcd"); +select * from t1; +f1 +Abcd +select * from t2;; +ERROR 42S02: Table 'test.t2' doesn't exist +select * from t1; +f1 +Abcd +select * from t1;; +Result coming up +f1 +Abcd +select * from t1;; +f1 +Abcd +mysqltest: At line 2: Cannot run query on connection between send and reap +select * from t1;; +drop table t1; mysqltest: At line 1: Missing required argument 'filename' to command 'remove_file' mysqltest: At line 1: Missing required argument 'filename' to command 'write_file' mysqltest: At line 1: End of file encountered before 'EOF' delimiter was found @@ -682,6 +702,29 @@ INSERT INTO t1 SELECT f1 - 256 FROM t1; INSERT INTO t1 SELECT f1 - 512 FROM t1; SELECT * FROM t1; DROP TABLE t1; +select "500g blåbærsyltetøy" as "will be lower cased"; +will be lower cased +500g blåbærsyltetøy +SELECT "UPPER" AS "WILL NOT BE lower cased"; +WILL NOT BE lower cased +UPPER +UP +SELECT 0 as "UP AGAIN"; +UP AGAIN +0 +select "abcdef" as "uvwxyz"; +uvwxyz +abcdef +select "xyz" as name union select "abc" as name order by name desc; +name +abc +xyz +select 1 as "some new text"; +some new text +1 +select 0 as "will not lower case ÄËÐ"; +will not lower case ÄËÐ +0 CREATE TABLE t1( a int, b varchar(255), c datetime ); diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index b4ea9202df7..45fc0715312 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1605,6 +1605,57 @@ insert into t1 values (2,4); select * from t1; drop table t1; +# ---------------------------------------------------------------------------- +# Tests of send +# ---------------------------------------------------------------------------- + +create table t1 ( f1 char(10)); +insert into t1 values ("Abcd"); + +# 1. Basic test + +send select * from t1; +reap; + +# 2. Test with error + +--send select * from t2; +--error ER_NO_SUCH_TABLE +--reap + +# 3. test send of next stmt + +--send +select * from t1; +--reap + +# 4. Non-query stmt betwen send and reap allowed + +--send select * from t1; +--sleep 0.05 +--echo Result coming up +--reap + +# 5. Test of send_eval + +--let $my_stmt= select * from t1; +--send_eval $my_stmt +--reap + +# 6. Test that mysqltest does not allow query stmt between send and reap +# Untestable directly as it causes mysqltest to fail + +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.in +--send select * from t1; +select 1; +--reap +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.in 2>&1 +remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.in; + +drop table t1; + # ---------------------------------------------------------------------------- # test for remove_file # ---------------------------------------------------------------------------- @@ -2059,6 +2110,44 @@ INSERT INTO t1 SELECT f1 - 512 FROM t1; SELECT * FROM t1; --enable_result_log DROP TABLE t1; + +# ---------------------------------------------------------------------------- +# test for lowercase_result +# ---------------------------------------------------------------------------- + +# 1. Basic test +--lowercase_result +SELECT "500g BLÅBÆRSYLTETØY" AS "WILL BE lower cased"; + +# 2. test that it does not apply to next statement +SELECT "UPPER" AS "WILL NOT BE lower cased"; + +# 3. test that it does not affect non-SQL or the following statement +--lowercase_result +--echo UP +SELECT 0 as "UP AGAIN"; + +# 4. test that it works with eval and variables +let $lower_stmt=SELECT "ABCdef" AS "uvwXYZ"; +--lowercase_result +eval $lower_stmt; + +# 5. test that it works in combination with sort +sorted_result; +lowercase_result; +SELECT "Xyz" AS Name UNION SELECT "Abc" as Name ORDER BY Name DESC; + +# 6. Test combination with replace, and that lower casing is done first +--lowercase_result +--replace_result old new +SELECT 1 as "SOME OLD TEXT"; + +# 7. Test missing lower casing of "unknown" characters +--character_set utf8 +--lowercase_result +SELECT 0 as "WILL NOT lower case ÄËÐ"; +--character_set latin1 + # ---------------------------------------------------------------------------- # Some coverage tests # ----------------------------------------------------------------------------